- Lower DEBUG_CONSISTENCY to 1 2 is only really useful when debugging
[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 <limits.h>
13
14 #define MAX_ALLOCATION_PASSES 100
15
16 #define DEBUG_CONSISTENCY 1
17 #define DEBUG_SDP_BLOCKS 0
18 #define DEBUG_TRIPLE_COLOR 0
19
20 #warning "FIXME boundary cases with small types in larger registers"
21 #warning "FIXME give clear error messages about unused variables"
22 #warning "FIXME properly handle multi dimensional arrays"
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 /* Types on the destination platform */
208 #warning "FIXME this assumes 32bit x86 is the destination"
209 typedef int8_t   schar_t;
210 typedef uint8_t  uchar_t;
211 typedef int8_t   char_t;
212 typedef int16_t  short_t;
213 typedef uint16_t ushort_t;
214 typedef int32_t  int_t;
215 typedef uint32_t uint_t;
216 typedef int32_t  long_t;
217 typedef uint32_t ulong_t;
218
219 #define SCHAR_T_MIN (-128)
220 #define SCHAR_T_MAX 127
221 #define UCHAR_T_MAX 255
222 #define CHAR_T_MIN  SCHAR_T_MIN
223 #define CHAR_T_MAX  SCHAR_T_MAX
224 #define SHRT_T_MIN  (-32768)
225 #define SHRT_T_MAX  32767
226 #define USHRT_T_MAX 65535
227 #define INT_T_MIN   (-LONG_T_MAX - 1)
228 #define INT_T_MAX   2147483647
229 #define UINT_T_MAX  4294967295U
230 #define LONG_T_MIN  (-LONG_T_MAX - 1)
231 #define LONG_T_MAX  2147483647
232 #define ULONG_T_MAX 4294967295U
233
234 struct file_state {
235         struct file_state *prev;
236         const char *basename;
237         char *dirname;
238         char *buf;
239         off_t size;
240         char *pos;
241         int line;
242         char *line_start;
243         int report_line;
244         const char *report_name;
245         const char *report_dir;
246 };
247 struct hash_entry;
248 struct token {
249         int tok;
250         struct hash_entry *ident;
251         int str_len;
252         union {
253                 ulong_t integer;
254                 const char *str;
255         } val;
256 };
257
258 /* I have two classes of types:
259  * Operational types.
260  * Logical types.  (The type the C standard says the operation is of)
261  *
262  * The operational types are:
263  * chars
264  * shorts
265  * ints
266  * longs
267  *
268  * floats
269  * doubles
270  * long doubles
271  *
272  * pointer
273  */
274
275
276 /* Machine model.
277  * No memory is useable by the compiler.
278  * There is no floating point support.
279  * All operations take place in general purpose registers.
280  * There is one type of general purpose register.
281  * Unsigned longs are stored in that general purpose register.
282  */
283
284 /* Operations on general purpose registers.
285  */
286
287 #define OP_SDIVT      0
288 #define OP_UDIVT      1
289 #define OP_SMUL       2
290 #define OP_UMUL       3
291 #define OP_SDIV       4
292 #define OP_UDIV       5
293 #define OP_SMOD       6
294 #define OP_UMOD       7
295 #define OP_ADD        8
296 #define OP_SUB        9
297 #define OP_SL        10
298 #define OP_USR       11
299 #define OP_SSR       12 
300 #define OP_AND       13 
301 #define OP_XOR       14
302 #define OP_OR        15
303 #define OP_POS       16 /* Dummy positive operator don't use it */
304 #define OP_NEG       17
305 #define OP_INVERT    18
306                      
307 #define OP_EQ        20
308 #define OP_NOTEQ     21
309 #define OP_SLESS     22
310 #define OP_ULESS     23
311 #define OP_SMORE     24
312 #define OP_UMORE     25
313 #define OP_SLESSEQ   26
314 #define OP_ULESSEQ   27
315 #define OP_SMOREEQ   28
316 #define OP_UMOREEQ   29
317                      
318 #define OP_LFALSE    30  /* Test if the expression is logically false */
319 #define OP_LTRUE     31  /* Test if the expression is logcially true */
320
321 #define OP_LOAD      32
322 #define OP_STORE     33
323 /* For OP_STORE ->type holds the type
324  * RHS(0) holds the destination address
325  * RHS(1) holds the value to store.
326  */
327
328 #define OP_NOOP      34
329
330 #define OP_MIN_CONST 50
331 #define OP_MAX_CONST 59
332 #define IS_CONST_OP(X) (((X) >= OP_MIN_CONST) && ((X) <= OP_MAX_CONST))
333 #define OP_INTCONST  50
334 /* For OP_INTCONST ->type holds the type.
335  * ->u.cval holds the constant value.
336  */
337 #define OP_BLOBCONST 51
338 /* For OP_BLOBCONST ->type holds the layout and size
339  * information.  u.blob holds a pointer to the raw binary
340  * data for the constant initializer.
341  */
342 #define OP_ADDRCONST 52
343 /* For OP_ADDRCONST ->type holds the type.
344  * MISC(0) holds the reference to the static variable.
345  * ->u.cval holds an offset from that value.
346  */
347
348 #define OP_WRITE     60 
349 /* OP_WRITE moves one pseudo register to another.
350  * RHS(0) holds the destination pseudo register, which must be an OP_DECL.
351  * RHS(1) holds the psuedo to move.
352  */
353
354 #define OP_READ      61
355 /* OP_READ reads the value of a variable and makes
356  * it available for the pseudo operation.
357  * Useful for things like def-use chains.
358  * RHS(0) holds points to the triple to read from.
359  */
360 #define OP_COPY      62
361 /* OP_COPY makes a copy of the psedo register or constant in RHS(0).
362  */
363 #define OP_PIECE     63
364 /* OP_PIECE returns one piece of a instruction that returns a structure.
365  * MISC(0) is the instruction
366  * u.cval is the LHS piece of the instruction to return.
367  */
368 #define OP_ASM       64
369 /* OP_ASM holds a sequence of assembly instructions, the result
370  * of a C asm directive.
371  * RHS(x) holds input value x to the assembly sequence.
372  * LHS(x) holds the output value x from the assembly sequence.
373  * u.blob holds the string of assembly instructions.
374  */
375
376 #define OP_DEREF     65
377 /* OP_DEREF generates an lvalue from a pointer.
378  * RHS(0) holds the pointer value.
379  * OP_DEREF serves as a place holder to indicate all necessary
380  * checks have been done to indicate a value is an lvalue.
381  */
382 #define OP_DOT       66
383 /* OP_DOT references a submember of a structure lvalue.
384  * RHS(0) holds the lvalue.
385  * ->u.field holds the name of the field we want.
386  *
387  * Not seen outside of expressions.
388  */
389 #define OP_VAL       67
390 /* OP_VAL returns the value of a subexpression of the current expression.
391  * Useful for operators that have side effects.
392  * RHS(0) holds the expression.
393  * MISC(0) holds the subexpression of RHS(0) that is the
394  * value of the expression.
395  *
396  * Not seen outside of expressions.
397  */
398 #define OP_LAND      68
399 /* OP_LAND performs a C logical and between RHS(0) and RHS(1).
400  * Not seen outside of expressions.
401  */
402 #define OP_LOR       69
403 /* OP_LOR performs a C logical or between RHS(0) and RHS(1).
404  * Not seen outside of expressions.
405  */
406 #define OP_COND      70
407 /* OP_CODE performas a C ? : operation. 
408  * RHS(0) holds the test.
409  * RHS(1) holds the expression to evaluate if the test returns true.
410  * RHS(2) holds the expression to evaluate if the test returns false.
411  * Not seen outside of expressions.
412  */
413 #define OP_COMMA     71
414 /* OP_COMMA performacs a C comma operation.
415  * That is RHS(0) is evaluated, then RHS(1)
416  * and the value of RHS(1) is returned.
417  * Not seen outside of expressions.
418  */
419
420 #define OP_FCALL      72
421 /* OP_FCALL performs a procedure call. 
422  * MISC(0) holds a pointer to the OP_LIST of a function
423  * RHS(x) holds argument x of a function
424  * 
425  * Currently not seen outside of expressions.
426  */
427 #define OP_VAL_VEC   74
428 /* OP_VAL_VEC is an array of triples that are either variable
429  * or values for a structure or an array.
430  * RHS(x) holds element x of the vector.
431  * triple->type->elements holds the size of the vector.
432  */
433
434 /* statements */
435 #define OP_LIST      80
436 /* OP_LIST Holds a list of statements that compose a function, and a result value.
437  * RHS(0) holds the list of statements.
438  * MISC(0) holds the value of the statements.
439  * A list of all functions is maintained.
440  */
441
442 #define OP_BRANCH    81 /* an unconditional branch */
443 /* For branch instructions
444  * TARG(0) holds the branch target.
445  * ->next holds where to branch to if the branch is not taken.
446  * The branch target can only be a label
447  */
448
449 #define OP_CBRANCH   82 /* a conditional branch */
450 /* For conditional branch instructions
451  * RHS(0) holds the branch condition.
452  * TARG(1) holds the branch target.
453  * ->next holds where to branch to if the branch is not taken.
454  * The branch target can only be a label
455  */
456
457 #define OP_CALL      83 /* an uncontional branch that will return */
458 /* For call instructions
459  * MISC(0) holds the OP_RET that returns from the branch
460  * TARG(0) holds the branch target.
461  * ->next holds where to branch to if the branch is not taken.
462  * The branch target can only be a label
463  */
464
465 #define OP_RET       84 /* an uncontinonal branch through a variable back to an OP_CALL */
466 /* For call instructions
467  * RHS(0) holds the variable with the return address
468  * The branch target can only be a label
469  */
470
471 #define OP_LABEL     86
472 /* OP_LABEL is a triple that establishes an target for branches.
473  * ->use is the list of all branches that use this label.
474  */
475
476 #define OP_ADECL     87 
477 /* OP_ADECL is a triple that establishes an lvalue for assignments.
478  * ->use is a list of statements that use the variable.
479  */
480
481 #define OP_SDECL     88
482 /* OP_SDECL is a triple that establishes a variable of static
483  * storage duration.
484  * ->use is a list of statements that use the variable.
485  * MISC(0) holds the initializer expression.
486  */
487
488
489 #define OP_PHI       89
490 /* OP_PHI is a triple used in SSA form code.  
491  * It is used when multiple code paths merge and a variable needs
492  * a single assignment from any of those code paths.
493  * The operation is a cross between OP_DECL and OP_WRITE, which
494  * is what OP_PHI is generated from.
495  * 
496  * RHS(x) points to the value from code path x
497  * The number of RHS entries is the number of control paths into the block
498  * in which OP_PHI resides.  The elements of the array point to point
499  * to the variables OP_PHI is derived from.
500  *
501  * MISC(0) holds a pointer to the orginal OP_DECL node.
502  */
503
504 /* Architecture specific instructions */
505 #define OP_CMP         100
506 #define OP_TEST        101
507 #define OP_SET_EQ      102
508 #define OP_SET_NOTEQ   103
509 #define OP_SET_SLESS   104
510 #define OP_SET_ULESS   105
511 #define OP_SET_SMORE   106
512 #define OP_SET_UMORE   107
513 #define OP_SET_SLESSEQ 108
514 #define OP_SET_ULESSEQ 109
515 #define OP_SET_SMOREEQ 110
516 #define OP_SET_UMOREEQ 111
517
518 #define OP_JMP         112
519 #define OP_JMP_EQ      113
520 #define OP_JMP_NOTEQ   114
521 #define OP_JMP_SLESS   115
522 #define OP_JMP_ULESS   116
523 #define OP_JMP_SMORE   117
524 #define OP_JMP_UMORE   118
525 #define OP_JMP_SLESSEQ 119
526 #define OP_JMP_ULESSEQ 120
527 #define OP_JMP_SMOREEQ 121
528 #define OP_JMP_UMOREEQ 122
529
530 /* Builtin operators that it is just simpler to use the compiler for */
531 #define OP_INB         130
532 #define OP_INW         131
533 #define OP_INL         132
534 #define OP_OUTB        133
535 #define OP_OUTW        134
536 #define OP_OUTL        135
537 #define OP_BSF         136
538 #define OP_BSR         137
539 #define OP_RDMSR       138
540 #define OP_WRMSR       139
541 #define OP_HLT         140
542
543 struct op_info {
544         const char *name;
545         unsigned flags;
546 #define PURE   1 /* Triple has no side effects */
547 #define IMPURE 2 /* Triple has side effects */
548 #define PURE_BITS(FLAGS) ((FLAGS) & 0x3)
549 #define DEF    4 /* Triple is a variable definition */
550 #define BLOCK  8 /* Triple stores the current block */
551 #define STRUCTURAL 16 /* Triple does not generate a machine instruction */
552 #define BRANCH     32 /* Triple is a branch instruction */
553 #define CBRANCH    64 /* Triple is a conditional branch instruction */
554         unsigned char lhs, rhs, misc, targ;
555 };
556
557 #define OP(LHS, RHS, MISC, TARG, FLAGS, NAME) { \
558         .name = (NAME), \
559         .flags = (FLAGS), \
560         .lhs = (LHS), \
561         .rhs = (RHS), \
562         .misc = (MISC), \
563         .targ = (TARG), \
564          }
565 static const struct op_info table_ops[] = {
566 [OP_SDIVT      ] = OP( 2,  2, 0, 0, PURE | BLOCK , "sdivt"),
567 [OP_UDIVT      ] = OP( 2,  2, 0, 0, PURE | BLOCK , "udivt"),
568 [OP_SMUL       ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "smul"),
569 [OP_UMUL       ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "umul"),
570 [OP_SDIV       ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "sdiv"),
571 [OP_UDIV       ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "udiv"),
572 [OP_SMOD       ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "smod"),
573 [OP_UMOD       ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "umod"),
574 [OP_ADD        ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "add"),
575 [OP_SUB        ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "sub"),
576 [OP_SL         ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "sl"),
577 [OP_USR        ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "usr"),
578 [OP_SSR        ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "ssr"),
579 [OP_AND        ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "and"),
580 [OP_XOR        ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "xor"),
581 [OP_OR         ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "or"),
582 [OP_POS        ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK , "pos"),
583 [OP_NEG        ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK , "neg"),
584 [OP_INVERT     ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK , "invert"),
585
586 [OP_EQ         ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "eq"),
587 [OP_NOTEQ      ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "noteq"),
588 [OP_SLESS      ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "sless"),
589 [OP_ULESS      ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "uless"),
590 [OP_SMORE      ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "smore"),
591 [OP_UMORE      ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "umore"),
592 [OP_SLESSEQ    ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "slesseq"),
593 [OP_ULESSEQ    ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "ulesseq"),
594 [OP_SMOREEQ    ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "smoreeq"),
595 [OP_UMOREEQ    ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "umoreeq"),
596 [OP_LFALSE     ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK , "lfalse"),
597 [OP_LTRUE      ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK , "ltrue"),
598
599 [OP_LOAD       ] = OP( 0,  1, 0, 0, IMPURE | DEF | BLOCK, "load"),
600 [OP_STORE      ] = OP( 0,  2, 0, 0, IMPURE | BLOCK , "store"),
601
602 [OP_NOOP       ] = OP( 0,  0, 0, 0, PURE | BLOCK | STRUCTURAL, "noop"),
603
604 [OP_INTCONST   ] = OP( 0,  0, 0, 0, PURE | DEF, "intconst"),
605 [OP_BLOBCONST  ] = OP( 0,  0, 0, 0, PURE , "blobconst"),
606 [OP_ADDRCONST  ] = OP( 0,  0, 1, 0, PURE | DEF, "addrconst"),
607
608 [OP_WRITE      ] = OP( 0,  2, 0, 0, PURE | BLOCK, "write"),
609 [OP_READ       ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "read"),
610 [OP_COPY       ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "copy"),
611 [OP_PIECE      ] = OP( 0,  0, 1, 0, PURE | DEF | STRUCTURAL, "piece"),
612 [OP_ASM        ] = OP(-1, -1, 0, 0, IMPURE, "asm"),
613 [OP_DEREF      ] = OP( 0,  1, 0, 0, 0 | DEF | BLOCK, "deref"), 
614 [OP_DOT        ] = OP( 0,  1, 0, 0, 0 | DEF | BLOCK, "dot"),
615
616 [OP_VAL        ] = OP( 0,  1, 1, 0, 0 | DEF | BLOCK, "val"),
617 [OP_LAND       ] = OP( 0,  2, 0, 0, 0 | DEF | BLOCK, "land"),
618 [OP_LOR        ] = OP( 0,  2, 0, 0, 0 | DEF | BLOCK, "lor"),
619 [OP_COND       ] = OP( 0,  3, 0, 0, 0 | DEF | BLOCK, "cond"),
620 [OP_COMMA      ] = OP( 0,  2, 0, 0, 0 | DEF | BLOCK, "comma"),
621 /* Call is special most it can stand in for anything so it depends on context */
622 [OP_FCALL       ] = OP(-1, -1, 1, 0, 0 | BLOCK, "fcall"),
623 /* The sizes of OP_FCALL and OP_VAL_VEC depend upon context */
624 [OP_VAL_VEC    ] = OP( 0, -1, 0, 0, 0 | BLOCK | STRUCTURAL, "valvec"),
625
626 [OP_LIST       ] = OP( 0,  1, 1, 0, 0 | DEF | STRUCTURAL, "list"),
627 [OP_BRANCH     ] = OP( 0,  0, 0, 1, PURE | BLOCK | BRANCH, "branch"),
628 [OP_CBRANCH    ] = OP( 0,  1, 0, 1, PURE | BLOCK | BRANCH | CBRANCH, "cbranch"),
629 [OP_CALL       ] = OP( 0,  0, 1, 1, PURE | BLOCK | BRANCH, "call"),
630 [OP_RET        ] = OP( 0,  1, 0, 0, PURE | BLOCK | BRANCH, "ret"),
631 [OP_LABEL      ] = OP( 0,  0, 0, 0, PURE | BLOCK | STRUCTURAL, "label"),
632 [OP_ADECL      ] = OP( 0,  0, 0, 0, PURE | BLOCK | STRUCTURAL, "adecl"),
633 [OP_SDECL      ] = OP( 0,  0, 1, 0, PURE | BLOCK | STRUCTURAL, "sdecl"),
634 /* The number of RHS elements of OP_PHI depend upon context */
635 [OP_PHI        ] = OP( 0, -1, 1, 0, PURE | DEF | BLOCK, "phi"),
636
637 [OP_CMP        ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK, "cmp"),
638 [OP_TEST       ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "test"),
639 [OP_SET_EQ     ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_eq"),
640 [OP_SET_NOTEQ  ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_noteq"),
641 [OP_SET_SLESS  ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_sless"),
642 [OP_SET_ULESS  ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_uless"),
643 [OP_SET_SMORE  ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_smore"),
644 [OP_SET_UMORE  ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_umore"),
645 [OP_SET_SLESSEQ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_slesseq"),
646 [OP_SET_ULESSEQ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_ulesseq"),
647 [OP_SET_SMOREEQ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_smoreq"),
648 [OP_SET_UMOREEQ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_umoreq"),
649 [OP_JMP        ] = OP( 0,  0, 0, 1, PURE | BLOCK | BRANCH, "jmp"),
650 [OP_JMP_EQ     ] = OP( 0,  1, 0, 1, PURE | BLOCK | BRANCH | CBRANCH, "jmp_eq"),
651 [OP_JMP_NOTEQ  ] = OP( 0,  1, 0, 1, PURE | BLOCK | BRANCH | CBRANCH, "jmp_noteq"),
652 [OP_JMP_SLESS  ] = OP( 0,  1, 0, 1, PURE | BLOCK | BRANCH | CBRANCH, "jmp_sless"),
653 [OP_JMP_ULESS  ] = OP( 0,  1, 0, 1, PURE | BLOCK | BRANCH | CBRANCH, "jmp_uless"),
654 [OP_JMP_SMORE  ] = OP( 0,  1, 0, 1, PURE | BLOCK | BRANCH | CBRANCH, "jmp_smore"),
655 [OP_JMP_UMORE  ] = OP( 0,  1, 0, 1, PURE | BLOCK | BRANCH | CBRANCH, "jmp_umore"),
656 [OP_JMP_SLESSEQ] = OP( 0,  1, 0, 1, PURE | BLOCK | BRANCH | CBRANCH, "jmp_slesseq"),
657 [OP_JMP_ULESSEQ] = OP( 0,  1, 0, 1, PURE | BLOCK | BRANCH | CBRANCH, "jmp_ulesseq"),
658 [OP_JMP_SMOREEQ] = OP( 0,  1, 0, 1, PURE | BLOCK | BRANCH | CBRANCH, "jmp_smoreq"),
659 [OP_JMP_UMOREEQ] = OP( 0,  1, 0, 1, PURE | BLOCK | BRANCH | CBRANCH, "jmp_umoreq"),
660
661 [OP_INB        ] = OP( 0,  1, 0, 0, IMPURE | DEF | BLOCK, "__inb"),
662 [OP_INW        ] = OP( 0,  1, 0, 0, IMPURE | DEF | BLOCK, "__inw"),
663 [OP_INL        ] = OP( 0,  1, 0, 0, IMPURE | DEF | BLOCK, "__inl"),
664 [OP_OUTB       ] = OP( 0,  2, 0, 0, IMPURE| BLOCK, "__outb"),
665 [OP_OUTW       ] = OP( 0,  2, 0, 0, IMPURE| BLOCK, "__outw"),
666 [OP_OUTL       ] = OP( 0,  2, 0, 0, IMPURE| BLOCK, "__outl"),
667 [OP_BSF        ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "__bsf"),
668 [OP_BSR        ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "__bsr"),
669 [OP_RDMSR      ] = OP( 2,  1, 0, 0, IMPURE | BLOCK, "__rdmsr"),
670 [OP_WRMSR      ] = OP( 0,  3, 0, 0, IMPURE | BLOCK, "__wrmsr"),
671 [OP_HLT        ] = OP( 0,  0, 0, 0, IMPURE | BLOCK, "__hlt"),
672 };
673 #undef OP
674 #define OP_MAX      (sizeof(table_ops)/sizeof(table_ops[0]))
675
676 static const char *tops(int index) 
677 {
678         static const char unknown[] = "unknown op";
679         if (index < 0) {
680                 return unknown;
681         }
682         if (index > OP_MAX) {
683                 return unknown;
684         }
685         return table_ops[index].name;
686 }
687
688 struct asm_info;
689 struct triple;
690 struct block;
691 struct triple_set {
692         struct triple_set *next;
693         struct triple *member;
694 };
695
696 #define MAX_LHS  15
697 #define MAX_RHS  250
698 #define MAX_MISC 3
699 #define MAX_TARG 3
700
701 struct occurance {
702         int count;
703         const char *filename;
704         const char *function;
705         int line;
706         int col;
707         struct occurance *parent;
708 };
709 struct triple {
710         struct triple *next, *prev;
711         struct triple_set *use;
712         struct type *type;
713         unsigned char op;
714         unsigned char template_id;
715         unsigned short sizes;
716 #define TRIPLE_LHS(SIZES)  (((SIZES) >>  0) & 0x0f)
717 #define TRIPLE_RHS(SIZES)  (((SIZES) >>  4) & 0xff)
718 #define TRIPLE_MISC(SIZES) (((SIZES) >> 12) & 0x03)
719 #define TRIPLE_TARG(SIZES) (((SIZES) >> 14) & 0x03)
720 #define TRIPLE_SIZE(SIZES) \
721         (TRIPLE_LHS(SIZES)  + \
722          TRIPLE_RHS(SIZES)  + \
723          TRIPLE_MISC(SIZES) + \
724          TRIPLE_TARG(SIZES))
725 #define TRIPLE_SIZES(LHS, RHS, MISC, TARG) \
726         ((((LHS) & 0x0f) <<  0) | \
727         (((RHS)  & 0xff) <<  4) | \
728         (((MISC) & 0x03) << 12) | \
729         (((TARG) & 0x03) << 14))
730 #define TRIPLE_LHS_OFF(SIZES)  (0)
731 #define TRIPLE_RHS_OFF(SIZES)  (TRIPLE_LHS_OFF(SIZES) + TRIPLE_LHS(SIZES))
732 #define TRIPLE_MISC_OFF(SIZES) (TRIPLE_RHS_OFF(SIZES) + TRIPLE_RHS(SIZES))
733 #define TRIPLE_TARG_OFF(SIZES) (TRIPLE_MISC_OFF(SIZES) + TRIPLE_MISC(SIZES))
734 #define LHS(PTR,INDEX) ((PTR)->param[TRIPLE_LHS_OFF((PTR)->sizes) + (INDEX)])
735 #define RHS(PTR,INDEX) ((PTR)->param[TRIPLE_RHS_OFF((PTR)->sizes) + (INDEX)])
736 #define TARG(PTR,INDEX) ((PTR)->param[TRIPLE_TARG_OFF((PTR)->sizes) + (INDEX)])
737 #define MISC(PTR,INDEX) ((PTR)->param[TRIPLE_MISC_OFF((PTR)->sizes) + (INDEX)])
738         unsigned id; /* A scratch value and finally the register */
739 #define TRIPLE_FLAG_FLATTENED   (1 << 31)
740 #define TRIPLE_FLAG_PRE_SPLIT   (1 << 30)
741 #define TRIPLE_FLAG_POST_SPLIT  (1 << 29)
742 #define TRIPLE_FLAG_VOLATILE    (1 << 28)
743 #define TRIPLE_FLAG_LOCAL       (1 << 27)
744         struct occurance *occurance;
745         union {
746                 ulong_t cval;
747                 struct block  *block;
748                 void *blob;
749                 struct hash_entry *field;
750                 struct asm_info *ainfo;
751         } u;
752         struct triple *param[2];
753 };
754
755 struct reg_info {
756         unsigned reg;
757         unsigned regcm;
758 };
759 struct ins_template {
760         struct reg_info lhs[MAX_LHS + 1], rhs[MAX_RHS + 1];
761 };
762
763 struct asm_info {
764         struct ins_template tmpl;
765         char *str;
766 };
767
768 struct block_set {
769         struct block_set *next;
770         struct block *member;
771 };
772 struct block {
773         struct block *work_next;
774         struct triple *first, *last;
775         int edge_count;
776         struct block_set *edges;
777         int users;
778         struct block_set *use;
779         struct block_set *idominates;
780         struct block_set *domfrontier;
781         struct block *idom;
782         struct block_set *ipdominates;
783         struct block_set *ipdomfrontier;
784         struct block *ipdom;
785         int vertex;
786         
787 };
788
789 struct symbol {
790         struct symbol *next;
791         struct hash_entry *ident;
792         struct triple *def;
793         struct type *type;
794         int scope_depth;
795 };
796
797 struct macro {
798         struct hash_entry *ident;
799         char *buf;
800         int buf_len;
801 };
802
803 struct hash_entry {
804         struct hash_entry *next;
805         const char *name;
806         int name_len;
807         int tok;
808         struct macro *sym_define;
809         struct symbol *sym_label;
810         struct symbol *sym_tag;
811         struct symbol *sym_ident;
812 };
813
814 #define HASH_TABLE_SIZE 2048
815
816 struct compiler_state {
817         const char *label_prefix;
818         const char *ofilename;
819         unsigned long flags;
820         unsigned long debug;
821         unsigned long max_allocation_passes;
822 };
823 struct arch_state {
824         unsigned long features;
825 };
826 struct compile_state {
827         struct compiler_state *compiler;
828         struct arch_state *arch;
829         FILE *output;
830         struct file_state *file;
831         struct occurance *last_occurance;
832         const char *function;
833         struct token token[4];
834         struct hash_entry *hash_table[HASH_TABLE_SIZE];
835         struct hash_entry *i_switch;
836         struct hash_entry *i_case;
837         struct hash_entry *i_continue;
838         struct hash_entry *i_break;
839         struct hash_entry *i_default;
840         struct hash_entry *i_return;
841         int scope_depth;
842         int if_depth, if_value;
843         int macro_line;
844         struct file_state *macro_file;
845         struct triple *functions;
846         struct triple *main_function;
847         struct triple *first;
848         struct triple *global_pool;
849         struct block *first_block, *last_block;
850         int last_vertex;
851 };
852
853 /* visibility global/local */
854 /* static/auto duration */
855 /* typedef, register, inline */
856 #define STOR_SHIFT         0
857 #define STOR_MASK     0x001f
858 /* Visibility */
859 #define STOR_GLOBAL   0x0001
860 /* Duration */
861 #define STOR_PERM     0x0002
862 /* Definition locality */
863 #define STOR_NONLOCAL 0x0004  /* The definition is not in this translation unit */
864 /* Storage specifiers */
865 #define STOR_AUTO     0x0000
866 #define STOR_STATIC   0x0002
867 #define STOR_LOCAL    0x0003
868 #define STOR_EXTERN   0x0007
869 #define STOR_INLINE   0x0008
870 #define STOR_REGISTER 0x0010
871 #define STOR_TYPEDEF  0x0018
872
873 #define QUAL_SHIFT         5
874 #define QUAL_MASK     0x00e0
875 #define QUAL_NONE     0x0000
876 #define QUAL_CONST    0x0020
877 #define QUAL_VOLATILE 0x0040
878 #define QUAL_RESTRICT 0x0080
879
880 #define TYPE_SHIFT         8
881 #define TYPE_MASK     0x1f00
882 #define TYPE_INTEGER(TYPE)    ((((TYPE) >= TYPE_CHAR) && ((TYPE) <= TYPE_ULLONG)) || ((TYPE) == TYPE_ENUM))
883 #define TYPE_ARITHMETIC(TYPE) ((((TYPE) >= TYPE_CHAR) && ((TYPE) <= TYPE_LDOUBLE)) || ((TYPE) == TYPE_ENUM))
884 #define TYPE_UNSIGNED(TYPE)   ((TYPE) & 0x0100)
885 #define TYPE_SIGNED(TYPE)     (!TYPE_UNSIGNED(TYPE))
886 #define TYPE_MKUNSIGNED(TYPE) (((TYPE) & ~0xF000) | 0x0100)
887 #define TYPE_RANK(TYPE)       ((TYPE) & ~0xF1FF)
888 #define TYPE_PTR(TYPE)        (((TYPE) & TYPE_MASK) == TYPE_POINTER)
889 #define TYPE_DEFAULT  0x0000
890 #define TYPE_VOID     0x0100
891 #define TYPE_CHAR     0x0200
892 #define TYPE_UCHAR    0x0300
893 #define TYPE_SHORT    0x0400
894 #define TYPE_USHORT   0x0500
895 #define TYPE_INT      0x0600
896 #define TYPE_UINT     0x0700
897 #define TYPE_LONG     0x0800
898 #define TYPE_ULONG    0x0900
899 #define TYPE_LLONG    0x0a00 /* long long */
900 #define TYPE_ULLONG   0x0b00
901 #define TYPE_FLOAT    0x0c00
902 #define TYPE_DOUBLE   0x0d00
903 #define TYPE_LDOUBLE  0x0e00 /* long double */
904
905 /* Note: TYPE_ENUM is chosen very carefully so TYPE_RANK works */
906 #define TYPE_ENUM     0x1600
907 #define TYPE_LIST     0x1700
908 /* TYPE_LIST is a basic building block when defining enumerations
909  * type->field_ident holds the name of this enumeration entry.
910  * type->right holds the entry in the list.
911  */
912
913 #define TYPE_STRUCT   0x1000
914 #define TYPE_UNION    0x1100
915 #define TYPE_POINTER  0x1200 
916 /* For TYPE_POINTER:
917  * type->left holds the type pointed to.
918  */
919 #define TYPE_FUNCTION 0x1300 
920 /* For TYPE_FUNCTION:
921  * type->left holds the return type.
922  * type->right holds the...
923  */
924 #define TYPE_PRODUCT  0x1400
925 /* TYPE_PRODUCT is a basic building block when defining structures
926  * type->left holds the type that appears first in memory.
927  * type->right holds the type that appears next in memory.
928  */
929 #define TYPE_OVERLAP  0x1500
930 /* TYPE_OVERLAP is a basic building block when defining unions
931  * type->left and type->right holds to types that overlap
932  * each other in memory.
933  */
934 #define TYPE_ARRAY    0x1800
935 /* TYPE_ARRAY is a basic building block when definitng arrays.
936  * type->left holds the type we are an array of.
937  * type-> holds the number of elements.
938  */
939
940 #define ELEMENT_COUNT_UNSPECIFIED ULONG_T_MAX
941
942 struct type {
943         unsigned int type;
944         struct type *left, *right;
945         ulong_t elements;
946         struct hash_entry *field_ident;
947         struct hash_entry *type_ident;
948 };
949
950 #define TEMPLATE_BITS      7
951 #define MAX_TEMPLATES      (1<<TEMPLATE_BITS)
952 #define MAX_REG_EQUIVS     16
953 #define MAX_REGC           14
954 #define MAX_REGISTERS      75
955 #define REGISTER_BITS      7
956 #define MAX_VIRT_REGISTERS (1<<REGISTER_BITS)
957 #define REG_UNSET          0
958 #define REG_UNNEEDED       1
959 #define REG_VIRT0          (MAX_REGISTERS + 0)
960 #define REG_VIRT1          (MAX_REGISTERS + 1)
961 #define REG_VIRT2          (MAX_REGISTERS + 2)
962 #define REG_VIRT3          (MAX_REGISTERS + 3)
963 #define REG_VIRT4          (MAX_REGISTERS + 4)
964 #define REG_VIRT5          (MAX_REGISTERS + 5)
965 #define REG_VIRT6          (MAX_REGISTERS + 6)
966 #define REG_VIRT7          (MAX_REGISTERS + 7)
967 #define REG_VIRT8          (MAX_REGISTERS + 8)
968 #define REG_VIRT9          (MAX_REGISTERS + 9)
969
970 #if (MAX_REGISTERS + 9) > MAX_VIRT_REGISTERS
971 #error "MAX_VIRT_REGISTERS to small"
972 #endif
973 #if (MAX_REGC + REGISTER_BITS) > 27
974 #error "Too many id bits used"
975 #endif
976
977 /* Provision for 8 register classes */
978 #define REG_SHIFT  0
979 #define REGC_SHIFT REGISTER_BITS
980 #define REGC_MASK (((1 << MAX_REGC) - 1) << REGISTER_BITS)
981 #define REG_MASK (MAX_VIRT_REGISTERS -1)
982 #define ID_REG(ID)              ((ID) & REG_MASK)
983 #define SET_REG(ID, REG)        ((ID) = (((ID) & ~REG_MASK) | ((REG) & REG_MASK)))
984 #define ID_REGCM(ID)            (((ID) & REGC_MASK) >> REGC_SHIFT)
985 #define SET_REGCM(ID, REGCM)    ((ID) = (((ID) & ~REGC_MASK) | (((REGCM) << REGC_SHIFT) & REGC_MASK)))
986 #define SET_INFO(ID, INFO)      ((ID) = (((ID) & ~(REG_MASK | REGC_MASK)) | \
987                 (((INFO).reg) & REG_MASK) | ((((INFO).regcm) << REGC_SHIFT) & REGC_MASK)))
988
989 static unsigned arch_reg_regcm(struct compile_state *state, int reg);
990 static unsigned arch_regcm_normalize(struct compile_state *state, unsigned regcm);
991 static unsigned arch_regcm_reg_normalize(struct compile_state *state, unsigned regcm);
992 static void arch_reg_equivs(
993         struct compile_state *state, unsigned *equiv, int reg);
994 static int arch_select_free_register(
995         struct compile_state *state, char *used, int classes);
996 static unsigned arch_regc_size(struct compile_state *state, int class);
997 static int arch_regcm_intersect(unsigned regcm1, unsigned regcm2);
998 static unsigned arch_type_to_regcm(struct compile_state *state, struct type *type);
999 static const char *arch_reg_str(int reg);
1000 static struct reg_info arch_reg_constraint(
1001         struct compile_state *state, struct type *type, const char *constraint);
1002 static struct reg_info arch_reg_clobber(
1003         struct compile_state *state, const char *clobber);
1004 static struct reg_info arch_reg_lhs(struct compile_state *state, 
1005         struct triple *ins, int index);
1006 static struct reg_info arch_reg_rhs(struct compile_state *state, 
1007         struct triple *ins, int index);
1008 static struct triple *transform_to_arch_instruction(
1009         struct compile_state *state, struct triple *ins);
1010
1011
1012
1013 #define DEBUG_ABORT_ON_ERROR    0x00000001
1014 #define DEBUG_BASIC_BLOCKS      0x00000002
1015 #define DEBUG_FDOMINATORS       0x00000004
1016 #define DEBUG_RDOMINATORS       0x00000008
1017 #define DEBUG_TRIPLES           0x00000010
1018 #define DEBUG_INTERFERENCE      0x00000020
1019 #define DEBUG_SCC_TRANSFORM     0x00000040
1020 #define DEBUG_SCC_TRANSFORM2    0x00000080
1021 #define DEBUG_REBUILD_SSA_FORM  0x00000100
1022 #define DEBUG_INLINE            0x00000200
1023 #define DEBUG_RANGE_CONFLICTS   0x00000400
1024 #define DEBUG_RANGE_CONFLICTS2  0x00000800
1025 #define DEBUG_COLOR_GRAPH       0x00001000
1026 #define DEBUG_COLOR_GRAPH2      0x00002000
1027 #define DEBUG_COALESCING        0x00004000
1028 #define DEBUG_COALESCING2       0x00008000
1029
1030 #define DEBUG_DEFAULT ( \
1031         DEBUG_ABORT_ON_ERROR | \
1032         DEBUG_BASIC_BLOCKS | \
1033         DEBUG_FDOMINATORS | \
1034         DEBUG_RDOMINATORS | \
1035         DEBUG_TRIPLES | \
1036         0 )
1037
1038 #define COMPILER_ELIMINATE_INEFECTUAL_CODE 0x00000001
1039 #define COMPILER_SIMPLIFY                  0x00000002
1040 #define COMPILER_SCC_TRANSFORM             0x00000004
1041 #define COMPILER_INLINE                    0x00000008
1042 #define COMPILER_ALWAYS_INLINE             0x00000010
1043 #define COMPILER_SIMPLIFY_OP               0x00000020
1044 #define COMPILER_SIMPLIFY_PHI              0x00000040
1045 #define COMPILER_SIMPLIFY_LABEL            0x00000080
1046 #define COMPILER_SIMPLIFY_BRANCH           0x00000100
1047 #define COMPILER_SIMPLIFY_COPY             0x00000200
1048 #define COMPILER_SIMPLIFY_ARITH            0x00000400
1049 #define COMPILER_SIMPLIFY_SHIFT            0x00000800
1050 #define COMPILER_SIMPLIFY_BITWISE          0x00001000
1051 #define COMPILER_SIMPLIFY_LOGICAL          0x00002000
1052
1053 #define COMPILER_DEFAULT_FLAGS ( \
1054         COMPILER_ELIMINATE_INEFECTUAL_CODE | \
1055         COMPILER_INLINE | \
1056         COMPILER_ALWAYS_INLINE | \
1057         COMPILER_SIMPLIFY_OP | \
1058         COMPILER_SIMPLIFY_PHI | \
1059         COMPILER_SIMPLIFY_LABEL | \
1060         COMPILER_SIMPLIFY_BRANCH | \
1061         COMPILER_SIMPLIFY_COPY | \
1062         COMPILER_SIMPLIFY_ARITH | \
1063         COMPILER_SIMPLIFY_SHIFT | \
1064         COMPILER_SIMPLIFY_BITWISE | \
1065         COMPILER_SIMPLIFY_LOGICAL | \
1066         0 )
1067
1068 #define GLOBAL_SCOPE_DEPTH   1
1069 #define FUNCTION_SCOPE_DEPTH (GLOBAL_SCOPE_DEPTH + 1)
1070
1071 static void compile_file(struct compile_state *old_state, const char *filename, int local);
1072
1073
1074
1075 static void init_compiler_state(struct compiler_state *compiler)
1076 {
1077         memset(compiler, 0, sizeof(*compiler));
1078         compiler->label_prefix = "";
1079         compiler->ofilename = "auto.inc";
1080         compiler->flags = COMPILER_DEFAULT_FLAGS;
1081         compiler->debug = 0;
1082         compiler->max_allocation_passes = MAX_ALLOCATION_PASSES;
1083
1084 }
1085
1086 struct compiler_flag {
1087         const char *name;
1088         unsigned long flag;
1089 };
1090 static int set_flag(
1091         const struct compiler_flag *ptr, unsigned long *flags,
1092         int act, const char *flag)
1093 {
1094         int result = -1;
1095         for(; ptr->name; ptr++) {
1096                 if (strcmp(ptr->name, flag) == 0) {
1097                         break;
1098                 }
1099         }
1100         if (ptr->name) {
1101                 result = 0;
1102                 *flags &= ~(ptr->flag);
1103                 if (act) {
1104                         *flags |= ptr->flag;
1105                 }
1106         }
1107         return result;
1108 }
1109
1110 static int compiler_encode_flag(
1111         struct compiler_state *compiler, const char *flag)
1112 {
1113         static const struct compiler_flag flags[] = {
1114                 { "eliminate-inefectual-code", COMPILER_ELIMINATE_INEFECTUAL_CODE },
1115                 { "simplify",                  COMPILER_SIMPLIFY },
1116                 { "scc-transform",             COMPILER_SCC_TRANSFORM },
1117                 { "inline",                    COMPILER_INLINE },
1118                 { "always-inline",             COMPILER_ALWAYS_INLINE },
1119                 { "simplify-op",               COMPILER_SIMPLIFY_OP },
1120                 { "simplify-phi",              COMPILER_SIMPLIFY_PHI },
1121                 { "simplify-label",            COMPILER_SIMPLIFY_LABEL },
1122                 { "simplify-branch",           COMPILER_SIMPLIFY_BRANCH },
1123                 { "simplify-copy",             COMPILER_SIMPLIFY_COPY },
1124                 { "simplify-arith",            COMPILER_SIMPLIFY_ARITH },
1125                 { "simplify-shift",            COMPILER_SIMPLIFY_SHIFT },
1126                 { "simplify-bitwise",          COMPILER_SIMPLIFY_BITWISE },
1127                 { "simplify-logical",          COMPILER_SIMPLIFY_LOGICAL },
1128                 { 0, 0 },
1129         };
1130         static const struct compiler_flag opt_flags[] = {
1131                 { "-O",  COMPILER_SIMPLIFY },
1132                 { "-O2", COMPILER_SIMPLIFY | COMPILER_SCC_TRANSFORM },
1133                 { 0, 0, },
1134         };
1135         static const struct compiler_flag debug_flags[] = {
1136                 { "abort-on-error",        DEBUG_ABORT_ON_ERROR },
1137                 { "basic-blocks",          DEBUG_BASIC_BLOCKS },
1138                 { "fdominators",           DEBUG_FDOMINATORS },
1139                 { "rdominators",           DEBUG_RDOMINATORS },
1140                 { "triples",               DEBUG_TRIPLES },
1141                 { "interference",          DEBUG_INTERFERENCE },
1142                 { "scc-transform",         DEBUG_SCC_TRANSFORM },
1143                 { "scc-transform2",        DEBUG_SCC_TRANSFORM2 },
1144                 { "rebuild-ssa-form",      DEBUG_REBUILD_SSA_FORM },
1145                 { "inline",                DEBUG_INLINE },
1146                 { "live-range-conflicts",  DEBUG_RANGE_CONFLICTS },
1147                 { "live-range-conflicts2", DEBUG_RANGE_CONFLICTS2 },
1148                 { "color-graph",           DEBUG_COLOR_GRAPH },
1149                 { "color-graph2",          DEBUG_COLOR_GRAPH2 },
1150                 { "coalescing",            DEBUG_COALESCING },
1151                 { "coalescing2",           DEBUG_COALESCING2 },
1152                 { 0, 0 },
1153         };
1154         int act;
1155         int result;
1156
1157         act = 1;
1158         result = -1;
1159         if (strncmp(flag, "no-", 3) == 0) {
1160                 flag += 3;
1161                 act = 0;
1162         }
1163         if (strncmp(flag, "-O", 2) == 0) {
1164                 result = set_flag(opt_flags, &compiler->flags, act, flag);
1165         }
1166         else if (act && strncmp(flag, "label-prefix=", 13) == 0) {
1167                 result = 0;
1168                 compiler->label_prefix = flag + 13;
1169         }
1170         else if (act && strncmp(flag, "max-allocation-passes=", 22) == 0) {
1171                 unsigned long max_passes;
1172                 char *end;
1173                 max_passes = strtoul(flag + 22, &end, 10);
1174                 if (end[0] == '\0') {
1175                         result = 0;
1176                         compiler->max_allocation_passes = max_passes;
1177                 }
1178         }
1179         else if (act && strcmp(flag, "debug") == 0) {
1180                 result = 0;
1181                 compiler->debug |= DEBUG_DEFAULT;
1182         }
1183         else if (strncmp(flag, "debug-", 6) == 0) {
1184                 flag += 6;
1185                 result = set_flag(debug_flags, &compiler->debug, act, flag);
1186         }
1187         else {
1188                 result = set_flag(flags, &compiler->flags, act, flag);
1189         }
1190         return result;
1191 }
1192
1193 static void do_cleanup(struct compile_state *state)
1194 {
1195         if (state->output) {
1196                 fclose(state->output);
1197                 unlink(state->compiler->ofilename);
1198         }
1199 }
1200
1201 static int get_col(struct file_state *file)
1202 {
1203         int col;
1204         char *ptr, *end;
1205         ptr = file->line_start;
1206         end = file->pos;
1207         for(col = 0; ptr < end; ptr++) {
1208                 if (*ptr != '\t') {
1209                         col++;
1210                 } 
1211                 else {
1212                         col = (col & ~7) + 8;
1213                 }
1214         }
1215         return col;
1216 }
1217
1218 static void loc(FILE *fp, struct compile_state *state, struct triple *triple)
1219 {
1220         int col;
1221         if (triple && triple->occurance) {
1222                 struct occurance *spot;
1223                 for(spot = triple->occurance; spot; spot = spot->parent) {
1224                         fprintf(fp, "%s:%d.%d: ", 
1225                                 spot->filename, spot->line, spot->col);
1226                 }
1227                 return;
1228         }
1229         if (!state->file) {
1230                 return;
1231         }
1232         col = get_col(state->file);
1233         fprintf(fp, "%s:%d.%d: ", 
1234                 state->file->report_name, state->file->report_line, col);
1235 }
1236
1237 static void internal_error(struct compile_state *state, struct triple *ptr, 
1238         char *fmt, ...)
1239 {
1240         va_list args;
1241         va_start(args, fmt);
1242         loc(stderr, state, ptr);
1243         fputc('\n', stderr);
1244         if (ptr) {
1245                 fprintf(stderr, "%p %s ", ptr, tops(ptr->op));
1246         }
1247         fprintf(stderr, "Internal compiler error: ");
1248         vfprintf(stderr, fmt, args);
1249         fprintf(stderr, "\n");
1250         va_end(args);
1251         do_cleanup(state);
1252         abort();
1253 }
1254
1255
1256 static void internal_warning(struct compile_state *state, struct triple *ptr, 
1257         char *fmt, ...)
1258 {
1259         va_list args;
1260         va_start(args, fmt);
1261         loc(stderr, state, ptr);
1262         if (ptr) {
1263                 fprintf(stderr, "%p %s ", ptr, tops(ptr->op));
1264         }
1265         fprintf(stderr, "Internal compiler warning: ");
1266         vfprintf(stderr, fmt, args);
1267         fprintf(stderr, "\n");
1268         va_end(args);
1269 }
1270
1271
1272
1273 static void error(struct compile_state *state, struct triple *ptr, 
1274         char *fmt, ...)
1275 {
1276         va_list args;
1277         va_start(args, fmt);
1278         loc(stderr, state, ptr);
1279         fputc('\n', stderr);
1280         if (ptr && (state->compiler->debug & DEBUG_ABORT_ON_ERROR)) {
1281                 fprintf(stderr, "%p %s ", ptr, tops(ptr->op));
1282         }
1283         vfprintf(stderr, fmt, args);
1284         va_end(args);
1285         fprintf(stderr, "\n");
1286         do_cleanup(state);
1287         if (state->compiler->debug & DEBUG_ABORT_ON_ERROR) {
1288                 abort();
1289         }
1290         exit(1);
1291 }
1292
1293 static void warning(struct compile_state *state, struct triple *ptr, 
1294         char *fmt, ...)
1295 {
1296         va_list args;
1297         va_start(args, fmt);
1298         loc(stderr, state, ptr);
1299         fprintf(stderr, "warning: "); 
1300         vfprintf(stderr, fmt, args);
1301         fprintf(stderr, "\n");
1302         va_end(args);
1303 }
1304
1305 #define FINISHME() warning(state, 0, "FINISHME @ %s.%s:%d", __FILE__, __func__, __LINE__)
1306
1307 static void valid_op(struct compile_state *state, int op)
1308 {
1309         char *fmt = "invalid op: %d";
1310         if (op >= OP_MAX) {
1311                 internal_error(state, 0, fmt, op);
1312         }
1313         if (op < 0) {
1314                 internal_error(state, 0, fmt, op);
1315         }
1316 }
1317
1318 static void valid_ins(struct compile_state *state, struct triple *ptr)
1319 {
1320         valid_op(state, ptr->op);
1321 }
1322
1323 static void process_trigraphs(struct compile_state *state)
1324 {
1325         char *src, *dest, *end;
1326         struct file_state *file;
1327         file = state->file;
1328         src = dest = file->buf;
1329         end = file->buf + file->size;
1330         while((end - src) >= 3) {
1331                 if ((src[0] == '?') && (src[1] == '?')) {
1332                         int c = -1;
1333                         switch(src[2]) {
1334                         case '=': c = '#'; break;
1335                         case '/': c = '\\'; break;
1336                         case '\'': c = '^'; break;
1337                         case '(': c = '['; break;
1338                         case ')': c = ']'; break;
1339                         case '!': c = '!'; break;
1340                         case '<': c = '{'; break;
1341                         case '>': c = '}'; break;
1342                         case '-': c = '~'; break;
1343                         }
1344                         if (c != -1) {
1345                                 *dest++ = c;
1346                                 src += 3;
1347                         }
1348                         else {
1349                                 *dest++ = *src++;
1350                         }
1351                 }
1352                 else {
1353                         *dest++ = *src++;
1354                 }
1355         }
1356         while(src != end) {
1357                 *dest++ = *src++;
1358         }
1359         file->size = dest - file->buf;
1360 }
1361
1362 static void splice_lines(struct compile_state *state)
1363 {
1364         char *src, *dest, *end;
1365         struct file_state *file;
1366         file = state->file;
1367         src = dest = file->buf;
1368         end = file->buf + file->size;
1369         while((end - src) >= 2) {
1370                 if ((src[0] == '\\') && (src[1] == '\n')) {
1371                         src += 2;
1372                 }
1373                 else {
1374                         *dest++ = *src++;
1375                 }
1376         }
1377         while(src != end) {
1378                 *dest++ = *src++;
1379         }
1380         file->size = dest - file->buf;
1381 }
1382
1383 static struct type void_type;
1384 static void use_triple(struct triple *used, struct triple *user)
1385 {
1386         struct triple_set **ptr, *new;
1387         if (!used)
1388                 return;
1389         if (!user)
1390                 return;
1391         ptr = &used->use;
1392         while(*ptr) {
1393                 if ((*ptr)->member == user) {
1394                         return;
1395                 }
1396                 ptr = &(*ptr)->next;
1397         }
1398         /* Append new to the head of the list, 
1399          * copy_func and rename_block_variables
1400          * depends on this.
1401          */
1402         new = xcmalloc(sizeof(*new), "triple_set");
1403         new->member = user;
1404         new->next   = used->use;
1405         used->use   = new;
1406 }
1407
1408 static void unuse_triple(struct triple *used, struct triple *unuser)
1409 {
1410         struct triple_set *use, **ptr;
1411         if (!used) {
1412                 return;
1413         }
1414         ptr = &used->use;
1415         while(*ptr) {
1416                 use = *ptr;
1417                 if (use->member == unuser) {
1418                         *ptr = use->next;
1419                         xfree(use);
1420                 }
1421                 else {
1422                         ptr = &use->next;
1423                 }
1424         }
1425 }
1426
1427 static void put_occurance(struct occurance *occurance)
1428 {
1429         if (occurance) {
1430                 occurance->count -= 1;
1431                 if (occurance->count <= 0) {
1432                         if (occurance->parent) {
1433                                 put_occurance(occurance->parent);
1434                         }
1435                         xfree(occurance);
1436                 }
1437         }
1438 }
1439
1440 static void get_occurance(struct occurance *occurance)
1441 {
1442         if (occurance) {
1443                 occurance->count += 1;
1444         }
1445 }
1446
1447
1448 static struct occurance *new_occurance(struct compile_state *state)
1449 {
1450         struct occurance *result, *last;
1451         const char *filename;
1452         const char *function;
1453         int line, col;
1454
1455         function = "";
1456         filename = 0;
1457         line = 0;
1458         col  = 0;
1459         if (state->file) {
1460                 filename = state->file->report_name;
1461                 line     = state->file->report_line;
1462                 col      = get_col(state->file);
1463         }
1464         if (state->function) {
1465                 function = state->function;
1466         }
1467         last = state->last_occurance;
1468         if (last &&
1469                 (last->col == col) &&
1470                 (last->line == line) &&
1471                 (last->function == function) &&
1472                 ((last->filename == filename) ||
1473                         (strcmp(last->filename, filename) == 0))) 
1474         {
1475                 get_occurance(last);
1476                 return last;
1477         }
1478         if (last) {
1479                 state->last_occurance = 0;
1480                 put_occurance(last);
1481         }
1482         result = xmalloc(sizeof(*result), "occurance");
1483         result->count    = 2;
1484         result->filename = filename;
1485         result->function = function;
1486         result->line     = line;
1487         result->col      = col;
1488         result->parent   = 0;
1489         state->last_occurance = result;
1490         return result;
1491 }
1492
1493 static struct occurance *inline_occurance(struct compile_state *state,
1494         struct occurance *base, struct occurance *top)
1495 {
1496         struct occurance *result, *last;
1497         if (top->parent) {
1498                 internal_error(state, 0, "inlining an already inlined function?");
1499         }
1500         /* If I have a null base treat it that way */
1501         if ((base->parent == 0) &&
1502                 (base->col == 0) &&
1503                 (base->line == 0) &&
1504                 (base->function[0] == '\0') &&
1505                 (base->filename[0] == '\0')) {
1506                 base = 0;
1507         }
1508         /* See if I can reuse the last occurance I had */
1509         last = state->last_occurance;
1510         if (last &&
1511                 (last->parent   == base) &&
1512                 (last->col      == top->col) &&
1513                 (last->line     == top->line) &&
1514                 (last->function == top->function) &&
1515                 (last->filename == top->filename)) {
1516                 get_occurance(last);
1517                 return last;
1518         }
1519         /* I can't reuse the last occurance so free it */
1520         if (last) {
1521                 state->last_occurance = 0;
1522                 put_occurance(last);
1523         }
1524         /* Generate a new occurance structure */
1525         get_occurance(base);
1526         result = xmalloc(sizeof(*result), "occurance");
1527         result->count    = 2;
1528         result->filename = top->filename;
1529         result->function = top->function;
1530         result->line     = top->line;
1531         result->col      = top->col;
1532         result->parent   = base;
1533         state->last_occurance = result;
1534         return result;
1535 }
1536
1537 static struct occurance dummy_occurance = {
1538         .count    = 2,
1539         .filename = __FILE__,
1540         .function = "",
1541         .line     = __LINE__,
1542         .col      = 0,
1543         .parent   = 0,
1544 };
1545
1546 /* The zero triple is used as a place holder when we are removing pointers
1547  * from a triple.  Having allows certain sanity checks to pass even
1548  * when the original triple that was pointed to is gone.
1549  */
1550 static struct triple zero_triple = {
1551         .next      = &zero_triple,
1552         .prev      = &zero_triple,
1553         .use       = 0,
1554         .op        = OP_INTCONST,
1555         .sizes     = TRIPLE_SIZES(0, 0, 0, 0),
1556         .id        = -1, /* An invalid id */
1557         .u = { .cval = 0, },
1558         .occurance = &dummy_occurance,
1559         .param = { [0] = 0, [1] = 0, },
1560 };
1561
1562
1563 static unsigned short triple_sizes(struct compile_state *state,
1564         int op, struct type *type, int lhs_wanted, int rhs_wanted,
1565         struct occurance *occurance)
1566 {
1567         int lhs, rhs, misc, targ;
1568         struct triple dummy;
1569         dummy.op = op;
1570         dummy.occurance = occurance;
1571         valid_op(state, op);
1572         lhs = table_ops[op].lhs;
1573         rhs = table_ops[op].rhs;
1574         misc = table_ops[op].misc;
1575         targ = table_ops[op].targ;
1576         
1577         
1578         if (op == OP_FCALL) {
1579                 rhs = rhs_wanted;
1580                 lhs = 0;
1581                 if ((type->type & TYPE_MASK) == TYPE_STRUCT) {
1582                         lhs = type->left->elements;
1583                 }
1584         }
1585         else if (op == OP_VAL_VEC) {
1586                 rhs = type->elements;
1587         }
1588         else if (op == OP_PHI) {
1589                 rhs = rhs_wanted;
1590         }
1591         else if (op == OP_ASM) {
1592                 rhs = rhs_wanted;
1593                 lhs = lhs_wanted;
1594         }
1595         if ((rhs < 0) || (rhs > MAX_RHS)) {
1596                 internal_error(state, &dummy, "bad rhs %d", rhs);
1597         }
1598         if ((lhs < 0) || (lhs > MAX_LHS)) {
1599                 internal_error(state, &dummy, "bad lhs");
1600         }
1601         if ((misc < 0) || (misc > MAX_MISC)) {
1602                 internal_error(state, &dummy, "bad misc");
1603         }
1604         if ((targ < 0) || (targ > MAX_TARG)) {
1605                 internal_error(state, &dummy, "bad targs");
1606         }
1607         return TRIPLE_SIZES(lhs, rhs, misc, targ);
1608 }
1609
1610 static struct triple *alloc_triple(struct compile_state *state, 
1611         int op, struct type *type, int lhs, int rhs,
1612         struct occurance *occurance)
1613 {
1614         size_t size, sizes, extra_count, min_count;
1615         struct triple *ret;
1616         sizes = triple_sizes(state, op, type, lhs, rhs, occurance);
1617
1618         min_count = sizeof(ret->param)/sizeof(ret->param[0]);
1619         extra_count = TRIPLE_SIZE(sizes);
1620         extra_count = (extra_count < min_count)? 0 : extra_count - min_count;
1621
1622         size = sizeof(*ret) + sizeof(ret->param[0]) * extra_count;
1623         ret = xcmalloc(size, "tripple");
1624         ret->op        = op;
1625         ret->sizes     = sizes;
1626         ret->type      = type;
1627         ret->next      = ret;
1628         ret->prev      = ret;
1629         ret->occurance = occurance;
1630         return ret;
1631 }
1632
1633 struct triple *dup_triple(struct compile_state *state, struct triple *src)
1634 {
1635         struct triple *dup;
1636         int src_lhs, src_rhs, src_size;
1637         src_lhs = TRIPLE_LHS(src->sizes);
1638         src_rhs = TRIPLE_RHS(src->sizes);
1639         src_size = TRIPLE_SIZE(src->sizes);
1640         get_occurance(src->occurance);
1641         dup = alloc_triple(state, src->op, src->type, src_lhs, src_rhs,
1642                 src->occurance);
1643         memcpy(dup, src, sizeof(*src));
1644         memcpy(dup->param, src->param, src_size * sizeof(src->param[0]));
1645         return dup;
1646 }
1647
1648 static struct triple *new_triple(struct compile_state *state, 
1649         int op, struct type *type, int lhs, int rhs)
1650 {
1651         struct triple *ret;
1652         struct occurance *occurance;
1653         occurance = new_occurance(state);
1654         ret = alloc_triple(state, op, type, lhs, rhs, occurance);
1655         return ret;
1656 }
1657
1658 static struct triple *build_triple(struct compile_state *state, 
1659         int op, struct type *type, struct triple *left, struct triple *right,
1660         struct occurance *occurance)
1661 {
1662         struct triple *ret;
1663         size_t count;
1664         ret = alloc_triple(state, op, type, -1, -1, occurance);
1665         count = TRIPLE_SIZE(ret->sizes);
1666         if (count > 0) {
1667                 ret->param[0] = left;
1668         }
1669         if (count > 1) {
1670                 ret->param[1] = right;
1671         }
1672         return ret;
1673 }
1674
1675 static struct triple *triple(struct compile_state *state, 
1676         int op, struct type *type, struct triple *left, struct triple *right)
1677 {
1678         struct triple *ret;
1679         size_t count;
1680         ret = new_triple(state, op, type, -1, -1);
1681         count = TRIPLE_SIZE(ret->sizes);
1682         if (count >= 1) {
1683                 ret->param[0] = left;
1684         }
1685         if (count >= 2) {
1686                 ret->param[1] = right;
1687         }
1688         return ret;
1689 }
1690
1691 static struct triple *branch(struct compile_state *state, 
1692         struct triple *targ, struct triple *test)
1693 {
1694         struct triple *ret;
1695         if (test) {
1696                 ret = new_triple(state, OP_CBRANCH, &void_type, -1, 1);
1697                 RHS(ret, 0) = test;
1698         } else {
1699                 ret = new_triple(state, OP_BRANCH, &void_type, -1, 0);
1700         }
1701         TARG(ret, 0) = targ;
1702         /* record the branch target was used */
1703         if (!targ || (targ->op != OP_LABEL)) {
1704                 internal_error(state, 0, "branch not to label");
1705         }
1706         return ret;
1707 }
1708
1709 static void insert_triple(struct compile_state *state,
1710         struct triple *first, struct triple *ptr)
1711 {
1712         if (ptr) {
1713                 if ((ptr->id & TRIPLE_FLAG_FLATTENED) || (ptr->next != ptr)) {
1714                         internal_error(state, ptr, "expression already used");
1715                 }
1716                 ptr->next       = first;
1717                 ptr->prev       = first->prev;
1718                 ptr->prev->next = ptr;
1719                 ptr->next->prev = ptr;
1720                 
1721                 if ((ptr->prev->op == OP_CBRANCH) || (ptr->prev->op == OP_CALL)) {
1722                         unuse_triple(first, ptr->prev);
1723                         use_triple(ptr, ptr->prev);
1724                 }
1725         }
1726 }
1727
1728 static int triple_stores_block(struct compile_state *state, struct triple *ins)
1729 {
1730         /* This function is used to determine if u.block 
1731          * is utilized to store the current block number.
1732          */
1733         int stores_block;
1734         valid_ins(state, ins);
1735         stores_block = (table_ops[ins->op].flags & BLOCK) == BLOCK;
1736         return stores_block;
1737 }
1738
1739 static struct block *block_of_triple(struct compile_state *state, 
1740         struct triple *ins)
1741 {
1742         struct triple *first;
1743         if (!ins || ins == &zero_triple) {
1744                 return 0;
1745         }
1746         first = state->first;
1747         while(ins != first && !triple_stores_block(state, ins)) {
1748                 if (ins == ins->prev) {
1749                         internal_error(state, ins, "ins == ins->prev?");
1750                 }
1751                 ins = ins->prev;
1752         }
1753         if (!triple_stores_block(state, ins)) {
1754                 internal_error(state, ins, "Cannot find block");
1755         }
1756         return ins->u.block;
1757 }
1758
1759 static struct triple *pre_triple(struct compile_state *state,
1760         struct triple *base,
1761         int op, struct type *type, struct triple *left, struct triple *right)
1762 {
1763         struct block *block;
1764         struct triple *ret;
1765         /* If I am an OP_PIECE jump to the real instruction */
1766         if (base->op == OP_PIECE) {
1767                 base = MISC(base, 0);
1768         }
1769         block = block_of_triple(state, base);
1770         get_occurance(base->occurance);
1771         ret = build_triple(state, op, type, left, right, base->occurance);
1772         if (triple_stores_block(state, ret)) {
1773                 ret->u.block = block;
1774         }
1775         insert_triple(state, base, ret);
1776         if (block->first == base) {
1777                 block->first = ret;
1778         }
1779         return ret;
1780 }
1781
1782 static struct triple *post_triple(struct compile_state *state,
1783         struct triple *base,
1784         int op, struct type *type, struct triple *left, struct triple *right)
1785 {
1786         struct block *block;
1787         struct triple *ret;
1788         int zlhs;
1789         /* If I am an OP_PIECE jump to the real instruction */
1790         if (base->op == OP_PIECE) {
1791                 base = MISC(base, 0);
1792         }
1793         /* If I have a left hand side skip over it */
1794         zlhs = TRIPLE_LHS(base->sizes);
1795         if (zlhs) {
1796                 base = LHS(base, zlhs - 1);
1797         }
1798
1799         block = block_of_triple(state, base);
1800         get_occurance(base->occurance);
1801         ret = build_triple(state, op, type, left, right, base->occurance);
1802         if (triple_stores_block(state, ret)) {
1803                 ret->u.block = block;
1804         }
1805         insert_triple(state, base->next, ret);
1806         if (block->last == base) {
1807                 block->last = ret;
1808         }
1809         return ret;
1810 }
1811
1812 static struct triple *label(struct compile_state *state)
1813 {
1814         /* Labels don't get a type */
1815         struct triple *result;
1816         result = triple(state, OP_LABEL, &void_type, 0, 0);
1817         return result;
1818 }
1819
1820 static void display_triple(FILE *fp, struct triple *ins)
1821 {
1822         struct occurance *ptr;
1823         const char *reg;
1824         char pre, post;
1825         pre = post = ' ';
1826         if (ins->id & TRIPLE_FLAG_PRE_SPLIT) {
1827                 pre = '^';
1828         }
1829         if (ins->id & TRIPLE_FLAG_POST_SPLIT) {
1830                 post = 'v';
1831         }
1832         reg = arch_reg_str(ID_REG(ins->id));
1833         if (ins->op == OP_INTCONST) {
1834                 fprintf(fp, "(%p) %c%c %-7s %-2d %-10s <0x%08lx>         ",
1835                         ins, pre, post, reg, ins->template_id, tops(ins->op), 
1836                         (unsigned long)(ins->u.cval));
1837         }
1838         else if (ins->op == OP_ADDRCONST) {
1839                 fprintf(fp, "(%p) %c%c %-7s %-2d %-10s %-10p <0x%08lx>",
1840                         ins, pre, post, reg, ins->template_id, tops(ins->op), 
1841                         MISC(ins, 0), (unsigned long)(ins->u.cval));
1842         }
1843         else {
1844                 int i, count;
1845                 fprintf(fp, "(%p) %c%c %-7s %-2d %-10s", 
1846                         ins, pre, post, reg, ins->template_id, tops(ins->op));
1847                 count = TRIPLE_SIZE(ins->sizes);
1848                 for(i = 0; i < count; i++) {
1849                         fprintf(fp, " %-10p", ins->param[i]);
1850                 }
1851                 for(; i < 2; i++) {
1852                         fprintf(fp, "           ");
1853                 }
1854         }
1855         fprintf(fp, " @");
1856         for(ptr = ins->occurance; ptr; ptr = ptr->parent) {
1857                 fprintf(fp, " %s,%s:%d.%d",
1858                         ptr->function, 
1859                         ptr->filename,
1860                         ptr->line, 
1861                         ptr->col);
1862         }
1863         fprintf(fp, "\n");
1864 #if 0
1865         {
1866                 struct triple_set *user;
1867                 for(user = ptr->use; user; user = user->next) {
1868                         fprintf(fp, "use: %p\n", user->member);
1869                 }
1870         }
1871 #endif
1872         fflush(fp);
1873 }
1874
1875 static void display_triple_changes(
1876         FILE *fp, const struct triple *new, const struct triple *orig)
1877 {
1878
1879         int new_count, orig_count;
1880         new_count = TRIPLE_SIZE(new->sizes);
1881         orig_count = TRIPLE_SIZE(orig->sizes);
1882         if ((new->op != orig->op) ||
1883                 (new_count != orig_count) ||
1884                 (memcmp(orig->param, new->param,        
1885                         orig_count * sizeof(orig->param[0])) != 0) ||
1886                 (memcmp(&orig->u, &new->u, sizeof(orig->u)) != 0)) 
1887         {
1888                 struct occurance *ptr;
1889                 int i, min_count, indent;
1890                 fprintf(fp, "(%p)", orig);
1891                 if (orig->op == new->op) {
1892                         fprintf(fp, " %-11s", tops(orig->op));
1893                 } else {
1894                         fprintf(fp, " [%-10s %-10s]", 
1895                                 tops(new->op), tops(orig->op));
1896                 }
1897                 min_count = new_count;
1898                 if (min_count > orig_count) {
1899                         min_count = orig_count;
1900                 }
1901                 for(indent = i = 0; i < min_count; i++) {
1902                         if (orig->param[i] == new->param[i]) {
1903                                 fprintf(fp, " %-11p", 
1904                                         orig->param[i]);
1905                                 indent += 12;
1906                         } else {
1907                                 fprintf(fp, " [%-10p %-10p]",
1908                                         new->param[i], 
1909                                         orig->param[i]);
1910                                 indent += 24;
1911                         }
1912                 }
1913                 for(; i < orig_count; i++) {
1914                         fprintf(fp, " [%-9p]", orig->param[i]);
1915                         indent += 12;
1916                 }
1917                 for(; i < new_count; i++) {
1918                         fprintf(fp, " [%-9p]", new->param[i]);
1919                         indent += 12;
1920                 }
1921                 if ((new->op == OP_INTCONST)||
1922                         (new->op == OP_ADDRCONST)) {
1923                         fprintf(fp, " <0x%08lx>", 
1924                                 (unsigned long)(new->u.cval));
1925                         indent += 13;
1926                 }
1927                 for(;indent < 36; indent++) {
1928                         putc(' ', fp);
1929                 }
1930                 fprintf(fp, " @");
1931                 for(ptr = orig->occurance; ptr; ptr = ptr->parent) {
1932                         fprintf(fp, " %s,%s:%d.%d",
1933                                 ptr->function, 
1934                                 ptr->filename,
1935                                 ptr->line, 
1936                                 ptr->col);
1937                         
1938                 }
1939                 fprintf(fp, "\n");
1940                 fflush(fp);
1941         }
1942 }
1943
1944 static void display_func(FILE *fp, struct triple *func)
1945 {
1946         struct triple *first, *ins;
1947         fprintf(fp, "display_func %s\n", func->type->type_ident->name);
1948         first = ins = RHS(func, 0);
1949         do {
1950                 display_triple(fp, ins);
1951                 ins = ins->next;
1952         } while(ins != first);
1953 }
1954
1955 static int triple_is_pure(struct compile_state *state, struct triple *ins, unsigned id)
1956 {
1957         /* Does the triple have no side effects.
1958          * I.e. Rexecuting the triple with the same arguments 
1959          * gives the same value.
1960          */
1961         unsigned pure;
1962         valid_ins(state, ins);
1963         pure = PURE_BITS(table_ops[ins->op].flags);
1964         if ((pure != PURE) && (pure != IMPURE)) {
1965                 internal_error(state, 0, "Purity of %s not known\n",
1966                         tops(ins->op));
1967         }
1968         return (pure == PURE) && !(id & TRIPLE_FLAG_VOLATILE);
1969 }
1970
1971 static int triple_is_branch(struct compile_state *state, struct triple *ins)
1972 {
1973         /* Is this triple a branch instruction? */
1974         valid_ins(state, ins);
1975         return (table_ops[ins->op].flags & BRANCH) != 0;
1976 }
1977
1978 static int triple_is_cond_branch(struct compile_state *state, struct triple *ins)
1979 {
1980         /* Is this triple a conditional branch instruction? */
1981         valid_ins(state, ins);
1982         return (table_ops[ins->op].flags & CBRANCH) != 0;
1983 }
1984
1985 static int triple_is_uncond_branch(struct compile_state *state, struct triple *ins)
1986 {
1987         /* Is this triple a unconditional branch instruction? */
1988         valid_ins(state, ins);
1989         return (table_ops[ins->op].flags & CBRANCH) == 0;
1990 }
1991
1992 static int triple_is_def(struct compile_state *state, struct triple *ins)
1993 {
1994         /* This function is used to determine which triples need
1995          * a register.
1996          */
1997         int is_def;
1998         valid_ins(state, ins);
1999         is_def = (table_ops[ins->op].flags & DEF) == DEF;
2000         return is_def;
2001 }
2002
2003 static int triple_is_structural(struct compile_state *state, struct triple *ins)
2004 {
2005         int is_structural;
2006         valid_ins(state, ins);
2007         is_structural = (table_ops[ins->op].flags & STRUCTURAL) == STRUCTURAL;
2008         return is_structural;
2009 }
2010
2011 static struct triple **triple_iter(struct compile_state *state,
2012         size_t count, struct triple **vector,
2013         struct triple *ins, struct triple **last)
2014 {
2015         struct triple **ret;
2016         ret = 0;
2017         if (count) {
2018                 if (!last) {
2019                         ret = vector;
2020                 }
2021                 else if ((last >= vector) && (last < (vector + count - 1))) {
2022                         ret = last + 1;
2023                 }
2024         }
2025         return ret;
2026         
2027 }
2028
2029 static struct triple **triple_lhs(struct compile_state *state,
2030         struct triple *ins, struct triple **last)
2031 {
2032         return triple_iter(state, TRIPLE_LHS(ins->sizes), &LHS(ins,0), 
2033                 ins, last);
2034 }
2035
2036 static struct triple **triple_rhs(struct compile_state *state,
2037         struct triple *ins, struct triple **last)
2038 {
2039         return triple_iter(state, TRIPLE_RHS(ins->sizes), &RHS(ins,0), 
2040                 ins, last);
2041 }
2042
2043 static struct triple **triple_misc(struct compile_state *state,
2044         struct triple *ins, struct triple **last)
2045 {
2046         return triple_iter(state, TRIPLE_MISC(ins->sizes), &MISC(ins,0), 
2047                 ins, last);
2048 }
2049
2050 static struct triple **triple_targ(struct compile_state *state,
2051         struct triple *ins, struct triple **last)
2052 {
2053         size_t count;
2054         struct triple **ret, **vector;
2055         ret = 0;
2056         count = TRIPLE_TARG(ins->sizes);
2057         vector = &TARG(ins, 0);
2058         if (!ret && 
2059                 ((ins->op == OP_CALL) || (table_ops[ins->op].flags & CBRANCH))) {
2060                 if (!last) {
2061                         ret = &ins->next;
2062                 } else if (last == &ins->next) {
2063                         last = 0;
2064                 }
2065         }
2066         if (!ret && count) {
2067                 if (!last) {
2068                         ret = vector;
2069                 }
2070                 else if ((last >= vector) && (last < (vector + count - 1))) {
2071                         ret = last + 1;
2072                 }
2073                 else if (last == vector + count - 1) {
2074                         last = 0;
2075                 }
2076         }
2077         if (!ret && (ins->op == OP_RET)) {
2078                 struct triple_set *use;
2079                 for(use = ins->use; use; use = use->next) {
2080                         if (use->member->op != OP_CALL) {
2081                                 continue;
2082                         }
2083                         if (!last) {
2084                                 ret = &use->member->next;
2085                                 break;
2086                         }
2087                         else if (last == &use->member->next) {
2088                                 last = 0;
2089                         }
2090                 }
2091         }
2092         return ret;
2093 }
2094
2095 static void verify_use(struct compile_state *state,
2096         struct triple *user, struct triple *used)
2097 {
2098         int size, i;
2099         size = TRIPLE_SIZE(user->sizes);
2100         for(i = 0; i < size; i++) {
2101                 if (user->param[i] == used) {
2102                         break;
2103                 }
2104         }
2105         if (triple_is_branch(state, user)) {
2106                 if (user->next == used) {
2107                         i = -1;
2108                 }
2109         }
2110         if (i == size) {
2111                 internal_error(state, user, "%s(%p) does not use %s(%p)",
2112                         tops(user->op), user, tops(used->op), used);
2113         }
2114 }
2115
2116 static int find_rhs_use(struct compile_state *state, 
2117         struct triple *user, struct triple *used)
2118 {
2119         struct triple **param;
2120         int size, i;
2121         verify_use(state, user, used);
2122         size = TRIPLE_RHS(user->sizes);
2123         param = &RHS(user, 0);
2124         for(i = 0; i < size; i++) {
2125                 if (param[i] == used) {
2126                         return i;
2127                 }
2128         }
2129         return -1;
2130 }
2131
2132 static void free_triple(struct compile_state *state, struct triple *ptr)
2133 {
2134         size_t size;
2135         size = sizeof(*ptr) - sizeof(ptr->param) +
2136                 (sizeof(ptr->param[0])*TRIPLE_SIZE(ptr->sizes));
2137         ptr->prev->next = ptr->next;
2138         ptr->next->prev = ptr->prev;
2139         if (ptr->use) {
2140                 internal_error(state, ptr, "ptr->use != 0");
2141         }
2142         put_occurance(ptr->occurance);
2143         memset(ptr, -1, size);
2144         xfree(ptr);
2145 }
2146
2147 static void release_triple(struct compile_state *state, struct triple *ptr)
2148 {
2149         struct triple_set *set, *next;
2150         struct triple **expr;
2151         struct block *block;
2152         valid_ins(state, ptr);
2153         /* Make certain the we are not the first or last element of a block */
2154         block = block_of_triple(state, ptr);
2155         if (block) {
2156                 if ((block->last == ptr) && (block->first == ptr)) {
2157                         block->last = block->first = 0;
2158                 }
2159                 else if (block->last == ptr) {
2160                         block->last = ptr->prev;
2161                 }
2162                 else if (block->first == ptr) {
2163                         block->first = ptr->next;
2164                 }
2165         }
2166         /* Remove ptr from use chains where it is the user */
2167         expr = triple_rhs(state, ptr, 0);
2168         for(; expr; expr = triple_rhs(state, ptr, expr)) {
2169                 if (*expr) {
2170                         unuse_triple(*expr, ptr);
2171                 }
2172         }
2173         expr = triple_lhs(state, ptr, 0);
2174         for(; expr; expr = triple_lhs(state, ptr, expr)) {
2175                 if (*expr) {
2176                         unuse_triple(*expr, ptr);
2177                 }
2178         }
2179         expr = triple_misc(state, ptr, 0);
2180         for(; expr; expr = triple_misc(state, ptr, expr)) {
2181                 if (*expr) {
2182                         unuse_triple(*expr, ptr);
2183                 }
2184         }
2185         expr = triple_targ(state, ptr, 0);
2186         for(; expr; expr = triple_targ(state, ptr, expr)) {
2187                 if (*expr){
2188                         unuse_triple(*expr, ptr);
2189                 }
2190         }
2191         /* Reomve ptr from use chains where it is used */
2192         for(set = ptr->use; set; set = next) {
2193                 next = set->next;
2194                 valid_ins(state, set->member);
2195                 expr = triple_rhs(state, set->member, 0);
2196                 for(; expr; expr = triple_rhs(state, set->member, expr)) {
2197                         if (*expr == ptr) {
2198                                 *expr = &zero_triple;
2199                         }
2200                 }
2201                 expr = triple_lhs(state, set->member, 0);
2202                 for(; expr; expr = triple_lhs(state, set->member, expr)) {
2203                         if (*expr == ptr) {
2204                                 *expr = &zero_triple;
2205                         }
2206                 }
2207                 expr = triple_misc(state, set->member, 0);
2208                 for(; expr; expr = triple_misc(state, set->member, expr)) {
2209                         if (*expr == ptr) {
2210                                 *expr = &zero_triple;
2211                         }
2212                 }
2213                 expr = triple_targ(state, set->member, 0);
2214                 for(; expr; expr = triple_targ(state, set->member, expr)) {
2215                         if (*expr == ptr) {
2216                                 *expr = &zero_triple;
2217                         }
2218                 }
2219                 unuse_triple(ptr, set->member);
2220         }
2221         free_triple(state, ptr);
2222 }
2223
2224 static void print_triples(struct compile_state *state);
2225 static void print_blocks(struct compile_state *state, const char *func, FILE *fp);
2226
2227 #define TOK_UNKNOWN     0
2228 #define TOK_SPACE       1
2229 #define TOK_SEMI        2
2230 #define TOK_LBRACE      3
2231 #define TOK_RBRACE      4
2232 #define TOK_COMMA       5
2233 #define TOK_EQ          6
2234 #define TOK_COLON       7
2235 #define TOK_LBRACKET    8
2236 #define TOK_RBRACKET    9
2237 #define TOK_LPAREN      10
2238 #define TOK_RPAREN      11
2239 #define TOK_STAR        12
2240 #define TOK_DOTS        13
2241 #define TOK_MORE        14
2242 #define TOK_LESS        15
2243 #define TOK_TIMESEQ     16
2244 #define TOK_DIVEQ       17
2245 #define TOK_MODEQ       18
2246 #define TOK_PLUSEQ      19
2247 #define TOK_MINUSEQ     20
2248 #define TOK_SLEQ        21
2249 #define TOK_SREQ        22
2250 #define TOK_ANDEQ       23
2251 #define TOK_XOREQ       24
2252 #define TOK_OREQ        25
2253 #define TOK_EQEQ        26
2254 #define TOK_NOTEQ       27
2255 #define TOK_QUEST       28
2256 #define TOK_LOGOR       29
2257 #define TOK_LOGAND      30
2258 #define TOK_OR          31
2259 #define TOK_AND         32
2260 #define TOK_XOR         33
2261 #define TOK_LESSEQ      34
2262 #define TOK_MOREEQ      35
2263 #define TOK_SL          36
2264 #define TOK_SR          37
2265 #define TOK_PLUS        38
2266 #define TOK_MINUS       39
2267 #define TOK_DIV         40
2268 #define TOK_MOD         41
2269 #define TOK_PLUSPLUS    42
2270 #define TOK_MINUSMINUS  43
2271 #define TOK_BANG        44
2272 #define TOK_ARROW       45
2273 #define TOK_DOT         46
2274 #define TOK_TILDE       47
2275 #define TOK_LIT_STRING  48
2276 #define TOK_LIT_CHAR    49
2277 #define TOK_LIT_INT     50
2278 #define TOK_LIT_FLOAT   51
2279 #define TOK_MACRO       52
2280 #define TOK_CONCATENATE 53
2281
2282 #define TOK_IDENT       54
2283 #define TOK_STRUCT_NAME 55
2284 #define TOK_ENUM_CONST  56
2285 #define TOK_TYPE_NAME   57
2286
2287 #define TOK_AUTO        58
2288 #define TOK_BREAK       59
2289 #define TOK_CASE        60
2290 #define TOK_CHAR        61
2291 #define TOK_CONST       62
2292 #define TOK_CONTINUE    63
2293 #define TOK_DEFAULT     64
2294 #define TOK_DO          65
2295 #define TOK_DOUBLE      66
2296 #define TOK_ELSE        67
2297 #define TOK_ENUM        68
2298 #define TOK_EXTERN      69
2299 #define TOK_FLOAT       70
2300 #define TOK_FOR         71
2301 #define TOK_GOTO        72
2302 #define TOK_IF          73
2303 #define TOK_INLINE      74
2304 #define TOK_INT         75
2305 #define TOK_LONG        76
2306 #define TOK_REGISTER    77
2307 #define TOK_RESTRICT    78
2308 #define TOK_RETURN      79
2309 #define TOK_SHORT       80
2310 #define TOK_SIGNED      81
2311 #define TOK_SIZEOF      82
2312 #define TOK_STATIC      83
2313 #define TOK_STRUCT      84
2314 #define TOK_SWITCH      85
2315 #define TOK_TYPEDEF     86
2316 #define TOK_UNION       87
2317 #define TOK_UNSIGNED    88
2318 #define TOK_VOID        89
2319 #define TOK_VOLATILE    90
2320 #define TOK_WHILE       91
2321 #define TOK_ASM         92
2322 #define TOK_ATTRIBUTE   93
2323 #define TOK_ALIGNOF     94
2324 #define TOK_FIRST_KEYWORD TOK_AUTO
2325 #define TOK_LAST_KEYWORD  TOK_ALIGNOF
2326
2327 #define TOK_DEFINE      100
2328 #define TOK_UNDEF       101
2329 #define TOK_INCLUDE     102
2330 #define TOK_LINE        103
2331 #define TOK_ERROR       104
2332 #define TOK_WARNING     105
2333 #define TOK_PRAGMA      106
2334 #define TOK_IFDEF       107
2335 #define TOK_IFNDEF      108
2336 #define TOK_ELIF        109
2337 #define TOK_ENDIF       110
2338
2339 #define TOK_FIRST_MACRO TOK_DEFINE
2340 #define TOK_LAST_MACRO  TOK_ENDIF
2341          
2342 #define TOK_EOF         111
2343
2344 static const char *tokens[] = {
2345 [TOK_UNKNOWN     ] = "unknown",
2346 [TOK_SPACE       ] = ":space:",
2347 [TOK_SEMI        ] = ";",
2348 [TOK_LBRACE      ] = "{",
2349 [TOK_RBRACE      ] = "}",
2350 [TOK_COMMA       ] = ",",
2351 [TOK_EQ          ] = "=",
2352 [TOK_COLON       ] = ":",
2353 [TOK_LBRACKET    ] = "[",
2354 [TOK_RBRACKET    ] = "]",
2355 [TOK_LPAREN      ] = "(",
2356 [TOK_RPAREN      ] = ")",
2357 [TOK_STAR        ] = "*",
2358 [TOK_DOTS        ] = "...",
2359 [TOK_MORE        ] = ">",
2360 [TOK_LESS        ] = "<",
2361 [TOK_TIMESEQ     ] = "*=",
2362 [TOK_DIVEQ       ] = "/=",
2363 [TOK_MODEQ       ] = "%=",
2364 [TOK_PLUSEQ      ] = "+=",
2365 [TOK_MINUSEQ     ] = "-=",
2366 [TOK_SLEQ        ] = "<<=",
2367 [TOK_SREQ        ] = ">>=",
2368 [TOK_ANDEQ       ] = "&=",
2369 [TOK_XOREQ       ] = "^=",
2370 [TOK_OREQ        ] = "|=",
2371 [TOK_EQEQ        ] = "==",
2372 [TOK_NOTEQ       ] = "!=",
2373 [TOK_QUEST       ] = "?",
2374 [TOK_LOGOR       ] = "||",
2375 [TOK_LOGAND      ] = "&&",
2376 [TOK_OR          ] = "|",
2377 [TOK_AND         ] = "&",
2378 [TOK_XOR         ] = "^",
2379 [TOK_LESSEQ      ] = "<=",
2380 [TOK_MOREEQ      ] = ">=",
2381 [TOK_SL          ] = "<<",
2382 [TOK_SR          ] = ">>",
2383 [TOK_PLUS        ] = "+",
2384 [TOK_MINUS       ] = "-",
2385 [TOK_DIV         ] = "/",
2386 [TOK_MOD         ] = "%",
2387 [TOK_PLUSPLUS    ] = "++",
2388 [TOK_MINUSMINUS  ] = "--",
2389 [TOK_BANG        ] = "!",
2390 [TOK_ARROW       ] = "->",
2391 [TOK_DOT         ] = ".",
2392 [TOK_TILDE       ] = "~",
2393 [TOK_LIT_STRING  ] = ":string:",
2394 [TOK_IDENT       ] = ":ident:",
2395 [TOK_TYPE_NAME   ] = ":typename:",
2396 [TOK_LIT_CHAR    ] = ":char:",
2397 [TOK_LIT_INT     ] = ":integer:",
2398 [TOK_LIT_FLOAT   ] = ":float:",
2399 [TOK_MACRO       ] = "#",
2400 [TOK_CONCATENATE ] = "##",
2401
2402 [TOK_AUTO        ] = "auto",
2403 [TOK_BREAK       ] = "break",
2404 [TOK_CASE        ] = "case",
2405 [TOK_CHAR        ] = "char",
2406 [TOK_CONST       ] = "const",
2407 [TOK_CONTINUE    ] = "continue",
2408 [TOK_DEFAULT     ] = "default",
2409 [TOK_DO          ] = "do",
2410 [TOK_DOUBLE      ] = "double",
2411 [TOK_ELSE        ] = "else",
2412 [TOK_ENUM        ] = "enum",
2413 [TOK_EXTERN      ] = "extern",
2414 [TOK_FLOAT       ] = "float",
2415 [TOK_FOR         ] = "for",
2416 [TOK_GOTO        ] = "goto",
2417 [TOK_IF          ] = "if",
2418 [TOK_INLINE      ] = "inline",
2419 [TOK_INT         ] = "int",
2420 [TOK_LONG        ] = "long",
2421 [TOK_REGISTER    ] = "register",
2422 [TOK_RESTRICT    ] = "restrict",
2423 [TOK_RETURN      ] = "return",
2424 [TOK_SHORT       ] = "short",
2425 [TOK_SIGNED      ] = "signed",
2426 [TOK_SIZEOF      ] = "sizeof",
2427 [TOK_STATIC      ] = "static",
2428 [TOK_STRUCT      ] = "struct",
2429 [TOK_SWITCH      ] = "switch",
2430 [TOK_TYPEDEF     ] = "typedef",
2431 [TOK_UNION       ] = "union",
2432 [TOK_UNSIGNED    ] = "unsigned",
2433 [TOK_VOID        ] = "void",
2434 [TOK_VOLATILE    ] = "volatile",
2435 [TOK_WHILE       ] = "while",
2436 [TOK_ASM         ] = "asm",
2437 [TOK_ATTRIBUTE   ] = "__attribute__",
2438 [TOK_ALIGNOF     ] = "__alignof__",
2439
2440 [TOK_DEFINE      ] = "define",
2441 [TOK_UNDEF       ] = "undef",
2442 [TOK_INCLUDE     ] = "include",
2443 [TOK_LINE        ] = "line",
2444 [TOK_ERROR       ] = "error",
2445 [TOK_WARNING     ] = "warning",
2446 [TOK_PRAGMA      ] = "pragma",
2447 [TOK_IFDEF       ] = "ifdef",
2448 [TOK_IFNDEF      ] = "ifndef",
2449 [TOK_ELIF        ] = "elif",
2450 [TOK_ENDIF       ] = "endif",
2451
2452 [TOK_EOF         ] = "EOF",
2453 };
2454
2455 static unsigned int hash(const char *str, int str_len)
2456 {
2457         unsigned int hash;
2458         const char *end;
2459         end = str + str_len;
2460         hash = 0;
2461         for(; str < end; str++) {
2462                 hash = (hash *263) + *str;
2463         }
2464         hash = hash & (HASH_TABLE_SIZE -1);
2465         return hash;
2466 }
2467
2468 static struct hash_entry *lookup(
2469         struct compile_state *state, const char *name, int name_len)
2470 {
2471         struct hash_entry *entry;
2472         unsigned int index;
2473         index = hash(name, name_len);
2474         entry = state->hash_table[index];
2475         while(entry && 
2476                 ((entry->name_len != name_len) ||
2477                         (memcmp(entry->name, name, name_len) != 0))) {
2478                 entry = entry->next;
2479         }
2480         if (!entry) {
2481                 char *new_name;
2482                 /* Get a private copy of the name */
2483                 new_name = xmalloc(name_len + 1, "hash_name");
2484                 memcpy(new_name, name, name_len);
2485                 new_name[name_len] = '\0';
2486
2487                 /* Create a new hash entry */
2488                 entry = xcmalloc(sizeof(*entry), "hash_entry");
2489                 entry->next = state->hash_table[index];
2490                 entry->name = new_name;
2491                 entry->name_len = name_len;
2492
2493                 /* Place the new entry in the hash table */
2494                 state->hash_table[index] = entry;
2495         }
2496         return entry;
2497 }
2498
2499 static void ident_to_keyword(struct compile_state *state, struct token *tk)
2500 {
2501         struct hash_entry *entry;
2502         entry = tk->ident;
2503         if (entry && ((entry->tok == TOK_TYPE_NAME) ||
2504                 (entry->tok == TOK_ENUM_CONST) ||
2505                 ((entry->tok >= TOK_FIRST_KEYWORD) && 
2506                         (entry->tok <= TOK_LAST_KEYWORD)))) {
2507                 tk->tok = entry->tok;
2508         }
2509 }
2510
2511 static void ident_to_macro(struct compile_state *state, struct token *tk)
2512 {
2513         struct hash_entry *entry;
2514         entry = tk->ident;
2515         if (entry && 
2516                 (entry->tok >= TOK_FIRST_MACRO) &&
2517                 (entry->tok <= TOK_LAST_MACRO)) {
2518                 tk->tok = entry->tok;
2519         }
2520 }
2521
2522 static void hash_keyword(
2523         struct compile_state *state, const char *keyword, int tok)
2524 {
2525         struct hash_entry *entry;
2526         entry = lookup(state, keyword, strlen(keyword));
2527         if (entry && entry->tok != TOK_UNKNOWN) {
2528                 die("keyword %s already hashed", keyword);
2529         }
2530         entry->tok  = tok;
2531 }
2532
2533 static void symbol(
2534         struct compile_state *state, struct hash_entry *ident,
2535         struct symbol **chain, struct triple *def, struct type *type)
2536 {
2537         struct symbol *sym;
2538         if (*chain && ((*chain)->scope_depth == state->scope_depth)) {
2539                 error(state, 0, "%s already defined", ident->name);
2540         }
2541         sym = xcmalloc(sizeof(*sym), "symbol");
2542         sym->ident = ident;
2543         sym->def   = def;
2544         sym->type  = type;
2545         sym->scope_depth = state->scope_depth;
2546         sym->next = *chain;
2547         *chain    = sym;
2548 }
2549
2550 static void label_symbol(struct compile_state *state, 
2551         struct hash_entry *ident, struct triple *label)
2552 {
2553         struct symbol *sym;
2554         if (ident->sym_label) {
2555                 error(state, 0, "label %s already defined", ident->name);
2556         }
2557         sym = xcmalloc(sizeof(*sym), "label");
2558         sym->ident = ident;
2559         sym->def   = label;
2560         sym->type  = &void_type;
2561         sym->scope_depth = FUNCTION_SCOPE_DEPTH;
2562         sym->next  = 0;
2563         ident->sym_label = sym;
2564 }
2565
2566 static void start_scope(struct compile_state *state)
2567 {
2568         state->scope_depth++;
2569 }
2570
2571 static void end_scope_syms(struct symbol **chain, int depth)
2572 {
2573         struct symbol *sym, *next;
2574         sym = *chain;
2575         while(sym && (sym->scope_depth == depth)) {
2576                 next = sym->next;
2577                 xfree(sym);
2578                 sym = next;
2579         }
2580         *chain = sym;
2581 }
2582
2583 static void end_scope(struct compile_state *state)
2584 {
2585         int i;
2586         int depth;
2587         /* Walk through the hash table and remove all symbols
2588          * in the current scope. 
2589          */
2590         depth = state->scope_depth;
2591         for(i = 0; i < HASH_TABLE_SIZE; i++) {
2592                 struct hash_entry *entry;
2593                 entry = state->hash_table[i];
2594                 while(entry) {
2595                         end_scope_syms(&entry->sym_label, depth);
2596                         end_scope_syms(&entry->sym_tag,   depth);
2597                         end_scope_syms(&entry->sym_ident, depth);
2598                         entry = entry->next;
2599                 }
2600         }
2601         state->scope_depth = depth - 1;
2602 }
2603
2604 static void register_keywords(struct compile_state *state)
2605 {
2606         hash_keyword(state, "auto",          TOK_AUTO);
2607         hash_keyword(state, "break",         TOK_BREAK);
2608         hash_keyword(state, "case",          TOK_CASE);
2609         hash_keyword(state, "char",          TOK_CHAR);
2610         hash_keyword(state, "const",         TOK_CONST);
2611         hash_keyword(state, "continue",      TOK_CONTINUE);
2612         hash_keyword(state, "default",       TOK_DEFAULT);
2613         hash_keyword(state, "do",            TOK_DO);
2614         hash_keyword(state, "double",        TOK_DOUBLE);
2615         hash_keyword(state, "else",          TOK_ELSE);
2616         hash_keyword(state, "enum",          TOK_ENUM);
2617         hash_keyword(state, "extern",        TOK_EXTERN);
2618         hash_keyword(state, "float",         TOK_FLOAT);
2619         hash_keyword(state, "for",           TOK_FOR);
2620         hash_keyword(state, "goto",          TOK_GOTO);
2621         hash_keyword(state, "if",            TOK_IF);
2622         hash_keyword(state, "inline",        TOK_INLINE);
2623         hash_keyword(state, "int",           TOK_INT);
2624         hash_keyword(state, "long",          TOK_LONG);
2625         hash_keyword(state, "register",      TOK_REGISTER);
2626         hash_keyword(state, "restrict",      TOK_RESTRICT);
2627         hash_keyword(state, "return",        TOK_RETURN);
2628         hash_keyword(state, "short",         TOK_SHORT);
2629         hash_keyword(state, "signed",        TOK_SIGNED);
2630         hash_keyword(state, "sizeof",        TOK_SIZEOF);
2631         hash_keyword(state, "static",        TOK_STATIC);
2632         hash_keyword(state, "struct",        TOK_STRUCT);
2633         hash_keyword(state, "switch",        TOK_SWITCH);
2634         hash_keyword(state, "typedef",       TOK_TYPEDEF);
2635         hash_keyword(state, "union",         TOK_UNION);
2636         hash_keyword(state, "unsigned",      TOK_UNSIGNED);
2637         hash_keyword(state, "void",          TOK_VOID);
2638         hash_keyword(state, "volatile",      TOK_VOLATILE);
2639         hash_keyword(state, "__volatile__",  TOK_VOLATILE);
2640         hash_keyword(state, "while",         TOK_WHILE);
2641         hash_keyword(state, "asm",           TOK_ASM);
2642         hash_keyword(state, "__asm__",       TOK_ASM);
2643         hash_keyword(state, "__attribute__", TOK_ATTRIBUTE);
2644         hash_keyword(state, "__alignof__",   TOK_ALIGNOF);
2645 }
2646
2647 static void register_macro_keywords(struct compile_state *state)
2648 {
2649         hash_keyword(state, "define",        TOK_DEFINE);
2650         hash_keyword(state, "undef",         TOK_UNDEF);
2651         hash_keyword(state, "include",       TOK_INCLUDE);
2652         hash_keyword(state, "line",          TOK_LINE);
2653         hash_keyword(state, "error",         TOK_ERROR);
2654         hash_keyword(state, "warning",       TOK_WARNING);
2655         hash_keyword(state, "pragma",        TOK_PRAGMA);
2656         hash_keyword(state, "ifdef",         TOK_IFDEF);
2657         hash_keyword(state, "ifndef",        TOK_IFNDEF);
2658         hash_keyword(state, "elif",          TOK_ELIF);
2659         hash_keyword(state, "endif",         TOK_ENDIF);
2660 }
2661
2662 static int spacep(int c)
2663 {
2664         int ret = 0;
2665         switch(c) {
2666         case ' ':
2667         case '\t':
2668         case '\f':
2669         case '\v':
2670         case '\r':
2671         case '\n':
2672                 ret = 1;
2673                 break;
2674         }
2675         return ret;
2676 }
2677
2678 static int digitp(int c)
2679 {
2680         int ret = 0;
2681         switch(c) {
2682         case '0': case '1': case '2': case '3': case '4': 
2683         case '5': case '6': case '7': case '8': case '9':
2684                 ret = 1;
2685                 break;
2686         }
2687         return ret;
2688 }
2689 static int digval(int c)
2690 {
2691         int val = -1;
2692         if ((c >= '0') && (c <= '9')) {
2693                 val = c - '0';
2694         }
2695         return val;
2696 }
2697
2698 static int hexdigitp(int c)
2699 {
2700         int ret = 0;
2701         switch(c) {
2702         case '0': case '1': case '2': case '3': case '4': 
2703         case '5': case '6': case '7': case '8': case '9':
2704         case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
2705         case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
2706                 ret = 1;
2707                 break;
2708         }
2709         return ret;
2710 }
2711 static int hexdigval(int c) 
2712 {
2713         int val = -1;
2714         if ((c >= '0') && (c <= '9')) {
2715                 val = c - '0';
2716         }
2717         else if ((c >= 'A') && (c <= 'F')) {
2718                 val = 10 + (c - 'A');
2719         }
2720         else if ((c >= 'a') && (c <= 'f')) {
2721                 val = 10 + (c - 'a');
2722         }
2723         return val;
2724 }
2725
2726 static int octdigitp(int c)
2727 {
2728         int ret = 0;
2729         switch(c) {
2730         case '0': case '1': case '2': case '3': 
2731         case '4': case '5': case '6': case '7':
2732                 ret = 1;
2733                 break;
2734         }
2735         return ret;
2736 }
2737 static int octdigval(int c)
2738 {
2739         int val = -1;
2740         if ((c >= '0') && (c <= '7')) {
2741                 val = c - '0';
2742         }
2743         return val;
2744 }
2745
2746 static int letterp(int c)
2747 {
2748         int ret = 0;
2749         switch(c) {
2750         case 'a': case 'b': case 'c': case 'd': case 'e':
2751         case 'f': case 'g': case 'h': case 'i': case 'j':
2752         case 'k': case 'l': case 'm': case 'n': case 'o':
2753         case 'p': case 'q': case 'r': case 's': case 't':
2754         case 'u': case 'v': case 'w': case 'x': case 'y':
2755         case 'z':
2756         case 'A': case 'B': case 'C': case 'D': case 'E':
2757         case 'F': case 'G': case 'H': case 'I': case 'J':
2758         case 'K': case 'L': case 'M': case 'N': case 'O':
2759         case 'P': case 'Q': case 'R': case 'S': case 'T':
2760         case 'U': case 'V': case 'W': case 'X': case 'Y':
2761         case 'Z':
2762         case '_':
2763                 ret = 1;
2764                 break;
2765         }
2766         return ret;
2767 }
2768
2769 static int char_value(struct compile_state *state,
2770         const signed char **strp, const signed char *end)
2771 {
2772         const signed char *str;
2773         int c;
2774         str = *strp;
2775         c = *str++;
2776         if ((c == '\\') && (str < end)) {
2777                 switch(*str) {
2778                 case 'n':  c = '\n'; str++; break;
2779                 case 't':  c = '\t'; str++; break;
2780                 case 'v':  c = '\v'; str++; break;
2781                 case 'b':  c = '\b'; str++; break;
2782                 case 'r':  c = '\r'; str++; break;
2783                 case 'f':  c = '\f'; str++; break;
2784                 case 'a':  c = '\a'; str++; break;
2785                 case '\\': c = '\\'; str++; break;
2786                 case '?':  c = '?';  str++; break;
2787                 case '\'': c = '\''; str++; break;
2788                 case '"':  c = '"';  break;
2789                 case 'x': 
2790                         c = 0;
2791                         str++;
2792                         while((str < end) && hexdigitp(*str)) {
2793                                 c <<= 4;
2794                                 c += hexdigval(*str);
2795                                 str++;
2796                         }
2797                         break;
2798                 case '0': case '1': case '2': case '3': 
2799                 case '4': case '5': case '6': case '7':
2800                         c = 0;
2801                         while((str < end) && octdigitp(*str)) {
2802                                 c <<= 3;
2803                                 c += octdigval(*str);
2804                                 str++;
2805                         }
2806                         break;
2807                 default:
2808                         error(state, 0, "Invalid character constant");
2809                         break;
2810                 }
2811         }
2812         *strp = str;
2813         return c;
2814 }
2815
2816 static char *after_digits(char *ptr, char *end)
2817 {
2818         while((ptr < end) && digitp(*ptr)) {
2819                 ptr++;
2820         }
2821         return ptr;
2822 }
2823
2824 static char *after_octdigits(char *ptr, char *end)
2825 {
2826         while((ptr < end) && octdigitp(*ptr)) {
2827                 ptr++;
2828         }
2829         return ptr;
2830 }
2831
2832 static char *after_hexdigits(char *ptr, char *end)
2833 {
2834         while((ptr < end) && hexdigitp(*ptr)) {
2835                 ptr++;
2836         }
2837         return ptr;
2838 }
2839
2840 static void save_string(struct compile_state *state, 
2841         struct token *tk, char *start, char *end, const char *id)
2842 {
2843         char *str;
2844         int str_len;
2845         /* Create a private copy of the string */
2846         str_len = end - start + 1;
2847         str = xmalloc(str_len + 1, id);
2848         memcpy(str, start, str_len);
2849         str[str_len] = '\0';
2850
2851         /* Store the copy in the token */
2852         tk->val.str = str;
2853         tk->str_len = str_len;
2854 }
2855 static void next_token(struct compile_state *state, int index)
2856 {
2857         struct file_state *file;
2858         struct token *tk;
2859         char *token;
2860         int c, c1, c2, c3;
2861         char *tokp, *end;
2862         int tok;
2863 next_token:
2864         file = state->file;
2865         tk = &state->token[index];
2866         tk->str_len = 0;
2867         tk->ident = 0;
2868         token = tokp = file->pos;
2869         end = file->buf + file->size;
2870         tok = TOK_UNKNOWN;
2871         c = -1;
2872         if (tokp < end) {
2873                 c = *tokp;
2874         }
2875         c1 = -1;
2876         if ((tokp + 1) < end) {
2877                 c1 = tokp[1];
2878         }
2879         c2 = -1;
2880         if ((tokp + 2) < end) {
2881                 c2 = tokp[2];
2882         }
2883         c3 = -1;
2884         if ((tokp + 3) < end) {
2885                 c3 = tokp[3];
2886         }
2887         if (tokp >= end) {
2888                 tok = TOK_EOF;
2889                 tokp = end;
2890         }
2891         /* Whitespace */
2892         else if (spacep(c)) {
2893                 tok = TOK_SPACE;
2894                 while ((tokp < end) && spacep(c)) {
2895                         if (c == '\n') {
2896                                 file->line++;
2897                                 file->report_line++;
2898                                 file->line_start = tokp + 1;
2899                         }
2900                         c = *(++tokp);
2901                 }
2902                 if (!spacep(c)) {
2903                         tokp--;
2904                 }
2905         }
2906         /* EOL Comments */
2907         else if ((c == '/') && (c1 == '/')) {
2908                 tok = TOK_SPACE;
2909                 for(tokp += 2; tokp < end; tokp++) {
2910                         c = *tokp;
2911                         if (c == '\n') {
2912                                 file->line++;
2913                                 file->report_line++;
2914                                 file->line_start = tokp +1;
2915                                 break;
2916                         }
2917                 }
2918         }
2919         /* Comments */
2920         else if ((c == '/') && (c1 == '*')) {
2921                 int line;
2922                 char *line_start;
2923                 line = file->line;
2924                 line_start = file->line_start;
2925                 for(tokp += 2; (end - tokp) >= 2; tokp++) {
2926                         c = *tokp;
2927                         if (c == '\n') {
2928                                 line++;
2929                                 line_start = tokp +1;
2930                         }
2931                         else if ((c == '*') && (tokp[1] == '/')) {
2932                                 tok = TOK_SPACE;
2933                                 tokp += 1;
2934                                 break;
2935                         }
2936                 }
2937                 if (tok == TOK_UNKNOWN) {
2938                         error(state, 0, "unterminated comment");
2939                 }
2940                 file->report_line += line - file->line;
2941                 file->line = line;
2942                 file->line_start = line_start;
2943         }
2944         /* string constants */
2945         else if ((c == '"') ||
2946                 ((c == 'L') && (c1 == '"'))) {
2947                 int line;
2948                 char *line_start;
2949                 int wchar;
2950                 line = file->line;
2951                 line_start = file->line_start;
2952                 wchar = 0;
2953                 if (c == 'L') {
2954                         wchar = 1;
2955                         tokp++;
2956                 }
2957                 for(tokp += 1; tokp < end; tokp++) {
2958                         c = *tokp;
2959                         if (c == '\n') {
2960                                 line++;
2961                                 line_start = tokp + 1;
2962                         }
2963                         else if ((c == '\\') && (tokp +1 < end)) {
2964                                 tokp++;
2965                         }
2966                         else if (c == '"') {
2967                                 tok = TOK_LIT_STRING;
2968                                 break;
2969                         }
2970                 }
2971                 if (tok == TOK_UNKNOWN) {
2972                         error(state, 0, "unterminated string constant");
2973                 }
2974                 if (line != file->line) {
2975                         warning(state, 0, "multiline string constant");
2976                 }
2977                 file->report_line += line - file->line;
2978                 file->line = line;
2979                 file->line_start = line_start;
2980
2981                 /* Save the string value */
2982                 save_string(state, tk, token, tokp, "literal string");
2983         }
2984         /* character constants */
2985         else if ((c == '\'') ||
2986                 ((c == 'L') && (c1 == '\''))) {
2987                 int line;
2988                 char *line_start;
2989                 int wchar;
2990                 line = file->line;
2991                 line_start = file->line_start;
2992                 wchar = 0;
2993                 if (c == 'L') {
2994                         wchar = 1;
2995                         tokp++;
2996                 }
2997                 for(tokp += 1; tokp < end; tokp++) {
2998                         c = *tokp;
2999                         if (c == '\n') {
3000                                 line++;
3001                                 line_start = tokp + 1;
3002                         }
3003                         else if ((c == '\\') && (tokp +1 < end)) {
3004                                 tokp++;
3005                         }
3006                         else if (c == '\'') {
3007                                 tok = TOK_LIT_CHAR;
3008                                 break;
3009                         }
3010                 }
3011                 if (tok == TOK_UNKNOWN) {
3012                         error(state, 0, "unterminated character constant");
3013                 }
3014                 if (line != file->line) {
3015                         warning(state, 0, "multiline character constant");
3016                 }
3017                 file->report_line += line - file->line;
3018                 file->line = line;
3019                 file->line_start = line_start;
3020
3021                 /* Save the character value */
3022                 save_string(state, tk, token, tokp, "literal character");
3023         }
3024         /* integer and floating constants 
3025          * Integer Constants
3026          * {digits}
3027          * 0[Xx]{hexdigits}
3028          * 0{octdigit}+
3029          * 
3030          * Floating constants
3031          * {digits}.{digits}[Ee][+-]?{digits}
3032          * {digits}.{digits}
3033          * {digits}[Ee][+-]?{digits}
3034          * .{digits}[Ee][+-]?{digits}
3035          * .{digits}
3036          */
3037         
3038         else if (digitp(c) || ((c == '.') && (digitp(c1)))) {
3039                 char *next, *new;
3040                 int is_float;
3041                 is_float = 0;
3042                 if (c != '.') {
3043                         next = after_digits(tokp, end);
3044                 }
3045                 else {
3046                         next = tokp;
3047                 }
3048                 if (next[0] == '.') {
3049                         new = after_digits(next, end);
3050                         is_float = (new != next);
3051                         next = new;
3052                 }
3053                 if ((next[0] == 'e') || (next[0] == 'E')) {
3054                         if (((next + 1) < end) && 
3055                                 ((next[1] == '+') || (next[1] == '-'))) {
3056                                 next++;
3057                         }
3058                         new = after_digits(next, end);
3059                         is_float = (new != next);
3060                         next = new;
3061                 }
3062                 if (is_float) {
3063                         tok = TOK_LIT_FLOAT;
3064                         if ((next < end) && (
3065                                 (next[0] == 'f') ||
3066                                 (next[0] == 'F') ||
3067                                 (next[0] == 'l') ||
3068                                 (next[0] == 'L'))
3069                                 ) {
3070                                 next++;
3071                         }
3072                 }
3073                 if (!is_float && digitp(c)) {
3074                         tok = TOK_LIT_INT;
3075                         if ((c == '0') && ((c1 == 'x') || (c1 == 'X'))) {
3076                                 next = after_hexdigits(tokp + 2, end);
3077                         }
3078                         else if (c == '0') {
3079                                 next = after_octdigits(tokp, end);
3080                         }
3081                         else {
3082                                 next = after_digits(tokp, end);
3083                         }
3084                         /* crazy integer suffixes */
3085                         if ((next < end) && 
3086                                 ((next[0] == 'u') || (next[0] == 'U'))) { 
3087                                 next++;
3088                                 if ((next < end) &&
3089                                         ((next[0] == 'l') || (next[0] == 'L'))) {
3090                                         next++;
3091                                 }
3092                         }
3093                         else if ((next < end) &&
3094                                 ((next[0] == 'l') || (next[0] == 'L'))) {
3095                                 next++;
3096                                 if ((next < end) && 
3097                                         ((next[0] == 'u') || (next[0] == 'U'))) { 
3098                                         next++;
3099                                 }
3100                         }
3101                 }
3102                 tokp = next - 1;
3103
3104                 /* Save the integer/floating point value */
3105                 save_string(state, tk, token, tokp, "literal number");
3106         }
3107         /* identifiers */
3108         else if (letterp(c)) {
3109                 tok = TOK_IDENT;
3110                 for(tokp += 1; tokp < end; tokp++) {
3111                         c = *tokp;
3112                         if (!letterp(c) && !digitp(c)) {
3113                                 break;
3114                         }
3115                 }
3116                 tokp -= 1;
3117                 tk->ident = lookup(state, token, tokp +1 - token);
3118         }
3119         /* C99 alternate macro characters */
3120         else if ((c == '%') && (c1 == ':') && (c2 == '%') && (c3 == ':')) { 
3121                 tokp += 3; 
3122                 tok = TOK_CONCATENATE; 
3123         }
3124         else if ((c == '.') && (c1 == '.') && (c2 == '.')) { tokp += 2; tok = TOK_DOTS; }
3125         else if ((c == '<') && (c1 == '<') && (c2 == '=')) { tokp += 2; tok = TOK_SLEQ; }
3126         else if ((c == '>') && (c1 == '>') && (c2 == '=')) { tokp += 2; tok = TOK_SREQ; }
3127         else if ((c == '*') && (c1 == '=')) { tokp += 1; tok = TOK_TIMESEQ; }
3128         else if ((c == '/') && (c1 == '=')) { tokp += 1; tok = TOK_DIVEQ; }
3129         else if ((c == '%') && (c1 == '=')) { tokp += 1; tok = TOK_MODEQ; }
3130         else if ((c == '+') && (c1 == '=')) { tokp += 1; tok = TOK_PLUSEQ; }
3131         else if ((c == '-') && (c1 == '=')) { tokp += 1; tok = TOK_MINUSEQ; }
3132         else if ((c == '&') && (c1 == '=')) { tokp += 1; tok = TOK_ANDEQ; }
3133         else if ((c == '^') && (c1 == '=')) { tokp += 1; tok = TOK_XOREQ; }
3134         else if ((c == '|') && (c1 == '=')) { tokp += 1; tok = TOK_OREQ; }
3135         else if ((c == '=') && (c1 == '=')) { tokp += 1; tok = TOK_EQEQ; }
3136         else if ((c == '!') && (c1 == '=')) { tokp += 1; tok = TOK_NOTEQ; }
3137         else if ((c == '|') && (c1 == '|')) { tokp += 1; tok = TOK_LOGOR; }
3138         else if ((c == '&') && (c1 == '&')) { tokp += 1; tok = TOK_LOGAND; }
3139         else if ((c == '<') && (c1 == '=')) { tokp += 1; tok = TOK_LESSEQ; }
3140         else if ((c == '>') && (c1 == '=')) { tokp += 1; tok = TOK_MOREEQ; }
3141         else if ((c == '<') && (c1 == '<')) { tokp += 1; tok = TOK_SL; }
3142         else if ((c == '>') && (c1 == '>')) { tokp += 1; tok = TOK_SR; }
3143         else if ((c == '+') && (c1 == '+')) { tokp += 1; tok = TOK_PLUSPLUS; }
3144         else if ((c == '-') && (c1 == '-')) { tokp += 1; tok = TOK_MINUSMINUS; }
3145         else if ((c == '-') && (c1 == '>')) { tokp += 1; tok = TOK_ARROW; }
3146         else if ((c == '<') && (c1 == ':')) { tokp += 1; tok = TOK_LBRACKET; }
3147         else if ((c == ':') && (c1 == '>')) { tokp += 1; tok = TOK_RBRACKET; }
3148         else if ((c == '<') && (c1 == '%')) { tokp += 1; tok = TOK_LBRACE; }
3149         else if ((c == '%') && (c1 == '>')) { tokp += 1; tok = TOK_RBRACE; }
3150         else if ((c == '%') && (c1 == ':')) { tokp += 1; tok = TOK_MACRO; }
3151         else if ((c == '#') && (c1 == '#')) { tokp += 1; tok = TOK_CONCATENATE; }
3152         else if (c == ';') { tok = TOK_SEMI; }
3153         else if (c == '{') { tok = TOK_LBRACE; }
3154         else if (c == '}') { tok = TOK_RBRACE; }
3155         else if (c == ',') { tok = TOK_COMMA; }
3156         else if (c == '=') { tok = TOK_EQ; }
3157         else if (c == ':') { tok = TOK_COLON; }
3158         else if (c == '[') { tok = TOK_LBRACKET; }
3159         else if (c == ']') { tok = TOK_RBRACKET; }
3160         else if (c == '(') { tok = TOK_LPAREN; }
3161         else if (c == ')') { tok = TOK_RPAREN; }
3162         else if (c == '*') { tok = TOK_STAR; }
3163         else if (c == '>') { tok = TOK_MORE; }
3164         else if (c == '<') { tok = TOK_LESS; }
3165         else if (c == '?') { tok = TOK_QUEST; }
3166         else if (c == '|') { tok = TOK_OR; }
3167         else if (c == '&') { tok = TOK_AND; }
3168         else if (c == '^') { tok = TOK_XOR; }
3169         else if (c == '+') { tok = TOK_PLUS; }
3170         else if (c == '-') { tok = TOK_MINUS; }
3171         else if (c == '/') { tok = TOK_DIV; }
3172         else if (c == '%') { tok = TOK_MOD; }
3173         else if (c == '!') { tok = TOK_BANG; }
3174         else if (c == '.') { tok = TOK_DOT; }
3175         else if (c == '~') { tok = TOK_TILDE; }
3176         else if (c == '#') { tok = TOK_MACRO; }
3177         if (tok == TOK_MACRO) {
3178                 /* Only match preprocessor directives at the start of a line */
3179                 char *ptr;
3180                 for(ptr = file->line_start; spacep(*ptr); ptr++)
3181                         ;
3182                 if (ptr != tokp) {
3183                         tok = TOK_UNKNOWN;
3184                 }
3185         }
3186         if (tok == TOK_UNKNOWN) {
3187                 error(state, 0, "unknown token");
3188         }
3189
3190         file->pos = tokp + 1;
3191         tk->tok = tok;
3192         if (tok == TOK_IDENT) {
3193                 ident_to_keyword(state, tk);
3194         }
3195         /* Don't return space tokens. */
3196         if (tok == TOK_SPACE) {
3197                 goto next_token;
3198         }
3199 }
3200
3201 static void compile_macro(struct compile_state *state, struct token *tk)
3202 {
3203         struct file_state *file;
3204         struct hash_entry *ident;
3205         ident = tk->ident;
3206         file = xmalloc(sizeof(*file), "file_state");
3207         file->basename = xstrdup(tk->ident->name);
3208         file->dirname = xstrdup("");
3209         file->size = ident->sym_define->buf_len;
3210         file->buf = xmalloc(file->size +2,  file->basename);
3211         memcpy(file->buf, ident->sym_define->buf, file->size);
3212         file->buf[file->size] = '\n';
3213         file->buf[file->size + 1] = '\0';
3214         file->pos = file->buf;
3215         file->line_start = file->pos;
3216         file->line = 1;
3217         file->report_line = 1;
3218         file->report_name = file->basename;
3219         file->report_dir  = file->dirname;
3220         file->prev = state->file;
3221         state->file = file;
3222 }
3223
3224
3225 static int mpeek(struct compile_state *state, int index)
3226 {
3227         struct token *tk;
3228         int rescan;
3229         tk = &state->token[index + 1];
3230         if (tk->tok == -1) {
3231                 next_token(state, index + 1);
3232         }
3233         do {
3234                 rescan = 0;
3235                 if ((tk->tok == TOK_EOF) && 
3236                         (state->file != state->macro_file) &&
3237                         (state->file->prev)) {
3238                         struct file_state *file = state->file;
3239                         state->file = file->prev;
3240                         /* file->basename is used keep it */
3241                         if (file->report_dir != file->dirname) {
3242                                 xfree(file->report_dir);
3243                         }
3244                         xfree(file->dirname);
3245                         xfree(file->buf);
3246                         xfree(file);
3247                         next_token(state, index + 1);
3248                         rescan = 1;
3249                 }
3250                 else if (tk->ident && tk->ident->sym_define) {
3251                         compile_macro(state, tk);
3252                         next_token(state, index + 1);
3253                         rescan = 1;
3254                 }
3255         } while(rescan);
3256         /* Don't show the token on the next line */
3257         if (state->macro_line < state->macro_file->line) {
3258                 return TOK_EOF;
3259         }
3260         return state->token[index +1].tok;
3261 }
3262
3263 static void meat(struct compile_state *state, int index, int tok)
3264 {
3265         int next_tok;
3266         int i;
3267         next_tok = mpeek(state, index);
3268         if (next_tok != tok) {
3269                 const char *name1, *name2;
3270                 name1 = tokens[next_tok];
3271                 name2 = "";
3272                 if (next_tok == TOK_IDENT) {
3273                         name2 = state->token[index + 1].ident->name;
3274                 }
3275                 error(state, 0, "found %s %s expected %s", 
3276                         name1, name2, tokens[tok]);
3277         }
3278         /* Free the old token value */
3279         if (state->token[index].str_len) {
3280                 memset((void *)(state->token[index].val.str), -1, 
3281                         state->token[index].str_len);
3282                 xfree(state->token[index].val.str);
3283         }
3284         for(i = index; i < sizeof(state->token)/sizeof(state->token[0]) - 1; i++) {
3285                 state->token[i] = state->token[i + 1];
3286         }
3287         memset(&state->token[i], 0, sizeof(state->token[i]));
3288         state->token[i].tok = -1;
3289 }
3290
3291 static long_t mcexpr(struct compile_state *state, int index);
3292
3293 static long_t mprimary_expr(struct compile_state *state, int index)
3294 {
3295         long_t val;
3296         int tok;
3297         tok = mpeek(state, index);
3298         while(state->token[index + 1].ident && 
3299                 state->token[index + 1].ident->sym_define) {
3300                 meat(state, index, tok);
3301                 compile_macro(state, &state->token[index]);
3302                 tok = mpeek(state, index);
3303         }
3304         switch(tok) {
3305         case TOK_LPAREN:
3306                 meat(state, index, TOK_LPAREN);
3307                 val = mcexpr(state, index);
3308                 meat(state, index, TOK_RPAREN);
3309                 break;
3310         case TOK_LIT_INT:
3311         {
3312                 long lval;
3313                 char *end;
3314                 meat(state, index, TOK_LIT_INT);
3315                 errno = 0;
3316                 lval = strtol(state->token[index].val.str, &end, 0);
3317                 if ((lval > LONG_T_MAX) || (lval < LONG_T_MIN) ||
3318                         (((lval == LONG_MIN) || (lval == LONG_MAX)) &&
3319                                 (errno == ERANGE))) {
3320                         error(state, 0, "Integer constant to large");
3321                 }
3322                 val = lval;
3323                 break;
3324         }
3325         default:
3326                 meat(state, index, TOK_LIT_INT);
3327                 val = 0;
3328         }
3329         return val;
3330 }
3331 static long_t munary_expr(struct compile_state *state, int index)
3332 {
3333         long_t val;
3334         switch(mpeek(state, index)) {
3335         case TOK_PLUS:
3336                 meat(state, index, TOK_PLUS);
3337                 val = munary_expr(state, index);
3338                 val = + val;
3339                 break;
3340         case TOK_MINUS:
3341                 meat(state, index, TOK_MINUS);
3342                 val = munary_expr(state, index);
3343                 val = - val;
3344                 break;
3345         case TOK_TILDE:
3346                 meat(state, index, TOK_BANG);
3347                 val = munary_expr(state, index);
3348                 val = ~ val;
3349                 break;
3350         case TOK_BANG:
3351                 meat(state, index, TOK_BANG);
3352                 val = munary_expr(state, index);
3353                 val = ! val;
3354                 break;
3355         default:
3356                 val = mprimary_expr(state, index);
3357                 break;
3358         }
3359         return val;
3360         
3361 }
3362 static long_t mmul_expr(struct compile_state *state, int index)
3363 {
3364         long_t val;
3365         int done;
3366         val = munary_expr(state, index);
3367         do {
3368                 long_t right;
3369                 done = 0;
3370                 switch(mpeek(state, index)) {
3371                 case TOK_STAR:
3372                         meat(state, index, TOK_STAR);
3373                         right = munary_expr(state, index);
3374                         val = val * right;
3375                         break;
3376                 case TOK_DIV:
3377                         meat(state, index, TOK_DIV);
3378                         right = munary_expr(state, index);
3379                         val = val / right;
3380                         break;
3381                 case TOK_MOD:
3382                         meat(state, index, TOK_MOD);
3383                         right = munary_expr(state, index);
3384                         val = val % right;
3385                         break;
3386                 default:
3387                         done = 1;
3388                         break;
3389                 }
3390         } while(!done);
3391
3392         return val;
3393 }
3394
3395 static long_t madd_expr(struct compile_state *state, int index)
3396 {
3397         long_t val;
3398         int done;
3399         val = mmul_expr(state, index);
3400         do {
3401                 long_t right;
3402                 done = 0;
3403                 switch(mpeek(state, index)) {
3404                 case TOK_PLUS:
3405                         meat(state, index, TOK_PLUS);
3406                         right = mmul_expr(state, index);
3407                         val = val + right;
3408                         break;
3409                 case TOK_MINUS:
3410                         meat(state, index, TOK_MINUS);
3411                         right = mmul_expr(state, index);
3412                         val = val - right;
3413                         break;
3414                 default:
3415                         done = 1;
3416                         break;
3417                 }
3418         } while(!done);
3419
3420         return val;
3421 }
3422
3423 static long_t mshift_expr(struct compile_state *state, int index)
3424 {
3425         long_t val;
3426         int done;
3427         val = madd_expr(state, index);
3428         do {
3429                 long_t right;
3430                 done = 0;
3431                 switch(mpeek(state, index)) {
3432                 case TOK_SL:
3433                         meat(state, index, TOK_SL);
3434                         right = madd_expr(state, index);
3435                         val = val << right;
3436                         break;
3437                 case TOK_SR:
3438                         meat(state, index, TOK_SR);
3439                         right = madd_expr(state, index);
3440                         val = val >> right;
3441                         break;
3442                 default:
3443                         done = 1;
3444                         break;
3445                 }
3446         } while(!done);
3447
3448         return val;
3449 }
3450
3451 static long_t mrel_expr(struct compile_state *state, int index)
3452 {
3453         long_t val;
3454         int done;
3455         val = mshift_expr(state, index);
3456         do {
3457                 long_t right;
3458                 done = 0;
3459                 switch(mpeek(state, index)) {
3460                 case TOK_LESS:
3461                         meat(state, index, TOK_LESS);
3462                         right = mshift_expr(state, index);
3463                         val = val < right;
3464                         break;
3465                 case TOK_MORE:
3466                         meat(state, index, TOK_MORE);
3467                         right = mshift_expr(state, index);
3468                         val = val > right;
3469                         break;
3470                 case TOK_LESSEQ:
3471                         meat(state, index, TOK_LESSEQ);
3472                         right = mshift_expr(state, index);
3473                         val = val <= right;
3474                         break;
3475                 case TOK_MOREEQ:
3476                         meat(state, index, TOK_MOREEQ);
3477                         right = mshift_expr(state, index);
3478                         val = val >= right;
3479                         break;
3480                 default:
3481                         done = 1;
3482                         break;
3483                 }
3484         } while(!done);
3485         return val;
3486 }
3487
3488 static long_t meq_expr(struct compile_state *state, int index)
3489 {
3490         long_t val;
3491         int done;
3492         val = mrel_expr(state, index);
3493         do {
3494                 long_t right;
3495                 done = 0;
3496                 switch(mpeek(state, index)) {
3497                 case TOK_EQEQ:
3498                         meat(state, index, TOK_EQEQ);
3499                         right = mrel_expr(state, index);
3500                         val = val == right;
3501                         break;
3502                 case TOK_NOTEQ:
3503                         meat(state, index, TOK_NOTEQ);
3504                         right = mrel_expr(state, index);
3505                         val = val != right;
3506                         break;
3507                 default:
3508                         done = 1;
3509                         break;
3510                 }
3511         } while(!done);
3512         return val;
3513 }
3514
3515 static long_t mand_expr(struct compile_state *state, int index)
3516 {
3517         long_t val;
3518         val = meq_expr(state, index);
3519         if (mpeek(state, index) == TOK_AND) {
3520                 long_t right;
3521                 meat(state, index, TOK_AND);
3522                 right = meq_expr(state, index);
3523                 val = val & right;
3524         }
3525         return val;
3526 }
3527
3528 static long_t mxor_expr(struct compile_state *state, int index)
3529 {
3530         long_t val;
3531         val = mand_expr(state, index);
3532         if (mpeek(state, index) == TOK_XOR) {
3533                 long_t right;
3534                 meat(state, index, TOK_XOR);
3535                 right = mand_expr(state, index);
3536                 val = val ^ right;
3537         }
3538         return val;
3539 }
3540
3541 static long_t mor_expr(struct compile_state *state, int index)
3542 {
3543         long_t val;
3544         val = mxor_expr(state, index);
3545         if (mpeek(state, index) == TOK_OR) {
3546                 long_t right;
3547                 meat(state, index, TOK_OR);
3548                 right = mxor_expr(state, index);
3549                 val = val | right;
3550         }
3551         return val;
3552 }
3553
3554 static long_t mland_expr(struct compile_state *state, int index)
3555 {
3556         long_t val;
3557         val = mor_expr(state, index);
3558         if (mpeek(state, index) == TOK_LOGAND) {
3559                 long_t right;
3560                 meat(state, index, TOK_LOGAND);
3561                 right = mor_expr(state, index);
3562                 val = val && right;
3563         }
3564         return val;
3565 }
3566 static long_t mlor_expr(struct compile_state *state, int index)
3567 {
3568         long_t val;
3569         val = mland_expr(state, index);
3570         if (mpeek(state, index) == TOK_LOGOR) {
3571                 long_t right;
3572                 meat(state, index, TOK_LOGOR);
3573                 right = mland_expr(state, index);
3574                 val = val || right;
3575         }
3576         return val;
3577 }
3578
3579 static long_t mcexpr(struct compile_state *state, int index)
3580 {
3581         return mlor_expr(state, index);
3582 }
3583 static void preprocess(struct compile_state *state, int index)
3584 {
3585         /* Doing much more with the preprocessor would require
3586          * a parser and a major restructuring.
3587          * Postpone that for later.
3588          */
3589         struct file_state *file;
3590         struct token *tk;
3591         int line;
3592         int tok;
3593         
3594         file = state->file;
3595         tk = &state->token[index];
3596         state->macro_line = line = file->line;
3597         state->macro_file = file;
3598
3599         next_token(state, index);
3600         ident_to_macro(state, tk);
3601         if (tk->tok == TOK_IDENT) {
3602                 error(state, 0, "undefined preprocessing directive `%s'",
3603                         tk->ident->name);
3604         }
3605         switch(tk->tok) {
3606         case TOK_LIT_INT:
3607         {
3608                 int override_line;
3609                 override_line = strtoul(tk->val.str, 0, 10);
3610                 next_token(state, index);
3611                 /* I have a cpp line marker parse it */
3612                 if (tk->tok == TOK_LIT_STRING) {
3613                         const char *token, *base;
3614                         char *name, *dir;
3615                         int name_len, dir_len;
3616                         name = xmalloc(tk->str_len, "report_name");
3617                         token = tk->val.str + 1;
3618                         base = strrchr(token, '/');
3619                         name_len = tk->str_len -2;
3620                         if (base != 0) {
3621                                 dir_len = base - token;
3622                                 base++;
3623                                 name_len -= base - token;
3624                         } else {
3625                                 dir_len = 0;
3626                                 base = token;
3627                         }
3628                         memcpy(name, base, name_len);
3629                         name[name_len] = '\0';
3630                         dir = xmalloc(dir_len + 1, "report_dir");
3631                         memcpy(dir, token, dir_len);
3632                         dir[dir_len] = '\0';
3633                         file->report_line = override_line - 1;
3634                         file->report_name = name;
3635                         file->report_dir = dir;
3636                 }
3637         }
3638                 break;
3639         case TOK_LINE:
3640                 meat(state, index, TOK_LINE);
3641                 meat(state, index, TOK_LIT_INT);
3642                 file->report_line = strtoul(tk->val.str, 0, 10) -1;
3643                 if (mpeek(state, index) == TOK_LIT_STRING) {
3644                         const char *token, *base;
3645                         char *name, *dir;
3646                         int name_len, dir_len;
3647                         meat(state, index, TOK_LIT_STRING);
3648                         name = xmalloc(tk->str_len, "report_name");
3649                         token = tk->val.str + 1;
3650                         base = strrchr(token, '/');
3651                         name_len = tk->str_len - 2;
3652                         if (base != 0) {
3653                                 dir_len = base - token;
3654                                 base++;
3655                                 name_len -= base - token;
3656                         } else {
3657                                 dir_len = 0;
3658                                 base = token;
3659                         }
3660                         memcpy(name, base, name_len);
3661                         name[name_len] = '\0';
3662                         dir = xmalloc(dir_len + 1, "report_dir");
3663                         memcpy(dir, token, dir_len);
3664                         dir[dir_len] = '\0';
3665                         file->report_name = name;
3666                         file->report_dir = dir;
3667                 }
3668                 break;
3669         case TOK_UNDEF:
3670         case TOK_PRAGMA:
3671                 if (state->if_value < 0) {
3672                         break;
3673                 }
3674                 warning(state, 0, "Ignoring preprocessor directive: %s", 
3675                         tk->ident->name);
3676                 break;
3677         case TOK_ELIF:
3678                 error(state, 0, "#elif not supported");
3679 #warning "FIXME multiple #elif and #else in an #if do not work properly"
3680                 if (state->if_depth == 0) {
3681                         error(state, 0, "#elif without #if");
3682                 }
3683                 /* If the #if was taken the #elif just disables the following code */
3684                 if (state->if_value >= 0) {
3685                         state->if_value = - state->if_value;
3686                 }
3687                 /* If the previous #if was not taken see if the #elif enables the 
3688                  * trailing code.
3689                  */
3690                 else if ((state->if_value < 0) && 
3691                         (state->if_depth == - state->if_value))
3692                 {
3693                         if (mcexpr(state, index) != 0) {
3694                                 state->if_value = state->if_depth;
3695                         }
3696                         else {
3697                                 state->if_value = - state->if_depth;
3698                         }
3699                 }
3700                 break;
3701         case TOK_IF:
3702                 state->if_depth++;
3703                 if (state->if_value < 0) {
3704                         break;
3705                 }
3706                 if (mcexpr(state, index) != 0) {
3707                         state->if_value = state->if_depth;
3708                 }
3709                 else {
3710                         state->if_value = - state->if_depth;
3711                 }
3712                 break;
3713         case TOK_IFNDEF:
3714                 state->if_depth++;
3715                 if (state->if_value < 0) {
3716                         break;
3717                 }
3718                 next_token(state, index);
3719                 if ((line != file->line) || (tk->tok != TOK_IDENT)) {
3720                         error(state, 0, "Invalid macro name");
3721                 }
3722                 if (tk->ident->sym_define == 0) {
3723                         state->if_value = state->if_depth;
3724                 } 
3725                 else {
3726                         state->if_value = - state->if_depth;
3727                 }
3728                 break;
3729         case TOK_IFDEF:
3730                 state->if_depth++;
3731                 if (state->if_value < 0) {
3732                         break;
3733                 }
3734                 next_token(state, index);
3735                 if ((line != file->line) || (tk->tok != TOK_IDENT)) {
3736                         error(state, 0, "Invalid macro name");
3737                 }
3738                 if (tk->ident->sym_define != 0) {
3739                         state->if_value = state->if_depth;
3740                 }
3741                 else {
3742                         state->if_value = - state->if_depth;
3743                 }
3744                 break;
3745         case TOK_ELSE:
3746                 if (state->if_depth == 0) {
3747                         error(state, 0, "#else without #if");
3748                 }
3749                 if ((state->if_value >= 0) ||
3750                         ((state->if_value < 0) && 
3751                                 (state->if_depth == -state->if_value)))
3752                 {
3753                         state->if_value = - state->if_value;
3754                 }
3755                 break;
3756         case TOK_ENDIF:
3757                 if (state->if_depth == 0) {
3758                         error(state, 0, "#endif without #if");
3759                 }
3760                 if ((state->if_value >= 0) ||
3761                         ((state->if_value < 0) &&
3762                                 (state->if_depth == -state->if_value))) 
3763                 {
3764                         state->if_value = state->if_depth - 1;
3765                 }
3766                 state->if_depth--;
3767                 break;
3768         case TOK_DEFINE:
3769         {
3770                 struct hash_entry *ident;
3771                 struct macro *macro;
3772                 char *ptr;
3773                 
3774                 if (state->if_value < 0) /* quit early when #if'd out */
3775                         break;
3776
3777                 meat(state, index, TOK_IDENT);
3778                 ident = tk->ident;
3779                 
3780
3781                 if (*file->pos == '(') {
3782 #warning "FIXME macros with arguments not supported"
3783                         error(state, 0, "Macros with arguments not supported");
3784                 }
3785
3786                 /* Find the end of the line to get an estimate of
3787                  * the macro's length.
3788                  */
3789                 for(ptr = file->pos; *ptr != '\n'; ptr++)  
3790                         ;
3791
3792                 if (ident->sym_define != 0) {
3793                         error(state, 0, "macro %s already defined\n", ident->name);
3794                 }
3795                 macro = xmalloc(sizeof(*macro), "macro");
3796                 macro->ident = ident;
3797                 macro->buf_len = ptr - file->pos +1;
3798                 macro->buf = xmalloc(macro->buf_len +2, "macro buf");
3799
3800                 memcpy(macro->buf, file->pos, macro->buf_len);
3801                 macro->buf[macro->buf_len] = '\n';
3802                 macro->buf[macro->buf_len +1] = '\0';
3803
3804                 ident->sym_define = macro;
3805                 break;
3806         }
3807         case TOK_ERROR:
3808         {
3809                 char *end;
3810                 int len;
3811                 /* Find the end of the line */
3812                 for(end = file->pos; *end != '\n'; end++)
3813                         ;
3814                 len = (end - file->pos);
3815                 if (state->if_value >= 0) {
3816                         error(state, 0, "%*.*s", len, len, file->pos);
3817                 }
3818                 file->pos = end;
3819                 break;
3820         }
3821         case TOK_WARNING:
3822         {
3823                 char *end;
3824                 int len;
3825                 /* Find the end of the line */
3826                 for(end = file->pos; *end != '\n'; end++)
3827                         ;
3828                 len = (end - file->pos);
3829                 if (state->if_value >= 0) {
3830                         warning(state, 0, "%*.*s", len, len, file->pos);
3831                 }
3832                 file->pos = end;
3833                 break;
3834         }
3835         case TOK_INCLUDE:
3836         {
3837                 char *name;
3838                 char *ptr;
3839                 int local;
3840                 local = 0;
3841                 name = 0;
3842                 next_token(state, index);
3843                 if (tk->tok == TOK_LIT_STRING) {
3844                         const char *token;
3845                         int name_len;
3846                         name = xmalloc(tk->str_len, "include");
3847                         token = tk->val.str +1;
3848                         name_len = tk->str_len -2;
3849                         if (*token == '"') {
3850                                 token++;
3851                                 name_len--;
3852                         }
3853                         memcpy(name, token, name_len);
3854                         name[name_len] = '\0';
3855                         local = 1;
3856                 }
3857                 else if (tk->tok == TOK_LESS) {
3858                         char *start, *end;
3859                         start = file->pos;
3860                         for(end = start; *end != '\n'; end++) {
3861                                 if (*end == '>') {
3862                                         break;
3863                                 }
3864                         }
3865                         if (*end == '\n') {
3866                                 error(state, 0, "Unterminated included directive");
3867                         }
3868                         name = xmalloc(end - start + 1, "include");
3869                         memcpy(name, start, end - start);
3870                         name[end - start] = '\0';
3871                         file->pos = end +1;
3872                         local = 0;
3873                 }
3874                 else {
3875                         error(state, 0, "Invalid include directive");
3876                 }
3877                 /* Error if there are any characters after the include */
3878                 for(ptr = file->pos; *ptr != '\n'; ptr++) {
3879                         switch(*ptr) {
3880                         case ' ':
3881                         case '\t':
3882                         case '\v':
3883                                 break;
3884                         default:
3885                                 error(state, 0, "garbage after include directive");
3886                         }
3887                 }
3888                 if (state->if_value >= 0) {
3889                         compile_file(state, name, local);
3890                 }
3891                 xfree(name);
3892                 next_token(state, index);
3893                 return;
3894         }
3895         default:
3896                 /* Ignore # without a following ident */
3897                 if (tk->tok == TOK_IDENT) {
3898                         error(state, 0, "Invalid preprocessor directive: %s", 
3899                                 tk->ident->name);
3900                 }
3901                 break;
3902         }
3903         /* Consume the rest of the macro line */
3904         do {
3905                 tok = mpeek(state, index);
3906                 meat(state, index, tok);
3907         } while(tok != TOK_EOF);
3908         return;
3909 }
3910
3911 static void token(struct compile_state *state, int index)
3912 {
3913         struct file_state *file;
3914         struct token *tk;
3915         int rescan;
3916
3917         tk = &state->token[index];
3918         next_token(state, index);
3919         do {
3920                 rescan = 0;
3921                 file = state->file;
3922                 if (tk->tok == TOK_EOF && file->prev) {
3923                         state->file = file->prev;
3924                         /* file->basename is used keep it */
3925                         xfree(file->dirname);
3926                         xfree(file->buf);
3927                         xfree(file);
3928                         next_token(state, index);
3929                         rescan = 1;
3930                 }
3931                 else if (tk->tok == TOK_MACRO) {
3932                         preprocess(state, index);
3933                         rescan = 1;
3934                 }
3935                 else if (tk->ident && tk->ident->sym_define) {
3936                         compile_macro(state, tk);
3937                         next_token(state, index);
3938                         rescan = 1;
3939                 }
3940                 else if (state->if_value < 0) {
3941                         next_token(state, index);
3942                         rescan = 1;
3943                 }
3944         } while(rescan);
3945 }
3946
3947 static int peek(struct compile_state *state)
3948 {
3949         if (state->token[1].tok == -1) {
3950                 token(state, 1);
3951         }
3952         return state->token[1].tok;
3953 }
3954
3955 static int peek2(struct compile_state *state)
3956 {
3957         if (state->token[1].tok == -1) {
3958                 token(state, 1);
3959         }
3960         if (state->token[2].tok == -1) {
3961                 token(state, 2);
3962         }
3963         return state->token[2].tok;
3964 }
3965
3966 static void eat(struct compile_state *state, int tok)
3967 {
3968         int next_tok;
3969         int i;
3970         next_tok = peek(state);
3971         if (next_tok != tok) {
3972                 const char *name1, *name2;
3973                 name1 = tokens[next_tok];
3974                 name2 = "";
3975                 if (next_tok == TOK_IDENT) {
3976                         name2 = state->token[1].ident->name;
3977                 }
3978                 error(state, 0, "\tfound %s %s expected %s",
3979                         name1, name2 ,tokens[tok]);
3980         }
3981         /* Free the old token value */
3982         if (state->token[0].str_len) {
3983                 xfree((void *)(state->token[0].val.str));
3984         }
3985         for(i = 0; i < sizeof(state->token)/sizeof(state->token[0]) - 1; i++) {
3986                 state->token[i] = state->token[i + 1];
3987         }
3988         memset(&state->token[i], 0, sizeof(state->token[i]));
3989         state->token[i].tok = -1;
3990 }
3991
3992 #warning "FIXME do not hardcode the include paths"
3993 static char *include_paths[] = {
3994         "/home/eric/projects/linuxbios/checkin/solo/freebios2/src/include",
3995         "/home/eric/projects/linuxbios/checkin/solo/freebios2/src/arch/i386/include",
3996         "/home/eric/projects/linuxbios/checkin/solo/freebios2/src",
3997         0
3998 };
3999
4000 static void compile_file(struct compile_state *state, const char *filename, int local)
4001 {
4002         char cwd[4096];
4003         const char *subdir, *base;
4004         int subdir_len;
4005         struct file_state *file;
4006         char *basename;
4007         file = xmalloc(sizeof(*file), "file_state");
4008
4009         base = strrchr(filename, '/');
4010         subdir = filename;
4011         if (base != 0) {
4012                 subdir_len = base - filename;
4013                 base++;
4014         }
4015         else {
4016                 base = filename;
4017                 subdir_len = 0;
4018         }
4019         basename = xmalloc(strlen(base) +1, "basename");
4020         strcpy(basename, base);
4021         file->basename = basename;
4022
4023         if (getcwd(cwd, sizeof(cwd)) == 0) {
4024                 die("cwd buffer to small");
4025         }
4026         
4027         if (subdir[0] == '/') {
4028                 file->dirname = xmalloc(subdir_len + 1, "dirname");
4029                 memcpy(file->dirname, subdir, subdir_len);
4030                 file->dirname[subdir_len] = '\0';
4031         }
4032         else {
4033                 char *dir;
4034                 int dirlen;
4035                 char **path;
4036                 /* Find the appropriate directory... */
4037                 dir = 0;
4038                 if (!state->file && exists(cwd, filename)) {
4039                         dir = cwd;
4040                 }
4041                 if (local && state->file && exists(state->file->dirname, filename)) {
4042                         dir = state->file->dirname;
4043                 }
4044                 for(path = include_paths; !dir && *path; path++) {
4045                         if (exists(*path, filename)) {
4046                                 dir = *path;
4047                         }
4048                 }
4049                 if (!dir) {
4050                         error(state, 0, "Cannot find `%s'\n", filename);
4051                 }
4052                 dirlen = strlen(dir);
4053                 file->dirname = xmalloc(dirlen + 1 + subdir_len + 1, "dirname");
4054                 memcpy(file->dirname, dir, dirlen);
4055                 file->dirname[dirlen] = '/';
4056                 memcpy(file->dirname + dirlen + 1, subdir, subdir_len);
4057                 file->dirname[dirlen + 1 + subdir_len] = '\0';
4058         }
4059         file->buf = slurp_file(file->dirname, file->basename, &file->size);
4060         xchdir(cwd);
4061
4062         file->pos = file->buf;
4063         file->line_start = file->pos;
4064         file->line = 1;
4065
4066         file->report_line = 1;
4067         file->report_name = file->basename;
4068         file->report_dir  = file->dirname;
4069
4070         file->prev = state->file;
4071         state->file = file;
4072         
4073         process_trigraphs(state);
4074         splice_lines(state);
4075 }
4076
4077 /* Type helper functions */
4078
4079 static struct type *new_type(
4080         unsigned int type, struct type *left, struct type *right)
4081 {
4082         struct type *result;
4083         result = xmalloc(sizeof(*result), "type");
4084         result->type = type;
4085         result->left = left;
4086         result->right = right;
4087         result->field_ident = 0;
4088         result->type_ident = 0;
4089         return result;
4090 }
4091
4092 static struct type *clone_type(unsigned int specifiers, struct type *old)
4093 {
4094         struct type *result;
4095         result = xmalloc(sizeof(*result), "type");
4096         memcpy(result, old, sizeof(*result));
4097         result->type &= TYPE_MASK;
4098         result->type |= specifiers;
4099         return result;
4100 }
4101
4102 #define SIZEOF_SHORT 2
4103 #define SIZEOF_INT   4
4104 #define SIZEOF_LONG  (sizeof(long_t))
4105
4106 #define ALIGNOF_SHORT 2
4107 #define ALIGNOF_INT   4
4108 #define ALIGNOF_LONG  (sizeof(long_t))
4109
4110 #define MASK_UCHAR(X)    ((X) & ((ulong_t)0xff))
4111 #define MASK_USHORT(X)   ((X) & (((ulong_t)1 << (SIZEOF_SHORT*8)) - 1))
4112 static inline ulong_t mask_uint(ulong_t x)
4113 {
4114         if (SIZEOF_INT < SIZEOF_LONG) {
4115                 ulong_t mask = (((ulong_t)1) << ((ulong_t)(SIZEOF_INT*8))) -1;
4116                 x &= mask;
4117         }
4118         return x;
4119 }
4120 #define MASK_UINT(X)      (mask_uint(X))
4121 #define MASK_ULONG(X)    (X)
4122
4123 static struct type void_type   = { .type  = TYPE_VOID };
4124 static struct type char_type   = { .type  = TYPE_CHAR };
4125 static struct type uchar_type  = { .type  = TYPE_UCHAR };
4126 static struct type short_type  = { .type  = TYPE_SHORT };
4127 static struct type ushort_type = { .type  = TYPE_USHORT };
4128 static struct type int_type    = { .type  = TYPE_INT };
4129 static struct type uint_type   = { .type  = TYPE_UINT };
4130 static struct type long_type   = { .type  = TYPE_LONG };
4131 static struct type ulong_type  = { .type  = TYPE_ULONG };
4132
4133 static struct type void_ptr_type  = {
4134         .type = TYPE_POINTER,
4135         .left = &void_type,
4136 };
4137
4138 static struct type void_func_type = { 
4139         .type  = TYPE_FUNCTION,
4140         .left  = &void_type,
4141         .right = &void_type,
4142 };
4143
4144 static struct triple *variable(struct compile_state *state, struct type *type)
4145 {
4146         struct triple *result;
4147         if ((type->type & STOR_MASK) != STOR_PERM) {
4148                 if ((type->type & TYPE_MASK) != TYPE_STRUCT) {
4149                         result = triple(state, OP_ADECL, type, 0, 0);
4150                 } else {
4151                         struct type *field;
4152                         struct triple **vector;
4153                         ulong_t index;
4154                         result = new_triple(state, OP_VAL_VEC, type, -1, -1);
4155                         vector = &result->param[0];
4156
4157                         field = type->left;
4158                         index = 0;
4159                         while((field->type & TYPE_MASK) == TYPE_PRODUCT) {
4160                                 vector[index] = variable(state, field->left);
4161                                 field = field->right;
4162                                 index++;
4163                         }
4164                         vector[index] = variable(state, field);
4165                 }
4166         }
4167         else {
4168                 result = triple(state, OP_SDECL, type, 0, 0);
4169         }
4170         return result;
4171 }
4172
4173 static void stor_of(FILE *fp, struct type *type)
4174 {
4175         switch(type->type & STOR_MASK) {
4176         case STOR_AUTO:
4177                 fprintf(fp, "auto ");
4178                 break;
4179         case STOR_STATIC:
4180                 fprintf(fp, "static ");
4181                 break;
4182         case STOR_LOCAL:
4183                 fprintf(fp, "local ");
4184                 break;
4185         case STOR_EXTERN:
4186                 fprintf(fp, "extern ");
4187                 break;
4188         case STOR_REGISTER:
4189                 fprintf(fp, "register ");
4190                 break;
4191         case STOR_TYPEDEF:
4192                 fprintf(fp, "typedef ");
4193                 break;
4194         case STOR_INLINE | STOR_LOCAL:
4195                 fprintf(fp, "inline ");
4196                 break;
4197         case STOR_INLINE | STOR_STATIC:
4198                 fprintf(fp, "static inline");
4199                 break;
4200         case STOR_INLINE | STOR_EXTERN:
4201                 fprintf(fp, "extern inline");
4202                 break;
4203         default:
4204                 fprintf(fp, "stor:%x", type->type & STOR_MASK);
4205                 break;
4206         }
4207 }
4208 static void qual_of(FILE *fp, struct type *type)
4209 {
4210         if (type->type & QUAL_CONST) {
4211                 fprintf(fp, " const");
4212         }
4213         if (type->type & QUAL_VOLATILE) {
4214                 fprintf(fp, " volatile");
4215         }
4216         if (type->type & QUAL_RESTRICT) {
4217                 fprintf(fp, " restrict");
4218         }
4219 }
4220
4221 static void name_of(FILE *fp, struct type *type)
4222 {
4223         stor_of(fp, type);
4224         switch(type->type & TYPE_MASK) {
4225         case TYPE_VOID:
4226                 fprintf(fp, "void");
4227                 qual_of(fp, type);
4228                 break;
4229         case TYPE_CHAR:
4230                 fprintf(fp, "signed char");
4231                 qual_of(fp, type);
4232                 break;
4233         case TYPE_UCHAR:
4234                 fprintf(fp, "unsigned char");
4235                 qual_of(fp, type);
4236                 break;
4237         case TYPE_SHORT:
4238                 fprintf(fp, "signed short");
4239                 qual_of(fp, type);
4240                 break;
4241         case TYPE_USHORT:
4242                 fprintf(fp, "unsigned short");
4243                 qual_of(fp, type);
4244                 break;
4245         case TYPE_INT:
4246                 fprintf(fp, "signed int");
4247                 qual_of(fp, type);
4248                 break;
4249         case TYPE_UINT:
4250                 fprintf(fp, "unsigned int");
4251                 qual_of(fp, type);
4252                 break;
4253         case TYPE_LONG:
4254                 fprintf(fp, "signed long");
4255                 qual_of(fp, type);
4256                 break;
4257         case TYPE_ULONG:
4258                 fprintf(fp, "unsigned long");
4259                 qual_of(fp, type);
4260                 break;
4261         case TYPE_POINTER:
4262                 name_of(fp, type->left);
4263                 fprintf(fp, " * ");
4264                 qual_of(fp, type);
4265                 break;
4266         case TYPE_PRODUCT:
4267         case TYPE_OVERLAP:
4268                 name_of(fp, type->left);
4269                 fprintf(fp, ", ");
4270                 name_of(fp, type->right);
4271                 break;
4272         case TYPE_ENUM:
4273                 fprintf(fp, "enum %s", type->type_ident->name);
4274                 qual_of(fp, type);
4275                 break;
4276         case TYPE_STRUCT:
4277                 fprintf(fp, "struct %s", type->type_ident->name);
4278                 qual_of(fp, type);
4279                 break;
4280         case TYPE_FUNCTION:
4281         {
4282                 name_of(fp, type->left);
4283                 fprintf(fp, " (*)(");
4284                 name_of(fp, type->right);
4285                 fprintf(fp, ")");
4286                 break;
4287         }
4288         case TYPE_ARRAY:
4289                 name_of(fp, type->left);
4290                 fprintf(fp, " [%ld]", (long)(type->elements));
4291                 break;
4292         default:
4293                 fprintf(fp, "????: %x", type->type & TYPE_MASK);
4294                 break;
4295         }
4296 }
4297
4298 static size_t align_of(struct compile_state *state, struct type *type)
4299 {
4300         size_t align;
4301         align = 0;
4302         switch(type->type & TYPE_MASK) {
4303         case TYPE_VOID:
4304                 align = 1;
4305                 break;
4306         case TYPE_CHAR:
4307         case TYPE_UCHAR:
4308                 align = 1;
4309                 break;
4310         case TYPE_SHORT:
4311         case TYPE_USHORT:
4312                 align = ALIGNOF_SHORT;
4313                 break;
4314         case TYPE_INT:
4315         case TYPE_UINT:
4316         case TYPE_ENUM:
4317                 align = ALIGNOF_INT;
4318                 break;
4319         case TYPE_LONG:
4320         case TYPE_ULONG:
4321         case TYPE_POINTER:
4322                 align = ALIGNOF_LONG;
4323                 break;
4324         case TYPE_PRODUCT:
4325         case TYPE_OVERLAP:
4326         {
4327                 size_t left_align, right_align;
4328                 left_align  = align_of(state, type->left);
4329                 right_align = align_of(state, type->right);
4330                 align = (left_align >= right_align) ? left_align : right_align;
4331                 break;
4332         }
4333         case TYPE_ARRAY:
4334                 align = align_of(state, type->left);
4335                 break;
4336         case TYPE_STRUCT:
4337                 align = align_of(state, type->left);
4338                 break;
4339         default:
4340                 error(state, 0, "alignof not yet defined for type\n");
4341                 break;
4342         }
4343         return align;
4344 }
4345
4346 static size_t needed_padding(size_t offset, size_t align)
4347 {
4348         size_t padding;
4349         padding = 0;
4350         if (offset % align) {
4351                 padding = align - (offset % align);
4352         }
4353         return padding;
4354 }
4355 static size_t size_of(struct compile_state *state, struct type *type)
4356 {
4357         size_t size;
4358         size = 0;
4359         switch(type->type & TYPE_MASK) {
4360         case TYPE_VOID:
4361                 size = 0;
4362                 break;
4363         case TYPE_CHAR:
4364         case TYPE_UCHAR:
4365                 size = 1;
4366                 break;
4367         case TYPE_SHORT:
4368         case TYPE_USHORT:
4369                 size = SIZEOF_SHORT;
4370                 break;
4371         case TYPE_INT:
4372         case TYPE_UINT:
4373         case TYPE_ENUM:
4374                 size = SIZEOF_INT;
4375                 break;
4376         case TYPE_LONG:
4377         case TYPE_ULONG:
4378         case TYPE_POINTER:
4379                 size = SIZEOF_LONG;
4380                 break;
4381         case TYPE_PRODUCT:
4382         {
4383                 size_t align, pad;
4384                 size = 0;
4385                 while((type->type & TYPE_MASK) == TYPE_PRODUCT) {
4386                         align = align_of(state, type->left);
4387                         pad = needed_padding(size, align);
4388                         size = size + pad + size_of(state, type->left);
4389                         type = type->right;
4390                 }
4391                 align = align_of(state, type);
4392                 pad = needed_padding(size, align);
4393                 size = size + pad + size_of(state, type);
4394                 break;
4395         }
4396         case TYPE_OVERLAP:
4397         {
4398                 size_t size_left, size_right;
4399                 size_left = size_of(state, type->left);
4400                 size_right = size_of(state, type->right);
4401                 size = (size_left >= size_right)? size_left : size_right;
4402                 break;
4403         }
4404         case TYPE_ARRAY:
4405                 if (type->elements == ELEMENT_COUNT_UNSPECIFIED) {
4406                         internal_error(state, 0, "Invalid array type");
4407                 } else {
4408                         size = size_of(state, type->left) * type->elements;
4409                 }
4410                 break;
4411         case TYPE_STRUCT:
4412         {
4413                 size_t align, pad;
4414                 size = size_of(state, type->left);
4415                 /* Pad structures so their size is a multiples of their alignment */
4416                 align = align_of(state, type);
4417                 pad = needed_padding(size, align);
4418                 size = size + pad;
4419                 break;
4420         }
4421         default:
4422                 internal_error(state, 0, "sizeof not yet defined for type\n");
4423                 break;
4424         }
4425         return size;
4426 }
4427
4428 static size_t field_offset(struct compile_state *state, 
4429         struct type *type, struct hash_entry *field)
4430 {
4431         struct type *member;
4432         size_t size, align;
4433         if ((type->type & TYPE_MASK) != TYPE_STRUCT) {
4434                 internal_error(state, 0, "field_offset only works on structures");
4435         }
4436         size = 0;
4437         member = type->left;
4438         while((member->type & TYPE_MASK) == TYPE_PRODUCT) {
4439                 align = align_of(state, member->left);
4440                 size += needed_padding(size, align);
4441                 if (member->left->field_ident == field) {
4442                         member = member->left;
4443                         break;
4444                 }
4445                 size += size_of(state, member->left);
4446                 member = member->right;
4447         }
4448         align = align_of(state, member);
4449         size += needed_padding(size, align);
4450         if (member->field_ident != field) {
4451                 error(state, 0, "member %s not present", field->name);
4452         }
4453         return size;
4454 }
4455
4456 static struct type *field_type(struct compile_state *state, 
4457         struct type *type, struct hash_entry *field)
4458 {
4459         struct type *member;
4460         if ((type->type & TYPE_MASK) != TYPE_STRUCT) {
4461                 internal_error(state, 0, "field_type only works on structures");
4462         }
4463         member = type->left;
4464         while((member->type & TYPE_MASK) == TYPE_PRODUCT) {
4465                 if (member->left->field_ident == field) {
4466                         member = member->left;
4467                         break;
4468                 }
4469                 member = member->right;
4470         }
4471         if (member->field_ident != field) {
4472                 error(state, 0, "member %s not present", field->name);
4473         }
4474         return member;
4475 }
4476
4477 static struct type *next_field(struct compile_state *state,
4478         struct type *type, struct type *prev_member) 
4479 {
4480         struct type *member;
4481         if ((type->type & TYPE_MASK) != TYPE_STRUCT) {
4482                 internal_error(state, 0, "next_field only works on structures");
4483         }
4484         member = type->left;
4485         while((member->type & TYPE_MASK) == TYPE_PRODUCT) {
4486                 if (!prev_member) {
4487                         member = member->left;
4488                         break;
4489                 }
4490                 if (member->left == prev_member) {
4491                         prev_member = 0;
4492                 }
4493                 member = member->right;
4494         }
4495         if (member == prev_member) {
4496                 prev_member = 0;
4497         }
4498         if (prev_member) {
4499                 internal_error(state, 0, "prev_member %s not present", 
4500                         prev_member->field_ident->name);
4501         }
4502         return member;
4503 }
4504
4505 static struct triple *struct_field(struct compile_state *state,
4506         struct triple *decl, struct hash_entry *field)
4507 {
4508         struct triple **vector;
4509         struct type *type;
4510         ulong_t index;
4511         type = decl->type;
4512         if ((type->type & TYPE_MASK) != TYPE_STRUCT) {
4513                 return decl;
4514         }
4515         if (decl->op != OP_VAL_VEC) {
4516                 internal_error(state, 0, "Invalid struct variable");
4517         }
4518         if (!field) {
4519                 internal_error(state, 0, "Missing structure field");
4520         }
4521         type = type->left;
4522         vector = &RHS(decl, 0);
4523         index = 0;
4524         while((type->type & TYPE_MASK) == TYPE_PRODUCT) {
4525                 if (type->left->field_ident == field) {
4526                         type = type->left;
4527                         break;
4528                 }
4529                 index += 1;
4530                 type = type->right;
4531         }
4532         if (type->field_ident != field) {
4533                 internal_error(state, 0, "field %s not found?", field->name);
4534         }
4535         return vector[index];
4536 }
4537
4538 static void arrays_complete(struct compile_state *state, struct type *type)
4539 {
4540         if ((type->type & TYPE_MASK) == TYPE_ARRAY) {
4541                 if (type->elements == ELEMENT_COUNT_UNSPECIFIED) {
4542                         error(state, 0, "array size not specified");
4543                 }
4544                 arrays_complete(state, type->left);
4545         }
4546 }
4547
4548 static unsigned int do_integral_promotion(unsigned int type)
4549 {
4550         type &= TYPE_MASK;
4551         if (type == TYPE_ENUM) type = TYPE_INT;
4552         if (TYPE_INTEGER(type) && (TYPE_RANK(type) < TYPE_RANK(TYPE_INT))) {
4553                 type = TYPE_INT;
4554         }
4555         return type;
4556 }
4557
4558 static unsigned int do_arithmetic_conversion(
4559         unsigned int left, unsigned int right)
4560 {
4561         left &= TYPE_MASK;
4562         right &= TYPE_MASK;
4563         /* Convert enums to ints */
4564         if (left == TYPE_ENUM) left = TYPE_INT;
4565         if (right == TYPE_ENUM) right = TYPE_INT;
4566         if ((left == TYPE_LDOUBLE) || (right == TYPE_LDOUBLE)) {
4567                 return TYPE_LDOUBLE;
4568         }
4569         else if ((left == TYPE_DOUBLE) || (right == TYPE_DOUBLE)) {
4570                 return TYPE_DOUBLE;
4571         }
4572         else if ((left == TYPE_FLOAT) || (right == TYPE_FLOAT)) {
4573                 return TYPE_FLOAT;
4574         }
4575         left = do_integral_promotion(left);
4576         right = do_integral_promotion(right);
4577         /* If both operands have the same size done */
4578         if (left == right) {
4579                 return left;
4580         }
4581         /* If both operands have the same signedness pick the larger */
4582         else if (!!TYPE_UNSIGNED(left) == !!TYPE_UNSIGNED(right)) {
4583                 return (TYPE_RANK(left) >= TYPE_RANK(right)) ? left : right;
4584         }
4585         /* If the signed type can hold everything use it */
4586         else if (TYPE_SIGNED(left) && (TYPE_RANK(left) > TYPE_RANK(right))) {
4587                 return left;
4588         }
4589         else if (TYPE_SIGNED(right) && (TYPE_RANK(right) > TYPE_RANK(left))) {
4590                 return right;
4591         }
4592         /* Convert to the unsigned type with the same rank as the signed type */
4593         else if (TYPE_SIGNED(left)) {
4594                 return TYPE_MKUNSIGNED(left);
4595         }
4596         else {
4597                 return TYPE_MKUNSIGNED(right);
4598         }
4599 }
4600
4601 /* see if two types are the same except for qualifiers */
4602 static int equiv_types(struct type *left, struct type *right)
4603 {
4604         unsigned int type;
4605         /* Error if the basic types do not match */
4606         if ((left->type & TYPE_MASK) != (right->type & TYPE_MASK)) {
4607                 return 0;
4608         }
4609         type = left->type & TYPE_MASK;
4610         /* If the basic types match and it is a void type we are done */
4611         if (type == TYPE_VOID) {
4612                 return 1;
4613         }
4614         /* if the basic types match and it is an arithmetic type we are done */
4615         if (TYPE_ARITHMETIC(type)) {
4616                 return 1;
4617         }
4618         /* If it is a pointer type recurse and keep testing */
4619         if (type == TYPE_POINTER) {
4620                 return equiv_types(left->left, right->left);
4621         }
4622         else if (type == TYPE_ARRAY) {
4623                 return (left->elements == right->elements) &&
4624                         equiv_types(left->left, right->left);
4625         }
4626         /* test for struct/union equality */
4627         else if (type == TYPE_STRUCT) {
4628                 return left->type_ident == right->type_ident;
4629         }
4630         /* Test for equivalent functions */
4631         else if (type == TYPE_FUNCTION) {
4632                 return equiv_types(left->left, right->left) &&
4633                         equiv_types(left->right, right->right);
4634         }
4635         /* We only see TYPE_PRODUCT as part of function equivalence matching */
4636         else if (type == TYPE_PRODUCT) {
4637                 return equiv_types(left->left, right->left) &&
4638                         equiv_types(left->right, right->right);
4639         }
4640         /* We should see TYPE_OVERLAP */
4641         else {
4642                 return 0;
4643         }
4644 }
4645
4646 static int equiv_ptrs(struct type *left, struct type *right)
4647 {
4648         if (((left->type & TYPE_MASK) != TYPE_POINTER) ||
4649                 ((right->type & TYPE_MASK) != TYPE_POINTER)) {
4650                 return 0;
4651         }
4652         return equiv_types(left->left, right->left);
4653 }
4654
4655 static struct type *compatible_types(struct type *left, struct type *right)
4656 {
4657         struct type *result;
4658         unsigned int type, qual_type;
4659         /* Error if the basic types do not match */
4660         if ((left->type & TYPE_MASK) != (right->type & TYPE_MASK)) {
4661                 return 0;
4662         }
4663         type = left->type & TYPE_MASK;
4664         qual_type = (left->type & ~STOR_MASK) | (right->type & ~STOR_MASK);
4665         result = 0;
4666         /* if the basic types match and it is an arithmetic type we are done */
4667         if (TYPE_ARITHMETIC(type)) {
4668                 result = new_type(qual_type, 0, 0);
4669         }
4670         /* If it is a pointer type recurse and keep testing */
4671         else if (type == TYPE_POINTER) {
4672                 result = compatible_types(left->left, right->left);
4673                 if (result) {
4674                         result = new_type(qual_type, result, 0);
4675                 }
4676         }
4677         /* test for struct/union equality */
4678         else if (type == TYPE_STRUCT) {
4679                 if (left->type_ident == right->type_ident) {
4680                         result = left;
4681                 }
4682         }
4683         /* Test for equivalent functions */
4684         else if (type == TYPE_FUNCTION) {
4685                 struct type *lf, *rf;
4686                 lf = compatible_types(left->left, right->left);
4687                 rf = compatible_types(left->right, right->right);
4688                 if (lf && rf) {
4689                         result = new_type(qual_type, lf, rf);
4690                 }
4691         }
4692         /* We only see TYPE_PRODUCT as part of function equivalence matching */
4693         else if (type == TYPE_PRODUCT) {
4694                 struct type *lf, *rf;
4695                 lf = compatible_types(left->left, right->left);
4696                 rf = compatible_types(left->right, right->right);
4697                 if (lf && rf) {
4698                         result = new_type(qual_type, lf, rf);
4699                 }
4700         }
4701         else {
4702                 /* Nothing else is compatible */
4703         }
4704         return result;
4705 }
4706
4707 static struct type *compatible_ptrs(struct type *left, struct type *right)
4708 {
4709         struct type *result;
4710         if (((left->type & TYPE_MASK) != TYPE_POINTER) ||
4711                 ((right->type & TYPE_MASK) != TYPE_POINTER)) {
4712                 return 0;
4713         }
4714         result = compatible_types(left->left, right->left);
4715         if (result) {
4716                 unsigned int qual_type;
4717                 qual_type = (left->type & ~STOR_MASK) | (right->type & ~STOR_MASK);
4718                 result = new_type(qual_type, result, 0);
4719         }
4720         return result;
4721         
4722 }
4723 static struct triple *integral_promotion(
4724         struct compile_state *state, struct triple *def)
4725 {
4726         struct type *type;
4727         type = def->type;
4728         /* As all operations are carried out in registers
4729          * the values are converted on load I just convert
4730          * logical type of the operand.
4731          */
4732         if (TYPE_INTEGER(type->type)) {
4733                 unsigned int int_type;
4734                 int_type = type->type & ~TYPE_MASK;
4735                 int_type |= do_integral_promotion(type->type);
4736                 if (int_type != type->type) {
4737                         if (def->op != OP_LOAD) {
4738                                 def->type = new_type(int_type, 0, 0);
4739                         }
4740                         else {
4741 #warning "FIXME can I just cast all operands like this?"
4742                                 def = triple(state, OP_COPY, 
4743                                         new_type(int_type, 0, 0), def, 0);
4744                         }
4745                 }
4746         }
4747         return def;
4748 }
4749
4750
4751 static void arithmetic(struct compile_state *state, struct triple *def)
4752 {
4753         if (!TYPE_ARITHMETIC(def->type->type)) {
4754                 error(state, 0, "arithmetic type expexted");
4755         }
4756 }
4757
4758 static void ptr_arithmetic(struct compile_state *state, struct triple *def)
4759 {
4760         if (!TYPE_PTR(def->type->type) && !TYPE_ARITHMETIC(def->type->type)) {
4761                 error(state, def, "pointer or arithmetic type expected");
4762         }
4763 }
4764
4765 static int is_integral(struct triple *ins)
4766 {
4767         return TYPE_INTEGER(ins->type->type);
4768 }
4769
4770 static void integral(struct compile_state *state, struct triple *def)
4771 {
4772         if (!is_integral(def)) {
4773                 error(state, 0, "integral type expected");
4774         }
4775 }
4776
4777
4778 static void bool(struct compile_state *state, struct triple *def)
4779 {
4780         if (!TYPE_ARITHMETIC(def->type->type) &&
4781                 ((def->type->type & TYPE_MASK) != TYPE_POINTER)) {
4782                 error(state, 0, "arithmetic or pointer type expected");
4783         }
4784 }
4785
4786 static int is_signed(struct type *type)
4787 {
4788         return !!TYPE_SIGNED(type->type);
4789 }
4790
4791 /* Is this value located in a register otherwise it must be in memory */
4792 static int is_in_reg(struct compile_state *state, struct triple *def)
4793 {
4794         int in_reg;
4795         if (def->op == OP_ADECL) {
4796                 in_reg = 1;
4797         }
4798         else if ((def->op == OP_SDECL) || (def->op == OP_DEREF)) {
4799                 in_reg = 0;
4800         }
4801         else if (def->op == OP_VAL_VEC) {
4802                 in_reg = is_in_reg(state, RHS(def, 0));
4803         }
4804         else if (def->op == OP_DOT) {
4805                 in_reg = is_in_reg(state, RHS(def, 0));
4806         }
4807         else {
4808                 internal_error(state, 0, "unknown expr storage location");
4809                 in_reg = -1;
4810         }
4811         return in_reg;
4812 }
4813
4814 /* Is this a stable variable location otherwise it must be a temporary */
4815 static int is_stable(struct compile_state *state, struct triple *def)
4816 {
4817         int ret;
4818         ret = 0;
4819         if (!def) {
4820                 return 0;
4821         }
4822         if ((def->op == OP_ADECL) || 
4823                 (def->op == OP_SDECL) || 
4824                 (def->op == OP_DEREF) ||
4825                 (def->op == OP_BLOBCONST)) {
4826                 ret = 1;
4827         }
4828         else if (def->op == OP_DOT) {
4829                 ret = is_stable(state, RHS(def, 0));
4830         }
4831         else if (def->op == OP_VAL_VEC) {
4832                 struct triple **vector;
4833                 ulong_t i;
4834                 ret = 1;
4835                 vector = &RHS(def, 0);
4836                 for(i = 0; i < def->type->elements; i++) {
4837                         if (!is_stable(state, vector[i])) {
4838                                 ret = 0;
4839                                 break;
4840                         }
4841                 }
4842         }
4843         return ret;
4844 }
4845
4846 static int is_lvalue(struct compile_state *state, struct triple *def)
4847 {
4848         int ret;
4849         ret = 1;
4850         if (!def) {
4851                 return 0;
4852         }
4853         if (!is_stable(state, def)) {
4854                 return 0;
4855         }
4856         if (def->op == OP_DOT) {
4857                 ret = is_lvalue(state, RHS(def, 0));
4858         }
4859         return ret;
4860 }
4861
4862 static void clvalue(struct compile_state *state, struct triple *def)
4863 {
4864         if (!def) {
4865                 internal_error(state, def, "nothing where lvalue expected?");
4866         }
4867         if (!is_lvalue(state, def)) { 
4868                 error(state, def, "lvalue expected");
4869         }
4870 }
4871 static void lvalue(struct compile_state *state, struct triple *def)
4872 {
4873         clvalue(state, def);
4874         if (def->type->type & QUAL_CONST) {
4875                 error(state, def, "modifable lvalue expected");
4876         }
4877 }
4878
4879 static int is_pointer(struct triple *def)
4880 {
4881         return (def->type->type & TYPE_MASK) == TYPE_POINTER;
4882 }
4883
4884 static void pointer(struct compile_state *state, struct triple *def)
4885 {
4886         if (!is_pointer(def)) {
4887                 error(state, def, "pointer expected");
4888         }
4889 }
4890
4891 static struct triple *int_const(
4892         struct compile_state *state, struct type *type, ulong_t value)
4893 {
4894         struct triple *result;
4895         switch(type->type & TYPE_MASK) {
4896         case TYPE_CHAR:
4897         case TYPE_INT:   case TYPE_UINT:
4898         case TYPE_LONG:  case TYPE_ULONG:
4899                 break;
4900         default:
4901                 internal_error(state, 0, "constant for unkown type");
4902         }
4903         result = triple(state, OP_INTCONST, type, 0, 0);
4904         result->u.cval = value;
4905         return result;
4906 }
4907
4908
4909 static struct triple *read_expr(struct compile_state *state, struct triple *def);
4910
4911 static struct triple *do_mk_addr_expr(struct compile_state *state, 
4912         struct triple *expr, struct type *type, ulong_t offset)
4913 {
4914         struct triple *result;
4915         clvalue(state, expr);
4916
4917         type = new_type(TYPE_POINTER | (type->type & QUAL_MASK), type, 0);
4918
4919         result = 0;
4920         if (expr->op == OP_ADECL) {
4921                 error(state, expr, "address of auto variables not supported");
4922         }
4923         else if (expr->op == OP_SDECL) {
4924                 result = triple(state, OP_ADDRCONST, type, 0, 0);
4925                 MISC(result, 0) = expr;
4926                 result->u.cval = offset;
4927         }
4928         else if (expr->op == OP_DEREF) {
4929                 result = triple(state, OP_ADD, type,
4930                         RHS(expr, 0),
4931                         int_const(state, &ulong_type, offset));
4932         }
4933         if (!result) {
4934                 internal_error(state, expr, "cannot take address of expression");
4935         }
4936         return result;
4937 }
4938
4939 static struct triple *mk_addr_expr(
4940         struct compile_state *state, struct triple *expr, ulong_t offset)
4941 {
4942         return do_mk_addr_expr(state, expr, expr->type, offset);
4943 }
4944
4945 static struct triple *mk_deref_expr(
4946         struct compile_state *state, struct triple *expr)
4947 {
4948         struct type *base_type;
4949         pointer(state, expr);
4950         base_type = expr->type->left;
4951         return triple(state, OP_DEREF, base_type, expr, 0);
4952 }
4953
4954 static struct triple *array_to_pointer(struct compile_state *state, struct triple *def)
4955 {
4956         if ((def->type->type & TYPE_MASK) == TYPE_ARRAY) {
4957                 struct type *type;
4958                 type = new_type(
4959                         TYPE_POINTER | (def->type->type & QUAL_MASK),
4960                         def->type->left, 0);
4961                 if ((def->op == OP_SDECL) || IS_CONST_OP(def->op)) {
4962                         struct triple *addrconst;
4963                         if ((def->op != OP_SDECL) && (def->op != OP_BLOBCONST)) {
4964                                 internal_error(state, def, "bad array constant");
4965                         }
4966                         addrconst = triple(state, OP_ADDRCONST, type, 0, 0);
4967                         MISC(addrconst, 0) = def;
4968                         def = addrconst;
4969                 }
4970                 else {
4971                         def = triple(state, OP_COPY, type, def, 0);
4972                 }
4973         }
4974         return def;
4975 }
4976
4977 static struct triple *deref_field(
4978         struct compile_state *state, struct triple *expr, struct hash_entry *field)
4979 {
4980         struct triple *result;
4981         struct type *type, *member;
4982         if (!field) {
4983                 internal_error(state, 0, "No field passed to deref_field");
4984         }
4985         result = 0;
4986         type = expr->type;
4987         if ((type->type & TYPE_MASK) != TYPE_STRUCT) {
4988                 error(state, 0, "request for member %s in something not a struct or union",
4989                         field->name);
4990         }
4991         member = field_type(state, type, field);
4992         if ((type->type & STOR_MASK) == STOR_PERM) {
4993                 /* Do the pointer arithmetic to get a deref the field */
4994                 ulong_t offset;
4995                 offset = field_offset(state, type, field);
4996                 result = do_mk_addr_expr(state, expr, member, offset);
4997                 result = mk_deref_expr(state, result);
4998         }
4999         else {
5000                 /* Find the variable for the field I want. */
5001                 result = triple(state, OP_DOT, member, expr, 0);
5002                 result->u.field = field;
5003         }
5004         return result;
5005 }
5006
5007 static struct triple *read_expr(struct compile_state *state, struct triple *def)
5008 {
5009         int op;
5010         if  (!def) {
5011                 return 0;
5012         }
5013         if (!is_stable(state, def)) {
5014                 return def;
5015         }
5016         /* Tranform an array to a pointer to the first element */
5017         
5018 #warning "CHECK_ME is this the right place to transform arrays to pointers?"
5019         if ((def->type->type & TYPE_MASK) == TYPE_ARRAY) {
5020                 return array_to_pointer(state, def);
5021         }
5022         if (is_in_reg(state, def)) {
5023                 op = OP_READ;
5024         } else {
5025                 if (def->op == OP_SDECL) {
5026                         def = mk_addr_expr(state, def, 0);
5027                         def = mk_deref_expr(state, def);
5028                 }
5029                 op = OP_LOAD;
5030         }
5031         return triple(state, op, def->type, def, 0);
5032 }
5033
5034 int is_write_compatible(struct compile_state *state, 
5035         struct type *dest, struct type *rval)
5036 {
5037         int compatible = 0;
5038         /* Both operands have arithmetic type */
5039         if (TYPE_ARITHMETIC(dest->type) && TYPE_ARITHMETIC(rval->type)) {
5040                 compatible = 1;
5041         }
5042         /* One operand is a pointer and the other is a pointer to void */
5043         else if (((dest->type & TYPE_MASK) == TYPE_POINTER) &&
5044                 ((rval->type & TYPE_MASK) == TYPE_POINTER) &&
5045                 (((dest->left->type & TYPE_MASK) == TYPE_VOID) ||
5046                         ((rval->left->type & TYPE_MASK) == TYPE_VOID))) {
5047                 compatible = 1;
5048         }
5049         /* If both types are the same without qualifiers we are good */
5050         else if (equiv_ptrs(dest, rval)) {
5051                 compatible = 1;
5052         }
5053         /* test for struct/union equality  */
5054         else if (((dest->type & TYPE_MASK) == TYPE_STRUCT) &&
5055                 ((rval->type & TYPE_MASK) == TYPE_STRUCT) &&
5056                 (dest->type_ident == rval->type_ident)) {
5057                 compatible = 1;
5058         }
5059         return compatible;
5060 }
5061
5062
5063 static void write_compatible(struct compile_state *state,
5064         struct type *dest, struct type *rval)
5065 {
5066         if (!is_write_compatible(state, dest, rval)) {
5067                 error(state, 0, "Incompatible types in assignment");
5068         }
5069 }
5070
5071 static int is_init_compatible(struct compile_state *state,
5072         struct type *dest, struct type *rval)
5073 {
5074         int compatible = 0;
5075         if (is_write_compatible(state, dest, rval)) {
5076                 compatible = 1;
5077         }
5078         else if (equiv_types(dest, rval)) {
5079                 compatible = 1;
5080         }
5081         return compatible;
5082 }
5083
5084 static struct triple *write_expr(
5085         struct compile_state *state, struct triple *dest, struct triple *rval)
5086 {
5087         struct triple *def;
5088         int op;
5089
5090         def = 0;
5091         if (!rval) {
5092                 internal_error(state, 0, "missing rval");
5093         }
5094
5095         if (rval->op == OP_LIST) {
5096                 internal_error(state, 0, "expression of type OP_LIST?");
5097         }
5098         if (!is_lvalue(state, dest)) {
5099                 internal_error(state, 0, "writing to a non lvalue?");
5100         }
5101         if (dest->type->type & QUAL_CONST) {
5102                 internal_error(state, 0, "modifable lvalue expexted");
5103         }
5104
5105         write_compatible(state, dest->type, rval->type);
5106
5107         /* Now figure out which assignment operator to use */
5108         op = -1;
5109         if (is_in_reg(state, dest)) {
5110                 op = OP_WRITE;
5111         } else {
5112                 op = OP_STORE;
5113         }
5114         def = triple(state, op, dest->type, dest, rval);
5115         return def;
5116 }
5117
5118 static struct triple *init_expr(
5119         struct compile_state *state, struct triple *dest, struct triple *rval)
5120 {
5121         struct triple *def;
5122
5123         def = 0;
5124         if (!rval) {
5125                 internal_error(state, 0, "missing rval");
5126         }
5127         if ((dest->type->type & STOR_MASK) != STOR_PERM) {
5128                 rval = read_expr(state, rval);
5129                 def = write_expr(state, dest, rval);
5130         }
5131         else {
5132                 /* Fill in the array size if necessary */
5133                 if (((dest->type->type & TYPE_MASK) == TYPE_ARRAY) &&
5134                         ((rval->type->type & TYPE_MASK) == TYPE_ARRAY)) {
5135                         if (dest->type->elements == ELEMENT_COUNT_UNSPECIFIED) {
5136                                 dest->type->elements = rval->type->elements;
5137                         }
5138                 }
5139                 if (!equiv_types(dest->type, rval->type)) {
5140                         error(state, 0, "Incompatible types in inializer");
5141                 }
5142                 MISC(dest, 0) = rval;
5143                 insert_triple(state, dest, rval);
5144                 rval->id |= TRIPLE_FLAG_FLATTENED;
5145                 use_triple(MISC(dest, 0), dest);
5146         }
5147         return def;
5148 }
5149
5150 struct type *arithmetic_result(
5151         struct compile_state *state, struct triple *left, struct triple *right)
5152 {
5153         struct type *type;
5154         /* Sanity checks to ensure I am working with arithmetic types */
5155         arithmetic(state, left);
5156         arithmetic(state, right);
5157         type = new_type(
5158                 do_arithmetic_conversion(
5159                         left->type->type, 
5160                         right->type->type), 0, 0);
5161         return type;
5162 }
5163
5164 struct type *ptr_arithmetic_result(
5165         struct compile_state *state, struct triple *left, struct triple *right)
5166 {
5167         struct type *type;
5168         /* Sanity checks to ensure I am working with the proper types */
5169         ptr_arithmetic(state, left);
5170         arithmetic(state, right);
5171         if (TYPE_ARITHMETIC(left->type->type) && 
5172                 TYPE_ARITHMETIC(right->type->type)) {
5173                 type = arithmetic_result(state, left, right);
5174         }
5175         else if (TYPE_PTR(left->type->type)) {
5176                 type = left->type;
5177         }
5178         else {
5179                 internal_error(state, 0, "huh?");
5180                 type = 0;
5181         }
5182         return type;
5183 }
5184
5185
5186 /* boolean helper function */
5187
5188 static struct triple *ltrue_expr(struct compile_state *state, 
5189         struct triple *expr)
5190 {
5191         switch(expr->op) {
5192         case OP_LTRUE:   case OP_LFALSE:  case OP_EQ:      case OP_NOTEQ:
5193         case OP_SLESS:   case OP_ULESS:   case OP_SMORE:   case OP_UMORE:
5194         case OP_SLESSEQ: case OP_ULESSEQ: case OP_SMOREEQ: case OP_UMOREEQ:
5195                 /* If the expression is already boolean do nothing */
5196                 break;
5197         default:
5198                 expr = triple(state, OP_LTRUE, &int_type, expr, 0);
5199                 break;
5200         }
5201         return expr;
5202 }
5203
5204 static struct triple *lfalse_expr(struct compile_state *state, 
5205         struct triple *expr)
5206 {
5207         return triple(state, OP_LFALSE, &int_type, expr, 0);
5208 }
5209
5210 static struct triple *cond_expr(
5211         struct compile_state *state, 
5212         struct triple *test, struct triple *left, struct triple *right)
5213 {
5214         struct triple *def;
5215         struct type *result_type;
5216         unsigned int left_type, right_type;
5217         bool(state, test);
5218         left_type = left->type->type;
5219         right_type = right->type->type;
5220         result_type = 0;
5221         /* Both operands have arithmetic type */
5222         if (TYPE_ARITHMETIC(left_type) && TYPE_ARITHMETIC(right_type)) {
5223                 result_type = arithmetic_result(state, left, right);
5224         }
5225         /* Both operands have void type */
5226         else if (((left_type & TYPE_MASK) == TYPE_VOID) &&
5227                 ((right_type & TYPE_MASK) == TYPE_VOID)) {
5228                 result_type = &void_type;
5229         }
5230         /* pointers to the same type... */
5231         else if ((result_type = compatible_ptrs(left->type, right->type))) {
5232                 ;
5233         }
5234         /* Both operands are pointers and left is a pointer to void */
5235         else if (((left_type & TYPE_MASK) == TYPE_POINTER) &&
5236                 ((right_type & TYPE_MASK) == TYPE_POINTER) &&
5237                 ((left->type->left->type & TYPE_MASK) == TYPE_VOID)) {
5238                 result_type = right->type;
5239         }
5240         /* Both operands are pointers and right is a pointer to void */
5241         else if (((left_type & TYPE_MASK) == TYPE_POINTER) &&
5242                 ((right_type & TYPE_MASK) == TYPE_POINTER) &&
5243                 ((right->type->left->type & TYPE_MASK) == TYPE_VOID)) {
5244                 result_type = left->type;
5245         }
5246         if (!result_type) {
5247                 error(state, 0, "Incompatible types in conditional expression");
5248         }
5249         /* Cleanup and invert the test */
5250         test = lfalse_expr(state, read_expr(state, test));
5251         def = new_triple(state, OP_COND, result_type, 0, 3);
5252         def->param[0] = test;
5253         def->param[1] = left;
5254         def->param[2] = right;
5255         return def;
5256 }
5257
5258
5259 static int expr_depth(struct compile_state *state, struct triple *ins)
5260 {
5261         int count;
5262         count = 0;
5263         if (!ins || (ins->id & TRIPLE_FLAG_FLATTENED)) {
5264                 count = 0;
5265         }
5266         else if (ins->op == OP_DEREF) {
5267                 count = expr_depth(state, RHS(ins, 0)) - 1;
5268         }
5269         else if (ins->op == OP_VAL) {
5270                 count = expr_depth(state, RHS(ins, 0)) - 1;
5271         }
5272         else if (ins->op == OP_COMMA) {
5273                 int ldepth, rdepth;
5274                 ldepth = expr_depth(state, RHS(ins, 0));
5275                 rdepth = expr_depth(state, RHS(ins, 1));
5276                 count = (ldepth >= rdepth)? ldepth : rdepth;
5277         }
5278         else if (ins->op == OP_FCALL) {
5279                 /* Don't figure the depth of a call just guess it is huge */
5280                 count = 1000;
5281         }
5282         else {
5283                 struct triple **expr;
5284                 expr = triple_rhs(state, ins, 0);
5285                 for(;expr; expr = triple_rhs(state, ins, expr)) {
5286                         if (*expr) {
5287                                 int depth;
5288                                 depth = expr_depth(state, *expr);
5289                                 if (depth > count) {
5290                                         count = depth;
5291                                 }
5292                         }
5293                 }
5294         }
5295         return count + 1;
5296 }
5297
5298 static struct triple *flatten(
5299         struct compile_state *state, struct triple *first, struct triple *ptr);
5300
5301 static struct triple *flatten_generic(
5302         struct compile_state *state, struct triple *first, struct triple *ptr,
5303         int ignored)
5304 {
5305         struct rhs_vector {
5306                 int depth;
5307                 struct triple **ins;
5308         } vector[MAX_RHS];
5309         int i, rhs, lhs;
5310         /* Only operations with just a rhs and a lhs should come here */
5311         rhs = TRIPLE_RHS(ptr->sizes);
5312         lhs = TRIPLE_LHS(ptr->sizes);
5313         if (TRIPLE_SIZE(ptr->sizes) != lhs + rhs + ignored) {
5314                 internal_error(state, ptr, "unexpected args for: %d %s",
5315                         ptr->op, tops(ptr->op));
5316         }
5317         /* Find the depth of the rhs elements */
5318         for(i = 0; i < rhs; i++) {
5319                 vector[i].ins = &RHS(ptr, i);
5320                 vector[i].depth = expr_depth(state, *vector[i].ins);
5321         }
5322         /* Selection sort the rhs */
5323         for(i = 0; i < rhs; i++) {
5324                 int j, max = i;
5325                 for(j = i + 1; j < rhs; j++ ) {
5326                         if (vector[j].depth > vector[max].depth) {
5327                                 max = j;
5328                         }
5329                 }
5330                 if (max != i) {
5331                         struct rhs_vector tmp;
5332                         tmp = vector[i];
5333                         vector[i] = vector[max];
5334                         vector[max] = tmp;
5335                 }
5336         }
5337         /* Now flatten the rhs elements */
5338         for(i = 0; i < rhs; i++) {
5339                 *vector[i].ins = flatten(state, first, *vector[i].ins);
5340                 use_triple(*vector[i].ins, ptr);
5341         }
5342         
5343         /* Now flatten the lhs elements */
5344         for(i = 0; i < lhs; i++) {
5345                 struct triple **ins = &LHS(ptr, i);
5346                 *ins = flatten(state, first, *ins);
5347                 use_triple(*ins, ptr);
5348         }
5349         return ptr;
5350 }
5351
5352 static struct triple *flatten_land(
5353         struct compile_state *state, struct triple *first, struct triple *ptr)
5354 {
5355         struct triple *left, *right;
5356         struct triple *val, *test, *jmp, *label1, *end;
5357
5358         /* Find the triples */
5359         left = RHS(ptr, 0);
5360         right = RHS(ptr, 1);
5361
5362         /* Generate the needed triples */
5363         end = label(state);
5364
5365         /* Thread the triples together */
5366         val          = flatten(state, first, variable(state, ptr->type));
5367         left         = flatten(state, first, write_expr(state, val, left));
5368         test         = flatten(state, first, 
5369                 lfalse_expr(state, read_expr(state, val)));
5370         jmp          = flatten(state, first, branch(state, end, test));
5371         label1       = flatten(state, first, label(state));
5372         right        = flatten(state, first, write_expr(state, val, right));
5373         TARG(jmp, 0) = flatten(state, first, end); 
5374         
5375         /* Now give the caller something to chew on */
5376         return read_expr(state, val);
5377 }
5378
5379 static struct triple *flatten_lor(
5380         struct compile_state *state, struct triple *first, struct triple *ptr)
5381 {
5382         struct triple *left, *right;
5383         struct triple *val, *jmp, *label1, *end;
5384
5385         /* Find the triples */
5386         left = RHS(ptr, 0);
5387         right = RHS(ptr, 1);
5388
5389         /* Generate the needed triples */
5390         end = label(state);
5391
5392         /* Thread the triples together */
5393         val          = flatten(state, first, variable(state, ptr->type));
5394         left         = flatten(state, first, write_expr(state, val, left));
5395         jmp          = flatten(state, first, branch(state, end, left));
5396         label1       = flatten(state, first, label(state));
5397         right        = flatten(state, first, write_expr(state, val, right));
5398         TARG(jmp, 0) = flatten(state, first, end);
5399        
5400         
5401         /* Now give the caller something to chew on */
5402         return read_expr(state, val);
5403 }
5404
5405 static struct triple *flatten_cond(
5406         struct compile_state *state, struct triple *first, struct triple *ptr)
5407 {
5408         struct triple *test, *left, *right;
5409         struct triple *val, *mv1, *jmp1, *label1, *mv2, *middle, *jmp2, *end;
5410
5411         /* Find the triples */
5412         test = RHS(ptr, 0);
5413         left = RHS(ptr, 1);
5414         right = RHS(ptr, 2);
5415
5416         /* Generate the needed triples */
5417         end = label(state);
5418         middle = label(state);
5419
5420         /* Thread the triples together */
5421         val           = flatten(state, first, variable(state, ptr->type));
5422         test          = flatten(state, first, test);
5423         jmp1          = flatten(state, first, branch(state, middle, test));
5424         label1        = flatten(state, first, label(state));
5425         left          = flatten(state, first, left);
5426         mv1           = flatten(state, first, write_expr(state, val, left));
5427         jmp2          = flatten(state, first, branch(state, end, 0));
5428         TARG(jmp1, 0) = flatten(state, first, middle);
5429         right         = flatten(state, first, right);
5430         mv2           = flatten(state, first, write_expr(state, val, right));
5431         TARG(jmp2, 0) = flatten(state, first, end);
5432         
5433         /* Now give the caller something to chew on */
5434         return read_expr(state, val);
5435 }
5436
5437 static struct triple *flatten_fcall(
5438         struct compile_state *state, struct triple *first, struct triple *ptr)
5439 {
5440         return flatten_generic(state, first, ptr, 1);
5441 }
5442
5443 static struct triple *flatten(
5444         struct compile_state *state, struct triple *first, struct triple *ptr)
5445 {
5446         struct triple *orig_ptr;
5447         if (!ptr)
5448                 return 0;
5449         do {
5450                 orig_ptr = ptr;
5451                 /* Only flatten triples once */
5452                 if (ptr->id & TRIPLE_FLAG_FLATTENED) {
5453                         return ptr;
5454                 }
5455                 switch(ptr->op) {
5456                 case OP_COMMA:
5457                         RHS(ptr, 0) = flatten(state, first, RHS(ptr, 0));
5458                         ptr = RHS(ptr, 1);
5459                         break;
5460                 case OP_VAL:
5461                         RHS(ptr, 0) = flatten(state, first, RHS(ptr, 0));
5462                         return MISC(ptr, 0);
5463                         break;
5464                 case OP_LAND:
5465                         ptr = flatten_land(state, first, ptr);
5466                         break;
5467                 case OP_LOR:
5468                         ptr = flatten_lor(state, first, ptr);
5469                         break;
5470                 case OP_COND:
5471                         ptr = flatten_cond(state, first, ptr);
5472                         break;
5473                 case OP_FCALL:
5474                         ptr = flatten_fcall(state, first, ptr);
5475                         break;
5476                 case OP_READ:
5477                 case OP_LOAD:
5478                         RHS(ptr, 0) = flatten(state, first, RHS(ptr, 0));
5479                         use_triple(RHS(ptr, 0), ptr);
5480                         break;
5481                 case OP_BRANCH:
5482                         use_triple(TARG(ptr, 0), ptr);
5483                         break;
5484                 case OP_CBRANCH:
5485                         RHS(ptr, 0) = flatten(state, first, RHS(ptr, 0));
5486                         use_triple(RHS(ptr, 0), ptr);
5487                         use_triple(TARG(ptr, 0), ptr);
5488                         if (ptr->next != ptr) {
5489                                 use_triple(ptr->next, ptr);
5490                         }
5491                         break;
5492                 case OP_CALL:
5493                         MISC(ptr, 0) = flatten(state, first, MISC(ptr, 0));
5494                         use_triple(MISC(ptr, 0), ptr);
5495                         use_triple(TARG(ptr, 0), ptr);
5496                         if (ptr->next != ptr) {
5497                                 use_triple(ptr->next, ptr);
5498                         }
5499                         break;
5500                 case OP_RET:
5501                         RHS(ptr, 0) = flatten(state, first, RHS(ptr, 0));
5502                         use_triple(RHS(ptr, 0), ptr);
5503                         break;
5504                 case OP_BLOBCONST:
5505                         insert_triple(state, state->global_pool, ptr);
5506                         ptr->id |= TRIPLE_FLAG_FLATTENED;
5507                         ptr->id &= ~TRIPLE_FLAG_LOCAL;
5508                         ptr = triple(state, OP_SDECL, ptr->type, ptr, 0);
5509                         use_triple(MISC(ptr, 0), ptr);
5510                         break;
5511                 case OP_DEREF:
5512                         /* Since OP_DEREF is just a marker delete it when I flatten it */
5513                         ptr = RHS(ptr, 0);
5514                         RHS(orig_ptr, 0) = 0;
5515                         free_triple(state, orig_ptr);
5516                         break;
5517                 case OP_DOT:
5518                 {
5519                         struct triple *base;
5520                         base = RHS(ptr, 0);
5521                         if (base->op == OP_DEREF) {
5522                                 struct triple *left;
5523                                 ulong_t offset;
5524                                 offset = field_offset(state, base->type, ptr->u.field);
5525                                 left = RHS(base, 0);
5526                                 ptr = triple(state, OP_ADD, left->type, 
5527                                         read_expr(state, left),
5528                                         int_const(state, &ulong_type, offset));
5529                                 free_triple(state, base);
5530                         }
5531                         else if (base->op == OP_VAL_VEC) {
5532                                 base = flatten(state, first, base);
5533                                 ptr = struct_field(state, base, ptr->u.field);
5534                         }
5535                         break;
5536                 }
5537                 case OP_PIECE:
5538                         MISC(ptr, 0) = flatten(state, first, MISC(ptr, 0));
5539                         use_triple(MISC(ptr, 0), ptr);
5540                         use_triple(ptr, MISC(ptr, 0));
5541                         break;
5542                 case OP_ADDRCONST:
5543                         MISC(ptr, 0) = flatten(state, first, MISC(ptr, 0));
5544                         use_triple(MISC(ptr, 0), ptr);
5545                         break;
5546                 case OP_SDECL:
5547                         first = state->global_pool;
5548                         MISC(ptr, 0) = flatten(state, first, MISC(ptr, 0));
5549                         use_triple(MISC(ptr, 0), ptr);
5550                         insert_triple(state, first, ptr);
5551                         ptr->id |= TRIPLE_FLAG_FLATTENED;
5552                         ptr->id &= ~TRIPLE_FLAG_LOCAL;
5553                         return ptr;
5554                 case OP_ADECL:
5555                         break;
5556                 default:
5557                         /* Flatten the easy cases we don't override */
5558                         ptr = flatten_generic(state, first, ptr, 0);
5559                         break;
5560                 }
5561         } while(ptr && (ptr != orig_ptr));
5562         if (ptr) {
5563                 insert_triple(state, first, ptr);
5564                 ptr->id |= TRIPLE_FLAG_FLATTENED;
5565                 ptr->id &= ~TRIPLE_FLAG_LOCAL;
5566         }
5567         return ptr;
5568 }
5569
5570 static void release_expr(struct compile_state *state, struct triple *expr)
5571 {
5572         struct triple *head;
5573         head = label(state);
5574         flatten(state, head, expr);
5575         while(head->next != head) {
5576                 release_triple(state, head->next);
5577         }
5578         free_triple(state, head);
5579 }
5580
5581 static int replace_rhs_use(struct compile_state *state,
5582         struct triple *orig, struct triple *new, struct triple *use)
5583 {
5584         struct triple **expr;
5585         int found;
5586         found = 0;
5587         expr = triple_rhs(state, use, 0);
5588         for(;expr; expr = triple_rhs(state, use, expr)) {
5589                 if (*expr == orig) {
5590                         *expr = new;
5591                         found = 1;
5592                 }
5593         }
5594         if (found) {
5595                 unuse_triple(orig, use);
5596                 use_triple(new, use);
5597         }
5598         return found;
5599 }
5600
5601 static int replace_lhs_use(struct compile_state *state,
5602         struct triple *orig, struct triple *new, struct triple *use)
5603 {
5604         struct triple **expr;
5605         int found;
5606         found = 0;
5607         expr = triple_lhs(state, use, 0);
5608         for(;expr; expr = triple_lhs(state, use, expr)) {
5609                 if (*expr == orig) {
5610                         *expr = new;
5611                         found = 1;
5612                 }
5613         }
5614         if (found) {
5615                 unuse_triple(orig, use);
5616                 use_triple(new, use);
5617         }
5618         return found;
5619 }
5620
5621 static void propogate_use(struct compile_state *state,
5622         struct triple *orig, struct triple *new)
5623 {
5624         struct triple_set *user, *next;
5625         for(user = orig->use; user; user = next) {
5626                 struct triple *use;
5627                 int found;
5628                 next = user->next;
5629                 use = user->member;
5630                 found = 0;
5631                 found |= replace_rhs_use(state, orig, new, use);
5632                 found |= replace_lhs_use(state, orig, new, use);
5633                 if (!found) {
5634                         internal_error(state, use, "use without use");
5635                 }
5636         }
5637         if (orig->use) {
5638                 internal_error(state, orig, "used after propogate_use");
5639         }
5640 }
5641
5642 /*
5643  * Code generators
5644  * ===========================
5645  */
5646
5647 static struct triple *mk_add_expr(
5648         struct compile_state *state, struct triple *left, struct triple *right)
5649 {
5650         struct type *result_type;
5651         /* Put pointer operands on the left */
5652         if (is_pointer(right)) {
5653                 struct triple *tmp;
5654                 tmp = left;
5655                 left = right;
5656                 right = tmp;
5657         }
5658         left  = read_expr(state, left);
5659         right = read_expr(state, right);
5660         result_type = ptr_arithmetic_result(state, left, right);
5661         if (is_pointer(left)) {
5662                 right = triple(state, 
5663                         is_signed(right->type)? OP_SMUL : OP_UMUL, 
5664                         &ulong_type, 
5665                         right, 
5666                         int_const(state, &ulong_type, 
5667                                 size_of(state, left->type->left)));
5668         }
5669         return triple(state, OP_ADD, result_type, left, right);
5670 }
5671
5672 static struct triple *mk_sub_expr(
5673         struct compile_state *state, struct triple *left, struct triple *right)
5674 {
5675         struct type *result_type;
5676         result_type = ptr_arithmetic_result(state, left, right);
5677         left  = read_expr(state, left);
5678         right = read_expr(state, right);
5679         if (is_pointer(left)) {
5680                 right = triple(state, 
5681                         is_signed(right->type)? OP_SMUL : OP_UMUL, 
5682                         &ulong_type, 
5683                         right, 
5684                         int_const(state, &ulong_type, 
5685                                 size_of(state, left->type->left)));
5686         }
5687         return triple(state, OP_SUB, result_type, left, right);
5688 }
5689
5690 static struct triple *mk_pre_inc_expr(
5691         struct compile_state *state, struct triple *def)
5692 {
5693         struct triple *val;
5694         lvalue(state, def);
5695         val = mk_add_expr(state, def, int_const(state, &int_type, 1));
5696         return triple(state, OP_VAL, def->type,
5697                 write_expr(state, def, val),
5698                 val);
5699 }
5700
5701 static struct triple *mk_pre_dec_expr(
5702         struct compile_state *state, struct triple *def)
5703 {
5704         struct triple *val;
5705         lvalue(state, def);
5706         val = mk_sub_expr(state, def, int_const(state, &int_type, 1));
5707         return triple(state, OP_VAL, def->type,
5708                 write_expr(state, def, val),
5709                 val);
5710 }
5711
5712 static struct triple *mk_post_inc_expr(
5713         struct compile_state *state, struct triple *def)
5714 {
5715         struct triple *val;
5716         lvalue(state, def);
5717         val = read_expr(state, def);
5718         return triple(state, OP_VAL, def->type,
5719                 write_expr(state, def,
5720                         mk_add_expr(state, val, int_const(state, &int_type, 1)))
5721                 , val);
5722 }
5723
5724 static struct triple *mk_post_dec_expr(
5725         struct compile_state *state, struct triple *def)
5726 {
5727         struct triple *val;
5728         lvalue(state, def);
5729         val = read_expr(state, def);
5730         return triple(state, OP_VAL, def->type, 
5731                 write_expr(state, def,
5732                         mk_sub_expr(state, val, int_const(state, &int_type, 1)))
5733                 , val);
5734 }
5735
5736 static struct triple *mk_subscript_expr(
5737         struct compile_state *state, struct triple *left, struct triple *right)
5738 {
5739         left  = read_expr(state, left);
5740         right = read_expr(state, right);
5741         if (!is_pointer(left) && !is_pointer(right)) {
5742                 error(state, left, "subscripted value is not a pointer");
5743         }
5744         return mk_deref_expr(state, mk_add_expr(state, left, right));
5745 }
5746
5747 static struct triple *mk_cast_expr(
5748         struct compile_state *state, struct type *type, struct triple *expr)
5749 {
5750         struct triple *def;
5751         def = read_expr(state, expr);
5752         def = triple(state, OP_COPY, type, def, 0);
5753         return def;
5754 }
5755
5756 /*
5757  * Compile time evaluation
5758  * ===========================
5759  */
5760 static int is_const(struct triple *ins)
5761 {
5762         return IS_CONST_OP(ins->op);
5763 }
5764
5765 static int is_simple_const(struct triple *ins)
5766 {
5767         return IS_CONST_OP(ins->op) && (ins->op != OP_ADDRCONST);
5768 }
5769
5770 static int constants_equal(struct compile_state *state, 
5771         struct triple *left, struct triple *right)
5772 {
5773         int equal;
5774         if (!is_const(left) || !is_const(right)) {
5775                 equal = 0;
5776         }
5777         else if (left->op != right->op) {
5778                 equal = 0;
5779         }
5780         else if (!equiv_types(left->type, right->type)) {
5781                 equal = 0;
5782         }
5783         else {
5784                 equal = 0;
5785                 switch(left->op) {
5786                 case OP_INTCONST:
5787                         if (left->u.cval == right->u.cval) {
5788                                 equal = 1;
5789                         }
5790                         break;
5791                 case OP_BLOBCONST:
5792                 {
5793                         size_t lsize, rsize;
5794                         lsize = size_of(state, left->type);
5795                         rsize = size_of(state, right->type);
5796                         if (lsize != rsize) {
5797                                 break;
5798                         }
5799                         if (memcmp(left->u.blob, right->u.blob, lsize) == 0) {
5800                                 equal = 1;
5801                         }
5802                         break;
5803                 }
5804                 case OP_ADDRCONST:
5805                         if ((MISC(left, 0) == MISC(right, 0)) &&
5806                                 (left->u.cval == right->u.cval)) {
5807                                 equal = 1;
5808                         }
5809                         break;
5810                 default:
5811                         internal_error(state, left, "uknown constant type");
5812                         break;
5813                 }
5814         }
5815         return equal;
5816 }
5817
5818 static int is_zero(struct triple *ins)
5819 {
5820         return is_simple_const(ins) && (ins->u.cval == 0);
5821 }
5822
5823 static int is_one(struct triple *ins)
5824 {
5825         return is_simple_const(ins) && (ins->u.cval == 1);
5826 }
5827
5828 static long_t bit_count(ulong_t value)
5829 {
5830         int count;
5831         int i;
5832         count = 0;
5833         for(i = (sizeof(ulong_t)*8) -1; i >= 0; i--) {
5834                 ulong_t mask;
5835                 mask = 1;
5836                 mask <<= i;
5837                 if (value & mask) {
5838                         count++;
5839                 }
5840         }
5841         return count;
5842         
5843 }
5844 static long_t bsr(ulong_t value)
5845 {
5846         int i;
5847         for(i = (sizeof(ulong_t)*8) -1; i >= 0; i--) {
5848                 ulong_t mask;
5849                 mask = 1;
5850                 mask <<= i;
5851                 if (value & mask) {
5852                         return i;
5853                 }
5854         }
5855         return -1;
5856 }
5857
5858 static long_t bsf(ulong_t value)
5859 {
5860         int i;
5861         for(i = 0; i < (sizeof(ulong_t)*8); i++) {
5862                 ulong_t mask;
5863                 mask = 1;
5864                 mask <<= 1;
5865                 if (value & mask) {
5866                         return i;
5867                 }
5868         }
5869         return -1;
5870 }
5871
5872 static long_t log2(ulong_t value)
5873 {
5874         return bsr(value);
5875 }
5876
5877 static long_t tlog2(struct triple *ins)
5878 {
5879         return log2(ins->u.cval);
5880 }
5881
5882 static int is_pow2(struct triple *ins)
5883 {
5884         ulong_t value, mask;
5885         long_t log;
5886         if (!is_const(ins)) {
5887                 return 0;
5888         }
5889         value = ins->u.cval;
5890         log = log2(value);
5891         if (log == -1) {
5892                 return 0;
5893         }
5894         mask = 1;
5895         mask <<= log;
5896         return  ((value & mask) == value);
5897 }
5898
5899 static ulong_t read_const(struct compile_state *state,
5900         struct triple *ins, struct triple *rhs)
5901 {
5902         switch(rhs->type->type &TYPE_MASK) {
5903         case TYPE_CHAR:   
5904         case TYPE_SHORT:
5905         case TYPE_INT:
5906         case TYPE_LONG:
5907         case TYPE_UCHAR:   
5908         case TYPE_USHORT:  
5909         case TYPE_UINT:
5910         case TYPE_ULONG:
5911         case TYPE_POINTER:
5912                 break;
5913         default:
5914                 internal_error(state, rhs, "bad type to read_const\n");
5915                 break;
5916         }
5917         if (!is_simple_const(rhs)) {
5918                 internal_error(state, rhs, "bad op to read_const\n");
5919         }
5920         return rhs->u.cval;
5921 }
5922
5923 static long_t read_sconst(struct compile_state *state,
5924         struct triple *ins, struct triple *rhs)
5925 {
5926         return (long_t)(rhs->u.cval);
5927 }
5928
5929 int const_ltrue(struct compile_state *state, struct triple *ins, struct triple *rhs)
5930 {
5931         if (!is_const(rhs)) {
5932                 internal_error(state, 0, "non const passed to const_true\n");
5933         }
5934         return !is_zero(rhs);
5935 }
5936
5937 int const_eq(struct compile_state *state, struct triple *ins,
5938         struct triple *left, struct triple *right)
5939 {
5940         int result;
5941         if (!is_const(left) || !is_const(right)) {
5942                 internal_error(state, ins, "non const passed to const_eq\n");
5943                 result = 0;
5944         }
5945         else if (left == right) {
5946                 result = 1;
5947         }
5948         else if (is_simple_const(left) && is_simple_const(right)) {
5949                 ulong_t lval, rval;
5950                 lval = read_const(state, ins, left);
5951                 rval = read_const(state, ins, right);
5952                 result = (lval == rval);
5953         }
5954         else if ((left->op == OP_ADDRCONST) && 
5955                 (right->op == OP_ADDRCONST)) {
5956                 result = (MISC(left, 0) == MISC(right, 0)) &&
5957                         (left->u.cval == right->u.cval);
5958         }
5959         else {
5960                 internal_error(state, ins, "incomparable constants passed to const_eq\n");
5961                 result = 0;
5962         }
5963         return result;
5964         
5965 }
5966
5967 int const_ucmp(struct compile_state *state, struct triple *ins,
5968         struct triple *left, struct triple *right)
5969 {
5970         int result;
5971         if (!is_const(left) || !is_const(right)) {
5972                 internal_error(state, ins, "non const past to ucmp_const\n");
5973                 result = -2;
5974         }
5975         else if (left == right) {
5976                 result = 0;
5977         }
5978         else if (is_simple_const(left) && is_simple_const(right)) {
5979                 ulong_t lval, rval;
5980                 lval = read_const(state, ins, left);
5981                 rval = read_const(state, ins, right);
5982                 result = 0;
5983                 if (lval > rval) {
5984                         result = 1;
5985                 } else if (rval > lval) {
5986                         result = -1;
5987                 }
5988         }
5989         else if ((left->op == OP_ADDRCONST) && 
5990                 (right->op == OP_ADDRCONST) &&
5991                 (MISC(left, 0) == MISC(right, 0))) {
5992                 result = 0;
5993                 if (left->u.cval > right->u.cval) {
5994                         result = 1;
5995                 } else if (left->u.cval < right->u.cval) {
5996                         result = -1;
5997                 }
5998         }
5999         else {
6000                 internal_error(state, ins, "incomparable constants passed to const_ucmp\n");
6001                 result = -2;
6002         }
6003         return result;
6004 }
6005
6006 int const_scmp(struct compile_state *state, struct triple *ins,
6007         struct triple *left, struct triple *right)
6008 {
6009         int result;
6010         if (!is_const(left) || !is_const(right)) {
6011                 internal_error(state, ins, "non const past to ucmp_const\n");
6012                 result = -2;
6013         }
6014         else if (left == right) {
6015                 result = 0;
6016         }
6017         else if (is_simple_const(left) && is_simple_const(right)) {
6018                 long_t lval, rval;
6019                 lval = read_sconst(state, ins, left);
6020                 rval = read_sconst(state, ins, right);
6021                 result = 0;
6022                 if (lval > rval) {
6023                         result = 1;
6024                 } else if (rval > lval) {
6025                         result = -1;
6026                 }
6027         }
6028         else {
6029                 internal_error(state, ins, "incomparable constants passed to const_scmp\n");
6030                 result = -2;
6031         }
6032         return result;
6033 }
6034
6035 static void unuse_rhs(struct compile_state *state, struct triple *ins)
6036 {
6037         struct triple **expr;
6038         expr = triple_rhs(state, ins, 0);
6039         for(;expr;expr = triple_rhs(state, ins, expr)) {
6040                 if (*expr) {
6041                         unuse_triple(*expr, ins);
6042                         *expr = 0;
6043                 }
6044         }
6045 }
6046
6047 static void unuse_lhs(struct compile_state *state, struct triple *ins)
6048 {
6049         struct triple **expr;
6050         expr = triple_lhs(state, ins, 0);
6051         for(;expr;expr = triple_lhs(state, ins, expr)) {
6052                 unuse_triple(*expr, ins);
6053                 *expr = 0;
6054         }
6055 }
6056
6057 static void check_lhs(struct compile_state *state, struct triple *ins)
6058 {
6059         struct triple **expr;
6060         expr = triple_lhs(state, ins, 0);
6061         for(;expr;expr = triple_lhs(state, ins, expr)) {
6062                 internal_error(state, ins, "unexpected lhs");
6063         }
6064         
6065 }
6066 static void check_targ(struct compile_state *state, struct triple *ins)
6067 {
6068         struct triple **expr;
6069         expr = triple_targ(state, ins, 0);
6070         for(;expr;expr = triple_targ(state, ins, expr)) {
6071                 internal_error(state, ins, "unexpected targ");
6072         }
6073 }
6074
6075 static void wipe_ins(struct compile_state *state, struct triple *ins)
6076 {
6077         /* Becareful which instructions you replace the wiped
6078          * instruction with, as there are not enough slots
6079          * in all instructions to hold all others.
6080          */
6081         check_targ(state, ins);
6082         unuse_rhs(state, ins);
6083         unuse_lhs(state, ins);
6084 }
6085
6086 static void mkcopy(struct compile_state *state, 
6087         struct triple *ins, struct triple *rhs)
6088 {
6089         struct block *block;
6090         block = block_of_triple(state, ins);
6091         wipe_ins(state, ins);
6092         ins->op = OP_COPY;
6093         ins->sizes = TRIPLE_SIZES(0, 1, 0, 0);
6094         ins->u.block = block;
6095         RHS(ins, 0) = rhs;
6096         use_triple(RHS(ins, 0), ins);
6097 }
6098
6099 static void mkconst(struct compile_state *state, 
6100         struct triple *ins, ulong_t value)
6101 {
6102         if (!is_integral(ins) && !is_pointer(ins)) {
6103                 internal_error(state, ins, "unknown type to make constant\n");
6104         }
6105         wipe_ins(state, ins);
6106         ins->op = OP_INTCONST;
6107         ins->sizes = TRIPLE_SIZES(0, 0, 0, 0);
6108         ins->u.cval = value;
6109 }
6110
6111 static void mkaddr_const(struct compile_state *state,
6112         struct triple *ins, struct triple *sdecl, ulong_t value)
6113 {
6114         if (sdecl->op != OP_SDECL) {
6115                 internal_error(state, ins, "bad base for addrconst");
6116         }
6117         wipe_ins(state, ins);
6118         ins->op = OP_ADDRCONST;
6119         ins->sizes = TRIPLE_SIZES(0, 0, 1, 0);
6120         MISC(ins, 0) = sdecl;
6121         ins->u.cval = value;
6122         use_triple(sdecl, ins);
6123 }
6124
6125 /* Transform multicomponent variables into simple register variables */
6126 static void flatten_structures(struct compile_state *state)
6127 {
6128         struct triple *ins, *first;
6129         first = state->first;
6130         ins = first;
6131         /* Pass one expand structure values into valvecs.
6132          */
6133         ins = first;
6134         do {
6135                 struct triple *next;
6136                 next = ins->next;
6137                 valid_ins(state, ins);
6138                 if ((ins->type->type & TYPE_MASK) == TYPE_STRUCT) {
6139                         if (ins->op == OP_VAL_VEC) {
6140                                 /* Do nothing */
6141                         }
6142                         else if ((ins->op == OP_LOAD) || (ins->op == OP_READ)) {
6143                                 struct triple *def, **vector;
6144                                 struct type *tptr;
6145                                 int op;
6146                                 ulong_t i;
6147
6148                                 op = ins->op;
6149                                 def = RHS(ins, 0);
6150                                 get_occurance(ins->occurance);
6151                                 next = alloc_triple(state, OP_VAL_VEC, ins->type, -1, -1,
6152                                         ins->occurance);
6153
6154                                 vector = &RHS(next, 0);
6155                                 tptr = next->type->left;
6156                                 for(i = 0; i < next->type->elements; i++) {
6157                                         struct triple *sfield;
6158                                         struct type *mtype;
6159                                         mtype = tptr;
6160                                         if ((mtype->type & TYPE_MASK) == TYPE_PRODUCT) {
6161                                                 mtype = mtype->left;
6162                                         }
6163                                         sfield = deref_field(state, def, mtype->field_ident);
6164                                         
6165                                         vector[i] = triple(
6166                                                 state, op, mtype, sfield, 0);
6167                                         put_occurance(vector[i]->occurance);
6168                                         get_occurance(next->occurance);
6169                                         vector[i]->occurance = next->occurance;
6170                                         tptr = tptr->right;
6171                                 }
6172                                 propogate_use(state, ins, next);
6173                                 flatten(state, ins, next);
6174                                 release_triple(state, ins);
6175                         }
6176                         else if ((ins->op == OP_STORE) || (ins->op == OP_WRITE)) {
6177                                 struct triple *src, *dst, **vector;
6178                                 struct type *tptr;
6179                                 int op;
6180                                 ulong_t i;
6181
6182                                 op = ins->op;
6183                                 src = RHS(ins, 1);
6184                                 dst = RHS(ins, 0);
6185                                 get_occurance(ins->occurance);
6186                                 next = alloc_triple(state, OP_VAL_VEC, ins->type, -1, -1,
6187                                         ins->occurance);
6188                                 
6189                                 vector = &RHS(next, 0);
6190                                 tptr = next->type->left;
6191                                 for(i = 0; i < ins->type->elements; i++) {
6192                                         struct triple *dfield, *sfield;
6193                                         struct type *mtype;
6194                                         mtype = tptr;
6195                                         if ((mtype->type & TYPE_MASK) == TYPE_PRODUCT) {
6196                                                 mtype = mtype->left;
6197                                         }
6198                                         sfield = deref_field(state, src, mtype->field_ident);
6199                                         dfield = deref_field(state, dst, mtype->field_ident);
6200                                         vector[i] = triple(
6201                                                 state, op, mtype, dfield, sfield);
6202                                         put_occurance(vector[i]->occurance);
6203                                         get_occurance(next->occurance);
6204                                         vector[i]->occurance = next->occurance;
6205                                         tptr = tptr->right;
6206                                 }
6207                                 propogate_use(state, ins, next);
6208                                 flatten(state, ins, next);
6209                                 release_triple(state, ins);
6210                         }
6211                 }
6212                 ins = next;
6213         } while(ins != first);
6214         /* Pass two flatten the valvecs.
6215          */
6216         ins = first;
6217         do {
6218                 struct triple *next;
6219                 next = ins->next;
6220                 if (ins->op == OP_VAL_VEC) {
6221                         if (ins->use) {
6222                                 internal_error(state, ins, "valvec used\n");
6223                         }
6224                         release_triple(state, ins);
6225                 } 
6226                 ins = next;
6227         } while(ins != first);
6228         /* Pass three verify the state and set ->id to 0.
6229          */
6230         ins = first;
6231         do {
6232                 ins->id &= ~TRIPLE_FLAG_FLATTENED;
6233                 if ((ins->op != OP_BLOBCONST) && (ins->op != OP_SDECL) &&
6234                         ((ins->type->type & TYPE_MASK) == TYPE_STRUCT)) {
6235                         internal_error(state, ins, "STRUCT_TYPE remains?");
6236                 }
6237                 if (ins->op == OP_DOT) {
6238                         internal_error(state, ins, "OP_DOT remains?");
6239                 }
6240                 if (ins->op == OP_VAL_VEC) {
6241                         internal_error(state, ins, "OP_VAL_VEC remains?");
6242                 }
6243                 ins = ins->next;
6244         } while(ins != first);
6245 }
6246
6247 /* For those operations that cannot be simplified */
6248 static void simplify_noop(struct compile_state *state, struct triple *ins)
6249 {
6250         return;
6251 }
6252
6253 static void simplify_smul(struct compile_state *state, struct triple *ins)
6254 {
6255         if (is_const(RHS(ins, 0)) && !is_const(RHS(ins, 1))) {
6256                 struct triple *tmp;
6257                 tmp = RHS(ins, 0);
6258                 RHS(ins, 0) = RHS(ins, 1);
6259                 RHS(ins, 1) = tmp;
6260         }
6261         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6262                 long_t left, right;
6263                 left  = read_sconst(state, ins, RHS(ins, 0));
6264                 right = read_sconst(state, ins, RHS(ins, 1));
6265                 mkconst(state, ins, left * right);
6266         }
6267         else if (is_zero(RHS(ins, 1))) {
6268                 mkconst(state, ins, 0);
6269         }
6270         else if (is_one(RHS(ins, 1))) {
6271                 mkcopy(state, ins, RHS(ins, 0));
6272         }
6273         else if (is_pow2(RHS(ins, 1))) {
6274                 struct triple *val;
6275                 val = int_const(state, ins->type, tlog2(RHS(ins, 1)));
6276                 ins->op = OP_SL;
6277                 insert_triple(state, state->global_pool, val);
6278                 unuse_triple(RHS(ins, 1), ins);
6279                 use_triple(val, ins);
6280                 RHS(ins, 1) = val;
6281         }
6282 }
6283
6284 static void simplify_umul(struct compile_state *state, struct triple *ins)
6285 {
6286         if (is_const(RHS(ins, 0)) && !is_const(RHS(ins, 1))) {
6287                 struct triple *tmp;
6288                 tmp = RHS(ins, 0);
6289                 RHS(ins, 0) = RHS(ins, 1);
6290                 RHS(ins, 1) = tmp;
6291         }
6292         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6293                 ulong_t left, right;
6294                 left  = read_const(state, ins, RHS(ins, 0));
6295                 right = read_const(state, ins, RHS(ins, 1));
6296                 mkconst(state, ins, left * right);
6297         }
6298         else if (is_zero(RHS(ins, 1))) {
6299                 mkconst(state, ins, 0);
6300         }
6301         else if (is_one(RHS(ins, 1))) {
6302                 mkcopy(state, ins, RHS(ins, 0));
6303         }
6304         else if (is_pow2(RHS(ins, 1))) {
6305                 struct triple *val;
6306                 val = int_const(state, ins->type, tlog2(RHS(ins, 1)));
6307                 ins->op = OP_SL;
6308                 insert_triple(state, state->global_pool, val);
6309                 unuse_triple(RHS(ins, 1), ins);
6310                 use_triple(val, ins);
6311                 RHS(ins, 1) = val;
6312         }
6313 }
6314
6315 static void simplify_sdiv(struct compile_state *state, struct triple *ins)
6316 {
6317         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6318                 long_t left, right;
6319                 left  = read_sconst(state, ins, RHS(ins, 0));
6320                 right = read_sconst(state, ins, RHS(ins, 1));
6321                 mkconst(state, ins, left / right);
6322         }
6323         else if (is_zero(RHS(ins, 0))) {
6324                 mkconst(state, ins, 0);
6325         }
6326         else if (is_zero(RHS(ins, 1))) {
6327                 error(state, ins, "division by zero");
6328         }
6329         else if (is_one(RHS(ins, 1))) {
6330                 mkcopy(state, ins, RHS(ins, 0));
6331         }
6332         else if (is_pow2(RHS(ins, 1))) {
6333                 struct triple *val;
6334                 val = int_const(state, ins->type, tlog2(RHS(ins, 1)));
6335                 ins->op = OP_SSR;
6336                 insert_triple(state, state->global_pool, val);
6337                 unuse_triple(RHS(ins, 1), ins);
6338                 use_triple(val, ins);
6339                 RHS(ins, 1) = val;
6340         }
6341 }
6342
6343 static void simplify_udiv(struct compile_state *state, struct triple *ins)
6344 {
6345         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6346                 ulong_t left, right;
6347                 left  = read_const(state, ins, RHS(ins, 0));
6348                 right = read_const(state, ins, RHS(ins, 1));
6349                 mkconst(state, ins, left / right);
6350         }
6351         else if (is_zero(RHS(ins, 0))) {
6352                 mkconst(state, ins, 0);
6353         }
6354         else if (is_zero(RHS(ins, 1))) {
6355                 error(state, ins, "division by zero");
6356         }
6357         else if (is_one(RHS(ins, 1))) {
6358                 mkcopy(state, ins, RHS(ins, 0));
6359         }
6360         else if (is_pow2(RHS(ins, 1))) {
6361                 struct triple *val;
6362                 val = int_const(state, ins->type, tlog2(RHS(ins, 1)));
6363                 ins->op = OP_USR;
6364                 insert_triple(state, state->global_pool, val);
6365                 unuse_triple(RHS(ins, 1), ins);
6366                 use_triple(val, ins);
6367                 RHS(ins, 1) = val;
6368         }
6369 }
6370
6371 static void simplify_smod(struct compile_state *state, struct triple *ins)
6372 {
6373         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6374                 long_t left, right;
6375                 left  = read_const(state, ins, RHS(ins, 0));
6376                 right = read_const(state, ins, RHS(ins, 1));
6377                 mkconst(state, ins, left % right);
6378         }
6379         else if (is_zero(RHS(ins, 0))) {
6380                 mkconst(state, ins, 0);
6381         }
6382         else if (is_zero(RHS(ins, 1))) {
6383                 error(state, ins, "division by zero");
6384         }
6385         else if (is_one(RHS(ins, 1))) {
6386                 mkconst(state, ins, 0);
6387         }
6388         else if (is_pow2(RHS(ins, 1))) {
6389                 struct triple *val;
6390                 val = int_const(state, ins->type, RHS(ins, 1)->u.cval - 1);
6391                 ins->op = OP_AND;
6392                 insert_triple(state, state->global_pool, val);
6393                 unuse_triple(RHS(ins, 1), ins);
6394                 use_triple(val, ins);
6395                 RHS(ins, 1) = val;
6396         }
6397 }
6398
6399 static void simplify_umod(struct compile_state *state, struct triple *ins)
6400 {
6401         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6402                 ulong_t left, right;
6403                 left  = read_const(state, ins, RHS(ins, 0));
6404                 right = read_const(state, ins, RHS(ins, 1));
6405                 mkconst(state, ins, left % right);
6406         }
6407         else if (is_zero(RHS(ins, 0))) {
6408                 mkconst(state, ins, 0);
6409         }
6410         else if (is_zero(RHS(ins, 1))) {
6411                 error(state, ins, "division by zero");
6412         }
6413         else if (is_one(RHS(ins, 1))) {
6414                 mkconst(state, ins, 0);
6415         }
6416         else if (is_pow2(RHS(ins, 1))) {
6417                 struct triple *val;
6418                 val = int_const(state, ins->type, RHS(ins, 1)->u.cval - 1);
6419                 ins->op = OP_AND;
6420                 insert_triple(state, state->global_pool, val);
6421                 unuse_triple(RHS(ins, 1), ins);
6422                 use_triple(val, ins);
6423                 RHS(ins, 1) = val;
6424         }
6425 }
6426
6427 static void simplify_add(struct compile_state *state, struct triple *ins)
6428 {
6429         /* start with the pointer on the left */
6430         if (is_pointer(RHS(ins, 1))) {
6431                 struct triple *tmp;
6432                 tmp = RHS(ins, 0);
6433                 RHS(ins, 0) = RHS(ins, 1);
6434                 RHS(ins, 1) = tmp;
6435         }
6436         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6437                 if (RHS(ins, 0)->op == OP_INTCONST) {
6438                         ulong_t left, right;
6439                         left  = read_const(state, ins, RHS(ins, 0));
6440                         right = read_const(state, ins, RHS(ins, 1));
6441                         mkconst(state, ins, left + right);
6442                 }
6443                 else if (RHS(ins, 0)->op == OP_ADDRCONST) {
6444                         struct triple *sdecl;
6445                         ulong_t left, right;
6446                         sdecl = MISC(RHS(ins, 0), 0);
6447                         left  = RHS(ins, 0)->u.cval;
6448                         right = RHS(ins, 1)->u.cval;
6449                         mkaddr_const(state, ins, sdecl, left + right);
6450                 }
6451                 else {
6452                         internal_warning(state, ins, "Optimize me!");
6453                 }
6454         }
6455         else if (is_const(RHS(ins, 0)) && !is_const(RHS(ins, 1))) {
6456                 struct triple *tmp;
6457                 tmp = RHS(ins, 1);
6458                 RHS(ins, 1) = RHS(ins, 0);
6459                 RHS(ins, 0) = tmp;
6460         }
6461 }
6462
6463 static void simplify_sub(struct compile_state *state, struct triple *ins)
6464 {
6465         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6466                 if (RHS(ins, 0)->op == OP_INTCONST) {
6467                         ulong_t left, right;
6468                         left  = read_const(state, ins, RHS(ins, 0));
6469                         right = read_const(state, ins, RHS(ins, 1));
6470                         mkconst(state, ins, left - right);
6471                 }
6472                 else if (RHS(ins, 0)->op == OP_ADDRCONST) {
6473                         struct triple *sdecl;
6474                         ulong_t left, right;
6475                         sdecl = MISC(RHS(ins, 0), 0);
6476                         left  = RHS(ins, 0)->u.cval;
6477                         right = RHS(ins, 1)->u.cval;
6478                         mkaddr_const(state, ins, sdecl, left - right);
6479                 }
6480                 else {
6481                         internal_warning(state, ins, "Optimize me!");
6482                 }
6483         }
6484 }
6485
6486 static void simplify_sl(struct compile_state *state, struct triple *ins)
6487 {
6488         if (is_const(RHS(ins, 1))) {
6489                 ulong_t right;
6490                 right = read_const(state, ins, RHS(ins, 1));
6491                 if (right >= (size_of(state, ins->type)*8)) {
6492                         warning(state, ins, "left shift count >= width of type");
6493                 }
6494         }
6495         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6496                 ulong_t left, right;
6497                 left  = read_const(state, ins, RHS(ins, 0));
6498                 right = read_const(state, ins, RHS(ins, 1));
6499                 mkconst(state, ins,  left << right);
6500         }
6501 }
6502
6503 static void simplify_usr(struct compile_state *state, struct triple *ins)
6504 {
6505         if (is_const(RHS(ins, 1))) {
6506                 ulong_t right;
6507                 right = read_const(state, ins, RHS(ins, 1));
6508                 if (right >= (size_of(state, ins->type)*8)) {
6509                         warning(state, ins, "right shift count >= width of type");
6510                 }
6511         }
6512         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6513                 ulong_t left, right;
6514                 left  = read_const(state, ins, RHS(ins, 0));
6515                 right = read_const(state, ins, RHS(ins, 1));
6516                 mkconst(state, ins, left >> right);
6517         }
6518 }
6519
6520 static void simplify_ssr(struct compile_state *state, struct triple *ins)
6521 {
6522         if (is_const(RHS(ins, 1))) {
6523                 ulong_t right;
6524                 right = read_const(state, ins, RHS(ins, 1));
6525                 if (right >= (size_of(state, ins->type)*8)) {
6526                         warning(state, ins, "right shift count >= width of type");
6527                 }
6528         }
6529         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6530                 long_t left, right;
6531                 left  = read_sconst(state, ins, RHS(ins, 0));
6532                 right = read_sconst(state, ins, RHS(ins, 1));
6533                 mkconst(state, ins, left >> right);
6534         }
6535 }
6536
6537 static void simplify_and(struct compile_state *state, struct triple *ins)
6538 {
6539         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6540                 ulong_t left, right;
6541                 left  = read_const(state, ins, RHS(ins, 0));
6542                 right = read_const(state, ins, RHS(ins, 1));
6543                 mkconst(state, ins, left & right);
6544         }
6545 }
6546
6547 static void simplify_or(struct compile_state *state, struct triple *ins)
6548 {
6549         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6550                 ulong_t left, right;
6551                 left  = read_const(state, ins, RHS(ins, 0));
6552                 right = read_const(state, ins, RHS(ins, 1));
6553                 mkconst(state, ins, left | right);
6554         }
6555 }
6556
6557 static void simplify_xor(struct compile_state *state, struct triple *ins)
6558 {
6559         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6560                 ulong_t left, right;
6561                 left  = read_const(state, ins, RHS(ins, 0));
6562                 right = read_const(state, ins, RHS(ins, 1));
6563                 mkconst(state, ins, left ^ right);
6564         }
6565 }
6566
6567 static void simplify_pos(struct compile_state *state, struct triple *ins)
6568 {
6569         if (is_const(RHS(ins, 0))) {
6570                 mkconst(state, ins, RHS(ins, 0)->u.cval);
6571         }
6572         else {
6573                 mkcopy(state, ins, RHS(ins, 0));
6574         }
6575 }
6576
6577 static void simplify_neg(struct compile_state *state, struct triple *ins)
6578 {
6579         if (is_const(RHS(ins, 0))) {
6580                 ulong_t left;
6581                 left = read_const(state, ins, RHS(ins, 0));
6582                 mkconst(state, ins, -left);
6583         }
6584         else if (RHS(ins, 0)->op == OP_NEG) {
6585                 mkcopy(state, ins, RHS(RHS(ins, 0), 0));
6586         }
6587 }
6588
6589 static void simplify_invert(struct compile_state *state, struct triple *ins)
6590 {
6591         if (is_const(RHS(ins, 0))) {
6592                 ulong_t left;
6593                 left = read_const(state, ins, RHS(ins, 0));
6594                 mkconst(state, ins, ~left);
6595         }
6596 }
6597
6598 static void simplify_eq(struct compile_state *state, struct triple *ins)
6599 {
6600         struct triple *left, *right;
6601         left = RHS(ins, 0);
6602         right = RHS(ins, 1);
6603
6604         if (is_const(left) && is_const(right)) {
6605                 mkconst(state, ins, const_eq(state, ins, left, right) == 1);
6606         }
6607         else if (left == right) {
6608                 mkconst(state, ins, 1);
6609         }
6610 }
6611
6612 static void simplify_noteq(struct compile_state *state, struct triple *ins)
6613 {
6614         struct triple *left, *right;
6615         left = RHS(ins, 0);
6616         right = RHS(ins, 1);
6617
6618         if (is_const(left) && is_const(right)) {
6619                 mkconst(state, ins, const_eq(state, ins, left, right) != 1);
6620         }
6621         if (left == right) {
6622                 mkconst(state, ins, 0);
6623         }
6624 }
6625
6626 static void simplify_sless(struct compile_state *state, struct triple *ins)
6627 {
6628         struct triple *left, *right;
6629         left = RHS(ins, 0);
6630         right = RHS(ins, 1);
6631
6632         if (is_const(left) && is_const(right)) {
6633                 mkconst(state, ins, const_scmp(state, ins, left, right) < 0);
6634         }
6635         else if (left == right) {
6636                 mkconst(state, ins, 0);
6637         }
6638 }
6639
6640 static void simplify_uless(struct compile_state *state, struct triple *ins)
6641 {
6642         struct triple *left, *right;
6643         left = RHS(ins, 0);
6644         right = RHS(ins, 1);
6645
6646         if (is_const(left) && is_const(right)) {
6647                 mkconst(state, ins, const_ucmp(state, ins, left, right) < 0);
6648         }
6649         else if (is_zero(right)) {
6650                 mkconst(state, ins, 0);
6651         }
6652         else if (left == right) {
6653                 mkconst(state, ins, 0);
6654         }
6655 }
6656
6657 static void simplify_smore(struct compile_state *state, struct triple *ins)
6658 {
6659         struct triple *left, *right;
6660         left = RHS(ins, 0);
6661         right = RHS(ins, 1);
6662
6663         if (is_const(left) && is_const(right)) {
6664                 mkconst(state, ins, const_scmp(state, ins, left, right) > 0);
6665         }
6666         else if (left == right) {
6667                 mkconst(state, ins, 0);
6668         }
6669 }
6670
6671 static void simplify_umore(struct compile_state *state, struct triple *ins)
6672 {
6673         struct triple *left, *right;
6674         left = RHS(ins, 0);
6675         right = RHS(ins, 1);
6676
6677         if (is_const(left) && is_const(right)) {
6678                 mkconst(state, ins, const_ucmp(state, ins, left, right) > 0);
6679         }
6680         else if (is_zero(left)) {
6681                 mkconst(state, ins, 0);
6682         }
6683         else if (left == right) {
6684                 mkconst(state, ins, 0);
6685         }
6686 }
6687
6688
6689 static void simplify_slesseq(struct compile_state *state, struct triple *ins)
6690 {
6691         struct triple *left, *right;
6692         left = RHS(ins, 0);
6693         right = RHS(ins, 1);
6694
6695         if (is_const(left) && is_const(right)) {
6696                 mkconst(state, ins, const_scmp(state, ins, left, right) <= 0);
6697         }
6698         else if (left == right) {
6699                 mkconst(state, ins, 1);
6700         }
6701 }
6702
6703 static void simplify_ulesseq(struct compile_state *state, struct triple *ins)
6704 {
6705         struct triple *left, *right;
6706         left = RHS(ins, 0);
6707         right = RHS(ins, 1);
6708
6709         if (is_const(left) && is_const(right)) {
6710                 mkconst(state, ins, const_ucmp(state, ins, left, right) <= 0);
6711         }
6712         else if (is_zero(left)) {
6713                 mkconst(state, ins, 1);
6714         }
6715         else if (left == right) {
6716                 mkconst(state, ins, 1);
6717         }
6718 }
6719
6720 static void simplify_smoreeq(struct compile_state *state, struct triple *ins)
6721 {
6722         struct triple *left, *right;
6723         left = RHS(ins, 0);
6724         right = RHS(ins, 1);
6725
6726         if (is_const(left) && is_const(right)) {
6727                 mkconst(state, ins, const_scmp(state, ins, left, right) >= 0);
6728         }
6729         else if (left == right) {
6730                 mkconst(state, ins, 1);
6731         }
6732 }
6733
6734 static void simplify_umoreeq(struct compile_state *state, struct triple *ins)
6735 {
6736         struct triple *left, *right;
6737         left = RHS(ins, 0);
6738         right = RHS(ins, 1);
6739
6740         if (is_const(left) && is_const(right)) {
6741                 mkconst(state, ins, const_ucmp(state, ins, left, right) >= 0);
6742         }
6743         else if (is_zero(right)) {
6744                 mkconst(state, ins, 1);
6745         }
6746         else if (left == right) {
6747                 mkconst(state, ins, 1);
6748         }
6749 }
6750
6751 static void simplify_lfalse(struct compile_state *state, struct triple *ins)
6752 {
6753         struct triple *rhs;
6754         rhs = RHS(ins, 0);
6755
6756         if (is_const(rhs)) {
6757                 mkconst(state, ins, !const_ltrue(state, ins, rhs));
6758         }
6759         /* Otherwise if I am the only user... */
6760         else if ((rhs->use) &&
6761                 (rhs->use->member == ins) && (rhs->use->next == 0)) {
6762                 int need_copy = 1;
6763                 /* Invert a boolean operation */
6764                 switch(rhs->op) {
6765                 case OP_LTRUE:   rhs->op = OP_LFALSE;  break;
6766                 case OP_LFALSE:  rhs->op = OP_LTRUE;   break;
6767                 case OP_EQ:      rhs->op = OP_NOTEQ;   break;
6768                 case OP_NOTEQ:   rhs->op = OP_EQ;      break;
6769                 case OP_SLESS:   rhs->op = OP_SMOREEQ; break;
6770                 case OP_ULESS:   rhs->op = OP_UMOREEQ; break;
6771                 case OP_SMORE:   rhs->op = OP_SLESSEQ; break;
6772                 case OP_UMORE:   rhs->op = OP_ULESSEQ; break;
6773                 case OP_SLESSEQ: rhs->op = OP_SMORE;   break;
6774                 case OP_ULESSEQ: rhs->op = OP_UMORE;   break;
6775                 case OP_SMOREEQ: rhs->op = OP_SLESS;   break;
6776                 case OP_UMOREEQ: rhs->op = OP_ULESS;   break;
6777                 default:
6778                         need_copy = 0;
6779                         break;
6780                 }
6781                 if (need_copy) {
6782                         mkcopy(state, ins, rhs);
6783                 }
6784         }
6785 }
6786
6787 static void simplify_ltrue (struct compile_state *state, struct triple *ins)
6788 {
6789         struct triple *rhs;
6790         rhs = RHS(ins, 0);
6791
6792         if (is_const(rhs)) {
6793                 mkconst(state, ins, const_ltrue(state, ins, rhs));
6794         }
6795         else switch(rhs->op) {
6796         case OP_LTRUE:   case OP_LFALSE:  case OP_EQ:      case OP_NOTEQ:
6797         case OP_SLESS:   case OP_ULESS:   case OP_SMORE:   case OP_UMORE:
6798         case OP_SLESSEQ: case OP_ULESSEQ: case OP_SMOREEQ: case OP_UMOREEQ:
6799                 mkcopy(state, ins, rhs);
6800         }
6801
6802 }
6803
6804 static void simplify_copy(struct compile_state *state, struct triple *ins)
6805 {
6806         if (is_const(RHS(ins, 0))) {
6807                 switch(RHS(ins, 0)->op) {
6808                 case OP_INTCONST:
6809                 {
6810                         ulong_t left;
6811                         left = read_const(state, ins, RHS(ins, 0));
6812                         mkconst(state, ins, left);
6813                         break;
6814                 }
6815                 case OP_ADDRCONST:
6816                 {
6817                         struct triple *sdecl;
6818                         ulong_t offset;
6819                         sdecl  = MISC(RHS(ins, 0), 0);
6820                         offset = RHS(ins, 0)->u.cval;
6821                         mkaddr_const(state, ins, sdecl, offset);
6822                         break;
6823                 }
6824                 default:
6825                         internal_error(state, ins, "uknown constant");
6826                         break;
6827                 }
6828         }
6829 }
6830
6831 static int phi_present(struct block *block)
6832 {
6833         struct triple *ptr;
6834         if (!block) {
6835                 return 0;
6836         }
6837         ptr = block->first;
6838         do {
6839                 if (ptr->op == OP_PHI) {
6840                         return 1;
6841                 }
6842                 ptr = ptr->next;
6843         } while(ptr != block->last);
6844         return 0;
6845 }
6846
6847 static int phi_dependency(struct block *block)
6848 {
6849         /* A block has a phi dependency if a phi function
6850          * depends on that block to exist, and makes a block
6851          * that is otherwise useless unsafe to remove.
6852          */
6853         if (block) {
6854                 struct block_set *edge;
6855                 for(edge = block->edges; edge; edge = edge->next) {
6856                         if (phi_present(edge->member)) {
6857                                 return 1;
6858                         }
6859                 }
6860         }
6861         return 0;
6862 }
6863
6864 static struct triple *branch_target(struct compile_state *state, struct triple *ins)
6865 {
6866         struct triple *targ;
6867         targ = TARG(ins, 0);
6868         /* During scc_transform temporary triples are allocated that
6869          * loop back onto themselves. If I see one don't advance the
6870          * target.
6871          */
6872         while(triple_is_structural(state, targ) && 
6873                 (targ->next != targ) && (targ->next != state->first)) {
6874                 targ = targ->next;
6875         }
6876         return targ;
6877 }
6878
6879
6880 static void simplify_branch(struct compile_state *state, struct triple *ins)
6881 {
6882         int simplified;
6883         if ((ins->op != OP_BRANCH) && (ins->op != OP_CBRANCH)) {
6884                 internal_error(state, ins, "not branch");
6885         }
6886         if (ins->use != 0) {
6887                 internal_error(state, ins, "branch use");
6888         }
6889         /* The challenge here with simplify branch is that I need to 
6890          * make modifications to the control flow graph as well
6891          * as to the branch instruction itself.  That is handled
6892          * by rebuilding the basic blocks after simplify all is called.
6893          */
6894
6895         /* If we have a branch to an unconditional branch update
6896          * our target.  But watch out for dependencies from phi
6897          * functions. 
6898          */
6899         do {
6900                 struct triple *targ;
6901                 simplified = 0;
6902                 targ = branch_target(state, ins);
6903                 if ((targ != ins) && (targ->op == OP_BRANCH) && 
6904                         !phi_dependency(targ->u.block))
6905                 {
6906                         unuse_triple(TARG(ins, 0), ins);
6907                         TARG(ins, 0) = TARG(targ, 0);
6908                         use_triple(TARG(ins, 0), ins);
6909                         simplified = 1;
6910                 }
6911         } while(simplified);
6912
6913         /* If we have a conditional branch with a constant condition
6914          * make it an unconditional branch.
6915          */
6916         if ((ins->op == OP_CBRANCH) && is_const(RHS(ins, 0))) {
6917                 struct triple *targ;
6918                 ulong_t value;
6919                 value = read_const(state, ins, RHS(ins, 0));
6920                 unuse_triple(RHS(ins, 0), ins);
6921                 targ = TARG(ins, 0);
6922                 ins->sizes = TRIPLE_SIZES(0, 0, 0, 1);
6923                 ins->op = OP_BRANCH;
6924                 if (value) {
6925                         unuse_triple(ins->next, ins);
6926                         TARG(ins, 0) = targ;
6927                 }
6928                 else {
6929                         unuse_triple(targ, ins);
6930                         TARG(ins, 0) = ins->next;
6931                 }
6932         }
6933         
6934         /* If we have a branch to the next instruction
6935          * make it a noop.
6936          */
6937         if (TARG(ins, 0) == ins->next) {
6938                 unuse_triple(ins->next, ins);
6939                 if (ins->op == OP_CBRANCH) {
6940                         unuse_triple(RHS(ins, 0), ins);
6941                         unuse_triple(ins->next, ins);
6942                 }
6943                 ins->sizes = TRIPLE_SIZES(0, 0, 0, 0);
6944                 ins->op = OP_NOOP;
6945                 if (ins->use) {
6946                         internal_error(state, ins, "noop use != 0");
6947                 }
6948         }
6949 }
6950
6951 static void simplify_label(struct compile_state *state, struct triple *ins)
6952 {
6953         /* Ignore volatile labels */
6954         if (!triple_is_pure(state, ins, ins->id)) {
6955                 return;
6956         }
6957         if (ins->use == 0) {
6958                 ins->op = OP_NOOP;
6959         }
6960         else if (ins->prev->op == OP_LABEL) {
6961                 /* In general it is not safe to merge one label that
6962                  * imediately follows another.  The problem is that the empty
6963                  * looking block may have phi functions that depend on it.
6964                  */
6965                 if (!phi_dependency(ins->prev->u.block)) {
6966                         struct triple_set *user, *next;
6967                         ins->op = OP_NOOP;
6968                         for(user = ins->use; user; user = next) {
6969                                 struct triple *use, **expr;
6970                                 next = user->next;
6971                                 use = user->member;
6972                                 expr = triple_targ(state, use, 0);
6973                                 for(;expr; expr = triple_targ(state, use, expr)) {
6974                                         if (*expr == ins) {
6975                                                 *expr = ins->prev;
6976                                                 unuse_triple(ins, use);
6977                                                 use_triple(ins->prev, use);
6978                                         }
6979                                         
6980                                 }
6981                         }
6982                         if (ins->use) {
6983                                 internal_error(state, ins, "noop use != 0");
6984                         }
6985                 }
6986         }
6987 }
6988
6989 static void simplify_phi(struct compile_state *state, struct triple *ins)
6990 {
6991         struct triple **slot;
6992         struct triple *value;
6993         int zrhs, i;
6994         ulong_t cvalue;
6995         slot = &RHS(ins, 0);
6996         zrhs = TRIPLE_RHS(ins->sizes);
6997         if (zrhs == 0) {
6998                 return;
6999         }
7000         /* See if all of the rhs members of a phi have the same value */
7001         if (slot[0] && is_simple_const(slot[0])) {
7002                 cvalue = read_const(state, ins, slot[0]);
7003                 for(i = 1; i < zrhs; i++) {
7004                         if (    !slot[i] ||
7005                                 !is_simple_const(slot[i]) ||
7006                                 (cvalue != read_const(state, ins, slot[i]))) {
7007                                 break;
7008                         }
7009                 }
7010                 if (i == zrhs) {
7011                         mkconst(state, ins, cvalue);
7012                         return;
7013                 }
7014         }
7015         
7016         /* See if all of rhs members of a phi are the same */
7017         value = slot[0];
7018         for(i = 1; i < zrhs; i++) {
7019                 if (slot[i] != value) {
7020                         break;
7021                 }
7022         }
7023         if (i == zrhs) {
7024                 /* If the phi has a single value just copy it */
7025                 mkcopy(state, ins, value);
7026                 return;
7027         }
7028 }
7029
7030
7031 static void simplify_bsf(struct compile_state *state, struct triple *ins)
7032 {
7033         if (is_const(RHS(ins, 0))) {
7034                 ulong_t left;
7035                 left = read_const(state, ins, RHS(ins, 0));
7036                 mkconst(state, ins, bsf(left));
7037         }
7038 }
7039
7040 static void simplify_bsr(struct compile_state *state, struct triple *ins)
7041 {
7042         if (is_const(RHS(ins, 0))) {
7043                 ulong_t left;
7044                 left = read_const(state, ins, RHS(ins, 0));
7045                 mkconst(state, ins, bsr(left));
7046         }
7047 }
7048
7049
7050 typedef void (*simplify_t)(struct compile_state *state, struct triple *ins);
7051 static const struct simplify_table {
7052         simplify_t func;
7053         unsigned long flag;
7054 } table_simplify[] = {
7055 #define simplify_sdivt    simplify_noop
7056 #define simplify_udivt    simplify_noop
7057 #define simplify_piece    simplify_noop
7058
7059 [OP_SDIVT      ] = { simplify_sdivt,    COMPILER_SIMPLIFY_ARITH },
7060 [OP_UDIVT      ] = { simplify_udivt,    COMPILER_SIMPLIFY_ARITH },
7061 [OP_SMUL       ] = { simplify_smul,     COMPILER_SIMPLIFY_ARITH },
7062 [OP_UMUL       ] = { simplify_umul,     COMPILER_SIMPLIFY_ARITH },
7063 [OP_SDIV       ] = { simplify_sdiv,     COMPILER_SIMPLIFY_ARITH },
7064 [OP_UDIV       ] = { simplify_udiv,     COMPILER_SIMPLIFY_ARITH },
7065 [OP_SMOD       ] = { simplify_smod,     COMPILER_SIMPLIFY_ARITH },
7066 [OP_UMOD       ] = { simplify_umod,     COMPILER_SIMPLIFY_ARITH },
7067 [OP_ADD        ] = { simplify_add,      COMPILER_SIMPLIFY_ARITH },
7068 [OP_SUB        ] = { simplify_sub,      COMPILER_SIMPLIFY_ARITH },
7069 [OP_SL         ] = { simplify_sl,       COMPILER_SIMPLIFY_SHIFT },
7070 [OP_USR        ] = { simplify_usr,      COMPILER_SIMPLIFY_SHIFT },
7071 [OP_SSR        ] = { simplify_ssr,      COMPILER_SIMPLIFY_SHIFT },
7072 [OP_AND        ] = { simplify_and,      COMPILER_SIMPLIFY_BITWISE },
7073 [OP_XOR        ] = { simplify_xor,      COMPILER_SIMPLIFY_BITWISE },
7074 [OP_OR         ] = { simplify_or,       COMPILER_SIMPLIFY_BITWISE },
7075 [OP_POS        ] = { simplify_pos,      COMPILER_SIMPLIFY_ARITH },
7076 [OP_NEG        ] = { simplify_neg,      COMPILER_SIMPLIFY_ARITH },
7077 [OP_INVERT     ] = { simplify_invert,   COMPILER_SIMPLIFY_BITWISE },
7078
7079 [OP_EQ         ] = { simplify_eq,       COMPILER_SIMPLIFY_LOGICAL },
7080 [OP_NOTEQ      ] = { simplify_noteq,    COMPILER_SIMPLIFY_LOGICAL },
7081 [OP_SLESS      ] = { simplify_sless,    COMPILER_SIMPLIFY_LOGICAL },
7082 [OP_ULESS      ] = { simplify_uless,    COMPILER_SIMPLIFY_LOGICAL },
7083 [OP_SMORE      ] = { simplify_smore,    COMPILER_SIMPLIFY_LOGICAL },
7084 [OP_UMORE      ] = { simplify_umore,    COMPILER_SIMPLIFY_LOGICAL },
7085 [OP_SLESSEQ    ] = { simplify_slesseq,  COMPILER_SIMPLIFY_LOGICAL },
7086 [OP_ULESSEQ    ] = { simplify_ulesseq,  COMPILER_SIMPLIFY_LOGICAL },
7087 [OP_SMOREEQ    ] = { simplify_smoreeq,  COMPILER_SIMPLIFY_LOGICAL },
7088 [OP_UMOREEQ    ] = { simplify_umoreeq,  COMPILER_SIMPLIFY_LOGICAL },
7089 [OP_LFALSE     ] = { simplify_lfalse,   COMPILER_SIMPLIFY_LOGICAL },
7090 [OP_LTRUE      ] = { simplify_ltrue,    COMPILER_SIMPLIFY_LOGICAL },
7091
7092 [OP_LOAD       ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
7093 [OP_STORE      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
7094
7095 [OP_NOOP       ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
7096
7097 [OP_INTCONST   ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
7098 [OP_BLOBCONST  ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
7099 [OP_ADDRCONST  ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
7100
7101 [OP_WRITE      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
7102 [OP_READ       ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
7103 [OP_COPY       ] = { simplify_copy,     COMPILER_SIMPLIFY_COPY },
7104 [OP_PIECE      ] = { simplify_piece,    COMPILER_SIMPLIFY_OP },
7105 [OP_ASM        ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
7106
7107 [OP_DOT        ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
7108 [OP_VAL_VEC    ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
7109
7110 [OP_LIST       ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
7111 [OP_BRANCH     ] = { simplify_branch,   COMPILER_SIMPLIFY_BRANCH },
7112 [OP_CBRANCH    ] = { simplify_branch,   COMPILER_SIMPLIFY_BRANCH },
7113 [OP_CALL       ] = { simplify_noop,     COMPILER_SIMPLIFY_BRANCH },
7114 [OP_RET        ] = { simplify_noop,     COMPILER_SIMPLIFY_BRANCH },
7115 [OP_LABEL      ] = { simplify_label,    COMPILER_SIMPLIFY_LABEL },
7116 [OP_ADECL      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
7117 [OP_SDECL      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
7118 [OP_PHI        ] = { simplify_phi,      COMPILER_SIMPLIFY_PHI },
7119
7120 [OP_INB        ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
7121 [OP_INW        ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
7122 [OP_INL        ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
7123 [OP_OUTB       ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
7124 [OP_OUTW       ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
7125 [OP_OUTL       ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
7126 [OP_BSF        ] = { simplify_bsf,      COMPILER_SIMPLIFY_OP },
7127 [OP_BSR        ] = { simplify_bsr,      COMPILER_SIMPLIFY_OP },
7128 [OP_RDMSR      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
7129 [OP_WRMSR      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },               
7130 [OP_HLT        ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
7131 };
7132
7133 static void simplify(struct compile_state *state, struct triple *ins)
7134 {
7135         int op;
7136         simplify_t do_simplify;
7137         do {
7138                 op = ins->op;
7139                 do_simplify = 0;
7140                 if ((op < 0) || (op > sizeof(table_simplify)/sizeof(table_simplify[0]))) {
7141                         do_simplify = 0;
7142                 }
7143                 else if (state->compiler->flags & table_simplify[op].flag) {
7144                         do_simplify = table_simplify[op].func;
7145                 }
7146                 else {
7147                         do_simplify = simplify_noop;
7148                 }
7149         
7150                 if (!do_simplify) {
7151                         internal_error(state, ins, "cannot simplify op: %d %s\n",
7152                                 op, tops(op));
7153                         return;
7154                 }
7155                 do_simplify(state, ins);
7156         } while(ins->op != op);
7157 }
7158
7159 static void rebuild_ssa_form(struct compile_state *state);
7160
7161 static void simplify_all(struct compile_state *state)
7162 {
7163         struct triple *ins, *first;
7164         if (!(state->compiler->flags & COMPILER_SIMPLIFY)) {
7165                 return;
7166         }
7167         first = state->first;
7168         ins = first->prev;
7169         do {
7170                 simplify(state, ins);
7171                 ins = ins->prev;
7172         } while(ins != first->prev);
7173         ins = first;
7174         do {
7175                 simplify(state, ins);
7176                 ins = ins->next;
7177         }while(ins != first);
7178         rebuild_ssa_form(state);
7179
7180         print_blocks(state, __func__, stdout);
7181 }
7182
7183 /*
7184  * Builtins....
7185  * ============================
7186  */
7187
7188 static void register_builtin_function(struct compile_state *state,
7189         const char *name, int op, struct type *rtype, ...)
7190 {
7191         struct type *ftype, *atype, *param, **next;
7192         struct triple *def, *arg, *result, *work, *last, *first, *retvar, *ret;
7193         struct hash_entry *ident;
7194         struct file_state file;
7195         int parameters;
7196         int name_len;
7197         va_list args;
7198         int i;
7199
7200         /* Dummy file state to get debug handling right */
7201         memset(&file, 0, sizeof(file));
7202         file.basename = "<built-in>";
7203         file.line = 1;
7204         file.report_line = 1;
7205         file.report_name = file.basename;
7206         file.prev = state->file;
7207         state->file = &file;
7208         state->function = name;
7209
7210         /* Find the Parameter count */
7211         valid_op(state, op);
7212         parameters = table_ops[op].rhs;
7213         if (parameters < 0 ) {
7214                 internal_error(state, 0, "Invalid builtin parameter count");
7215         }
7216
7217         /* Find the function type */
7218         ftype = new_type(TYPE_FUNCTION | STOR_INLINE | STOR_STATIC, rtype, 0);
7219         next = &ftype->right;
7220         va_start(args, rtype);
7221         for(i = 0; i < parameters; i++) {
7222                 atype = va_arg(args, struct type *);
7223                 if (!*next) {
7224                         *next = atype;
7225                 } else {
7226                         *next = new_type(TYPE_PRODUCT, *next, atype);
7227                         next = &((*next)->right);
7228                 }
7229         }
7230         if (!*next) {
7231                 *next = &void_type;
7232         }
7233         va_end(args);
7234
7235         /* Generate the needed triples */
7236         def = triple(state, OP_LIST, ftype, 0, 0);
7237         first = label(state);
7238         RHS(def, 0) = first;
7239         retvar = variable(state, &void_ptr_type);
7240         retvar = flatten(state, first, retvar);
7241         ret = triple(state, OP_RET, &void_type, read_expr(state, retvar), 0);
7242
7243         /* Now string them together */
7244         param = ftype->right;
7245         for(i = 0; i < parameters; i++) {
7246                 if ((param->type & TYPE_MASK) == TYPE_PRODUCT) {
7247                         atype = param->left;
7248                 } else {
7249                         atype = param;
7250                 }
7251                 arg = flatten(state, first, variable(state, atype));
7252                 param = param->right;
7253         }
7254         result = 0;
7255         if ((rtype->type & TYPE_MASK) != TYPE_VOID) {
7256                 result = flatten(state, first, variable(state, rtype));
7257         }
7258         MISC(def, 0) = result;
7259         work = new_triple(state, op, rtype, -1, parameters);
7260         for(i = 0, arg = first->next->next; i < parameters; i++, arg = arg->next) {
7261                 RHS(work, i) = read_expr(state, arg);
7262         }
7263         if (result && ((rtype->type & TYPE_MASK) == TYPE_STRUCT)) {
7264                 struct triple *val;
7265                 /* Populate the LHS with the target registers */
7266                 work = flatten(state, first, work);
7267                 work->type = &void_type;
7268                 param = rtype->left;
7269                 if (rtype->elements != TRIPLE_LHS(work->sizes)) {
7270                         internal_error(state, 0, "Invalid result type");
7271                 }
7272                 val = new_triple(state, OP_VAL_VEC, rtype, -1, -1);
7273                 for(i = 0; i < rtype->elements; i++) {
7274                         struct triple *piece;
7275                         atype = param;
7276                         if ((param->type & TYPE_MASK) == TYPE_PRODUCT) {
7277                                 atype = param->left;
7278                         }
7279                         if (!TYPE_ARITHMETIC(atype->type) &&
7280                                 !TYPE_PTR(atype->type)) {
7281                                 internal_error(state, 0, "Invalid lhs type");
7282                         }
7283                         piece = triple(state, OP_PIECE, atype, work, 0);
7284                         piece->u.cval = i;
7285                         LHS(work, i) = piece;
7286                         RHS(val, i) = piece;
7287                 }
7288                 work = val;
7289         }
7290         if (result) {
7291                 work = write_expr(state, result, work);
7292         }
7293         work = flatten(state, first, work);
7294         last = flatten(state, first, label(state));
7295         ret  = flatten(state, first, ret);
7296         name_len = strlen(name);
7297         ident = lookup(state, name, name_len);
7298         ftype->type_ident = ident;
7299         symbol(state, ident, &ident->sym_ident, def, ftype);
7300         
7301         state->file = file.prev;
7302         state->function = 0;
7303         
7304         if (!state->functions) {
7305                 state->functions = def;
7306         } else {
7307                 insert_triple(state, state->functions, def);
7308         }
7309         if (state->compiler->debug & DEBUG_INLINE) {
7310                 fprintf(stdout, "\n");
7311                 loc(stdout, state, 0);
7312                 fprintf(stdout, "\n__________ %s _________\n", __FUNCTION__);
7313                 display_func(stdout, def);
7314                 fprintf(stdout, "__________ %s _________ done\n\n", __FUNCTION__);
7315         }
7316 }
7317
7318 static struct type *partial_struct(struct compile_state *state,
7319         const char *field_name, struct type *type, struct type *rest)
7320 {
7321         struct hash_entry *field_ident;
7322         struct type *result;
7323         int field_name_len;
7324
7325         field_name_len = strlen(field_name);
7326         field_ident = lookup(state, field_name, field_name_len);
7327
7328         result = clone_type(0, type);
7329         result->field_ident = field_ident;
7330
7331         if (rest) {
7332                 result = new_type(TYPE_PRODUCT, result, rest);
7333         }
7334         return result;
7335 }
7336
7337 static struct type *register_builtin_type(struct compile_state *state,
7338         const char *name, struct type *type)
7339 {
7340         struct hash_entry *ident;
7341         int name_len;
7342
7343         name_len = strlen(name);
7344         ident = lookup(state, name, name_len);
7345         
7346         if ((type->type & TYPE_MASK) == TYPE_PRODUCT) {
7347                 ulong_t elements = 0;
7348                 struct type *field;
7349                 type = new_type(TYPE_STRUCT, type, 0);
7350                 field = type->left;
7351                 while((field->type & TYPE_MASK) == TYPE_PRODUCT) {
7352                         elements++;
7353                         field = field->right;
7354                 }
7355                 elements++;
7356                 symbol(state, ident, &ident->sym_tag, 0, type);
7357                 type->type_ident = ident;
7358                 type->elements = elements;
7359         }
7360         symbol(state, ident, &ident->sym_ident, 0, type);
7361         ident->tok = TOK_TYPE_NAME;
7362         return type;
7363 }
7364
7365
7366 static void register_builtins(struct compile_state *state)
7367 {
7368         struct type *div_type, *ldiv_type;
7369         struct type *udiv_type, *uldiv_type;
7370         struct type *msr_type;
7371
7372         div_type = register_builtin_type(state, "__builtin_div_t",
7373                 partial_struct(state, "quot", &int_type,
7374                 partial_struct(state, "rem",  &int_type, 0)));
7375         ldiv_type = register_builtin_type(state, "__builtin_ldiv_t",
7376                 partial_struct(state, "quot", &long_type,
7377                 partial_struct(state, "rem",  &long_type, 0)));
7378         udiv_type = register_builtin_type(state, "__builtin_udiv_t",
7379                 partial_struct(state, "quot", &uint_type,
7380                 partial_struct(state, "rem",  &uint_type, 0)));
7381         uldiv_type = register_builtin_type(state, "__builtin_uldiv_t",
7382                 partial_struct(state, "quot", &ulong_type,
7383                 partial_struct(state, "rem",  &ulong_type, 0)));
7384
7385         register_builtin_function(state, "__builtin_div",   OP_SDIVT, div_type,
7386                 &int_type, &int_type);
7387         register_builtin_function(state, "__builtin_ldiv",  OP_SDIVT, ldiv_type,
7388                 &long_type, &long_type);
7389         register_builtin_function(state, "__builtin_udiv",  OP_UDIVT, udiv_type,
7390                 &uint_type, &uint_type);
7391         register_builtin_function(state, "__builtin_uldiv", OP_UDIVT, uldiv_type,
7392                 &ulong_type, &ulong_type);
7393
7394         register_builtin_function(state, "__builtin_inb", OP_INB, &uchar_type, 
7395                 &ushort_type);
7396         register_builtin_function(state, "__builtin_inw", OP_INW, &ushort_type,
7397                 &ushort_type);
7398         register_builtin_function(state, "__builtin_inl", OP_INL, &uint_type,   
7399                 &ushort_type);
7400
7401         register_builtin_function(state, "__builtin_outb", OP_OUTB, &void_type, 
7402                 &uchar_type, &ushort_type);
7403         register_builtin_function(state, "__builtin_outw", OP_OUTW, &void_type, 
7404                 &ushort_type, &ushort_type);
7405         register_builtin_function(state, "__builtin_outl", OP_OUTL, &void_type, 
7406                 &uint_type, &ushort_type);
7407         
7408         register_builtin_function(state, "__builtin_bsf", OP_BSF, &int_type, 
7409                 &int_type);
7410         register_builtin_function(state, "__builtin_bsr", OP_BSR, &int_type, 
7411                 &int_type);
7412
7413         msr_type = register_builtin_type(state, "__builtin_msr_t",
7414                 partial_struct(state, "lo", &ulong_type,
7415                 partial_struct(state, "hi", &ulong_type, 0)));
7416
7417         register_builtin_function(state, "__builtin_rdmsr", OP_RDMSR, msr_type,
7418                 &ulong_type);
7419         register_builtin_function(state, "__builtin_wrmsr", OP_WRMSR, &void_type,
7420                 &ulong_type, &ulong_type, &ulong_type);
7421         
7422         register_builtin_function(state, "__builtin_hlt", OP_HLT, &void_type, 
7423                 &void_type);
7424 }
7425
7426 static struct type *declarator(
7427         struct compile_state *state, struct type *type, 
7428         struct hash_entry **ident, int need_ident);
7429 static void decl(struct compile_state *state, struct triple *first);
7430 static struct type *specifier_qualifier_list(struct compile_state *state);
7431 static int isdecl_specifier(int tok);
7432 static struct type *decl_specifiers(struct compile_state *state);
7433 static int istype(int tok);
7434 static struct triple *expr(struct compile_state *state);
7435 static struct triple *assignment_expr(struct compile_state *state);
7436 static struct type *type_name(struct compile_state *state);
7437 static void statement(struct compile_state *state, struct triple *fist);
7438
7439 static struct triple *call_expr(
7440         struct compile_state *state, struct triple *func)
7441 {
7442         struct triple *def;
7443         struct type *param, *type;
7444         ulong_t pvals, index;
7445
7446         if ((func->type->type & TYPE_MASK) != TYPE_FUNCTION) {
7447                 error(state, 0, "Called object is not a function");
7448         }
7449         if (func->op != OP_LIST) {
7450                 internal_error(state, 0, "improper function");
7451         }
7452         eat(state, TOK_LPAREN);
7453         /* Find the return type without any specifiers */
7454         type = clone_type(0, func->type->left);
7455         /* Count the number of rhs entries for OP_FCALL */
7456         param = func->type->right;
7457         pvals = 0;
7458         while((param->type & TYPE_MASK) == TYPE_PRODUCT) {
7459                 pvals++;
7460                 param = param->right;
7461         }
7462         if ((param->type & TYPE_MASK) != TYPE_VOID) {
7463                 pvals++;
7464         }
7465         def = new_triple(state, OP_FCALL, type, -1, pvals);
7466         MISC(def, 0) = func;
7467
7468         param = func->type->right;
7469         for(index = 0; index < pvals; index++) {
7470                 struct triple *val;
7471                 struct type *arg_type;
7472                 val = read_expr(state, assignment_expr(state));
7473                 arg_type = param;
7474                 if ((param->type & TYPE_MASK) == TYPE_PRODUCT) {
7475                         arg_type = param->left;
7476                 }
7477                 write_compatible(state, arg_type, val->type);
7478                 RHS(def, index) = val;
7479                 if (index != (pvals - 1)) {
7480                         eat(state, TOK_COMMA);
7481                         param = param->right;
7482                 }
7483         }
7484         eat(state, TOK_RPAREN);
7485         return def;
7486 }
7487
7488
7489 static struct triple *character_constant(struct compile_state *state)
7490 {
7491         struct triple *def;
7492         struct token *tk;
7493         const signed char *str, *end;
7494         int c;
7495         int str_len;
7496         eat(state, TOK_LIT_CHAR);
7497         tk = &state->token[0];
7498         str = tk->val.str + 1;
7499         str_len = tk->str_len - 2;
7500         if (str_len <= 0) {
7501                 error(state, 0, "empty character constant");
7502         }
7503         end = str + str_len;
7504         c = char_value(state, &str, end);
7505         if (str != end) {
7506                 error(state, 0, "multibyte character constant not supported");
7507         }
7508         def = int_const(state, &char_type, (ulong_t)((long_t)c));
7509         return def;
7510 }
7511
7512 static struct triple *string_constant(struct compile_state *state)
7513 {
7514         struct triple *def;
7515         struct token *tk;
7516         struct type *type;
7517         const signed char *str, *end;
7518         signed char *buf, *ptr;
7519         int str_len;
7520
7521         buf = 0;
7522         type = new_type(TYPE_ARRAY, &char_type, 0);
7523         type->elements = 0;
7524         /* The while loop handles string concatenation */
7525         do {
7526                 eat(state, TOK_LIT_STRING);
7527                 tk = &state->token[0];
7528                 str = tk->val.str + 1;
7529                 str_len = tk->str_len - 2;
7530                 if (str_len < 0) {
7531                         error(state, 0, "negative string constant length");
7532                 }
7533                 end = str + str_len;
7534                 ptr = buf;
7535                 buf = xmalloc(type->elements + str_len + 1, "string_constant");
7536                 memcpy(buf, ptr, type->elements);
7537                 ptr = buf + type->elements;
7538                 do {
7539                         *ptr++ = char_value(state, &str, end);
7540                 } while(str < end);
7541                 type->elements = ptr - buf;
7542         } while(peek(state) == TOK_LIT_STRING);
7543         *ptr = '\0';
7544         type->elements += 1;
7545         def = triple(state, OP_BLOBCONST, type, 0, 0);
7546         def->u.blob = buf;
7547         return def;
7548 }
7549
7550
7551 static struct triple *integer_constant(struct compile_state *state)
7552 {
7553         struct triple *def;
7554         unsigned long val;
7555         struct token *tk;
7556         char *end;
7557         int u, l, decimal;
7558         struct type *type;
7559
7560         eat(state, TOK_LIT_INT);
7561         tk = &state->token[0];
7562         errno = 0;
7563         decimal = (tk->val.str[0] != '0');
7564         val = strtoul(tk->val.str, &end, 0);
7565         if ((val > ULONG_T_MAX) || ((val == ULONG_MAX) && (errno == ERANGE))) {
7566                 error(state, 0, "Integer constant to large");
7567         }
7568         u = l = 0;
7569         if ((*end == 'u') || (*end == 'U')) {
7570                 u = 1;
7571                         end++;
7572         }
7573         if ((*end == 'l') || (*end == 'L')) {
7574                 l = 1;
7575                 end++;
7576         }
7577         if ((*end == 'u') || (*end == 'U')) {
7578                 u = 1;
7579                 end++;
7580         }
7581         if (*end) {
7582                 error(state, 0, "Junk at end of integer constant");
7583         }
7584         if (u && l)  {
7585                 type = &ulong_type;
7586         }
7587         else if (l) {
7588                 type = &long_type;
7589                 if (!decimal && (val > LONG_T_MAX)) {
7590                         type = &ulong_type;
7591                 }
7592         }
7593         else if (u) {
7594                 type = &uint_type;
7595                 if (val > UINT_T_MAX) {
7596                         type = &ulong_type;
7597                 }
7598         }
7599         else {
7600                 type = &int_type;
7601                 if (!decimal && (val > INT_T_MAX) && (val <= UINT_T_MAX)) {
7602                         type = &uint_type;
7603                 }
7604                 else if (!decimal && (val > LONG_T_MAX)) {
7605                         type = &ulong_type;
7606                 }
7607                 else if (val > INT_T_MAX) {
7608                         type = &long_type;
7609                 }
7610         }
7611         def = int_const(state, type, val);
7612         return def;
7613 }
7614
7615 static struct triple *primary_expr(struct compile_state *state)
7616 {
7617         struct triple *def;
7618         int tok;
7619         tok = peek(state);
7620         switch(tok) {
7621         case TOK_IDENT:
7622         {
7623                 struct hash_entry *ident;
7624                 /* Here ident is either:
7625                  * a varable name
7626                  * a function name
7627                  */
7628                 eat(state, TOK_IDENT);
7629                 ident = state->token[0].ident;
7630                 if (!ident->sym_ident) {
7631                         error(state, 0, "%s undeclared", ident->name);
7632                 }
7633                 def = ident->sym_ident->def;
7634                 break;
7635         }
7636         case TOK_ENUM_CONST:
7637         {
7638                 struct hash_entry *ident;
7639                 /* Here ident is an enumeration constant */
7640                 eat(state, TOK_ENUM_CONST);
7641                 ident = state->token[0].ident;
7642                 if (!ident->sym_ident) {
7643                         error(state, 0, "%s undeclared", ident->name);
7644                 }
7645                 def = ident->sym_ident->def;
7646                 break;
7647         }
7648         case TOK_LPAREN:
7649                 eat(state, TOK_LPAREN);
7650                 def = expr(state);
7651                 eat(state, TOK_RPAREN);
7652                 break;
7653         case TOK_LIT_INT:
7654                 def = integer_constant(state);
7655                 break;
7656         case TOK_LIT_FLOAT:
7657                 eat(state, TOK_LIT_FLOAT);
7658                 error(state, 0, "Floating point constants not supported");
7659                 def = 0;
7660                 FINISHME();
7661                 break;
7662         case TOK_LIT_CHAR:
7663                 def = character_constant(state);
7664                 break;
7665         case TOK_LIT_STRING:
7666                 def = string_constant(state);
7667                 break;
7668         default:
7669                 def = 0;
7670                 error(state, 0, "Unexpected token: %s\n", tokens[tok]);
7671         }
7672         return def;
7673 }
7674
7675 static struct triple *postfix_expr(struct compile_state *state)
7676 {
7677         struct triple *def;
7678         int postfix;
7679         def = primary_expr(state);
7680         do {
7681                 struct triple *left;
7682                 int tok;
7683                 postfix = 1;
7684                 left = def;
7685                 switch((tok = peek(state))) {
7686                 case TOK_LBRACKET:
7687                         eat(state, TOK_LBRACKET);
7688                         def = mk_subscript_expr(state, left, expr(state));
7689                         eat(state, TOK_RBRACKET);
7690                         break;
7691                 case TOK_LPAREN:
7692                         def = call_expr(state, def);
7693                         break;
7694                 case TOK_DOT:
7695                 {
7696                         struct hash_entry *field;
7697                         eat(state, TOK_DOT);
7698                         eat(state, TOK_IDENT);
7699                         field = state->token[0].ident;
7700                         def = deref_field(state, def, field);
7701                         break;
7702                 }
7703                 case TOK_ARROW:
7704                 {
7705                         struct hash_entry *field;
7706                         eat(state, TOK_ARROW);
7707                         eat(state, TOK_IDENT);
7708                         field = state->token[0].ident;
7709                         def = mk_deref_expr(state, read_expr(state, def));
7710                         def = deref_field(state, def, field);
7711                         break;
7712                 }
7713                 case TOK_PLUSPLUS:
7714                         eat(state, TOK_PLUSPLUS);
7715                         def = mk_post_inc_expr(state, left);
7716                         break;
7717                 case TOK_MINUSMINUS:
7718                         eat(state, TOK_MINUSMINUS);
7719                         def = mk_post_dec_expr(state, left);
7720                         break;
7721                 default:
7722                         postfix = 0;
7723                         break;
7724                 }
7725         } while(postfix);
7726         return def;
7727 }
7728
7729 static struct triple *cast_expr(struct compile_state *state);
7730
7731 static struct triple *unary_expr(struct compile_state *state)
7732 {
7733         struct triple *def, *right;
7734         int tok;
7735         switch((tok = peek(state))) {
7736         case TOK_PLUSPLUS:
7737                 eat(state, TOK_PLUSPLUS);
7738                 def = mk_pre_inc_expr(state, unary_expr(state));
7739                 break;
7740         case TOK_MINUSMINUS:
7741                 eat(state, TOK_MINUSMINUS);
7742                 def = mk_pre_dec_expr(state, unary_expr(state));
7743                 break;
7744         case TOK_AND:
7745                 eat(state, TOK_AND);
7746                 def = mk_addr_expr(state, cast_expr(state), 0);
7747                 break;
7748         case TOK_STAR:
7749                 eat(state, TOK_STAR);
7750                 def = mk_deref_expr(state, read_expr(state, cast_expr(state)));
7751                 break;
7752         case TOK_PLUS:
7753                 eat(state, TOK_PLUS);
7754                 right = read_expr(state, cast_expr(state));
7755                 arithmetic(state, right);
7756                 def = integral_promotion(state, right);
7757                 break;
7758         case TOK_MINUS:
7759                 eat(state, TOK_MINUS);
7760                 right = read_expr(state, cast_expr(state));
7761                 arithmetic(state, right);
7762                 def = integral_promotion(state, right);
7763                 def = triple(state, OP_NEG, def->type, def, 0);
7764                 break;
7765         case TOK_TILDE:
7766                 eat(state, TOK_TILDE);
7767                 right = read_expr(state, cast_expr(state));
7768                 integral(state, right);
7769                 def = integral_promotion(state, right);
7770                 def = triple(state, OP_INVERT, def->type, def, 0);
7771                 break;
7772         case TOK_BANG:
7773                 eat(state, TOK_BANG);
7774                 right = read_expr(state, cast_expr(state));
7775                 bool(state, right);
7776                 def = lfalse_expr(state, right);
7777                 break;
7778         case TOK_SIZEOF:
7779         {
7780                 struct type *type;
7781                 int tok1, tok2;
7782                 eat(state, TOK_SIZEOF);
7783                 tok1 = peek(state);
7784                 tok2 = peek2(state);
7785                 if ((tok1 == TOK_LPAREN) && istype(tok2)) {
7786                         eat(state, TOK_LPAREN);
7787                         type = type_name(state);
7788                         eat(state, TOK_RPAREN);
7789                 }
7790                 else {
7791                         struct triple *expr;
7792                         expr = unary_expr(state);
7793                         type = expr->type;
7794                         release_expr(state, expr);
7795                 }
7796                 def = int_const(state, &ulong_type, size_of(state, type));
7797                 break;
7798         }
7799         case TOK_ALIGNOF:
7800         {
7801                 struct type *type;
7802                 int tok1, tok2;
7803                 eat(state, TOK_ALIGNOF);
7804                 tok1 = peek(state);
7805                 tok2 = peek2(state);
7806                 if ((tok1 == TOK_LPAREN) && istype(tok2)) {
7807                         eat(state, TOK_LPAREN);
7808                         type = type_name(state);
7809                         eat(state, TOK_RPAREN);
7810                 }
7811                 else {
7812                         struct triple *expr;
7813                         expr = unary_expr(state);
7814                         type = expr->type;
7815                         release_expr(state, expr);
7816                 }
7817                 def = int_const(state, &ulong_type, align_of(state, type));
7818                 break;
7819         }
7820         default:
7821                 def = postfix_expr(state);
7822                 break;
7823         }
7824         return def;
7825 }
7826
7827 static struct triple *cast_expr(struct compile_state *state)
7828 {
7829         struct triple *def;
7830         int tok1, tok2;
7831         tok1 = peek(state);
7832         tok2 = peek2(state);
7833         if ((tok1 == TOK_LPAREN) && istype(tok2)) {
7834                 struct type *type;
7835                 eat(state, TOK_LPAREN);
7836                 type = type_name(state);
7837                 eat(state, TOK_RPAREN);
7838                 def = mk_cast_expr(state, type, cast_expr(state));
7839         }
7840         else {
7841                 def = unary_expr(state);
7842         }
7843         return def;
7844 }
7845
7846 static struct triple *mult_expr(struct compile_state *state)
7847 {
7848         struct triple *def;
7849         int done;
7850         def = cast_expr(state);
7851         do {
7852                 struct triple *left, *right;
7853                 struct type *result_type;
7854                 int tok, op, sign;
7855                 done = 0;
7856                 switch(tok = (peek(state))) {
7857                 case TOK_STAR:
7858                 case TOK_DIV:
7859                 case TOK_MOD:
7860                         left = read_expr(state, def);
7861                         arithmetic(state, left);
7862
7863                         eat(state, tok);
7864
7865                         right = read_expr(state, cast_expr(state));
7866                         arithmetic(state, right);
7867
7868                         result_type = arithmetic_result(state, left, right);
7869                         sign = is_signed(result_type);
7870                         op = -1;
7871                         switch(tok) {
7872                         case TOK_STAR: op = sign? OP_SMUL : OP_UMUL; break;
7873                         case TOK_DIV:  op = sign? OP_SDIV : OP_UDIV; break;
7874                         case TOK_MOD:  op = sign? OP_SMOD : OP_UMOD; break;
7875                         }
7876                         def = triple(state, op, result_type, left, right);
7877                         break;
7878                 default:
7879                         done = 1;
7880                         break;
7881                 }
7882         } while(!done);
7883         return def;
7884 }
7885
7886 static struct triple *add_expr(struct compile_state *state)
7887 {
7888         struct triple *def;
7889         int done;
7890         def = mult_expr(state);
7891         do {
7892                 done = 0;
7893                 switch( peek(state)) {
7894                 case TOK_PLUS:
7895                         eat(state, TOK_PLUS);
7896                         def = mk_add_expr(state, def, mult_expr(state));
7897                         break;
7898                 case TOK_MINUS:
7899                         eat(state, TOK_MINUS);
7900                         def = mk_sub_expr(state, def, mult_expr(state));
7901                         break;
7902                 default:
7903                         done = 1;
7904                         break;
7905                 }
7906         } while(!done);
7907         return def;
7908 }
7909
7910 static struct triple *shift_expr(struct compile_state *state)
7911 {
7912         struct triple *def;
7913         int done;
7914         def = add_expr(state);
7915         do {
7916                 struct triple *left, *right;
7917                 int tok, op;
7918                 done = 0;
7919                 switch((tok = peek(state))) {
7920                 case TOK_SL:
7921                 case TOK_SR:
7922                         left = read_expr(state, def);
7923                         integral(state, left);
7924                         left = integral_promotion(state, left);
7925
7926                         eat(state, tok);
7927
7928                         right = read_expr(state, add_expr(state));
7929                         integral(state, right);
7930                         right = integral_promotion(state, right);
7931                         
7932                         op = (tok == TOK_SL)? OP_SL : 
7933                                 is_signed(left->type)? OP_SSR: OP_USR;
7934
7935                         def = triple(state, op, left->type, left, right);
7936                         break;
7937                 default:
7938                         done = 1;
7939                         break;
7940                 }
7941         } while(!done);
7942         return def;
7943 }
7944
7945 static struct triple *relational_expr(struct compile_state *state)
7946 {
7947 #warning "Extend relational exprs to work on more than arithmetic types"
7948         struct triple *def;
7949         int done;
7950         def = shift_expr(state);
7951         do {
7952                 struct triple *left, *right;
7953                 struct type *arg_type;
7954                 int tok, op, sign;
7955                 done = 0;
7956                 switch((tok = peek(state))) {
7957                 case TOK_LESS:
7958                 case TOK_MORE:
7959                 case TOK_LESSEQ:
7960                 case TOK_MOREEQ:
7961                         left = read_expr(state, def);
7962                         arithmetic(state, left);
7963
7964                         eat(state, tok);
7965
7966                         right = read_expr(state, shift_expr(state));
7967                         arithmetic(state, right);
7968
7969                         arg_type = arithmetic_result(state, left, right);
7970                         sign = is_signed(arg_type);
7971                         op = -1;
7972                         switch(tok) {
7973                         case TOK_LESS:   op = sign? OP_SLESS : OP_ULESS; break;
7974                         case TOK_MORE:   op = sign? OP_SMORE : OP_UMORE; break;
7975                         case TOK_LESSEQ: op = sign? OP_SLESSEQ : OP_ULESSEQ; break;
7976                         case TOK_MOREEQ: op = sign? OP_SMOREEQ : OP_UMOREEQ; break;
7977                         }
7978                         def = triple(state, op, &int_type, left, right);
7979                         break;
7980                 default:
7981                         done = 1;
7982                         break;
7983                 }
7984         } while(!done);
7985         return def;
7986 }
7987
7988 static struct triple *equality_expr(struct compile_state *state)
7989 {
7990 #warning "Extend equality exprs to work on more than arithmetic types"
7991         struct triple *def;
7992         int done;
7993         def = relational_expr(state);
7994         do {
7995                 struct triple *left, *right;
7996                 int tok, op;
7997                 done = 0;
7998                 switch((tok = peek(state))) {
7999                 case TOK_EQEQ:
8000                 case TOK_NOTEQ:
8001                         left = read_expr(state, def);
8002                         arithmetic(state, left);
8003                         eat(state, tok);
8004                         right = read_expr(state, relational_expr(state));
8005                         arithmetic(state, right);
8006                         op = (tok == TOK_EQEQ) ? OP_EQ: OP_NOTEQ;
8007                         def = triple(state, op, &int_type, left, right);
8008                         break;
8009                 default:
8010                         done = 1;
8011                         break;
8012                 }
8013         } while(!done);
8014         return def;
8015 }
8016
8017 static struct triple *and_expr(struct compile_state *state)
8018 {
8019         struct triple *def;
8020         def = equality_expr(state);
8021         while(peek(state) == TOK_AND) {
8022                 struct triple *left, *right;
8023                 struct type *result_type;
8024                 left = read_expr(state, def);
8025                 integral(state, left);
8026                 eat(state, TOK_AND);
8027                 right = read_expr(state, equality_expr(state));
8028                 integral(state, right);
8029                 result_type = arithmetic_result(state, left, right);
8030                 def = triple(state, OP_AND, result_type, left, right);
8031         }
8032         return def;
8033 }
8034
8035 static struct triple *xor_expr(struct compile_state *state)
8036 {
8037         struct triple *def;
8038         def = and_expr(state);
8039         while(peek(state) == TOK_XOR) {
8040                 struct triple *left, *right;
8041                 struct type *result_type;
8042                 left = read_expr(state, def);
8043                 integral(state, left);
8044                 eat(state, TOK_XOR);
8045                 right = read_expr(state, and_expr(state));
8046                 integral(state, right);
8047                 result_type = arithmetic_result(state, left, right);
8048                 def = triple(state, OP_XOR, result_type, left, right);
8049         }
8050         return def;
8051 }
8052
8053 static struct triple *or_expr(struct compile_state *state)
8054 {
8055         struct triple *def;
8056         def = xor_expr(state);
8057         while(peek(state) == TOK_OR) {
8058                 struct triple *left, *right;
8059                 struct type *result_type;
8060                 left = read_expr(state, def);
8061                 integral(state, left);
8062                 eat(state, TOK_OR);
8063                 right = read_expr(state, xor_expr(state));
8064                 integral(state, right);
8065                 result_type = arithmetic_result(state, left, right);
8066                 def = triple(state, OP_OR, result_type, left, right);
8067         }
8068         return def;
8069 }
8070
8071 static struct triple *land_expr(struct compile_state *state)
8072 {
8073         struct triple *def;
8074         def = or_expr(state);
8075         while(peek(state) == TOK_LOGAND) {
8076                 struct triple *left, *right;
8077                 left = read_expr(state, def);
8078                 bool(state, left);
8079                 eat(state, TOK_LOGAND);
8080                 right = read_expr(state, or_expr(state));
8081                 bool(state, right);
8082
8083                 def = triple(state, OP_LAND, &int_type,
8084                         ltrue_expr(state, left),
8085                         ltrue_expr(state, right));
8086         }
8087         return def;
8088 }
8089
8090 static struct triple *lor_expr(struct compile_state *state)
8091 {
8092         struct triple *def;
8093         def = land_expr(state);
8094         while(peek(state) == TOK_LOGOR) {
8095                 struct triple *left, *right;
8096                 left = read_expr(state, def);
8097                 bool(state, left);
8098                 eat(state, TOK_LOGOR);
8099                 right = read_expr(state, land_expr(state));
8100                 bool(state, right);
8101                 
8102                 def = triple(state, OP_LOR, &int_type,
8103                         ltrue_expr(state, left),
8104                         ltrue_expr(state, right));
8105         }
8106         return def;
8107 }
8108
8109 static struct triple *conditional_expr(struct compile_state *state)
8110 {
8111         struct triple *def;
8112         def = lor_expr(state);
8113         if (peek(state) == TOK_QUEST) {
8114                 struct triple *test, *left, *right;
8115                 bool(state, def);
8116                 test = ltrue_expr(state, read_expr(state, def));
8117                 eat(state, TOK_QUEST);
8118                 left = read_expr(state, expr(state));
8119                 eat(state, TOK_COLON);
8120                 right = read_expr(state, conditional_expr(state));
8121
8122                 def = cond_expr(state, test, left, right);
8123         }
8124         return def;
8125 }
8126
8127 static struct triple *eval_const_expr(
8128         struct compile_state *state, struct triple *expr)
8129 {
8130         struct triple *def;
8131         if (is_const(expr)) {
8132                 def = expr;
8133         } 
8134         else {
8135                 /* If we don't start out as a constant simplify into one */
8136                 struct triple *head, *ptr;
8137                 head = label(state); /* dummy initial triple */
8138                 flatten(state, head, expr);
8139                 for(ptr = head->next; ptr != head; ptr = ptr->next) {
8140                         simplify(state, ptr);
8141                 }
8142                 /* Remove the constant value the tail of the list */
8143                 def = head->prev;
8144                 def->prev->next = def->next;
8145                 def->next->prev = def->prev;
8146                 def->next = def->prev = def;
8147                 if (!is_const(def)) {
8148                         error(state, 0, "Not a constant expression");
8149                 }
8150                 /* Free the intermediate expressions */
8151                 while(head->next != head) {
8152                         release_triple(state, head->next);
8153                 }
8154                 free_triple(state, head);
8155         }
8156         return def;
8157 }
8158
8159 static struct triple *constant_expr(struct compile_state *state)
8160 {
8161         return eval_const_expr(state, conditional_expr(state));
8162 }
8163
8164 static struct triple *assignment_expr(struct compile_state *state)
8165 {
8166         struct triple *def, *left, *right;
8167         int tok, op, sign;
8168         /* The C grammer in K&R shows assignment expressions
8169          * only taking unary expressions as input on their
8170          * left hand side.  But specifies the precedence of
8171          * assignemnt as the lowest operator except for comma.
8172          *
8173          * Allowing conditional expressions on the left hand side
8174          * of an assignement results in a grammar that accepts
8175          * a larger set of statements than standard C.   As long
8176          * as the subset of the grammar that is standard C behaves
8177          * correctly this should cause no problems.
8178          * 
8179          * For the extra token strings accepted by the grammar
8180          * none of them should produce a valid lvalue, so they
8181          * should not produce functioning programs.
8182          *
8183          * GCC has this bug as well, so surprises should be minimal.
8184          */
8185         def = conditional_expr(state);
8186         left = def;
8187         switch((tok = peek(state))) {
8188         case TOK_EQ:
8189                 lvalue(state, left);
8190                 eat(state, TOK_EQ);
8191                 def = write_expr(state, left, 
8192                         read_expr(state, assignment_expr(state)));
8193                 break;
8194         case TOK_TIMESEQ:
8195         case TOK_DIVEQ:
8196         case TOK_MODEQ:
8197                 lvalue(state, left);
8198                 arithmetic(state, left);
8199                 eat(state, tok);
8200                 right = read_expr(state, assignment_expr(state));
8201                 arithmetic(state, right);
8202
8203                 sign = is_signed(left->type);
8204                 op = -1;
8205                 switch(tok) {
8206                 case TOK_TIMESEQ: op = sign? OP_SMUL : OP_UMUL; break;
8207                 case TOK_DIVEQ:   op = sign? OP_SDIV : OP_UDIV; break;
8208                 case TOK_MODEQ:   op = sign? OP_SMOD : OP_UMOD; break;
8209                 }
8210                 def = write_expr(state, left,
8211                         triple(state, op, left->type, 
8212                                 read_expr(state, left), right));
8213                 break;
8214         case TOK_PLUSEQ:
8215                 lvalue(state, left);
8216                 eat(state, TOK_PLUSEQ);
8217                 def = write_expr(state, left,
8218                         mk_add_expr(state, left, assignment_expr(state)));
8219                 break;
8220         case TOK_MINUSEQ:
8221                 lvalue(state, left);
8222                 eat(state, TOK_MINUSEQ);
8223                 def = write_expr(state, left,
8224                         mk_sub_expr(state, left, assignment_expr(state)));
8225                 break;
8226         case TOK_SLEQ:
8227         case TOK_SREQ:
8228         case TOK_ANDEQ:
8229         case TOK_XOREQ:
8230         case TOK_OREQ:
8231                 lvalue(state, left);
8232                 integral(state, left);
8233                 eat(state, tok);
8234                 right = read_expr(state, assignment_expr(state));
8235                 integral(state, right);
8236                 right = integral_promotion(state, right);
8237                 sign = is_signed(left->type);
8238                 op = -1;
8239                 switch(tok) {
8240                 case TOK_SLEQ:  op = OP_SL; break;
8241                 case TOK_SREQ:  op = sign? OP_SSR: OP_USR; break;
8242                 case TOK_ANDEQ: op = OP_AND; break;
8243                 case TOK_XOREQ: op = OP_XOR; break;
8244                 case TOK_OREQ:  op = OP_OR; break;
8245                 }
8246                 def = write_expr(state, left,
8247                         triple(state, op, left->type, 
8248                                 read_expr(state, left), right));
8249                 break;
8250         }
8251         return def;
8252 }
8253
8254 static struct triple *expr(struct compile_state *state)
8255 {
8256         struct triple *def;
8257         def = assignment_expr(state);
8258         while(peek(state) == TOK_COMMA) {
8259                 struct triple *left, *right;
8260                 left = def;
8261                 eat(state, TOK_COMMA);
8262                 right = assignment_expr(state);
8263                 def = triple(state, OP_COMMA, right->type, left, right);
8264         }
8265         return def;
8266 }
8267
8268 static void expr_statement(struct compile_state *state, struct triple *first)
8269 {
8270         if (peek(state) != TOK_SEMI) {
8271                 flatten(state, first, expr(state));
8272         }
8273         eat(state, TOK_SEMI);
8274 }
8275
8276 static void if_statement(struct compile_state *state, struct triple *first)
8277 {
8278         struct triple *test, *jmp1, *jmp2, *middle, *end;
8279
8280         jmp1 = jmp2 = middle = 0;
8281         eat(state, TOK_IF);
8282         eat(state, TOK_LPAREN);
8283         test = expr(state);
8284         bool(state, test);
8285         /* Cleanup and invert the test */
8286         test = lfalse_expr(state, read_expr(state, test));
8287         eat(state, TOK_RPAREN);
8288         /* Generate the needed pieces */
8289         middle = label(state);
8290         jmp1 = branch(state, middle, test);
8291         /* Thread the pieces together */
8292         flatten(state, first, test);
8293         flatten(state, first, jmp1);
8294         flatten(state, first, label(state));
8295         statement(state, first);
8296         if (peek(state) == TOK_ELSE) {
8297                 eat(state, TOK_ELSE);
8298                 /* Generate the rest of the pieces */
8299                 end = label(state);
8300                 jmp2 = branch(state, end, 0);
8301                 /* Thread them together */
8302                 flatten(state, first, jmp2);
8303                 flatten(state, first, middle);
8304                 statement(state, first);
8305                 flatten(state, first, end);
8306         }
8307         else {
8308                 flatten(state, first, middle);
8309         }
8310 }
8311
8312 static void for_statement(struct compile_state *state, struct triple *first)
8313 {
8314         struct triple *head, *test, *tail, *jmp1, *jmp2, *end;
8315         struct triple *label1, *label2, *label3;
8316         struct hash_entry *ident;
8317
8318         eat(state, TOK_FOR);
8319         eat(state, TOK_LPAREN);
8320         head = test = tail = jmp1 = jmp2 = 0;
8321         if (peek(state) != TOK_SEMI) {
8322                 head = expr(state);
8323         } 
8324         eat(state, TOK_SEMI);
8325         if (peek(state) != TOK_SEMI) {
8326                 test = expr(state);
8327                 bool(state, test);
8328                 test = ltrue_expr(state, read_expr(state, test));
8329         }
8330         eat(state, TOK_SEMI);
8331         if (peek(state) != TOK_RPAREN) {
8332                 tail = expr(state);
8333         }
8334         eat(state, TOK_RPAREN);
8335         /* Generate the needed pieces */
8336         label1 = label(state);
8337         label2 = label(state);
8338         label3 = label(state);
8339         if (test) {
8340                 jmp1 = branch(state, label3, 0);
8341                 jmp2 = branch(state, label1, test);
8342         }
8343         else {
8344                 jmp2 = branch(state, label1, 0);
8345         }
8346         end = label(state);
8347         /* Remember where break and continue go */
8348         start_scope(state);
8349         ident = state->i_break;
8350         symbol(state, ident, &ident->sym_ident, end, end->type);
8351         ident = state->i_continue;
8352         symbol(state, ident, &ident->sym_ident, label2, label2->type);
8353         /* Now include the body */
8354         flatten(state, first, head);
8355         flatten(state, first, jmp1);
8356         flatten(state, first, label1);
8357         statement(state, first);
8358         flatten(state, first, label2);
8359         flatten(state, first, tail);
8360         flatten(state, first, label3);
8361         flatten(state, first, test);
8362         flatten(state, first, jmp2);
8363         flatten(state, first, end);
8364         /* Cleanup the break/continue scope */
8365         end_scope(state);
8366 }
8367
8368 static void while_statement(struct compile_state *state, struct triple *first)
8369 {
8370         struct triple *label1, *test, *label2, *jmp1, *jmp2, *end;
8371         struct hash_entry *ident;
8372         eat(state, TOK_WHILE);
8373         eat(state, TOK_LPAREN);
8374         test = expr(state);
8375         bool(state, test);
8376         test = ltrue_expr(state, read_expr(state, test));
8377         eat(state, TOK_RPAREN);
8378         /* Generate the needed pieces */
8379         label1 = label(state);
8380         label2 = label(state);
8381         jmp1 = branch(state, label2, 0);
8382         jmp2 = branch(state, label1, test);
8383         end = label(state);
8384         /* Remember where break and continue go */
8385         start_scope(state);
8386         ident = state->i_break;
8387         symbol(state, ident, &ident->sym_ident, end, end->type);
8388         ident = state->i_continue;
8389         symbol(state, ident, &ident->sym_ident, label2, label2->type);
8390         /* Thread them together */
8391         flatten(state, first, jmp1);
8392         flatten(state, first, label1);
8393         statement(state, first);
8394         flatten(state, first, label2);
8395         flatten(state, first, test);
8396         flatten(state, first, jmp2);
8397         flatten(state, first, end);
8398         /* Cleanup the break/continue scope */
8399         end_scope(state);
8400 }
8401
8402 static void do_statement(struct compile_state *state, struct triple *first)
8403 {
8404         struct triple *label1, *label2, *test, *end;
8405         struct hash_entry *ident;
8406         eat(state, TOK_DO);
8407         /* Generate the needed pieces */
8408         label1 = label(state);
8409         label2 = label(state);
8410         end = label(state);
8411         /* Remember where break and continue go */
8412         start_scope(state);
8413         ident = state->i_break;
8414         symbol(state, ident, &ident->sym_ident, end, end->type);
8415         ident = state->i_continue;
8416         symbol(state, ident, &ident->sym_ident, label2, label2->type);
8417         /* Now include the body */
8418         flatten(state, first, label1);
8419         statement(state, first);
8420         /* Cleanup the break/continue scope */
8421         end_scope(state);
8422         /* Eat the rest of the loop */
8423         eat(state, TOK_WHILE);
8424         eat(state, TOK_LPAREN);
8425         test = read_expr(state, expr(state));
8426         bool(state, test);
8427         eat(state, TOK_RPAREN);
8428         eat(state, TOK_SEMI);
8429         /* Thread the pieces together */
8430         test = ltrue_expr(state, test);
8431         flatten(state, first, label2);
8432         flatten(state, first, test);
8433         flatten(state, first, branch(state, label1, test));
8434         flatten(state, first, end);
8435 }
8436
8437
8438 static void return_statement(struct compile_state *state, struct triple *first)
8439 {
8440         struct triple *jmp, *mv, *dest, *var, *val;
8441         int last;
8442         eat(state, TOK_RETURN);
8443
8444 #warning "FIXME implement a more general excess branch elimination"
8445         val = 0;
8446         /* If we have a return value do some more work */
8447         if (peek(state) != TOK_SEMI) {
8448                 val = read_expr(state, expr(state));
8449         }
8450         eat(state, TOK_SEMI);
8451
8452         /* See if this last statement in a function */
8453         last = ((peek(state) == TOK_RBRACE) && 
8454                 (state->scope_depth == GLOBAL_SCOPE_DEPTH +2));
8455
8456         /* Find the return variable */
8457         var = MISC(state->main_function, 0);
8458         /* Find the return destination */
8459         dest = state->i_return->sym_ident->def;
8460         mv = jmp = 0;
8461         /* If needed generate a jump instruction */
8462         if (!last) {
8463                 jmp = branch(state, dest, 0);
8464         }
8465         /* If needed generate an assignment instruction */
8466         if (val) {
8467                 mv = write_expr(state, var, val);
8468         }
8469         /* Now put the code together */
8470         if (mv) {
8471                 flatten(state, first, mv);
8472                 flatten(state, first, jmp);
8473         }
8474         else if (jmp) {
8475                 flatten(state, first, jmp);
8476         }
8477 }
8478
8479 static void break_statement(struct compile_state *state, struct triple *first)
8480 {
8481         struct triple *dest;
8482         eat(state, TOK_BREAK);
8483         eat(state, TOK_SEMI);
8484         if (!state->i_break->sym_ident) {
8485                 error(state, 0, "break statement not within loop or switch");
8486         }
8487         dest = state->i_break->sym_ident->def;
8488         flatten(state, first, branch(state, dest, 0));
8489 }
8490
8491 static void continue_statement(struct compile_state *state, struct triple *first)
8492 {
8493         struct triple *dest;
8494         eat(state, TOK_CONTINUE);
8495         eat(state, TOK_SEMI);
8496         if (!state->i_continue->sym_ident) {
8497                 error(state, 0, "continue statement outside of a loop");
8498         }
8499         dest = state->i_continue->sym_ident->def;
8500         flatten(state, first, branch(state, dest, 0));
8501 }
8502
8503 static void goto_statement(struct compile_state *state, struct triple *first)
8504 {
8505         struct hash_entry *ident;
8506         eat(state, TOK_GOTO);
8507         eat(state, TOK_IDENT);
8508         ident = state->token[0].ident;
8509         if (!ident->sym_label) {
8510                 /* If this is a forward branch allocate the label now,
8511                  * it will be flattend in the appropriate location later.
8512                  */
8513                 struct triple *ins;
8514                 ins = label(state);
8515                 label_symbol(state, ident, ins);
8516         }
8517         eat(state, TOK_SEMI);
8518
8519         flatten(state, first, branch(state, ident->sym_label->def, 0));
8520 }
8521
8522 static void labeled_statement(struct compile_state *state, struct triple *first)
8523 {
8524         struct triple *ins;
8525         struct hash_entry *ident;
8526         eat(state, TOK_IDENT);
8527
8528         ident = state->token[0].ident;
8529         if (ident->sym_label && ident->sym_label->def) {
8530                 ins = ident->sym_label->def;
8531                 put_occurance(ins->occurance);
8532                 ins->occurance = new_occurance(state);
8533         }
8534         else {
8535                 ins = label(state);
8536                 label_symbol(state, ident, ins);
8537         }
8538         if (ins->id & TRIPLE_FLAG_FLATTENED) {
8539                 error(state, 0, "label %s already defined", ident->name);
8540         }
8541         flatten(state, first, ins);
8542
8543         eat(state, TOK_COLON);
8544         statement(state, first);
8545 }
8546
8547 static void switch_statement(struct compile_state *state, struct triple *first)
8548 {
8549         struct triple *value, *top, *end, *dbranch;
8550         struct hash_entry *ident;
8551
8552         /* See if we have a valid switch statement */
8553         eat(state, TOK_SWITCH);
8554         eat(state, TOK_LPAREN);
8555         value = expr(state);
8556         integral(state, value);
8557         value = read_expr(state, value);
8558         eat(state, TOK_RPAREN);
8559         /* Generate the needed pieces */
8560         top = label(state);
8561         end = label(state);
8562         dbranch = branch(state, end, 0);
8563         /* Remember where case branches and break goes */
8564         start_scope(state);
8565         ident = state->i_switch;
8566         symbol(state, ident, &ident->sym_ident, value, value->type);
8567         ident = state->i_case;
8568         symbol(state, ident, &ident->sym_ident, top, top->type);
8569         ident = state->i_break;
8570         symbol(state, ident, &ident->sym_ident, end, end->type);
8571         ident = state->i_default;
8572         symbol(state, ident, &ident->sym_ident, dbranch, dbranch->type);
8573         /* Thread them together */
8574         flatten(state, first, value);
8575         flatten(state, first, top);
8576         flatten(state, first, dbranch);
8577         statement(state, first);
8578         flatten(state, first, end);
8579         /* Cleanup the switch scope */
8580         end_scope(state);
8581 }
8582
8583 static void case_statement(struct compile_state *state, struct triple *first)
8584 {
8585         struct triple *cvalue, *dest, *test, *jmp;
8586         struct triple *ptr, *value, *top, *dbranch;
8587
8588         /* See if w have a valid case statement */
8589         eat(state, TOK_CASE);
8590         cvalue = constant_expr(state);
8591         integral(state, cvalue);
8592         if (cvalue->op != OP_INTCONST) {
8593                 error(state, 0, "integer constant expected");
8594         }
8595         eat(state, TOK_COLON);
8596         if (!state->i_case->sym_ident) {
8597                 error(state, 0, "case statement not within a switch");
8598         }
8599
8600         /* Lookup the interesting pieces */
8601         top = state->i_case->sym_ident->def;
8602         value = state->i_switch->sym_ident->def;
8603         dbranch = state->i_default->sym_ident->def;
8604
8605         /* See if this case label has already been used */
8606         for(ptr = top; ptr != dbranch; ptr = ptr->next) {
8607                 if (ptr->op != OP_EQ) {
8608                         continue;
8609                 }
8610                 if (RHS(ptr, 1)->u.cval == cvalue->u.cval) {
8611                         error(state, 0, "duplicate case %d statement",
8612                                 cvalue->u.cval);
8613                 }
8614         }
8615         /* Generate the needed pieces */
8616         dest = label(state);
8617         test = triple(state, OP_EQ, &int_type, value, cvalue);
8618         jmp = branch(state, dest, test);
8619         /* Thread the pieces together */
8620         flatten(state, dbranch, test);
8621         flatten(state, dbranch, jmp);
8622         flatten(state, dbranch, label(state));
8623         flatten(state, first, dest);
8624         statement(state, first);
8625 }
8626
8627 static void default_statement(struct compile_state *state, struct triple *first)
8628 {
8629         struct triple *dest;
8630         struct triple *dbranch, *end;
8631
8632         /* See if we have a valid default statement */
8633         eat(state, TOK_DEFAULT);
8634         eat(state, TOK_COLON);
8635
8636         if (!state->i_case->sym_ident) {
8637                 error(state, 0, "default statement not within a switch");
8638         }
8639
8640         /* Lookup the interesting pieces */
8641         dbranch = state->i_default->sym_ident->def;
8642         end = state->i_break->sym_ident->def;
8643
8644         /* See if a default statement has already happened */
8645         if (TARG(dbranch, 0) != end) {
8646                 error(state, 0, "duplicate default statement");
8647         }
8648
8649         /* Generate the needed pieces */
8650         dest = label(state);
8651
8652         /* Thread the pieces together */
8653         TARG(dbranch, 0) = dest;
8654         flatten(state, first, dest);
8655         statement(state, first);
8656 }
8657
8658 static void asm_statement(struct compile_state *state, struct triple *first)
8659 {
8660         struct asm_info *info;
8661         struct {
8662                 struct triple *constraint;
8663                 struct triple *expr;
8664         } out_param[MAX_LHS], in_param[MAX_RHS], clob_param[MAX_LHS];
8665         struct triple *def, *asm_str;
8666         int out, in, clobbers, more, colons, i;
8667
8668         eat(state, TOK_ASM);
8669         /* For now ignore the qualifiers */
8670         switch(peek(state)) {
8671         case TOK_CONST:
8672                 eat(state, TOK_CONST);
8673                 break;
8674         case TOK_VOLATILE:
8675                 eat(state, TOK_VOLATILE);
8676                 break;
8677         }
8678         eat(state, TOK_LPAREN);
8679         asm_str = string_constant(state);
8680
8681         colons = 0;
8682         out = in = clobbers = 0;
8683         /* Outputs */
8684         if ((colons == 0) && (peek(state) == TOK_COLON)) {
8685                 eat(state, TOK_COLON);
8686                 colons++;
8687                 more = (peek(state) == TOK_LIT_STRING);
8688                 while(more) {
8689                         struct triple *var;
8690                         struct triple *constraint;
8691                         char *str;
8692                         more = 0;
8693                         if (out > MAX_LHS) {
8694                                 error(state, 0, "Maximum output count exceeded.");
8695                         }
8696                         constraint = string_constant(state);
8697                         str = constraint->u.blob;
8698                         if (str[0] != '=') {
8699                                 error(state, 0, "Output constraint does not start with =");
8700                         }
8701                         constraint->u.blob = str + 1;
8702                         eat(state, TOK_LPAREN);
8703                         var = conditional_expr(state);
8704                         eat(state, TOK_RPAREN);
8705
8706                         lvalue(state, var);
8707                         out_param[out].constraint = constraint;
8708                         out_param[out].expr       = var;
8709                         if (peek(state) == TOK_COMMA) {
8710                                 eat(state, TOK_COMMA);
8711                                 more = 1;
8712                         }
8713                         out++;
8714                 }
8715         }
8716         /* Inputs */
8717         if ((colons == 1) && (peek(state) == TOK_COLON)) {
8718                 eat(state, TOK_COLON);
8719                 colons++;
8720                 more = (peek(state) == TOK_LIT_STRING);
8721                 while(more) {
8722                         struct triple *val;
8723                         struct triple *constraint;
8724                         char *str;
8725                         more = 0;
8726                         if (in > MAX_RHS) {
8727                                 error(state, 0, "Maximum input count exceeded.");
8728                         }
8729                         constraint = string_constant(state);
8730                         str = constraint->u.blob;
8731                         if (digitp(str[0] && str[1] == '\0')) {
8732                                 int val;
8733                                 val = digval(str[0]);
8734                                 if ((val < 0) || (val >= out)) {
8735                                         error(state, 0, "Invalid input constraint %d", val);
8736                                 }
8737                         }
8738                         eat(state, TOK_LPAREN);
8739                         val = conditional_expr(state);
8740                         eat(state, TOK_RPAREN);
8741
8742                         in_param[in].constraint = constraint;
8743                         in_param[in].expr       = val;
8744                         if (peek(state) == TOK_COMMA) {
8745                                 eat(state, TOK_COMMA);
8746                                 more = 1;
8747                         }
8748                         in++;
8749                 }
8750         }
8751
8752         /* Clobber */
8753         if ((colons == 2) && (peek(state) == TOK_COLON)) {
8754                 eat(state, TOK_COLON);
8755                 colons++;
8756                 more = (peek(state) == TOK_LIT_STRING);
8757                 while(more) {
8758                         struct triple *clobber;
8759                         more = 0;
8760                         if ((clobbers + out) > MAX_LHS) {
8761                                 error(state, 0, "Maximum clobber limit exceeded.");
8762                         }
8763                         clobber = string_constant(state);
8764
8765                         clob_param[clobbers].constraint = clobber;
8766                         if (peek(state) == TOK_COMMA) {
8767                                 eat(state, TOK_COMMA);
8768                                 more = 1;
8769                         }
8770                         clobbers++;
8771                 }
8772         }
8773         eat(state, TOK_RPAREN);
8774         eat(state, TOK_SEMI);
8775
8776
8777         info = xcmalloc(sizeof(*info), "asm_info");
8778         info->str = asm_str->u.blob;
8779         free_triple(state, asm_str);
8780
8781         def = new_triple(state, OP_ASM, &void_type, clobbers + out, in);
8782         def->u.ainfo = info;
8783
8784         /* Find the register constraints */
8785         for(i = 0; i < out; i++) {
8786                 struct triple *constraint;
8787                 constraint = out_param[i].constraint;
8788                 info->tmpl.lhs[i] = arch_reg_constraint(state, 
8789                         out_param[i].expr->type, constraint->u.blob);
8790                 free_triple(state, constraint);
8791         }
8792         for(; i - out < clobbers; i++) {
8793                 struct triple *constraint;
8794                 constraint = clob_param[i - out].constraint;
8795                 info->tmpl.lhs[i] = arch_reg_clobber(state, constraint->u.blob);
8796                 free_triple(state, constraint);
8797         }
8798         for(i = 0; i < in; i++) {
8799                 struct triple *constraint;
8800                 const char *str;
8801                 constraint = in_param[i].constraint;
8802                 str = constraint->u.blob;
8803                 if (digitp(str[0]) && str[1] == '\0') {
8804                         struct reg_info cinfo;
8805                         int val;
8806                         val = digval(str[0]);
8807                         cinfo.reg = info->tmpl.lhs[val].reg;
8808                         cinfo.regcm = arch_type_to_regcm(state, in_param[i].expr->type);
8809                         cinfo.regcm &= info->tmpl.lhs[val].regcm;
8810                         if (cinfo.reg == REG_UNSET) {
8811                                 cinfo.reg = REG_VIRT0 + val;
8812                         }
8813                         if (cinfo.regcm == 0) {
8814                                 error(state, 0, "No registers for %d", val);
8815                         }
8816                         info->tmpl.lhs[val] = cinfo;
8817                         info->tmpl.rhs[i]   = cinfo;
8818                                 
8819                 } else {
8820                         info->tmpl.rhs[i] = arch_reg_constraint(state, 
8821                                 in_param[i].expr->type, str);
8822                 }
8823                 free_triple(state, constraint);
8824         }
8825
8826         /* Now build the helper expressions */
8827         for(i = 0; i < in; i++) {
8828                 RHS(def, i) = read_expr(state,in_param[i].expr);
8829         }
8830         flatten(state, first, def);
8831         for(i = 0; i < (out + clobbers); i++) {
8832                 struct type *type;
8833                 struct triple *piece;
8834                 type = (i < out)? out_param[i].expr->type : &void_type;
8835                 piece = triple(state, OP_PIECE, type, def, 0);
8836                 piece->u.cval = i;
8837                 LHS(def, i) = piece;
8838                 flatten(state, first, piece);
8839         }
8840         /* And write the helpers to their destinations */
8841         for(i = 0; i < out; i++) {
8842                 struct triple *piece;
8843                 piece = LHS(def, i);
8844                 flatten(state, first,
8845                         write_expr(state, out_param[i].expr, piece));
8846         }
8847 }
8848
8849
8850 static int isdecl(int tok)
8851 {
8852         switch(tok) {
8853         case TOK_AUTO:
8854         case TOK_REGISTER:
8855         case TOK_STATIC:
8856         case TOK_EXTERN:
8857         case TOK_TYPEDEF:
8858         case TOK_CONST:
8859         case TOK_RESTRICT:
8860         case TOK_VOLATILE:
8861         case TOK_VOID:
8862         case TOK_CHAR:
8863         case TOK_SHORT:
8864         case TOK_INT:
8865         case TOK_LONG:
8866         case TOK_FLOAT:
8867         case TOK_DOUBLE:
8868         case TOK_SIGNED:
8869         case TOK_UNSIGNED:
8870         case TOK_STRUCT:
8871         case TOK_UNION:
8872         case TOK_ENUM:
8873         case TOK_TYPE_NAME: /* typedef name */
8874                 return 1;
8875         default:
8876                 return 0;
8877         }
8878 }
8879
8880 static void compound_statement(struct compile_state *state, struct triple *first)
8881 {
8882         eat(state, TOK_LBRACE);
8883         start_scope(state);
8884
8885         /* statement-list opt */
8886         while (peek(state) != TOK_RBRACE) {
8887                 statement(state, first);
8888         }
8889         end_scope(state);
8890         eat(state, TOK_RBRACE);
8891 }
8892
8893 static void statement(struct compile_state *state, struct triple *first)
8894 {
8895         int tok;
8896         tok = peek(state);
8897         if (tok == TOK_LBRACE) {
8898                 compound_statement(state, first);
8899         }
8900         else if (tok == TOK_IF) {
8901                 if_statement(state, first); 
8902         }
8903         else if (tok == TOK_FOR) {
8904                 for_statement(state, first);
8905         }
8906         else if (tok == TOK_WHILE) {
8907                 while_statement(state, first);
8908         }
8909         else if (tok == TOK_DO) {
8910                 do_statement(state, first);
8911         }
8912         else if (tok == TOK_RETURN) {
8913                 return_statement(state, first);
8914         }
8915         else if (tok == TOK_BREAK) {
8916                 break_statement(state, first);
8917         }
8918         else if (tok == TOK_CONTINUE) {
8919                 continue_statement(state, first);
8920         }
8921         else if (tok == TOK_GOTO) {
8922                 goto_statement(state, first);
8923         }
8924         else if (tok == TOK_SWITCH) {
8925                 switch_statement(state, first);
8926         }
8927         else if (tok == TOK_ASM) {
8928                 asm_statement(state, first);
8929         }
8930         else if ((tok == TOK_IDENT) && (peek2(state) == TOK_COLON)) {
8931                 labeled_statement(state, first); 
8932         }
8933         else if (tok == TOK_CASE) {
8934                 case_statement(state, first);
8935         }
8936         else if (tok == TOK_DEFAULT) {
8937                 default_statement(state, first);
8938         }
8939         else if (isdecl(tok)) {
8940                 /* This handles C99 intermixing of statements and decls */
8941                 decl(state, first);
8942         }
8943         else {
8944                 expr_statement(state, first);
8945         }
8946 }
8947
8948 static struct type *param_decl(struct compile_state *state)
8949 {
8950         struct type *type;
8951         struct hash_entry *ident;
8952         /* Cheat so the declarator will know we are not global */
8953         start_scope(state); 
8954         ident = 0;
8955         type = decl_specifiers(state);
8956         type = declarator(state, type, &ident, 0);
8957         type->field_ident = ident;
8958         end_scope(state);
8959         return type;
8960 }
8961
8962 static struct type *param_type_list(struct compile_state *state, struct type *type)
8963 {
8964         struct type *ftype, **next;
8965         ftype = new_type(TYPE_FUNCTION | (type->type & STOR_MASK), type, param_decl(state));
8966         next = &ftype->right;
8967         while(peek(state) == TOK_COMMA) {
8968                 eat(state, TOK_COMMA);
8969                 if (peek(state) == TOK_DOTS) {
8970                         eat(state, TOK_DOTS);
8971                         error(state, 0, "variadic functions not supported");
8972                 }
8973                 else {
8974                         *next = new_type(TYPE_PRODUCT, *next, param_decl(state));
8975                         next = &((*next)->right);
8976                 }
8977         }
8978         return ftype;
8979 }
8980
8981
8982 static struct type *type_name(struct compile_state *state)
8983 {
8984         struct type *type;
8985         type = specifier_qualifier_list(state);
8986         /* abstract-declarator (may consume no tokens) */
8987         type = declarator(state, type, 0, 0);
8988         return type;
8989 }
8990
8991 static struct type *direct_declarator(
8992         struct compile_state *state, struct type *type, 
8993         struct hash_entry **ident, int need_ident)
8994 {
8995         struct type *outer;
8996         int op;
8997         outer = 0;
8998         arrays_complete(state, type);
8999         switch(peek(state)) {
9000         case TOK_IDENT:
9001                 eat(state, TOK_IDENT);
9002                 if (!ident) {
9003                         error(state, 0, "Unexpected identifier found");
9004                 }
9005                 /* The name of what we are declaring */
9006                 *ident = state->token[0].ident;
9007                 break;
9008         case TOK_LPAREN:
9009                 eat(state, TOK_LPAREN);
9010                 outer = declarator(state, type, ident, need_ident);
9011                 eat(state, TOK_RPAREN);
9012                 break;
9013         default:
9014                 if (need_ident) {
9015                         error(state, 0, "Identifier expected");
9016                 }
9017                 break;
9018         }
9019         do {
9020                 op = 1;
9021                 arrays_complete(state, type);
9022                 switch(peek(state)) {
9023                 case TOK_LPAREN:
9024                         eat(state, TOK_LPAREN);
9025                         type = param_type_list(state, type);
9026                         eat(state, TOK_RPAREN);
9027                         break;
9028                 case TOK_LBRACKET:
9029                 {
9030                         unsigned int qualifiers;
9031                         struct triple *value;
9032                         value = 0;
9033                         eat(state, TOK_LBRACKET);
9034                         if (peek(state) != TOK_RBRACKET) {
9035                                 value = constant_expr(state);
9036                                 integral(state, value);
9037                         }
9038                         eat(state, TOK_RBRACKET);
9039
9040                         qualifiers = type->type & (QUAL_MASK | STOR_MASK);
9041                         type = new_type(TYPE_ARRAY | qualifiers, type, 0);
9042                         if (value) {
9043                                 type->elements = value->u.cval;
9044                                 free_triple(state, value);
9045                         } else {
9046                                 type->elements = ELEMENT_COUNT_UNSPECIFIED;
9047                                 op = 0;
9048                         }
9049                 }
9050                         break;
9051                 default:
9052                         op = 0;
9053                         break;
9054                 }
9055         } while(op);
9056         if (outer) {
9057                 struct type *inner;
9058                 arrays_complete(state, type);
9059                 FINISHME();
9060                 for(inner = outer; inner->left; inner = inner->left)
9061                         ;
9062                 inner->left = type;
9063                 type = outer;
9064         }
9065         return type;
9066 }
9067
9068 static struct type *declarator(
9069         struct compile_state *state, struct type *type, 
9070         struct hash_entry **ident, int need_ident)
9071 {
9072         while(peek(state) == TOK_STAR) {
9073                 eat(state, TOK_STAR);
9074                 type = new_type(TYPE_POINTER | (type->type & STOR_MASK), type, 0);
9075         }
9076         type = direct_declarator(state, type, ident, need_ident);
9077         return type;
9078 }
9079
9080
9081 static struct type *typedef_name(
9082         struct compile_state *state, unsigned int specifiers)
9083 {
9084         struct hash_entry *ident;
9085         struct type *type;
9086         eat(state, TOK_TYPE_NAME);
9087         ident = state->token[0].ident;
9088         type = ident->sym_ident->type;
9089         specifiers |= type->type & QUAL_MASK;
9090         if ((specifiers & (STOR_MASK | QUAL_MASK)) != 
9091                 (type->type & (STOR_MASK | QUAL_MASK))) {
9092                 type = clone_type(specifiers, type);
9093         }
9094         return type;
9095 }
9096
9097 static struct type *enum_specifier(
9098         struct compile_state *state, unsigned int spec)
9099 {
9100         struct hash_entry *ident;
9101         ulong_t base;
9102         int tok;
9103         struct type *enum_type;
9104         enum_type = 0;
9105         ident = 0;
9106         eat(state, TOK_ENUM);
9107         tok = peek(state);
9108         if ((tok == TOK_IDENT) || (tok == TOK_ENUM_CONST) || (tok == TOK_TYPE_NAME)) {
9109                 eat(state, tok);
9110                 ident = state->token[0].ident;
9111                 
9112         }
9113         base = 0;
9114         if (!ident || (peek(state) == TOK_LBRACE)) {
9115                 struct type **next;
9116                 eat(state, TOK_LBRACE);
9117                 enum_type = new_type(TYPE_ENUM | spec, 0, 0);
9118                 enum_type->type_ident = ident;
9119                 next = &enum_type->right;
9120                 do {
9121                         struct hash_entry *eident;
9122                         struct triple *value;
9123                         struct type *entry;
9124                         eat(state, TOK_IDENT);
9125                         eident = state->token[0].ident;
9126                         if (eident->sym_ident) {
9127                                 error(state, 0, "%s already declared", 
9128                                         eident->name);
9129                         }
9130                         eident->tok = TOK_ENUM_CONST;
9131                         if (peek(state) == TOK_EQ) {
9132                                 struct triple *val;
9133                                 eat(state, TOK_EQ);
9134                                 val = constant_expr(state);
9135                                 integral(state, val);
9136                                 base = val->u.cval;
9137                         }
9138                         value = int_const(state, &int_type, base);
9139                         symbol(state, eident, &eident->sym_ident, value, &int_type);
9140                         entry = new_type(TYPE_LIST, 0, 0);
9141                         entry->field_ident = eident;
9142                         *next = entry;
9143                         next = &entry->right;
9144                         base += 1;
9145                         if (peek(state) == TOK_COMMA) {
9146                                 eat(state, TOK_COMMA);
9147                         }
9148                 } while(peek(state) != TOK_RBRACE);
9149                 eat(state, TOK_RBRACE);
9150                 if (ident) {
9151                         symbol(state, ident, &ident->sym_tag, 0, enum_type);
9152                 }
9153         }
9154         if (ident && ident->sym_tag &&
9155                 ident->sym_tag->type &&
9156                 ((ident->sym_tag->type->type & TYPE_MASK) == TYPE_ENUM)) {
9157                 enum_type = clone_type(spec, ident->sym_tag->type);
9158         }
9159         else if (ident && !enum_type) {
9160                 error(state, 0, "enum %s undeclared", ident->name);
9161         }
9162         return enum_type;
9163 }
9164
9165 static struct type *struct_declarator(
9166         struct compile_state *state, struct type *type, struct hash_entry **ident)
9167 {
9168         int tok;
9169         tok = peek(state);
9170         if (tok != TOK_COLON) {
9171                 type = declarator(state, type, ident, 1);
9172         }
9173         if ((tok == TOK_COLON) || (peek(state) == TOK_COLON)) {
9174                 struct triple *value;
9175                 eat(state, TOK_COLON);
9176                 value = constant_expr(state);
9177 #warning "FIXME implement bitfields to reduce register usage"
9178                 error(state, 0, "bitfields not yet implemented");
9179         }
9180         return type;
9181 }
9182
9183 static struct type *struct_or_union_specifier(
9184         struct compile_state *state, unsigned int spec)
9185 {
9186         struct type *struct_type;
9187         struct hash_entry *ident;
9188         unsigned int type_join;
9189         int tok;
9190         struct_type = 0;
9191         ident = 0;
9192         switch(peek(state)) {
9193         case TOK_STRUCT:
9194                 eat(state, TOK_STRUCT);
9195                 type_join = TYPE_PRODUCT;
9196                 break;
9197         case TOK_UNION:
9198                 eat(state, TOK_UNION);
9199                 type_join = TYPE_OVERLAP;
9200                 error(state, 0, "unions not yet supported\n");
9201                 break;
9202         default:
9203                 eat(state, TOK_STRUCT);
9204                 type_join = TYPE_PRODUCT;
9205                 break;
9206         }
9207         tok = peek(state);
9208         if ((tok == TOK_IDENT) || (tok == TOK_ENUM_CONST) || (tok == TOK_TYPE_NAME)) {
9209                 eat(state, tok);
9210                 ident = state->token[0].ident;
9211         }
9212         if (!ident || (peek(state) == TOK_LBRACE)) {
9213                 ulong_t elements;
9214                 struct type **next;
9215                 elements = 0;
9216                 eat(state, TOK_LBRACE);
9217                 next = &struct_type;
9218                 do {
9219                         struct type *base_type;
9220                         int done;
9221                         base_type = specifier_qualifier_list(state);
9222                         do {
9223                                 struct type *type;
9224                                 struct hash_entry *fident;
9225                                 done = 1;
9226                                 type = struct_declarator(state, base_type, &fident);
9227                                 elements++;
9228                                 if (peek(state) == TOK_COMMA) {
9229                                         done = 0;
9230                                         eat(state, TOK_COMMA);
9231                                 }
9232                                 type = clone_type(0, type);
9233                                 type->field_ident = fident;
9234                                 if (*next) {
9235                                         *next = new_type(type_join, *next, type);
9236                                         next = &((*next)->right);
9237                                 } else {
9238                                         *next = type;
9239                                 }
9240                         } while(!done);
9241                         eat(state, TOK_SEMI);
9242                 } while(peek(state) != TOK_RBRACE);
9243                 eat(state, TOK_RBRACE);
9244                 struct_type = new_type(TYPE_STRUCT | spec, struct_type, 0);
9245                 struct_type->type_ident = ident;
9246                 struct_type->elements = elements;
9247                 if (ident) {
9248                         symbol(state, ident, &ident->sym_tag, 0, struct_type);
9249                 }
9250         }
9251         if (ident && ident->sym_tag && 
9252                 ident->sym_tag->type && 
9253                 ((ident->sym_tag->type->type & TYPE_MASK) == TYPE_STRUCT)) {
9254                 struct_type = clone_type(spec, ident->sym_tag->type);
9255         }
9256         else if (ident && !struct_type) {
9257                 error(state, 0, "struct %s undeclared", ident->name);
9258         }
9259         return struct_type;
9260 }
9261
9262 static unsigned int storage_class_specifier_opt(struct compile_state *state)
9263 {
9264         unsigned int specifiers;
9265         switch(peek(state)) {
9266         case TOK_AUTO:
9267                 eat(state, TOK_AUTO);
9268                 specifiers = STOR_AUTO;
9269                 break;
9270         case TOK_REGISTER:
9271                 eat(state, TOK_REGISTER);
9272                 specifiers = STOR_REGISTER;
9273                 break;
9274         case TOK_STATIC:
9275                 eat(state, TOK_STATIC);
9276                 specifiers = STOR_STATIC;
9277                 break;
9278         case TOK_EXTERN:
9279                 eat(state, TOK_EXTERN);
9280                 specifiers = STOR_EXTERN;
9281                 break;
9282         case TOK_TYPEDEF:
9283                 eat(state, TOK_TYPEDEF);
9284                 specifiers = STOR_TYPEDEF;
9285                 break;
9286         default:
9287                 if (state->scope_depth <= GLOBAL_SCOPE_DEPTH) {
9288                         specifiers = STOR_LOCAL;
9289                 }
9290                 else {
9291                         specifiers = STOR_AUTO;
9292                 }
9293         }
9294         return specifiers;
9295 }
9296
9297 static unsigned int function_specifier_opt(struct compile_state *state)
9298 {
9299         /* Ignore the inline keyword */
9300         unsigned int specifiers;
9301         specifiers = 0;
9302         switch(peek(state)) {
9303         case TOK_INLINE:
9304                 eat(state, TOK_INLINE);
9305                 specifiers = STOR_INLINE;
9306         }
9307         return specifiers;
9308 }
9309
9310 static unsigned int type_qualifiers(struct compile_state *state)
9311 {
9312         unsigned int specifiers;
9313         int done;
9314         done = 0;
9315         specifiers = QUAL_NONE;
9316         do {
9317                 switch(peek(state)) {
9318                 case TOK_CONST:
9319                         eat(state, TOK_CONST);
9320                         specifiers = QUAL_CONST;
9321                         break;
9322                 case TOK_VOLATILE:
9323                         eat(state, TOK_VOLATILE);
9324                         specifiers = QUAL_VOLATILE;
9325                         break;
9326                 case TOK_RESTRICT:
9327                         eat(state, TOK_RESTRICT);
9328                         specifiers = QUAL_RESTRICT;
9329                         break;
9330                 default:
9331                         done = 1;
9332                         break;
9333                 }
9334         } while(!done);
9335         return specifiers;
9336 }
9337
9338 static struct type *type_specifier(
9339         struct compile_state *state, unsigned int spec)
9340 {
9341         struct type *type;
9342         type = 0;
9343         switch(peek(state)) {
9344         case TOK_VOID:
9345                 eat(state, TOK_VOID);
9346                 type = new_type(TYPE_VOID | spec, 0, 0);
9347                 break;
9348         case TOK_CHAR:
9349                 eat(state, TOK_CHAR);
9350                 type = new_type(TYPE_CHAR | spec, 0, 0);
9351                 break;
9352         case TOK_SHORT:
9353                 eat(state, TOK_SHORT);
9354                 if (peek(state) == TOK_INT) {
9355                         eat(state, TOK_INT);
9356                 }
9357                 type = new_type(TYPE_SHORT | spec, 0, 0);
9358                 break;
9359         case TOK_INT:
9360                 eat(state, TOK_INT);
9361                 type = new_type(TYPE_INT | spec, 0, 0);
9362                 break;
9363         case TOK_LONG:
9364                 eat(state, TOK_LONG);
9365                 switch(peek(state)) {
9366                 case TOK_LONG:
9367                         eat(state, TOK_LONG);
9368                         error(state, 0, "long long not supported");
9369                         break;
9370                 case TOK_DOUBLE:
9371                         eat(state, TOK_DOUBLE);
9372                         error(state, 0, "long double not supported");
9373                         break;
9374                 case TOK_INT:
9375                         eat(state, TOK_INT);
9376                         type = new_type(TYPE_LONG | spec, 0, 0);
9377                         break;
9378                 default:
9379                         type = new_type(TYPE_LONG | spec, 0, 0);
9380                         break;
9381                 }
9382                 break;
9383         case TOK_FLOAT:
9384                 eat(state, TOK_FLOAT);
9385                 error(state, 0, "type float not supported");
9386                 break;
9387         case TOK_DOUBLE:
9388                 eat(state, TOK_DOUBLE);
9389                 error(state, 0, "type double not supported");
9390                 break;
9391         case TOK_SIGNED:
9392                 eat(state, TOK_SIGNED);
9393                 switch(peek(state)) {
9394                 case TOK_LONG:
9395                         eat(state, TOK_LONG);
9396                         switch(peek(state)) {
9397                         case TOK_LONG:
9398                                 eat(state, TOK_LONG);
9399                                 error(state, 0, "type long long not supported");
9400                                 break;
9401                         case TOK_INT:
9402                                 eat(state, TOK_INT);
9403                                 type = new_type(TYPE_LONG | spec, 0, 0);
9404                                 break;
9405                         default:
9406                                 type = new_type(TYPE_LONG | spec, 0, 0);
9407                                 break;
9408                         }
9409                         break;
9410                 case TOK_INT:
9411                         eat(state, TOK_INT);
9412                         type = new_type(TYPE_INT | spec, 0, 0);
9413                         break;
9414                 case TOK_SHORT:
9415                         eat(state, TOK_SHORT);
9416                         type = new_type(TYPE_SHORT | spec, 0, 0);
9417                         break;
9418                 case TOK_CHAR:
9419                         eat(state, TOK_CHAR);
9420                         type = new_type(TYPE_CHAR | spec, 0, 0);
9421                         break;
9422                 default:
9423                         type = new_type(TYPE_INT | spec, 0, 0);
9424                         break;
9425                 }
9426                 break;
9427         case TOK_UNSIGNED:
9428                 eat(state, TOK_UNSIGNED);
9429                 switch(peek(state)) {
9430                 case TOK_LONG:
9431                         eat(state, TOK_LONG);
9432                         switch(peek(state)) {
9433                         case TOK_LONG:
9434                                 eat(state, TOK_LONG);
9435                                 error(state, 0, "unsigned long long not supported");
9436                                 break;
9437                         case TOK_INT:
9438                                 eat(state, TOK_INT);
9439                                 type = new_type(TYPE_ULONG | spec, 0, 0);
9440                                 break;
9441                         default:
9442                                 type = new_type(TYPE_ULONG | spec, 0, 0);
9443                                 break;
9444                         }
9445                         break;
9446                 case TOK_INT:
9447                         eat(state, TOK_INT);
9448                         type = new_type(TYPE_UINT | spec, 0, 0);
9449                         break;
9450                 case TOK_SHORT:
9451                         eat(state, TOK_SHORT);
9452                         type = new_type(TYPE_USHORT | spec, 0, 0);
9453                         break;
9454                 case TOK_CHAR:
9455                         eat(state, TOK_CHAR);
9456                         type = new_type(TYPE_UCHAR | spec, 0, 0);
9457                         break;
9458                 default:
9459                         type = new_type(TYPE_UINT | spec, 0, 0);
9460                         break;
9461                 }
9462                 break;
9463                 /* struct or union specifier */
9464         case TOK_STRUCT:
9465         case TOK_UNION:
9466                 type = struct_or_union_specifier(state, spec);
9467                 break;
9468                 /* enum-spefifier */
9469         case TOK_ENUM:
9470                 type = enum_specifier(state, spec);
9471                 break;
9472                 /* typedef name */
9473         case TOK_TYPE_NAME:
9474                 type = typedef_name(state, spec);
9475                 break;
9476         default:
9477                 error(state, 0, "bad type specifier %s", 
9478                         tokens[peek(state)]);
9479                 break;
9480         }
9481         return type;
9482 }
9483
9484 static int istype(int tok)
9485 {
9486         switch(tok) {
9487         case TOK_CONST:
9488         case TOK_RESTRICT:
9489         case TOK_VOLATILE:
9490         case TOK_VOID:
9491         case TOK_CHAR:
9492         case TOK_SHORT:
9493         case TOK_INT:
9494         case TOK_LONG:
9495         case TOK_FLOAT:
9496         case TOK_DOUBLE:
9497         case TOK_SIGNED:
9498         case TOK_UNSIGNED:
9499         case TOK_STRUCT:
9500         case TOK_UNION:
9501         case TOK_ENUM:
9502         case TOK_TYPE_NAME:
9503                 return 1;
9504         default:
9505                 return 0;
9506         }
9507 }
9508
9509
9510 static struct type *specifier_qualifier_list(struct compile_state *state)
9511 {
9512         struct type *type;
9513         unsigned int specifiers = 0;
9514
9515         /* type qualifiers */
9516         specifiers |= type_qualifiers(state);
9517
9518         /* type specifier */
9519         type = type_specifier(state, specifiers);
9520
9521         return type;
9522 }
9523
9524 static int isdecl_specifier(int tok)
9525 {
9526         switch(tok) {
9527                 /* storage class specifier */
9528         case TOK_AUTO:
9529         case TOK_REGISTER:
9530         case TOK_STATIC:
9531         case TOK_EXTERN:
9532         case TOK_TYPEDEF:
9533                 /* type qualifier */
9534         case TOK_CONST:
9535         case TOK_RESTRICT:
9536         case TOK_VOLATILE:
9537                 /* type specifiers */
9538         case TOK_VOID:
9539         case TOK_CHAR:
9540         case TOK_SHORT:
9541         case TOK_INT:
9542         case TOK_LONG:
9543         case TOK_FLOAT:
9544         case TOK_DOUBLE:
9545         case TOK_SIGNED:
9546         case TOK_UNSIGNED:
9547                 /* struct or union specifier */
9548         case TOK_STRUCT:
9549         case TOK_UNION:
9550                 /* enum-spefifier */
9551         case TOK_ENUM:
9552                 /* typedef name */
9553         case TOK_TYPE_NAME:
9554                 /* function specifiers */
9555         case TOK_INLINE:
9556                 return 1;
9557         default:
9558                 return 0;
9559         }
9560 }
9561
9562 static struct type *decl_specifiers(struct compile_state *state)
9563 {
9564         struct type *type;
9565         unsigned int specifiers;
9566         /* I am overly restrictive in the arragement of specifiers supported.
9567          * C is overly flexible in this department it makes interpreting
9568          * the parse tree difficult.
9569          */
9570         specifiers = 0;
9571
9572         /* storage class specifier */
9573         specifiers |= storage_class_specifier_opt(state);
9574
9575         /* function-specifier */
9576         specifiers |= function_specifier_opt(state);
9577
9578         /* type qualifier */
9579         specifiers |= type_qualifiers(state);
9580
9581         /* type specifier */
9582         type = type_specifier(state, specifiers);
9583         return type;
9584 }
9585
9586 struct field_info {
9587         struct type *type;
9588         size_t offset;
9589 };
9590
9591 static struct field_info designator(struct compile_state *state, struct type *type)
9592 {
9593         int tok;
9594         struct field_info info;
9595         info.offset = ~0U;
9596         info.type = 0;
9597         do {
9598                 switch(peek(state)) {
9599                 case TOK_LBRACKET:
9600                 {
9601                         struct triple *value;
9602                         if ((type->type & TYPE_MASK) != TYPE_ARRAY) {
9603                                 error(state, 0, "Array designator not in array initializer");
9604                         }
9605                         eat(state, TOK_LBRACKET);
9606                         value = constant_expr(state);
9607                         eat(state, TOK_RBRACKET);
9608
9609                         info.type = type->left;
9610                         info.offset = value->u.cval * size_of(state, info.type);
9611                         break;
9612                 }
9613                 case TOK_DOT:
9614                 {
9615                         struct hash_entry *field;
9616                         if ((type->type & TYPE_MASK) != TYPE_STRUCT) {
9617                                 error(state, 0, "Struct designator not in struct initializer");
9618                         }
9619                         eat(state, TOK_DOT);
9620                         eat(state, TOK_IDENT);
9621                         field = state->token[0].ident;
9622                         info.offset = field_offset(state, type, field);
9623                         info.type   = field_type(state, type, field);
9624                         break;
9625                 }
9626                 default:
9627                         error(state, 0, "Invalid designator");
9628                 }
9629                 tok = peek(state);
9630         } while((tok == TOK_LBRACKET) || (tok == TOK_DOT));
9631         eat(state, TOK_EQ);
9632         return info;
9633 }
9634
9635 static struct triple *initializer(
9636         struct compile_state *state, struct type *type)
9637 {
9638         struct triple *result;
9639 #warning "FIXME more consistent initializer handling (where should eval_const_expr go?"
9640         if (peek(state) != TOK_LBRACE) {
9641                 result = assignment_expr(state);
9642                 if (((type->type & TYPE_MASK) == TYPE_ARRAY) &&
9643                         (type->elements == ELEMENT_COUNT_UNSPECIFIED) &&
9644                         ((result->type->type & TYPE_MASK) == TYPE_ARRAY) &&
9645                         (result->type->elements != ELEMENT_COUNT_UNSPECIFIED) &&
9646                         (equiv_types(type->left, result->type->left))) {
9647                         type->elements = result->type->elements;
9648                 }
9649                 if (is_stable(state, result) && 
9650                         ((result->type->type & TYPE_MASK) == TYPE_ARRAY) &&
9651                         (type->type & TYPE_MASK) != TYPE_ARRAY)
9652                 {
9653                         result = array_to_pointer(state, result);
9654                 }
9655                 if (!is_init_compatible(state, type, result->type)) {
9656                         error(state, 0, "Incompatible types in initializer");
9657                 }
9658                 if (!equiv_types(type, result->type)) {
9659                         result = mk_cast_expr(state, type, result);
9660                 }
9661         }
9662         else {
9663                 int comma;
9664                 size_t max_offset;
9665                 struct field_info info;
9666                 void *buf;
9667                 if (((type->type & TYPE_MASK) != TYPE_ARRAY) &&
9668                         ((type->type & TYPE_MASK) != TYPE_STRUCT)) {
9669                         internal_error(state, 0, "unknown initializer type");
9670                 }
9671                 info.offset = 0;
9672                 info.type = type->left;
9673                 if ((type->type & TYPE_MASK) == TYPE_STRUCT) {
9674                         info.type = next_field(state, type, 0);
9675                 }
9676                 if (type->elements == ELEMENT_COUNT_UNSPECIFIED) {
9677                         max_offset = 0;
9678                 } else {
9679                         max_offset = size_of(state, type);
9680                 }
9681                 buf = xcmalloc(max_offset, "initializer");
9682                 eat(state, TOK_LBRACE);
9683                 do {
9684                         struct triple *value;
9685                         struct type *value_type;
9686                         size_t value_size;
9687                         void *dest;
9688                         int tok;
9689                         comma = 0;
9690                         tok = peek(state);
9691                         if ((tok == TOK_LBRACKET) || (tok == TOK_DOT)) {
9692                                 info = designator(state, type);
9693                         }
9694                         if ((type->elements != ELEMENT_COUNT_UNSPECIFIED) &&
9695                                 (info.offset >= max_offset)) {
9696                                 error(state, 0, "element beyond bounds");
9697                         }
9698                         value_type = info.type;
9699                         value = eval_const_expr(state, initializer(state, value_type));
9700                         value_size = size_of(state, value_type);
9701                         if (((type->type & TYPE_MASK) == TYPE_ARRAY) &&
9702                                 (type->elements == ELEMENT_COUNT_UNSPECIFIED) &&
9703                                 (max_offset <= info.offset)) {
9704                                 void *old_buf;
9705                                 size_t old_size;
9706                                 old_buf = buf;
9707                                 old_size = max_offset;
9708                                 max_offset = info.offset + value_size;
9709                                 buf = xmalloc(max_offset, "initializer");
9710                                 memcpy(buf, old_buf, old_size);
9711                                 xfree(old_buf);
9712                         }
9713                         dest = ((char *)buf) + info.offset;
9714                         if (value->op == OP_BLOBCONST) {
9715                                 memcpy(dest, value->u.blob, value_size);
9716                         }
9717                         else if ((value->op == OP_INTCONST) && (value_size == 1)) {
9718                                 *((uint8_t *)dest) = value->u.cval & 0xff;
9719                         }
9720                         else if ((value->op == OP_INTCONST) && (value_size == 2)) {
9721                                 *((uint16_t *)dest) = value->u.cval & 0xffff;
9722                         }
9723                         else if ((value->op == OP_INTCONST) && (value_size == 4)) {
9724                                 *((uint32_t *)dest) = value->u.cval & 0xffffffff;
9725                         }
9726                         else {
9727                                 internal_error(state, 0, "unhandled constant initializer");
9728                         }
9729                         free_triple(state, value);
9730                         if (peek(state) == TOK_COMMA) {
9731                                 eat(state, TOK_COMMA);
9732                                 comma = 1;
9733                         }
9734                         info.offset += value_size;
9735                         if ((type->type & TYPE_MASK) == TYPE_STRUCT) {
9736                                 info.type = next_field(state, type, info.type);
9737                                 info.offset = field_offset(state, type, 
9738                                         info.type->field_ident);
9739                         }
9740                 } while(comma && (peek(state) != TOK_RBRACE));
9741                 if ((type->elements == ELEMENT_COUNT_UNSPECIFIED) &&
9742                         ((type->type & TYPE_MASK) == TYPE_ARRAY)) {
9743                         type->elements = max_offset / size_of(state, type->left);
9744                 }
9745                 eat(state, TOK_RBRACE);
9746                 result = triple(state, OP_BLOBCONST, type, 0, 0);
9747                 result->u.blob = buf;
9748         }
9749         return result;
9750 }
9751
9752 static void resolve_branches(struct compile_state *state)
9753 {
9754         /* Make a second pass and finish anything outstanding
9755          * with respect to branches.  The only outstanding item
9756          * is to see if there are goto to labels that have not
9757          * been defined and to error about them.
9758          */
9759         int i;
9760         for(i = 0; i < HASH_TABLE_SIZE; i++) {
9761                 struct hash_entry *entry;
9762                 for(entry = state->hash_table[i]; entry; entry = entry->next) {
9763                         struct triple *ins;
9764                         if (!entry->sym_label) {
9765                                 continue;
9766                         }
9767                         ins = entry->sym_label->def;
9768                         if (!(ins->id & TRIPLE_FLAG_FLATTENED)) {
9769                                 error(state, ins, "label `%s' used but not defined",
9770                                         entry->name);
9771                         }
9772                 }
9773         }
9774 }
9775
9776 static struct triple *function_definition(
9777         struct compile_state *state, struct type *type)
9778 {
9779         struct triple *def, *tmp, *first, *end, *retvar, *ret;
9780         struct hash_entry *ident;
9781         struct type *param;
9782         int i;
9783         if ((type->type &TYPE_MASK) != TYPE_FUNCTION) {
9784                 error(state, 0, "Invalid function header");
9785         }
9786
9787         /* Verify the function type */
9788         if (((type->right->type & TYPE_MASK) != TYPE_VOID)  &&
9789                 ((type->right->type & TYPE_MASK) != TYPE_PRODUCT) &&
9790                 (type->right->field_ident == 0)) {
9791                 error(state, 0, "Invalid function parameters");
9792         }
9793         param = type->right;
9794         i = 0;
9795         while((param->type & TYPE_MASK) == TYPE_PRODUCT) {
9796                 i++;
9797                 if (!param->left->field_ident) {
9798                         error(state, 0, "No identifier for parameter %d\n", i);
9799                 }
9800                 param = param->right;
9801         }
9802         i++;
9803         if (((param->type & TYPE_MASK) != TYPE_VOID) && !param->field_ident) {
9804                 error(state, 0, "No identifier for paramter %d\n", i);
9805         }
9806         
9807         /* Get a list of statements for this function. */
9808         def = triple(state, OP_LIST, type, 0, 0);
9809
9810         /* Start a new scope for the passed parameters */
9811         start_scope(state);
9812
9813         /* Put a label at the very start of a function */
9814         first = label(state);
9815         RHS(def, 0) = first;
9816
9817         /* Put a label at the very end of a function */
9818         end = label(state);
9819         flatten(state, first, end);
9820         /* Remember where return goes */
9821         ident = state->i_return;
9822         symbol(state, ident, &ident->sym_ident, end, end->type);
9823
9824         /* Allocate a variable for the return address */
9825         retvar = variable(state, &void_ptr_type);
9826         retvar = flatten(state, end, retvar);
9827
9828         /* Add in the return instruction */
9829         ret = triple(state, OP_RET, &void_type, read_expr(state, retvar), 0);
9830         ret = flatten(state, first, ret);
9831
9832         /* Walk through the parameters and create symbol table entries
9833          * for them.
9834          */
9835         param = type->right;
9836         while((param->type & TYPE_MASK) == TYPE_PRODUCT) {
9837                 ident = param->left->field_ident;
9838                 tmp = variable(state, param->left);
9839                 symbol(state, ident, &ident->sym_ident, tmp, tmp->type);
9840                 flatten(state, end, tmp);
9841                 param = param->right;
9842         }
9843         if ((param->type & TYPE_MASK) != TYPE_VOID) {
9844                 /* And don't forget the last parameter */
9845                 ident = param->field_ident;
9846                 tmp = variable(state, param);
9847                 symbol(state, ident, &ident->sym_ident, tmp, tmp->type);
9848                 flatten(state, end, tmp);
9849         }
9850         /* Add a variable for the return value */
9851         MISC(def, 0) = 0;
9852         if ((type->left->type & TYPE_MASK) != TYPE_VOID) {
9853                 /* Remove all type qualifiers from the return type */
9854                 tmp = variable(state, clone_type(0, type->left));
9855                 flatten(state, end, tmp);
9856                 /* Remember where the return value is */
9857                 MISC(def, 0) = tmp;
9858         }
9859
9860         /* Remember which function I am compiling.
9861          * Also assume the last defined function is the main function.
9862          */
9863         state->main_function = def;
9864
9865         /* Now get the actual function definition */
9866         compound_statement(state, end);
9867
9868         /* Finish anything unfinished with branches */
9869         resolve_branches(state);
9870
9871         /* Remove the parameter scope */
9872         end_scope(state);
9873
9874
9875         /* Remember I have defined a function */
9876         if (!state->functions) {
9877                 state->functions = def;
9878         } else {
9879                 insert_triple(state, state->functions, def);
9880         }
9881         if (state->compiler->debug & DEBUG_INLINE) {
9882                 fprintf(stdout, "\n");
9883                 loc(stdout, state, 0);
9884                 fprintf(stdout, "\n__________ %s _________\n", __FUNCTION__);
9885                 display_func(stdout, def);
9886                 fprintf(stdout, "__________ %s _________ done\n\n", __FUNCTION__);
9887         }
9888
9889         return def;
9890 }
9891
9892 static struct triple *do_decl(struct compile_state *state, 
9893         struct type *type, struct hash_entry *ident)
9894 {
9895         struct triple *def;
9896         def = 0;
9897         /* Clean up the storage types used */
9898         switch (type->type & STOR_MASK) {
9899         case STOR_AUTO:
9900         case STOR_STATIC:
9901                 /* These are the good types I am aiming for */
9902                 break;
9903         case STOR_REGISTER:
9904                 type->type &= ~STOR_MASK;
9905                 type->type |= STOR_AUTO;
9906                 break;
9907         case STOR_LOCAL:
9908         case STOR_EXTERN:
9909                 type->type &= ~STOR_MASK;
9910                 type->type |= STOR_STATIC;
9911                 break;
9912         case STOR_TYPEDEF:
9913                 if (!ident) {
9914                         error(state, 0, "typedef without name");
9915                 }
9916                 symbol(state, ident, &ident->sym_ident, 0, type);
9917                 ident->tok = TOK_TYPE_NAME;
9918                 return 0;
9919                 break;
9920         default:
9921                 internal_error(state, 0, "Undefined storage class");
9922         }
9923         if ((type->type & TYPE_MASK) == TYPE_FUNCTION) {
9924                 error(state, 0, "Function prototypes not supported");
9925         }
9926         if (ident && 
9927                 ((type->type & STOR_MASK) == STOR_STATIC) &&
9928                 ((type->type & QUAL_CONST) == 0)) {
9929                 error(state, 0, "non const static variables not supported");
9930         }
9931         if (ident) {
9932                 def = variable(state, type);
9933                 symbol(state, ident, &ident->sym_ident, def, type);
9934         }
9935         return def;
9936 }
9937
9938 static void decl(struct compile_state *state, struct triple *first)
9939 {
9940         struct type *base_type, *type;
9941         struct hash_entry *ident;
9942         struct triple *def;
9943         int global;
9944         global = (state->scope_depth <= GLOBAL_SCOPE_DEPTH);
9945         base_type = decl_specifiers(state);
9946         ident = 0;
9947         type = declarator(state, base_type, &ident, 0);
9948         if (global && ident && (peek(state) == TOK_LBRACE)) {
9949                 /* function */
9950                 type->type_ident = ident;
9951                 state->function = ident->name;
9952                 def = function_definition(state, type);
9953                 symbol(state, ident, &ident->sym_ident, def, type);
9954                 state->function = 0;
9955         }
9956         else {
9957                 int done;
9958                 flatten(state, first, do_decl(state, type, ident));
9959                 /* type or variable definition */
9960                 do {
9961                         done = 1;
9962                         if (peek(state) == TOK_EQ) {
9963                                 if (!ident) {
9964                                         error(state, 0, "cannot assign to a type");
9965                                 }
9966                                 eat(state, TOK_EQ);
9967                                 flatten(state, first,
9968                                         init_expr(state, 
9969                                                 ident->sym_ident->def, 
9970                                                 initializer(state, type)));
9971                         }
9972                         arrays_complete(state, type);
9973                         if (peek(state) == TOK_COMMA) {
9974                                 eat(state, TOK_COMMA);
9975                                 ident = 0;
9976                                 type = declarator(state, base_type, &ident, 0);
9977                                 flatten(state, first, do_decl(state, type, ident));
9978                                 done = 0;
9979                         }
9980                 } while(!done);
9981                 eat(state, TOK_SEMI);
9982         }
9983 }
9984
9985 static void decls(struct compile_state *state)
9986 {
9987         struct triple *list;
9988         int tok;
9989         list = label(state);
9990         while(1) {
9991                 tok = peek(state);
9992                 if (tok == TOK_EOF) {
9993                         return;
9994                 }
9995                 if (tok == TOK_SPACE) {
9996                         eat(state, TOK_SPACE);
9997                 }
9998                 decl(state, list);
9999                 if (list->next != list) {
10000                         error(state, 0, "global variables not supported");
10001                 }
10002         }
10003 }
10004
10005 /* 
10006  * Function inlining
10007  */
10008
10009 static struct triple *call(struct compile_state *state,
10010         struct triple *retvar, struct triple *ret_addr, 
10011         struct triple *targ, struct triple *ret)
10012 {
10013         struct triple *call;
10014
10015         if (!retvar || !is_lvalue(state, retvar)) {
10016                 internal_error(state, 0, "writing to a non lvalue?");
10017         }
10018         write_compatible(state, retvar->type, &void_ptr_type);
10019
10020         call = new_triple(state, OP_CALL, &void_type, 1, 0);
10021         TARG(call, 0) = targ;
10022         MISC(call, 0) = ret;
10023         if (!targ || (targ->op != OP_LABEL)) {
10024                 internal_error(state, 0, "call not to a label");
10025         }
10026         if (!ret || (ret->op != OP_RET)) {
10027                 internal_error(state, 0, "call not matched with return");
10028         }
10029         return call;
10030 }
10031
10032 static void mark_live_functions(struct compile_state *state, struct triple *first)
10033 {
10034         struct triple *ptr;
10035         ptr = first;
10036         do {
10037                 if (ptr->op == OP_FCALL) {
10038                         struct triple *func;
10039                         func = MISC(ptr, 0);
10040                         if (func->u.cval++ == 0) {
10041                                 mark_live_functions(state, RHS(func, 0));
10042                         }
10043                 }
10044                 ptr = ptr->next;
10045         } while(ptr != first);
10046 }
10047
10048 static void walk_functions(struct compile_state *state,
10049         void (*cb)(struct compile_state *state, struct triple *func, void *arg),
10050         void *arg)
10051 {
10052         struct triple *func, *first;
10053         func = first = state->functions;
10054         do {
10055                 cb(state, func, arg);
10056                 func = func->next;
10057         } while(func != first);
10058 }
10059
10060
10061 static int local_triple(struct compile_state *state, 
10062         struct triple *func, struct triple *ins)
10063 {
10064         int local = (ins->id & TRIPLE_FLAG_LOCAL);
10065 #if 0
10066         if (!local) {
10067                 fprintf(stderr, "global: ");
10068                 display_triple(stderr, ins);
10069         }
10070 #endif
10071         return local;
10072 }
10073
10074 struct triple *copy_func(struct compile_state *state, struct triple *ofunc, 
10075         struct occurance *base_occurance)
10076 {
10077         struct triple *nfunc;
10078         struct triple *nfirst, *ofirst;
10079         struct triple *new, *old;
10080
10081         if (state->compiler->debug & DEBUG_INLINE) {
10082                 fprintf(stdout, "\n");
10083                 loc(stdout, state, 0);
10084                 fprintf(stdout, "\n__________ %s _________\n", __FUNCTION__);
10085                 display_func(stdout, ofunc);
10086                 fprintf(stdout, "__________ %s _________ done\n\n", __FUNCTION__);
10087         }
10088
10089         /* Make a new copy of the old function */
10090         nfunc = triple(state, OP_LIST, ofunc->type, 0, 0);
10091         nfirst = 0;
10092         ofirst = old = RHS(ofunc, 0);
10093         do {
10094                 struct triple *new;
10095                 struct occurance *occurance;
10096                 int old_lhs, old_rhs;
10097                 old_lhs = TRIPLE_LHS(old->sizes);
10098                 old_rhs = TRIPLE_RHS(old->sizes);
10099                 occurance = inline_occurance(state, base_occurance, old->occurance);
10100                 if (ofunc->u.cval && (old->op == OP_FCALL)) {
10101                         MISC(old, 0)->u.cval += 1;
10102                 }
10103                 new = alloc_triple(state, old->op, old->type, old_lhs, old_rhs,
10104                         occurance);
10105                 if (!triple_stores_block(state, new)) {
10106                         memcpy(&new->u, &old->u, sizeof(new->u));
10107                 }
10108                 if (!nfirst) {
10109                         RHS(nfunc, 0) = nfirst = new;
10110                 }
10111                 else {
10112                         insert_triple(state, nfirst, new);
10113                 }
10114                 new->id |= TRIPLE_FLAG_FLATTENED;
10115                 
10116                 /* During the copy remember new as user of old */
10117                 use_triple(old, new);
10118
10119                 /* Populate the return type if present */
10120                 if (old == MISC(ofunc, 0)) {
10121                         MISC(nfunc, 0) = new;
10122                 }
10123                 /* Remember which instructions are local */
10124                 old->id |= TRIPLE_FLAG_LOCAL;
10125                 old = old->next;
10126         } while(old != ofirst);
10127
10128         /* Make a second pass to fix up any unresolved references */
10129         old = ofirst;
10130         new = nfirst;
10131         do {
10132                 struct triple **oexpr, **nexpr;
10133                 int count, i;
10134                 /* Lookup where the copy is, to join pointers */
10135                 count = TRIPLE_SIZE(old->sizes);
10136                 for(i = 0; i < count; i++) {
10137                         oexpr = &old->param[i];
10138                         nexpr = &new->param[i];
10139                         if (*oexpr && !*nexpr) {
10140                                 if (!local_triple(state, ofunc, *oexpr)) {
10141                                         *nexpr = *oexpr;
10142                                 }
10143                                 else if ((*oexpr)->use) {
10144                                         *nexpr = (*oexpr)->use->member;
10145                                 }
10146                                 if (*nexpr == old) {
10147                                         internal_error(state, 0, "new == old?");
10148                                 }
10149                                 use_triple(*nexpr, new);
10150                         }
10151                         if (!*nexpr && *oexpr) {
10152                                 internal_error(state, 0, "Could not copy %d\n", i);
10153                         }
10154                 }
10155                 old = old->next;
10156                 new = new->next;
10157         } while((old != ofirst) && (new != nfirst));
10158         
10159         /* Make a third pass to cleanup the extra useses */
10160         old = ofirst;
10161         new = nfirst;
10162         do {
10163                 unuse_triple(old, new);
10164                 /* Forget which instructions are local */
10165                 old->id &= ~TRIPLE_FLAG_LOCAL;
10166                 old = old->next;
10167                 new = new->next;
10168         } while ((old != ofirst) && (new != nfirst));
10169         return nfunc;
10170 }
10171
10172 static struct triple *flatten_inline_call(
10173         struct compile_state *state, struct triple *first, struct triple *ptr)
10174 {
10175         /* Inline the function call */
10176         struct type *ptype;
10177         struct triple *ofunc, *nfunc, *nfirst, *param, *result;
10178         struct triple *end, *nend;
10179         int pvals, i;
10180
10181         /* Find the triples */
10182         ofunc = MISC(ptr, 0);
10183         if (ofunc->op != OP_LIST) {
10184                 internal_error(state, 0, "improper function");
10185         }
10186         nfunc = copy_func(state, ofunc, ptr->occurance);
10187         nfirst = RHS(nfunc, 0)->next->next;
10188         /* Prepend the parameter reading into the new function list */
10189         ptype = nfunc->type->right;
10190         param = RHS(nfunc, 0)->next->next;
10191         pvals = TRIPLE_RHS(ptr->sizes);
10192         for(i = 0; i < pvals; i++) {
10193                 struct type *atype;
10194                 struct triple *arg;
10195                 atype = ptype;
10196                 if ((ptype->type & TYPE_MASK) == TYPE_PRODUCT) {
10197                         atype = ptype->left;
10198                 }
10199                 while((param->type->type & TYPE_MASK) != (atype->type & TYPE_MASK)) {
10200                         param = param->next;
10201                 }
10202                 arg = RHS(ptr, i);
10203                 flatten(state, nfirst, write_expr(state, param, arg));
10204                 ptype = ptype->right;
10205                 param = param->next;
10206         }
10207         result = 0;
10208         if ((nfunc->type->left->type & TYPE_MASK) != TYPE_VOID) {
10209                 result = read_expr(state, MISC(nfunc,0));
10210         }
10211         if (state->compiler->debug & DEBUG_INLINE) {
10212                 fprintf(stdout, "\n");
10213                 loc(stdout, state, 0);
10214                 fprintf(stdout, "\n__________ %s _________\n", __FUNCTION__);
10215                 display_func(stdout, nfunc);
10216                 fprintf(stdout, "__________ %s _________ done\n\n", __FUNCTION__);
10217         }
10218
10219         /* Get rid of the extra triples */
10220         nfirst = RHS(nfunc, 0)->next->next;
10221         release_triple(state, RHS(nfunc, 0)->prev->prev);
10222         release_triple(state, RHS(nfunc, 0)->prev);
10223         release_triple(state, RHS(nfunc, 0)->next);
10224         free_triple(state, RHS(nfunc, 0));
10225         RHS(nfunc, 0) = 0;
10226         free_triple(state, nfunc);
10227
10228         /* Append the new function list onto the return list */
10229         end = first->prev;
10230         nend = nfirst->prev;
10231         end->next    = nfirst;
10232         nfirst->prev = end;
10233         nend->next   = first;
10234         first->prev  = nend;
10235
10236         return result;
10237 }
10238
10239 static struct triple *flatten_function_call(
10240         struct compile_state *state, struct triple *first, struct triple *ptr)
10241 {
10242         /* Generate an ordinary function call */
10243         struct triple *func, *func_first, *func_last, *retvar;
10244         struct type *ptype;
10245         struct triple *param;
10246         struct triple *jmp;
10247         struct triple *ret_addr, *ret_loc, *ret_set;
10248         struct triple *result;
10249         int pvals, i;
10250
10251         FINISHME();
10252         /* Find the triples */
10253         func = MISC(ptr, 0);
10254         func_first = RHS(func, 0);
10255         retvar = func_first->next;
10256         func_last  = func_first->prev;
10257
10258         /* Generate some needed triples */
10259         ret_loc = label(state);
10260         ret_addr = triple(state, OP_ADDRCONST, &void_ptr_type, ret_loc, 0);
10261
10262         /* Pass the parameters to the new function */
10263         ptype = func->type->right;
10264         param = func_first->next->next;
10265         pvals = TRIPLE_RHS(ptr->sizes);
10266         for(i = 0; i < pvals; i++) {
10267                 struct type *atype;
10268                 struct triple *arg;
10269                 atype = ptype;
10270                 if ((ptype->type & TYPE_MASK) == TYPE_PRODUCT) {
10271                         atype = ptype->left;
10272                 }
10273                 while((param->type->type & TYPE_MASK) != (atype->type & TYPE_MASK)) {
10274                         param = param->next;
10275                 }
10276                 arg = RHS(ptr, i);
10277                 flatten(state, first, write_expr(state, param, arg));
10278                 ptype = ptype->right;
10279                 param = param->next;
10280         }
10281        
10282         /* Thread the triples together */
10283         ret_loc       = flatten(state, first, ret_loc);
10284         ret_addr      = flatten(state, ret_loc, ret_addr);
10285         ret_set       = flatten(state, ret_loc, write_expr(state, retvar, ret_addr));
10286         jmp           = flatten(state, ret_loc, 
10287                 call(state, retvar, ret_addr, func_first, func_last));
10288
10289         /* Find the result */
10290         result = 0;
10291         if ((func->type->left->type & TYPE_MASK) != TYPE_VOID) {
10292                 result = read_expr(state, MISC(func, 0));
10293         }
10294
10295         if (state->compiler->debug & DEBUG_INLINE) {
10296                 fprintf(stdout, "\n");
10297                 loc(stdout, state, 0);
10298                 fprintf(stdout, "\n__________ %s _________\n", __FUNCTION__);
10299                 display_func(stdout, func);
10300                 fprintf(stdout, "__________ %s _________ done\n\n", __FUNCTION__);
10301         }
10302
10303         return result;
10304 }
10305
10306 static void inline_functions(struct compile_state *state, struct triple *first)
10307 {
10308         struct triple *ptr, *next;
10309         ptr = next = first;
10310         do {
10311                 int do_inline;
10312                 struct triple *func, *prev, *new;
10313                 ptr = next;
10314                 prev = ptr->prev;
10315                 next = ptr->next;
10316                 if (ptr->op != OP_FCALL) {
10317                         continue;
10318                 }
10319                 func = MISC(ptr, 0);
10320                 /* See if the function should be inlined */
10321                 switch(func->type->type & STOR_MASK) {
10322                 case STOR_STATIC | STOR_INLINE:
10323                 case STOR_LOCAL  | STOR_INLINE:
10324                 case STOR_EXTERN | STOR_INLINE:
10325                         do_inline = 1;
10326                         break;
10327                 default:
10328                         do_inline = (func->u.cval == 1);
10329                         break;
10330                 }
10331                 if (state->compiler->flags & COMPILER_ALWAYS_INLINE) {
10332                         do_inline = 1;
10333                 }
10334                 if (!(state->compiler->flags & COMPILER_INLINE)) {
10335                         do_inline = 0;
10336                 }
10337                 if (!do_inline) {
10338                         continue;
10339                 }
10340                 if (state->compiler->debug & DEBUG_INLINE) {
10341                         fprintf(stderr, "inlining %s\n",
10342                                 func->type->type_ident->name);
10343                 }
10344
10345                 /* Update the function use counts */
10346                 func->u.cval -= 1;
10347                 /* Unhook the call and really inline it */
10348                 next->prev = prev;
10349                 prev->next = next;
10350                 ptr->next = ptr->prev = ptr;
10351                 
10352                 new = flatten(state, next, 
10353                         flatten_inline_call(state, next, ptr));
10354                 if (new) {
10355                         propogate_use(state, ptr, new);
10356                 }
10357                 release_triple(state, ptr);
10358                 next = prev->next;
10359         } while (next != first);
10360         ptr = next = first;
10361         do {
10362                 struct triple *func, *prev, *new;
10363                 ptr = next;
10364                 prev = ptr->prev;
10365                 next = ptr->next;
10366                 if (ptr->op != OP_FCALL) {
10367                         continue;
10368                 }
10369                 func = MISC(ptr, 0);
10370                 inline_functions(state, RHS(func, 0));
10371                 /* Unhook the call and really flatten it */
10372                 next->prev = prev;
10373                 prev->next = next;
10374                 ptr->next = ptr->prev = ptr;
10375                 new = flatten(state, next, 
10376                         flatten_function_call(state, next, ptr));
10377                 if (new) {
10378                         propogate_use(state, ptr, new);
10379                 }
10380                 release_triple(state, ptr);
10381                 next = prev->next;
10382         } while(next != first);
10383 }
10384         
10385 static void insert_function(struct compile_state *state,
10386         struct triple *func, void *arg)
10387 {
10388         struct triple *first, *end, *ffirst, *fend;
10389
10390         if (state->compiler->debug & DEBUG_INLINE) {
10391                 fprintf(stderr, "%s func count: %d\n", 
10392                         func->type->type_ident->name, func->u.cval);
10393         }
10394         if (func->u.cval == 0) {
10395                 return;
10396         }
10397         if (state->compiler->flags & COMPILER_ALWAYS_INLINE) {
10398                 internal_error(state, func, "always inline failed\n");
10399         }
10400
10401         /* Find the end points of the lists */
10402         first  = arg;
10403         end    = first->prev;
10404         ffirst = RHS(func, 0);
10405         fend   = ffirst->prev;
10406
10407         /* splice the lists together */
10408         end->next    = ffirst;
10409         ffirst->prev = end;
10410         fend->next   = first;
10411         first->prev  = fend;
10412 }
10413
10414 static void join_functions(struct compile_state *state)
10415 {
10416         struct triple *jmp, *start, *end, *call;
10417         struct file_state file;
10418
10419         /* Dummy file state to get debug handing right */
10420         memset(&file, 0, sizeof(file));
10421         file.basename = "";
10422         file.line = 0;
10423         file.report_line = 0;
10424         file.report_name = file.basename;
10425         file.prev = state->file;
10426         state->file = &file;
10427         state->function = "";
10428         
10429         /* Lay down the basic program structure */
10430         end = label(state);
10431         start = label(state);
10432         start = flatten(state, state->first, start);
10433         end = flatten(state, state->first, end);
10434         call = new_triple(state, OP_FCALL, &void_type, -1, 0);
10435         MISC(call, 0) = state->main_function;
10436         flatten(state, state->first, call);
10437         
10438         /* See which functions are called, and how often */
10439         mark_live_functions(state, state->first);
10440         inline_functions(state, state->first);
10441         walk_functions(state, insert_function, end);
10442
10443         if (start->next != end) {
10444                 jmp = flatten(state, start, branch(state, end, 0));
10445         }
10446
10447         /* Done now cleanup */
10448         state->file = file.prev;
10449         state->function = 0;
10450 }
10451
10452 /*
10453  * Data structurs for optimation.
10454  */
10455
10456
10457 static int do_use_block(
10458         struct block *used, struct block_set **head, struct block *user, 
10459         int front)
10460 {
10461         struct block_set **ptr, *new;
10462         if (!used)
10463                 return 0;
10464         if (!user)
10465                 return 0;
10466         ptr = head;
10467         while(*ptr) {
10468                 if ((*ptr)->member == user) {
10469                         return 0;
10470                 }
10471                 ptr = &(*ptr)->next;
10472         }
10473         new = xcmalloc(sizeof(*new), "block_set");
10474         new->member = user;
10475         if (front) {
10476                 new->next = *head;
10477                 *head = new;
10478         }
10479         else {
10480                 new->next = 0;
10481                 *ptr = new;
10482         }
10483         return 1;
10484 }
10485 static int do_unuse_block(
10486         struct block *used, struct block_set **head, struct block *unuser)
10487 {
10488         struct block_set *use, **ptr;
10489         int count;
10490         count = 0;
10491         ptr = head;
10492         while(*ptr) {
10493                 use = *ptr;
10494                 if (use->member == unuser) {
10495                         *ptr = use->next;
10496                         memset(use, -1, sizeof(*use));
10497                         xfree(use);
10498                         count += 1;
10499                 }
10500                 else {
10501                         ptr = &use->next;
10502                 }
10503         }
10504         return count;
10505 }
10506
10507 static void use_block(struct block *used, struct block *user)
10508 {
10509         int count;
10510         /* Append new to the head of the list, print_block
10511          * depends on this.
10512          */
10513         count = do_use_block(used, &used->use, user, 1); 
10514         used->users += count;
10515 }
10516 static void unuse_block(struct block *used, struct block *unuser)
10517 {
10518         int count;
10519         count = do_unuse_block(used, &used->use, unuser); 
10520         used->users -= count;
10521 }
10522
10523 static void add_block_edge(struct block *block, struct block *edge, int front)
10524 {
10525         int count;
10526         count = do_use_block(block, &block->edges, edge, front);
10527         block->edge_count += count;
10528 }
10529
10530 static void remove_block_edge(struct block *block, struct block *edge)
10531 {
10532         int count;
10533         count = do_unuse_block(block, &block->edges, edge);
10534         block->edge_count -= count;
10535 }
10536
10537 static void idom_block(struct block *idom, struct block *user)
10538 {
10539         do_use_block(idom, &idom->idominates, user, 0);
10540 }
10541
10542 static void unidom_block(struct block *idom, struct block *unuser)
10543 {
10544         do_unuse_block(idom, &idom->idominates, unuser);
10545 }
10546
10547 static void domf_block(struct block *block, struct block *domf)
10548 {
10549         do_use_block(block, &block->domfrontier, domf, 0);
10550 }
10551
10552 static void undomf_block(struct block *block, struct block *undomf)
10553 {
10554         do_unuse_block(block, &block->domfrontier, undomf);
10555 }
10556
10557 static void ipdom_block(struct block *ipdom, struct block *user)
10558 {
10559         do_use_block(ipdom, &ipdom->ipdominates, user, 0);
10560 }
10561
10562 static void unipdom_block(struct block *ipdom, struct block *unuser)
10563 {
10564         do_unuse_block(ipdom, &ipdom->ipdominates, unuser);
10565 }
10566
10567 static void ipdomf_block(struct block *block, struct block *ipdomf)
10568 {
10569         do_use_block(block, &block->ipdomfrontier, ipdomf, 0);
10570 }
10571
10572 static void unipdomf_block(struct block *block, struct block *unipdomf)
10573 {
10574         do_unuse_block(block, &block->ipdomfrontier, unipdomf);
10575 }
10576
10577 static int walk_triples(
10578         struct compile_state *state, 
10579         int (*cb)(struct compile_state *state, struct triple *ptr))
10580 {
10581         struct triple *ptr;
10582         int result;
10583         ptr = state->first;
10584         do {
10585                 result = cb(state, ptr);
10586                 if (ptr->next->prev != ptr) {
10587                         internal_error(state, ptr->next, "bad prev");
10588                 }
10589                 ptr = ptr->next;
10590         } while((result == 0) && (ptr != state->first));
10591         return result;
10592 }
10593
10594 #define PRINT_LIST 1
10595 static int do_print_triple(struct compile_state *state, struct triple *ins)
10596 {
10597         int op;
10598         op = ins->op;
10599         if (op == OP_LIST) {
10600 #if !PRINT_LIST
10601                 return 0;
10602 #endif
10603         }
10604         if ((op == OP_LABEL) && (ins->use)) {
10605                 printf("\n%p:\n", ins);
10606         }
10607         display_triple(stdout, ins);
10608
10609         if (triple_is_branch(state, ins) && ins->use && (ins->op != OP_RET)) {
10610                 internal_error(state, ins, "branch used?");
10611         }
10612         if (triple_is_branch(state, ins)) {
10613                 printf("\n");
10614         }
10615         return 0;
10616 }
10617
10618 static void print_triples(struct compile_state *state)
10619 {
10620         if (state->compiler->debug & DEBUG_TRIPLES) {
10621                 walk_triples(state, do_print_triple);
10622         }
10623 }
10624
10625 struct cf_block {
10626         struct block *block;
10627 };
10628 static void find_cf_blocks(struct cf_block *cf, struct block *block)
10629 {
10630         struct block_set *edge;
10631         if (!block || (cf[block->vertex].block == block)) {
10632                 return;
10633         }
10634         cf[block->vertex].block = block;
10635         for(edge = block->edges; edge; edge = edge->next) {
10636                 find_cf_blocks(cf, edge->member);
10637         }
10638 }
10639
10640 static void print_control_flow(struct compile_state *state)
10641 {
10642         struct cf_block *cf;
10643         int i;
10644         printf("\ncontrol flow\n");
10645         cf = xcmalloc(sizeof(*cf) * (state->last_vertex + 1), "cf_block");
10646         find_cf_blocks(cf, state->first_block);
10647
10648         for(i = 1; i <= state->last_vertex; i++) {
10649                 struct block *block;
10650                 struct block_set *edge;
10651                 block = cf[i].block;
10652                 if (!block)
10653                         continue;
10654                 printf("(%p) %d:", block, block->vertex);
10655                 for(edge = block->edges; edge; edge = edge->next) {
10656                         printf(" %d", edge->member->vertex);
10657                 }
10658                 printf("\n");
10659         }
10660
10661         xfree(cf);
10662 }
10663
10664
10665 static struct block *basic_block(struct compile_state *state, struct triple *first)
10666 {
10667         struct block *block;
10668         struct triple *ptr;
10669         if (first->op != OP_LABEL) {
10670                 internal_error(state, 0, "block does not start with a label");
10671         }
10672         /* See if this basic block has already been setup */
10673         if (first->u.block != 0) {
10674                 return first->u.block;
10675         }
10676         /* Allocate another basic block structure */
10677         state->last_vertex += 1;
10678         block = xcmalloc(sizeof(*block), "block");
10679         block->first = block->last = first;
10680         block->vertex = state->last_vertex;
10681         ptr = first;
10682         do {
10683                 if ((ptr != first) && (ptr->op == OP_LABEL) && (ptr->use)) { 
10684                         break;
10685                 }
10686                 block->last = ptr;
10687                 /* If ptr->u is not used remember where the baic block is */
10688                 if (triple_stores_block(state, ptr)) {
10689                         ptr->u.block = block;
10690                 }
10691                 if (triple_is_branch(state, ptr)) {
10692                         break;
10693                 }
10694                 ptr = ptr->next;
10695         } while (ptr != state->first);
10696         if (ptr == state->first) {
10697                 /* The block has no outflowing edges */
10698         }
10699         else if (ptr->op == OP_LABEL) {
10700                 struct block *next;
10701                 next = basic_block(state, ptr);
10702                 add_block_edge(block, next, 0);
10703                 use_block(next, block);
10704         }
10705         else if (triple_is_branch(state, ptr)) {
10706                 struct triple **expr, *first;
10707                 struct block *child;
10708                 /* Find the branch targets.
10709                  * I special case the first branch as that magically
10710                  * avoids some difficult cases for the register allocator.
10711                  */
10712                 expr = triple_targ(state, ptr, 0);
10713                 if (!expr) {
10714                         internal_error(state, ptr, "branch without targets");
10715                 }
10716                 first = *expr;
10717                 expr = triple_targ(state, ptr, expr);
10718                 for(; expr; expr = triple_targ(state, ptr, expr)) {
10719                         if (!*expr) continue;
10720                         child = basic_block(state, *expr);
10721                         use_block(child, block);
10722                         add_block_edge(block, child, 0);
10723                 }
10724                 if (first) {
10725                         child = basic_block(state, first);
10726                         use_block(child, block);
10727                         add_block_edge(block, child, 1);
10728                 }
10729         }
10730         else {
10731                 internal_error(state, 0, "Bad basic block split");
10732         }
10733 #if 0
10734 {
10735         struct block_set *edge;
10736         fprintf(stderr, "basic_block: %10p [%2d] ( %10p - %10p )",
10737                 block, block->vertex, 
10738                 block->first, block->last);
10739         for(edge = block->edges; edge; edge = edge->next) {
10740                 fprintf(stderr, " %10p [%2d]",
10741                         edge->member ? edge->member->first : 0,
10742                         edge->member ? edge->member->vertex : -1);
10743         }
10744         fprintf(stderr, "\n");
10745 }
10746 #endif
10747         return block;
10748 }
10749
10750
10751 static void walk_blocks(struct compile_state *state,
10752         void (*cb)(struct compile_state *state, struct block *block, void *arg),
10753         void *arg)
10754 {
10755         struct triple *ptr, *first;
10756         struct block *last_block;
10757         last_block = 0;
10758         first = state->first;
10759         ptr = first;
10760         do {
10761                 if (triple_stores_block(state, ptr)) {
10762                         struct block *block;
10763                         block = ptr->u.block;
10764                         if (block && (block != last_block)) {
10765                                 cb(state, block, arg);
10766                         }
10767                         last_block = block;
10768                 }
10769                 ptr = ptr->next;
10770         } while(ptr != first);
10771 }
10772
10773 static void print_block(
10774         struct compile_state *state, struct block *block, void *arg)
10775 {
10776         struct block_set *user, *edge;
10777         struct triple *ptr;
10778         FILE *fp = arg;
10779
10780         fprintf(fp, "\nblock: %p (%d) ",
10781                 block, 
10782                 block->vertex);
10783
10784         for(edge = block->edges; edge; edge = edge->next) {
10785                 fprintf(fp, " %p<-%p",
10786                         edge->member,
10787                         (edge->member && edge->member->use)?
10788                         edge->member->use->member : 0);
10789         }
10790         fprintf(fp, "\n");
10791         if (block->first->op == OP_LABEL) {
10792                 fprintf(fp, "%p:\n", block->first);
10793         }
10794         for(ptr = block->first; ; ptr = ptr->next) {
10795                 display_triple(fp, ptr);
10796                 if (ptr == block->last)
10797                         break;
10798         }
10799         fprintf(fp, "users %d: ", block->users);
10800         for(user = block->use; user; user = user->next) {
10801                 fprintf(fp, "%p (%d) ", 
10802                         user->member,
10803                         user->member->vertex);
10804         }
10805         fprintf(fp,"\n\n");
10806 }
10807
10808
10809 static void romcc_print_blocks(struct compile_state *state, FILE *fp)
10810 {
10811         fprintf(fp, "--------------- blocks ---------------\n");
10812         walk_blocks(state, print_block, fp);
10813 }
10814 static void print_blocks(struct compile_state *state, const char *func, FILE *fp)
10815 {
10816         if (state->compiler->debug & DEBUG_BASIC_BLOCKS) {
10817                 fprintf(fp, "After %s\n", func);
10818                 romcc_print_blocks(state, fp);
10819                 print_control_flow(state);
10820         }
10821 }
10822
10823 static void prune_nonblock_triples(struct compile_state *state)
10824 {
10825         struct block *block;
10826         struct triple *first, *ins, *next;
10827         /* Delete the triples not in a basic block */
10828         first = state->first;
10829         block = 0;
10830         ins = first;
10831         do {
10832                 next = ins->next;
10833                 if (ins->op == OP_LABEL) {
10834                         block = ins->u.block;
10835                 }
10836                 if (!block) {
10837                         release_triple(state, ins);
10838                 }
10839                 if (block && block->last == ins) {
10840                         block = 0;
10841                 }
10842                 ins = next;
10843         } while(ins != first);
10844 }
10845
10846 static void setup_basic_blocks(struct compile_state *state)
10847 {
10848         if (!triple_stores_block(state, state->first)) {
10849                 internal_error(state, 0, "ins will not store block?");
10850         }
10851         /* Find the basic blocks */
10852         state->last_vertex = 0;
10853         state->first_block = basic_block(state, state->first);
10854         /* Delete the triples not in a basic block */
10855         prune_nonblock_triples(state);
10856
10857         /* Find the last basic block.
10858          *
10859          * For purposes of reverse flow computation it is
10860          * important that the last basic block is empty.
10861          * This allows the control flow graph to be modified to
10862          * have one unique starting block and one unique final block.
10863          * With the insertion of a few extra edges.
10864          *
10865          * If the final block contained instructions it could contain
10866          * phi functions from edges that would never contribute a
10867          * value.  Which for now at least I consider a compile error.
10868          */
10869         state->last_block = block_of_triple(state, state->first->prev);
10870         if ((state->last_block->first != state->last_block->last) ||
10871                 (state->last_block->last->op != OP_LABEL))
10872         {
10873                 struct block *block, *prev_block;
10874                 struct triple *final;
10875
10876                 prev_block = state->last_block;
10877                 
10878                 final = label(state);
10879                 flatten(state, state->first, final);
10880                 final->id |= TRIPLE_FLAG_VOLATILE;
10881                 use_triple(final, final);
10882                 block = basic_block(state, final);
10883
10884                 state->last_block = block;
10885
10886                 add_block_edge(prev_block, block, 0);
10887                 use_block(block, prev_block);
10888         }
10889
10890 #if 0
10891         /* If we are debugging print what I have just done */
10892         if (state->compiler->debug & DEBUG_BASIC_BLOCKS) {
10893                 print_blocks(state, stdout);
10894                 print_control_flow(state);
10895         }
10896 #endif
10897 }
10898
10899 static void free_basic_block(struct compile_state *state, struct block *block)
10900 {
10901         struct block_set *edge, *entry;
10902         struct block *child;
10903         if (!block) {
10904                 return;
10905         }
10906         if (block->vertex == -1) {
10907                 return;
10908         }
10909         block->vertex = -1;
10910         for(edge = block->edges; edge; edge = edge->next) {
10911                 if (edge->member) {
10912                         unuse_block(edge->member, block);
10913                 }
10914         }
10915         if (block->idom) {
10916                 unidom_block(block->idom, block);
10917         }
10918         block->idom = 0;
10919         if (block->ipdom) {
10920                 unipdom_block(block->ipdom, block);
10921         }
10922         block->ipdom = 0;
10923         while((entry = block->use)) {
10924                 child = entry->member;
10925                 unuse_block(block, child);
10926                 if (child && (child->vertex != -1)) {
10927                         for(edge = child->edges; edge; edge = edge->next) {
10928                                 edge->member = 0;
10929                         }
10930                 }
10931         }
10932         while((entry = block->idominates)) {
10933                 child = entry->member;
10934                 unidom_block(block, child);
10935                 if (child && (child->vertex != -1)) {
10936                         child->idom = 0;
10937                 }
10938         }
10939         while((entry = block->domfrontier)) {
10940                 child = entry->member;
10941                 undomf_block(block, child);
10942         }
10943         while((entry = block->ipdominates)) {
10944                 child = entry->member;
10945                 unipdom_block(block, child);
10946                 if (child && (child->vertex != -1)) {
10947                         child->ipdom = 0;
10948                 }
10949         }
10950         while((entry = block->ipdomfrontier)) {
10951                 child = entry->member;
10952                 unipdomf_block(block, child);
10953         }
10954         if (block->users != 0) {
10955                 internal_error(state, 0, "block still has users");
10956         }
10957         while((edge = block->edges)) {
10958                 child = edge->member;
10959                 remove_block_edge(block, child);
10960                 
10961                 if (child && (child->vertex != -1)) {
10962                         free_basic_block(state, child);
10963                 }
10964         }
10965         memset(block, -1, sizeof(*block));
10966         xfree(block);
10967 }
10968
10969 static void free_basic_blocks(struct compile_state *state)
10970 {
10971         struct triple *first, *ins;
10972         free_basic_block(state, state->first_block);
10973         state->last_vertex = 0;
10974         state->first_block = state->last_block = 0;
10975         first = state->first;
10976         ins = first;
10977         do {
10978                 if (triple_stores_block(state, ins)) {
10979                         ins->u.block = 0;
10980                 }
10981                 ins = ins->next;
10982         } while(ins != first);
10983         
10984 }
10985
10986 struct sdom_block {
10987         struct block *block;
10988         struct sdom_block *sdominates;
10989         struct sdom_block *sdom_next;
10990         struct sdom_block *sdom;
10991         struct sdom_block *label;
10992         struct sdom_block *parent;
10993         struct sdom_block *ancestor;
10994         int vertex;
10995 };
10996
10997
10998 static void unsdom_block(struct sdom_block *block)
10999 {
11000         struct sdom_block **ptr;
11001         if (!block->sdom_next) {
11002                 return;
11003         }
11004         ptr = &block->sdom->sdominates;
11005         while(*ptr) {
11006                 if ((*ptr) == block) {
11007                         *ptr = block->sdom_next;
11008                         return;
11009                 }
11010                 ptr = &(*ptr)->sdom_next;
11011         }
11012 }
11013
11014 static void sdom_block(struct sdom_block *sdom, struct sdom_block *block)
11015 {
11016         unsdom_block(block);
11017         block->sdom = sdom;
11018         block->sdom_next = sdom->sdominates;
11019         sdom->sdominates = block;
11020 }
11021
11022
11023
11024 static int initialize_sdblock(struct sdom_block *sd,
11025         struct block *parent, struct block *block, int vertex)
11026 {
11027         struct block_set *edge;
11028         if (!block || (sd[block->vertex].block == block)) {
11029                 return vertex;
11030         }
11031         vertex += 1;
11032         /* Renumber the blocks in a convinient fashion */
11033         block->vertex = vertex;
11034         sd[vertex].block    = block;
11035         sd[vertex].sdom     = &sd[vertex];
11036         sd[vertex].label    = &sd[vertex];
11037         sd[vertex].parent   = parent? &sd[parent->vertex] : 0;
11038         sd[vertex].ancestor = 0;
11039         sd[vertex].vertex   = vertex;
11040         for(edge = block->edges; edge; edge = edge->next) {
11041                 vertex = initialize_sdblock(sd, block, edge->member, vertex);
11042         }
11043         return vertex;
11044 }
11045
11046 static int initialize_spdblock(
11047         struct compile_state *state, struct sdom_block *sd,
11048         struct block *parent, struct block *block, int vertex)
11049 {
11050         struct block_set *user;
11051         if (!block || (sd[block->vertex].block == block)) {
11052                 return vertex;
11053         }
11054         vertex += 1;
11055         /* Renumber the blocks in a convinient fashion */
11056         block->vertex = vertex;
11057         sd[vertex].block    = block;
11058         sd[vertex].sdom     = &sd[vertex];
11059         sd[vertex].label    = &sd[vertex];
11060         sd[vertex].parent   = parent? &sd[parent->vertex] : 0;
11061         sd[vertex].ancestor = 0;
11062         sd[vertex].vertex   = vertex;
11063         for(user = block->use; user; user = user->next) {
11064                 vertex = initialize_spdblock(state, sd, block, user->member, vertex);
11065         }
11066         return vertex;
11067 }
11068
11069 static int setup_spdblocks(struct compile_state *state, struct sdom_block *sd)
11070 {
11071         struct block *block;
11072         int vertex;
11073         /* Setup as many sdpblocks as possible without using fake edges */
11074         vertex = initialize_spdblock(state, sd, 0, state->last_block, 0);
11075
11076         /* Walk through the graph and find unconnected blocks.  Add a
11077          * fake edge from the unconnected blocks to the end of the
11078          * graph. 
11079          */
11080         block = state->first_block->last->next->u.block;
11081         for(; block && block != state->first_block; block = block->last->next->u.block) {
11082                 if (sd[block->vertex].block == block) {
11083                         continue;
11084                 }
11085 #if DEBUG_SDP_BLOCKS
11086                 fprintf(stderr, "Adding %d\n", vertex +1);
11087 #endif
11088                 add_block_edge(block, state->last_block, 0);
11089                 use_block(state->last_block, block);
11090
11091                 vertex = initialize_spdblock(state, sd, state->last_block, block, vertex);
11092         }
11093         return vertex;
11094 }
11095
11096 static void compress_ancestors(struct sdom_block *v)
11097 {
11098         /* This procedure assumes ancestor(v) != 0 */
11099         /* if (ancestor(ancestor(v)) != 0) {
11100          *      compress(ancestor(ancestor(v)));
11101          *      if (semi(label(ancestor(v))) < semi(label(v))) {
11102          *              label(v) = label(ancestor(v));
11103          *      }
11104          *      ancestor(v) = ancestor(ancestor(v));
11105          * }
11106          */
11107         if (!v->ancestor) {
11108                 return;
11109         }
11110         if (v->ancestor->ancestor) {
11111                 compress_ancestors(v->ancestor->ancestor);
11112                 if (v->ancestor->label->sdom->vertex < v->label->sdom->vertex) {
11113                         v->label = v->ancestor->label;
11114                 }
11115                 v->ancestor = v->ancestor->ancestor;
11116         }
11117 }
11118
11119 static void compute_sdom(struct compile_state *state, struct sdom_block *sd)
11120 {
11121         int i;
11122         /* // step 2 
11123          *  for each v <= pred(w) {
11124          *      u = EVAL(v);
11125          *      if (semi[u] < semi[w] { 
11126          *              semi[w] = semi[u]; 
11127          *      } 
11128          * }
11129          * add w to bucket(vertex(semi[w]));
11130          * LINK(parent(w), w);
11131          *
11132          * // step 3
11133          * for each v <= bucket(parent(w)) {
11134          *      delete v from bucket(parent(w));
11135          *      u = EVAL(v);
11136          *      dom(v) = (semi[u] < semi[v]) ? u : parent(w);
11137          * }
11138          */
11139         for(i = state->last_vertex; i >= 2; i--) {
11140                 struct sdom_block *v, *parent, *next;
11141                 struct block_set *user;
11142                 struct block *block;
11143                 block = sd[i].block;
11144                 parent = sd[i].parent;
11145                 /* Step 2 */
11146                 for(user = block->use; user; user = user->next) {
11147                         struct sdom_block *v, *u;
11148                         v = &sd[user->member->vertex];
11149                         u = !(v->ancestor)? v : (compress_ancestors(v), v->label);
11150                         if (u->sdom->vertex < sd[i].sdom->vertex) {
11151                                 sd[i].sdom = u->sdom;
11152                         }
11153                 }
11154                 sdom_block(sd[i].sdom, &sd[i]);
11155                 sd[i].ancestor = parent;
11156                 /* Step 3 */
11157                 for(v = parent->sdominates; v; v = next) {
11158                         struct sdom_block *u;
11159                         next = v->sdom_next;
11160                         unsdom_block(v);
11161                         u = (!v->ancestor) ? v : (compress_ancestors(v), v->label);
11162                         v->block->idom = (u->sdom->vertex < v->sdom->vertex)? 
11163                                 u->block : parent->block;
11164                 }
11165         }
11166 }
11167
11168 static void compute_spdom(struct compile_state *state, struct sdom_block *sd)
11169 {
11170         int i;
11171         /* // step 2 
11172          *  for each v <= pred(w) {
11173          *      u = EVAL(v);
11174          *      if (semi[u] < semi[w] { 
11175          *              semi[w] = semi[u]; 
11176          *      } 
11177          * }
11178          * add w to bucket(vertex(semi[w]));
11179          * LINK(parent(w), w);
11180          *
11181          * // step 3
11182          * for each v <= bucket(parent(w)) {
11183          *      delete v from bucket(parent(w));
11184          *      u = EVAL(v);
11185          *      dom(v) = (semi[u] < semi[v]) ? u : parent(w);
11186          * }
11187          */
11188         for(i = state->last_vertex; i >= 2; i--) {
11189                 struct sdom_block *u, *v, *parent, *next;
11190                 struct block_set *edge;
11191                 struct block *block;
11192                 block = sd[i].block;
11193                 parent = sd[i].parent;
11194                 /* Step 2 */
11195                 for(edge = block->edges; edge; edge = edge->next) {
11196                         v = &sd[edge->member->vertex];
11197                         u = !(v->ancestor)? v : (compress_ancestors(v), v->label);
11198                         if (u->sdom->vertex < sd[i].sdom->vertex) {
11199                                 sd[i].sdom = u->sdom;
11200                         }
11201                 }
11202                 sdom_block(sd[i].sdom, &sd[i]);
11203                 sd[i].ancestor = parent;
11204                 /* Step 3 */
11205                 for(v = parent->sdominates; v; v = next) {
11206                         struct sdom_block *u;
11207                         next = v->sdom_next;
11208                         unsdom_block(v);
11209                         u = (!v->ancestor) ? v : (compress_ancestors(v), v->label);
11210                         v->block->ipdom = (u->sdom->vertex < v->sdom->vertex)? 
11211                                 u->block : parent->block;
11212                 }
11213         }
11214 }
11215
11216 static void compute_idom(struct compile_state *state, struct sdom_block *sd)
11217 {
11218         int i;
11219         for(i = 2; i <= state->last_vertex; i++) {
11220                 struct block *block;
11221                 block = sd[i].block;
11222                 if (block->idom->vertex != sd[i].sdom->vertex) {
11223                         block->idom = block->idom->idom;
11224                 }
11225                 idom_block(block->idom, block);
11226         }
11227         sd[1].block->idom = 0;
11228 }
11229
11230 static void compute_ipdom(struct compile_state *state, struct sdom_block *sd)
11231 {
11232         int i;
11233         for(i = 2; i <= state->last_vertex; i++) {
11234                 struct block *block;
11235                 block = sd[i].block;
11236                 if (block->ipdom->vertex != sd[i].sdom->vertex) {
11237                         block->ipdom = block->ipdom->ipdom;
11238                 }
11239                 ipdom_block(block->ipdom, block);
11240         }
11241         sd[1].block->ipdom = 0;
11242 }
11243
11244         /* Theorem 1:
11245          *   Every vertex of a flowgraph G = (V, E, r) except r has
11246          *   a unique immediate dominator.  
11247          *   The edges {(idom(w), w) |w <= V - {r}} form a directed tree
11248          *   rooted at r, called the dominator tree of G, such that 
11249          *   v dominates w if and only if v is a proper ancestor of w in
11250          *   the dominator tree.
11251          */
11252         /* Lemma 1:  
11253          *   If v and w are vertices of G such that v <= w,
11254          *   than any path from v to w must contain a common ancestor
11255          *   of v and w in T.
11256          */
11257         /* Lemma 2:  For any vertex w != r, idom(w) -> w */
11258         /* Lemma 3:  For any vertex w != r, sdom(w) -> w */
11259         /* Lemma 4:  For any vertex w != r, idom(w) -> sdom(w) */
11260         /* Theorem 2:
11261          *   Let w != r.  Suppose every u for which sdom(w) -> u -> w satisfies
11262          *   sdom(u) >= sdom(w).  Then idom(w) = sdom(w).
11263          */
11264         /* Theorem 3:
11265          *   Let w != r and let u be a vertex for which sdom(u) is 
11266          *   minimum amoung vertices u satisfying sdom(w) -> u -> w.
11267          *   Then sdom(u) <= sdom(w) and idom(u) = idom(w).
11268          */
11269         /* Lemma 5:  Let vertices v,w satisfy v -> w.
11270          *           Then v -> idom(w) or idom(w) -> idom(v)
11271          */
11272
11273 static void find_immediate_dominators(struct compile_state *state)
11274 {
11275         struct sdom_block *sd;
11276         /* w->sdom = min{v| there is a path v = v0,v1,...,vk = w such that:
11277          *           vi > w for (1 <= i <= k - 1}
11278          */
11279         /* Theorem 4:
11280          *   For any vertex w != r.
11281          *   sdom(w) = min(
11282          *                 {v|(v,w) <= E  and v < w } U 
11283          *                 {sdom(u) | u > w and there is an edge (v, w) such that u -> v})
11284          */
11285         /* Corollary 1:
11286          *   Let w != r and let u be a vertex for which sdom(u) is 
11287          *   minimum amoung vertices u satisfying sdom(w) -> u -> w.
11288          *   Then:
11289          *                   { sdom(w) if sdom(w) = sdom(u),
11290          *        idom(w) = {
11291          *                   { idom(u) otherwise
11292          */
11293         /* The algorithm consists of the following 4 steps.
11294          * Step 1.  Carry out a depth-first search of the problem graph.  
11295          *    Number the vertices from 1 to N as they are reached during
11296          *    the search.  Initialize the variables used in succeeding steps.
11297          * Step 2.  Compute the semidominators of all vertices by applying
11298          *    theorem 4.   Carry out the computation vertex by vertex in
11299          *    decreasing order by number.
11300          * Step 3.  Implicitly define the immediate dominator of each vertex
11301          *    by applying Corollary 1.
11302          * Step 4.  Explicitly define the immediate dominator of each vertex,
11303          *    carrying out the computation vertex by vertex in increasing order
11304          *    by number.
11305          */
11306         /* Step 1 initialize the basic block information */
11307         sd = xcmalloc(sizeof(*sd) * (state->last_vertex + 1), "sdom_state");
11308         initialize_sdblock(sd, 0, state->first_block, 0);
11309 #if 0
11310         sd[1].size  = 0;
11311         sd[1].label = 0;
11312         sd[1].sdom  = 0;
11313 #endif
11314         /* Step 2 compute the semidominators */
11315         /* Step 3 implicitly define the immediate dominator of each vertex */
11316         compute_sdom(state, sd);
11317         /* Step 4 explicitly define the immediate dominator of each vertex */
11318         compute_idom(state, sd);
11319         xfree(sd);
11320 }
11321
11322 static void find_post_dominators(struct compile_state *state)
11323 {
11324         struct sdom_block *sd;
11325         int vertex;
11326         /* Step 1 initialize the basic block information */
11327         sd = xcmalloc(sizeof(*sd) * (state->last_vertex + 1), "sdom_state");
11328
11329         vertex = setup_spdblocks(state, sd);
11330         if (vertex != state->last_vertex) {
11331                 internal_error(state, 0, "missing %d blocks\n",
11332                         state->last_vertex - vertex);
11333         }
11334
11335         /* Step 2 compute the semidominators */
11336         /* Step 3 implicitly define the immediate dominator of each vertex */
11337         compute_spdom(state, sd);
11338         /* Step 4 explicitly define the immediate dominator of each vertex */
11339         compute_ipdom(state, sd);
11340         xfree(sd);
11341 }
11342
11343
11344
11345 static void find_block_domf(struct compile_state *state, struct block *block)
11346 {
11347         struct block *child;
11348         struct block_set *user, *edge;
11349         if (block->domfrontier != 0) {
11350                 internal_error(state, block->first, "domfrontier present?");
11351         }
11352         for(user = block->idominates; user; user = user->next) {
11353                 child = user->member;
11354                 if (child->idom != block) {
11355                         internal_error(state, block->first, "bad idom");
11356                 }
11357                 find_block_domf(state, child);
11358         }
11359         for(edge = block->edges; edge; edge = edge->next) {
11360                 if (edge->member->idom != block) {
11361                         domf_block(block, edge->member);
11362                 }
11363         }
11364         for(user = block->idominates; user; user = user->next) {
11365                 struct block_set *frontier;
11366                 child = user->member;
11367                 for(frontier = child->domfrontier; frontier; frontier = frontier->next) {
11368                         if (frontier->member->idom != block) {
11369                                 domf_block(block, frontier->member);
11370                         }
11371                 }
11372         }
11373 }
11374
11375 static void find_block_ipdomf(struct compile_state *state, struct block *block)
11376 {
11377         struct block *child;
11378         struct block_set *user;
11379         if (block->ipdomfrontier != 0) {
11380                 internal_error(state, block->first, "ipdomfrontier present?");
11381         }
11382         for(user = block->ipdominates; user; user = user->next) {
11383                 child = user->member;
11384                 if (child->ipdom != block) {
11385                         internal_error(state, block->first, "bad ipdom");
11386                 }
11387                 find_block_ipdomf(state, child);
11388         }
11389         for(user = block->use; user; user = user->next) {
11390                 if (user->member->ipdom != block) {
11391                         ipdomf_block(block, user->member);
11392                 }
11393         }
11394         for(user = block->ipdominates; user; user = user->next) {
11395                 struct block_set *frontier;
11396                 child = user->member;
11397                 for(frontier = child->ipdomfrontier; frontier; frontier = frontier->next) {
11398                         if (frontier->member->ipdom != block) {
11399                                 ipdomf_block(block, frontier->member);
11400                         }
11401                 }
11402         }
11403 }
11404
11405 static void print_dominated(
11406         struct compile_state *state, struct block *block, void *arg)
11407 {
11408         struct block_set *user;
11409         FILE *fp = arg;
11410
11411         fprintf(fp, "%d:", block->vertex);
11412         for(user = block->idominates; user; user = user->next) {
11413                 fprintf(fp, " %d", user->member->vertex);
11414                 if (user->member->idom != block) {
11415                         internal_error(state, user->member->first, "bad idom");
11416                 }
11417         }
11418         fprintf(fp,"\n");
11419 }
11420
11421 static void print_dominated2(
11422         struct compile_state *state, FILE *fp, int depth, struct block *block)
11423 {
11424         struct block_set *user;
11425         struct triple *ins;
11426         struct occurance *ptr, *ptr2;
11427         const char *filename1, *filename2;
11428         int equal_filenames;
11429         int i;
11430         for(i = 0; i < depth; i++) {
11431                 fprintf(fp, "   ");
11432         }
11433         fprintf(fp, "%3d: %p (%p - %p) @", 
11434                 block->vertex, block, block->first, block->last);
11435         ins = block->first;
11436         while(ins != block->last && (ins->occurance->line == 0)) {
11437                 ins = ins->next;
11438         }
11439         ptr = ins->occurance;
11440         ptr2 = block->last->occurance;
11441         filename1 = ptr->filename? ptr->filename : "";
11442         filename2 = ptr2->filename? ptr2->filename : "";
11443         equal_filenames = (strcmp(filename1, filename2) == 0);
11444         if ((ptr == ptr2) || (equal_filenames && ptr->line == ptr2->line)) {
11445                 fprintf(fp, " %s:%d", ptr->filename, ptr->line);
11446         } else if (equal_filenames) {
11447                 fprintf(fp, " %s:(%d - %d)",
11448                         ptr->filename, ptr->line, ptr2->line);
11449         } else {
11450                 fprintf(fp, " (%s:%d - %s:%d)",
11451                         ptr->filename, ptr->line,
11452                         ptr2->filename, ptr2->line);
11453         }
11454         fprintf(fp, "\n");
11455         for(user = block->idominates; user; user = user->next) {
11456                 print_dominated2(state, fp, depth + 1, user->member);
11457         }
11458 }
11459
11460 static void print_dominators(struct compile_state *state, FILE *fp)
11461 {
11462         fprintf(fp, "\ndominates\n");
11463         walk_blocks(state, print_dominated, fp);
11464         fprintf(fp, "dominates\n");
11465         print_dominated2(state, fp, 0, state->first_block);
11466 }
11467
11468
11469 static int print_frontiers(
11470         struct compile_state *state, struct block *block, int vertex)
11471 {
11472         struct block_set *user, *edge;
11473
11474         if (!block || (block->vertex != vertex + 1)) {
11475                 return vertex;
11476         }
11477         vertex += 1;
11478
11479         printf("%d:", block->vertex);
11480         for(user = block->domfrontier; user; user = user->next) {
11481                 printf(" %d", user->member->vertex);
11482         }
11483         printf("\n");
11484         
11485         for(edge = block->edges; edge; edge = edge->next) {
11486                 vertex = print_frontiers(state, edge->member, vertex);
11487         }
11488         return vertex;
11489 }
11490 static void print_dominance_frontiers(struct compile_state *state)
11491 {
11492         printf("\ndominance frontiers\n");
11493         print_frontiers(state, state->first_block, 0);
11494         
11495 }
11496
11497 static void analyze_idominators(struct compile_state *state)
11498 {
11499         /* Find the immediate dominators */
11500         find_immediate_dominators(state);
11501         /* Find the dominance frontiers */
11502         find_block_domf(state, state->first_block);
11503         /* If debuging print the print what I have just found */
11504         if (state->compiler->debug & DEBUG_FDOMINATORS) {
11505                 print_dominators(state, stdout);
11506                 print_dominance_frontiers(state);
11507                 print_control_flow(state);
11508         }
11509 }
11510
11511
11512
11513 static void print_ipdominated(
11514         struct compile_state *state, struct block *block, void *arg)
11515 {
11516         struct block_set *user;
11517         FILE *fp = arg;
11518
11519         fprintf(fp, "%d:", block->vertex);
11520         for(user = block->ipdominates; user; user = user->next) {
11521                 fprintf(fp, " %d", user->member->vertex);
11522                 if (user->member->ipdom != block) {
11523                         internal_error(state, user->member->first, "bad ipdom");
11524                 }
11525         }
11526         fprintf(fp, "\n");
11527 }
11528
11529 static void print_ipdominators(struct compile_state *state, FILE *fp)
11530 {
11531         fprintf(fp, "\nipdominates\n");
11532         walk_blocks(state, print_ipdominated, fp);
11533 }
11534
11535 static int print_pfrontiers(
11536         struct compile_state *state, struct block *block, int vertex)
11537 {
11538         struct block_set *user;
11539
11540         if (!block || (block->vertex != vertex + 1)) {
11541                 return vertex;
11542         }
11543         vertex += 1;
11544
11545         printf("%d:", block->vertex);
11546         for(user = block->ipdomfrontier; user; user = user->next) {
11547                 printf(" %d", user->member->vertex);
11548         }
11549         printf("\n");
11550         for(user = block->use; user; user = user->next) {
11551                 vertex = print_pfrontiers(state, user->member, vertex);
11552         }
11553         return vertex;
11554 }
11555 static void print_ipdominance_frontiers(struct compile_state *state)
11556 {
11557         printf("\nipdominance frontiers\n");
11558         print_pfrontiers(state, state->last_block, 0);
11559         
11560 }
11561
11562 static void analyze_ipdominators(struct compile_state *state)
11563 {
11564         /* Find the post dominators */
11565         find_post_dominators(state);
11566         /* Find the control dependencies (post dominance frontiers) */
11567         find_block_ipdomf(state, state->last_block);
11568         /* If debuging print the print what I have just found */
11569         if (state->compiler->debug & DEBUG_RDOMINATORS) {
11570                 print_ipdominators(state, stdout);
11571                 print_ipdominance_frontiers(state);
11572                 print_control_flow(state);
11573         }
11574 }
11575
11576 static int bdominates(struct compile_state *state,
11577         struct block *dom, struct block *sub)
11578 {
11579         while(sub && (sub != dom)) {
11580                 sub = sub->idom;
11581         }
11582         return sub == dom;
11583 }
11584
11585 static int tdominates(struct compile_state *state,
11586         struct triple *dom, struct triple *sub)
11587 {
11588         struct block *bdom, *bsub;
11589         int result;
11590         bdom = block_of_triple(state, dom);
11591         bsub = block_of_triple(state, sub);
11592         if (bdom != bsub) {
11593                 result = bdominates(state, bdom, bsub);
11594         } 
11595         else {
11596                 struct triple *ins;
11597                 ins = sub;
11598                 while((ins != bsub->first) && (ins != dom)) {
11599                         ins = ins->prev;
11600                 }
11601                 result = (ins == dom);
11602         }
11603         return result;
11604 }
11605
11606 static void analyze_basic_blocks(struct compile_state *state)
11607 {
11608         setup_basic_blocks(state);
11609         analyze_idominators(state);
11610         analyze_ipdominators(state);
11611 }
11612
11613 static void insert_phi_operations(struct compile_state *state)
11614 {
11615         size_t size;
11616         struct triple *first;
11617         int *has_already, *work;
11618         struct block *work_list, **work_list_tail;
11619         int iter;
11620         struct triple *var, *vnext;
11621
11622         size = sizeof(int) * (state->last_vertex + 1);
11623         has_already = xcmalloc(size, "has_already");
11624         work =        xcmalloc(size, "work");
11625         iter = 0;
11626
11627         first = state->first;
11628         for(var = first->next; var != first ; var = vnext) {
11629                 struct block *block;
11630                 struct triple_set *user, *unext;
11631                 vnext = var->next;
11632                 if ((var->op != OP_ADECL) || !var->use) {
11633                         continue;
11634                 }
11635                 iter += 1;
11636                 work_list = 0;
11637                 work_list_tail = &work_list;
11638                 for(user = var->use; user; user = unext) {
11639                         unext = user->next;
11640                         if (user->member->op == OP_READ) {
11641                                 continue;
11642                         }
11643                         if (user->member->op != OP_WRITE) {
11644                                 internal_error(state, user->member, 
11645                                         "bad variable access");
11646                         }
11647                         block = user->member->u.block;
11648                         if (!block) {
11649                                 warning(state, user->member, "dead code");
11650                                 release_triple(state, user->member);
11651                                 continue;
11652                         }
11653                         if (work[block->vertex] >= iter) {
11654                                 continue;
11655                         }
11656                         work[block->vertex] = iter;
11657                         *work_list_tail = block;
11658                         block->work_next = 0;
11659                         work_list_tail = &block->work_next;
11660                 }
11661                 for(block = work_list; block; block = block->work_next) {
11662                         struct block_set *df;
11663                         for(df = block->domfrontier; df; df = df->next) {
11664                                 struct triple *phi;
11665                                 struct block *front;
11666                                 int in_edges;
11667                                 front = df->member;
11668
11669                                 if (has_already[front->vertex] >= iter) {
11670                                         continue;
11671                                 }
11672                                 /* Count how many edges flow into this block */
11673                                 in_edges = front->users;
11674                                 /* Insert a phi function for this variable */
11675                                 get_occurance(var->occurance);
11676                                 phi = alloc_triple(
11677                                         state, OP_PHI, var->type, -1, in_edges, 
11678                                         var->occurance);
11679                                 phi->u.block = front;
11680                                 MISC(phi, 0) = var;
11681                                 use_triple(var, phi);
11682                                 /* Insert the phi functions immediately after the label */
11683                                 insert_triple(state, front->first->next, phi);
11684                                 if (front->first == front->last) {
11685                                         front->last = front->first->next;
11686                                 }
11687                                 has_already[front->vertex] = iter;
11688                                 transform_to_arch_instruction(state, phi);
11689
11690                                 /* If necessary plan to visit the basic block */
11691                                 if (work[front->vertex] >= iter) {
11692                                         continue;
11693                                 }
11694                                 work[front->vertex] = iter;
11695                                 *work_list_tail = front;
11696                                 front->work_next = 0;
11697                                 work_list_tail = &front->work_next;
11698                         }
11699                 }
11700         }
11701         xfree(has_already);
11702         xfree(work);
11703 }
11704
11705
11706 struct stack {
11707         struct triple_set *top;
11708         unsigned orig_id;
11709 };
11710
11711 static int count_adecls(struct compile_state *state)
11712 {
11713         struct triple *first, *ins;
11714         int adecls = 0;
11715         first = state->first;
11716         ins = first;
11717         do {
11718                 if (ins->op == OP_ADECL) {
11719                         adecls += 1;
11720                 }
11721                 ins = ins->next;
11722         } while(ins != first);
11723         return adecls;
11724 }
11725
11726 static void number_adecls(struct compile_state *state, struct stack *stacks)
11727 {
11728         struct triple *first, *ins;
11729         int adecls = 0;
11730         first = state->first;
11731         ins = first;
11732         do {
11733                 if (ins->op == OP_ADECL) {
11734                         adecls += 1;
11735                         stacks[adecls].orig_id = ins->id;
11736                         ins->id = adecls;
11737                 }
11738                 ins = ins->next;
11739         } while(ins != first);
11740 }
11741
11742 static void restore_adecls(struct compile_state *state, struct stack *stacks)
11743 {
11744         struct triple *first, *ins;
11745         first = state->first;
11746         ins = first;
11747         do {
11748                 if (ins->op == OP_ADECL) {
11749                         ins->id = stacks[ins->id].orig_id;
11750                 }
11751                 ins = ins->next;
11752         } while(ins != first);
11753 }
11754
11755 static struct triple *peek_triple(struct stack *stacks, struct triple *var)
11756 {
11757         struct triple_set *head;
11758         struct triple *top_val;
11759         top_val = 0;
11760         head = stacks[var->id].top;
11761         if (head) {
11762                 top_val = head->member;
11763         }
11764         return top_val;
11765 }
11766
11767 static void push_triple(struct stack *stacks, struct triple *var, struct triple *val)
11768 {
11769         struct triple_set *new;
11770         /* Append new to the head of the list,
11771          * it's the only sensible behavoir for a stack.
11772          */
11773         new = xcmalloc(sizeof(*new), "triple_set");
11774         new->member = val;
11775         new->next   = stacks[var->id].top;
11776         stacks[var->id].top = new;
11777 }
11778
11779 static void pop_triple(struct stack *stacks, struct triple *var, struct triple *oldval)
11780 {
11781         struct triple_set *set, **ptr;
11782         ptr = &stacks[var->id].top;
11783         while(*ptr) {
11784                 set = *ptr;
11785                 if (set->member == oldval) {
11786                         *ptr = set->next;
11787                         xfree(set);
11788                         /* Only free one occurance from the stack */
11789                         return;
11790                 }
11791                 else {
11792                         ptr = &set->next;
11793                 }
11794         }
11795 }
11796
11797 /*
11798  * C(V)
11799  * S(V)
11800  */
11801 static void fixup_block_phi_variables(
11802         struct compile_state *state, struct stack *stacks, struct block *parent, struct block *block)
11803 {
11804         struct block_set *set;
11805         struct triple *ptr;
11806         int edge;
11807         if (!parent || !block)
11808                 return;
11809         /* Find the edge I am coming in on */
11810         edge = 0;
11811         for(set = block->use; set; set = set->next, edge++) {
11812                 if (set->member == parent) {
11813                         break;
11814                 }
11815         }
11816         if (!set) {
11817                 internal_error(state, 0, "phi input is not on a control predecessor");
11818         }
11819         for(ptr = block->first; ; ptr = ptr->next) {
11820                 if (ptr->op == OP_PHI) {
11821                         struct triple *var, *val, **slot;
11822                         var = MISC(ptr, 0);
11823                         if (!var) {
11824                                 internal_error(state, ptr, "no var???");
11825                         }
11826                         /* Find the current value of the variable */
11827                         val = peek_triple(stacks, var);
11828                         if (val && ((val->op == OP_WRITE) || (val->op == OP_READ))) {
11829                                 internal_error(state, val, "bad value in phi");
11830                         }
11831                         if (edge >= TRIPLE_RHS(ptr->sizes)) {
11832                                 internal_error(state, ptr, "edges > phi rhs");
11833                         }
11834                         slot = &RHS(ptr, edge);
11835                         if ((*slot != 0) && (*slot != val)) {
11836                                 internal_error(state, ptr, "phi already bound on this edge");
11837                         }
11838                         *slot = val;
11839                         use_triple(val, ptr);
11840                 }
11841                 if (ptr == block->last) {
11842                         break;
11843                 }
11844         }
11845 }
11846
11847
11848 static void rename_block_variables(
11849         struct compile_state *state, struct stack *stacks, struct block *block)
11850 {
11851         struct block_set *user, *edge;
11852         struct triple *ptr, *next, *last;
11853         int done;
11854         if (!block)
11855                 return;
11856         last = block->first;
11857         done = 0;
11858         for(ptr = block->first; !done; ptr = next) {
11859                 next = ptr->next;
11860                 if (ptr == block->last) {
11861                         done = 1;
11862                 }
11863                 /* RHS(A) */
11864                 if (ptr->op == OP_READ) {
11865                         struct triple *var, *val;
11866                         var = RHS(ptr, 0);
11867                         unuse_triple(var, ptr);
11868                         /* Find the current value of the variable */
11869                         val = peek_triple(stacks, var);
11870                         if (!val) {
11871                                 error(state, ptr, "variable used without being set");
11872                         }
11873                         if ((val->op == OP_WRITE) || (val->op == OP_READ)) {
11874                                 internal_error(state, val, "bad value in read");
11875                         }
11876                         propogate_use(state, ptr, val);
11877                         release_triple(state, ptr);
11878                         continue;
11879                 }
11880                 /* LHS(A) */
11881                 if (ptr->op == OP_WRITE) {
11882                         struct triple *var, *val, *tval;
11883                         var = RHS(ptr, 0);
11884                         tval = val = RHS(ptr, 1);
11885                         if ((val->op == OP_WRITE) || (val->op == OP_READ)) {
11886                                 internal_error(state, ptr, "bad value in write");
11887                         }
11888                         /* Insert a copy if the types differ */
11889                         if (!equiv_types(ptr->type, val->type)) {
11890                                 if (val->op == OP_INTCONST) {
11891                                         tval = pre_triple(state, ptr, OP_INTCONST, ptr->type, 0, 0);
11892                                         tval->u.cval = val->u.cval;
11893                                 }
11894                                 else {
11895                                         tval = pre_triple(state, ptr, OP_COPY, ptr->type, val, 0);
11896                                         use_triple(val, tval);
11897                                 }
11898                                 transform_to_arch_instruction(state, tval);
11899                                 unuse_triple(val, ptr);
11900                                 RHS(ptr, 1) = tval;
11901                                 use_triple(tval, ptr);
11902                         }
11903                         propogate_use(state, ptr, tval);
11904                         unuse_triple(var, ptr);
11905                         /* Push OP_WRITE ptr->right onto a stack of variable uses */
11906                         push_triple(stacks, var, tval);
11907                 }
11908                 if (ptr->op == OP_PHI) {
11909                         struct triple *var;
11910                         var = MISC(ptr, 0);
11911                         /* Push OP_PHI onto a stack of variable uses */
11912                         push_triple(stacks, var, ptr);
11913                 }
11914                 last = ptr;
11915         }
11916         block->last = last;
11917
11918         /* Fixup PHI functions in the cf successors */
11919         for(edge = block->edges; edge; edge = edge->next) {
11920                 fixup_block_phi_variables(state, stacks, block, edge->member);
11921         }
11922         /* rename variables in the dominated nodes */
11923         for(user = block->idominates; user; user = user->next) {
11924                 rename_block_variables(state, stacks, user->member);
11925         }
11926         /* pop the renamed variable stack */
11927         last = block->first;
11928         done = 0;
11929         for(ptr = block->first; !done ; ptr = next) {
11930                 next = ptr->next;
11931                 if (ptr == block->last) {
11932                         done = 1;
11933                 }
11934                 if (ptr->op == OP_WRITE) {
11935                         struct triple *var;
11936                         var = RHS(ptr, 0);
11937                         /* Pop OP_WRITE ptr->right from the stack of variable uses */
11938                         pop_triple(stacks, var, RHS(ptr, 1));
11939                         release_triple(state, ptr);
11940                         continue;
11941                 }
11942                 if (ptr->op == OP_PHI) {
11943                         struct triple *var;
11944                         var = MISC(ptr, 0);
11945                         /* Pop OP_WRITE ptr->right from the stack of variable uses */
11946                         pop_triple(stacks, var, ptr);
11947                 }
11948                 last = ptr;
11949         }
11950         block->last = last;
11951 }
11952
11953 static void rename_variables(struct compile_state *state)
11954 {
11955         struct stack *stacks;
11956         int adecls;
11957
11958         /* Allocate stacks for the Variables */
11959         adecls = count_adecls(state);
11960         stacks = xcmalloc(sizeof(stacks[0])*(adecls + 1), "adecl stacks");
11961
11962         /* Give each adecl a stack */
11963         number_adecls(state, stacks);
11964
11965         /* Rename the variables */
11966         rename_block_variables(state, stacks, state->first_block);
11967
11968         /* Remove the stacks from the adecls */
11969         restore_adecls(state, stacks);
11970         xfree(stacks);
11971 }
11972
11973 static void prune_block_variables(struct compile_state *state,
11974         struct block *block)
11975 {
11976         struct block_set *user;
11977         struct triple *next, *last, *ptr;
11978         int done;
11979         last = block->first;
11980         done = 0;
11981         for(ptr = block->first; !done; ptr = next) {
11982                 next = ptr->next;
11983                 if (ptr == block->last) {
11984                         done = 1;
11985                 }
11986                 if (ptr->op == OP_ADECL) {
11987                         struct triple_set *user, *next;
11988                         for(user = ptr->use; user; user = next) {
11989                                 struct triple *use;
11990                                 next = user->next;
11991                                 use = user->member;
11992                                 if (use->op != OP_PHI) {
11993                                         internal_error(state, use, "decl still used");
11994                                 }
11995                                 if (MISC(use, 0) != ptr) {
11996                                         internal_error(state, use, "bad phi use of decl");
11997                                 }
11998                                 unuse_triple(ptr, use);
11999                                 MISC(use, 0) = 0;
12000                         }
12001                         release_triple(state, ptr);
12002                         continue;
12003                 }
12004                 last = ptr;
12005         }
12006         block->last = last;
12007         for(user = block->idominates; user; user = user->next) {
12008                 prune_block_variables(state, user->member);
12009         }
12010 }
12011
12012 struct phi_triple {
12013         struct triple *phi;
12014         unsigned orig_id;
12015         int alive;
12016 };
12017
12018 static void keep_phi(struct compile_state *state, struct phi_triple *live, struct triple *phi)
12019 {
12020         struct triple **slot;
12021         int zrhs, i;
12022         if (live[phi->id].alive) {
12023                 return;
12024         }
12025         live[phi->id].alive = 1;
12026         zrhs = TRIPLE_RHS(phi->sizes);
12027         slot = &RHS(phi, 0);
12028         for(i = 0; i < zrhs; i++) {
12029                 struct triple *used;
12030                 used = slot[i];
12031                 if (used && (used->op == OP_PHI)) {
12032                         keep_phi(state, live, used);
12033                 }
12034         }
12035 }
12036
12037 static void prune_unused_phis(struct compile_state *state)
12038 {
12039         struct triple *first, *phi;
12040         struct phi_triple *live;
12041         int phis, i;
12042         
12043         /* Find the first instruction */
12044         first = state->first;
12045
12046         /* Count how many phi functions I need to process */
12047         phis = 0;
12048         for(phi = first->next; phi != first; phi = phi->next) {
12049                 if (phi->op == OP_PHI) {
12050                         phis += 1;
12051                 }
12052         }
12053         
12054         /* Mark them all dead */
12055         live = xcmalloc(sizeof(*live) * (phis + 1), "phi_triple");
12056         phis = 0;
12057         for(phi = first->next; phi != first; phi = phi->next) {
12058                 if (phi->op != OP_PHI) {
12059                         continue;
12060                 }
12061                 live[phis].alive   = 0;
12062                 live[phis].orig_id = phi->id;
12063                 live[phis].phi     = phi;
12064                 phi->id = phis;
12065                 phis += 1;
12066         }
12067         
12068         /* Mark phis alive that are used by non phis */
12069         for(i = 0; i < phis; i++) {
12070                 struct triple_set *set;
12071                 for(set = live[i].phi->use; !live[i].alive && set; set = set->next) {
12072                         if (set->member->op != OP_PHI) {
12073                                 keep_phi(state, live, live[i].phi);
12074                                 break;
12075                         }
12076                 }
12077         }
12078
12079         /* Delete the extraneous phis */
12080         for(i = 0; i < phis; i++) {
12081                 struct triple **slot;
12082                 int zrhs, j;
12083                 if (!live[i].alive) {
12084                         release_triple(state, live[i].phi);
12085                         continue;
12086                 }
12087                 phi = live[i].phi;
12088                 slot = &RHS(phi, 0);
12089                 zrhs = TRIPLE_RHS(phi->sizes);
12090                 for(j = 0; j < zrhs; j++) {
12091                         if(!slot[j]) {
12092                                 error(state, phi, "variable not set on all paths to use");
12093                         }
12094                 }
12095         }
12096         xfree(live);
12097 }
12098
12099 static void transform_to_ssa_form(struct compile_state *state)
12100 {
12101         insert_phi_operations(state);
12102         rename_variables(state);
12103
12104         prune_block_variables(state, state->first_block);
12105         prune_unused_phis(state);
12106
12107         print_blocks(state, __func__, stdout);
12108 }
12109
12110
12111 static void clear_vertex(
12112         struct compile_state *state, struct block *block, void *arg)
12113 {
12114         /* Clear the current blocks vertex and the vertex of all
12115          * of the current blocks neighbors in case there are malformed
12116          * blocks with now instructions at this point.
12117          */
12118         struct block_set *user, *edge;
12119         block->vertex = 0;
12120         for(edge = block->edges; edge; edge = edge->next) {
12121                 edge->member->vertex = 0;
12122         }
12123         for(user = block->use; user; user = user->next) {
12124                 user->member->vertex = 0;
12125         }
12126 }
12127
12128 static void mark_live_block(
12129         struct compile_state *state, struct block *block, int *next_vertex)
12130 {
12131         /* See if this is a block that has not been marked */
12132         if (block->vertex != 0) {
12133                 return;
12134         }
12135         block->vertex = *next_vertex;
12136         *next_vertex += 1;
12137         if (triple_is_branch(state, block->last)) {
12138                 struct triple **targ;
12139                 targ = triple_targ(state, block->last, 0);
12140                 for(; targ; targ = triple_targ(state, block->last, targ)) {
12141                         if (!*targ) {
12142                                 continue;
12143                         }
12144                         if (!triple_stores_block(state, *targ)) {
12145                                 internal_error(state, 0, "bad targ");
12146                         }
12147                         mark_live_block(state, (*targ)->u.block, next_vertex);
12148                 }
12149         }
12150         else if (block->last->next != state->first) {
12151                 struct triple *ins;
12152                 ins = block->last->next;
12153                 if (!triple_stores_block(state, ins)) {
12154                         internal_error(state, 0, "bad block start");
12155                 }
12156                 mark_live_block(state, ins->u.block, next_vertex);
12157         }
12158 }
12159
12160 static void transform_from_ssa_form(struct compile_state *state)
12161 {
12162         /* To get out of ssa form we insert moves on the incoming
12163          * edges to blocks containting phi functions.
12164          */
12165         struct triple *first;
12166         struct triple *phi, *var, *next;
12167         int next_vertex;
12168
12169         /* Walk the control flow to see which blocks remain alive */
12170         walk_blocks(state, clear_vertex, 0);
12171         next_vertex = 1;
12172         mark_live_block(state, state->first_block, &next_vertex);
12173
12174         /* Walk all of the operations to find the phi functions */
12175         first = state->first;
12176         for(phi = first->next; phi != first ; phi = next) {
12177                 struct block_set *set;
12178                 struct block *block;
12179                 struct triple **slot;
12180                 struct triple *var;
12181                 struct triple_set *use, *use_next;
12182                 int edge, used;
12183                 next = phi->next;
12184                 if (phi->op != OP_PHI) {
12185                         continue;
12186                 }
12187
12188                 block = phi->u.block;
12189                 slot  = &RHS(phi, 0);
12190
12191                 /* If this phi is in a dead block just forget it */
12192                 if (block->vertex == 0) {
12193                         release_triple(state, phi);
12194                         continue;
12195                 }
12196
12197                 /* Forget uses from code in dead blocks */
12198                 for(use = phi->use; use; use = use_next) {
12199                         struct block *ublock;
12200                         struct triple **expr;
12201                         use_next = use->next;
12202                         ublock = block_of_triple(state, use->member);
12203                         if ((use->member == phi) || (ublock->vertex != 0)) {
12204                                 continue;
12205                         }
12206                         expr = triple_rhs(state, use->member, 0);
12207                         for(; expr; expr = triple_rhs(state, use->member, expr)) {
12208                                 if (*expr == phi) {
12209                                         *expr = 0;
12210                                 }
12211                         }
12212                         unuse_triple(phi, use->member);
12213                 }
12214                 /* A variable to replace the phi function */
12215                 var = post_triple(state, phi, OP_ADECL, phi->type, 0,0);
12216
12217                 /* Replaces use of phi with var */
12218                 propogate_use(state, phi, var);
12219
12220                 /* Walk all of the incoming edges/blocks and insert moves.
12221                  */
12222                 used = 0;
12223                 for(edge = 0, set = block->use; set; set = set->next, edge++) {
12224                         struct block *eblock, *vblock;
12225                         struct triple *move;
12226                         struct triple *val, *base;
12227                         eblock = set->member;
12228                         val = slot[edge];
12229                         slot[edge] = 0;
12230                         unuse_triple(val, phi);
12231                         vblock = block_of_triple(state, val);
12232
12233                         /* If we don't have a value that belongs in an OP_WRITE
12234                          * continue on.
12235                          */
12236                         if (!val || (val == &zero_triple) || (val == phi) || 
12237                                 (!vblock) || (vblock->vertex == 0)) {
12238                                 continue;
12239                         }
12240
12241                         /* If the value occurs in a dead block see if a replacement
12242                          * block can be found.
12243                          */
12244                         while(eblock && (eblock->vertex == 0)) {
12245                                 eblock = eblock->idom;
12246                         }
12247                         /* If not continue on with the next value. */
12248                         if (!eblock || (eblock->vertex == 0)) {
12249                                 continue;
12250                         }
12251
12252                         /* If we have an empty incoming block ignore it. */
12253                         if (!eblock->first) {
12254                                 internal_error(state, 0, "empty block?");
12255                         }
12256                         
12257                         /* Make certain the write is placed in the edge block... */
12258                         base = eblock->first;
12259                         if (block_of_triple(state, val) == eblock) {
12260                                 base = val;
12261                         }
12262                         move = post_triple(state, base, OP_WRITE, var->type, var, val);
12263                         use_triple(val, move);
12264                         use_triple(var, move);
12265                         used = 1;
12266                 }               
12267                 /* If var is not used free it */
12268                 if (!used) {
12269                         free_triple(state, var);
12270                 }
12271
12272                 /* Release the phi function */
12273                 release_triple(state, phi);
12274         }
12275         
12276         /* Walk all of the operations to find the adecls */
12277         for(var = first->next; var != first ; var = var->next) {
12278                 struct triple_set *use, *use_next;
12279                 if (var->op != OP_ADECL) {
12280                         continue;
12281                 }
12282
12283                 /* Walk through all of the rhs uses of var and
12284                  * replace them with read of var.
12285                  */
12286                 for(use = var->use; use; use = use_next) {
12287                         struct triple *read, *user;
12288                         struct triple **slot;
12289                         int zrhs, i, used;
12290                         use_next = use->next;
12291                         user = use->member;
12292                         
12293                         /* Generate a read of var */
12294                         read = pre_triple(state, user, OP_READ, var->type, var, 0);
12295                         use_triple(var, read);
12296
12297                         /* Find the rhs uses and see if they need to be replaced */
12298                         used = 0;
12299                         zrhs = TRIPLE_RHS(user->sizes);
12300                         slot = &RHS(user, 0);
12301                         for(i = 0; i < zrhs; i++) {
12302                                 if ((slot[i] == var) &&
12303                                         ((i != 0) || (user->op != OP_WRITE))) 
12304                                 {
12305                                         slot[i] = read;
12306                                         used = 1;
12307                                 }
12308                         }
12309                         /* If we did use it cleanup the uses */
12310                         if (used) {
12311                                 unuse_triple(var, user);
12312                                 use_triple(read, user);
12313                         } 
12314                         /* If we didn't use it release the extra triple */
12315                         else {
12316                                 release_triple(state, read);
12317                         }
12318                 }
12319         }
12320 }
12321
12322 #define HI() if (state->compiler->debug & DEBUG_REBUILD_SSA_FORM) { \
12323         fprintf(stderr, "@ %s:%d\n", __FILE__, __LINE__); romcc_print_blocks(state, stderr); \
12324         } 
12325
12326 static void rebuild_ssa_form(struct compile_state *state)
12327 {
12328 HI();
12329         transform_from_ssa_form(state);
12330 HI();
12331         free_basic_blocks(state);
12332         analyze_basic_blocks(state);
12333 HI();
12334         insert_phi_operations(state);
12335 HI();
12336         rename_variables(state);
12337 HI();
12338         
12339         prune_block_variables(state, state->first_block);
12340 HI();
12341         prune_unused_phis(state);
12342 HI();
12343 }
12344 #undef HI
12345
12346 /* 
12347  * Register conflict resolution
12348  * =========================================================
12349  */
12350
12351 static struct reg_info find_def_color(
12352         struct compile_state *state, struct triple *def)
12353 {
12354         struct triple_set *set;
12355         struct reg_info info;
12356         info.reg = REG_UNSET;
12357         info.regcm = 0;
12358         if (!triple_is_def(state, def)) {
12359                 return info;
12360         }
12361         info = arch_reg_lhs(state, def, 0);
12362         if (info.reg >= MAX_REGISTERS) {
12363                 info.reg = REG_UNSET;
12364         }
12365         for(set = def->use; set; set = set->next) {
12366                 struct reg_info tinfo;
12367                 int i;
12368                 i = find_rhs_use(state, set->member, def);
12369                 if (i < 0) {
12370                         continue;
12371                 }
12372                 tinfo = arch_reg_rhs(state, set->member, i);
12373                 if (tinfo.reg >= MAX_REGISTERS) {
12374                         tinfo.reg = REG_UNSET;
12375                 }
12376                 if ((tinfo.reg != REG_UNSET) && 
12377                         (info.reg != REG_UNSET) &&
12378                         (tinfo.reg != info.reg)) {
12379                         internal_error(state, def, "register conflict");
12380                 }
12381                 if ((info.regcm & tinfo.regcm) == 0) {
12382                         internal_error(state, def, "regcm conflict %x & %x == 0",
12383                                 info.regcm, tinfo.regcm);
12384                 }
12385                 if (info.reg == REG_UNSET) {
12386                         info.reg = tinfo.reg;
12387                 }
12388                 info.regcm &= tinfo.regcm;
12389         }
12390         if (info.reg >= MAX_REGISTERS) {
12391                 internal_error(state, def, "register out of range");
12392         }
12393         return info;
12394 }
12395
12396 static struct reg_info find_lhs_pre_color(
12397         struct compile_state *state, struct triple *ins, int index)
12398 {
12399         struct reg_info info;
12400         int zlhs, zrhs, i;
12401         zrhs = TRIPLE_RHS(ins->sizes);
12402         zlhs = TRIPLE_LHS(ins->sizes);
12403         if (!zlhs && triple_is_def(state, ins)) {
12404                 zlhs = 1;
12405         }
12406         if (index >= zlhs) {
12407                 internal_error(state, ins, "Bad lhs %d", index);
12408         }
12409         info = arch_reg_lhs(state, ins, index);
12410         for(i = 0; i < zrhs; i++) {
12411                 struct reg_info rinfo;
12412                 rinfo = arch_reg_rhs(state, ins, i);
12413                 if ((info.reg == rinfo.reg) &&
12414                         (rinfo.reg >= MAX_REGISTERS)) {
12415                         struct reg_info tinfo;
12416                         tinfo = find_lhs_pre_color(state, RHS(ins, index), 0);
12417                         info.reg = tinfo.reg;
12418                         info.regcm &= tinfo.regcm;
12419                         break;
12420                 }
12421         }
12422         if (info.reg >= MAX_REGISTERS) {
12423                 info.reg = REG_UNSET;
12424         }
12425         return info;
12426 }
12427
12428 static struct reg_info find_rhs_post_color(
12429         struct compile_state *state, struct triple *ins, int index);
12430
12431 static struct reg_info find_lhs_post_color(
12432         struct compile_state *state, struct triple *ins, int index)
12433 {
12434         struct triple_set *set;
12435         struct reg_info info;
12436         struct triple *lhs;
12437 #if DEBUG_TRIPLE_COLOR
12438         fprintf(stderr, "find_lhs_post_color(%p, %d)\n",
12439                 ins, index);
12440 #endif
12441         if ((index == 0) && triple_is_def(state, ins)) {
12442                 lhs = ins;
12443         }
12444         else if (index < TRIPLE_LHS(ins->sizes)) {
12445                 lhs = LHS(ins, index);
12446         }
12447         else {
12448                 internal_error(state, ins, "Bad lhs %d", index);
12449                 lhs = 0;
12450         }
12451         info = arch_reg_lhs(state, ins, index);
12452         if (info.reg >= MAX_REGISTERS) {
12453                 info.reg = REG_UNSET;
12454         }
12455         for(set = lhs->use; set; set = set->next) {
12456                 struct reg_info rinfo;
12457                 struct triple *user;
12458                 int zrhs, i;
12459                 user = set->member;
12460                 zrhs = TRIPLE_RHS(user->sizes);
12461                 for(i = 0; i < zrhs; i++) {
12462                         if (RHS(user, i) != lhs) {
12463                                 continue;
12464                         }
12465                         rinfo = find_rhs_post_color(state, user, i);
12466                         if ((info.reg != REG_UNSET) &&
12467                                 (rinfo.reg != REG_UNSET) &&
12468                                 (info.reg != rinfo.reg)) {
12469                                 internal_error(state, ins, "register conflict");
12470                         }
12471                         if ((info.regcm & rinfo.regcm) == 0) {
12472                                 internal_error(state, ins, "regcm conflict %x & %x == 0",
12473                                         info.regcm, rinfo.regcm);
12474                         }
12475                         if (info.reg == REG_UNSET) {
12476                                 info.reg = rinfo.reg;
12477                         }
12478                         info.regcm &= rinfo.regcm;
12479                 }
12480         }
12481 #if DEBUG_TRIPLE_COLOR
12482         fprintf(stderr, "find_lhs_post_color(%p, %d) -> ( %d, %x)\n",
12483                 ins, index, info.reg, info.regcm);
12484 #endif
12485         return info;
12486 }
12487
12488 static struct reg_info find_rhs_post_color(
12489         struct compile_state *state, struct triple *ins, int index)
12490 {
12491         struct reg_info info, rinfo;
12492         int zlhs, i;
12493 #if DEBUG_TRIPLE_COLOR
12494         fprintf(stderr, "find_rhs_post_color(%p, %d)\n",
12495                 ins, index);
12496 #endif
12497         rinfo = arch_reg_rhs(state, ins, index);
12498         zlhs = TRIPLE_LHS(ins->sizes);
12499         if (!zlhs && triple_is_def(state, ins)) {
12500                 zlhs = 1;
12501         }
12502         info = rinfo;
12503         if (info.reg >= MAX_REGISTERS) {
12504                 info.reg = REG_UNSET;
12505         }
12506         for(i = 0; i < zlhs; i++) {
12507                 struct reg_info linfo;
12508                 linfo = arch_reg_lhs(state, ins, i);
12509                 if ((linfo.reg == rinfo.reg) &&
12510                         (linfo.reg >= MAX_REGISTERS)) {
12511                         struct reg_info tinfo;
12512                         tinfo = find_lhs_post_color(state, ins, i);
12513                         if (tinfo.reg >= MAX_REGISTERS) {
12514                                 tinfo.reg = REG_UNSET;
12515                         }
12516                         info.regcm &= linfo.regcm;
12517                         info.regcm &= tinfo.regcm;
12518                         if (info.reg != REG_UNSET) {
12519                                 internal_error(state, ins, "register conflict");
12520                         }
12521                         if (info.regcm == 0) {
12522                                 internal_error(state, ins, "regcm conflict");
12523                         }
12524                         info.reg = tinfo.reg;
12525                 }
12526         }
12527 #if DEBUG_TRIPLE_COLOR
12528         fprintf(stderr, "find_rhs_post_color(%p, %d) -> ( %d, %x)\n",
12529                 ins, index, info.reg, info.regcm);
12530 #endif
12531         return info;
12532 }
12533
12534 static struct reg_info find_lhs_color(
12535         struct compile_state *state, struct triple *ins, int index)
12536 {
12537         struct reg_info pre, post, info;
12538 #if DEBUG_TRIPLE_COLOR
12539         fprintf(stderr, "find_lhs_color(%p, %d)\n",
12540                 ins, index);
12541 #endif
12542         pre = find_lhs_pre_color(state, ins, index);
12543         post = find_lhs_post_color(state, ins, index);
12544         if ((pre.reg != post.reg) &&
12545                 (pre.reg != REG_UNSET) &&
12546                 (post.reg != REG_UNSET)) {
12547                 internal_error(state, ins, "register conflict");
12548         }
12549         info.regcm = pre.regcm & post.regcm;
12550         info.reg = pre.reg;
12551         if (info.reg == REG_UNSET) {
12552                 info.reg = post.reg;
12553         }
12554 #if DEBUG_TRIPLE_COLOR
12555         fprintf(stderr, "find_lhs_color(%p, %d) -> ( %d, %x) ... (%d, %x) (%d, %x)\n",
12556                 ins, index, info.reg, info.regcm,
12557                 pre.reg, pre.regcm, post.reg, post.regcm);
12558 #endif
12559         return info;
12560 }
12561
12562 static struct triple *post_copy(struct compile_state *state, struct triple *ins)
12563 {
12564         struct triple_set *entry, *next;
12565         struct triple *out;
12566         struct reg_info info, rinfo;
12567
12568         info = arch_reg_lhs(state, ins, 0);
12569         out = post_triple(state, ins, OP_COPY, ins->type, ins, 0);
12570         use_triple(RHS(out, 0), out);
12571         /* Get the users of ins to use out instead */
12572         for(entry = ins->use; entry; entry = next) {
12573                 int i;
12574                 next = entry->next;
12575                 if (entry->member == out) {
12576                         continue;
12577                 }
12578                 i = find_rhs_use(state, entry->member, ins);
12579                 if (i < 0) {
12580                         continue;
12581                 }
12582                 rinfo = arch_reg_rhs(state, entry->member, i);
12583                 if ((info.reg == REG_UNNEEDED) && (rinfo.reg == REG_UNNEEDED)) {
12584                         continue;
12585                 }
12586                 replace_rhs_use(state, ins, out, entry->member);
12587         }
12588         transform_to_arch_instruction(state, out);
12589         return out;
12590 }
12591
12592 static struct triple *typed_pre_copy(
12593         struct compile_state *state, struct type *type, struct triple *ins, int index)
12594 {
12595         /* Carefully insert enough operations so that I can
12596          * enter any operation with a GPR32.
12597          */
12598         struct triple *in;
12599         struct triple **expr;
12600         unsigned classes;
12601         struct reg_info info;
12602         if (ins->op == OP_PHI) {
12603                 internal_error(state, ins, "pre_copy on a phi?");
12604         }
12605         classes = arch_type_to_regcm(state, type);
12606         info = arch_reg_rhs(state, ins, index);
12607         expr = &RHS(ins, index);
12608         if ((info.regcm & classes) == 0) {
12609                 internal_error(state, ins, "pre_copy with no register classes");
12610         }
12611         in = pre_triple(state, ins, OP_COPY, type, *expr, 0);
12612         unuse_triple(*expr, ins);
12613         *expr = in;
12614         use_triple(RHS(in, 0), in);
12615         use_triple(in, ins);
12616         transform_to_arch_instruction(state, in);
12617         return in;
12618         
12619 }
12620 static struct triple *pre_copy(
12621         struct compile_state *state, struct triple *ins, int index)
12622 {
12623         return typed_pre_copy(state, RHS(ins, index)->type, ins, index);
12624 }
12625
12626
12627 static void insert_copies_to_phi(struct compile_state *state)
12628 {
12629         /* To get out of ssa form we insert moves on the incoming
12630          * edges to blocks containting phi functions.
12631          */
12632         struct triple *first;
12633         struct triple *phi;
12634
12635         /* Walk all of the operations to find the phi functions */
12636         first = state->first;
12637         for(phi = first->next; phi != first ; phi = phi->next) {
12638                 struct block_set *set;
12639                 struct block *block;
12640                 struct triple **slot, *copy;
12641                 int edge;
12642                 if (phi->op != OP_PHI) {
12643                         continue;
12644                 }
12645                 phi->id |= TRIPLE_FLAG_POST_SPLIT;
12646                 block = phi->u.block;
12647                 slot  = &RHS(phi, 0);
12648                 /* Phi's that feed into mandatory live range joins
12649                  * cause nasty complications.  Insert a copy of
12650                  * the phi value so I never have to deal with
12651                  * that in the rest of the code.
12652                  */
12653                 copy = post_copy(state, phi);
12654                 copy->id |= TRIPLE_FLAG_PRE_SPLIT;
12655                 /* Walk all of the incoming edges/blocks and insert moves.
12656                  */
12657                 for(edge = 0, set = block->use; set; set = set->next, edge++) {
12658                         struct block *eblock;
12659                         struct triple *move;
12660                         struct triple *val;
12661                         struct triple *ptr;
12662                         eblock = set->member;
12663                         val = slot[edge];
12664
12665                         if (val == phi) {
12666                                 continue;
12667                         }
12668
12669                         get_occurance(val->occurance);
12670                         move = build_triple(state, OP_COPY, phi->type, val, 0,
12671                                 val->occurance);
12672                         move->u.block = eblock;
12673                         move->id |= TRIPLE_FLAG_PRE_SPLIT;
12674                         use_triple(val, move);
12675                         
12676                         slot[edge] = move;
12677                         unuse_triple(val, phi);
12678                         use_triple(move, phi);
12679
12680                         /* Walk up the dominator tree until I have found the appropriate block */
12681                         while(eblock && !tdominates(state, val, eblock->last)) {
12682                                 eblock = eblock->idom;
12683                         }
12684                         if (!eblock) {
12685                                 internal_error(state, phi, "Cannot find block dominated by %p",
12686                                         val);
12687                         }
12688
12689                         /* Walk through the block backwards to find
12690                          * an appropriate location for the OP_COPY.
12691                          */
12692                         for(ptr = eblock->last; ptr != eblock->first; ptr = ptr->prev) {
12693                                 struct triple **expr;
12694                                 if ((ptr == phi) || (ptr == val)) {
12695                                         goto out;
12696                                 }
12697                                 expr = triple_rhs(state, ptr, 0);
12698                                 for(;expr; expr = triple_rhs(state, ptr, expr)) {
12699                                         if ((*expr) == phi) {
12700                                                 goto out;
12701                                         }
12702                                 }
12703                         }
12704                 out:
12705                         if (triple_is_branch(state, ptr)) {
12706                                 internal_error(state, ptr,
12707                                         "Could not insert write to phi");
12708                         }
12709                         insert_triple(state, ptr->next, move);
12710                         if (eblock->last == ptr) {
12711                                 eblock->last = move;
12712                         }
12713                         transform_to_arch_instruction(state, move);
12714                 }
12715         }
12716         print_blocks(state, __func__, stdout);
12717 }
12718
12719 struct triple_reg_set {
12720         struct triple_reg_set *next;
12721         struct triple *member;
12722         struct triple *new;
12723 };
12724
12725 struct reg_block {
12726         struct block *block;
12727         struct triple_reg_set *in;
12728         struct triple_reg_set *out;
12729         int vertex;
12730 };
12731
12732 static int do_triple_set(struct triple_reg_set **head, 
12733         struct triple *member, struct triple *new_member)
12734 {
12735         struct triple_reg_set **ptr, *new;
12736         if (!member)
12737                 return 0;
12738         ptr = head;
12739         while(*ptr) {
12740                 if ((*ptr)->member == member) {
12741                         return 0;
12742                 }
12743                 ptr = &(*ptr)->next;
12744         }
12745         new = xcmalloc(sizeof(*new), "triple_set");
12746         new->member = member;
12747         new->new    = new_member;
12748         new->next   = *head;
12749         *head       = new;
12750         return 1;
12751 }
12752
12753 static void do_triple_unset(struct triple_reg_set **head, struct triple *member)
12754 {
12755         struct triple_reg_set *entry, **ptr;
12756         ptr = head;
12757         while(*ptr) {
12758                 entry = *ptr;
12759                 if (entry->member == member) {
12760                         *ptr = entry->next;
12761                         xfree(entry);
12762                         return;
12763                 }
12764                 else {
12765                         ptr = &entry->next;
12766                 }
12767         }
12768 }
12769
12770 static int in_triple(struct reg_block *rb, struct triple *in)
12771 {
12772         return do_triple_set(&rb->in, in, 0);
12773 }
12774 static void unin_triple(struct reg_block *rb, struct triple *unin)
12775 {
12776         do_triple_unset(&rb->in, unin);
12777 }
12778
12779 static int out_triple(struct reg_block *rb, struct triple *out)
12780 {
12781         return do_triple_set(&rb->out, out, 0);
12782 }
12783 static void unout_triple(struct reg_block *rb, struct triple *unout)
12784 {
12785         do_triple_unset(&rb->out, unout);
12786 }
12787
12788 static int initialize_regblock(struct reg_block *blocks,
12789         struct block *block, int vertex)
12790 {
12791         struct block_set *user;
12792         if (!block || (blocks[block->vertex].block == block)) {
12793                 return vertex;
12794         }
12795         vertex += 1;
12796         /* Renumber the blocks in a convinient fashion */
12797         block->vertex = vertex;
12798         blocks[vertex].block    = block;
12799         blocks[vertex].vertex   = vertex;
12800         for(user = block->use; user; user = user->next) {
12801                 vertex = initialize_regblock(blocks, user->member, vertex);
12802         }
12803         return vertex;
12804 }
12805
12806 static int phi_in(struct compile_state *state, struct reg_block *blocks,
12807         struct reg_block *rb, struct block *suc)
12808 {
12809         /* Read the conditional input set of a successor block
12810          * (i.e. the input to the phi nodes) and place it in the
12811          * current blocks output set.
12812          */
12813         struct block_set *set;
12814         struct triple *ptr;
12815         int edge;
12816         int done, change;
12817         change = 0;
12818         /* Find the edge I am coming in on */
12819         for(edge = 0, set = suc->use; set; set = set->next, edge++) {
12820                 if (set->member == rb->block) {
12821                         break;
12822                 }
12823         }
12824         if (!set) {
12825                 internal_error(state, 0, "Not coming on a control edge?");
12826         }
12827         for(done = 0, ptr = suc->first; !done; ptr = ptr->next) {
12828                 struct triple **slot, *expr, *ptr2;
12829                 int out_change, done2;
12830                 done = (ptr == suc->last);
12831                 if (ptr->op != OP_PHI) {
12832                         continue;
12833                 }
12834                 slot = &RHS(ptr, 0);
12835                 expr = slot[edge];
12836                 out_change = out_triple(rb, expr);
12837                 if (!out_change) {
12838                         continue;
12839                 }
12840                 /* If we don't define the variable also plast it
12841                  * in the current blocks input set.
12842                  */
12843                 ptr2 = rb->block->first;
12844                 for(done2 = 0; !done2; ptr2 = ptr2->next) {
12845                         if (ptr2 == expr) {
12846                                 break;
12847                         }
12848                         done2 = (ptr2 == rb->block->last);
12849                 }
12850                 if (!done2) {
12851                         continue;
12852                 }
12853                 change |= in_triple(rb, expr);
12854         }
12855         return change;
12856 }
12857
12858 static int reg_in(struct compile_state *state, struct reg_block *blocks,
12859         struct reg_block *rb, struct block *suc)
12860 {
12861         struct triple_reg_set *in_set;
12862         int change;
12863         change = 0;
12864         /* Read the input set of a successor block
12865          * and place it in the current blocks output set.
12866          */
12867         in_set = blocks[suc->vertex].in;
12868         for(; in_set; in_set = in_set->next) {
12869                 int out_change, done;
12870                 struct triple *first, *last, *ptr;
12871                 out_change = out_triple(rb, in_set->member);
12872                 if (!out_change) {
12873                         continue;
12874                 }
12875                 /* If we don't define the variable also place it
12876                  * in the current blocks input set.
12877                  */
12878                 first = rb->block->first;
12879                 last = rb->block->last;
12880                 done = 0;
12881                 for(ptr = first; !done; ptr = ptr->next) {
12882                         if (ptr == in_set->member) {
12883                                 break;
12884                         }
12885                         done = (ptr == last);
12886                 }
12887                 if (!done) {
12888                         continue;
12889                 }
12890                 change |= in_triple(rb, in_set->member);
12891         }
12892         change |= phi_in(state, blocks, rb, suc);
12893         return change;
12894 }
12895
12896
12897 static int use_in(struct compile_state *state, struct reg_block *rb)
12898 {
12899         /* Find the variables we use but don't define and add
12900          * it to the current blocks input set.
12901          */
12902 #warning "FIXME is this O(N^2) algorithm bad?"
12903         struct block *block;
12904         struct triple *ptr;
12905         int done;
12906         int change;
12907         block = rb->block;
12908         change = 0;
12909         for(done = 0, ptr = block->last; !done; ptr = ptr->prev) {
12910                 struct triple **expr;
12911                 done = (ptr == block->first);
12912                 /* The variable a phi function uses depends on the
12913                  * control flow, and is handled in phi_in, not
12914                  * here.
12915                  */
12916                 if (ptr->op == OP_PHI) {
12917                         continue;
12918                 }
12919                 expr = triple_rhs(state, ptr, 0);
12920                 for(;expr; expr = triple_rhs(state, ptr, expr)) {
12921                         struct triple *rhs, *test;
12922                         int tdone;
12923                         rhs = *expr;
12924                         if (!rhs) {
12925                                 continue;
12926                         }
12927                         /* See if rhs is defined in this block */
12928                         for(tdone = 0, test = ptr; !tdone; test = test->prev) {
12929                                 tdone = (test == block->first);
12930                                 if (test == rhs) {
12931                                         rhs = 0;
12932                                         break;
12933                                 }
12934                         }
12935                         /* If I still have a valid rhs add it to in */
12936                         change |= in_triple(rb, rhs);
12937                 }
12938         }
12939         return change;
12940 }
12941
12942 static struct reg_block *compute_variable_lifetimes(
12943         struct compile_state *state)
12944 {
12945         struct reg_block *blocks;
12946         int change;
12947         blocks = xcmalloc(
12948                 sizeof(*blocks)*(state->last_vertex + 1), "reg_block");
12949         initialize_regblock(blocks, state->last_block, 0);
12950         do {
12951                 int i;
12952                 change = 0;
12953                 for(i = 1; i <= state->last_vertex; i++) {
12954                         struct block_set *edge;
12955                         struct reg_block *rb;
12956                         rb = &blocks[i];
12957                         /* Add the all successor's input set to in */
12958                         for(edge = rb->block->edges; edge; edge = edge->next) {
12959                                 change |= reg_in(state, blocks, rb, edge->member);
12960                         }
12961                         /* Add use to in... */
12962                         change |= use_in(state, rb);
12963                 }
12964         } while(change);
12965         return blocks;
12966 }
12967
12968 static void free_variable_lifetimes(
12969         struct compile_state *state, struct reg_block *blocks)
12970 {
12971         int i;
12972         /* free in_set && out_set on each block */
12973         for(i = 1; i <= state->last_vertex; i++) {
12974                 struct triple_reg_set *entry, *next;
12975                 struct reg_block *rb;
12976                 rb = &blocks[i];
12977                 for(entry = rb->in; entry ; entry = next) {
12978                         next = entry->next;
12979                         do_triple_unset(&rb->in, entry->member);
12980                 }
12981                 for(entry = rb->out; entry; entry = next) {
12982                         next = entry->next;
12983                         do_triple_unset(&rb->out, entry->member);
12984                 }
12985         }
12986         xfree(blocks);
12987
12988 }
12989
12990 typedef void (*wvl_cb_t)(
12991         struct compile_state *state, 
12992         struct reg_block *blocks, struct triple_reg_set *live, 
12993         struct reg_block *rb, struct triple *ins, void *arg);
12994
12995 static void walk_variable_lifetimes(struct compile_state *state,
12996         struct reg_block *blocks, wvl_cb_t cb, void *arg)
12997 {
12998         int i;
12999         
13000         for(i = 1; i <= state->last_vertex; i++) {
13001                 struct triple_reg_set *live;
13002                 struct triple_reg_set *entry, *next;
13003                 struct triple *ptr, *prev;
13004                 struct reg_block *rb;
13005                 struct block *block;
13006                 int done;
13007
13008                 /* Get the blocks */
13009                 rb = &blocks[i];
13010                 block = rb->block;
13011
13012                 /* Copy out into live */
13013                 live = 0;
13014                 for(entry = rb->out; entry; entry = next) {
13015                         next = entry->next;
13016                         do_triple_set(&live, entry->member, entry->new);
13017                 }
13018                 /* Walk through the basic block calculating live */
13019                 for(done = 0, ptr = block->last; !done; ptr = prev) {
13020                         struct triple **expr;
13021
13022                         prev = ptr->prev;
13023                         done = (ptr == block->first);
13024
13025                         /* Ensure the current definition is in live */
13026                         if (triple_is_def(state, ptr)) {
13027                                 do_triple_set(&live, ptr, 0);
13028                         }
13029
13030                         /* Inform the callback function of what is
13031                          * going on.
13032                          */
13033                          cb(state, blocks, live, rb, ptr, arg);
13034                         
13035                         /* Remove the current definition from live */
13036                         do_triple_unset(&live, ptr);
13037
13038                         /* Add the current uses to live.
13039                          *
13040                          * It is safe to skip phi functions because they do
13041                          * not have any block local uses, and the block
13042                          * output sets already properly account for what
13043                          * control flow depedent uses phi functions do have.
13044                          */
13045                         if (ptr->op == OP_PHI) {
13046                                 continue;
13047                         }
13048                         expr = triple_rhs(state, ptr, 0);
13049                         for(;expr; expr = triple_rhs(state, ptr, expr)) {
13050                                 /* If the triple is not a definition skip it. */
13051                                 if (!*expr || !triple_is_def(state, *expr)) {
13052                                         continue;
13053                                 }
13054                                 do_triple_set(&live, *expr, 0);
13055                         }
13056                 }
13057                 /* Free live */
13058                 for(entry = live; entry; entry = next) {
13059                         next = entry->next;
13060                         do_triple_unset(&live, entry->member);
13061                 }
13062         }
13063 }
13064
13065 static int count_triples(struct compile_state *state)
13066 {
13067         struct triple *first, *ins;
13068         int triples = 0;
13069         first = state->first;
13070         ins = first;
13071         do {
13072                 triples++;
13073                 ins = ins->next;
13074         } while (ins != first);
13075         return triples;
13076 }
13077
13078
13079 struct dead_triple {
13080         struct triple *triple;
13081         struct dead_triple *work_next;
13082         struct block *block;
13083         int old_id;
13084         int flags;
13085 #define TRIPLE_FLAG_ALIVE 1
13086 };
13087
13088
13089 static void awaken(
13090         struct compile_state *state,
13091         struct dead_triple *dtriple, struct triple **expr,
13092         struct dead_triple ***work_list_tail)
13093 {
13094         struct triple *triple;
13095         struct dead_triple *dt;
13096         if (!expr) {
13097                 return;
13098         }
13099         triple = *expr;
13100         if (!triple) {
13101                 return;
13102         }
13103         if (triple->id <= 0)  {
13104                 internal_error(state, triple, "bad triple id: %d",
13105                         triple->id);
13106         }
13107         if (triple->op == OP_NOOP) {
13108                 internal_error(state, triple, "awakening noop?");
13109                 return;
13110         }
13111         dt = &dtriple[triple->id];
13112         if (!(dt->flags & TRIPLE_FLAG_ALIVE)) {
13113                 dt->flags |= TRIPLE_FLAG_ALIVE;
13114                 if (!dt->work_next) {
13115                         **work_list_tail = dt;
13116                         *work_list_tail = &dt->work_next;
13117                 }
13118         }
13119 }
13120
13121 static void eliminate_inefectual_code(struct compile_state *state)
13122 {
13123         struct block *block;
13124         struct dead_triple *dtriple, *work_list, **work_list_tail, *dt;
13125         int triples, i;
13126         struct triple *first, *final, *ins;
13127
13128         if (!(state->compiler->flags & COMPILER_ELIMINATE_INEFECTUAL_CODE)) {
13129                 return;
13130         }
13131
13132         /* Setup the work list */
13133         work_list = 0;
13134         work_list_tail = &work_list;
13135
13136         first = state->first;
13137         final = state->first->prev;
13138
13139         /* Count how many triples I have */
13140         triples = count_triples(state);
13141
13142         /* Now put then in an array and mark all of the triples dead */
13143         dtriple = xcmalloc(sizeof(*dtriple) * (triples + 1), "dtriples");
13144         
13145         ins = first;
13146         i = 1;
13147         block = 0;
13148         do {
13149                 dtriple[i].triple = ins;
13150                 dtriple[i].block  = block_of_triple(state, ins);
13151                 dtriple[i].flags  = 0;
13152                 dtriple[i].old_id = ins->id;
13153                 ins->id = i;
13154                 /* See if it is an operation we always keep */
13155                 if (!triple_is_pure(state, ins, dtriple[i].old_id)) {
13156                         awaken(state, dtriple, &ins, &work_list_tail);
13157                 }
13158                 i++;
13159                 ins = ins->next;
13160         } while(ins != first);
13161         while(work_list) {
13162                 struct block *block;
13163                 struct dead_triple *dt;
13164                 struct block_set *user;
13165                 struct triple **expr;
13166                 dt = work_list;
13167                 work_list = dt->work_next;
13168                 if (!work_list) {
13169                         work_list_tail = &work_list;
13170                 }
13171                 /* Make certain the block the current instruction is in lives */
13172                 block = block_of_triple(state, dt->triple);
13173                 awaken(state, dtriple, &block->first, &work_list_tail);
13174                 if (triple_is_branch(state, block->last)) {
13175                         awaken(state, dtriple, &block->last, &work_list_tail);
13176                 }
13177
13178                 /* Wake up the data depencencies of this triple */
13179                 expr = 0;
13180                 do {
13181                         expr = triple_rhs(state, dt->triple, expr);
13182                         awaken(state, dtriple, expr, &work_list_tail);
13183                 } while(expr);
13184                 do {
13185                         expr = triple_lhs(state, dt->triple, expr);
13186                         awaken(state, dtriple, expr, &work_list_tail);
13187                 } while(expr);
13188                 do {
13189                         expr = triple_misc(state, dt->triple, expr);
13190                         awaken(state, dtriple, expr, &work_list_tail);
13191                 } while(expr);
13192                 /* Wake up the forward control dependencies */
13193                 do {
13194                         expr = triple_targ(state, dt->triple, expr);
13195                         awaken(state, dtriple, expr, &work_list_tail);
13196                 } while(expr);
13197                 /* Wake up the reverse control dependencies of this triple */
13198                 for(user = dt->block->ipdomfrontier; user; user = user->next) {
13199                         struct triple *last;
13200                         last = user->member->last;
13201                         while((last->op == OP_NOOP) && (last != user->member->first)) {
13202                                 internal_warning(state, last, "awakening noop?");
13203                                 last = last->prev;
13204                         }
13205                         awaken(state, dtriple, &last, &work_list_tail);
13206                 }
13207         }
13208         for(dt = &dtriple[1]; dt <= &dtriple[triples]; dt++) {
13209                 if ((dt->triple->op == OP_NOOP) && 
13210                         (dt->flags & TRIPLE_FLAG_ALIVE)) {
13211                         internal_error(state, dt->triple, "noop effective?");
13212                 }
13213                 dt->triple->id = dt->old_id;    /* Restore the color */
13214                 if (!(dt->flags & TRIPLE_FLAG_ALIVE)) {
13215                         release_triple(state, dt->triple);
13216                 }
13217         }
13218         xfree(dtriple);
13219
13220         rebuild_ssa_form(state);
13221
13222         print_blocks(state, __func__, stdout);
13223 }
13224
13225
13226 static void insert_mandatory_copies(struct compile_state *state)
13227 {
13228         struct triple *ins, *first;
13229
13230         /* The object is with a minimum of inserted copies,
13231          * to resolve in fundamental register conflicts between
13232          * register value producers and consumers.
13233          * Theoretically we may be greater than minimal when we
13234          * are inserting copies before instructions but that
13235          * case should be rare.
13236          */
13237         first = state->first;
13238         ins = first;
13239         do {
13240                 struct triple_set *entry, *next;
13241                 struct triple *tmp;
13242                 struct reg_info info;
13243                 unsigned reg, regcm;
13244                 int do_post_copy, do_pre_copy;
13245                 tmp = 0;
13246                 if (!triple_is_def(state, ins)) {
13247                         goto next;
13248                 }
13249                 /* Find the architecture specific color information */
13250                 info = arch_reg_lhs(state, ins, 0);
13251                 if (info.reg >= MAX_REGISTERS) {
13252                         info.reg = REG_UNSET;
13253                 }
13254                 
13255                 reg = REG_UNSET;
13256                 regcm = arch_type_to_regcm(state, ins->type);
13257                 do_post_copy = do_pre_copy = 0;
13258
13259                 /* Walk through the uses of ins and check for conflicts */
13260                 for(entry = ins->use; entry; entry = next) {
13261                         struct reg_info rinfo;
13262                         int i;
13263                         next = entry->next;
13264                         i = find_rhs_use(state, entry->member, ins);
13265                         if (i < 0) {
13266                                 continue;
13267                         }
13268                         
13269                         /* Find the users color requirements */
13270                         rinfo = arch_reg_rhs(state, entry->member, i);
13271                         if (rinfo.reg >= MAX_REGISTERS) {
13272                                 rinfo.reg = REG_UNSET;
13273                         }
13274                         
13275                         /* See if I need a pre_copy */
13276                         if (rinfo.reg != REG_UNSET) {
13277                                 if ((reg != REG_UNSET) && (reg != rinfo.reg)) {
13278                                         do_pre_copy = 1;
13279                                 }
13280                                 reg = rinfo.reg;
13281                         }
13282                         regcm &= rinfo.regcm;
13283                         regcm = arch_regcm_normalize(state, regcm);
13284                         if (regcm == 0) {
13285                                 do_pre_copy = 1;
13286                         }
13287                         /* Always use pre_copies for constants.
13288                          * They do not take up any registers until a
13289                          * copy places them in one.
13290                          */
13291                         if ((info.reg == REG_UNNEEDED) && 
13292                                 (rinfo.reg != REG_UNNEEDED)) {
13293                                 do_pre_copy = 1;
13294                         }
13295                 }
13296                 do_post_copy =
13297                         !do_pre_copy &&
13298                         (((info.reg != REG_UNSET) && 
13299                                 (reg != REG_UNSET) &&
13300                                 (info.reg != reg)) ||
13301                         ((info.regcm & regcm) == 0));
13302
13303                 reg = info.reg;
13304                 regcm = info.regcm;
13305                 /* Walk through the uses of ins and do a pre_copy or see if a post_copy is warranted */
13306                 for(entry = ins->use; entry; entry = next) {
13307                         struct reg_info rinfo;
13308                         int i;
13309                         next = entry->next;
13310                         i = find_rhs_use(state, entry->member, ins);
13311                         if (i < 0) {
13312                                 continue;
13313                         }
13314                         
13315                         /* Find the users color requirements */
13316                         rinfo = arch_reg_rhs(state, entry->member, i);
13317                         if (rinfo.reg >= MAX_REGISTERS) {
13318                                 rinfo.reg = REG_UNSET;
13319                         }
13320
13321                         /* Now see if it is time to do the pre_copy */
13322                         if (rinfo.reg != REG_UNSET) {
13323                                 if (((reg != REG_UNSET) && (reg != rinfo.reg)) ||
13324                                         ((regcm & rinfo.regcm) == 0) ||
13325                                         /* Don't let a mandatory coalesce sneak
13326                                          * into a operation that is marked to prevent
13327                                          * coalescing.
13328                                          */
13329                                         ((reg != REG_UNNEEDED) &&
13330                                         ((ins->id & TRIPLE_FLAG_POST_SPLIT) ||
13331                                         (entry->member->id & TRIPLE_FLAG_PRE_SPLIT)))
13332                                         ) {
13333                                         if (do_pre_copy) {
13334                                                 struct triple *user;
13335                                                 user = entry->member;
13336                                                 if (RHS(user, i) != ins) {
13337                                                         internal_error(state, user, "bad rhs");
13338                                                 }
13339                                                 tmp = pre_copy(state, user, i);
13340                                                 tmp->id |= TRIPLE_FLAG_PRE_SPLIT;
13341                                                 continue;
13342                                         } else {
13343                                                 do_post_copy = 1;
13344                                         }
13345                                 }
13346                                 reg = rinfo.reg;
13347                         }
13348                         if ((regcm & rinfo.regcm) == 0) {
13349                                 if (do_pre_copy) {
13350                                         struct triple *user;
13351                                         user = entry->member;
13352                                         if (RHS(user, i) != ins) {
13353                                                 internal_error(state, user, "bad rhs");
13354                                         }
13355                                         tmp = pre_copy(state, user, i);
13356                                         tmp->id |= TRIPLE_FLAG_PRE_SPLIT;
13357                                         continue;
13358                                 } else {
13359                                         do_post_copy = 1;
13360                                 }
13361                         }
13362                         regcm &= rinfo.regcm;
13363                         
13364                 }
13365                 if (do_post_copy) {
13366                         struct reg_info pre, post;
13367                         tmp = post_copy(state, ins);
13368                         tmp->id |= TRIPLE_FLAG_PRE_SPLIT;
13369                         pre = arch_reg_lhs(state, ins, 0);
13370                         post = arch_reg_lhs(state, tmp, 0);
13371                         if ((pre.reg == post.reg) && (pre.regcm == post.regcm)) {
13372                                 internal_error(state, tmp, "useless copy");
13373                         }
13374                 }
13375         next:
13376                 ins = ins->next;
13377         } while(ins != first);
13378
13379         print_blocks(state, __func__, stdout);
13380 }
13381
13382
13383 struct live_range_edge;
13384 struct live_range_def;
13385 struct live_range {
13386         struct live_range_edge *edges;
13387         struct live_range_def *defs;
13388 /* Note. The list pointed to by defs is kept in order.
13389  * That is baring splits in the flow control
13390  * defs dominates defs->next wich dominates defs->next->next
13391  * etc.
13392  */
13393         unsigned color;
13394         unsigned classes;
13395         unsigned degree;
13396         unsigned length;
13397         struct live_range *group_next, **group_prev;
13398 };
13399
13400 struct live_range_edge {
13401         struct live_range_edge *next;
13402         struct live_range *node;
13403 };
13404
13405 struct live_range_def {
13406         struct live_range_def *next;
13407         struct live_range_def *prev;
13408         struct live_range *lr;
13409         struct triple *def;
13410         unsigned orig_id;
13411 };
13412
13413 #define LRE_HASH_SIZE 2048
13414 struct lre_hash {
13415         struct lre_hash *next;
13416         struct live_range *left;
13417         struct live_range *right;
13418 };
13419
13420
13421 struct reg_state {
13422         struct lre_hash *hash[LRE_HASH_SIZE];
13423         struct reg_block *blocks;
13424         struct live_range_def *lrd;
13425         struct live_range *lr;
13426         struct live_range *low, **low_tail;
13427         struct live_range *high, **high_tail;
13428         unsigned defs;
13429         unsigned ranges;
13430         int passes, max_passes;
13431 };
13432
13433
13434
13435 struct print_interference_block_info {
13436         struct reg_state *rstate;
13437         FILE *fp;
13438         int need_edges;
13439 };
13440 static void print_interference_block(
13441         struct compile_state *state, struct block *block, void *arg)
13442
13443 {
13444         struct print_interference_block_info *info = arg;
13445         struct reg_state *rstate = info->rstate;
13446         struct block_set *edge;
13447         FILE *fp = info->fp;
13448         struct reg_block *rb;
13449         struct triple *ptr;
13450         int phi_present;
13451         int done;
13452         rb = &rstate->blocks[block->vertex];
13453
13454         fprintf(fp, "\nblock: %p (%d),",
13455                 block,  block->vertex);
13456         for(edge = block->edges; edge; edge = edge->next) {
13457                 fprintf(fp, " %p<-%p",
13458                         edge->member, 
13459                         edge->member && edge->member->use?edge->member->use->member : 0);
13460         }
13461         fprintf(fp, "\n");
13462         if (rb->in) {
13463                 struct triple_reg_set *in_set;
13464                 fprintf(fp, "        in:");
13465                 for(in_set = rb->in; in_set; in_set = in_set->next) {
13466                         fprintf(fp, " %-10p", in_set->member);
13467                 }
13468                 fprintf(fp, "\n");
13469         }
13470         phi_present = 0;
13471         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
13472                 done = (ptr == block->last);
13473                 if (ptr->op == OP_PHI) {
13474                         phi_present = 1;
13475                         break;
13476                 }
13477         }
13478         if (phi_present) {
13479                 int edge;
13480                 for(edge = 0; edge < block->users; edge++) {
13481                         fprintf(fp, "     in(%d):", edge);
13482                         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
13483                                 struct triple **slot;
13484                                 done = (ptr == block->last);
13485                                 if (ptr->op != OP_PHI) {
13486                                         continue;
13487                                 }
13488                                 slot = &RHS(ptr, 0);
13489                                 fprintf(fp, " %-10p", slot[edge]);
13490                         }
13491                         fprintf(fp, "\n");
13492                 }
13493         }
13494         if (block->first->op == OP_LABEL) {
13495                 fprintf(fp, "%p:\n", block->first);
13496         }
13497         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
13498                 struct live_range *lr;
13499                 unsigned id;
13500                 int op;
13501                 op = ptr->op;
13502                 done = (ptr == block->last);
13503                 lr = rstate->lrd[ptr->id].lr;
13504                 
13505                 id = ptr->id;
13506                 ptr->id = rstate->lrd[id].orig_id;
13507                 SET_REG(ptr->id, lr->color);
13508                 display_triple(fp, ptr);
13509                 ptr->id = id;
13510
13511                 if (triple_is_def(state, ptr) && (lr->defs == 0)) {
13512                         internal_error(state, ptr, "lr has no defs!");
13513                 }
13514                 if (info->need_edges) {
13515                         if (lr->defs) {
13516                                 struct live_range_def *lrd;
13517                                 fprintf(fp, "       range:");
13518                                 lrd = lr->defs;
13519                                 do {
13520                                         fprintf(fp, " %-10p", lrd->def);
13521                                         lrd = lrd->next;
13522                                 } while(lrd != lr->defs);
13523                                 fprintf(fp, "\n");
13524                         }
13525                         if (lr->edges > 0) {
13526                                 struct live_range_edge *edge;
13527                                 fprintf(fp, "       edges:");
13528                                 for(edge = lr->edges; edge; edge = edge->next) {
13529                                         struct live_range_def *lrd;
13530                                         lrd = edge->node->defs;
13531                                         do {
13532                                                 fprintf(fp, " %-10p", lrd->def);
13533                                                 lrd = lrd->next;
13534                                         } while(lrd != edge->node->defs);
13535                                         fprintf(fp, "|");
13536                                 }
13537                                 fprintf(fp, "\n");
13538                         }
13539                 }
13540                 /* Do a bunch of sanity checks */
13541                 valid_ins(state, ptr);
13542                 if ((ptr->id < 0) || (ptr->id > rstate->defs)) {
13543                         internal_error(state, ptr, "Invalid triple id: %d",
13544                                 ptr->id);
13545                 }
13546         }
13547         if (rb->out) {
13548                 struct triple_reg_set *out_set;
13549                 fprintf(fp, "       out:");
13550                 for(out_set = rb->out; out_set; out_set = out_set->next) {
13551                         fprintf(fp, " %-10p", out_set->member);
13552                 }
13553                 fprintf(fp, "\n");
13554         }
13555         fprintf(fp, "\n");
13556 }
13557
13558 static void print_interference_blocks(
13559         struct compile_state *state, struct reg_state *rstate, FILE *fp, int need_edges)
13560 {
13561         struct print_interference_block_info info;
13562         info.rstate = rstate;
13563         info.fp = fp;
13564         info.need_edges = need_edges;
13565         fprintf(fp, "\nlive variables by block\n");
13566         walk_blocks(state, print_interference_block, &info);
13567
13568 }
13569
13570 static unsigned regc_max_size(struct compile_state *state, int classes)
13571 {
13572         unsigned max_size;
13573         int i;
13574         max_size = 0;
13575         for(i = 0; i < MAX_REGC; i++) {
13576                 if (classes & (1 << i)) {
13577                         unsigned size;
13578                         size = arch_regc_size(state, i);
13579                         if (size > max_size) {
13580                                 max_size = size;
13581                         }
13582                 }
13583         }
13584         return max_size;
13585 }
13586
13587 static int reg_is_reg(struct compile_state *state, int reg1, int reg2)
13588 {
13589         unsigned equivs[MAX_REG_EQUIVS];
13590         int i;
13591         if ((reg1 < 0) || (reg1 >= MAX_REGISTERS)) {
13592                 internal_error(state, 0, "invalid register");
13593         }
13594         if ((reg2 < 0) || (reg2 >= MAX_REGISTERS)) {
13595                 internal_error(state, 0, "invalid register");
13596         }
13597         arch_reg_equivs(state, equivs, reg1);
13598         for(i = 0; (i < MAX_REG_EQUIVS) && equivs[i] != REG_UNSET; i++) {
13599                 if (equivs[i] == reg2) {
13600                         return 1;
13601                 }
13602         }
13603         return 0;
13604 }
13605
13606 static void reg_fill_used(struct compile_state *state, char *used, int reg)
13607 {
13608         unsigned equivs[MAX_REG_EQUIVS];
13609         int i;
13610         if (reg == REG_UNNEEDED) {
13611                 return;
13612         }
13613         arch_reg_equivs(state, equivs, reg);
13614         for(i = 0; (i < MAX_REG_EQUIVS) && equivs[i] != REG_UNSET; i++) {
13615                 used[equivs[i]] = 1;
13616         }
13617         return;
13618 }
13619
13620 static void reg_inc_used(struct compile_state *state, char *used, int reg)
13621 {
13622         unsigned equivs[MAX_REG_EQUIVS];
13623         int i;
13624         if (reg == REG_UNNEEDED) {
13625                 return;
13626         }
13627         arch_reg_equivs(state, equivs, reg);
13628         for(i = 0; (i < MAX_REG_EQUIVS) && equivs[i] != REG_UNSET; i++) {
13629                 used[equivs[i]] += 1;
13630         }
13631         return;
13632 }
13633
13634 static unsigned int hash_live_edge(
13635         struct live_range *left, struct live_range *right)
13636 {
13637         unsigned int hash, val;
13638         unsigned long lval, rval;
13639         lval = ((unsigned long)left)/sizeof(struct live_range);
13640         rval = ((unsigned long)right)/sizeof(struct live_range);
13641         hash = 0;
13642         while(lval) {
13643                 val = lval & 0xff;
13644                 lval >>= 8;
13645                 hash = (hash *263) + val;
13646         }
13647         while(rval) {
13648                 val = rval & 0xff;
13649                 rval >>= 8;
13650                 hash = (hash *263) + val;
13651         }
13652         hash = hash & (LRE_HASH_SIZE - 1);
13653         return hash;
13654 }
13655
13656 static struct lre_hash **lre_probe(struct reg_state *rstate,
13657         struct live_range *left, struct live_range *right)
13658 {
13659         struct lre_hash **ptr;
13660         unsigned int index;
13661         /* Ensure left <= right */
13662         if (left > right) {
13663                 struct live_range *tmp;
13664                 tmp = left;
13665                 left = right;
13666                 right = tmp;
13667         }
13668         index = hash_live_edge(left, right);
13669         
13670         ptr = &rstate->hash[index];
13671         while(*ptr) {
13672                 if (((*ptr)->left == left) && ((*ptr)->right == right)) {
13673                         break;
13674                 }
13675                 ptr = &(*ptr)->next;
13676         }
13677         return ptr;
13678 }
13679
13680 static int interfere(struct reg_state *rstate,
13681         struct live_range *left, struct live_range *right)
13682 {
13683         struct lre_hash **ptr;
13684         ptr = lre_probe(rstate, left, right);
13685         return ptr && *ptr;
13686 }
13687
13688 static void add_live_edge(struct reg_state *rstate, 
13689         struct live_range *left, struct live_range *right)
13690 {
13691         /* FIXME the memory allocation overhead is noticeable here... */
13692         struct lre_hash **ptr, *new_hash;
13693         struct live_range_edge *edge;
13694
13695         if (left == right) {
13696                 return;
13697         }
13698         if ((left == &rstate->lr[0]) || (right == &rstate->lr[0])) {
13699                 return;
13700         }
13701         /* Ensure left <= right */
13702         if (left > right) {
13703                 struct live_range *tmp;
13704                 tmp = left;
13705                 left = right;
13706                 right = tmp;
13707         }
13708         ptr = lre_probe(rstate, left, right);
13709         if (*ptr) {
13710                 return;
13711         }
13712 #if 0
13713         fprintf(stderr, "new_live_edge(%p, %p)\n",
13714                 left, right);
13715 #endif
13716         new_hash = xmalloc(sizeof(*new_hash), "lre_hash");
13717         new_hash->next  = *ptr;
13718         new_hash->left  = left;
13719         new_hash->right = right;
13720         *ptr = new_hash;
13721
13722         edge = xmalloc(sizeof(*edge), "live_range_edge");
13723         edge->next   = left->edges;
13724         edge->node   = right;
13725         left->edges  = edge;
13726         left->degree += 1;
13727         
13728         edge = xmalloc(sizeof(*edge), "live_range_edge");
13729         edge->next    = right->edges;
13730         edge->node    = left;
13731         right->edges  = edge;
13732         right->degree += 1;
13733 }
13734
13735 static void remove_live_edge(struct reg_state *rstate,
13736         struct live_range *left, struct live_range *right)
13737 {
13738         struct live_range_edge *edge, **ptr;
13739         struct lre_hash **hptr, *entry;
13740         hptr = lre_probe(rstate, left, right);
13741         if (!hptr || !*hptr) {
13742                 return;
13743         }
13744         entry = *hptr;
13745         *hptr = entry->next;
13746         xfree(entry);
13747
13748         for(ptr = &left->edges; *ptr; ptr = &(*ptr)->next) {
13749                 edge = *ptr;
13750                 if (edge->node == right) {
13751                         *ptr = edge->next;
13752                         memset(edge, 0, sizeof(*edge));
13753                         xfree(edge);
13754                         right->degree--;
13755                         break;
13756                 }
13757         }
13758         for(ptr = &right->edges; *ptr; ptr = &(*ptr)->next) {
13759                 edge = *ptr;
13760                 if (edge->node == left) {
13761                         *ptr = edge->next;
13762                         memset(edge, 0, sizeof(*edge));
13763                         xfree(edge);
13764                         left->degree--;
13765                         break;
13766                 }
13767         }
13768 }
13769
13770 static void remove_live_edges(struct reg_state *rstate, struct live_range *range)
13771 {
13772         struct live_range_edge *edge, *next;
13773         for(edge = range->edges; edge; edge = next) {
13774                 next = edge->next;
13775                 remove_live_edge(rstate, range, edge->node);
13776         }
13777 }
13778
13779 static void transfer_live_edges(struct reg_state *rstate, 
13780         struct live_range *dest, struct live_range *src)
13781 {
13782         struct live_range_edge *edge, *next;
13783         for(edge = src->edges; edge; edge = next) {
13784                 struct live_range *other;
13785                 next = edge->next;
13786                 other = edge->node;
13787                 remove_live_edge(rstate, src, other);
13788                 add_live_edge(rstate, dest, other);
13789         }
13790 }
13791
13792
13793 /* Interference graph...
13794  * 
13795  * new(n) --- Return a graph with n nodes but no edges.
13796  * add(g,x,y) --- Return a graph including g with an between x and y
13797  * interfere(g, x, y) --- Return true if there exists an edge between the nodes
13798  *                x and y in the graph g
13799  * degree(g, x) --- Return the degree of the node x in the graph g
13800  * neighbors(g, x, f) --- Apply function f to each neighbor of node x in the graph g
13801  *
13802  * Implement with a hash table && a set of adjcency vectors.
13803  * The hash table supports constant time implementations of add and interfere.
13804  * The adjacency vectors support an efficient implementation of neighbors.
13805  */
13806
13807 /* 
13808  *     +---------------------------------------------------+
13809  *     |         +--------------+                          |
13810  *     v         v              |                          |
13811  * renumber -> build graph -> colalesce -> spill_costs -> simplify -> select 
13812  *
13813  * -- In simplify implment optimistic coloring... (No backtracking)
13814  * -- Implement Rematerialization it is the only form of spilling we can perform
13815  *    Essentially this means dropping a constant from a register because
13816  *    we can regenerate it later.
13817  *
13818  * --- Very conservative colalescing (don't colalesce just mark the opportunities)
13819  *     coalesce at phi points...
13820  * --- Bias coloring if at all possible do the coalesing a compile time.
13821  *
13822  *
13823  */
13824
13825 static void different_colored(
13826         struct compile_state *state, struct reg_state *rstate, 
13827         struct triple *parent, struct triple *ins)
13828 {
13829         struct live_range *lr;
13830         struct triple **expr;
13831         lr = rstate->lrd[ins->id].lr;
13832         expr = triple_rhs(state, ins, 0);
13833         for(;expr; expr = triple_rhs(state, ins, expr)) {
13834                 struct live_range *lr2;
13835                 if (!*expr || (*expr == parent) || (*expr == ins)) {
13836                         continue;
13837                 }
13838                 lr2 = rstate->lrd[(*expr)->id].lr;
13839                 if (lr->color == lr2->color) {
13840                         internal_error(state, ins, "live range too big");
13841                 }
13842         }
13843 }
13844
13845
13846 static struct live_range *coalesce_ranges(
13847         struct compile_state *state, struct reg_state *rstate,
13848         struct live_range *lr1, struct live_range *lr2)
13849 {
13850         struct live_range_def *head, *mid1, *mid2, *end, *lrd;
13851         unsigned color;
13852         unsigned classes;
13853         if (lr1 == lr2) {
13854                 return lr1;
13855         }
13856         if (!lr1->defs || !lr2->defs) {
13857                 internal_error(state, 0,
13858                         "cannot coalese dead live ranges");
13859         }
13860         if ((lr1->color == REG_UNNEEDED) ||
13861                 (lr2->color == REG_UNNEEDED)) {
13862                 internal_error(state, 0, 
13863                         "cannot coalesce live ranges without a possible color");
13864         }
13865         if ((lr1->color != lr2->color) &&
13866                 (lr1->color != REG_UNSET) &&
13867                 (lr2->color != REG_UNSET)) {
13868                 internal_error(state, lr1->defs->def, 
13869                         "cannot coalesce live ranges of different colors");
13870         }
13871         color = lr1->color;
13872         if (color == REG_UNSET) {
13873                 color = lr2->color;
13874         }
13875         classes = lr1->classes & lr2->classes;
13876         if (!classes) {
13877                 internal_error(state, lr1->defs->def,
13878                         "cannot coalesce live ranges with dissimilar register classes");
13879         }
13880         if (state->compiler->debug & DEBUG_COALESCING) {
13881                 fprintf(stderr, "coalescing:");
13882                 lrd = lr1->defs;
13883                 do {
13884                         fprintf(stderr, " %p", lrd->def);
13885                         lrd = lrd->next;
13886                 } while(lrd != lr1->defs);
13887                 fprintf(stderr, " |");
13888                 lrd = lr2->defs;
13889                 do {
13890                         fprintf(stderr, " %p", lrd->def);
13891                         lrd = lrd->next;
13892                 } while(lrd != lr2->defs);
13893                 fprintf(stderr, "\n");
13894         }
13895         /* If there is a clear dominate live range put it in lr1,
13896          * For purposes of this test phi functions are
13897          * considered dominated by the definitions that feed into
13898          * them. 
13899          */
13900         if ((lr1->defs->prev->def->op == OP_PHI) ||
13901                 ((lr2->defs->prev->def->op != OP_PHI) &&
13902                 tdominates(state, lr2->defs->def, lr1->defs->def))) {
13903                 struct live_range *tmp;
13904                 tmp = lr1;
13905                 lr1 = lr2;
13906                 lr2 = tmp;
13907         }
13908 #if 0
13909         if (lr1->defs->orig_id  & TRIPLE_FLAG_POST_SPLIT) {
13910                 fprintf(stderr, "lr1 post\n");
13911         }
13912         if (lr1->defs->orig_id & TRIPLE_FLAG_PRE_SPLIT) {
13913                 fprintf(stderr, "lr1 pre\n");
13914         }
13915         if (lr2->defs->orig_id  & TRIPLE_FLAG_POST_SPLIT) {
13916                 fprintf(stderr, "lr2 post\n");
13917         }
13918         if (lr2->defs->orig_id & TRIPLE_FLAG_PRE_SPLIT) {
13919                 fprintf(stderr, "lr2 pre\n");
13920         }
13921 #endif
13922 #if 0
13923         fprintf(stderr, "coalesce color1(%p): %3d color2(%p) %3d\n",
13924                 lr1->defs->def,
13925                 lr1->color,
13926                 lr2->defs->def,
13927                 lr2->color);
13928 #endif
13929         
13930         /* Append lr2 onto lr1 */
13931 #warning "FIXME should this be a merge instead of a splice?"
13932         /* This FIXME item applies to the correctness of live_range_end 
13933          * and to the necessity of making multiple passes of coalesce_live_ranges.
13934          * A failure to find some coalesce opportunities in coaleace_live_ranges
13935          * does not impact the correct of the compiler just the efficiency with
13936          * which registers are allocated.
13937          */
13938         head = lr1->defs;
13939         mid1 = lr1->defs->prev;
13940         mid2 = lr2->defs;
13941         end  = lr2->defs->prev;
13942         
13943         head->prev = end;
13944         end->next  = head;
13945
13946         mid1->next = mid2;
13947         mid2->prev = mid1;
13948
13949         /* Fixup the live range in the added live range defs */
13950         lrd = head;
13951         do {
13952                 lrd->lr = lr1;
13953                 lrd = lrd->next;
13954         } while(lrd != head);
13955
13956         /* Mark lr2 as free. */
13957         lr2->defs = 0;
13958         lr2->color = REG_UNNEEDED;
13959         lr2->classes = 0;
13960
13961         if (!lr1->defs) {
13962                 internal_error(state, 0, "lr1->defs == 0 ?");
13963         }
13964
13965         lr1->color   = color;
13966         lr1->classes = classes;
13967
13968         /* Keep the graph in sync by transfering the edges from lr2 to lr1 */
13969         transfer_live_edges(rstate, lr1, lr2);
13970
13971         return lr1;
13972 }
13973
13974 static struct live_range_def *live_range_head(
13975         struct compile_state *state, struct live_range *lr,
13976         struct live_range_def *last)
13977 {
13978         struct live_range_def *result;
13979         result = 0;
13980         if (last == 0) {
13981                 result = lr->defs;
13982         }
13983         else if (!tdominates(state, lr->defs->def, last->next->def)) {
13984                 result = last->next;
13985         }
13986         return result;
13987 }
13988
13989 static struct live_range_def *live_range_end(
13990         struct compile_state *state, struct live_range *lr,
13991         struct live_range_def *last)
13992 {
13993         struct live_range_def *result;
13994         result = 0;
13995         if (last == 0) {
13996                 result = lr->defs->prev;
13997         }
13998         else if (!tdominates(state, last->prev->def, lr->defs->prev->def)) {
13999                 result = last->prev;
14000         }
14001         return result;
14002 }
14003
14004
14005 static void initialize_live_ranges(
14006         struct compile_state *state, struct reg_state *rstate)
14007 {
14008         struct triple *ins, *first;
14009         size_t count, size;
14010         int i, j;
14011
14012         first = state->first;
14013         /* First count how many instructions I have.
14014          */
14015         count = count_triples(state);
14016         /* Potentially I need one live range definitions for each
14017          * instruction.
14018          */
14019         rstate->defs = count;
14020         /* Potentially I need one live range for each instruction
14021          * plus an extra for the dummy live range.
14022          */
14023         rstate->ranges = count + 1;
14024         size = sizeof(rstate->lrd[0]) * rstate->defs;
14025         rstate->lrd = xcmalloc(size, "live_range_def");
14026         size = sizeof(rstate->lr[0]) * rstate->ranges;
14027         rstate->lr  = xcmalloc(size, "live_range");
14028
14029         /* Setup the dummy live range */
14030         rstate->lr[0].classes = 0;
14031         rstate->lr[0].color = REG_UNSET;
14032         rstate->lr[0].defs = 0;
14033         i = j = 0;
14034         ins = first;
14035         do {
14036                 /* If the triple is a variable give it a live range */
14037                 if (triple_is_def(state, ins)) {
14038                         struct reg_info info;
14039                         /* Find the architecture specific color information */
14040                         info = find_def_color(state, ins);
14041                         i++;
14042                         rstate->lr[i].defs    = &rstate->lrd[j];
14043                         rstate->lr[i].color   = info.reg;
14044                         rstate->lr[i].classes = info.regcm;
14045                         rstate->lr[i].degree  = 0;
14046                         rstate->lrd[j].lr = &rstate->lr[i];
14047                 } 
14048                 /* Otherwise give the triple the dummy live range. */
14049                 else {
14050                         rstate->lrd[j].lr = &rstate->lr[0];
14051                 }
14052
14053                 /* Initalize the live_range_def */
14054                 rstate->lrd[j].next    = &rstate->lrd[j];
14055                 rstate->lrd[j].prev    = &rstate->lrd[j];
14056                 rstate->lrd[j].def     = ins;
14057                 rstate->lrd[j].orig_id = ins->id;
14058                 ins->id = j;
14059
14060                 j++;
14061                 ins = ins->next;
14062         } while(ins != first);
14063         rstate->ranges = i;
14064
14065         /* Make a second pass to handle achitecture specific register
14066          * constraints.
14067          */
14068         ins = first;
14069         do {
14070                 int zlhs, zrhs, i, j;
14071                 if (ins->id > rstate->defs) {
14072                         internal_error(state, ins, "bad id");
14073                 }
14074                 
14075                 /* Walk through the template of ins and coalesce live ranges */
14076                 zlhs = TRIPLE_LHS(ins->sizes);
14077                 if ((zlhs == 0) && triple_is_def(state, ins)) {
14078                         zlhs = 1;
14079                 }
14080                 zrhs = TRIPLE_RHS(ins->sizes);
14081
14082                 if (state->compiler->debug & DEBUG_COALESCING2) {
14083                         fprintf(stderr, "mandatory coalesce: %p %d %d\n",
14084                                 ins, zlhs, zrhs);
14085                 }
14086
14087                 for(i = 0; i < zlhs; i++) {
14088                         struct reg_info linfo;
14089                         struct live_range_def *lhs;
14090                         linfo = arch_reg_lhs(state, ins, i);
14091                         if (linfo.reg < MAX_REGISTERS) {
14092                                 continue;
14093                         }
14094                         if (triple_is_def(state, ins)) {
14095                                 lhs = &rstate->lrd[ins->id];
14096                         } else {
14097                                 lhs = &rstate->lrd[LHS(ins, i)->id];
14098                         }
14099
14100                         if (state->compiler->debug & DEBUG_COALESCING2) {
14101                                 fprintf(stderr, "coalesce lhs(%d): %p %d\n",
14102                                         i, lhs, linfo.reg);
14103                         }
14104
14105                         for(j = 0; j < zrhs; j++) {
14106                                 struct reg_info rinfo;
14107                                 struct live_range_def *rhs;
14108                                 rinfo = arch_reg_rhs(state, ins, j);
14109                                 if (rinfo.reg < MAX_REGISTERS) {
14110                                         continue;
14111                                 }
14112                                 rhs = &rstate->lrd[RHS(ins, j)->id];
14113
14114                                 if (state->compiler->debug & DEBUG_COALESCING2) {
14115                                         fprintf(stderr, "coalesce rhs(%d): %p %d\n",
14116                                                 j, rhs, rinfo.reg);
14117                                 }
14118
14119                                 if (rinfo.reg == linfo.reg) {
14120                                         coalesce_ranges(state, rstate, 
14121                                                 lhs->lr, rhs->lr);
14122                                 }
14123                         }
14124                 }
14125                 ins = ins->next;
14126         } while(ins != first);
14127 }
14128
14129 static void graph_ins(
14130         struct compile_state *state, 
14131         struct reg_block *blocks, struct triple_reg_set *live, 
14132         struct reg_block *rb, struct triple *ins, void *arg)
14133 {
14134         struct reg_state *rstate = arg;
14135         struct live_range *def;
14136         struct triple_reg_set *entry;
14137
14138         /* If the triple is not a definition
14139          * we do not have a definition to add to
14140          * the interference graph.
14141          */
14142         if (!triple_is_def(state, ins)) {
14143                 return;
14144         }
14145         def = rstate->lrd[ins->id].lr;
14146         
14147         /* Create an edge between ins and everything that is
14148          * alive, unless the live_range cannot share
14149          * a physical register with ins.
14150          */
14151         for(entry = live; entry; entry = entry->next) {
14152                 struct live_range *lr;
14153                 if ((entry->member->id < 0) || (entry->member->id > rstate->defs)) {
14154                         internal_error(state, 0, "bad entry?");
14155                 }
14156                 lr = rstate->lrd[entry->member->id].lr;
14157                 if (def == lr) {
14158                         continue;
14159                 }
14160                 if (!arch_regcm_intersect(def->classes, lr->classes)) {
14161                         continue;
14162                 }
14163                 add_live_edge(rstate, def, lr);
14164         }
14165         return;
14166 }
14167
14168 static struct live_range *get_verify_live_range(
14169         struct compile_state *state, struct reg_state *rstate, struct triple *ins)
14170 {
14171         struct live_range *lr;
14172         struct live_range_def *lrd;
14173         int ins_found;
14174         if ((ins->id < 0) || (ins->id > rstate->defs)) {
14175                 internal_error(state, ins, "bad ins?");
14176         }
14177         lr = rstate->lrd[ins->id].lr;
14178         ins_found = 0;
14179         lrd = lr->defs;
14180         do {
14181                 if (lrd->def == ins) {
14182                         ins_found = 1;
14183                 }
14184                 lrd = lrd->next;
14185         } while(lrd != lr->defs);
14186         if (!ins_found) {
14187                 internal_error(state, ins, "ins not in live range");
14188         }
14189         return lr;
14190 }
14191
14192 static void verify_graph_ins(
14193         struct compile_state *state, 
14194         struct reg_block *blocks, struct triple_reg_set *live, 
14195         struct reg_block *rb, struct triple *ins, void *arg)
14196 {
14197         struct reg_state *rstate = arg;
14198         struct triple_reg_set *entry1, *entry2;
14199
14200
14201         /* Compare live against edges and make certain the code is working */
14202         for(entry1 = live; entry1; entry1 = entry1->next) {
14203                 struct live_range *lr1;
14204                 lr1 = get_verify_live_range(state, rstate, entry1->member);
14205                 for(entry2 = live; entry2; entry2 = entry2->next) {
14206                         struct live_range *lr2;
14207                         struct live_range_edge *edge2;
14208                         int lr1_found;
14209                         int lr2_degree;
14210                         if (entry2 == entry1) {
14211                                 continue;
14212                         }
14213                         lr2 = get_verify_live_range(state, rstate, entry2->member);
14214                         if (lr1 == lr2) {
14215                                 internal_error(state, entry2->member, 
14216                                         "live range with 2 values simultaneously alive");
14217                         }
14218                         if (!arch_regcm_intersect(lr1->classes, lr2->classes)) {
14219                                 continue;
14220                         }
14221                         if (!interfere(rstate, lr1, lr2)) {
14222                                 internal_error(state, entry2->member, 
14223                                         "edges don't interfere?");
14224                         }
14225                                 
14226                         lr1_found = 0;
14227                         lr2_degree = 0;
14228                         for(edge2 = lr2->edges; edge2; edge2 = edge2->next) {
14229                                 lr2_degree++;
14230                                 if (edge2->node == lr1) {
14231                                         lr1_found = 1;
14232                                 }
14233                         }
14234                         if (lr2_degree != lr2->degree) {
14235                                 internal_error(state, entry2->member,
14236                                         "computed degree: %d does not match reported degree: %d\n",
14237                                         lr2_degree, lr2->degree);
14238                         }
14239                         if (!lr1_found) {
14240                                 internal_error(state, entry2->member, "missing edge");
14241                         }
14242                 }
14243         }
14244         return;
14245 }
14246
14247
14248 static void print_interference_ins(
14249         struct compile_state *state, 
14250         struct reg_block *blocks, struct triple_reg_set *live, 
14251         struct reg_block *rb, struct triple *ins, void *arg)
14252 {
14253         struct reg_state *rstate = arg;
14254         struct live_range *lr;
14255         unsigned id;
14256
14257         lr = rstate->lrd[ins->id].lr;
14258         id = ins->id;
14259         ins->id = rstate->lrd[id].orig_id;
14260         SET_REG(ins->id, lr->color);
14261         display_triple(stdout, ins);
14262         ins->id = id;
14263
14264         if (lr->defs) {
14265                 struct live_range_def *lrd;
14266                 printf("       range:");
14267                 lrd = lr->defs;
14268                 do {
14269                         printf(" %-10p", lrd->def);
14270                         lrd = lrd->next;
14271                 } while(lrd != lr->defs);
14272                 printf("\n");
14273         }
14274         if (live) {
14275                 struct triple_reg_set *entry;
14276                 printf("        live:");
14277                 for(entry = live; entry; entry = entry->next) {
14278                         printf(" %-10p", entry->member);
14279                 }
14280                 printf("\n");
14281         }
14282         if (lr->edges) {
14283                 struct live_range_edge *entry;
14284                 printf("       edges:");
14285                 for(entry = lr->edges; entry; entry = entry->next) {
14286                         struct live_range_def *lrd;
14287                         lrd = entry->node->defs;
14288                         do {
14289                                 printf(" %-10p", lrd->def);
14290                                 lrd = lrd->next;
14291                         } while(lrd != entry->node->defs);
14292                         printf("|");
14293                 }
14294                 printf("\n");
14295         }
14296         if (triple_is_branch(state, ins)) {
14297                 printf("\n");
14298         }
14299         return;
14300 }
14301
14302 static int coalesce_live_ranges(
14303         struct compile_state *state, struct reg_state *rstate)
14304 {
14305         /* At the point where a value is moved from one
14306          * register to another that value requires two
14307          * registers, thus increasing register pressure.
14308          * Live range coaleescing reduces the register
14309          * pressure by keeping a value in one register
14310          * longer.
14311          *
14312          * In the case of a phi function all paths leading
14313          * into it must be allocated to the same register
14314          * otherwise the phi function may not be removed.
14315          *
14316          * Forcing a value to stay in a single register
14317          * for an extended period of time does have
14318          * limitations when applied to non homogenous
14319          * register pool.  
14320          *
14321          * The two cases I have identified are:
14322          * 1) Two forced register assignments may
14323          *    collide.
14324          * 2) Registers may go unused because they
14325          *    are only good for storing the value
14326          *    and not manipulating it.
14327          *
14328          * Because of this I need to split live ranges,
14329          * even outside of the context of coalesced live
14330          * ranges.  The need to split live ranges does
14331          * impose some constraints on live range coalescing.
14332          *
14333          * - Live ranges may not be coalesced across phi
14334          *   functions.  This creates a 2 headed live
14335          *   range that cannot be sanely split.
14336          *
14337          * - phi functions (coalesced in initialize_live_ranges) 
14338          *   are handled as pre split live ranges so we will
14339          *   never attempt to split them.
14340          */
14341         int coalesced;
14342         int i;
14343
14344         coalesced = 0;
14345         for(i = 0; i <= rstate->ranges; i++) {
14346                 struct live_range *lr1;
14347                 struct live_range_def *lrd1;
14348                 lr1 = &rstate->lr[i];
14349                 if (!lr1->defs) {
14350                         continue;
14351                 }
14352                 lrd1 = live_range_end(state, lr1, 0);
14353                 for(; lrd1; lrd1 = live_range_end(state, lr1, lrd1)) {
14354                         struct triple_set *set;
14355                         if (lrd1->def->op != OP_COPY) {
14356                                 continue;
14357                         }
14358                         /* Skip copies that are the result of a live range split. */
14359                         if (lrd1->orig_id & TRIPLE_FLAG_POST_SPLIT) {
14360                                 continue;
14361                         }
14362                         for(set = lrd1->def->use; set; set = set->next) {
14363                                 struct live_range_def *lrd2;
14364                                 struct live_range *lr2, *res;
14365
14366                                 lrd2 = &rstate->lrd[set->member->id];
14367
14368                                 /* Don't coalesce with instructions
14369                                  * that are the result of a live range
14370                                  * split.
14371                                  */
14372                                 if (lrd2->orig_id & TRIPLE_FLAG_PRE_SPLIT) {
14373                                         continue;
14374                                 }
14375                                 lr2 = rstate->lrd[set->member->id].lr;
14376                                 if (lr1 == lr2) {
14377                                         continue;
14378                                 }
14379                                 if ((lr1->color != lr2->color) &&
14380                                         (lr1->color != REG_UNSET) &&
14381                                         (lr2->color != REG_UNSET)) {
14382                                         continue;
14383                                 }
14384                                 if ((lr1->classes & lr2->classes) == 0) {
14385                                         continue;
14386                                 }
14387                                 
14388                                 if (interfere(rstate, lr1, lr2)) {
14389                                         continue;
14390                                 }
14391
14392                                 res = coalesce_ranges(state, rstate, lr1, lr2);
14393                                 coalesced += 1;
14394                                 if (res != lr1) {
14395                                         goto next;
14396                                 }
14397                         }
14398                 }
14399         next:
14400                 ;
14401         }
14402         return coalesced;
14403 }
14404
14405
14406 static void fix_coalesce_conflicts(struct compile_state *state,
14407         struct reg_block *blocks, struct triple_reg_set *live,
14408         struct reg_block *rb, struct triple *ins, void *arg)
14409 {
14410         int *conflicts = arg;
14411         int zlhs, zrhs, i, j;
14412
14413         /* See if we have a mandatory coalesce operation between
14414          * a lhs and a rhs value.  If so and the rhs value is also
14415          * alive then this triple needs to be pre copied.  Otherwise
14416          * we would have two definitions in the same live range simultaneously
14417          * alive.
14418          */
14419         zlhs = TRIPLE_LHS(ins->sizes);
14420         if ((zlhs == 0) && triple_is_def(state, ins)) {
14421                 zlhs = 1;
14422         }
14423         zrhs = TRIPLE_RHS(ins->sizes);
14424         for(i = 0; i < zlhs; i++) {
14425                 struct reg_info linfo;
14426                 linfo = arch_reg_lhs(state, ins, i);
14427                 if (linfo.reg < MAX_REGISTERS) {
14428                         continue;
14429                 }
14430                 for(j = 0; j < zrhs; j++) {
14431                         struct reg_info rinfo;
14432                         struct triple *rhs;
14433                         struct triple_reg_set *set;
14434                         int found;
14435                         found = 0;
14436                         rinfo = arch_reg_rhs(state, ins, j);
14437                         if (rinfo.reg != linfo.reg) {
14438                                 continue;
14439                         }
14440                         rhs = RHS(ins, j);
14441                         for(set = live; set && !found; set = set->next) {
14442                                 if (set->member == rhs) {
14443                                         found = 1;
14444                                 }
14445                         }
14446                         if (found) {
14447                                 struct triple *copy;
14448                                 copy = pre_copy(state, ins, j);
14449                                 copy->id |= TRIPLE_FLAG_PRE_SPLIT;
14450                                 (*conflicts)++;
14451                         }
14452                 }
14453         }
14454         return;
14455 }
14456
14457 static int correct_coalesce_conflicts(
14458         struct compile_state *state, struct reg_block *blocks)
14459 {
14460         int conflicts;
14461         conflicts = 0;
14462         walk_variable_lifetimes(state, blocks, fix_coalesce_conflicts, &conflicts);
14463         return conflicts;
14464 }
14465
14466 static void replace_set_use(struct compile_state *state,
14467         struct triple_reg_set *head, struct triple *orig, struct triple *new)
14468 {
14469         struct triple_reg_set *set;
14470         for(set = head; set; set = set->next) {
14471                 if (set->member == orig) {
14472                         set->member = new;
14473                 }
14474         }
14475 }
14476
14477 static void replace_block_use(struct compile_state *state, 
14478         struct reg_block *blocks, struct triple *orig, struct triple *new)
14479 {
14480         int i;
14481 #warning "WISHLIST visit just those blocks that need it *"
14482         for(i = 1; i <= state->last_vertex; i++) {
14483                 struct reg_block *rb;
14484                 rb = &blocks[i];
14485                 replace_set_use(state, rb->in, orig, new);
14486                 replace_set_use(state, rb->out, orig, new);
14487         }
14488 }
14489
14490 static void color_instructions(struct compile_state *state)
14491 {
14492         struct triple *ins, *first;
14493         first = state->first;
14494         ins = first;
14495         do {
14496                 if (triple_is_def(state, ins)) {
14497                         struct reg_info info;
14498                         info = find_lhs_color(state, ins, 0);
14499                         if (info.reg >= MAX_REGISTERS) {
14500                                 info.reg = REG_UNSET;
14501                         }
14502                         SET_INFO(ins->id, info);
14503                 }
14504                 ins = ins->next;
14505         } while(ins != first);
14506 }
14507
14508 static struct reg_info read_lhs_color(
14509         struct compile_state *state, struct triple *ins, int index)
14510 {
14511         struct reg_info info;
14512         if ((index == 0) && triple_is_def(state, ins)) {
14513                 info.reg   = ID_REG(ins->id);
14514                 info.regcm = ID_REGCM(ins->id);
14515         }
14516         else if (index < TRIPLE_LHS(ins->sizes)) {
14517                 info = read_lhs_color(state, LHS(ins, index), 0);
14518         }
14519         else {
14520                 internal_error(state, ins, "Bad lhs %d", index);
14521                 info.reg = REG_UNSET;
14522                 info.regcm = 0;
14523         }
14524         return info;
14525 }
14526
14527 static struct triple *resolve_tangle(
14528         struct compile_state *state, struct triple *tangle)
14529 {
14530         struct reg_info info, uinfo;
14531         struct triple_set *set, *next;
14532         struct triple *copy;
14533
14534 #warning "WISHLIST recalculate all affected instructions colors"
14535         info = find_lhs_color(state, tangle, 0);
14536         for(set = tangle->use; set; set = next) {
14537                 struct triple *user;
14538                 int i, zrhs;
14539                 next = set->next;
14540                 user = set->member;
14541                 zrhs = TRIPLE_RHS(user->sizes);
14542                 for(i = 0; i < zrhs; i++) {
14543                         if (RHS(user, i) != tangle) {
14544                                 continue;
14545                         }
14546                         uinfo = find_rhs_post_color(state, user, i);
14547                         if (uinfo.reg == info.reg) {
14548                                 copy = pre_copy(state, user, i);
14549                                 copy->id |= TRIPLE_FLAG_PRE_SPLIT;
14550                                 SET_INFO(copy->id, uinfo);
14551                         }
14552                 }
14553         }
14554         copy = 0;
14555         uinfo = find_lhs_pre_color(state, tangle, 0);
14556         if (uinfo.reg == info.reg) {
14557                 struct reg_info linfo;
14558                 copy = post_copy(state, tangle);
14559                 copy->id |= TRIPLE_FLAG_PRE_SPLIT;
14560                 linfo = find_lhs_color(state, copy, 0);
14561                 SET_INFO(copy->id, linfo);
14562         }
14563         info = find_lhs_color(state, tangle, 0);
14564         SET_INFO(tangle->id, info);
14565         
14566         return copy;
14567 }
14568
14569
14570 static void fix_tangles(struct compile_state *state,
14571         struct reg_block *blocks, struct triple_reg_set *live,
14572         struct reg_block *rb, struct triple *ins, void *arg)
14573 {
14574         int *tangles = arg;
14575         struct triple *tangle;
14576         do {
14577                 char used[MAX_REGISTERS];
14578                 struct triple_reg_set *set;
14579                 tangle = 0;
14580
14581                 /* Find out which registers have multiple uses at this point */
14582                 memset(used, 0, sizeof(used));
14583                 for(set = live; set; set = set->next) {
14584                         struct reg_info info;
14585                         info = read_lhs_color(state, set->member, 0);
14586                         if (info.reg == REG_UNSET) {
14587                                 continue;
14588                         }
14589                         reg_inc_used(state, used, info.reg);
14590                 }
14591                 
14592                 /* Now find the least dominated definition of a register in
14593                  * conflict I have seen so far.
14594                  */
14595                 for(set = live; set; set = set->next) {
14596                         struct reg_info info;
14597                         info = read_lhs_color(state, set->member, 0);
14598                         if (used[info.reg] < 2) {
14599                                 continue;
14600                         }
14601                         /* Changing copies that feed into phi functions
14602                          * is incorrect.
14603                          */
14604                         if (set->member->use && 
14605                                 (set->member->use->member->op == OP_PHI)) {
14606                                 continue;
14607                         }
14608                         if (!tangle || tdominates(state, set->member, tangle)) {
14609                                 tangle = set->member;
14610                         }
14611                 }
14612                 /* If I have found a tangle resolve it */
14613                 if (tangle) {
14614                         struct triple *post_copy;
14615                         (*tangles)++;
14616                         post_copy = resolve_tangle(state, tangle);
14617                         if (post_copy) {
14618                                 replace_block_use(state, blocks, tangle, post_copy);
14619                         }
14620                         if (post_copy && (tangle != ins)) {
14621                                 replace_set_use(state, live, tangle, post_copy);
14622                         }
14623                 }
14624         } while(tangle);
14625         return;
14626 }
14627
14628 static int correct_tangles(
14629         struct compile_state *state, struct reg_block *blocks)
14630 {
14631         int tangles;
14632         tangles = 0;
14633         color_instructions(state);
14634         walk_variable_lifetimes(state, blocks, fix_tangles, &tangles);
14635         return tangles;
14636 }
14637
14638
14639 static void ids_from_rstate(struct compile_state *state, struct reg_state *rstate);
14640 static void cleanup_rstate(struct compile_state *state, struct reg_state *rstate);
14641
14642 struct triple *find_constrained_def(
14643         struct compile_state *state, struct live_range *range, struct triple *constrained)
14644 {
14645         struct live_range_def *lrd, *lrd_next;
14646         lrd_next = range->defs;
14647         do {
14648                 struct reg_info info;
14649                 unsigned regcm;
14650
14651                 lrd = lrd_next;
14652                 lrd_next = lrd->next;
14653
14654                 regcm = arch_type_to_regcm(state, lrd->def->type);
14655                 info = find_lhs_color(state, lrd->def, 0);
14656                 regcm      = arch_regcm_reg_normalize(state, regcm);
14657                 info.regcm = arch_regcm_reg_normalize(state, info.regcm);
14658                 /* If the 2 register class masks are equal then
14659                  * the current register class is not constrained.
14660                  */
14661                 if (regcm == info.regcm) {
14662                         continue;
14663                 }
14664                 
14665                 /* If there is just one use.
14666                  * That use cannot accept a larger register class.
14667                  * There are no intervening definitions except
14668                  * definitions that feed into that use.
14669                  * Then a triple is not constrained.
14670                  * FIXME handle this case!
14671                  */
14672 #warning "FIXME ignore cases that cannot be fixed (a definition followed by a use)"
14673                 
14674
14675                 /* Of the constrained live ranges deal with the
14676                  * least dominated one first.
14677                  */
14678                 if (state->compiler->debug & DEBUG_RANGE_CONFLICTS) {
14679                         fprintf(stderr, "canidate: %p %-8s regcm: %x %x\n",
14680                                 lrd->def, tops(lrd->def->op), regcm, info.regcm);
14681                 }
14682                 if (!constrained || 
14683                         tdominates(state, lrd->def, constrained))
14684                 {
14685                         constrained = lrd->def;
14686                 }
14687         } while(lrd_next != range->defs);
14688         return constrained;
14689 }
14690
14691 static int split_constrained_ranges(
14692         struct compile_state *state, struct reg_state *rstate, 
14693         struct live_range *range)
14694 {
14695         /* Walk through the edges in conflict and our current live
14696          * range, and find definitions that are more severly constrained
14697          * than they type of data they contain require.
14698          * 
14699          * Then pick one of those ranges and relax the constraints.
14700          */
14701         struct live_range_edge *edge;
14702         struct triple *constrained;
14703
14704         constrained = 0;
14705         for(edge = range->edges; edge; edge = edge->next) {
14706                 constrained = find_constrained_def(state, edge->node, constrained);
14707         }
14708 #warning "FIXME should I call find_constrained_def here only if no previous constrained def was found?"
14709         if (!constrained) {
14710                 constrained = find_constrained_def(state, range, constrained);
14711         }
14712
14713         if (state->compiler->debug & DEBUG_RANGE_CONFLICTS) {
14714                 fprintf(stderr, "constrained: %p %-8s\n",
14715                         constrained, tops(constrained->op));
14716         }
14717         if (constrained) {
14718                 ids_from_rstate(state, rstate);
14719                 cleanup_rstate(state, rstate);
14720                 resolve_tangle(state, constrained);
14721         }
14722         return !!constrained;
14723 }
14724         
14725 static int split_ranges(
14726         struct compile_state *state, struct reg_state *rstate,
14727         char *used, struct live_range *range)
14728 {
14729         int split;
14730         if (state->compiler->debug & DEBUG_RANGE_CONFLICTS) {
14731                 fprintf(stderr, "split_ranges %d %s %p\n", 
14732                         rstate->passes, tops(range->defs->def->op), range->defs->def);
14733         }
14734         if ((range->color == REG_UNNEEDED) ||
14735                 (rstate->passes >= rstate->max_passes)) {
14736                 return 0;
14737         }
14738         split = split_constrained_ranges(state, rstate, range);
14739
14740         /* Ideally I would split the live range that will not be used
14741          * for the longest period of time in hopes that this will 
14742          * (a) allow me to spill a register or
14743          * (b) allow me to place a value in another register.
14744          *
14745          * So far I don't have a test case for this, the resolving
14746          * of mandatory constraints has solved all of my
14747          * know issues.  So I have choosen not to write any
14748          * code until I cat get a better feel for cases where
14749          * it would be useful to have.
14750          *
14751          */
14752 #warning "WISHLIST implement live range splitting..."
14753         
14754         if (!split && (state->compiler->debug & DEBUG_RANGE_CONFLICTS2)) {
14755                 print_interference_blocks(state, rstate, stderr, 0);
14756                 print_dominators(state, stderr);
14757         }
14758         return split;
14759 }
14760
14761 static FILE *cgdebug_fp(struct compile_state *state)
14762 {
14763         FILE *fp;
14764         fp = 0;
14765         if (!fp && (state->compiler->debug & DEBUG_COLOR_GRAPH2)) {
14766                 fp = stderr;
14767         }
14768         if (!fp && (state->compiler->debug & DEBUG_COLOR_GRAPH)) {
14769                 fp = stdout;
14770         }
14771         return fp;
14772 }
14773
14774 static void cgdebug_printf(struct compile_state *state, const char *fmt, ...)
14775 {
14776         FILE *fp;
14777         fp = cgdebug_fp(state);
14778         if (fp) {
14779                 va_list args;
14780                 va_start(args, fmt);
14781                 vfprintf(fp, fmt, args);
14782                 va_end(args);
14783         }
14784 }
14785
14786 static void cgdebug_flush(struct compile_state *state)
14787 {
14788         FILE *fp;
14789         fp = cgdebug_fp(state);
14790         if (fp) {
14791                 fflush(fp);
14792         }
14793 }
14794
14795 static void cgdebug_loc(struct compile_state *state, struct triple *ins)
14796 {
14797         FILE *fp;
14798         fp = cgdebug_fp(state);
14799         if (fp) {
14800                 loc(fp, state, ins);
14801         }
14802 }
14803
14804 static int select_free_color(struct compile_state *state, 
14805         struct reg_state *rstate, struct live_range *range)
14806 {
14807         struct triple_set *entry;
14808         struct live_range_def *lrd;
14809         struct live_range_def *phi;
14810         struct live_range_edge *edge;
14811         char used[MAX_REGISTERS];
14812         struct triple **expr;
14813
14814         /* Instead of doing just the trivial color select here I try
14815          * a few extra things because a good color selection will help reduce
14816          * copies.
14817          */
14818
14819         /* Find the registers currently in use */
14820         memset(used, 0, sizeof(used));
14821         for(edge = range->edges; edge; edge = edge->next) {
14822                 if (edge->node->color == REG_UNSET) {
14823                         continue;
14824                 }
14825                 reg_fill_used(state, used, edge->node->color);
14826         }
14827
14828         if (state->compiler->debug & DEBUG_COLOR_GRAPH2) {
14829                 int i;
14830                 i = 0;
14831                 for(edge = range->edges; edge; edge = edge->next) {
14832                         i++;
14833                 }
14834                 cgdebug_printf(state, "\n%s edges: %d", 
14835                         tops(range->defs->def->op), i);
14836                 cgdebug_loc(state, range->defs->def);
14837                 cgdebug_printf(state, "\n");
14838                 for(i = 0; i < MAX_REGISTERS; i++) {
14839                         if (used[i]) {
14840                                 cgdebug_printf(state, "used: %s\n",
14841                                         arch_reg_str(i));
14842                         }
14843                 }
14844         }       
14845
14846         /* If a color is already assigned see if it will work */
14847         if (range->color != REG_UNSET) {
14848                 struct live_range_def *lrd;
14849                 if (!used[range->color]) {
14850                         return 1;
14851                 }
14852                 for(edge = range->edges; edge; edge = edge->next) {
14853                         if (edge->node->color != range->color) {
14854                                 continue;
14855                         }
14856                         warning(state, edge->node->defs->def, "edge: ");
14857                         lrd = edge->node->defs;
14858                         do {
14859                                 warning(state, lrd->def, " %p %s",
14860                                         lrd->def, tops(lrd->def->op));
14861                                 lrd = lrd->next;
14862                         } while(lrd != edge->node->defs);
14863                 }
14864                 lrd = range->defs;
14865                 warning(state, range->defs->def, "def: ");
14866                 do {
14867                         warning(state, lrd->def, " %p %s",
14868                                 lrd->def, tops(lrd->def->op));
14869                         lrd = lrd->next;
14870                 } while(lrd != range->defs);
14871                 internal_error(state, range->defs->def,
14872                         "live range with already used color %s",
14873                         arch_reg_str(range->color));
14874         }
14875
14876         /* If I feed into an expression reuse it's color.
14877          * This should help remove copies in the case of 2 register instructions
14878          * and phi functions.
14879          */
14880         phi = 0;
14881         lrd = live_range_end(state, range, 0);
14882         for(; (range->color == REG_UNSET) && lrd ; lrd = live_range_end(state, range, lrd)) {
14883                 entry = lrd->def->use;
14884                 for(;(range->color == REG_UNSET) && entry; entry = entry->next) {
14885                         struct live_range_def *insd;
14886                         unsigned regcm;
14887                         insd = &rstate->lrd[entry->member->id];
14888                         if (insd->lr->defs == 0) {
14889                                 continue;
14890                         }
14891                         if (!phi && (insd->def->op == OP_PHI) &&
14892                                 !interfere(rstate, range, insd->lr)) {
14893                                 phi = insd;
14894                         }
14895                         if (insd->lr->color == REG_UNSET) {
14896                                 continue;
14897                         }
14898                         regcm = insd->lr->classes;
14899                         if (((regcm & range->classes) == 0) ||
14900                                 (used[insd->lr->color])) {
14901                                 continue;
14902                         }
14903                         if (interfere(rstate, range, insd->lr)) {
14904                                 continue;
14905                         }
14906                         range->color = insd->lr->color;
14907                 }
14908         }
14909         /* If I feed into a phi function reuse it's color or the color
14910          * of something else that feeds into the phi function.
14911          */
14912         if (phi) {
14913                 if (phi->lr->color != REG_UNSET) {
14914                         if (used[phi->lr->color]) {
14915                                 range->color = phi->lr->color;
14916                         }
14917                 }
14918                 else {
14919                         expr = triple_rhs(state, phi->def, 0);
14920                         for(; expr; expr = triple_rhs(state, phi->def, expr)) {
14921                                 struct live_range *lr;
14922                                 unsigned regcm;
14923                                 if (!*expr) {
14924                                         continue;
14925                                 }
14926                                 lr = rstate->lrd[(*expr)->id].lr;
14927                                 if (lr->color == REG_UNSET) {
14928                                         continue;
14929                                 }
14930                                 regcm = lr->classes;
14931                                 if (((regcm & range->classes) == 0) ||
14932                                         (used[lr->color])) {
14933                                         continue;
14934                                 }
14935                                 if (interfere(rstate, range, lr)) {
14936                                         continue;
14937                                 }
14938                                 range->color = lr->color;
14939                         }
14940                 }
14941         }
14942         /* If I don't interfere with a rhs node reuse it's color */
14943         lrd = live_range_head(state, range, 0);
14944         for(; (range->color == REG_UNSET) && lrd ; lrd = live_range_head(state, range, lrd)) {
14945                 expr = triple_rhs(state, lrd->def, 0);
14946                 for(; expr; expr = triple_rhs(state, lrd->def, expr)) {
14947                         struct live_range *lr;
14948                         unsigned regcm;
14949                         if (!*expr) {
14950                                 continue;
14951                         }
14952                         lr = rstate->lrd[(*expr)->id].lr;
14953                         if (lr->color == REG_UNSET) {
14954                                 continue;
14955                         }
14956                         regcm = lr->classes;
14957                         if (((regcm & range->classes) == 0) ||
14958                                 (used[lr->color])) {
14959                                 continue;
14960                         }
14961                         if (interfere(rstate, range, lr)) {
14962                                 continue;
14963                         }
14964                         range->color = lr->color;
14965                         break;
14966                 }
14967         }
14968         /* If I have not opportunitically picked a useful color
14969          * pick the first color that is free.
14970          */
14971         if (range->color == REG_UNSET) {
14972                 range->color = 
14973                         arch_select_free_register(state, used, range->classes);
14974         }
14975         if (range->color == REG_UNSET) {
14976                 struct live_range_def *lrd;
14977                 int i;
14978                 if (split_ranges(state, rstate, used, range)) {
14979                         return 0;
14980                 }
14981                 for(edge = range->edges; edge; edge = edge->next) {
14982                         warning(state, edge->node->defs->def, "edge reg %s",
14983                                 arch_reg_str(edge->node->color));
14984                         lrd = edge->node->defs;
14985                         do {
14986                                 warning(state, lrd->def, " %s %p",
14987                                         tops(lrd->def->op), lrd->def);
14988                                 lrd = lrd->next;
14989                         } while(lrd != edge->node->defs);
14990                 }
14991                 warning(state, range->defs->def, "range: ");
14992                 lrd = range->defs;
14993                 do {
14994                         warning(state, lrd->def, " %s %p",
14995                                 tops(lrd->def->op), lrd->def);
14996                         lrd = lrd->next;
14997                 } while(lrd != range->defs);
14998                         
14999                 warning(state, range->defs->def, "classes: %x",
15000                         range->classes);
15001                 for(i = 0; i < MAX_REGISTERS; i++) {
15002                         if (used[i]) {
15003                                 warning(state, range->defs->def, "used: %s",
15004                                         arch_reg_str(i));
15005                         }
15006                 }
15007                 error(state, range->defs->def, "too few registers");
15008         }
15009         range->classes &= arch_reg_regcm(state, range->color);
15010         if ((range->color == REG_UNSET) || (range->classes == 0)) {
15011                 internal_error(state, range->defs->def, "select_free_color did not?");
15012         }
15013         return 1;
15014 }
15015
15016 static int color_graph(struct compile_state *state, struct reg_state *rstate)
15017 {
15018         int colored;
15019         struct live_range_edge *edge;
15020         struct live_range *range;
15021         if (rstate->low) {
15022                 cgdebug_printf(state, "Lo: ");
15023                 range = rstate->low;
15024                 if (*range->group_prev != range) {
15025                         internal_error(state, 0, "lo: *prev != range?");
15026                 }
15027                 *range->group_prev = range->group_next;
15028                 if (range->group_next) {
15029                         range->group_next->group_prev = range->group_prev;
15030                 }
15031                 if (&range->group_next == rstate->low_tail) {
15032                         rstate->low_tail = range->group_prev;
15033                 }
15034                 if (rstate->low == range) {
15035                         internal_error(state, 0, "low: next != prev?");
15036                 }
15037         }
15038         else if (rstate->high) {
15039                 cgdebug_printf(state, "Hi: ");
15040                 range = rstate->high;
15041                 if (*range->group_prev != range) {
15042                         internal_error(state, 0, "hi: *prev != range?");
15043                 }
15044                 *range->group_prev = range->group_next;
15045                 if (range->group_next) {
15046                         range->group_next->group_prev = range->group_prev;
15047                 }
15048                 if (&range->group_next == rstate->high_tail) {
15049                         rstate->high_tail = range->group_prev;
15050                 }
15051                 if (rstate->high == range) {
15052                         internal_error(state, 0, "high: next != prev?");
15053                 }
15054         }
15055         else {
15056                 return 1;
15057         }
15058         cgdebug_printf(state, " %d\n", range - rstate->lr);
15059         range->group_prev = 0;
15060         for(edge = range->edges; edge; edge = edge->next) {
15061                 struct live_range *node;
15062                 node = edge->node;
15063                 /* Move nodes from the high to the low list */
15064                 if (node->group_prev && (node->color == REG_UNSET) &&
15065                         (node->degree == regc_max_size(state, node->classes))) {
15066                         if (*node->group_prev != node) {
15067                                 internal_error(state, 0, "move: *prev != node?");
15068                         }
15069                         *node->group_prev = node->group_next;
15070                         if (node->group_next) {
15071                                 node->group_next->group_prev = node->group_prev;
15072                         }
15073                         if (&node->group_next == rstate->high_tail) {
15074                                 rstate->high_tail = node->group_prev;
15075                         }
15076                         cgdebug_printf(state, "Moving...%d to low\n", node - rstate->lr);
15077                         node->group_prev  = rstate->low_tail;
15078                         node->group_next  = 0;
15079                         *rstate->low_tail = node;
15080                         rstate->low_tail  = &node->group_next;
15081                         if (*node->group_prev != node) {
15082                                 internal_error(state, 0, "move2: *prev != node?");
15083                         }
15084                 }
15085                 node->degree -= 1;
15086         }
15087         colored = color_graph(state, rstate);
15088         if (colored) {
15089                 cgdebug_printf(state, "Coloring %d @", range - rstate->lr);
15090                 cgdebug_loc(state, range->defs->def);
15091                 cgdebug_flush(state);
15092                 colored = select_free_color(state, rstate, range);
15093                 cgdebug_printf(state, " %s\n", arch_reg_str(range->color));
15094         }
15095         return colored;
15096 }
15097
15098 static void verify_colors(struct compile_state *state, struct reg_state *rstate)
15099 {
15100         struct live_range *lr;
15101         struct live_range_edge *edge;
15102         struct triple *ins, *first;
15103         char used[MAX_REGISTERS];
15104         first = state->first;
15105         ins = first;
15106         do {
15107                 if (triple_is_def(state, ins)) {
15108                         if ((ins->id < 0) || (ins->id > rstate->defs)) {
15109                                 internal_error(state, ins, 
15110                                         "triple without a live range def");
15111                         }
15112                         lr = rstate->lrd[ins->id].lr;
15113                         if (lr->color == REG_UNSET) {
15114                                 internal_error(state, ins,
15115                                         "triple without a color");
15116                         }
15117                         /* Find the registers used by the edges */
15118                         memset(used, 0, sizeof(used));
15119                         for(edge = lr->edges; edge; edge = edge->next) {
15120                                 if (edge->node->color == REG_UNSET) {
15121                                         internal_error(state, 0,
15122                                                 "live range without a color");
15123                         }
15124                                 reg_fill_used(state, used, edge->node->color);
15125                         }
15126                         if (used[lr->color]) {
15127                                 internal_error(state, ins,
15128                                         "triple with already used color");
15129                         }
15130                 }
15131                 ins = ins->next;
15132         } while(ins != first);
15133 }
15134
15135 static void color_triples(struct compile_state *state, struct reg_state *rstate)
15136 {
15137         struct live_range *lr;
15138         struct triple *first, *ins;
15139         first = state->first;
15140         ins = first;
15141         do {
15142                 if ((ins->id < 0) || (ins->id > rstate->defs)) {
15143                         internal_error(state, ins, 
15144                                 "triple without a live range");
15145                 }
15146                 lr = rstate->lrd[ins->id].lr;
15147                 SET_REG(ins->id, lr->color);
15148                 ins = ins->next;
15149         } while (ins != first);
15150 }
15151
15152 static struct live_range *merge_sort_lr(
15153         struct live_range *first, struct live_range *last)
15154 {
15155         struct live_range *mid, *join, **join_tail, *pick;
15156         size_t size;
15157         size = (last - first) + 1;
15158         if (size >= 2) {
15159                 mid = first + size/2;
15160                 first = merge_sort_lr(first, mid -1);
15161                 mid   = merge_sort_lr(mid, last);
15162                 
15163                 join = 0;
15164                 join_tail = &join;
15165                 /* merge the two lists */
15166                 while(first && mid) {
15167                         if ((first->degree < mid->degree) ||
15168                                 ((first->degree == mid->degree) &&
15169                                         (first->length < mid->length))) {
15170                                 pick = first;
15171                                 first = first->group_next;
15172                                 if (first) {
15173                                         first->group_prev = 0;
15174                                 }
15175                         }
15176                         else {
15177                                 pick = mid;
15178                                 mid = mid->group_next;
15179                                 if (mid) {
15180                                         mid->group_prev = 0;
15181                                 }
15182                         }
15183                         pick->group_next = 0;
15184                         pick->group_prev = join_tail;
15185                         *join_tail = pick;
15186                         join_tail = &pick->group_next;
15187                 }
15188                 /* Splice the remaining list */
15189                 pick = (first)? first : mid;
15190                 *join_tail = pick;
15191                 if (pick) { 
15192                         pick->group_prev = join_tail;
15193                 }
15194         }
15195         else {
15196                 if (!first->defs) {
15197                         first = 0;
15198                 }
15199                 join = first;
15200         }
15201         return join;
15202 }
15203
15204 static void ids_from_rstate(struct compile_state *state, 
15205         struct reg_state *rstate)
15206 {
15207         struct triple *ins, *first;
15208         if (!rstate->defs) {
15209                 return;
15210         }
15211         /* Display the graph if desired */
15212         if (state->compiler->debug & DEBUG_INTERFERENCE) {
15213                 print_interference_blocks(state, rstate, stdout, 0);
15214                 print_control_flow(state);
15215                 fflush(stdout);
15216         }
15217         first = state->first;
15218         ins = first;
15219         do {
15220                 if (ins->id) {
15221                         struct live_range_def *lrd;
15222                         lrd = &rstate->lrd[ins->id];
15223                         ins->id = lrd->orig_id;
15224                 }
15225                 ins = ins->next;
15226         } while(ins != first);
15227 }
15228
15229 static void cleanup_live_edges(struct reg_state *rstate)
15230 {
15231         int i;
15232         /* Free the edges on each node */
15233         for(i = 1; i <= rstate->ranges; i++) {
15234                 remove_live_edges(rstate, &rstate->lr[i]);
15235         }
15236 }
15237
15238 static void cleanup_rstate(struct compile_state *state, struct reg_state *rstate)
15239 {
15240         cleanup_live_edges(rstate);
15241         xfree(rstate->lrd);
15242         xfree(rstate->lr);
15243
15244         /* Free the variable lifetime information */
15245         if (rstate->blocks) {
15246                 free_variable_lifetimes(state, rstate->blocks);
15247         }
15248         rstate->defs = 0;
15249         rstate->ranges = 0;
15250         rstate->lrd = 0;
15251         rstate->lr = 0;
15252         rstate->blocks = 0;
15253 }
15254
15255 static void verify_consistency(struct compile_state *state);
15256 static void allocate_registers(struct compile_state *state)
15257 {
15258         struct reg_state rstate;
15259         int colored;
15260
15261         /* Clear out the reg_state */
15262         memset(&rstate, 0, sizeof(rstate));
15263         rstate.max_passes = state->compiler->max_allocation_passes;
15264
15265         do {
15266                 struct live_range **point, **next;
15267                 int conflicts;
15268                 int tangles;
15269                 int coalesced;
15270
15271                 if (state->compiler->debug & DEBUG_RANGE_CONFLICTS) {
15272                         fprintf(stderr, "pass: %d\n", rstate.passes);
15273                         fflush(stderr);
15274                 }
15275
15276                 /* Restore ids */
15277                 ids_from_rstate(state, &rstate);
15278
15279                 /* Cleanup the temporary data structures */
15280                 cleanup_rstate(state, &rstate);
15281
15282                 /* Compute the variable lifetimes */
15283                 rstate.blocks = compute_variable_lifetimes(state);
15284
15285                 /* Fix invalid mandatory live range coalesce conflicts */
15286                 conflicts = correct_coalesce_conflicts(state, rstate.blocks);
15287
15288                 /* Fix two simultaneous uses of the same register.
15289                  * In a few pathlogical cases a partial untangle moves
15290                  * the tangle to a part of the graph we won't revisit.
15291                  * So we keep looping until we have no more tangle fixes
15292                  * to apply.
15293                  */
15294                 do {
15295                         tangles = correct_tangles(state, rstate.blocks);
15296                 } while(tangles);
15297
15298                 
15299                 print_blocks(state, "resolve_tangles", stdout);
15300                 verify_consistency(state);
15301                 
15302                 /* Allocate and initialize the live ranges */
15303                 initialize_live_ranges(state, &rstate);
15304
15305                 /* Note current doing coalescing in a loop appears to 
15306                  * buys me nothing.  The code is left this way in case
15307                  * there is some value in it.  Or if a future bugfix
15308                  *  yields some benefit.
15309                  */
15310                 do {
15311                         if (state->compiler->debug & DEBUG_COALESCING) {
15312                                 fprintf(stderr, "coalescing\n");
15313                         }
15314
15315                         /* Remove any previous live edge calculations */
15316                         cleanup_live_edges(&rstate);
15317
15318                         /* Compute the interference graph */
15319                         walk_variable_lifetimes(
15320                                 state, rstate.blocks, graph_ins, &rstate);
15321                         
15322                         /* Display the interference graph if desired */
15323                         if (state->compiler->debug & DEBUG_INTERFERENCE) {
15324                                 print_interference_blocks(state, &rstate, stdout, 1);
15325                                 printf("\nlive variables by instruction\n");
15326                                 walk_variable_lifetimes(
15327                                         state, rstate.blocks, 
15328                                         print_interference_ins, &rstate);
15329                         }
15330                         
15331                         coalesced = coalesce_live_ranges(state, &rstate);
15332
15333                         if (state->compiler->debug & DEBUG_COALESCING) {
15334                                 fprintf(stderr, "coalesced: %d\n", coalesced);
15335                         }
15336                 } while(coalesced);
15337
15338 #if DEBUG_CONSISTENCY > 1
15339 # if 0
15340                 fprintf(stderr, "verify_graph_ins...\n");
15341 # endif
15342                 /* Verify the interference graph */
15343                 walk_variable_lifetimes(
15344                         state, rstate.blocks, verify_graph_ins, &rstate);
15345 # if 0
15346                 fprintf(stderr, "verify_graph_ins done\n");
15347 #endif
15348 #endif
15349                         
15350                 /* Build the groups low and high.  But with the nodes
15351                  * first sorted by degree order.
15352                  */
15353                 rstate.low_tail  = &rstate.low;
15354                 rstate.high_tail = &rstate.high;
15355                 rstate.high = merge_sort_lr(&rstate.lr[1], &rstate.lr[rstate.ranges]);
15356                 if (rstate.high) {
15357                         rstate.high->group_prev = &rstate.high;
15358                 }
15359                 for(point = &rstate.high; *point; point = &(*point)->group_next)
15360                         ;
15361                 rstate.high_tail = point;
15362                 /* Walk through the high list and move everything that needs
15363                  * to be onto low.
15364                  */
15365                 for(point = &rstate.high; *point; point = next) {
15366                         struct live_range *range;
15367                         next = &(*point)->group_next;
15368                         range = *point;
15369                         
15370                         /* If it has a low degree or it already has a color
15371                          * place the node in low.
15372                          */
15373                         if ((range->degree < regc_max_size(state, range->classes)) ||
15374                                 (range->color != REG_UNSET)) {
15375                                 cgdebug_printf(state, "Lo: %5d degree %5d%s\n", 
15376                                         range - rstate.lr, range->degree,
15377                                         (range->color != REG_UNSET) ? " (colored)": "");
15378                                 *range->group_prev = range->group_next;
15379                                 if (range->group_next) {
15380                                         range->group_next->group_prev = range->group_prev;
15381                                 }
15382                                 if (&range->group_next == rstate.high_tail) {
15383                                         rstate.high_tail = range->group_prev;
15384                                 }
15385                                 range->group_prev  = rstate.low_tail;
15386                                 range->group_next  = 0;
15387                                 *rstate.low_tail   = range;
15388                                 rstate.low_tail    = &range->group_next;
15389                                 next = point;
15390                         }
15391                         else {
15392                                 cgdebug_printf(state, "hi: %5d degree %5d%s\n", 
15393                                         range - rstate.lr, range->degree,
15394                                         (range->color != REG_UNSET) ? " (colored)": "");
15395                         }
15396                 }
15397                 /* Color the live_ranges */
15398                 colored = color_graph(state, &rstate);
15399                 rstate.passes++;
15400         } while (!colored);
15401
15402         /* Verify the graph was properly colored */
15403         verify_colors(state, &rstate);
15404
15405         /* Move the colors from the graph to the triples */
15406         color_triples(state, &rstate);
15407
15408         /* Cleanup the temporary data structures */
15409         cleanup_rstate(state, &rstate);
15410
15411         /* Display the new graph */
15412         print_blocks(state, __func__, stdout);
15413 }
15414
15415 /* Sparce Conditional Constant Propogation
15416  * =========================================
15417  */
15418 struct ssa_edge;
15419 struct flow_block;
15420 struct lattice_node {
15421         unsigned old_id;
15422         struct triple *def;
15423         struct ssa_edge *out;
15424         struct flow_block *fblock;
15425         struct triple *val;
15426         /* lattice high   val && !is_const(val) 
15427          * lattice const  is_const(val)
15428          * lattice low    val == 0
15429          */
15430 };
15431 struct ssa_edge {
15432         struct lattice_node *src;
15433         struct lattice_node *dst;
15434         struct ssa_edge *work_next;
15435         struct ssa_edge *work_prev;
15436         struct ssa_edge *out_next;
15437 };
15438 struct flow_edge {
15439         struct flow_block *src;
15440         struct flow_block *dst;
15441         struct flow_edge *work_next;
15442         struct flow_edge *work_prev;
15443         struct flow_edge *in_next;
15444         struct flow_edge *out_next;
15445         int executable;
15446 };
15447 #define MAX_FLOW_BLOCK_EDGES 3
15448 struct flow_block {
15449         struct block *block;
15450         struct flow_edge *in;
15451         struct flow_edge *out;
15452         struct flow_edge *edges;
15453 };
15454
15455 struct scc_state {
15456         int ins_count;
15457         struct lattice_node *lattice;
15458         struct ssa_edge     *ssa_edges;
15459         struct flow_block   *flow_blocks;
15460         struct flow_edge    *flow_work_list;
15461         struct ssa_edge     *ssa_work_list;
15462 };
15463
15464
15465 static void scc_add_fedge(struct compile_state *state, struct scc_state *scc, 
15466         struct flow_edge *fedge)
15467 {
15468         if (state->compiler->debug & DEBUG_SCC_TRANSFORM2) {
15469                 fprintf(stderr, "adding fedge: %p (%4d -> %5d)\n",
15470                         fedge,
15471                         fedge->src->block?fedge->src->block->last->id: 0,
15472                         fedge->dst->block?fedge->dst->block->first->id: 0);
15473         }
15474         if ((fedge == scc->flow_work_list) ||
15475                 (fedge->work_next != fedge) ||
15476                 (fedge->work_prev != fedge)) {
15477
15478                 if (state->compiler->debug & DEBUG_SCC_TRANSFORM2) {
15479                         fprintf(stderr, "dupped fedge: %p\n",
15480                                 fedge);
15481                 }
15482                 return;
15483         }
15484         if (!scc->flow_work_list) {
15485                 scc->flow_work_list = fedge;
15486                 fedge->work_next = fedge->work_prev = fedge;
15487         }
15488         else {
15489                 struct flow_edge *ftail;
15490                 ftail = scc->flow_work_list->work_prev;
15491                 fedge->work_next = ftail->work_next;
15492                 fedge->work_prev = ftail;
15493                 fedge->work_next->work_prev = fedge;
15494                 fedge->work_prev->work_next = fedge;
15495         }
15496 }
15497
15498 static struct flow_edge *scc_next_fedge(
15499         struct compile_state *state, struct scc_state *scc)
15500 {
15501         struct flow_edge *fedge;
15502         fedge = scc->flow_work_list;
15503         if (fedge) {
15504                 fedge->work_next->work_prev = fedge->work_prev;
15505                 fedge->work_prev->work_next = fedge->work_next;
15506                 if (fedge->work_next != fedge) {
15507                         scc->flow_work_list = fedge->work_next;
15508                 } else {
15509                         scc->flow_work_list = 0;
15510                 }
15511                 fedge->work_next = fedge->work_prev = fedge;
15512         }
15513         return fedge;
15514 }
15515
15516 static void scc_add_sedge(struct compile_state *state, struct scc_state *scc,
15517         struct ssa_edge *sedge)
15518 {
15519         if (state->compiler->debug & DEBUG_SCC_TRANSFORM2) {
15520                 fprintf(stderr, "adding sedge: %5d (%4d -> %5d)\n",
15521                         sedge - scc->ssa_edges,
15522                         sedge->src->def->id,
15523                         sedge->dst->def->id);
15524         }
15525         if ((sedge == scc->ssa_work_list) ||
15526                 (sedge->work_next != sedge) ||
15527                 (sedge->work_prev != sedge)) {
15528
15529                 if (state->compiler->debug & DEBUG_SCC_TRANSFORM2) {
15530                         fprintf(stderr, "dupped sedge: %5d\n",
15531                                 sedge - scc->ssa_edges);
15532                 }
15533                 return;
15534         }
15535         if (!scc->ssa_work_list) {
15536                 scc->ssa_work_list = sedge;
15537                 sedge->work_next = sedge->work_prev = sedge;
15538         }
15539         else {
15540                 struct ssa_edge *stail;
15541                 stail = scc->ssa_work_list->work_prev;
15542                 sedge->work_next = stail->work_next;
15543                 sedge->work_prev = stail;
15544                 sedge->work_next->work_prev = sedge;
15545                 sedge->work_prev->work_next = sedge;
15546         }
15547 }
15548
15549 static struct ssa_edge *scc_next_sedge(
15550         struct compile_state *state, struct scc_state *scc)
15551 {
15552         struct ssa_edge *sedge;
15553         sedge = scc->ssa_work_list;
15554         if (sedge) {
15555                 sedge->work_next->work_prev = sedge->work_prev;
15556                 sedge->work_prev->work_next = sedge->work_next;
15557                 if (sedge->work_next != sedge) {
15558                         scc->ssa_work_list = sedge->work_next;
15559                 } else {
15560                         scc->ssa_work_list = 0;
15561                 }
15562                 sedge->work_next = sedge->work_prev = sedge;
15563         }
15564         return sedge;
15565 }
15566
15567 static void initialize_scc_state(
15568         struct compile_state *state, struct scc_state *scc)
15569 {
15570         int ins_count, ssa_edge_count;
15571         int ins_index, ssa_edge_index, fblock_index;
15572         struct triple *first, *ins;
15573         struct block *block;
15574         struct flow_block *fblock;
15575
15576         memset(scc, 0, sizeof(*scc));
15577
15578         /* Inialize pass zero find out how much memory we need */
15579         first = state->first;
15580         ins = first;
15581         ins_count = ssa_edge_count = 0;
15582         do {
15583                 struct triple_set *edge;
15584                 ins_count += 1;
15585                 for(edge = ins->use; edge; edge = edge->next) {
15586                         ssa_edge_count++;
15587                 }
15588                 ins = ins->next;
15589         } while(ins != first);
15590         if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
15591                 fprintf(stderr, "ins_count: %d ssa_edge_count: %d vertex_count: %d\n",
15592                         ins_count, ssa_edge_count, state->last_vertex);
15593         }
15594         scc->ins_count   = ins_count;
15595         scc->lattice     = 
15596                 xcmalloc(sizeof(*scc->lattice)*(ins_count + 1), "lattice");
15597         scc->ssa_edges   = 
15598                 xcmalloc(sizeof(*scc->ssa_edges)*(ssa_edge_count + 1), "ssa_edges");
15599         scc->flow_blocks = 
15600                 xcmalloc(sizeof(*scc->flow_blocks)*(state->last_vertex + 1), 
15601                         "flow_blocks");
15602
15603         /* Initialize pass one collect up the nodes */
15604         fblock = 0;
15605         block = 0;
15606         ins_index = ssa_edge_index = fblock_index = 0;
15607         ins = first;
15608         do {
15609                 if ((ins->op == OP_LABEL) && (block != ins->u.block)) {
15610                         block = ins->u.block;
15611                         if (!block) {
15612                                 internal_error(state, ins, "label without block");
15613                         }
15614                         fblock_index += 1;
15615                         block->vertex = fblock_index;
15616                         fblock = &scc->flow_blocks[fblock_index];
15617                         fblock->block = block;
15618                         fblock->edges = xcmalloc(sizeof(*fblock->edges)*block->edge_count,
15619                                 "flow_edges");
15620                 }
15621                 {
15622                         struct lattice_node *lnode;
15623                         ins_index += 1;
15624                         lnode = &scc->lattice[ins_index];
15625                         lnode->def = ins;
15626                         lnode->out = 0;
15627                         lnode->fblock = fblock;
15628                         lnode->val = ins; /* LATTICE HIGH */
15629                         lnode->old_id = ins->id;
15630                         ins->id = ins_index;
15631                 }
15632                 ins = ins->next;
15633         } while(ins != first);
15634         /* Initialize pass two collect up the edges */
15635         block = 0;
15636         fblock = 0;
15637         ins = first;
15638         do {
15639                 {
15640                         struct triple_set *edge;
15641                         struct ssa_edge **stail;
15642                         struct lattice_node *lnode;
15643                         lnode = &scc->lattice[ins->id];
15644                         lnode->out = 0;
15645                         stail = &lnode->out;
15646                         for(edge = ins->use; edge; edge = edge->next) {
15647                                 struct ssa_edge *sedge;
15648                                 ssa_edge_index += 1;
15649                                 sedge = &scc->ssa_edges[ssa_edge_index];
15650                                 *stail = sedge;
15651                                 stail = &sedge->out_next;
15652                                 sedge->src = lnode;
15653                                 sedge->dst = &scc->lattice[edge->member->id];
15654                                 sedge->work_next = sedge->work_prev = sedge;
15655                                 sedge->out_next = 0;
15656                         }
15657                 }
15658                 if ((ins->op == OP_LABEL) && (block != ins->u.block)) {
15659                         struct flow_edge *fedge, **ftail;
15660                         struct block_set *bedge;
15661                         block = ins->u.block;
15662                         fblock = &scc->flow_blocks[block->vertex];
15663                         fblock->in = 0;
15664                         fblock->out = 0;
15665                         ftail = &fblock->out;
15666
15667                         fedge = fblock->edges;
15668                         bedge = block->edges;
15669                         for(; bedge; bedge = bedge->next, fedge++) {
15670                                 fedge->dst = &scc->flow_blocks[bedge->member->vertex];
15671                                 if (fedge->dst->block != bedge->member) {
15672                                         internal_error(state, 0, "block mismatch");
15673                                 }
15674                                 *ftail = fedge;
15675                                 ftail = &fedge->out_next;
15676                                 fedge->out_next = 0;
15677                         }
15678                         for(fedge = fblock->out; fedge; fedge = fedge->out_next) {
15679                                 fedge->src = fblock;
15680                                 fedge->work_next = fedge->work_prev = fedge;
15681                                 fedge->executable = 0;
15682                         }
15683                 }
15684                 ins = ins->next;
15685         } while (ins != first);
15686         block = 0;
15687         fblock = 0;
15688         ins = first;
15689         do {
15690                 if ((ins->op  == OP_LABEL) && (block != ins->u.block)) {
15691                         struct flow_edge **ftail;
15692                         struct block_set *bedge;
15693                         block = ins->u.block;
15694                         fblock = &scc->flow_blocks[block->vertex];
15695                         ftail = &fblock->in;
15696                         for(bedge = block->use; bedge; bedge = bedge->next) {
15697                                 struct block *src_block;
15698                                 struct flow_block *sfblock;
15699                                 struct flow_edge *sfedge;
15700                                 src_block = bedge->member;
15701                                 sfblock = &scc->flow_blocks[src_block->vertex];
15702                                 for(sfedge = sfblock->out; sfedge; sfedge = sfedge->out_next) {
15703                                         if (sfedge->dst == fblock) {
15704                                                 break;
15705                                         }
15706                                 }
15707                                 if (!sfedge) {
15708                                         internal_error(state, 0, "edge mismatch");
15709                                 }
15710                                 *ftail = sfedge;
15711                                 ftail = &sfedge->in_next;
15712                                 sfedge->in_next = 0;
15713                         }
15714                 }
15715                 ins = ins->next;
15716         } while(ins != first);
15717         /* Setup a dummy block 0 as a node above the start node */
15718         {
15719                 struct flow_block *fblock, *dst;
15720                 struct flow_edge *fedge;
15721                 fblock = &scc->flow_blocks[0];
15722                 fblock->block = 0;
15723                 fblock->edges = xcmalloc(sizeof(*fblock->edges)*1, "flow_edges");
15724                 fblock->in = 0;
15725                 fblock->out = fblock->edges;
15726                 dst = &scc->flow_blocks[state->first_block->vertex];
15727                 fedge = fblock->edges;
15728                 fedge->src        = fblock;
15729                 fedge->dst        = dst;
15730                 fedge->work_next  = fedge;
15731                 fedge->work_prev  = fedge;
15732                 fedge->in_next    = fedge->dst->in;
15733                 fedge->out_next   = 0;
15734                 fedge->executable = 0;
15735                 fedge->dst->in = fedge;
15736                 
15737                 /* Initialize the work lists */
15738                 scc->flow_work_list = 0;
15739                 scc->ssa_work_list  = 0;
15740                 scc_add_fedge(state, scc, fedge);
15741         }
15742         if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
15743                 fprintf(stderr, "ins_index: %d ssa_edge_index: %d fblock_index: %d\n",
15744                         ins_index, ssa_edge_index, fblock_index);
15745         }
15746 }
15747
15748         
15749 static void free_scc_state(
15750         struct compile_state *state, struct scc_state *scc)
15751 {
15752         int i;
15753         for(i = 0; i < state->last_vertex + 1; i++) {
15754                 struct flow_block *fblock;
15755                 fblock = &scc->flow_blocks[i];
15756                 if (fblock->edges) {
15757                         xfree(fblock->edges);
15758                         fblock->edges = 0;
15759                 }
15760         }
15761         xfree(scc->flow_blocks);
15762         xfree(scc->ssa_edges);
15763         xfree(scc->lattice);
15764         
15765 }
15766
15767 static struct lattice_node *triple_to_lattice(
15768         struct compile_state *state, struct scc_state *scc, struct triple *ins)
15769 {
15770         if (ins->id <= 0) {
15771                 internal_error(state, ins, "bad id");
15772         }
15773         return &scc->lattice[ins->id];
15774 }
15775
15776 static struct triple *preserve_lval(
15777         struct compile_state *state, struct lattice_node *lnode)
15778 {
15779         struct triple *old;
15780         /* Preserve the original value */
15781         if (lnode->val) {
15782                 old = dup_triple(state, lnode->val);
15783                 if (lnode->val != lnode->def) {
15784                         xfree(lnode->val);
15785                 }
15786                 lnode->val = 0;
15787         } else {
15788                 old = 0;
15789         }
15790         return old;
15791 }
15792
15793 static int lval_changed(struct compile_state *state, 
15794         struct triple *old, struct lattice_node *lnode)
15795 {
15796         int changed;
15797         /* See if the lattice value has changed */
15798         changed = 1;
15799         if (!old && !lnode->val) {
15800                 changed = 0;
15801         }
15802         if (changed && lnode->val && !is_const(lnode->val)) {
15803                 changed = 0;
15804         }
15805         if (changed &&
15806                 lnode->val && old &&
15807                 (memcmp(lnode->val->param, old->param,
15808                         TRIPLE_SIZE(lnode->val->sizes) * sizeof(lnode->val->param[0])) == 0) &&
15809                 (memcmp(&lnode->val->u, &old->u, sizeof(old->u)) == 0)) {
15810                 changed = 0;
15811         }
15812         if (old) {
15813                 xfree(old);
15814         }
15815         return changed;
15816
15817 }
15818
15819 static void scc_debug_lnode(
15820         struct compile_state *state, struct lattice_node *lnode, int changed)
15821 {
15822         if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
15823                 FILE *fp = stderr;
15824                 struct triple *val, **expr;
15825                 val = lnode->val? lnode->val : lnode->def;
15826                 fprintf(fp, "%p %s %3d %10s (",
15827                         lnode->def, 
15828                         ((lnode->def->op == OP_PHI)? "phi: ": "expr:"),
15829                         lnode->def->id,
15830                         tops(lnode->def->op));
15831                 expr = triple_rhs(state, lnode->def, 0);
15832                 for(;expr;expr = triple_rhs(state, lnode->def, expr)) {
15833                         if (*expr) {
15834                                 fprintf(fp, " %d", (*expr)->id);
15835                         }
15836                 }
15837                 if (val->op == OP_INTCONST) {
15838                         fprintf(fp, " <0x%08lx>", (unsigned long)(val->u.cval));
15839                 }
15840                 fprintf(fp, " ) -> %s %s\n",
15841                         ((!lnode->val)? "lo": is_const(lnode->val)? "const": "hi"),
15842                         changed? "changed" : ""
15843                         );
15844         }
15845 }
15846
15847 static void scc_visit_phi(struct compile_state *state, struct scc_state *scc, 
15848         struct lattice_node *lnode)
15849 {
15850         struct lattice_node *tmp;
15851         struct triple **slot, *old;
15852         struct flow_edge *fedge;
15853         int changed;
15854         int index;
15855         if (lnode->def->op != OP_PHI) {
15856                 internal_error(state, lnode->def, "not phi");
15857         }
15858         /* Store the original value */
15859         old = preserve_lval(state, lnode);
15860
15861         /* default to lattice high */
15862         lnode->val = lnode->def;
15863         slot = &RHS(lnode->def, 0);
15864         index = 0;
15865         for(fedge = lnode->fblock->in; fedge; index++, fedge = fedge->in_next) {
15866                 if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
15867                         fprintf(stderr, "Examining edge: %d vertex: %d executable: %d\n", 
15868                                 index,
15869                                 fedge->dst->block->vertex,
15870                                 fedge->executable
15871                                 );
15872                 }
15873                 if (!fedge->executable) {
15874                         continue;
15875                 }
15876                 if (!slot[index]) {
15877                         internal_error(state, lnode->def, "no phi value");
15878                 }
15879                 tmp = triple_to_lattice(state, scc, slot[index]);
15880                 /* meet(X, lattice low) = lattice low */
15881                 if (!tmp->val) {
15882                         lnode->val = 0;
15883                 }
15884                 /* meet(X, lattice high) = X */
15885                 else if (!tmp->val) {
15886                         lnode->val = lnode->val;
15887                 }
15888                 /* meet(lattice high, X) = X */
15889                 else if (!is_const(lnode->val)) {
15890                         lnode->val = dup_triple(state, tmp->val);
15891                         lnode->val->type = lnode->def->type;
15892                 }
15893                 /* meet(const, const) = const or lattice low */
15894                 else if (!constants_equal(state, lnode->val, tmp->val)) {
15895                         lnode->val = 0;
15896                 }
15897                 if (!lnode->val) {
15898                         break;
15899                 }
15900         }
15901         changed = lval_changed(state, old, lnode);
15902         scc_debug_lnode(state, lnode, changed);
15903
15904         /* If the lattice value has changed update the work lists. */
15905         if (changed) {
15906                 struct ssa_edge *sedge;
15907                 for(sedge = lnode->out; sedge; sedge = sedge->out_next) {
15908                         scc_add_sedge(state, scc, sedge);
15909                 }
15910         }
15911 }
15912
15913 static int compute_lnode_val(struct compile_state *state, struct scc_state *scc,
15914         struct lattice_node *lnode)
15915 {
15916         int changed;
15917         struct triple *old, *scratch;
15918         struct triple **dexpr, **vexpr;
15919         int count, i;
15920         
15921         /* Store the original value */
15922         old = preserve_lval(state, lnode);
15923
15924         /* Reinitialize the value */
15925         lnode->val = scratch = dup_triple(state, lnode->def);
15926         scratch->id = lnode->old_id;
15927         scratch->next     = scratch;
15928         scratch->prev     = scratch;
15929         scratch->use      = 0;
15930
15931         count = TRIPLE_SIZE(scratch->sizes);
15932         for(i = 0; i < count; i++) {
15933                 dexpr = &lnode->def->param[i];
15934                 vexpr = &scratch->param[i];
15935                 *vexpr = *dexpr;
15936                 if (((i < TRIPLE_MISC_OFF(scratch->sizes)) ||
15937                         (i >= TRIPLE_TARG_OFF(scratch->sizes))) &&
15938                         *dexpr) {
15939                         struct lattice_node *tmp;
15940                         tmp = triple_to_lattice(state, scc, *dexpr);
15941                         *vexpr = (tmp->val)? tmp->val : tmp->def;
15942                 }
15943         }
15944         if (triple_is_branch(state, scratch)) {
15945                 scratch->next = lnode->def->next;
15946         }
15947         /* Recompute the value */
15948 #warning "FIXME see if simplify does anything bad"
15949         /* So far it looks like only the strength reduction
15950          * optimization are things I need to worry about.
15951          */
15952         simplify(state, scratch);
15953         /* Cleanup my value */
15954         if (scratch->use) {
15955                 internal_error(state, lnode->def, "scratch used?");
15956         }
15957         if ((scratch->prev != scratch) ||
15958                 ((scratch->next != scratch) &&
15959                         (!triple_is_branch(state, lnode->def) ||
15960                                 (scratch->next != lnode->def->next)))) {
15961                 internal_error(state, lnode->def, "scratch in list?");
15962         }
15963         /* undo any uses... */
15964         count = TRIPLE_SIZE(scratch->sizes);
15965         for(i = 0; i < count; i++) {
15966                 vexpr = &scratch->param[i];
15967                 if (*vexpr) {
15968                         unuse_triple(*vexpr, scratch);
15969                 }
15970         }
15971         if (!is_const(scratch)) {
15972                 for(i = 0; i < count; i++) {
15973                         dexpr = &lnode->def->param[i];
15974                         if (((i < TRIPLE_MISC_OFF(scratch->sizes)) ||
15975                                 (i >= TRIPLE_TARG_OFF(scratch->sizes))) &&
15976                                 *dexpr) {
15977                                 struct lattice_node *tmp;
15978                                 tmp = triple_to_lattice(state, scc, *dexpr);
15979                                 if (!tmp->val) {
15980                                         lnode->val = 0;
15981                                 }
15982                         }
15983                 }
15984         }
15985         if (lnode->val && 
15986                 (lnode->val->op == lnode->def->op) &&
15987                 (memcmp(lnode->val->param, lnode->def->param, 
15988                         count * sizeof(lnode->val->param[0])) == 0) &&
15989                 (memcmp(&lnode->val->u, &lnode->def->u, sizeof(lnode->def->u)) == 0)) {
15990                 lnode->val = lnode->def;
15991         }
15992         /* Find the cases that are always lattice lo */
15993         if (lnode->val && 
15994                 triple_is_def(state, lnode->val) &&
15995                 !triple_is_pure(state, lnode->val, lnode->old_id)) {
15996                 lnode->val = 0;
15997         }
15998         /* See if the lattice value has changed */
15999         changed = lval_changed(state, old, lnode);
16000         /* See if this value should not change */
16001         if (lnode->val && 
16002                 ((      !triple_is_def(state, lnode->def)  &&
16003                         !triple_is_cond_branch(state, lnode->def)) ||
16004                         (lnode->def->op == OP_PIECE))) {
16005 #warning "FIXME constant propogate through expressions with multiple left hand sides"
16006                 if (changed) {
16007                         internal_warning(state, lnode->def, "non def changes value?");
16008                 }
16009                 lnode->val = 0;
16010         }
16011         /* Report what has just happened */
16012         if (state->compiler->debug & DEBUG_SCC_TRANSFORM2) {
16013                 display_triple_changes(stderr, scratch, lnode->def);
16014         }
16015
16016         /* See if we need to free the scratch value */
16017         if (lnode->val != scratch) {
16018                 xfree(scratch);
16019         }
16020         return changed;
16021 }
16022
16023 static void scc_visit_branch(struct compile_state *state, struct scc_state *scc,
16024         struct lattice_node *lnode)
16025 {
16026         struct lattice_node *cond;
16027         struct flow_edge *left, *right;
16028         if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
16029                 struct flow_edge *fedge;
16030                 fprintf(stderr, "%s: %d (",
16031                         tops(lnode->def->op),
16032                         lnode->def->id);
16033                 
16034                 for(fedge = lnode->fblock->out; fedge; fedge = fedge->out_next) {
16035                         fprintf(stderr, " %d", fedge->dst->block->vertex);
16036                 }
16037                 fprintf(stderr, " )");
16038                 if (TRIPLE_RHS(lnode->def->sizes) > 0) {
16039                         fprintf(stderr, " <- %d",
16040                                 RHS(lnode->def, 0)->id);
16041                 }
16042                 fprintf(stderr, "\n");
16043         }
16044         if (!triple_is_branch(state, lnode->def)) {
16045                 internal_error(state, lnode->def, "not branch");
16046         }
16047         /* This only applies to conditional branches */
16048         if (!triple_is_cond_branch(state, lnode->def)) {
16049                 return;
16050         }
16051         cond = triple_to_lattice(state, scc, RHS(lnode->def,0));
16052         for(left = cond->fblock->out; left; left = left->out_next) {
16053                 if (left->dst->block->first == lnode->def->next) {
16054                         break;
16055                 }
16056         }
16057         if (!left) {
16058                 internal_error(state, lnode->def, "Cannot find left branch edge");
16059         }
16060         for(right = cond->fblock->out; right; right = right->out_next) {
16061                 if (right->dst->block->first == TARG(lnode->def, 0)) {
16062                         break;
16063                 }
16064         }
16065         if (!right) {
16066                 internal_error(state, lnode->def, "Cannot find right branch edge");
16067         }
16068         if (cond->val && !is_const(cond->val)) {
16069 #warning "FIXME do I need to do something here?"
16070                 warning(state, cond->def, "condition not constant?");
16071                 return;
16072         }
16073         if (cond->val == 0) {
16074                 scc_add_fedge(state, scc, left);
16075                 scc_add_fedge(state, scc, right);
16076         }
16077         else if (cond->val->u.cval) {
16078                 scc_add_fedge(state, scc, right);
16079         } else {
16080                 scc_add_fedge(state, scc, left);
16081         }
16082
16083 }
16084
16085 static void scc_visit_expr(struct compile_state *state, struct scc_state *scc,
16086         struct lattice_node *lnode)
16087 {
16088         int changed;
16089
16090         changed = compute_lnode_val(state, scc, lnode);
16091         scc_debug_lnode(state, lnode, changed);
16092
16093         if (triple_is_branch(state, lnode->def)) {
16094                 scc_visit_branch(state, scc, lnode);
16095         }
16096         else if (changed) {
16097                 struct ssa_edge *sedge;
16098                 for(sedge = lnode->out; sedge; sedge = sedge->out_next) {
16099                         scc_add_sedge(state, scc, sedge);
16100                 }
16101         }
16102 }
16103
16104 static void scc_writeback_values(
16105         struct compile_state *state, struct scc_state *scc)
16106 {
16107         struct triple *first, *ins;
16108         first = state->first;
16109         ins = first;
16110         do {
16111                 struct lattice_node *lnode;
16112                 lnode = triple_to_lattice(state, scc, ins);
16113
16114                 if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
16115                         if (lnode->val && 
16116                                 !is_const(lnode->val) &&
16117                                 !triple_is_uncond_branch(state, lnode->val) &&
16118                                 (lnode->val->op != OP_NOOP)) 
16119                         {
16120                                 struct flow_edge *fedge;
16121                                 int executable;
16122                                 executable = 0;
16123                                 for(fedge = lnode->fblock->in; 
16124                                     !executable && fedge; fedge = fedge->in_next) {
16125                                         executable |= fedge->executable;
16126                                 }
16127                                 if (executable) {
16128                                         internal_warning(state, lnode->val,
16129                                                 "lattice node %d %s->%s still high?",
16130                                                 ins->id, 
16131                                                 tops(lnode->def->op),
16132                                                 tops(lnode->val->op));
16133                                 }
16134                         }
16135                 }
16136
16137                 /* Restore id */
16138                 ins->id = lnode->old_id;
16139                 if (lnode->val && (lnode->val != ins)) {
16140                         /* See if it something I know how to write back */
16141                         switch(lnode->val->op) {
16142                         case OP_INTCONST:
16143                                 mkconst(state, ins, lnode->val->u.cval);
16144                                 break;
16145                         case OP_ADDRCONST:
16146                                 mkaddr_const(state, ins, 
16147                                         MISC(lnode->val, 0), lnode->val->u.cval);
16148                                 break;
16149                         default:
16150                                 /* By default don't copy the changes,
16151                                  * recompute them in place instead.
16152                                  */
16153                                 simplify(state, ins);
16154                                 break;
16155                         }
16156                         if (is_const(lnode->val) &&
16157                                 !constants_equal(state, lnode->val, ins)) {
16158                                 internal_error(state, 0, "constants not equal");
16159                         }
16160                         /* Free the lattice nodes */
16161                         xfree(lnode->val);
16162                         lnode->val = 0;
16163                 }
16164                 ins = ins->next;
16165         } while(ins != first);
16166 }
16167
16168 static void scc_transform(struct compile_state *state)
16169 {
16170         struct scc_state scc;
16171         if (!(state->compiler->flags & COMPILER_SCC_TRANSFORM)) {
16172                 return;
16173         }
16174
16175         initialize_scc_state(state, &scc);
16176
16177         while(scc.flow_work_list || scc.ssa_work_list) {
16178                 struct flow_edge *fedge;
16179                 struct ssa_edge *sedge;
16180                 struct flow_edge *fptr;
16181                 while((fedge = scc_next_fedge(state, &scc))) {
16182                         struct block *block;
16183                         struct triple *ptr;
16184                         struct flow_block *fblock;
16185                         int reps;
16186                         int done;
16187                         if (fedge->executable) {
16188                                 continue;
16189                         }
16190                         if (!fedge->dst) {
16191                                 internal_error(state, 0, "fedge without dst");
16192                         }
16193                         if (!fedge->src) {
16194                                 internal_error(state, 0, "fedge without src");
16195                         }
16196                         fedge->executable = 1;
16197                         fblock = fedge->dst;
16198                         block = fblock->block;
16199                         reps = 0;
16200                         for(fptr = fblock->in; fptr; fptr = fptr->in_next) {
16201                                 if (fptr->executable) {
16202                                         reps++;
16203                                 }
16204                         }
16205                         
16206                         if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
16207                                 fprintf(stderr, "vertex: %d reps: %d\n", 
16208                                         block->vertex, reps);
16209                         }
16210
16211                         done = 0;
16212                         for(ptr = block->first; !done; ptr = ptr->next) {
16213                                 struct lattice_node *lnode;
16214                                 done = (ptr == block->last);
16215                                 lnode = &scc.lattice[ptr->id];
16216                                 if (ptr->op == OP_PHI) {
16217                                         scc_visit_phi(state, &scc, lnode);
16218                                 }
16219                                 else if (reps == 1) {
16220                                         scc_visit_expr(state, &scc, lnode);
16221                                 }
16222                         }
16223                         /* Add unconditional branch edges */
16224                         if (!triple_is_cond_branch(state, fblock->block->last)) {
16225                                 struct flow_edge *out;
16226                                 for(out = fblock->out; out; out = out->out_next) {
16227                                         scc_add_fedge(state, &scc, out);
16228                                 }
16229                         }
16230                 }
16231                 while((sedge = scc_next_sedge(state, &scc))) {
16232                         struct lattice_node *lnode;
16233                         struct flow_block *fblock;
16234                         lnode = sedge->dst;
16235                         fblock = lnode->fblock;
16236
16237                         if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
16238                                 fprintf(stderr, "sedge: %5d (%5d -> %5d)\n",
16239                                         sedge - scc.ssa_edges,
16240                                         sedge->src->def->id,
16241                                         sedge->dst->def->id);
16242                         }
16243
16244                         if (lnode->def->op == OP_PHI) {
16245                                 scc_visit_phi(state, &scc, lnode);
16246                         }
16247                         else {
16248                                 for(fptr = fblock->in; fptr; fptr = fptr->in_next) {
16249                                         if (fptr->executable) {
16250                                                 break;
16251                                         }
16252                                 }
16253                                 if (fptr) {
16254                                         scc_visit_expr(state, &scc, lnode);
16255                                 }
16256                         }
16257                 }
16258         }
16259         
16260         scc_writeback_values(state, &scc);
16261         free_scc_state(state, &scc);
16262         rebuild_ssa_form(state);
16263         
16264         print_blocks(state, __func__, stdout);
16265 }
16266
16267
16268 static void transform_to_arch_instructions(struct compile_state *state)
16269 {
16270         struct triple *ins, *first;
16271         first = state->first;
16272         ins = first;
16273         do {
16274                 ins = transform_to_arch_instruction(state, ins);
16275         } while(ins != first);
16276         
16277         print_blocks(state, __func__, stdout);
16278 }
16279
16280 #if DEBUG_CONSISTENCY
16281 static void verify_uses(struct compile_state *state)
16282 {
16283         struct triple *first, *ins;
16284         struct triple_set *set;
16285         first = state->first;
16286         ins = first;
16287         do {
16288                 struct triple **expr;
16289                 expr = triple_rhs(state, ins, 0);
16290                 for(; expr; expr = triple_rhs(state, ins, expr)) {
16291                         struct triple *rhs;
16292                         rhs = *expr;
16293                         for(set = rhs?rhs->use:0; set; set = set->next) {
16294                                 if (set->member == ins) {
16295                                         break;
16296                                 }
16297                         }
16298                         if (!set) {
16299                                 internal_error(state, ins, "rhs not used");
16300                         }
16301                 }
16302                 expr = triple_lhs(state, ins, 0);
16303                 for(; expr; expr = triple_lhs(state, ins, expr)) {
16304                         struct triple *lhs;
16305                         lhs = *expr;
16306                         for(set =  lhs?lhs->use:0; set; set = set->next) {
16307                                 if (set->member == ins) {
16308                                         break;
16309                                 }
16310                         }
16311                         if (!set) {
16312                                 internal_error(state, ins, "lhs not used");
16313                         }
16314                 }
16315                 ins = ins->next;
16316         } while(ins != first);
16317         
16318 }
16319 static void verify_blocks_present(struct compile_state *state)
16320 {
16321         struct triple *first, *ins;
16322         if (!state->first_block) {
16323                 return;
16324         }
16325         first = state->first;
16326         ins = first;
16327         do {
16328                 valid_ins(state, ins);
16329                 if (triple_stores_block(state, ins)) {
16330                         if (!ins->u.block) {
16331                                 internal_error(state, ins, 
16332                                         "%p not in a block?\n", ins);
16333                         }
16334                 }
16335                 ins = ins->next;
16336         } while(ins != first);
16337         
16338         
16339 }
16340
16341 static int edge_present(struct compile_state *state, struct block *block, struct triple *edge)
16342 {
16343         struct block_set *bedge;
16344         struct block *targ;
16345         targ = block_of_triple(state, edge);
16346         for(bedge = block->edges; bedge; bedge = bedge->next) {
16347                 if (bedge->member == targ) {
16348                         return 1;
16349                 }
16350         }
16351         return 0;
16352 }
16353
16354 static void verify_blocks(struct compile_state *state)
16355 {
16356         struct triple *ins;
16357         struct block *block;
16358         int blocks;
16359         block = state->first_block;
16360         if (!block) {
16361                 return;
16362         }
16363         blocks = 0;
16364         do {
16365                 int users;
16366                 struct block_set *user, *edge;
16367                 blocks++;
16368                 for(ins = block->first; ins != block->last->next; ins = ins->next) {
16369                         if (triple_stores_block(state, ins) && (ins->u.block != block)) {
16370                                 internal_error(state, ins, "inconsitent block specified");
16371                         }
16372                         valid_ins(state, ins);
16373                 }
16374                 users = 0;
16375                 for(user = block->use; user; user = user->next) {
16376                         users++;
16377                         if (!user->member->first) {
16378                                 internal_error(state, block->first, "user is empty");
16379                         }
16380                         if ((block == state->last_block) &&
16381                                 (user->member == state->first_block)) {
16382                                 continue;
16383                         }
16384                         for(edge = user->member->edges; edge; edge = edge->next) {
16385                                 if (edge->member == block) {
16386                                         break;
16387                                 }
16388                         }
16389                         if (!edge) {
16390                                 internal_error(state, user->member->first,
16391                                         "user does not use block");
16392                         }
16393                 }
16394                 if (triple_is_branch(state, block->last)) {
16395                         struct triple **expr;
16396                         expr = triple_targ(state, block->last, 0);
16397                         for(;expr; expr = triple_targ(state, block->last, expr)) {
16398                                 if (*expr && !edge_present(state, block, *expr)) {
16399                                         internal_error(state, block->last, "no edge to targ");
16400                                 }
16401                         }
16402                 }
16403                 if (!triple_is_uncond_branch(state, block->last) &&
16404                         (block != state->last_block) &&
16405                         !edge_present(state, block, block->last->next)) {
16406                         internal_error(state, block->last, "no edge to block->last->next");
16407                 }
16408                 for(edge = block->edges; edge; edge = edge->next) {
16409                         for(user = edge->member->use; user; user = user->next) {
16410                                 if (user->member == block) {
16411                                         break;
16412                                 }
16413                         }
16414                         if (!user || user->member != block) {
16415                                 internal_error(state, block->first,
16416                                         "block does not use edge");
16417                         }
16418                         if (!edge->member->first) {
16419                                 internal_error(state, block->first, "edge block is empty");
16420                         }
16421                 }
16422                 if (block->users != users) {
16423                         internal_error(state, block->first, 
16424                                 "computed users %d != stored users %d\n",
16425                                 users, block->users);
16426                 }
16427                 if (!triple_stores_block(state, block->last->next)) {
16428                         internal_error(state, block->last->next, 
16429                                 "cannot find next block");
16430                 }
16431                 block = block->last->next->u.block;
16432                 if (!block) {
16433                         internal_error(state, block->last->next,
16434                                 "bad next block");
16435                 }
16436         } while(block != state->first_block);
16437         if (blocks != state->last_vertex) {
16438                 internal_error(state, 0, "computed blocks != stored blocks %d\n",
16439                         blocks, state->last_vertex);
16440         }
16441 }
16442
16443 static void verify_domination(struct compile_state *state)
16444 {
16445         struct triple *first, *ins;
16446         struct triple_set *set;
16447         if (!state->first_block) {
16448                 return;
16449         }
16450         
16451         first = state->first;
16452         ins = first;
16453         do {
16454                 for(set = ins->use; set; set = set->next) {
16455                         struct triple **slot;
16456                         struct triple *use_point;
16457                         int i, zrhs;
16458                         use_point = 0;
16459                         zrhs = TRIPLE_RHS(set->member->sizes);
16460                         slot = &RHS(set->member, 0);
16461                         /* See if the use is on the right hand side */
16462                         for(i = 0; i < zrhs; i++) {
16463                                 if (slot[i] == ins) {
16464                                         break;
16465                                 }
16466                         }
16467                         if (i < zrhs) {
16468                                 use_point = set->member;
16469                                 if (set->member->op == OP_PHI) {
16470                                         struct block_set *bset;
16471                                         int edge;
16472                                         bset = set->member->u.block->use;
16473                                         for(edge = 0; bset && (edge < i); edge++) {
16474                                                 bset = bset->next;
16475                                         }
16476                                         if (!bset) {
16477                                                 internal_error(state, set->member, 
16478                                                         "no edge for phi rhs %d\n", i);
16479                                         }
16480                                         use_point = bset->member->last;
16481                                 }
16482                         }
16483                         if (use_point &&
16484                                 !tdominates(state, ins, use_point)) {
16485                                 internal_error(state, use_point, 
16486                                         "non dominated rhs use point?");
16487                         }
16488                 }
16489                 ins = ins->next;
16490         } while(ins != first);
16491 }
16492
16493 static void verify_rhs(struct compile_state *state)
16494 {
16495         struct triple *first, *ins;
16496         first = state->first;
16497         ins = first;
16498         do {
16499                 struct triple **slot;
16500                 int zrhs, i;
16501                 zrhs = TRIPLE_RHS(ins->sizes);
16502                 slot = &RHS(ins, 0);
16503                 for(i = 0; i < zrhs; i++) {
16504                         if (slot[i] == 0) {
16505                                 internal_error(state, ins,
16506                                         "missing rhs %d on %s",
16507                                         i, tops(ins->op));
16508                         }
16509                         if ((ins->op != OP_PHI) && (slot[i] == ins)) {
16510                                 internal_error(state, ins,
16511                                         "ins == rhs[%d] on %s",
16512                                         i, tops(ins->op));
16513                         }
16514                 }
16515                 ins = ins->next;
16516         } while(ins != first);
16517 }
16518
16519 static void verify_piece(struct compile_state *state)
16520 {
16521         struct triple *first, *ins;
16522         first = state->first;
16523         ins = first;
16524         do {
16525                 struct triple *ptr;
16526                 int lhs, i;
16527                 lhs = TRIPLE_LHS(ins->sizes);
16528                 for(ptr = ins->next, i = 0; i < lhs; i++, ptr = ptr->next) {
16529                         if (ptr != LHS(ins, i)) {
16530                                 internal_error(state, ins, "malformed lhs on %s",
16531                                         tops(ins->op));
16532                         }
16533                         if (ptr->op != OP_PIECE) {
16534                                 internal_error(state, ins, "bad lhs op %s at %d on %s",
16535                                         tops(ptr->op), i, tops(ins->op));
16536                         }
16537                         if (ptr->u.cval != i) {
16538                                 internal_error(state, ins, "bad u.cval of %d %d expected",
16539                                         ptr->u.cval, i);
16540                         }
16541                 }
16542                 ins = ins->next;
16543         } while(ins != first);
16544 }
16545
16546 static void verify_ins_colors(struct compile_state *state)
16547 {
16548         struct triple *first, *ins;
16549         
16550         first = state->first;
16551         ins = first;
16552         do {
16553                 ins = ins->next;
16554         } while(ins != first);
16555 }
16556 static void verify_consistency(struct compile_state *state)
16557 {
16558         verify_uses(state);
16559         verify_blocks_present(state);
16560         verify_blocks(state);
16561         verify_domination(state);
16562         verify_rhs(state);
16563         verify_piece(state);
16564         verify_ins_colors(state);
16565 }
16566 #else 
16567 static void verify_consistency(struct compile_state *state) {}
16568 #endif /* DEBUG_CONSISTENCY */
16569
16570 static void optimize(struct compile_state *state)
16571 {
16572         /* Dump what the instruction graph intially looks like */
16573         print_triples(state);
16574
16575         /* Replace structures with simpler data types */
16576         flatten_structures(state);
16577         print_triples(state);
16578
16579         verify_consistency(state);
16580         /* Analize the intermediate code */
16581         analyze_basic_blocks(state);
16582
16583         /* Transform the code to ssa form. */
16584         /*
16585          * The transformation to ssa form puts a phi function
16586          * on each of edge of a dominance frontier where that
16587          * phi function might be needed.  At -O2 if we don't
16588          * eleminate the excess phi functions we can get an
16589          * exponential code size growth.  So I kill the extra
16590          * phi functions early and I kill them often.
16591          */
16592         transform_to_ssa_form(state);
16593         verify_consistency(state);
16594
16595         /* Remove dead code */
16596         eliminate_inefectual_code(state);
16597         verify_consistency(state);
16598
16599         /* Do strength reduction and simple constant optimizations */
16600         simplify_all(state);
16601         verify_consistency(state);
16602         /* Propogate constants throughout the code */
16603         scc_transform(state);
16604         verify_consistency(state);
16605 #warning "WISHLIST implement single use constants (least possible register pressure)"
16606 #warning "WISHLIST implement induction variable elimination"
16607         /* Select architecture instructions and an initial partial
16608          * coloring based on architecture constraints.
16609          */
16610         transform_to_arch_instructions(state);
16611         verify_consistency(state);
16612
16613         /* Remove dead code */
16614         eliminate_inefectual_code(state);
16615         verify_consistency(state);
16616
16617         /* Color all of the variables to see if they will fit in registers */
16618         insert_copies_to_phi(state);
16619         verify_consistency(state);
16620
16621         insert_mandatory_copies(state);
16622         verify_consistency(state);
16623
16624         allocate_registers(state);
16625         verify_consistency(state);
16626
16627         /* Remove the optimization information.
16628          * This is more to check for memory consistency than to free memory.
16629          */
16630         free_basic_blocks(state);
16631 }
16632
16633 static void print_op_asm(struct compile_state *state,
16634         struct triple *ins, FILE *fp)
16635 {
16636         struct asm_info *info;
16637         const char *ptr;
16638         unsigned lhs, rhs, i;
16639         info = ins->u.ainfo;
16640         lhs = TRIPLE_LHS(ins->sizes);
16641         rhs = TRIPLE_RHS(ins->sizes);
16642         /* Don't count the clobbers in lhs */
16643         for(i = 0; i < lhs; i++) {
16644                 if (LHS(ins, i)->type == &void_type) {
16645                         break;
16646                 }
16647         }
16648         lhs = i;
16649         fprintf(fp, "#ASM\n");
16650         fputc('\t', fp);
16651         for(ptr = info->str; *ptr; ptr++) {
16652                 char *next;
16653                 unsigned long param;
16654                 struct triple *piece;
16655                 if (*ptr != '%') {
16656                         fputc(*ptr, fp);
16657                         continue;
16658                 }
16659                 ptr++;
16660                 if (*ptr == '%') {
16661                         fputc('%', fp);
16662                         continue;
16663                 }
16664                 param = strtoul(ptr, &next, 10);
16665                 if (ptr == next) {
16666                         error(state, ins, "Invalid asm template");
16667                 }
16668                 if (param >= (lhs + rhs)) {
16669                         error(state, ins, "Invalid param %%%u in asm template",
16670                                 param);
16671                 }
16672                 piece = (param < lhs)? LHS(ins, param) : RHS(ins, param - lhs);
16673                 fprintf(fp, "%s", 
16674                         arch_reg_str(ID_REG(piece->id)));
16675                 ptr = next -1;
16676         }
16677         fprintf(fp, "\n#NOT ASM\n");
16678 }
16679
16680
16681 /* Only use the low x86 byte registers.  This allows me
16682  * allocate the entire register when a byte register is used.
16683  */
16684 #define X86_4_8BIT_GPRS 1
16685
16686 /* x86 featrues */
16687 #define X86_MMX_REGS (1<<0)
16688 #define X86_XMM_REGS (1<<1)
16689
16690 /* The x86 register classes */
16691 #define REGC_FLAGS       0
16692 #define REGC_GPR8        1
16693 #define REGC_GPR16       2
16694 #define REGC_GPR32       3
16695 #define REGC_DIVIDEND64  4
16696 #define REGC_DIVIDEND32  5
16697 #define REGC_MMX         6
16698 #define REGC_XMM         7
16699 #define REGC_GPR32_8     8
16700 #define REGC_GPR16_8     9
16701 #define REGC_GPR8_LO    10
16702 #define REGC_IMM32      11
16703 #define REGC_IMM16      12
16704 #define REGC_IMM8       13
16705 #define LAST_REGC  REGC_IMM8
16706 #if LAST_REGC >= MAX_REGC
16707 #error "MAX_REGC is to low"
16708 #endif
16709
16710 /* Register class masks */
16711 #define REGCM_FLAGS      (1 << REGC_FLAGS)
16712 #define REGCM_GPR8       (1 << REGC_GPR8)
16713 #define REGCM_GPR16      (1 << REGC_GPR16)
16714 #define REGCM_GPR32      (1 << REGC_GPR32)
16715 #define REGCM_DIVIDEND64 (1 << REGC_DIVIDEND64)
16716 #define REGCM_DIVIDEND32 (1 << REGC_DIVIDEND32)
16717 #define REGCM_MMX        (1 << REGC_MMX)
16718 #define REGCM_XMM        (1 << REGC_XMM)
16719 #define REGCM_GPR32_8    (1 << REGC_GPR32_8)
16720 #define REGCM_GPR16_8    (1 << REGC_GPR16_8)
16721 #define REGCM_GPR8_LO    (1 << REGC_GPR8_LO)
16722 #define REGCM_IMM32      (1 << REGC_IMM32)
16723 #define REGCM_IMM16      (1 << REGC_IMM16)
16724 #define REGCM_IMM8       (1 << REGC_IMM8)
16725 #define REGCM_ALL        ((1 << (LAST_REGC + 1)) - 1)
16726
16727 /* The x86 registers */
16728 #define REG_EFLAGS  2
16729 #define REGC_FLAGS_FIRST REG_EFLAGS
16730 #define REGC_FLAGS_LAST  REG_EFLAGS
16731 #define REG_AL      3
16732 #define REG_BL      4
16733 #define REG_CL      5
16734 #define REG_DL      6
16735 #define REG_AH      7
16736 #define REG_BH      8
16737 #define REG_CH      9
16738 #define REG_DH      10
16739 #define REGC_GPR8_LO_FIRST REG_AL
16740 #define REGC_GPR8_LO_LAST  REG_DL
16741 #define REGC_GPR8_FIRST  REG_AL
16742 #define REGC_GPR8_LAST   REG_DH
16743 #define REG_AX     11
16744 #define REG_BX     12
16745 #define REG_CX     13
16746 #define REG_DX     14
16747 #define REG_SI     15
16748 #define REG_DI     16
16749 #define REG_BP     17
16750 #define REG_SP     18
16751 #define REGC_GPR16_FIRST REG_AX
16752 #define REGC_GPR16_LAST  REG_SP
16753 #define REG_EAX    19
16754 #define REG_EBX    20
16755 #define REG_ECX    21
16756 #define REG_EDX    22
16757 #define REG_ESI    23
16758 #define REG_EDI    24
16759 #define REG_EBP    25
16760 #define REG_ESP    26
16761 #define REGC_GPR32_FIRST REG_EAX
16762 #define REGC_GPR32_LAST  REG_ESP
16763 #define REG_EDXEAX 27
16764 #define REGC_DIVIDEND64_FIRST REG_EDXEAX
16765 #define REGC_DIVIDEND64_LAST  REG_EDXEAX
16766 #define REG_DXAX   28
16767 #define REGC_DIVIDEND32_FIRST REG_DXAX
16768 #define REGC_DIVIDEND32_LAST  REG_DXAX
16769 #define REG_MMX0   29
16770 #define REG_MMX1   30
16771 #define REG_MMX2   31
16772 #define REG_MMX3   32
16773 #define REG_MMX4   33
16774 #define REG_MMX5   34
16775 #define REG_MMX6   35
16776 #define REG_MMX7   36
16777 #define REGC_MMX_FIRST REG_MMX0
16778 #define REGC_MMX_LAST  REG_MMX7
16779 #define REG_XMM0   37
16780 #define REG_XMM1   38
16781 #define REG_XMM2   39
16782 #define REG_XMM3   40
16783 #define REG_XMM4   41
16784 #define REG_XMM5   42
16785 #define REG_XMM6   43
16786 #define REG_XMM7   44
16787 #define REGC_XMM_FIRST REG_XMM0
16788 #define REGC_XMM_LAST  REG_XMM7
16789 #warning "WISHLIST figure out how to use pinsrw and pextrw to better use extended regs"
16790 #define LAST_REG   REG_XMM7
16791
16792 #define REGC_GPR32_8_FIRST REG_EAX
16793 #define REGC_GPR32_8_LAST  REG_EDX
16794 #define REGC_GPR16_8_FIRST REG_AX
16795 #define REGC_GPR16_8_LAST  REG_DX
16796
16797 #define REGC_IMM8_FIRST    -1
16798 #define REGC_IMM8_LAST     -1
16799 #define REGC_IMM16_FIRST   -2
16800 #define REGC_IMM16_LAST    -1
16801 #define REGC_IMM32_FIRST   -4
16802 #define REGC_IMM32_LAST    -1
16803
16804 #if LAST_REG >= MAX_REGISTERS
16805 #error "MAX_REGISTERS to low"
16806 #endif
16807
16808
16809 static unsigned regc_size[LAST_REGC +1] = {
16810         [REGC_FLAGS]      = REGC_FLAGS_LAST      - REGC_FLAGS_FIRST + 1,
16811         [REGC_GPR8]       = REGC_GPR8_LAST       - REGC_GPR8_FIRST + 1,
16812         [REGC_GPR16]      = REGC_GPR16_LAST      - REGC_GPR16_FIRST + 1,
16813         [REGC_GPR32]      = REGC_GPR32_LAST      - REGC_GPR32_FIRST + 1,
16814         [REGC_DIVIDEND64] = REGC_DIVIDEND64_LAST - REGC_DIVIDEND64_FIRST + 1,
16815         [REGC_DIVIDEND32] = REGC_DIVIDEND32_LAST - REGC_DIVIDEND32_FIRST + 1,
16816         [REGC_MMX]        = REGC_MMX_LAST        - REGC_MMX_FIRST + 1,
16817         [REGC_XMM]        = REGC_XMM_LAST        - REGC_XMM_FIRST + 1,
16818         [REGC_GPR32_8]    = REGC_GPR32_8_LAST    - REGC_GPR32_8_FIRST + 1,
16819         [REGC_GPR16_8]    = REGC_GPR16_8_LAST    - REGC_GPR16_8_FIRST + 1,
16820         [REGC_GPR8_LO]    = REGC_GPR8_LO_LAST    - REGC_GPR8_LO_FIRST + 1,
16821         [REGC_IMM32]      = 0,
16822         [REGC_IMM16]      = 0,
16823         [REGC_IMM8]       = 0,
16824 };
16825
16826 static const struct {
16827         int first, last;
16828 } regcm_bound[LAST_REGC + 1] = {
16829         [REGC_FLAGS]      = { REGC_FLAGS_FIRST,      REGC_FLAGS_LAST },
16830         [REGC_GPR8]       = { REGC_GPR8_FIRST,       REGC_GPR8_LAST },
16831         [REGC_GPR16]      = { REGC_GPR16_FIRST,      REGC_GPR16_LAST },
16832         [REGC_GPR32]      = { REGC_GPR32_FIRST,      REGC_GPR32_LAST },
16833         [REGC_DIVIDEND64] = { REGC_DIVIDEND64_FIRST, REGC_DIVIDEND64_LAST },
16834         [REGC_DIVIDEND32] = { REGC_DIVIDEND32_FIRST, REGC_DIVIDEND32_LAST },
16835         [REGC_MMX]        = { REGC_MMX_FIRST,        REGC_MMX_LAST },
16836         [REGC_XMM]        = { REGC_XMM_FIRST,        REGC_XMM_LAST },
16837         [REGC_GPR32_8]    = { REGC_GPR32_8_FIRST,    REGC_GPR32_8_LAST },
16838         [REGC_GPR16_8]    = { REGC_GPR16_8_FIRST,    REGC_GPR16_8_LAST },
16839         [REGC_GPR8_LO]    = { REGC_GPR8_LO_FIRST,    REGC_GPR8_LO_LAST },
16840         [REGC_IMM32]      = { REGC_IMM32_FIRST,      REGC_IMM32_LAST },
16841         [REGC_IMM16]      = { REGC_IMM16_FIRST,      REGC_IMM16_LAST },
16842         [REGC_IMM8]       = { REGC_IMM8_FIRST,       REGC_IMM8_LAST },
16843 };
16844
16845 static void init_arch_state(struct arch_state *arch)
16846 {
16847         memset(arch, 0, sizeof(*arch));
16848         arch->features = 0;
16849 }
16850
16851 static int arch_encode_flag(struct arch_state *arch, const char *flag)
16852 {
16853         static const struct compiler_flag flags[] = {
16854                 { "mmx", X86_MMX_REGS },
16855                 { "sse", X86_XMM_REGS },
16856                 { 0,     0 },
16857         };
16858         static const struct compiler_flag cpus[] = {
16859                 { "i386", 0 },
16860                 { "p2",   X86_MMX_REGS },
16861                 { "p3",   X86_MMX_REGS | X86_XMM_REGS },
16862                 { "p4",   X86_MMX_REGS | X86_XMM_REGS },
16863                 { "k7",   X86_MMX_REGS },
16864                 { "k8",   X86_MMX_REGS | X86_XMM_REGS },
16865                 { "c3",   X86_MMX_REGS },
16866                 { "c3-2", X86_MMX_REGS | X86_XMM_REGS }, /* Nehemiah */
16867                 {  0,     0 }
16868         };
16869         int result;
16870         int act;
16871
16872         act = 1;
16873         result = -1;
16874         if (strncmp(flag, "no-", 3) == 0) {
16875                 flag += 3;
16876                 act = 0;
16877         }
16878         if (act && strncmp(flag, "cpu=", 4) == 0) {
16879                 flag += 4;
16880                 result = set_flag(cpus, &arch->features, 1, flag);
16881         }
16882         else {
16883                 result = set_flag(flags, &arch->features, act, flag);
16884         }
16885         return result;
16886 }
16887
16888 static unsigned arch_regc_size(struct compile_state *state, int class)
16889 {
16890         if ((class < 0) || (class > LAST_REGC)) {
16891                 return 0;
16892         }
16893         return regc_size[class];
16894 }
16895
16896 static int arch_regcm_intersect(unsigned regcm1, unsigned regcm2)
16897 {
16898         /* See if two register classes may have overlapping registers */
16899         unsigned gpr_mask = REGCM_GPR8 | REGCM_GPR8_LO | REGCM_GPR16_8 | REGCM_GPR16 |
16900                 REGCM_GPR32_8 | REGCM_GPR32 | 
16901                 REGCM_DIVIDEND32 | REGCM_DIVIDEND64;
16902
16903         /* Special case for the immediates */
16904         if ((regcm1 & (REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8)) &&
16905                 ((regcm1 & ~(REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8)) == 0) &&
16906                 (regcm2 & (REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8)) &&
16907                 ((regcm2 & ~(REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8)) == 0)) { 
16908                 return 0;
16909         }
16910         return (regcm1 & regcm2) ||
16911                 ((regcm1 & gpr_mask) && (regcm2 & gpr_mask));
16912 }
16913
16914 static void arch_reg_equivs(
16915         struct compile_state *state, unsigned *equiv, int reg)
16916 {
16917         if ((reg < 0) || (reg > LAST_REG)) {
16918                 internal_error(state, 0, "invalid register");
16919         }
16920         *equiv++ = reg;
16921         switch(reg) {
16922         case REG_AL:
16923 #if X86_4_8BIT_GPRS
16924                 *equiv++ = REG_AH;
16925 #endif
16926                 *equiv++ = REG_AX;
16927                 *equiv++ = REG_EAX;
16928                 *equiv++ = REG_DXAX;
16929                 *equiv++ = REG_EDXEAX;
16930                 break;
16931         case REG_AH:
16932 #if X86_4_8BIT_GPRS
16933                 *equiv++ = REG_AL;
16934 #endif
16935                 *equiv++ = REG_AX;
16936                 *equiv++ = REG_EAX;
16937                 *equiv++ = REG_DXAX;
16938                 *equiv++ = REG_EDXEAX;
16939                 break;
16940         case REG_BL:  
16941 #if X86_4_8BIT_GPRS
16942                 *equiv++ = REG_BH;
16943 #endif
16944                 *equiv++ = REG_BX;
16945                 *equiv++ = REG_EBX;
16946                 break;
16947
16948         case REG_BH:
16949 #if X86_4_8BIT_GPRS
16950                 *equiv++ = REG_BL;
16951 #endif
16952                 *equiv++ = REG_BX;
16953                 *equiv++ = REG_EBX;
16954                 break;
16955         case REG_CL:
16956 #if X86_4_8BIT_GPRS
16957                 *equiv++ = REG_CH;
16958 #endif
16959                 *equiv++ = REG_CX;
16960                 *equiv++ = REG_ECX;
16961                 break;
16962
16963         case REG_CH:
16964 #if X86_4_8BIT_GPRS
16965                 *equiv++ = REG_CL;
16966 #endif
16967                 *equiv++ = REG_CX;
16968                 *equiv++ = REG_ECX;
16969                 break;
16970         case REG_DL:
16971 #if X86_4_8BIT_GPRS
16972                 *equiv++ = REG_DH;
16973 #endif
16974                 *equiv++ = REG_DX;
16975                 *equiv++ = REG_EDX;
16976                 *equiv++ = REG_DXAX;
16977                 *equiv++ = REG_EDXEAX;
16978                 break;
16979         case REG_DH:
16980 #if X86_4_8BIT_GPRS
16981                 *equiv++ = REG_DL;
16982 #endif
16983                 *equiv++ = REG_DX;
16984                 *equiv++ = REG_EDX;
16985                 *equiv++ = REG_DXAX;
16986                 *equiv++ = REG_EDXEAX;
16987                 break;
16988         case REG_AX:
16989                 *equiv++ = REG_AL;
16990                 *equiv++ = REG_AH;
16991                 *equiv++ = REG_EAX;
16992                 *equiv++ = REG_DXAX;
16993                 *equiv++ = REG_EDXEAX;
16994                 break;
16995         case REG_BX:
16996                 *equiv++ = REG_BL;
16997                 *equiv++ = REG_BH;
16998                 *equiv++ = REG_EBX;
16999                 break;
17000         case REG_CX:  
17001                 *equiv++ = REG_CL;
17002                 *equiv++ = REG_CH;
17003                 *equiv++ = REG_ECX;
17004                 break;
17005         case REG_DX:  
17006                 *equiv++ = REG_DL;
17007                 *equiv++ = REG_DH;
17008                 *equiv++ = REG_EDX;
17009                 *equiv++ = REG_DXAX;
17010                 *equiv++ = REG_EDXEAX;
17011                 break;
17012         case REG_SI:  
17013                 *equiv++ = REG_ESI;
17014                 break;
17015         case REG_DI:
17016                 *equiv++ = REG_EDI;
17017                 break;
17018         case REG_BP:
17019                 *equiv++ = REG_EBP;
17020                 break;
17021         case REG_SP:
17022                 *equiv++ = REG_ESP;
17023                 break;
17024         case REG_EAX:
17025                 *equiv++ = REG_AL;
17026                 *equiv++ = REG_AH;
17027                 *equiv++ = REG_AX;
17028                 *equiv++ = REG_DXAX;
17029                 *equiv++ = REG_EDXEAX;
17030                 break;
17031         case REG_EBX:
17032                 *equiv++ = REG_BL;
17033                 *equiv++ = REG_BH;
17034                 *equiv++ = REG_BX;
17035                 break;
17036         case REG_ECX:
17037                 *equiv++ = REG_CL;
17038                 *equiv++ = REG_CH;
17039                 *equiv++ = REG_CX;
17040                 break;
17041         case REG_EDX:
17042                 *equiv++ = REG_DL;
17043                 *equiv++ = REG_DH;
17044                 *equiv++ = REG_DX;
17045                 *equiv++ = REG_DXAX;
17046                 *equiv++ = REG_EDXEAX;
17047                 break;
17048         case REG_ESI: 
17049                 *equiv++ = REG_SI;
17050                 break;
17051         case REG_EDI: 
17052                 *equiv++ = REG_DI;
17053                 break;
17054         case REG_EBP: 
17055                 *equiv++ = REG_BP;
17056                 break;
17057         case REG_ESP: 
17058                 *equiv++ = REG_SP;
17059                 break;
17060         case REG_DXAX: 
17061                 *equiv++ = REG_AL;
17062                 *equiv++ = REG_AH;
17063                 *equiv++ = REG_DL;
17064                 *equiv++ = REG_DH;
17065                 *equiv++ = REG_AX;
17066                 *equiv++ = REG_DX;
17067                 *equiv++ = REG_EAX;
17068                 *equiv++ = REG_EDX;
17069                 *equiv++ = REG_EDXEAX;
17070                 break;
17071         case REG_EDXEAX: 
17072                 *equiv++ = REG_AL;
17073                 *equiv++ = REG_AH;
17074                 *equiv++ = REG_DL;
17075                 *equiv++ = REG_DH;
17076                 *equiv++ = REG_AX;
17077                 *equiv++ = REG_DX;
17078                 *equiv++ = REG_EAX;
17079                 *equiv++ = REG_EDX;
17080                 *equiv++ = REG_DXAX;
17081                 break;
17082         }
17083         *equiv++ = REG_UNSET; 
17084 }
17085
17086 static unsigned arch_avail_mask(struct compile_state *state)
17087 {
17088         unsigned avail_mask;
17089         /* REGCM_GPR8 is not available */
17090         avail_mask = REGCM_GPR8_LO | REGCM_GPR16_8 | REGCM_GPR16 | 
17091                 REGCM_GPR32 | REGCM_GPR32_8 | 
17092                 REGCM_DIVIDEND32 | REGCM_DIVIDEND64 |
17093                 REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8 | REGCM_FLAGS;
17094         if (state->arch->features & X86_MMX_REGS) {
17095                 avail_mask |= REGCM_MMX;
17096         }
17097         if (state->arch->features & X86_XMM_REGS) {
17098                 avail_mask |= REGCM_XMM;
17099         }
17100         return avail_mask;
17101 }
17102
17103 static unsigned arch_regcm_normalize(struct compile_state *state, unsigned regcm)
17104 {
17105         unsigned mask, result;
17106         int class, class2;
17107         result = regcm;
17108
17109         for(class = 0, mask = 1; mask; mask <<= 1, class++) {
17110                 if ((result & mask) == 0) {
17111                         continue;
17112                 }
17113                 if (class > LAST_REGC) {
17114                         result &= ~mask;
17115                 }
17116                 for(class2 = 0; class2 <= LAST_REGC; class2++) {
17117                         if ((regcm_bound[class2].first >= regcm_bound[class].first) &&
17118                                 (regcm_bound[class2].last <= regcm_bound[class].last)) {
17119                                 result |= (1 << class2);
17120                         }
17121                 }
17122         }
17123         result &= arch_avail_mask(state);
17124         return result;
17125 }
17126
17127 static unsigned arch_regcm_reg_normalize(struct compile_state *state, unsigned regcm)
17128 {
17129         /* Like arch_regcm_normalize except immediate register classes are excluded */
17130         regcm = arch_regcm_normalize(state, regcm);
17131         /* Remove the immediate register classes */
17132         regcm &= ~(REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8);
17133         return regcm;
17134         
17135 }
17136
17137 static unsigned arch_reg_regcm(struct compile_state *state, int reg)
17138 {
17139         unsigned mask;
17140         int class;
17141         mask = 0;
17142         for(class = 0; class <= LAST_REGC; class++) {
17143                 if ((reg >= regcm_bound[class].first) &&
17144                         (reg <= regcm_bound[class].last)) {
17145                         mask |= (1 << class);
17146                 }
17147         }
17148         if (!mask) {
17149                 internal_error(state, 0, "reg %d not in any class", reg);
17150         }
17151         return mask;
17152 }
17153
17154 static struct reg_info arch_reg_constraint(
17155         struct compile_state *state, struct type *type, const char *constraint)
17156 {
17157         static const struct {
17158                 char class;
17159                 unsigned int mask;
17160                 unsigned int reg;
17161         } constraints[] = {
17162                 { 'r', REGCM_GPR32,   REG_UNSET },
17163                 { 'g', REGCM_GPR32,   REG_UNSET },
17164                 { 'p', REGCM_GPR32,   REG_UNSET },
17165                 { 'q', REGCM_GPR8_LO, REG_UNSET },
17166                 { 'Q', REGCM_GPR32_8, REG_UNSET },
17167                 { 'x', REGCM_XMM,     REG_UNSET },
17168                 { 'y', REGCM_MMX,     REG_UNSET },
17169                 { 'a', REGCM_GPR32,   REG_EAX },
17170                 { 'b', REGCM_GPR32,   REG_EBX },
17171                 { 'c', REGCM_GPR32,   REG_ECX },
17172                 { 'd', REGCM_GPR32,   REG_EDX },
17173                 { 'D', REGCM_GPR32,   REG_EDI },
17174                 { 'S', REGCM_GPR32,   REG_ESI },
17175                 { '\0', 0, REG_UNSET },
17176         };
17177         unsigned int regcm;
17178         unsigned int mask, reg;
17179         struct reg_info result;
17180         const char *ptr;
17181         regcm = arch_type_to_regcm(state, type);
17182         reg = REG_UNSET;
17183         mask = 0;
17184         for(ptr = constraint; *ptr; ptr++) {
17185                 int i;
17186                 if (*ptr ==  ' ') {
17187                         continue;
17188                 }
17189                 for(i = 0; constraints[i].class != '\0'; i++) {
17190                         if (constraints[i].class == *ptr) {
17191                                 break;
17192                         }
17193                 }
17194                 if (constraints[i].class == '\0') {
17195                         error(state, 0, "invalid register constraint ``%c''", *ptr);
17196                         break;
17197                 }
17198                 if ((constraints[i].mask & regcm) == 0) {
17199                         error(state, 0, "invalid register class %c specified",
17200                                 *ptr);
17201                 }
17202                 mask |= constraints[i].mask;
17203                 if (constraints[i].reg != REG_UNSET) {
17204                         if ((reg != REG_UNSET) && (reg != constraints[i].reg)) {
17205                                 error(state, 0, "Only one register may be specified");
17206                         }
17207                         reg = constraints[i].reg;
17208                 }
17209         }
17210         result.reg = reg;
17211         result.regcm = mask;
17212         return result;
17213 }
17214
17215 static struct reg_info arch_reg_clobber(
17216         struct compile_state *state, const char *clobber)
17217 {
17218         struct reg_info result;
17219         if (strcmp(clobber, "memory") == 0) {
17220                 result.reg = REG_UNSET;
17221                 result.regcm = 0;
17222         }
17223         else if (strcmp(clobber, "%eax") == 0) {
17224                 result.reg = REG_EAX;
17225                 result.regcm = REGCM_GPR32;
17226         }
17227         else if (strcmp(clobber, "%ebx") == 0) {
17228                 result.reg = REG_EBX;
17229                 result.regcm = REGCM_GPR32;
17230         }
17231         else if (strcmp(clobber, "%ecx") == 0) {
17232                 result.reg = REG_ECX;
17233                 result.regcm = REGCM_GPR32;
17234         }
17235         else if (strcmp(clobber, "%edx") == 0) {
17236                 result.reg = REG_EDX;
17237                 result.regcm = REGCM_GPR32;
17238         }
17239         else if (strcmp(clobber, "%esi") == 0) {
17240                 result.reg = REG_ESI;
17241                 result.regcm = REGCM_GPR32;
17242         }
17243         else if (strcmp(clobber, "%edi") == 0) {
17244                 result.reg = REG_EDI;
17245                 result.regcm = REGCM_GPR32;
17246         }
17247         else if (strcmp(clobber, "%ebp") == 0) {
17248                 result.reg = REG_EBP;
17249                 result.regcm = REGCM_GPR32;
17250         }
17251         else if (strcmp(clobber, "%esp") == 0) {
17252                 result.reg = REG_ESP;
17253                 result.regcm = REGCM_GPR32;
17254         }
17255         else if (strcmp(clobber, "cc") == 0) {
17256                 result.reg = REG_EFLAGS;
17257                 result.regcm = REGCM_FLAGS;
17258         }
17259         else if ((strncmp(clobber, "xmm", 3) == 0)  &&
17260                 octdigitp(clobber[3]) && (clobber[4] == '\0')) {
17261                 result.reg = REG_XMM0 + octdigval(clobber[3]);
17262                 result.regcm = REGCM_XMM;
17263         }
17264         else if ((strncmp(clobber, "mmx", 3) == 0) &&
17265                 octdigitp(clobber[3]) && (clobber[4] == '\0')) {
17266                 result.reg = REG_MMX0 + octdigval(clobber[3]);
17267                 result.regcm = REGCM_MMX;
17268         }
17269         else {
17270                 error(state, 0, "Invalid register clobber");
17271                 result.reg = REG_UNSET;
17272                 result.regcm = 0;
17273         }
17274         return result;
17275 }
17276
17277 static int do_select_reg(struct compile_state *state, 
17278         char *used, int reg, unsigned classes)
17279 {
17280         unsigned mask;
17281         if (used[reg]) {
17282                 return REG_UNSET;
17283         }
17284         mask = arch_reg_regcm(state, reg);
17285         return (classes & mask) ? reg : REG_UNSET;
17286 }
17287
17288 static int arch_select_free_register(
17289         struct compile_state *state, char *used, int classes)
17290 {
17291         /* Live ranges with the most neighbors are colored first.
17292          *
17293          * Generally it does not matter which colors are given
17294          * as the register allocator attempts to color live ranges
17295          * in an order where you are guaranteed not to run out of colors.
17296          *
17297          * Occasionally the register allocator cannot find an order
17298          * of register selection that will find a free color.  To
17299          * increase the odds the register allocator will work when
17300          * it guesses first give out registers from register classes
17301          * least likely to run out of registers.
17302          * 
17303          */
17304         int i, reg;
17305         reg = REG_UNSET;
17306         for(i = REGC_XMM_FIRST; (reg == REG_UNSET) && (i <= REGC_XMM_LAST); i++) {
17307                 reg = do_select_reg(state, used, i, classes);
17308         }
17309         for(i = REGC_MMX_FIRST; (reg == REG_UNSET) && (i <= REGC_MMX_LAST); i++) {
17310                 reg = do_select_reg(state, used, i, classes);
17311         }
17312         for(i = REGC_GPR32_LAST; (reg == REG_UNSET) && (i >= REGC_GPR32_FIRST); i--) {
17313                 reg = do_select_reg(state, used, i, classes);
17314         }
17315         for(i = REGC_GPR16_FIRST; (reg == REG_UNSET) && (i <= REGC_GPR16_LAST); i++) {
17316                 reg = do_select_reg(state, used, i, classes);
17317         }
17318         for(i = REGC_GPR8_FIRST; (reg == REG_UNSET) && (i <= REGC_GPR8_LAST); i++) {
17319                 reg = do_select_reg(state, used, i, classes);
17320         }
17321         for(i = REGC_GPR8_LO_FIRST; (reg == REG_UNSET) && (i <= REGC_GPR8_LO_LAST); i++) {
17322                 reg = do_select_reg(state, used, i, classes);
17323         }
17324         for(i = REGC_DIVIDEND32_FIRST; (reg == REG_UNSET) && (i <= REGC_DIVIDEND32_LAST); i++) {
17325                 reg = do_select_reg(state, used, i, classes);
17326         }
17327         for(i = REGC_DIVIDEND64_FIRST; (reg == REG_UNSET) && (i <= REGC_DIVIDEND64_LAST); i++) {
17328                 reg = do_select_reg(state, used, i, classes);
17329         }
17330         for(i = REGC_FLAGS_FIRST; (reg == REG_UNSET) && (i <= REGC_FLAGS_LAST); i++) {
17331                 reg = do_select_reg(state, used, i, classes);
17332         }
17333         return reg;
17334 }
17335
17336
17337 static unsigned arch_type_to_regcm(struct compile_state *state, struct type *type) 
17338 {
17339 #warning "FIXME force types smaller (if legal) before I get here"
17340         unsigned mask;
17341         mask = 0;
17342         switch(type->type & TYPE_MASK) {
17343         case TYPE_ARRAY:
17344         case TYPE_VOID: 
17345                 mask = 0; 
17346                 break;
17347         case TYPE_CHAR:
17348         case TYPE_UCHAR:
17349                 mask = REGCM_GPR8 | REGCM_GPR8_LO |
17350                         REGCM_GPR16 | REGCM_GPR16_8 | 
17351                         REGCM_GPR32 | REGCM_GPR32_8 |
17352                         REGCM_DIVIDEND32 | REGCM_DIVIDEND64 |
17353                         REGCM_MMX | REGCM_XMM |
17354                         REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8;
17355                 break;
17356         case TYPE_SHORT:
17357         case TYPE_USHORT:
17358                 mask =  REGCM_GPR16 | REGCM_GPR16_8 |
17359                         REGCM_GPR32 | REGCM_GPR32_8 |
17360                         REGCM_DIVIDEND32 | REGCM_DIVIDEND64 |
17361                         REGCM_MMX | REGCM_XMM |
17362                         REGCM_IMM32 | REGCM_IMM16;
17363                 break;
17364         case TYPE_INT:
17365         case TYPE_UINT:
17366         case TYPE_LONG:
17367         case TYPE_ULONG:
17368         case TYPE_POINTER:
17369                 mask =  REGCM_GPR32 | REGCM_GPR32_8 |
17370                         REGCM_DIVIDEND32 | REGCM_DIVIDEND64 |
17371                         REGCM_MMX | REGCM_XMM |
17372                         REGCM_IMM32;
17373                 break;
17374         default:
17375                 internal_error(state, 0, "no register class for type");
17376                 break;
17377         }
17378         mask = arch_regcm_normalize(state, mask);
17379         return mask;
17380 }
17381
17382 static int is_imm32(struct triple *imm)
17383 {
17384         return ((imm->op == OP_INTCONST) && (imm->u.cval <= 0xffffffffUL)) ||
17385                 (imm->op == OP_ADDRCONST);
17386         
17387 }
17388 static int is_imm16(struct triple *imm)
17389 {
17390         return ((imm->op == OP_INTCONST) && (imm->u.cval <= 0xffff));
17391 }
17392 static int is_imm8(struct triple *imm)
17393 {
17394         return ((imm->op == OP_INTCONST) && (imm->u.cval <= 0xff));
17395 }
17396
17397 static int get_imm32(struct triple *ins, struct triple **expr)
17398 {
17399         struct triple *imm;
17400         imm = *expr;
17401         while(imm->op == OP_COPY) {
17402                 imm = RHS(imm, 0);
17403         }
17404         if (!is_imm32(imm)) {
17405                 return 0;
17406         }
17407         unuse_triple(*expr, ins);
17408         use_triple(imm, ins);
17409         *expr = imm;
17410         return 1;
17411 }
17412
17413 static int get_imm8(struct triple *ins, struct triple **expr)
17414 {
17415         struct triple *imm;
17416         imm = *expr;
17417         while(imm->op == OP_COPY) {
17418                 imm = RHS(imm, 0);
17419         }
17420         if (!is_imm8(imm)) {
17421                 return 0;
17422         }
17423         unuse_triple(*expr, ins);
17424         use_triple(imm, ins);
17425         *expr = imm;
17426         return 1;
17427 }
17428
17429 #define TEMPLATE_NOP           0
17430 #define TEMPLATE_INTCONST8     1
17431 #define TEMPLATE_INTCONST32    2
17432 #define TEMPLATE_COPY8_REG     3
17433 #define TEMPLATE_COPY16_REG    4
17434 #define TEMPLATE_COPY32_REG    5
17435 #define TEMPLATE_COPY_IMM8     6
17436 #define TEMPLATE_COPY_IMM16    7
17437 #define TEMPLATE_COPY_IMM32    8
17438 #define TEMPLATE_PHI8          9
17439 #define TEMPLATE_PHI16        10
17440 #define TEMPLATE_PHI32        11
17441 #define TEMPLATE_STORE8       12
17442 #define TEMPLATE_STORE16      13
17443 #define TEMPLATE_STORE32      14
17444 #define TEMPLATE_LOAD8        15
17445 #define TEMPLATE_LOAD16       16
17446 #define TEMPLATE_LOAD32       17
17447 #define TEMPLATE_BINARY8_REG  18
17448 #define TEMPLATE_BINARY16_REG 19
17449 #define TEMPLATE_BINARY32_REG 20
17450 #define TEMPLATE_BINARY8_IMM  21
17451 #define TEMPLATE_BINARY16_IMM 22
17452 #define TEMPLATE_BINARY32_IMM 23
17453 #define TEMPLATE_SL8_CL       24
17454 #define TEMPLATE_SL16_CL      25
17455 #define TEMPLATE_SL32_CL      26
17456 #define TEMPLATE_SL8_IMM      27
17457 #define TEMPLATE_SL16_IMM     28
17458 #define TEMPLATE_SL32_IMM     29
17459 #define TEMPLATE_UNARY8       30
17460 #define TEMPLATE_UNARY16      31
17461 #define TEMPLATE_UNARY32      32
17462 #define TEMPLATE_CMP8_REG     33
17463 #define TEMPLATE_CMP16_REG    34
17464 #define TEMPLATE_CMP32_REG    35
17465 #define TEMPLATE_CMP8_IMM     36
17466 #define TEMPLATE_CMP16_IMM    37
17467 #define TEMPLATE_CMP32_IMM    38
17468 #define TEMPLATE_TEST8        39
17469 #define TEMPLATE_TEST16       40
17470 #define TEMPLATE_TEST32       41
17471 #define TEMPLATE_SET          42
17472 #define TEMPLATE_JMP          43
17473 #define TEMPLATE_RET          44
17474 #define TEMPLATE_INB_DX       45
17475 #define TEMPLATE_INB_IMM      46
17476 #define TEMPLATE_INW_DX       47
17477 #define TEMPLATE_INW_IMM      48
17478 #define TEMPLATE_INL_DX       49
17479 #define TEMPLATE_INL_IMM      50
17480 #define TEMPLATE_OUTB_DX      51
17481 #define TEMPLATE_OUTB_IMM     52
17482 #define TEMPLATE_OUTW_DX      53
17483 #define TEMPLATE_OUTW_IMM     54
17484 #define TEMPLATE_OUTL_DX      55
17485 #define TEMPLATE_OUTL_IMM     56
17486 #define TEMPLATE_BSF          57
17487 #define TEMPLATE_RDMSR        58
17488 #define TEMPLATE_WRMSR        59
17489 #define TEMPLATE_UMUL8        60
17490 #define TEMPLATE_UMUL16       61
17491 #define TEMPLATE_UMUL32       62
17492 #define TEMPLATE_DIV8         63
17493 #define TEMPLATE_DIV16        64
17494 #define TEMPLATE_DIV32        65
17495 #define LAST_TEMPLATE       TEMPLATE_DIV32
17496 #if LAST_TEMPLATE >= MAX_TEMPLATES
17497 #error "MAX_TEMPLATES to low"
17498 #endif
17499
17500 #define COPY8_REGCM     (REGCM_DIVIDEND64 | REGCM_DIVIDEND32 | REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO | REGCM_MMX | REGCM_XMM)
17501 #define COPY16_REGCM    (REGCM_DIVIDEND64 | REGCM_DIVIDEND32 | REGCM_GPR32 | REGCM_GPR16 | REGCM_MMX | REGCM_XMM)  
17502 #define COPY32_REGCM    (REGCM_DIVIDEND64 | REGCM_DIVIDEND32 | REGCM_GPR32 | REGCM_MMX | REGCM_XMM)
17503
17504
17505 static struct ins_template templates[] = {
17506         [TEMPLATE_NOP]      = {},
17507         [TEMPLATE_INTCONST8] = { 
17508                 .lhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
17509         },
17510         [TEMPLATE_INTCONST32] = { 
17511                 .lhs = { [0] = { REG_UNNEEDED, REGCM_IMM32 } },
17512         },
17513         [TEMPLATE_COPY8_REG] = {
17514                 .lhs = { [0] = { REG_UNSET, COPY8_REGCM } },
17515                 .rhs = { [0] = { REG_UNSET, COPY8_REGCM }  },
17516         },
17517         [TEMPLATE_COPY16_REG] = {
17518                 .lhs = { [0] = { REG_UNSET, COPY16_REGCM } },
17519                 .rhs = { [0] = { REG_UNSET, COPY16_REGCM }  },
17520         },
17521         [TEMPLATE_COPY32_REG] = {
17522                 .lhs = { [0] = { REG_UNSET, COPY32_REGCM } },
17523                 .rhs = { [0] = { REG_UNSET, COPY32_REGCM }  },
17524         },
17525         [TEMPLATE_COPY_IMM8] = {
17526                 .lhs = { [0] = { REG_UNSET, COPY8_REGCM } },
17527                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
17528         },
17529         [TEMPLATE_COPY_IMM16] = {
17530                 .lhs = { [0] = { REG_UNSET, COPY16_REGCM } },
17531                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM16 | REGCM_IMM8 } },
17532         },
17533         [TEMPLATE_COPY_IMM32] = {
17534                 .lhs = { [0] = { REG_UNSET, COPY32_REGCM } },
17535                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8 } },
17536         },
17537         [TEMPLATE_PHI8] = { 
17538                 .lhs = { [0] = { REG_VIRT0, COPY8_REGCM } },
17539                 .rhs = { 
17540                         [ 0] = { REG_VIRT0, COPY8_REGCM },
17541                         [ 1] = { REG_VIRT0, COPY8_REGCM },
17542                         [ 2] = { REG_VIRT0, COPY8_REGCM },
17543                         [ 3] = { REG_VIRT0, COPY8_REGCM },
17544                         [ 4] = { REG_VIRT0, COPY8_REGCM },
17545                         [ 5] = { REG_VIRT0, COPY8_REGCM },
17546                         [ 6] = { REG_VIRT0, COPY8_REGCM },
17547                         [ 7] = { REG_VIRT0, COPY8_REGCM },
17548                         [ 8] = { REG_VIRT0, COPY8_REGCM },
17549                         [ 9] = { REG_VIRT0, COPY8_REGCM },
17550                         [10] = { REG_VIRT0, COPY8_REGCM },
17551                         [11] = { REG_VIRT0, COPY8_REGCM },
17552                         [12] = { REG_VIRT0, COPY8_REGCM },
17553                         [13] = { REG_VIRT0, COPY8_REGCM },
17554                         [14] = { REG_VIRT0, COPY8_REGCM },
17555                         [15] = { REG_VIRT0, COPY8_REGCM },
17556                 }, },
17557         [TEMPLATE_PHI16] = { 
17558                 .lhs = { [0] = { REG_VIRT0, COPY16_REGCM } },
17559                 .rhs = { 
17560                         [ 0] = { REG_VIRT0, COPY16_REGCM },
17561                         [ 1] = { REG_VIRT0, COPY16_REGCM },
17562                         [ 2] = { REG_VIRT0, COPY16_REGCM },
17563                         [ 3] = { REG_VIRT0, COPY16_REGCM },
17564                         [ 4] = { REG_VIRT0, COPY16_REGCM },
17565                         [ 5] = { REG_VIRT0, COPY16_REGCM },
17566                         [ 6] = { REG_VIRT0, COPY16_REGCM },
17567                         [ 7] = { REG_VIRT0, COPY16_REGCM },
17568                         [ 8] = { REG_VIRT0, COPY16_REGCM },
17569                         [ 9] = { REG_VIRT0, COPY16_REGCM },
17570                         [10] = { REG_VIRT0, COPY16_REGCM },
17571                         [11] = { REG_VIRT0, COPY16_REGCM },
17572                         [12] = { REG_VIRT0, COPY16_REGCM },
17573                         [13] = { REG_VIRT0, COPY16_REGCM },
17574                         [14] = { REG_VIRT0, COPY16_REGCM },
17575                         [15] = { REG_VIRT0, COPY16_REGCM },
17576                 }, },
17577         [TEMPLATE_PHI32] = { 
17578                 .lhs = { [0] = { REG_VIRT0, COPY32_REGCM } },
17579                 .rhs = { 
17580                         [ 0] = { REG_VIRT0, COPY32_REGCM },
17581                         [ 1] = { REG_VIRT0, COPY32_REGCM },
17582                         [ 2] = { REG_VIRT0, COPY32_REGCM },
17583                         [ 3] = { REG_VIRT0, COPY32_REGCM },
17584                         [ 4] = { REG_VIRT0, COPY32_REGCM },
17585                         [ 5] = { REG_VIRT0, COPY32_REGCM },
17586                         [ 6] = { REG_VIRT0, COPY32_REGCM },
17587                         [ 7] = { REG_VIRT0, COPY32_REGCM },
17588                         [ 8] = { REG_VIRT0, COPY32_REGCM },
17589                         [ 9] = { REG_VIRT0, COPY32_REGCM },
17590                         [10] = { REG_VIRT0, COPY32_REGCM },
17591                         [11] = { REG_VIRT0, COPY32_REGCM },
17592                         [12] = { REG_VIRT0, COPY32_REGCM },
17593                         [13] = { REG_VIRT0, COPY32_REGCM },
17594                         [14] = { REG_VIRT0, COPY32_REGCM },
17595                         [15] = { REG_VIRT0, COPY32_REGCM },
17596                 }, },
17597         [TEMPLATE_STORE8] = {
17598                 .rhs = { 
17599                         [0] = { REG_UNSET, REGCM_GPR32 },
17600                         [1] = { REG_UNSET, REGCM_GPR8_LO },
17601                 },
17602         },
17603         [TEMPLATE_STORE16] = {
17604                 .rhs = { 
17605                         [0] = { REG_UNSET, REGCM_GPR32 },
17606                         [1] = { REG_UNSET, REGCM_GPR16 },
17607                 },
17608         },
17609         [TEMPLATE_STORE32] = {
17610                 .rhs = { 
17611                         [0] = { REG_UNSET, REGCM_GPR32 },
17612                         [1] = { REG_UNSET, REGCM_GPR32 },
17613                 },
17614         },
17615         [TEMPLATE_LOAD8] = {
17616                 .lhs = { [0] = { REG_UNSET, REGCM_GPR8_LO } },
17617                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
17618         },
17619         [TEMPLATE_LOAD16] = {
17620                 .lhs = { [0] = { REG_UNSET, REGCM_GPR16 } },
17621                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
17622         },
17623         [TEMPLATE_LOAD32] = {
17624                 .lhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
17625                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
17626         },
17627         [TEMPLATE_BINARY8_REG] = {
17628                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
17629                 .rhs = { 
17630                         [0] = { REG_VIRT0, REGCM_GPR8_LO },
17631                         [1] = { REG_UNSET, REGCM_GPR8_LO },
17632                 },
17633         },
17634         [TEMPLATE_BINARY16_REG] = {
17635                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
17636                 .rhs = { 
17637                         [0] = { REG_VIRT0, REGCM_GPR16 },
17638                         [1] = { REG_UNSET, REGCM_GPR16 },
17639                 },
17640         },
17641         [TEMPLATE_BINARY32_REG] = {
17642                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
17643                 .rhs = { 
17644                         [0] = { REG_VIRT0, REGCM_GPR32 },
17645                         [1] = { REG_UNSET, REGCM_GPR32 },
17646                 },
17647         },
17648         [TEMPLATE_BINARY8_IMM] = {
17649                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
17650                 .rhs = { 
17651                         [0] = { REG_VIRT0,    REGCM_GPR8_LO },
17652                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
17653                 },
17654         },
17655         [TEMPLATE_BINARY16_IMM] = {
17656                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
17657                 .rhs = { 
17658                         [0] = { REG_VIRT0,    REGCM_GPR16 },
17659                         [1] = { REG_UNNEEDED, REGCM_IMM16 },
17660                 },
17661         },
17662         [TEMPLATE_BINARY32_IMM] = {
17663                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
17664                 .rhs = { 
17665                         [0] = { REG_VIRT0,    REGCM_GPR32 },
17666                         [1] = { REG_UNNEEDED, REGCM_IMM32 },
17667                 },
17668         },
17669         [TEMPLATE_SL8_CL] = {
17670                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
17671                 .rhs = { 
17672                         [0] = { REG_VIRT0, REGCM_GPR8_LO },
17673                         [1] = { REG_CL, REGCM_GPR8_LO },
17674                 },
17675         },
17676         [TEMPLATE_SL16_CL] = {
17677                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
17678                 .rhs = { 
17679                         [0] = { REG_VIRT0, REGCM_GPR16 },
17680                         [1] = { REG_CL, REGCM_GPR8_LO },
17681                 },
17682         },
17683         [TEMPLATE_SL32_CL] = {
17684                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
17685                 .rhs = { 
17686                         [0] = { REG_VIRT0, REGCM_GPR32 },
17687                         [1] = { REG_CL, REGCM_GPR8_LO },
17688                 },
17689         },
17690         [TEMPLATE_SL8_IMM] = {
17691                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
17692                 .rhs = { 
17693                         [0] = { REG_VIRT0,    REGCM_GPR8_LO },
17694                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
17695                 },
17696         },
17697         [TEMPLATE_SL16_IMM] = {
17698                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
17699                 .rhs = { 
17700                         [0] = { REG_VIRT0,    REGCM_GPR16 },
17701                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
17702                 },
17703         },
17704         [TEMPLATE_SL32_IMM] = {
17705                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
17706                 .rhs = { 
17707                         [0] = { REG_VIRT0,    REGCM_GPR32 },
17708                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
17709                 },
17710         },
17711         [TEMPLATE_UNARY8] = {
17712                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
17713                 .rhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
17714         },
17715         [TEMPLATE_UNARY16] = {
17716                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
17717                 .rhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
17718         },
17719         [TEMPLATE_UNARY32] = {
17720                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
17721                 .rhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
17722         },
17723         [TEMPLATE_CMP8_REG] = {
17724                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
17725                 .rhs = {
17726                         [0] = { REG_UNSET, REGCM_GPR8_LO },
17727                         [1] = { REG_UNSET, REGCM_GPR8_LO },
17728                 },
17729         },
17730         [TEMPLATE_CMP16_REG] = {
17731                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
17732                 .rhs = {
17733                         [0] = { REG_UNSET, REGCM_GPR16 },
17734                         [1] = { REG_UNSET, REGCM_GPR16 },
17735                 },
17736         },
17737         [TEMPLATE_CMP32_REG] = {
17738                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
17739                 .rhs = {
17740                         [0] = { REG_UNSET, REGCM_GPR32 },
17741                         [1] = { REG_UNSET, REGCM_GPR32 },
17742                 },
17743         },
17744         [TEMPLATE_CMP8_IMM] = {
17745                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
17746                 .rhs = {
17747                         [0] = { REG_UNSET, REGCM_GPR8_LO },
17748                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
17749                 },
17750         },
17751         [TEMPLATE_CMP16_IMM] = {
17752                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
17753                 .rhs = {
17754                         [0] = { REG_UNSET, REGCM_GPR16 },
17755                         [1] = { REG_UNNEEDED, REGCM_IMM16 },
17756                 },
17757         },
17758         [TEMPLATE_CMP32_IMM] = {
17759                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
17760                 .rhs = {
17761                         [0] = { REG_UNSET, REGCM_GPR32 },
17762                         [1] = { REG_UNNEEDED, REGCM_IMM32 },
17763                 },
17764         },
17765         [TEMPLATE_TEST8] = {
17766                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
17767                 .rhs = { [0] = { REG_UNSET, REGCM_GPR8_LO } },
17768         },
17769         [TEMPLATE_TEST16] = {
17770                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
17771                 .rhs = { [0] = { REG_UNSET, REGCM_GPR16 } },
17772         },
17773         [TEMPLATE_TEST32] = {
17774                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
17775                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
17776         },
17777         [TEMPLATE_SET] = {
17778                 .lhs = { [0] = { REG_UNSET, REGCM_GPR8_LO } },
17779                 .rhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
17780         },
17781         [TEMPLATE_JMP] = {
17782                 .rhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
17783         },
17784         [TEMPLATE_RET] = {
17785                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
17786         },
17787         [TEMPLATE_INB_DX] = {
17788                 .lhs = { [0] = { REG_AL,  REGCM_GPR8_LO } },  
17789                 .rhs = { [0] = { REG_DX, REGCM_GPR16 } },
17790         },
17791         [TEMPLATE_INB_IMM] = {
17792                 .lhs = { [0] = { REG_AL,  REGCM_GPR8_LO } },  
17793                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
17794         },
17795         [TEMPLATE_INW_DX]  = { 
17796                 .lhs = { [0] = { REG_AX,  REGCM_GPR16 } }, 
17797                 .rhs = { [0] = { REG_DX, REGCM_GPR16 } },
17798         },
17799         [TEMPLATE_INW_IMM] = { 
17800                 .lhs = { [0] = { REG_AX,  REGCM_GPR16 } }, 
17801                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
17802         },
17803         [TEMPLATE_INL_DX]  = {
17804                 .lhs = { [0] = { REG_EAX, REGCM_GPR32 } },
17805                 .rhs = { [0] = { REG_DX, REGCM_GPR16 } },
17806         },
17807         [TEMPLATE_INL_IMM] = {
17808                 .lhs = { [0] = { REG_EAX, REGCM_GPR32 } },
17809                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
17810         },
17811         [TEMPLATE_OUTB_DX] = { 
17812                 .rhs = {
17813                         [0] = { REG_AL,  REGCM_GPR8_LO },
17814                         [1] = { REG_DX, REGCM_GPR16 },
17815                 },
17816         },
17817         [TEMPLATE_OUTB_IMM] = { 
17818                 .rhs = {
17819                         [0] = { REG_AL,  REGCM_GPR8_LO },  
17820                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
17821                 },
17822         },
17823         [TEMPLATE_OUTW_DX] = { 
17824                 .rhs = {
17825                         [0] = { REG_AX,  REGCM_GPR16 },
17826                         [1] = { REG_DX, REGCM_GPR16 },
17827                 },
17828         },
17829         [TEMPLATE_OUTW_IMM] = {
17830                 .rhs = {
17831                         [0] = { REG_AX,  REGCM_GPR16 }, 
17832                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
17833                 },
17834         },
17835         [TEMPLATE_OUTL_DX] = { 
17836                 .rhs = {
17837                         [0] = { REG_EAX, REGCM_GPR32 },
17838                         [1] = { REG_DX, REGCM_GPR16 },
17839                 },
17840         },
17841         [TEMPLATE_OUTL_IMM] = { 
17842                 .rhs = {
17843                         [0] = { REG_EAX, REGCM_GPR32 }, 
17844                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
17845                 },
17846         },
17847         [TEMPLATE_BSF] = {
17848                 .lhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
17849                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
17850         },
17851         [TEMPLATE_RDMSR] = {
17852                 .lhs = { 
17853                         [0] = { REG_EAX, REGCM_GPR32 },
17854                         [1] = { REG_EDX, REGCM_GPR32 },
17855                 },
17856                 .rhs = { [0] = { REG_ECX, REGCM_GPR32 } },
17857         },
17858         [TEMPLATE_WRMSR] = {
17859                 .rhs = {
17860                         [0] = { REG_ECX, REGCM_GPR32 },
17861                         [1] = { REG_EAX, REGCM_GPR32 },
17862                         [2] = { REG_EDX, REGCM_GPR32 },
17863                 },
17864         },
17865         [TEMPLATE_UMUL8] = {
17866                 .lhs = { [0] = { REG_AX, REGCM_GPR16 } },
17867                 .rhs = { 
17868                         [0] = { REG_AL, REGCM_GPR8_LO },
17869                         [1] = { REG_UNSET, REGCM_GPR8_LO },
17870                 },
17871         },
17872         [TEMPLATE_UMUL16] = {
17873                 .lhs = { [0] = { REG_DXAX, REGCM_DIVIDEND32 } },
17874                 .rhs = { 
17875                         [0] = { REG_AX, REGCM_GPR16 },
17876                         [1] = { REG_UNSET, REGCM_GPR16 },
17877                 },
17878         },
17879         [TEMPLATE_UMUL32] = {
17880                 .lhs = { [0] = { REG_EDXEAX, REGCM_DIVIDEND64 } },
17881                 .rhs = { 
17882                         [0] = { REG_EAX, REGCM_GPR32 },
17883                         [1] = { REG_UNSET, REGCM_GPR32 },
17884                 },
17885         },
17886         [TEMPLATE_DIV8] = {
17887                 .lhs = { 
17888                         [0] = { REG_AL, REGCM_GPR8_LO },
17889                         [1] = { REG_AH, REGCM_GPR8 },
17890                 },
17891                 .rhs = {
17892                         [0] = { REG_AX, REGCM_GPR16 },
17893                         [1] = { REG_UNSET, REGCM_GPR8_LO },
17894                 },
17895         },
17896         [TEMPLATE_DIV16] = {
17897                 .lhs = { 
17898                         [0] = { REG_AX, REGCM_GPR16 },
17899                         [1] = { REG_DX, REGCM_GPR16 },
17900                 },
17901                 .rhs = {
17902                         [0] = { REG_DXAX, REGCM_DIVIDEND32 },
17903                         [1] = { REG_UNSET, REGCM_GPR16 },
17904                 },
17905         },
17906         [TEMPLATE_DIV32] = {
17907                 .lhs = { 
17908                         [0] = { REG_EAX, REGCM_GPR32 },
17909                         [1] = { REG_EDX, REGCM_GPR32 },
17910                 },
17911                 .rhs = {
17912                         [0] = { REG_EDXEAX, REGCM_DIVIDEND64 },
17913                         [1] = { REG_UNSET, REGCM_GPR32 },
17914                 },
17915         },
17916 };
17917
17918 static void fixup_branch(struct compile_state *state,
17919         struct triple *branch, int jmp_op, int cmp_op, struct type *cmp_type,
17920         struct triple *left, struct triple *right)
17921 {
17922         struct triple *test;
17923         if (!left) {
17924                 internal_error(state, branch, "no branch test?");
17925         }
17926         test = pre_triple(state, branch,
17927                 cmp_op, cmp_type, left, right);
17928         test->template_id = TEMPLATE_TEST32; 
17929         if (cmp_op == OP_CMP) {
17930                 test->template_id = TEMPLATE_CMP32_REG;
17931                 if (get_imm32(test, &RHS(test, 1))) {
17932                         test->template_id = TEMPLATE_CMP32_IMM;
17933                 }
17934         }
17935         use_triple(RHS(test, 0), test);
17936         use_triple(RHS(test, 1), test);
17937         unuse_triple(RHS(branch, 0), branch);
17938         RHS(branch, 0) = test;
17939         branch->op = jmp_op;
17940         branch->template_id = TEMPLATE_JMP;
17941         use_triple(RHS(branch, 0), branch);
17942 }
17943
17944 static void fixup_branches(struct compile_state *state,
17945         struct triple *cmp, struct triple *use, int jmp_op)
17946 {
17947         struct triple_set *entry, *next;
17948         for(entry = use->use; entry; entry = next) {
17949                 next = entry->next;
17950                 if (entry->member->op == OP_COPY) {
17951                         fixup_branches(state, cmp, entry->member, jmp_op);
17952                 }
17953                 else if (entry->member->op == OP_CBRANCH) {
17954                         struct triple *branch;
17955                         struct triple *left, *right;
17956                         left = right = 0;
17957                         left = RHS(cmp, 0);
17958                         if (TRIPLE_RHS(cmp->sizes) > 1) {
17959                                 right = RHS(cmp, 1);
17960                         }
17961                         branch = entry->member;
17962                         fixup_branch(state, branch, jmp_op, 
17963                                 cmp->op, cmp->type, left, right);
17964                 }
17965         }
17966 }
17967
17968 static void bool_cmp(struct compile_state *state, 
17969         struct triple *ins, int cmp_op, int jmp_op, int set_op)
17970 {
17971         struct triple_set *entry, *next;
17972         struct triple *set;
17973
17974         /* Put a barrier up before the cmp which preceeds the
17975          * copy instruction.  If a set actually occurs this gives
17976          * us a chance to move variables in registers out of the way.
17977          */
17978
17979         /* Modify the comparison operator */
17980         ins->op = cmp_op;
17981         ins->template_id = TEMPLATE_TEST32;
17982         if (cmp_op == OP_CMP) {
17983                 ins->template_id = TEMPLATE_CMP32_REG;
17984                 if (get_imm32(ins, &RHS(ins, 1))) {
17985                         ins->template_id =  TEMPLATE_CMP32_IMM;
17986                 }
17987         }
17988         /* Generate the instruction sequence that will transform the
17989          * result of the comparison into a logical value.
17990          */
17991         set = post_triple(state, ins, set_op, &char_type, ins, 0);
17992         use_triple(ins, set);
17993         set->template_id = TEMPLATE_SET;
17994
17995         for(entry = ins->use; entry; entry = next) {
17996                 next = entry->next;
17997                 if (entry->member == set) {
17998                         continue;
17999                 }
18000                 replace_rhs_use(state, ins, set, entry->member);
18001         }
18002         fixup_branches(state, ins, set, jmp_op);
18003 }
18004
18005 static struct triple *after_lhs(struct compile_state *state, struct triple *ins)
18006 {
18007         struct triple *next;
18008         int lhs, i;
18009         lhs = TRIPLE_LHS(ins->sizes);
18010         for(next = ins->next, i = 0; i < lhs; i++, next = next->next) {
18011                 if (next != LHS(ins, i)) {
18012                         internal_error(state, ins, "malformed lhs on %s",
18013                                 tops(ins->op));
18014                 }
18015                 if (next->op != OP_PIECE) {
18016                         internal_error(state, ins, "bad lhs op %s at %d on %s",
18017                                 tops(next->op), i, tops(ins->op));
18018                 }
18019                 if (next->u.cval != i) {
18020                         internal_error(state, ins, "bad u.cval of %d %d expected",
18021                                 next->u.cval, i);
18022                 }
18023         }
18024         return next;
18025 }
18026
18027 struct reg_info arch_reg_lhs(struct compile_state *state, struct triple *ins, int index)
18028 {
18029         struct ins_template *template;
18030         struct reg_info result;
18031         int zlhs;
18032         if (ins->op == OP_PIECE) {
18033                 index = ins->u.cval;
18034                 ins = MISC(ins, 0);
18035         }
18036         zlhs = TRIPLE_LHS(ins->sizes);
18037         if (triple_is_def(state, ins)) {
18038                 zlhs = 1;
18039         }
18040         if (index >= zlhs) {
18041                 internal_error(state, ins, "index %d out of range for %s\n",
18042                         index, tops(ins->op));
18043         }
18044         switch(ins->op) {
18045         case OP_ASM:
18046                 template = &ins->u.ainfo->tmpl;
18047                 break;
18048         default:
18049                 if (ins->template_id > LAST_TEMPLATE) {
18050                         internal_error(state, ins, "bad template number %d", 
18051                                 ins->template_id);
18052                 }
18053                 template = &templates[ins->template_id];
18054                 break;
18055         }
18056         result = template->lhs[index];
18057         result.regcm = arch_regcm_normalize(state, result.regcm);
18058         if (result.reg != REG_UNNEEDED) {
18059                 result.regcm &= ~(REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8);
18060         }
18061         if (result.regcm == 0) {
18062                 internal_error(state, ins, "lhs %d regcm == 0", index);
18063         }
18064         return result;
18065 }
18066
18067 struct reg_info arch_reg_rhs(struct compile_state *state, struct triple *ins, int index)
18068 {
18069         struct reg_info result;
18070         struct ins_template *template;
18071         if ((index > TRIPLE_RHS(ins->sizes)) ||
18072                 (ins->op == OP_PIECE)) {
18073                 internal_error(state, ins, "index %d out of range for %s\n",
18074                         index, tops(ins->op));
18075         }
18076         switch(ins->op) {
18077         case OP_ASM:
18078                 template = &ins->u.ainfo->tmpl;
18079                 break;
18080         default:
18081                 if (ins->template_id > LAST_TEMPLATE) {
18082                         internal_error(state, ins, "bad template number %d", 
18083                                 ins->template_id);
18084                 }
18085                 template = &templates[ins->template_id];
18086                 break;
18087         }
18088         result = template->rhs[index];
18089         result.regcm = arch_regcm_normalize(state, result.regcm);
18090         if (result.regcm == 0) {
18091                 internal_error(state, ins, "rhs %d regcm == 0", index);
18092         }
18093         return result;
18094 }
18095
18096 static struct triple *mod_div(struct compile_state *state,
18097         struct triple *ins, int div_op, int index)
18098 {
18099         struct triple *div, *piece0, *piece1;
18100         
18101         /* Generate a piece to hold the remainder */
18102         piece1 = post_triple(state, ins, OP_PIECE, ins->type, 0, 0);
18103         piece1->u.cval = 1;
18104
18105         /* Generate a piece to hold the quotient */
18106         piece0 = post_triple(state, ins, OP_PIECE, ins->type, 0, 0);
18107         piece0->u.cval = 0;
18108
18109         /* Generate the appropriate division instruction */
18110         div = post_triple(state, ins, div_op, ins->type, 0, 0);
18111         RHS(div, 0) = RHS(ins, 0);
18112         RHS(div, 1) = RHS(ins, 1);
18113         LHS(div, 0) = piece0;
18114         LHS(div, 1) = piece1;
18115         div->template_id  = TEMPLATE_DIV32;
18116         use_triple(RHS(div, 0), div);
18117         use_triple(RHS(div, 1), div);
18118         use_triple(LHS(div, 0), div);
18119         use_triple(LHS(div, 1), div);
18120
18121         /* Hook on piece0 */
18122         MISC(piece0, 0) = div;
18123         use_triple(div, piece0);
18124
18125         /* Hook on piece1 */
18126         MISC(piece1, 0) = div;
18127         use_triple(div, piece1);
18128         
18129         /* Replate uses of ins with the appropriate piece of the div */
18130         propogate_use(state, ins, LHS(div, index));
18131         release_triple(state, ins);
18132
18133         /* Return the address of the next instruction */
18134         return piece1->next;
18135 }
18136
18137 static struct triple *transform_to_arch_instruction(
18138         struct compile_state *state, struct triple *ins)
18139 {
18140         /* Transform from generic 3 address instructions
18141          * to archtecture specific instructions.
18142          * And apply architecture specific constraints to instructions.
18143          * Copies are inserted to preserve the register flexibility
18144          * of 3 address instructions.
18145          */
18146         struct triple *next;
18147         size_t size;
18148         next = ins->next;
18149         switch(ins->op) {
18150         case OP_INTCONST:
18151                 ins->template_id = TEMPLATE_INTCONST32;
18152                 if (ins->u.cval < 256) {
18153                         ins->template_id = TEMPLATE_INTCONST8;
18154                 }
18155                 break;
18156         case OP_ADDRCONST:
18157                 ins->template_id = TEMPLATE_INTCONST32;
18158                 break;
18159         case OP_NOOP:
18160         case OP_SDECL:
18161         case OP_BLOBCONST:
18162         case OP_LABEL:
18163                 ins->template_id = TEMPLATE_NOP;
18164                 break;
18165         case OP_COPY:
18166                 size = size_of(state, ins->type);
18167                 if (is_imm8(RHS(ins, 0)) && (size <= 1)) {
18168                         ins->template_id = TEMPLATE_COPY_IMM8;
18169                 }
18170                 else if (is_imm16(RHS(ins, 0)) && (size <= 2)) {
18171                         ins->template_id = TEMPLATE_COPY_IMM16;
18172                 }
18173                 else if (is_imm32(RHS(ins, 0)) && (size <= 4)) {
18174                         ins->template_id = TEMPLATE_COPY_IMM32;
18175                 }
18176                 else if (is_const(RHS(ins, 0))) {
18177                         internal_error(state, ins, "bad constant passed to copy");
18178                 }
18179                 else if (size <= 1) {
18180                         ins->template_id = TEMPLATE_COPY8_REG;
18181                 }
18182                 else if (size <= 2) {
18183                         ins->template_id = TEMPLATE_COPY16_REG;
18184                 }
18185                 else if (size <= 4) {
18186                         ins->template_id = TEMPLATE_COPY32_REG;
18187                 }
18188                 else {
18189                         internal_error(state, ins, "bad type passed to copy");
18190                 }
18191                 break;
18192         case OP_PHI:
18193                 size = size_of(state, ins->type);
18194                 if (size <= 1) {
18195                         ins->template_id = TEMPLATE_PHI8;
18196                 }
18197                 else if (size <= 2) {
18198                         ins->template_id = TEMPLATE_PHI16;
18199                 }
18200                 else if (size <= 4) {
18201                         ins->template_id = TEMPLATE_PHI32;
18202                 }
18203                 else {
18204                         internal_error(state, ins, "bad type passed to phi");
18205                 }
18206                 break;
18207         case OP_STORE:
18208                 switch(ins->type->type & TYPE_MASK) {
18209                 case TYPE_CHAR:    case TYPE_UCHAR:
18210                         ins->template_id = TEMPLATE_STORE8;
18211                         break;
18212                 case TYPE_SHORT:   case TYPE_USHORT:
18213                         ins->template_id = TEMPLATE_STORE16;
18214                         break;
18215                 case TYPE_INT:     case TYPE_UINT:
18216                 case TYPE_LONG:    case TYPE_ULONG:
18217                 case TYPE_POINTER:
18218                         ins->template_id = TEMPLATE_STORE32;
18219                         break;
18220                 default:
18221                         internal_error(state, ins, "unknown type in store");
18222                         break;
18223                 }
18224                 break;
18225         case OP_LOAD:
18226                 switch(ins->type->type & TYPE_MASK) {
18227                 case TYPE_CHAR:   case TYPE_UCHAR:
18228                 case TYPE_SHORT:  case TYPE_USHORT:
18229                 case TYPE_INT:    case TYPE_UINT:
18230                 case TYPE_LONG:   case TYPE_ULONG:
18231                 case TYPE_POINTER:
18232                         break;
18233                 default:
18234                         internal_error(state, ins, "unknown type in load");
18235                         break;
18236                 }
18237                 ins->template_id = TEMPLATE_LOAD32;
18238                 break;
18239         case OP_ADD:
18240         case OP_SUB:
18241         case OP_AND:
18242         case OP_XOR:
18243         case OP_OR:
18244         case OP_SMUL:
18245                 ins->template_id = TEMPLATE_BINARY32_REG;
18246                 if (get_imm32(ins, &RHS(ins, 1))) {
18247                         ins->template_id = TEMPLATE_BINARY32_IMM;
18248                 }
18249                 break;
18250         case OP_SDIVT:
18251         case OP_UDIVT:
18252                 ins->template_id = TEMPLATE_DIV32;
18253                 next = after_lhs(state, ins);
18254                 break;
18255                 /* FIXME UMUL does not work yet.. */
18256         case OP_UMUL:
18257                 ins->template_id = TEMPLATE_UMUL32;
18258                 break;
18259         case OP_UDIV:
18260                 next = mod_div(state, ins, OP_UDIVT, 0);
18261                 break;
18262         case OP_SDIV:
18263                 next = mod_div(state, ins, OP_SDIVT, 0);
18264                 break;
18265         case OP_UMOD:
18266                 next = mod_div(state, ins, OP_UDIVT, 1);
18267                 break;
18268         case OP_SMOD:
18269                 next = mod_div(state, ins, OP_SDIVT, 1);
18270                 break;
18271         case OP_SL:
18272         case OP_SSR:
18273         case OP_USR:
18274                 ins->template_id = TEMPLATE_SL32_CL;
18275                 if (get_imm8(ins, &RHS(ins, 1))) {
18276                         ins->template_id = TEMPLATE_SL32_IMM;
18277                 } else if (size_of(state, RHS(ins, 1)->type) > 1) {
18278                         typed_pre_copy(state, &char_type, ins, 1);
18279                 }
18280                 break;
18281         case OP_INVERT:
18282         case OP_NEG:
18283                 ins->template_id = TEMPLATE_UNARY32;
18284                 break;
18285         case OP_EQ: 
18286                 bool_cmp(state, ins, OP_CMP, OP_JMP_EQ, OP_SET_EQ); 
18287                 break;
18288         case OP_NOTEQ:
18289                 bool_cmp(state, ins, OP_CMP, OP_JMP_NOTEQ, OP_SET_NOTEQ);
18290                 break;
18291         case OP_SLESS:
18292                 bool_cmp(state, ins, OP_CMP, OP_JMP_SLESS, OP_SET_SLESS);
18293                 break;
18294         case OP_ULESS:
18295                 bool_cmp(state, ins, OP_CMP, OP_JMP_ULESS, OP_SET_ULESS);
18296                 break;
18297         case OP_SMORE:
18298                 bool_cmp(state, ins, OP_CMP, OP_JMP_SMORE, OP_SET_SMORE);
18299                 break;
18300         case OP_UMORE:
18301                 bool_cmp(state, ins, OP_CMP, OP_JMP_UMORE, OP_SET_UMORE);
18302                 break;
18303         case OP_SLESSEQ:
18304                 bool_cmp(state, ins, OP_CMP, OP_JMP_SLESSEQ, OP_SET_SLESSEQ);
18305                 break;
18306         case OP_ULESSEQ:
18307                 bool_cmp(state, ins, OP_CMP, OP_JMP_ULESSEQ, OP_SET_ULESSEQ);
18308                 break;
18309         case OP_SMOREEQ:
18310                 bool_cmp(state, ins, OP_CMP, OP_JMP_SMOREEQ, OP_SET_SMOREEQ);
18311                 break;
18312         case OP_UMOREEQ:
18313                 bool_cmp(state, ins, OP_CMP, OP_JMP_UMOREEQ, OP_SET_UMOREEQ);
18314                 break;
18315         case OP_LTRUE:
18316                 bool_cmp(state, ins, OP_TEST, OP_JMP_NOTEQ, OP_SET_NOTEQ);
18317                 break;
18318         case OP_LFALSE:
18319                 bool_cmp(state, ins, OP_TEST, OP_JMP_EQ, OP_SET_EQ);
18320                 break;
18321         case OP_BRANCH:
18322                 ins->op = OP_JMP;
18323                 ins->template_id = TEMPLATE_NOP;
18324                 break;
18325         case OP_CBRANCH:
18326                 fixup_branch(state, ins, OP_JMP_NOTEQ, OP_TEST, 
18327                         RHS(ins, 0)->type, RHS(ins, 0), 0);
18328                 break;
18329         case OP_CALL:
18330                 ins->template_id = TEMPLATE_NOP;
18331                 break;
18332         case OP_RET:
18333                 ins->template_id = TEMPLATE_RET;
18334                 break;
18335         case OP_INB:
18336         case OP_INW:
18337         case OP_INL:
18338                 switch(ins->op) {
18339                 case OP_INB: ins->template_id = TEMPLATE_INB_DX; break;
18340                 case OP_INW: ins->template_id = TEMPLATE_INW_DX; break;
18341                 case OP_INL: ins->template_id = TEMPLATE_INL_DX; break;
18342                 }
18343                 if (get_imm8(ins, &RHS(ins, 0))) {
18344                         ins->template_id += 1;
18345                 }
18346                 break;
18347         case OP_OUTB:
18348         case OP_OUTW:
18349         case OP_OUTL:
18350                 switch(ins->op) {
18351                 case OP_OUTB: ins->template_id = TEMPLATE_OUTB_DX; break;
18352                 case OP_OUTW: ins->template_id = TEMPLATE_OUTW_DX; break;
18353                 case OP_OUTL: ins->template_id = TEMPLATE_OUTL_DX; break;
18354                 }
18355                 if (get_imm8(ins, &RHS(ins, 1))) {
18356                         ins->template_id += 1;
18357                 }
18358                 break;
18359         case OP_BSF:
18360         case OP_BSR:
18361                 ins->template_id = TEMPLATE_BSF;
18362                 break;
18363         case OP_RDMSR:
18364                 ins->template_id = TEMPLATE_RDMSR;
18365                 next = after_lhs(state, ins);
18366                 break;
18367         case OP_WRMSR:
18368                 ins->template_id = TEMPLATE_WRMSR;
18369                 break;
18370         case OP_HLT:
18371                 ins->template_id = TEMPLATE_NOP;
18372                 break;
18373         case OP_ASM:
18374                 ins->template_id = TEMPLATE_NOP;
18375                 next = after_lhs(state, ins);
18376                 break;
18377                 /* Already transformed instructions */
18378         case OP_TEST:
18379                 ins->template_id = TEMPLATE_TEST32;
18380                 break;
18381         case OP_CMP:
18382                 ins->template_id = TEMPLATE_CMP32_REG;
18383                 if (get_imm32(ins, &RHS(ins, 1))) {
18384                         ins->template_id = TEMPLATE_CMP32_IMM;
18385                 }
18386                 break;
18387         case OP_JMP:
18388                 ins->template_id = TEMPLATE_NOP;
18389                 break;
18390         case OP_JMP_EQ:      case OP_JMP_NOTEQ:
18391         case OP_JMP_SLESS:   case OP_JMP_ULESS:
18392         case OP_JMP_SMORE:   case OP_JMP_UMORE:
18393         case OP_JMP_SLESSEQ: case OP_JMP_ULESSEQ:
18394         case OP_JMP_SMOREEQ: case OP_JMP_UMOREEQ:
18395                 ins->template_id = TEMPLATE_JMP;
18396                 break;
18397         case OP_SET_EQ:      case OP_SET_NOTEQ:
18398         case OP_SET_SLESS:   case OP_SET_ULESS:
18399         case OP_SET_SMORE:   case OP_SET_UMORE:
18400         case OP_SET_SLESSEQ: case OP_SET_ULESSEQ:
18401         case OP_SET_SMOREEQ: case OP_SET_UMOREEQ:
18402                 ins->template_id = TEMPLATE_SET;
18403                 break;
18404                 /* Unhandled instructions */
18405         case OP_PIECE:
18406         default:
18407                 internal_error(state, ins, "unhandled ins: %d %s\n",
18408                         ins->op, tops(ins->op));
18409                 break;
18410         }
18411         return next;
18412 }
18413
18414 static long next_label(struct compile_state *state)
18415 {
18416         static long label_counter = 0;
18417         return ++label_counter;
18418 }
18419 static void generate_local_labels(struct compile_state *state)
18420 {
18421         struct triple *first, *label;
18422         first = state->first;
18423         label = first;
18424         do {
18425                 if ((label->op == OP_LABEL) || 
18426                         (label->op == OP_SDECL)) {
18427                         if (label->use) {
18428                                 label->u.cval = next_label(state);
18429                         } else {
18430                                 label->u.cval = 0;
18431                         }
18432                         
18433                 }
18434                 label = label->next;
18435         } while(label != first);
18436 }
18437
18438 static int check_reg(struct compile_state *state, 
18439         struct triple *triple, int classes)
18440 {
18441         unsigned mask;
18442         int reg;
18443         reg = ID_REG(triple->id);
18444         if (reg == REG_UNSET) {
18445                 internal_error(state, triple, "register not set");
18446         }
18447         mask = arch_reg_regcm(state, reg);
18448         if (!(classes & mask)) {
18449                 internal_error(state, triple, "reg %d in wrong class",
18450                         reg);
18451         }
18452         return reg;
18453 }
18454
18455 static const char *arch_reg_str(int reg)
18456 {
18457 #if REG_XMM7 != 44
18458 #error "Registers have renumberd fix arch_reg_str"
18459 #endif
18460         static const char *regs[] = {
18461                 "%unset",
18462                 "%unneeded",
18463                 "%eflags",
18464                 "%al", "%bl", "%cl", "%dl", "%ah", "%bh", "%ch", "%dh",
18465                 "%ax", "%bx", "%cx", "%dx", "%si", "%di", "%bp", "%sp",
18466                 "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi", "%ebp", "%esp",
18467                 "%edx:%eax",
18468                 "%dx:%ax",
18469                 "%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7",
18470                 "%xmm0", "%xmm1", "%xmm2", "%xmm3", 
18471                 "%xmm4", "%xmm5", "%xmm6", "%xmm7",
18472         };
18473         if (!((reg >= REG_EFLAGS) && (reg <= REG_XMM7))) {
18474                 reg = 0;
18475         }
18476         return regs[reg];
18477 }
18478
18479
18480 static const char *reg(struct compile_state *state, struct triple *triple,
18481         int classes)
18482 {
18483         int reg;
18484         reg = check_reg(state, triple, classes);
18485         return arch_reg_str(reg);
18486 }
18487
18488 const char *type_suffix(struct compile_state *state, struct type *type)
18489 {
18490         const char *suffix;
18491         switch(size_of(state, type)) {
18492         case 1: suffix = "b"; break;
18493         case 2: suffix = "w"; break;
18494         case 4: suffix = "l"; break;
18495         default:
18496                 internal_error(state, 0, "unknown suffix");
18497                 suffix = 0;
18498                 break;
18499         }
18500         return suffix;
18501 }
18502
18503 static void print_const_val(
18504         struct compile_state *state, struct triple *ins, FILE *fp)
18505 {
18506         switch(ins->op) {
18507         case OP_INTCONST:
18508                 fprintf(fp, " $%ld ", 
18509                         (long)(ins->u.cval));
18510                 break;
18511         case OP_ADDRCONST:
18512                 if ((MISC(ins, 0)->op != OP_SDECL) &&
18513                         (MISC(ins, 0)->op != OP_LABEL))
18514                 {
18515                         internal_error(state, ins, "bad base for addrconst");
18516                 }
18517                 if (MISC(ins, 0)->u.cval <= 0) {
18518                         internal_error(state, ins, "unlabeled constant");
18519                 }
18520                 fprintf(fp, " $L%s%lu+%lu ",
18521                         state->compiler->label_prefix, 
18522                         (unsigned long)(MISC(ins, 0)->u.cval),
18523                         (unsigned long)(ins->u.cval));
18524                 break;
18525         default:
18526                 internal_error(state, ins, "unknown constant type");
18527                 break;
18528         }
18529 }
18530
18531 static void print_const(struct compile_state *state,
18532         struct triple *ins, FILE *fp)
18533 {
18534         switch(ins->op) {
18535         case OP_INTCONST:
18536                 switch(ins->type->type & TYPE_MASK) {
18537                 case TYPE_CHAR:
18538                 case TYPE_UCHAR:
18539                         fprintf(fp, ".byte 0x%02lx\n", 
18540                                 (unsigned long)(ins->u.cval));
18541                         break;
18542                 case TYPE_SHORT:
18543                 case TYPE_USHORT:
18544                         fprintf(fp, ".short 0x%04lx\n", 
18545                                 (unsigned long)(ins->u.cval));
18546                         break;
18547                 case TYPE_INT:
18548                 case TYPE_UINT:
18549                 case TYPE_LONG:
18550                 case TYPE_ULONG:
18551                         fprintf(fp, ".int %lu\n", 
18552                                 (unsigned long)(ins->u.cval));
18553                         break;
18554                 default:
18555                         internal_error(state, ins, "Unknown constant type");
18556                 }
18557                 break;
18558         case OP_ADDRCONST:
18559                 if ((MISC(ins, 0)->op != OP_SDECL) &&
18560                         (MISC(ins, 0)->op != OP_LABEL)) {
18561                         internal_error(state, ins, "bad base for addrconst");
18562                 }
18563                 if (MISC(ins, 0)->u.cval <= 0) {
18564                         internal_error(state, ins, "unlabeled constant");
18565                 }
18566                 fprintf(fp, ".int L%s%lu+%lu\n",
18567                         state->compiler->label_prefix,
18568                         (unsigned long)(MISC(ins, 0)->u.cval),
18569                         (unsigned long)(ins->u.cval));
18570                 break;
18571         case OP_BLOBCONST:
18572         {
18573                 unsigned char *blob;
18574                 size_t size, i;
18575                 size = size_of(state, ins->type);
18576                 blob = ins->u.blob;
18577                 for(i = 0; i < size; i++) {
18578                         fprintf(fp, ".byte 0x%02x\n",
18579                                 blob[i]);
18580                 }
18581                 break;
18582         }
18583         default:
18584                 internal_error(state, ins, "Unknown constant type");
18585                 break;
18586         }
18587 }
18588
18589 #define TEXT_SECTION ".rom.text"
18590 #define DATA_SECTION ".rom.data"
18591
18592 static long get_const_pool_ref(
18593         struct compile_state *state, struct triple *ins, FILE *fp)
18594 {
18595         long ref;
18596         ref = next_label(state);
18597         fprintf(fp, ".section \"" DATA_SECTION "\"\n");
18598         fprintf(fp, ".balign %d\n", align_of(state, ins->type));
18599         fprintf(fp, "L%s%lu:\n", state->compiler->label_prefix, ref);
18600         print_const(state, ins, fp);
18601         fprintf(fp, ".section \"" TEXT_SECTION "\"\n");
18602         return ref;
18603 }
18604
18605 static void print_binary_op(struct compile_state *state,
18606         const char *op, struct triple *ins, FILE *fp) 
18607 {
18608         unsigned mask;
18609         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO;
18610         if (ID_REG(RHS(ins, 0)->id) != ID_REG(ins->id)) {
18611                 internal_error(state, ins, "invalid register assignment");
18612         }
18613         if (is_const(RHS(ins, 1))) {
18614                 fprintf(fp, "\t%s ", op);
18615                 print_const_val(state, RHS(ins, 1), fp);
18616                 fprintf(fp, ", %s\n",
18617                         reg(state, RHS(ins, 0), mask));
18618         }
18619         else {
18620                 unsigned lmask, rmask;
18621                 int lreg, rreg;
18622                 lreg = check_reg(state, RHS(ins, 0), mask);
18623                 rreg = check_reg(state, RHS(ins, 1), mask);
18624                 lmask = arch_reg_regcm(state, lreg);
18625                 rmask = arch_reg_regcm(state, rreg);
18626                 mask = lmask & rmask;
18627                 fprintf(fp, "\t%s %s, %s\n",
18628                         op,
18629                         reg(state, RHS(ins, 1), mask),
18630                         reg(state, RHS(ins, 0), mask));
18631         }
18632 }
18633 static void print_unary_op(struct compile_state *state, 
18634         const char *op, struct triple *ins, FILE *fp)
18635 {
18636         unsigned mask;
18637         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO;
18638         fprintf(fp, "\t%s %s\n",
18639                 op,
18640                 reg(state, RHS(ins, 0), mask));
18641 }
18642
18643 static void print_op_shift(struct compile_state *state,
18644         const char *op, struct triple *ins, FILE *fp)
18645 {
18646         unsigned mask;
18647         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO;
18648         if (ID_REG(RHS(ins, 0)->id) != ID_REG(ins->id)) {
18649                 internal_error(state, ins, "invalid register assignment");
18650         }
18651         if (is_const(RHS(ins, 1))) {
18652                 fprintf(fp, "\t%s ", op);
18653                 print_const_val(state, RHS(ins, 1), fp);
18654                 fprintf(fp, ", %s\n",
18655                         reg(state, RHS(ins, 0), mask));
18656         }
18657         else {
18658                 fprintf(fp, "\t%s %s, %s\n",
18659                         op,
18660                         reg(state, RHS(ins, 1), REGCM_GPR8_LO),
18661                         reg(state, RHS(ins, 0), mask));
18662         }
18663 }
18664
18665 static void print_op_in(struct compile_state *state, struct triple *ins, FILE *fp)
18666 {
18667         const char *op;
18668         int mask;
18669         int dreg;
18670         mask = 0;
18671         switch(ins->op) {
18672         case OP_INB: op = "inb", mask = REGCM_GPR8_LO; break;
18673         case OP_INW: op = "inw", mask = REGCM_GPR16; break;
18674         case OP_INL: op = "inl", mask = REGCM_GPR32; break;
18675         default:
18676                 internal_error(state, ins, "not an in operation");
18677                 op = 0;
18678                 break;
18679         }
18680         dreg = check_reg(state, ins, mask);
18681         if (!reg_is_reg(state, dreg, REG_EAX)) {
18682                 internal_error(state, ins, "dst != %%eax");
18683         }
18684         if (is_const(RHS(ins, 0))) {
18685                 fprintf(fp, "\t%s ", op);
18686                 print_const_val(state, RHS(ins, 0), fp);
18687                 fprintf(fp, ", %s\n",
18688                         reg(state, ins, mask));
18689         }
18690         else {
18691                 int addr_reg;
18692                 addr_reg = check_reg(state, RHS(ins, 0), REGCM_GPR16);
18693                 if (!reg_is_reg(state, addr_reg, REG_DX)) {
18694                         internal_error(state, ins, "src != %%dx");
18695                 }
18696                 fprintf(fp, "\t%s %s, %s\n",
18697                         op, 
18698                         reg(state, RHS(ins, 0), REGCM_GPR16),
18699                         reg(state, ins, mask));
18700         }
18701 }
18702
18703 static void print_op_out(struct compile_state *state, struct triple *ins, FILE *fp)
18704 {
18705         const char *op;
18706         int mask;
18707         int lreg;
18708         mask = 0;
18709         switch(ins->op) {
18710         case OP_OUTB: op = "outb", mask = REGCM_GPR8_LO; break;
18711         case OP_OUTW: op = "outw", mask = REGCM_GPR16; break;
18712         case OP_OUTL: op = "outl", mask = REGCM_GPR32; break;
18713         default:
18714                 internal_error(state, ins, "not an out operation");
18715                 op = 0;
18716                 break;
18717         }
18718         lreg = check_reg(state, RHS(ins, 0), mask);
18719         if (!reg_is_reg(state, lreg, REG_EAX)) {
18720                 internal_error(state, ins, "src != %%eax");
18721         }
18722         if (is_const(RHS(ins, 1))) {
18723                 fprintf(fp, "\t%s %s,", 
18724                         op, reg(state, RHS(ins, 0), mask));
18725                 print_const_val(state, RHS(ins, 1), fp);
18726                 fprintf(fp, "\n");
18727         }
18728         else {
18729                 int addr_reg;
18730                 addr_reg = check_reg(state, RHS(ins, 1), REGCM_GPR16);
18731                 if (!reg_is_reg(state, addr_reg, REG_DX)) {
18732                         internal_error(state, ins, "dst != %%dx");
18733                 }
18734                 fprintf(fp, "\t%s %s, %s\n",
18735                         op, 
18736                         reg(state, RHS(ins, 0), mask),
18737                         reg(state, RHS(ins, 1), REGCM_GPR16));
18738         }
18739 }
18740
18741 static void print_op_move(struct compile_state *state,
18742         struct triple *ins, FILE *fp)
18743 {
18744         /* op_move is complex because there are many types
18745          * of registers we can move between.
18746          * Because OP_COPY will be introduced in arbitrary locations
18747          * OP_COPY must not affect flags.
18748          */
18749         int omit_copy = 1; /* Is it o.k. to omit a noop copy? */
18750         struct triple *dst, *src;
18751         if (ins->op == OP_COPY) {
18752                 src = RHS(ins, 0);
18753                 dst = ins;
18754         }
18755         else {
18756                 internal_error(state, ins, "unknown move operation");
18757                 src = dst = 0;
18758         }
18759         if (!is_const(src)) {
18760                 int src_reg, dst_reg;
18761                 int src_regcm, dst_regcm;
18762                 src_reg   = ID_REG(src->id);
18763                 dst_reg   = ID_REG(dst->id);
18764                 src_regcm = arch_reg_regcm(state, src_reg);
18765                 dst_regcm = arch_reg_regcm(state, dst_reg);
18766                 /* If the class is the same just move the register */
18767                 if (src_regcm & dst_regcm & 
18768                         (REGCM_GPR8_LO | REGCM_GPR16 | REGCM_GPR32)) {
18769                         if ((src_reg != dst_reg) || !omit_copy) {
18770                                 fprintf(fp, "\tmov %s, %s\n",
18771                                         reg(state, src, src_regcm),
18772                                         reg(state, dst, dst_regcm));
18773                         }
18774                 }
18775                 /* Move 32bit to 16bit */
18776                 else if ((src_regcm & REGCM_GPR32) &&
18777                         (dst_regcm & REGCM_GPR16)) {
18778                         src_reg = (src_reg - REGC_GPR32_FIRST) + REGC_GPR16_FIRST;
18779                         if ((src_reg != dst_reg) || !omit_copy) {
18780                                 fprintf(fp, "\tmovw %s, %s\n",
18781                                         arch_reg_str(src_reg), 
18782                                         arch_reg_str(dst_reg));
18783                         }
18784                 }
18785                 /* Move from 32bit gprs to 16bit gprs */
18786                 else if ((src_regcm & REGCM_GPR32) &&
18787                         (dst_regcm & REGCM_GPR16)) {
18788                         dst_reg = (dst_reg - REGC_GPR16_FIRST) + REGC_GPR32_FIRST;
18789                         if ((src_reg != dst_reg) || !omit_copy) {
18790                                 fprintf(fp, "\tmov %s, %s\n",
18791                                         arch_reg_str(src_reg),
18792                                         arch_reg_str(dst_reg));
18793                         }
18794                 }
18795                 /* Move 32bit to 8bit */
18796                 else if ((src_regcm & REGCM_GPR32_8) &&
18797                         (dst_regcm & REGCM_GPR8_LO))
18798                 {
18799                         src_reg = (src_reg - REGC_GPR32_8_FIRST) + REGC_GPR8_FIRST;
18800                         if ((src_reg != dst_reg) || !omit_copy) {
18801                                 fprintf(fp, "\tmovb %s, %s\n",
18802                                         arch_reg_str(src_reg),
18803                                         arch_reg_str(dst_reg));
18804                         }
18805                 }
18806                 /* Move 16bit to 8bit */
18807                 else if ((src_regcm & REGCM_GPR16_8) &&
18808                         (dst_regcm & REGCM_GPR8_LO))
18809                 {
18810                         src_reg = (src_reg - REGC_GPR16_8_FIRST) + REGC_GPR8_FIRST;
18811                         if ((src_reg != dst_reg) || !omit_copy) {
18812                                 fprintf(fp, "\tmovb %s, %s\n",
18813                                         arch_reg_str(src_reg),
18814                                         arch_reg_str(dst_reg));
18815                         }
18816                 }
18817                 /* Move 8/16bit to 16/32bit */
18818                 else if ((src_regcm & (REGCM_GPR8_LO | REGCM_GPR16)) && 
18819                         (dst_regcm & (REGCM_GPR16 | REGCM_GPR32))) {
18820                         const char *op;
18821                         op = is_signed(src->type)? "movsx": "movzx";
18822                         fprintf(fp, "\t%s %s, %s\n",
18823                                 op,
18824                                 reg(state, src, src_regcm),
18825                                 reg(state, dst, dst_regcm));
18826                 }
18827                 /* Move between sse registers */
18828                 else if ((src_regcm & dst_regcm & REGCM_XMM)) {
18829                         if ((src_reg != dst_reg) || !omit_copy) {
18830                                 fprintf(fp, "\tmovdqa %s, %s\n",
18831                                         reg(state, src, src_regcm),
18832                                         reg(state, dst, dst_regcm));
18833                         }
18834                 }
18835                 /* Move between mmx registers */
18836                 else if ((src_regcm & dst_regcm & REGCM_MMX)) {
18837                         if ((src_reg != dst_reg) || !omit_copy) {
18838                                 fprintf(fp, "\tmovq %s, %s\n",
18839                                         reg(state, src, src_regcm),
18840                                         reg(state, dst, dst_regcm));
18841                         }
18842                 }
18843                 /* Move from sse to mmx registers */
18844                 else if ((src_regcm & REGCM_XMM) && (dst_regcm & REGCM_MMX)) {
18845                         fprintf(fp, "\tmovdq2q %s, %s\n",
18846                                 reg(state, src, src_regcm),
18847                                 reg(state, dst, dst_regcm));
18848                 }
18849                 /* Move from mmx to sse registers */
18850                 else if ((src_regcm & REGCM_MMX) && (dst_regcm & REGCM_XMM)) {
18851                         fprintf(fp, "\tmovq2dq %s, %s\n",
18852                                 reg(state, src, src_regcm),
18853                                 reg(state, dst, dst_regcm));
18854                 }
18855                 /* Move between 32bit gprs & mmx/sse registers */
18856                 else if ((src_regcm & (REGCM_GPR32 | REGCM_MMX | REGCM_XMM)) &&
18857                         (dst_regcm & (REGCM_GPR32 | REGCM_MMX | REGCM_XMM))) {
18858                         fprintf(fp, "\tmovd %s, %s\n",
18859                                 reg(state, src, src_regcm),
18860                                 reg(state, dst, dst_regcm));
18861                 }
18862                 /* Move from 16bit gprs &  mmx/sse registers */
18863                 else if ((src_regcm & REGCM_GPR16) &&
18864                         (dst_regcm & (REGCM_MMX | REGCM_XMM))) {
18865                         const char *op;
18866                         int mid_reg;
18867                         op = is_signed(src->type)? "movsx":"movzx";
18868                         mid_reg = (src_reg - REGC_GPR16_FIRST) + REGC_GPR32_FIRST;
18869                         fprintf(fp, "\t%s %s, %s\n\tmovd %s, %s\n",
18870                                 op,
18871                                 arch_reg_str(src_reg),
18872                                 arch_reg_str(mid_reg),
18873                                 arch_reg_str(mid_reg),
18874                                 arch_reg_str(dst_reg));
18875                 }
18876                 /* Move from mmx/sse registers to 16bit gprs */
18877                 else if ((src_regcm & (REGCM_MMX | REGCM_XMM)) &&
18878                         (dst_regcm & REGCM_GPR16)) {
18879                         dst_reg = (dst_reg - REGC_GPR16_FIRST) + REGC_GPR32_FIRST;
18880                         fprintf(fp, "\tmovd %s, %s\n",
18881                                 arch_reg_str(src_reg),
18882                                 arch_reg_str(dst_reg));
18883                 }
18884                 /* Move from gpr to 64bit dividend */
18885                 else if ((src_regcm & (REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO))  &&
18886                         (dst_regcm & REGCM_DIVIDEND64)) {
18887                         const char *extend;
18888                         extend = is_signed(src->type)? "cltd":"movl $0, %edx";
18889                         fprintf(fp, "\tmov %s, %%eax\n\t%s\n",
18890                                 arch_reg_str(src_reg), 
18891                                 extend);
18892                 }
18893                 /* Move from 64bit gpr to gpr */
18894                 else if ((src_regcm & REGCM_DIVIDEND64) &&
18895                         (dst_regcm & (REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO))) {
18896                         if (dst_regcm & REGCM_GPR32) {
18897                                 src_reg = REG_EAX;
18898                         } 
18899                         else if (dst_regcm & REGCM_GPR16) {
18900                                 src_reg = REG_AX;
18901                         }
18902                         else if (dst_regcm & REGCM_GPR8_LO) {
18903                                 src_reg = REG_AL;
18904                         }
18905                         fprintf(fp, "\tmov %s, %s\n",
18906                                 arch_reg_str(src_reg),
18907                                 arch_reg_str(dst_reg));
18908                 }
18909                 /* Move from mmx/sse registers to 64bit gpr */
18910                 else if ((src_regcm & (REGCM_MMX | REGCM_XMM)) &&
18911                         (dst_regcm & REGCM_DIVIDEND64)) {
18912                         const char *extend;
18913                         extend = is_signed(src->type)? "cltd": "movl $0, %edx";
18914                         fprintf(fp, "\tmovd %s, %%eax\n\t%s\n",
18915                                 arch_reg_str(src_reg),
18916                                 extend);
18917                 }
18918                 /* Move from 64bit gpr to mmx/sse register */
18919                 else if ((src_regcm & REGCM_DIVIDEND64) &&
18920                         (dst_regcm & (REGCM_XMM | REGCM_MMX))) {
18921                         fprintf(fp, "\tmovd %%eax, %s\n",
18922                                 arch_reg_str(dst_reg));
18923                 }
18924 #if X86_4_8BIT_GPRS
18925                 /* Move from 8bit gprs to  mmx/sse registers */
18926                 else if ((src_regcm & REGCM_GPR8_LO) && (src_reg <= REG_DL) &&
18927                         (dst_regcm & (REGCM_MMX | REGCM_XMM))) {
18928                         const char *op;
18929                         int mid_reg;
18930                         op = is_signed(src->type)? "movsx":"movzx";
18931                         mid_reg = (src_reg - REGC_GPR8_FIRST) + REGC_GPR32_FIRST;
18932                         fprintf(fp, "\t%s %s, %s\n\tmovd %s, %s\n",
18933                                 op,
18934                                 reg(state, src, src_regcm),
18935                                 arch_reg_str(mid_reg),
18936                                 arch_reg_str(mid_reg),
18937                                 reg(state, dst, dst_regcm));
18938                 }
18939                 /* Move from mmx/sse registers and 8bit gprs */
18940                 else if ((src_regcm & (REGCM_MMX | REGCM_XMM)) &&
18941                         (dst_regcm & REGCM_GPR8_LO) && (dst_reg <= REG_DL)) {
18942                         int mid_reg;
18943                         mid_reg = (dst_reg - REGC_GPR8_FIRST) + REGC_GPR32_FIRST;
18944                         fprintf(fp, "\tmovd %s, %s\n",
18945                                 reg(state, src, src_regcm),
18946                                 arch_reg_str(mid_reg));
18947                 }
18948                 /* Move from 32bit gprs to 8bit gprs */
18949                 else if ((src_regcm & REGCM_GPR32) &&
18950                         (dst_regcm & REGCM_GPR8_LO)) {
18951                         dst_reg = (dst_reg - REGC_GPR8_FIRST) + REGC_GPR32_FIRST;
18952                         if ((src_reg != dst_reg) || !omit_copy) {
18953                                 fprintf(fp, "\tmov %s, %s\n",
18954                                         arch_reg_str(src_reg),
18955                                         arch_reg_str(dst_reg));
18956                         }
18957                 }
18958                 /* Move from 16bit gprs to 8bit gprs */
18959                 else if ((src_regcm & REGCM_GPR16) &&
18960                         (dst_regcm & REGCM_GPR8_LO)) {
18961                         dst_reg = (dst_reg - REGC_GPR8_FIRST) + REGC_GPR16_FIRST;
18962                         if ((src_reg != dst_reg) || !omit_copy) {
18963                                 fprintf(fp, "\tmov %s, %s\n",
18964                                         arch_reg_str(src_reg),
18965                                         arch_reg_str(dst_reg));
18966                         }
18967                 }
18968 #endif /* X86_4_8BIT_GPRS */
18969                 else {
18970                         internal_error(state, ins, "unknown copy type");
18971                 }
18972         }
18973         else {
18974                 int dst_reg;
18975                 int dst_regcm;
18976                 dst_reg = ID_REG(dst->id);
18977                 dst_regcm = arch_reg_regcm(state, dst_reg);
18978                 if (dst_regcm & (REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO)) {
18979                         fprintf(fp, "\tmov ");
18980                         print_const_val(state, src, fp);
18981                         fprintf(fp, ", %s\n",
18982                                 reg(state, dst, REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO));
18983                 }
18984                 else if (dst_regcm & REGCM_DIVIDEND64) {
18985                         if (size_of(state, dst->type) > 4) {
18986                                 internal_error(state, ins, "64bit constant...");
18987                         }
18988                         fprintf(fp, "\tmov $0, %%edx\n");
18989                         fprintf(fp, "\tmov ");
18990                         print_const_val(state, src, fp);
18991                         fprintf(fp, ", %%eax\n");
18992                 }
18993                 else if (dst_regcm & REGCM_DIVIDEND32) {
18994                         if (size_of(state, dst->type) > 2) {
18995                                 internal_error(state, ins, "32bit constant...");
18996                         }
18997                         fprintf(fp, "\tmov $0, %%dx\n");
18998                         fprintf(fp, "\tmov ");
18999                         print_const_val(state, src, fp);
19000                         fprintf(fp, ", %%ax");
19001                 }
19002                 else if (dst_regcm & (REGCM_XMM | REGCM_MMX)) {
19003                         long ref;
19004                         ref = get_const_pool_ref(state, src, fp);
19005                         fprintf(fp, "\tmovd L%s%lu, %s\n",
19006                                 state->compiler->label_prefix, ref,
19007                                 reg(state, dst, (REGCM_XMM | REGCM_MMX)));
19008                 }
19009                 else {
19010                         internal_error(state, ins, "unknown copy immediate type");
19011                 }
19012         }
19013 }
19014
19015 static void print_op_load(struct compile_state *state,
19016         struct triple *ins, FILE *fp)
19017 {
19018         struct triple *dst, *src;
19019         const char *op;
19020         dst = ins;
19021         src = RHS(ins, 0);
19022         if (is_const(src) || is_const(dst)) {
19023                 internal_error(state, ins, "unknown load operation");
19024         }
19025         switch(ins->type->type & TYPE_MASK) {
19026         case TYPE_CHAR:   op = "movsbl"; break;
19027         case TYPE_UCHAR:  op = "movzbl"; break;
19028         case TYPE_SHORT:  op = "movswl"; break;
19029         case TYPE_USHORT: op = "movzwl"; break;
19030         case TYPE_INT:    case TYPE_UINT:
19031         case TYPE_LONG:   case TYPE_ULONG:
19032         case TYPE_POINTER:
19033                 op = "movl"; 
19034                 break;
19035         default:
19036                 internal_error(state, ins, "unknown type in load");
19037                 op = "<invalid opcode>";
19038                 break;
19039         }
19040         fprintf(fp, "\t%s (%s), %s\n",
19041                 op, 
19042                 reg(state, src, REGCM_GPR32),
19043                 reg(state, dst, REGCM_GPR32));
19044 }
19045
19046
19047 static void print_op_store(struct compile_state *state,
19048         struct triple *ins, FILE *fp)
19049 {
19050         struct triple *dst, *src;
19051         dst = RHS(ins, 0);
19052         src = RHS(ins, 1);
19053         if (is_const(src) && (src->op == OP_INTCONST)) {
19054                 long_t value;
19055                 value = (long_t)(src->u.cval);
19056                 fprintf(fp, "\tmov%s $%ld, (%s)\n",
19057                         type_suffix(state, src->type),
19058                         (long)(value),
19059                         reg(state, dst, REGCM_GPR32));
19060         }
19061         else if (is_const(dst) && (dst->op == OP_INTCONST)) {
19062                 fprintf(fp, "\tmov%s %s, 0x%08lx\n",
19063                         type_suffix(state, src->type),
19064                         reg(state, src, REGCM_GPR8_LO | REGCM_GPR16 | REGCM_GPR32),
19065                         (unsigned long)(dst->u.cval));
19066         }
19067         else {
19068                 if (is_const(src) || is_const(dst)) {
19069                         internal_error(state, ins, "unknown store operation");
19070                 }
19071                 fprintf(fp, "\tmov%s %s, (%s)\n",
19072                         type_suffix(state, src->type),
19073                         reg(state, src, REGCM_GPR8_LO | REGCM_GPR16 | REGCM_GPR32),
19074                         reg(state, dst, REGCM_GPR32));
19075         }
19076         
19077         
19078 }
19079
19080 static void print_op_smul(struct compile_state *state,
19081         struct triple *ins, FILE *fp)
19082 {
19083         if (!is_const(RHS(ins, 1))) {
19084                 fprintf(fp, "\timul %s, %s\n",
19085                         reg(state, RHS(ins, 1), REGCM_GPR32),
19086                         reg(state, RHS(ins, 0), REGCM_GPR32));
19087         }
19088         else {
19089                 fprintf(fp, "\timul ");
19090                 print_const_val(state, RHS(ins, 1), fp);
19091                 fprintf(fp, ", %s\n", reg(state, RHS(ins, 0), REGCM_GPR32));
19092         }
19093 }
19094
19095 static void print_op_cmp(struct compile_state *state,
19096         struct triple *ins, FILE *fp)
19097 {
19098         unsigned mask;
19099         int dreg;
19100         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO;
19101         dreg = check_reg(state, ins, REGCM_FLAGS);
19102         if (!reg_is_reg(state, dreg, REG_EFLAGS)) {
19103                 internal_error(state, ins, "bad dest register for cmp");
19104         }
19105         if (is_const(RHS(ins, 1))) {
19106                 fprintf(fp, "\tcmp ");
19107                 print_const_val(state, RHS(ins, 1), fp);
19108                 fprintf(fp, ", %s\n", reg(state, RHS(ins, 0), mask));
19109         }
19110         else {
19111                 unsigned lmask, rmask;
19112                 int lreg, rreg;
19113                 lreg = check_reg(state, RHS(ins, 0), mask);
19114                 rreg = check_reg(state, RHS(ins, 1), mask);
19115                 lmask = arch_reg_regcm(state, lreg);
19116                 rmask = arch_reg_regcm(state, rreg);
19117                 mask = lmask & rmask;
19118                 fprintf(fp, "\tcmp %s, %s\n",
19119                         reg(state, RHS(ins, 1), mask),
19120                         reg(state, RHS(ins, 0), mask));
19121         }
19122 }
19123
19124 static void print_op_test(struct compile_state *state,
19125         struct triple *ins, FILE *fp)
19126 {
19127         unsigned mask;
19128         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO;
19129         fprintf(fp, "\ttest %s, %s\n",
19130                 reg(state, RHS(ins, 0), mask),
19131                 reg(state, RHS(ins, 0), mask));
19132 }
19133
19134 static void print_op_branch(struct compile_state *state,
19135         struct triple *branch, FILE *fp)
19136 {
19137         const char *bop = "j";
19138         if ((branch->op == OP_JMP) || (branch->op == OP_CALL)) {
19139                 if (TRIPLE_RHS(branch->sizes) != 0) {
19140                         internal_error(state, branch, "jmp with condition?");
19141                 }
19142                 bop = "jmp";
19143         }
19144         else {
19145                 struct triple *ptr;
19146                 if (TRIPLE_RHS(branch->sizes) != 1) {
19147                         internal_error(state, branch, "jmpcc without condition?");
19148                 }
19149                 check_reg(state, RHS(branch, 0), REGCM_FLAGS);
19150                 if ((RHS(branch, 0)->op != OP_CMP) &&
19151                         (RHS(branch, 0)->op != OP_TEST)) {
19152                         internal_error(state, branch, "bad branch test");
19153                 }
19154 #warning "FIXME I have observed instructions between the test and branch instructions"
19155                 ptr = RHS(branch, 0);
19156                 for(ptr = RHS(branch, 0)->next; ptr != branch; ptr = ptr->next) {
19157                         if (ptr->op != OP_COPY) {
19158                                 internal_error(state, branch, "branch does not follow test");
19159                         }
19160                 }
19161                 switch(branch->op) {
19162                 case OP_JMP_EQ:       bop = "jz";  break;
19163                 case OP_JMP_NOTEQ:    bop = "jnz"; break;
19164                 case OP_JMP_SLESS:    bop = "jl";  break;
19165                 case OP_JMP_ULESS:    bop = "jb";  break;
19166                 case OP_JMP_SMORE:    bop = "jg";  break;
19167                 case OP_JMP_UMORE:    bop = "ja";  break;
19168                 case OP_JMP_SLESSEQ:  bop = "jle"; break;
19169                 case OP_JMP_ULESSEQ:  bop = "jbe"; break;
19170                 case OP_JMP_SMOREEQ:  bop = "jge"; break;
19171                 case OP_JMP_UMOREEQ:  bop = "jae"; break;
19172                 default:
19173                         internal_error(state, branch, "Invalid branch op");
19174                         break;
19175                 }
19176                 
19177         }
19178         fprintf(fp, "\t%s L%s%lu\n",
19179                 bop, 
19180                 state->compiler->label_prefix,
19181                 (unsigned long)(TARG(branch, 0)->u.cval));
19182 }
19183
19184 static void print_op_ret(struct compile_state *state,
19185         struct triple *branch, FILE *fp)
19186 {
19187         fprintf(fp, "\tjmp *%s\n",
19188                 reg(state, RHS(branch, 0), REGCM_GPR32));
19189 }
19190
19191 static void print_op_set(struct compile_state *state,
19192         struct triple *set, FILE *fp)
19193 {
19194         const char *sop = "set";
19195         if (TRIPLE_RHS(set->sizes) != 1) {
19196                 internal_error(state, set, "setcc without condition?");
19197         }
19198         check_reg(state, RHS(set, 0), REGCM_FLAGS);
19199         if ((RHS(set, 0)->op != OP_CMP) &&
19200                 (RHS(set, 0)->op != OP_TEST)) {
19201                 internal_error(state, set, "bad set test");
19202         }
19203         if (RHS(set, 0)->next != set) {
19204                 internal_error(state, set, "set does not follow test");
19205         }
19206         switch(set->op) {
19207         case OP_SET_EQ:       sop = "setz";  break;
19208         case OP_SET_NOTEQ:    sop = "setnz"; break;
19209         case OP_SET_SLESS:    sop = "setl";  break;
19210         case OP_SET_ULESS:    sop = "setb";  break;
19211         case OP_SET_SMORE:    sop = "setg";  break;
19212         case OP_SET_UMORE:    sop = "seta";  break;
19213         case OP_SET_SLESSEQ:  sop = "setle"; break;
19214         case OP_SET_ULESSEQ:  sop = "setbe"; break;
19215         case OP_SET_SMOREEQ:  sop = "setge"; break;
19216         case OP_SET_UMOREEQ:  sop = "setae"; break;
19217         default:
19218                 internal_error(state, set, "Invalid set op");
19219                 break;
19220         }
19221         fprintf(fp, "\t%s %s\n",
19222                 sop, reg(state, set, REGCM_GPR8_LO));
19223 }
19224
19225 static void print_op_bit_scan(struct compile_state *state, 
19226         struct triple *ins, FILE *fp) 
19227 {
19228         const char *op;
19229         switch(ins->op) {
19230         case OP_BSF: op = "bsf"; break;
19231         case OP_BSR: op = "bsr"; break;
19232         default: 
19233                 internal_error(state, ins, "unknown bit scan");
19234                 op = 0;
19235                 break;
19236         }
19237         fprintf(fp, 
19238                 "\t%s %s, %s\n"
19239                 "\tjnz 1f\n"
19240                 "\tmovl $-1, %s\n"
19241                 "1:\n",
19242                 op,
19243                 reg(state, RHS(ins, 0), REGCM_GPR32),
19244                 reg(state, ins, REGCM_GPR32),
19245                 reg(state, ins, REGCM_GPR32));
19246 }
19247
19248
19249 static void print_sdecl(struct compile_state *state,
19250         struct triple *ins, FILE *fp)
19251 {
19252         fprintf(fp, ".section \"" DATA_SECTION "\"\n");
19253         fprintf(fp, ".balign %d\n", align_of(state, ins->type));
19254         fprintf(fp, "L%s%lu:\n", 
19255                 state->compiler->label_prefix, (unsigned long)(ins->u.cval));
19256         print_const(state, MISC(ins, 0), fp);
19257         fprintf(fp, ".section \"" TEXT_SECTION "\"\n");
19258                 
19259 }
19260
19261 static void print_instruction(struct compile_state *state,
19262         struct triple *ins, FILE *fp)
19263 {
19264         /* Assumption: after I have exted the register allocator
19265          * everything is in a valid register. 
19266          */
19267         switch(ins->op) {
19268         case OP_ASM:
19269                 print_op_asm(state, ins, fp);
19270                 break;
19271         case OP_ADD:    print_binary_op(state, "add", ins, fp); break;
19272         case OP_SUB:    print_binary_op(state, "sub", ins, fp); break;
19273         case OP_AND:    print_binary_op(state, "and", ins, fp); break;
19274         case OP_XOR:    print_binary_op(state, "xor", ins, fp); break;
19275         case OP_OR:     print_binary_op(state, "or",  ins, fp); break;
19276         case OP_SL:     print_op_shift(state, "shl", ins, fp); break;
19277         case OP_USR:    print_op_shift(state, "shr", ins, fp); break;
19278         case OP_SSR:    print_op_shift(state, "sar", ins, fp); break;
19279         case OP_POS:    break;
19280         case OP_NEG:    print_unary_op(state, "neg", ins, fp); break;
19281         case OP_INVERT: print_unary_op(state, "not", ins, fp); break;
19282         case OP_INTCONST:
19283         case OP_ADDRCONST:
19284         case OP_BLOBCONST:
19285                 /* Don't generate anything here for constants */
19286         case OP_PHI:
19287                 /* Don't generate anything for variable declarations. */
19288                 break;
19289         case OP_SDECL:
19290                 print_sdecl(state, ins, fp);
19291                 break;
19292         case OP_COPY:   
19293                 print_op_move(state, ins, fp);
19294                 break;
19295         case OP_LOAD:
19296                 print_op_load(state, ins, fp);
19297                 break;
19298         case OP_STORE:
19299                 print_op_store(state, ins, fp);
19300                 break;
19301         case OP_SMUL:
19302                 print_op_smul(state, ins, fp);
19303                 break;
19304         case OP_CMP:    print_op_cmp(state, ins, fp); break;
19305         case OP_TEST:   print_op_test(state, ins, fp); break;
19306         case OP_JMP:
19307         case OP_JMP_EQ:      case OP_JMP_NOTEQ:
19308         case OP_JMP_SLESS:   case OP_JMP_ULESS:
19309         case OP_JMP_SMORE:   case OP_JMP_UMORE:
19310         case OP_JMP_SLESSEQ: case OP_JMP_ULESSEQ:
19311         case OP_JMP_SMOREEQ: case OP_JMP_UMOREEQ:
19312         case OP_CALL:
19313                 print_op_branch(state, ins, fp);
19314                 break;
19315         case OP_RET:
19316                 print_op_ret(state, ins, fp);
19317                 break;
19318         case OP_SET_EQ:      case OP_SET_NOTEQ:
19319         case OP_SET_SLESS:   case OP_SET_ULESS:
19320         case OP_SET_SMORE:   case OP_SET_UMORE:
19321         case OP_SET_SLESSEQ: case OP_SET_ULESSEQ:
19322         case OP_SET_SMOREEQ: case OP_SET_UMOREEQ:
19323                 print_op_set(state, ins, fp);
19324                 break;
19325         case OP_INB:  case OP_INW:  case OP_INL:
19326                 print_op_in(state, ins, fp); 
19327                 break;
19328         case OP_OUTB: case OP_OUTW: case OP_OUTL:
19329                 print_op_out(state, ins, fp); 
19330                 break;
19331         case OP_BSF:
19332         case OP_BSR:
19333                 print_op_bit_scan(state, ins, fp);
19334                 break;
19335         case OP_RDMSR:
19336                 after_lhs(state, ins);
19337                 fprintf(fp, "\trdmsr\n");
19338                 break;
19339         case OP_WRMSR:
19340                 fprintf(fp, "\twrmsr\n");
19341                 break;
19342         case OP_HLT:
19343                 fprintf(fp, "\thlt\n");
19344                 break;
19345         case OP_SDIVT:
19346                 fprintf(fp, "\tidiv %s\n", reg(state, RHS(ins, 1), REGCM_GPR32));
19347                 break;
19348         case OP_UDIVT:
19349                 fprintf(fp, "\tdiv %s\n", reg(state, RHS(ins, 1), REGCM_GPR32));
19350                 break;
19351         case OP_UMUL:
19352                 fprintf(fp, "\tmul %s\n", reg(state, RHS(ins, 1), REGCM_GPR32));
19353                 break;
19354         case OP_LABEL:
19355                 if (!ins->use) {
19356                         return;
19357                 }
19358                 fprintf(fp, "L%s%lu:\n", 
19359                         state->compiler->label_prefix, (unsigned long)(ins->u.cval));
19360                 break;
19361                 /* Ignore OP_PIECE */
19362         case OP_PIECE:
19363                 break;
19364                 /* Operations that should never get here */
19365         case OP_SDIV: case OP_UDIV:
19366         case OP_SMOD: case OP_UMOD:
19367         case OP_LTRUE:   case OP_LFALSE:  case OP_EQ:      case OP_NOTEQ:
19368         case OP_SLESS:   case OP_ULESS:   case OP_SMORE:   case OP_UMORE:
19369         case OP_SLESSEQ: case OP_ULESSEQ: case OP_SMOREEQ: case OP_UMOREEQ:
19370         default:
19371                 internal_error(state, ins, "unknown op: %d %s",
19372                         ins->op, tops(ins->op));
19373                 break;
19374         }
19375 }
19376
19377 static void print_instructions(struct compile_state *state)
19378 {
19379         struct triple *first, *ins;
19380         int print_location;
19381         struct occurance *last_occurance;
19382         FILE *fp;
19383         int max_inline_depth;
19384         max_inline_depth = 0;
19385         print_location = 1;
19386         last_occurance = 0;
19387         fp = state->output;
19388         fprintf(fp, ".section \"" TEXT_SECTION "\"\n");
19389         first = state->first;
19390         ins = first;
19391         do {
19392                 if (print_location && 
19393                         last_occurance != ins->occurance) {
19394                         if (!ins->occurance->parent) {
19395                                 fprintf(fp, "\t/* %s,%s:%d.%d */\n",
19396                                         ins->occurance->function,
19397                                         ins->occurance->filename,
19398                                         ins->occurance->line,
19399                                         ins->occurance->col);
19400                         }
19401                         else {
19402                                 struct occurance *ptr;
19403                                 int inline_depth;
19404                                 fprintf(fp, "\t/*\n");
19405                                 inline_depth = 0;
19406                                 for(ptr = ins->occurance; ptr; ptr = ptr->parent) {
19407                                         inline_depth++;
19408                                         fprintf(fp, "\t * %s,%s:%d.%d\n",
19409                                                 ptr->function,
19410                                                 ptr->filename,
19411                                                 ptr->line,
19412                                                 ptr->col);
19413                                 }
19414                                 fprintf(fp, "\t */\n");
19415                                 if (inline_depth > max_inline_depth) {
19416                                         max_inline_depth = inline_depth;
19417                                 }
19418                         }
19419                         if (last_occurance) {
19420                                 put_occurance(last_occurance);
19421                         }
19422                         get_occurance(ins->occurance);
19423                         last_occurance = ins->occurance;
19424                 }
19425
19426                 print_instruction(state, ins, fp);
19427                 ins = ins->next;
19428         } while(ins != first);
19429         if (print_location) {
19430                 fprintf(fp, "/* max inline depth %d */\n",
19431                         max_inline_depth);
19432         }
19433 }
19434
19435 static void generate_code(struct compile_state *state)
19436 {
19437         generate_local_labels(state);
19438         print_instructions(state);
19439         
19440 }
19441
19442 static void print_tokens(struct compile_state *state)
19443 {
19444         struct token *tk;
19445         tk = &state->token[0];
19446         do {
19447 #if 1
19448                 token(state, 0);
19449 #else
19450                 next_token(state, 0);
19451 #endif
19452                 loc(stdout, state, 0);
19453                 printf("%s <- `%s'\n",
19454                         tokens[tk->tok],
19455                         tk->ident ? tk->ident->name :
19456                         tk->str_len ? tk->val.str : "");
19457                 
19458         } while(tk->tok != TOK_EOF);
19459 }
19460
19461 static void compile(const char *filename, 
19462         struct compiler_state *compiler, struct arch_state *arch)
19463 {
19464         int i;
19465         struct compile_state state;
19466         struct triple *ptr;
19467         memset(&state, 0, sizeof(state));
19468         state.compiler = compiler;
19469         state.arch     = arch;
19470         state.file = 0;
19471         for(i = 0; i < sizeof(state.token)/sizeof(state.token[0]); i++) {
19472                 memset(&state.token[i], 0, sizeof(state.token[i]));
19473                 state.token[i].tok = -1;
19474         }
19475         /* Remember the output filename */
19476         state.output    = fopen(state.compiler->ofilename, "w");
19477         if (!state.output) {
19478                 error(&state, 0, "Cannot open output file %s\n",
19479                         state.compiler->ofilename);
19480         }
19481         /* Prep the preprocessor */
19482         state.if_depth = 0;
19483         state.if_value = 0;
19484         /* register the C keywords */
19485         register_keywords(&state);
19486         /* register the keywords the macro preprocessor knows */
19487         register_macro_keywords(&state);
19488         /* Memorize where some special keywords are. */
19489         state.i_switch   = lookup(&state, "switch", 6);
19490         state.i_case     = lookup(&state, "case", 4);
19491         state.i_continue = lookup(&state, "continue", 8);
19492         state.i_break    = lookup(&state, "break", 5);
19493         state.i_default  = lookup(&state, "default", 7);
19494         state.i_return   = lookup(&state, "return", 6);
19495
19496         /* Allocate beginning bounding labels for the function list */
19497         state.first = label(&state);
19498         state.first->id |= TRIPLE_FLAG_VOLATILE;
19499         use_triple(state.first, state.first);
19500         ptr = label(&state);
19501         ptr->id |= TRIPLE_FLAG_VOLATILE;
19502         use_triple(ptr, ptr);
19503         flatten(&state, state.first, ptr);
19504
19505         /* Allocate a label for the pool of global variables */
19506         state.global_pool = label(&state);
19507         state.global_pool->id |= TRIPLE_FLAG_VOLATILE;
19508         flatten(&state, state.first, state.global_pool);
19509
19510
19511         /* Enter the globl definition scope */
19512         start_scope(&state);
19513         register_builtins(&state);
19514         compile_file(&state, filename, 1);
19515 #if 0
19516         print_tokens(&state);
19517 #endif  
19518         decls(&state);
19519
19520         /* Exit the global definition scope */
19521         end_scope(&state);
19522
19523         /* Join all of the functions into one giant function */
19524         join_functions(&state);
19525
19526         /* Now that basic compilation has happened 
19527          * optimize the intermediate code 
19528          */
19529         optimize(&state);
19530
19531         generate_code(&state);
19532         if (state.compiler->debug) {
19533                 fprintf(stderr, "done\n");
19534         }
19535 }
19536
19537 static void version(void)
19538 {
19539         printf("romcc " VERSION " released " RELEASE_DATE "\n");
19540 }
19541
19542 static void usage(void)
19543 {
19544         version();
19545         printf(
19546                 "Usage: romcc <source>.c\n"
19547                 "Compile a C source file without using ram\n"
19548         );
19549 }
19550
19551 static void arg_error(char *fmt, ...)
19552 {
19553         va_list args;
19554         va_start(args, fmt);
19555         vfprintf(stderr, fmt, args);
19556         va_end(args);
19557         usage();
19558         exit(1);
19559 }
19560
19561 int main(int argc, char **argv)
19562 {
19563         const char *filename;
19564         struct compiler_state compiler;
19565         struct arch_state arch;
19566         int all_opts;
19567         init_compiler_state(&compiler);
19568         init_arch_state(&arch);
19569         filename = 0;
19570         all_opts = 0;
19571         while(argc > 1) {
19572                 if (!all_opts && (strcmp(argv[1], "-o") == 0) && (argc > 2)) {
19573                         compiler.ofilename = argv[2];
19574                         argv += 2;
19575                         argc -= 2;
19576                 }
19577                 else if (!all_opts && argv[1][0] == '-') {
19578                         int result;
19579                         result = -1;
19580                         if (strcmp(argv[1], "--") == 0) {
19581                                 result = 0;
19582                                 all_opts = 1;
19583                         }
19584                         else if (strncmp(argv[1],"-O", 2) == 0) {
19585                                 result = compiler_encode_flag(&compiler, argv[1]);
19586                         }
19587                         else if (strncmp(argv[1], "--label-prefix=", 15) == 0) {
19588                                 result = compiler_encode_flag(&compiler, argv[1]+2);
19589                         }
19590                         else if (strncmp(argv[1], "-f", 2) == 0) {
19591                                 result = compiler_encode_flag(&compiler, argv[1]+2);
19592                         }
19593                         else if (strncmp(argv[1], "-m", 2) == 0) {
19594                                 result = arch_encode_flag(&arch, argv[1]+2);
19595                         }
19596                         if (result < 0) {
19597                                 arg_error("Invalid option specified: %s\n",
19598                                         argv[1]);
19599                         }
19600                         argv++;
19601                         argc--;
19602                 }
19603                 else {
19604                         if (filename) {
19605                                 arg_error("Only one filename may be specified\n");
19606                         }
19607                         filename = argv[1];
19608                         argv++;
19609                         argc--;
19610                 }
19611         }
19612         if (!filename) {
19613                 arg_error("No filename specified\n");
19614         }
19615         compile(filename, &compiler, &arch);
19616
19617         return 0;
19618 }