- Moved hlt() to it's own header.
[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->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                 (def->op == OP_LIST)) {
4827                 ret = 1;
4828         }
4829         else if (def->op == OP_DOT) {
4830                 ret = is_stable(state, RHS(def, 0));
4831         }
4832         else if (def->op == OP_VAL_VEC) {
4833                 struct triple **vector;
4834                 ulong_t i;
4835                 ret = 1;
4836                 vector = &RHS(def, 0);
4837                 for(i = 0; i < def->type->elements; i++) {
4838                         if (!is_stable(state, vector[i])) {
4839                                 ret = 0;
4840                                 break;
4841                         }
4842                 }
4843         }
4844         return ret;
4845 }
4846
4847 static int is_lvalue(struct compile_state *state, struct triple *def)
4848 {
4849         int ret;
4850         ret = 1;
4851         if (!def) {
4852                 return 0;
4853         }
4854         if (!is_stable(state, def)) {
4855                 return 0;
4856         }
4857         if (def->op == OP_DOT) {
4858                 ret = is_lvalue(state, RHS(def, 0));
4859         }
4860         return ret;
4861 }
4862
4863 static void clvalue(struct compile_state *state, struct triple *def)
4864 {
4865         if (!def) {
4866                 internal_error(state, def, "nothing where lvalue expected?");
4867         }
4868         if (!is_lvalue(state, def)) { 
4869                 error(state, def, "lvalue expected");
4870         }
4871 }
4872 static void lvalue(struct compile_state *state, struct triple *def)
4873 {
4874         clvalue(state, def);
4875         if (def->type->type & QUAL_CONST) {
4876                 error(state, def, "modifable lvalue expected");
4877         }
4878 }
4879
4880 static int is_pointer(struct triple *def)
4881 {
4882         return (def->type->type & TYPE_MASK) == TYPE_POINTER;
4883 }
4884
4885 static void pointer(struct compile_state *state, struct triple *def)
4886 {
4887         if (!is_pointer(def)) {
4888                 error(state, def, "pointer expected");
4889         }
4890 }
4891
4892 static struct triple *int_const(
4893         struct compile_state *state, struct type *type, ulong_t value)
4894 {
4895         struct triple *result;
4896         switch(type->type & TYPE_MASK) {
4897         case TYPE_CHAR:
4898         case TYPE_INT:   case TYPE_UINT:
4899         case TYPE_LONG:  case TYPE_ULONG:
4900                 break;
4901         default:
4902                 internal_error(state, 0, "constant for unkown type");
4903         }
4904         result = triple(state, OP_INTCONST, type, 0, 0);
4905         result->u.cval = value;
4906         return result;
4907 }
4908
4909
4910 static struct triple *read_expr(struct compile_state *state, struct triple *def);
4911
4912 static struct triple *do_mk_addr_expr(struct compile_state *state, 
4913         struct triple *expr, struct type *type, ulong_t offset)
4914 {
4915         struct triple *result;
4916         clvalue(state, expr);
4917
4918         type = new_type(TYPE_POINTER | (type->type & QUAL_MASK), type, 0);
4919
4920         result = 0;
4921         if (expr->op == OP_ADECL) {
4922                 error(state, expr, "address of auto variables not supported");
4923         }
4924         else if (expr->op == OP_SDECL) {
4925                 result = triple(state, OP_ADDRCONST, type, 0, 0);
4926                 MISC(result, 0) = expr;
4927                 result->u.cval = offset;
4928         }
4929         else if (expr->op == OP_DEREF) {
4930                 result = triple(state, OP_ADD, type,
4931                         RHS(expr, 0),
4932                         int_const(state, &ulong_type, offset));
4933         }
4934         else if (expr->op == OP_LIST) {
4935                 error(state, 0, "Function addresses not supported");
4936         }
4937         if (!result) {
4938                 internal_error(state, expr, "cannot take address of expression");
4939         }
4940         return result;
4941 }
4942
4943 static struct triple *mk_addr_expr(
4944         struct compile_state *state, struct triple *expr, ulong_t offset)
4945 {
4946         return do_mk_addr_expr(state, expr, expr->type, offset);
4947 }
4948
4949 static struct triple *mk_deref_expr(
4950         struct compile_state *state, struct triple *expr)
4951 {
4952         struct type *base_type;
4953         pointer(state, expr);
4954         base_type = expr->type->left;
4955         return triple(state, OP_DEREF, base_type, expr, 0);
4956 }
4957
4958 static struct triple *lvalue_conversion(struct compile_state *state, struct triple *def)
4959 {
4960         /* Tranform an array to a pointer to the first element */
4961         if ((def->type->type & TYPE_MASK) == TYPE_ARRAY) {
4962                 struct type *type;
4963                 type = new_type(
4964                         TYPE_POINTER | (def->type->type & QUAL_MASK),
4965                         def->type->left, 0);
4966                 if ((def->op == OP_SDECL) || IS_CONST_OP(def->op)) {
4967                         struct triple *addrconst;
4968                         if ((def->op != OP_SDECL) && (def->op != OP_BLOBCONST)) {
4969                                 internal_error(state, def, "bad array constant");
4970                         }
4971                         addrconst = triple(state, OP_ADDRCONST, type, 0, 0);
4972                         MISC(addrconst, 0) = def;
4973                         def = addrconst;
4974                 }
4975                 else {
4976                         def = triple(state, OP_COPY, type, def, 0);
4977                 }
4978         }
4979         /* Transform a function to a pointer to it */
4980         else if ((def->type->type & TYPE_MASK) == TYPE_FUNCTION) {
4981                 def = mk_addr_expr(state, def, 0);
4982         }
4983         return def;
4984 }
4985
4986 static struct triple *deref_field(
4987         struct compile_state *state, struct triple *expr, struct hash_entry *field)
4988 {
4989         struct triple *result;
4990         struct type *type, *member;
4991         if (!field) {
4992                 internal_error(state, 0, "No field passed to deref_field");
4993         }
4994         result = 0;
4995         type = expr->type;
4996         if ((type->type & TYPE_MASK) != TYPE_STRUCT) {
4997                 error(state, 0, "request for member %s in something not a struct or union",
4998                         field->name);
4999         }
5000         member = field_type(state, type, field);
5001         if ((type->type & STOR_MASK) == STOR_PERM) {
5002                 /* Do the pointer arithmetic to get a deref the field */
5003                 ulong_t offset;
5004                 offset = field_offset(state, type, field);
5005                 result = do_mk_addr_expr(state, expr, member, offset);
5006                 result = mk_deref_expr(state, result);
5007         }
5008         else {
5009                 /* Find the variable for the field I want. */
5010                 result = triple(state, OP_DOT, member, expr, 0);
5011                 result->u.field = field;
5012         }
5013         return result;
5014 }
5015
5016 static struct triple *read_expr(struct compile_state *state, struct triple *def)
5017 {
5018         int op;
5019         if  (!def) {
5020                 return 0;
5021         }
5022 #warning "CHECK_ME is this the only place I need to do lvalue conversions?"
5023         /* Transform lvalues into something we can read */
5024         def = lvalue_conversion(state, def);
5025         if (!is_stable(state, def)) {
5026                 return def;
5027         }
5028         if (is_in_reg(state, def)) {
5029                 op = OP_READ;
5030         } else {
5031                 if (def->op == OP_SDECL) {
5032                         def = mk_addr_expr(state, def, 0);
5033                         def = mk_deref_expr(state, def);
5034                 }
5035                 op = OP_LOAD;
5036         }
5037         return triple(state, op, def->type, def, 0);
5038 }
5039
5040 int is_write_compatible(struct compile_state *state, 
5041         struct type *dest, struct type *rval)
5042 {
5043         int compatible = 0;
5044         /* Both operands have arithmetic type */
5045         if (TYPE_ARITHMETIC(dest->type) && TYPE_ARITHMETIC(rval->type)) {
5046                 compatible = 1;
5047         }
5048         /* One operand is a pointer and the other is a pointer to void */
5049         else if (((dest->type & TYPE_MASK) == TYPE_POINTER) &&
5050                 ((rval->type & TYPE_MASK) == TYPE_POINTER) &&
5051                 (((dest->left->type & TYPE_MASK) == TYPE_VOID) ||
5052                         ((rval->left->type & TYPE_MASK) == TYPE_VOID))) {
5053                 compatible = 1;
5054         }
5055         /* If both types are the same without qualifiers we are good */
5056         else if (equiv_ptrs(dest, rval)) {
5057                 compatible = 1;
5058         }
5059         /* test for struct/union equality  */
5060         else if (((dest->type & TYPE_MASK) == TYPE_STRUCT) &&
5061                 ((rval->type & TYPE_MASK) == TYPE_STRUCT) &&
5062                 (dest->type_ident == rval->type_ident)) {
5063                 compatible = 1;
5064         }
5065         return compatible;
5066 }
5067
5068
5069 static void write_compatible(struct compile_state *state,
5070         struct type *dest, struct type *rval)
5071 {
5072         if (!is_write_compatible(state, dest, rval)) {
5073                 error(state, 0, "Incompatible types in assignment");
5074         }
5075 }
5076
5077 static int is_init_compatible(struct compile_state *state,
5078         struct type *dest, struct type *rval)
5079 {
5080         int compatible = 0;
5081         if (is_write_compatible(state, dest, rval)) {
5082                 compatible = 1;
5083         }
5084         else if (equiv_types(dest, rval)) {
5085                 compatible = 1;
5086         }
5087         return compatible;
5088 }
5089
5090 static struct triple *write_expr(
5091         struct compile_state *state, struct triple *dest, struct triple *rval)
5092 {
5093         struct triple *def;
5094         int op;
5095
5096         def = 0;
5097         if (!rval) {
5098                 internal_error(state, 0, "missing rval");
5099         }
5100
5101         if (rval->op == OP_LIST) {
5102                 internal_error(state, 0, "expression of type OP_LIST?");
5103         }
5104         if (!is_lvalue(state, dest)) {
5105                 internal_error(state, 0, "writing to a non lvalue?");
5106         }
5107         if (dest->type->type & QUAL_CONST) {
5108                 internal_error(state, 0, "modifable lvalue expexted");
5109         }
5110
5111         write_compatible(state, dest->type, rval->type);
5112
5113         /* Now figure out which assignment operator to use */
5114         op = -1;
5115         if (is_in_reg(state, dest)) {
5116                 op = OP_WRITE;
5117         } else {
5118                 op = OP_STORE;
5119         }
5120         def = triple(state, op, dest->type, dest, rval);
5121         return def;
5122 }
5123
5124 static struct triple *init_expr(
5125         struct compile_state *state, struct triple *dest, struct triple *rval)
5126 {
5127         struct triple *def;
5128
5129         def = 0;
5130         if (!rval) {
5131                 internal_error(state, 0, "missing rval");
5132         }
5133         if ((dest->type->type & STOR_MASK) != STOR_PERM) {
5134                 rval = read_expr(state, rval);
5135                 def = write_expr(state, dest, rval);
5136         }
5137         else {
5138                 /* Fill in the array size if necessary */
5139                 if (((dest->type->type & TYPE_MASK) == TYPE_ARRAY) &&
5140                         ((rval->type->type & TYPE_MASK) == TYPE_ARRAY)) {
5141                         if (dest->type->elements == ELEMENT_COUNT_UNSPECIFIED) {
5142                                 dest->type->elements = rval->type->elements;
5143                         }
5144                 }
5145                 if (!equiv_types(dest->type, rval->type)) {
5146                         error(state, 0, "Incompatible types in inializer");
5147                 }
5148                 MISC(dest, 0) = rval;
5149                 insert_triple(state, dest, rval);
5150                 rval->id |= TRIPLE_FLAG_FLATTENED;
5151                 use_triple(MISC(dest, 0), dest);
5152         }
5153         return def;
5154 }
5155
5156 struct type *arithmetic_result(
5157         struct compile_state *state, struct triple *left, struct triple *right)
5158 {
5159         struct type *type;
5160         /* Sanity checks to ensure I am working with arithmetic types */
5161         arithmetic(state, left);
5162         arithmetic(state, right);
5163         type = new_type(
5164                 do_arithmetic_conversion(
5165                         left->type->type, 
5166                         right->type->type), 0, 0);
5167         return type;
5168 }
5169
5170 struct type *ptr_arithmetic_result(
5171         struct compile_state *state, struct triple *left, struct triple *right)
5172 {
5173         struct type *type;
5174         /* Sanity checks to ensure I am working with the proper types */
5175         ptr_arithmetic(state, left);
5176         arithmetic(state, right);
5177         if (TYPE_ARITHMETIC(left->type->type) && 
5178                 TYPE_ARITHMETIC(right->type->type)) {
5179                 type = arithmetic_result(state, left, right);
5180         }
5181         else if (TYPE_PTR(left->type->type)) {
5182                 type = left->type;
5183         }
5184         else {
5185                 internal_error(state, 0, "huh?");
5186                 type = 0;
5187         }
5188         return type;
5189 }
5190
5191
5192 /* boolean helper function */
5193
5194 static struct triple *ltrue_expr(struct compile_state *state, 
5195         struct triple *expr)
5196 {
5197         switch(expr->op) {
5198         case OP_LTRUE:   case OP_LFALSE:  case OP_EQ:      case OP_NOTEQ:
5199         case OP_SLESS:   case OP_ULESS:   case OP_SMORE:   case OP_UMORE:
5200         case OP_SLESSEQ: case OP_ULESSEQ: case OP_SMOREEQ: case OP_UMOREEQ:
5201                 /* If the expression is already boolean do nothing */
5202                 break;
5203         default:
5204                 expr = triple(state, OP_LTRUE, &int_type, expr, 0);
5205                 break;
5206         }
5207         return expr;
5208 }
5209
5210 static struct triple *lfalse_expr(struct compile_state *state, 
5211         struct triple *expr)
5212 {
5213         return triple(state, OP_LFALSE, &int_type, expr, 0);
5214 }
5215
5216 static struct triple *cond_expr(
5217         struct compile_state *state, 
5218         struct triple *test, struct triple *left, struct triple *right)
5219 {
5220         struct triple *def;
5221         struct type *result_type;
5222         unsigned int left_type, right_type;
5223         bool(state, test);
5224         left_type = left->type->type;
5225         right_type = right->type->type;
5226         result_type = 0;
5227         /* Both operands have arithmetic type */
5228         if (TYPE_ARITHMETIC(left_type) && TYPE_ARITHMETIC(right_type)) {
5229                 result_type = arithmetic_result(state, left, right);
5230         }
5231         /* Both operands have void type */
5232         else if (((left_type & TYPE_MASK) == TYPE_VOID) &&
5233                 ((right_type & TYPE_MASK) == TYPE_VOID)) {
5234                 result_type = &void_type;
5235         }
5236         /* pointers to the same type... */
5237         else if ((result_type = compatible_ptrs(left->type, right->type))) {
5238                 ;
5239         }
5240         /* Both operands are pointers and left is a pointer to void */
5241         else if (((left_type & TYPE_MASK) == TYPE_POINTER) &&
5242                 ((right_type & TYPE_MASK) == TYPE_POINTER) &&
5243                 ((left->type->left->type & TYPE_MASK) == TYPE_VOID)) {
5244                 result_type = right->type;
5245         }
5246         /* Both operands are pointers and right is a pointer to void */
5247         else if (((left_type & TYPE_MASK) == TYPE_POINTER) &&
5248                 ((right_type & TYPE_MASK) == TYPE_POINTER) &&
5249                 ((right->type->left->type & TYPE_MASK) == TYPE_VOID)) {
5250                 result_type = left->type;
5251         }
5252         if (!result_type) {
5253                 error(state, 0, "Incompatible types in conditional expression");
5254         }
5255         /* Cleanup and invert the test */
5256         test = lfalse_expr(state, read_expr(state, test));
5257         def = new_triple(state, OP_COND, result_type, 0, 3);
5258         def->param[0] = test;
5259         def->param[1] = left;
5260         def->param[2] = right;
5261         return def;
5262 }
5263
5264
5265 static int expr_depth(struct compile_state *state, struct triple *ins)
5266 {
5267         int count;
5268         count = 0;
5269         if (!ins || (ins->id & TRIPLE_FLAG_FLATTENED)) {
5270                 count = 0;
5271         }
5272         else if (ins->op == OP_DEREF) {
5273                 count = expr_depth(state, RHS(ins, 0)) - 1;
5274         }
5275         else if (ins->op == OP_VAL) {
5276                 count = expr_depth(state, RHS(ins, 0)) - 1;
5277         }
5278         else if (ins->op == OP_COMMA) {
5279                 int ldepth, rdepth;
5280                 ldepth = expr_depth(state, RHS(ins, 0));
5281                 rdepth = expr_depth(state, RHS(ins, 1));
5282                 count = (ldepth >= rdepth)? ldepth : rdepth;
5283         }
5284         else if (ins->op == OP_FCALL) {
5285                 /* Don't figure the depth of a call just guess it is huge */
5286                 count = 1000;
5287         }
5288         else {
5289                 struct triple **expr;
5290                 expr = triple_rhs(state, ins, 0);
5291                 for(;expr; expr = triple_rhs(state, ins, expr)) {
5292                         if (*expr) {
5293                                 int depth;
5294                                 depth = expr_depth(state, *expr);
5295                                 if (depth > count) {
5296                                         count = depth;
5297                                 }
5298                         }
5299                 }
5300         }
5301         return count + 1;
5302 }
5303
5304 static struct triple *flatten(
5305         struct compile_state *state, struct triple *first, struct triple *ptr);
5306
5307 static struct triple *flatten_generic(
5308         struct compile_state *state, struct triple *first, struct triple *ptr,
5309         int ignored)
5310 {
5311         struct rhs_vector {
5312                 int depth;
5313                 struct triple **ins;
5314         } vector[MAX_RHS];
5315         int i, rhs, lhs;
5316         /* Only operations with just a rhs and a lhs should come here */
5317         rhs = TRIPLE_RHS(ptr->sizes);
5318         lhs = TRIPLE_LHS(ptr->sizes);
5319         if (TRIPLE_SIZE(ptr->sizes) != lhs + rhs + ignored) {
5320                 internal_error(state, ptr, "unexpected args for: %d %s",
5321                         ptr->op, tops(ptr->op));
5322         }
5323         /* Find the depth of the rhs elements */
5324         for(i = 0; i < rhs; i++) {
5325                 vector[i].ins = &RHS(ptr, i);
5326                 vector[i].depth = expr_depth(state, *vector[i].ins);
5327         }
5328         /* Selection sort the rhs */
5329         for(i = 0; i < rhs; i++) {
5330                 int j, max = i;
5331                 for(j = i + 1; j < rhs; j++ ) {
5332                         if (vector[j].depth > vector[max].depth) {
5333                                 max = j;
5334                         }
5335                 }
5336                 if (max != i) {
5337                         struct rhs_vector tmp;
5338                         tmp = vector[i];
5339                         vector[i] = vector[max];
5340                         vector[max] = tmp;
5341                 }
5342         }
5343         /* Now flatten the rhs elements */
5344         for(i = 0; i < rhs; i++) {
5345                 *vector[i].ins = flatten(state, first, *vector[i].ins);
5346                 use_triple(*vector[i].ins, ptr);
5347         }
5348         
5349         /* Now flatten the lhs elements */
5350         for(i = 0; i < lhs; i++) {
5351                 struct triple **ins = &LHS(ptr, i);
5352                 *ins = flatten(state, first, *ins);
5353                 use_triple(*ins, ptr);
5354         }
5355         return ptr;
5356 }
5357
5358 static struct triple *flatten_land(
5359         struct compile_state *state, struct triple *first, struct triple *ptr)
5360 {
5361         struct triple *left, *right;
5362         struct triple *val, *test, *jmp, *label1, *end;
5363
5364         /* Find the triples */
5365         left = RHS(ptr, 0);
5366         right = RHS(ptr, 1);
5367
5368         /* Generate the needed triples */
5369         end = label(state);
5370
5371         /* Thread the triples together */
5372         val          = flatten(state, first, variable(state, ptr->type));
5373         left         = flatten(state, first, write_expr(state, val, left));
5374         test         = flatten(state, first, 
5375                 lfalse_expr(state, read_expr(state, val)));
5376         jmp          = flatten(state, first, branch(state, end, test));
5377         label1       = flatten(state, first, label(state));
5378         right        = flatten(state, first, write_expr(state, val, right));
5379         TARG(jmp, 0) = flatten(state, first, end); 
5380         
5381         /* Now give the caller something to chew on */
5382         return read_expr(state, val);
5383 }
5384
5385 static struct triple *flatten_lor(
5386         struct compile_state *state, struct triple *first, struct triple *ptr)
5387 {
5388         struct triple *left, *right;
5389         struct triple *val, *jmp, *label1, *end;
5390
5391         /* Find the triples */
5392         left = RHS(ptr, 0);
5393         right = RHS(ptr, 1);
5394
5395         /* Generate the needed triples */
5396         end = label(state);
5397
5398         /* Thread the triples together */
5399         val          = flatten(state, first, variable(state, ptr->type));
5400         left         = flatten(state, first, write_expr(state, val, left));
5401         jmp          = flatten(state, first, branch(state, end, left));
5402         label1       = flatten(state, first, label(state));
5403         right        = flatten(state, first, write_expr(state, val, right));
5404         TARG(jmp, 0) = flatten(state, first, end);
5405        
5406         
5407         /* Now give the caller something to chew on */
5408         return read_expr(state, val);
5409 }
5410
5411 static struct triple *flatten_cond(
5412         struct compile_state *state, struct triple *first, struct triple *ptr)
5413 {
5414         struct triple *test, *left, *right;
5415         struct triple *val, *mv1, *jmp1, *label1, *mv2, *middle, *jmp2, *end;
5416
5417         /* Find the triples */
5418         test = RHS(ptr, 0);
5419         left = RHS(ptr, 1);
5420         right = RHS(ptr, 2);
5421
5422         /* Generate the needed triples */
5423         end = label(state);
5424         middle = label(state);
5425
5426         /* Thread the triples together */
5427         val           = flatten(state, first, variable(state, ptr->type));
5428         test          = flatten(state, first, test);
5429         jmp1          = flatten(state, first, branch(state, middle, test));
5430         label1        = flatten(state, first, label(state));
5431         left          = flatten(state, first, left);
5432         mv1           = flatten(state, first, write_expr(state, val, left));
5433         jmp2          = flatten(state, first, branch(state, end, 0));
5434         TARG(jmp1, 0) = flatten(state, first, middle);
5435         right         = flatten(state, first, right);
5436         mv2           = flatten(state, first, write_expr(state, val, right));
5437         TARG(jmp2, 0) = flatten(state, first, end);
5438         
5439         /* Now give the caller something to chew on */
5440         return read_expr(state, val);
5441 }
5442
5443 static struct triple *flatten_fcall(
5444         struct compile_state *state, struct triple *first, struct triple *ptr)
5445 {
5446         return flatten_generic(state, first, ptr, 1);
5447 }
5448
5449 static struct triple *flatten(
5450         struct compile_state *state, struct triple *first, struct triple *ptr)
5451 {
5452         struct triple *orig_ptr;
5453         if (!ptr)
5454                 return 0;
5455         do {
5456                 orig_ptr = ptr;
5457                 /* Only flatten triples once */
5458                 if (ptr->id & TRIPLE_FLAG_FLATTENED) {
5459                         return ptr;
5460                 }
5461                 switch(ptr->op) {
5462                 case OP_COMMA:
5463                         RHS(ptr, 0) = flatten(state, first, RHS(ptr, 0));
5464                         ptr = RHS(ptr, 1);
5465                         break;
5466                 case OP_VAL:
5467                         RHS(ptr, 0) = flatten(state, first, RHS(ptr, 0));
5468                         return MISC(ptr, 0);
5469                         break;
5470                 case OP_LAND:
5471                         ptr = flatten_land(state, first, ptr);
5472                         break;
5473                 case OP_LOR:
5474                         ptr = flatten_lor(state, first, ptr);
5475                         break;
5476                 case OP_COND:
5477                         ptr = flatten_cond(state, first, ptr);
5478                         break;
5479                 case OP_FCALL:
5480                         ptr = flatten_fcall(state, first, ptr);
5481                         break;
5482                 case OP_READ:
5483                 case OP_LOAD:
5484                         RHS(ptr, 0) = flatten(state, first, RHS(ptr, 0));
5485                         use_triple(RHS(ptr, 0), ptr);
5486                         break;
5487                 case OP_BRANCH:
5488                         use_triple(TARG(ptr, 0), ptr);
5489                         break;
5490                 case OP_CBRANCH:
5491                         RHS(ptr, 0) = flatten(state, first, RHS(ptr, 0));
5492                         use_triple(RHS(ptr, 0), ptr);
5493                         use_triple(TARG(ptr, 0), ptr);
5494                         if (ptr->next != ptr) {
5495                                 use_triple(ptr->next, ptr);
5496                         }
5497                         break;
5498                 case OP_CALL:
5499                         MISC(ptr, 0) = flatten(state, first, MISC(ptr, 0));
5500                         use_triple(MISC(ptr, 0), ptr);
5501                         use_triple(TARG(ptr, 0), ptr);
5502                         if (ptr->next != ptr) {
5503                                 use_triple(ptr->next, ptr);
5504                         }
5505                         break;
5506                 case OP_RET:
5507                         RHS(ptr, 0) = flatten(state, first, RHS(ptr, 0));
5508                         use_triple(RHS(ptr, 0), ptr);
5509                         break;
5510                 case OP_BLOBCONST:
5511                         insert_triple(state, state->global_pool, ptr);
5512                         ptr->id |= TRIPLE_FLAG_FLATTENED;
5513                         ptr->id &= ~TRIPLE_FLAG_LOCAL;
5514                         ptr = triple(state, OP_SDECL, ptr->type, ptr, 0);
5515                         use_triple(MISC(ptr, 0), ptr);
5516                         break;
5517                 case OP_DEREF:
5518                         /* Since OP_DEREF is just a marker delete it when I flatten it */
5519                         ptr = RHS(ptr, 0);
5520                         RHS(orig_ptr, 0) = 0;
5521                         free_triple(state, orig_ptr);
5522                         break;
5523                 case OP_DOT:
5524                 {
5525                         struct triple *base;
5526                         base = RHS(ptr, 0);
5527                         if (base->op == OP_DEREF) {
5528                                 struct triple *left;
5529                                 ulong_t offset;
5530                                 offset = field_offset(state, base->type, ptr->u.field);
5531                                 left = RHS(base, 0);
5532                                 ptr = triple(state, OP_ADD, left->type, 
5533                                         read_expr(state, left),
5534                                         int_const(state, &ulong_type, offset));
5535                                 free_triple(state, base);
5536                         }
5537                         else if (base->op == OP_VAL_VEC) {
5538                                 base = flatten(state, first, base);
5539                                 ptr = struct_field(state, base, ptr->u.field);
5540                         }
5541                         break;
5542                 }
5543                 case OP_PIECE:
5544                         MISC(ptr, 0) = flatten(state, first, MISC(ptr, 0));
5545                         use_triple(MISC(ptr, 0), ptr);
5546                         use_triple(ptr, MISC(ptr, 0));
5547                         break;
5548                 case OP_ADDRCONST:
5549                         MISC(ptr, 0) = flatten(state, first, MISC(ptr, 0));
5550                         use_triple(MISC(ptr, 0), ptr);
5551                         break;
5552                 case OP_SDECL:
5553                         first = state->global_pool;
5554                         MISC(ptr, 0) = flatten(state, first, MISC(ptr, 0));
5555                         use_triple(MISC(ptr, 0), ptr);
5556                         insert_triple(state, first, ptr);
5557                         ptr->id |= TRIPLE_FLAG_FLATTENED;
5558                         ptr->id &= ~TRIPLE_FLAG_LOCAL;
5559                         return ptr;
5560                 case OP_ADECL:
5561                         break;
5562                 default:
5563                         /* Flatten the easy cases we don't override */
5564                         ptr = flatten_generic(state, first, ptr, 0);
5565                         break;
5566                 }
5567         } while(ptr && (ptr != orig_ptr));
5568         if (ptr) {
5569                 insert_triple(state, first, ptr);
5570                 ptr->id |= TRIPLE_FLAG_FLATTENED;
5571                 ptr->id &= ~TRIPLE_FLAG_LOCAL;
5572         }
5573         return ptr;
5574 }
5575
5576 static void release_expr(struct compile_state *state, struct triple *expr)
5577 {
5578         struct triple *head;
5579         head = label(state);
5580         flatten(state, head, expr);
5581         while(head->next != head) {
5582                 release_triple(state, head->next);
5583         }
5584         free_triple(state, head);
5585 }
5586
5587 static int replace_rhs_use(struct compile_state *state,
5588         struct triple *orig, struct triple *new, struct triple *use)
5589 {
5590         struct triple **expr;
5591         int found;
5592         found = 0;
5593         expr = triple_rhs(state, use, 0);
5594         for(;expr; expr = triple_rhs(state, use, expr)) {
5595                 if (*expr == orig) {
5596                         *expr = new;
5597                         found = 1;
5598                 }
5599         }
5600         if (found) {
5601                 unuse_triple(orig, use);
5602                 use_triple(new, use);
5603         }
5604         return found;
5605 }
5606
5607 static int replace_lhs_use(struct compile_state *state,
5608         struct triple *orig, struct triple *new, struct triple *use)
5609 {
5610         struct triple **expr;
5611         int found;
5612         found = 0;
5613         expr = triple_lhs(state, use, 0);
5614         for(;expr; expr = triple_lhs(state, use, expr)) {
5615                 if (*expr == orig) {
5616                         *expr = new;
5617                         found = 1;
5618                 }
5619         }
5620         if (found) {
5621                 unuse_triple(orig, use);
5622                 use_triple(new, use);
5623         }
5624         return found;
5625 }
5626
5627 static void propogate_use(struct compile_state *state,
5628         struct triple *orig, struct triple *new)
5629 {
5630         struct triple_set *user, *next;
5631         for(user = orig->use; user; user = next) {
5632                 struct triple *use;
5633                 int found;
5634                 next = user->next;
5635                 use = user->member;
5636                 found = 0;
5637                 found |= replace_rhs_use(state, orig, new, use);
5638                 found |= replace_lhs_use(state, orig, new, use);
5639                 if (!found) {
5640                         internal_error(state, use, "use without use");
5641                 }
5642         }
5643         if (orig->use) {
5644                 internal_error(state, orig, "used after propogate_use");
5645         }
5646 }
5647
5648 /*
5649  * Code generators
5650  * ===========================
5651  */
5652
5653 static struct triple *mk_add_expr(
5654         struct compile_state *state, struct triple *left, struct triple *right)
5655 {
5656         struct type *result_type;
5657         /* Put pointer operands on the left */
5658         if (is_pointer(right)) {
5659                 struct triple *tmp;
5660                 tmp = left;
5661                 left = right;
5662                 right = tmp;
5663         }
5664         left  = read_expr(state, left);
5665         right = read_expr(state, right);
5666         result_type = ptr_arithmetic_result(state, left, right);
5667         if (is_pointer(left)) {
5668                 right = triple(state, 
5669                         is_signed(right->type)? OP_SMUL : OP_UMUL, 
5670                         &ulong_type, 
5671                         right, 
5672                         int_const(state, &ulong_type, 
5673                                 size_of(state, left->type->left)));
5674         }
5675         return triple(state, OP_ADD, result_type, left, right);
5676 }
5677
5678 static struct triple *mk_sub_expr(
5679         struct compile_state *state, struct triple *left, struct triple *right)
5680 {
5681         struct type *result_type;
5682         result_type = ptr_arithmetic_result(state, left, right);
5683         left  = read_expr(state, left);
5684         right = read_expr(state, right);
5685         if (is_pointer(left)) {
5686                 right = triple(state, 
5687                         is_signed(right->type)? OP_SMUL : OP_UMUL, 
5688                         &ulong_type, 
5689                         right, 
5690                         int_const(state, &ulong_type, 
5691                                 size_of(state, left->type->left)));
5692         }
5693         return triple(state, OP_SUB, result_type, left, right);
5694 }
5695
5696 static struct triple *mk_pre_inc_expr(
5697         struct compile_state *state, struct triple *def)
5698 {
5699         struct triple *val;
5700         lvalue(state, def);
5701         val = mk_add_expr(state, def, int_const(state, &int_type, 1));
5702         return triple(state, OP_VAL, def->type,
5703                 write_expr(state, def, val),
5704                 val);
5705 }
5706
5707 static struct triple *mk_pre_dec_expr(
5708         struct compile_state *state, struct triple *def)
5709 {
5710         struct triple *val;
5711         lvalue(state, def);
5712         val = mk_sub_expr(state, def, int_const(state, &int_type, 1));
5713         return triple(state, OP_VAL, def->type,
5714                 write_expr(state, def, val),
5715                 val);
5716 }
5717
5718 static struct triple *mk_post_inc_expr(
5719         struct compile_state *state, struct triple *def)
5720 {
5721         struct triple *val;
5722         lvalue(state, def);
5723         val = read_expr(state, def);
5724         return triple(state, OP_VAL, def->type,
5725                 write_expr(state, def,
5726                         mk_add_expr(state, val, int_const(state, &int_type, 1)))
5727                 , val);
5728 }
5729
5730 static struct triple *mk_post_dec_expr(
5731         struct compile_state *state, struct triple *def)
5732 {
5733         struct triple *val;
5734         lvalue(state, def);
5735         val = read_expr(state, def);
5736         return triple(state, OP_VAL, def->type, 
5737                 write_expr(state, def,
5738                         mk_sub_expr(state, val, int_const(state, &int_type, 1)))
5739                 , val);
5740 }
5741
5742 static struct triple *mk_subscript_expr(
5743         struct compile_state *state, struct triple *left, struct triple *right)
5744 {
5745         left  = read_expr(state, left);
5746         right = read_expr(state, right);
5747         if (!is_pointer(left) && !is_pointer(right)) {
5748                 error(state, left, "subscripted value is not a pointer");
5749         }
5750         return mk_deref_expr(state, mk_add_expr(state, left, right));
5751 }
5752
5753 static struct triple *mk_cast_expr(
5754         struct compile_state *state, struct type *type, struct triple *expr)
5755 {
5756         struct triple *def;
5757         def = read_expr(state, expr);
5758         def = triple(state, OP_COPY, type, def, 0);
5759         return def;
5760 }
5761
5762 /*
5763  * Compile time evaluation
5764  * ===========================
5765  */
5766 static int is_const(struct triple *ins)
5767 {
5768         return IS_CONST_OP(ins->op);
5769 }
5770
5771 static int is_simple_const(struct triple *ins)
5772 {
5773         return IS_CONST_OP(ins->op) && (ins->op != OP_ADDRCONST);
5774 }
5775
5776 static int constants_equal(struct compile_state *state, 
5777         struct triple *left, struct triple *right)
5778 {
5779         int equal;
5780         if (!is_const(left) || !is_const(right)) {
5781                 equal = 0;
5782         }
5783         else if (left->op != right->op) {
5784                 equal = 0;
5785         }
5786         else if (!equiv_types(left->type, right->type)) {
5787                 equal = 0;
5788         }
5789         else {
5790                 equal = 0;
5791                 switch(left->op) {
5792                 case OP_INTCONST:
5793                         if (left->u.cval == right->u.cval) {
5794                                 equal = 1;
5795                         }
5796                         break;
5797                 case OP_BLOBCONST:
5798                 {
5799                         size_t lsize, rsize;
5800                         lsize = size_of(state, left->type);
5801                         rsize = size_of(state, right->type);
5802                         if (lsize != rsize) {
5803                                 break;
5804                         }
5805                         if (memcmp(left->u.blob, right->u.blob, lsize) == 0) {
5806                                 equal = 1;
5807                         }
5808                         break;
5809                 }
5810                 case OP_ADDRCONST:
5811                         if ((MISC(left, 0) == MISC(right, 0)) &&
5812                                 (left->u.cval == right->u.cval)) {
5813                                 equal = 1;
5814                         }
5815                         break;
5816                 default:
5817                         internal_error(state, left, "uknown constant type");
5818                         break;
5819                 }
5820         }
5821         return equal;
5822 }
5823
5824 static int is_zero(struct triple *ins)
5825 {
5826         return is_simple_const(ins) && (ins->u.cval == 0);
5827 }
5828
5829 static int is_one(struct triple *ins)
5830 {
5831         return is_simple_const(ins) && (ins->u.cval == 1);
5832 }
5833
5834 static long_t bit_count(ulong_t value)
5835 {
5836         int count;
5837         int i;
5838         count = 0;
5839         for(i = (sizeof(ulong_t)*8) -1; i >= 0; i--) {
5840                 ulong_t mask;
5841                 mask = 1;
5842                 mask <<= i;
5843                 if (value & mask) {
5844                         count++;
5845                 }
5846         }
5847         return count;
5848         
5849 }
5850 static long_t bsr(ulong_t value)
5851 {
5852         int i;
5853         for(i = (sizeof(ulong_t)*8) -1; i >= 0; i--) {
5854                 ulong_t mask;
5855                 mask = 1;
5856                 mask <<= i;
5857                 if (value & mask) {
5858                         return i;
5859                 }
5860         }
5861         return -1;
5862 }
5863
5864 static long_t bsf(ulong_t value)
5865 {
5866         int i;
5867         for(i = 0; i < (sizeof(ulong_t)*8); i++) {
5868                 ulong_t mask;
5869                 mask = 1;
5870                 mask <<= 1;
5871                 if (value & mask) {
5872                         return i;
5873                 }
5874         }
5875         return -1;
5876 }
5877
5878 static long_t log2(ulong_t value)
5879 {
5880         return bsr(value);
5881 }
5882
5883 static long_t tlog2(struct triple *ins)
5884 {
5885         return log2(ins->u.cval);
5886 }
5887
5888 static int is_pow2(struct triple *ins)
5889 {
5890         ulong_t value, mask;
5891         long_t log;
5892         if (!is_const(ins)) {
5893                 return 0;
5894         }
5895         value = ins->u.cval;
5896         log = log2(value);
5897         if (log == -1) {
5898                 return 0;
5899         }
5900         mask = 1;
5901         mask <<= log;
5902         return  ((value & mask) == value);
5903 }
5904
5905 static ulong_t read_const(struct compile_state *state,
5906         struct triple *ins, struct triple *rhs)
5907 {
5908         switch(rhs->type->type &TYPE_MASK) {
5909         case TYPE_CHAR:   
5910         case TYPE_SHORT:
5911         case TYPE_INT:
5912         case TYPE_LONG:
5913         case TYPE_UCHAR:   
5914         case TYPE_USHORT:  
5915         case TYPE_UINT:
5916         case TYPE_ULONG:
5917         case TYPE_POINTER:
5918                 break;
5919         default:
5920                 internal_error(state, rhs, "bad type to read_const\n");
5921                 break;
5922         }
5923         if (!is_simple_const(rhs)) {
5924                 internal_error(state, rhs, "bad op to read_const\n");
5925         }
5926         return rhs->u.cval;
5927 }
5928
5929 static long_t read_sconst(struct compile_state *state,
5930         struct triple *ins, struct triple *rhs)
5931 {
5932         return (long_t)(rhs->u.cval);
5933 }
5934
5935 int const_ltrue(struct compile_state *state, struct triple *ins, struct triple *rhs)
5936 {
5937         if (!is_const(rhs)) {
5938                 internal_error(state, 0, "non const passed to const_true\n");
5939         }
5940         return !is_zero(rhs);
5941 }
5942
5943 int const_eq(struct compile_state *state, struct triple *ins,
5944         struct triple *left, struct triple *right)
5945 {
5946         int result;
5947         if (!is_const(left) || !is_const(right)) {
5948                 internal_error(state, ins, "non const passed to const_eq\n");
5949                 result = 0;
5950         }
5951         else if (left == right) {
5952                 result = 1;
5953         }
5954         else if (is_simple_const(left) && is_simple_const(right)) {
5955                 ulong_t lval, rval;
5956                 lval = read_const(state, ins, left);
5957                 rval = read_const(state, ins, right);
5958                 result = (lval == rval);
5959         }
5960         else if ((left->op == OP_ADDRCONST) && 
5961                 (right->op == OP_ADDRCONST)) {
5962                 result = (MISC(left, 0) == MISC(right, 0)) &&
5963                         (left->u.cval == right->u.cval);
5964         }
5965         else {
5966                 internal_error(state, ins, "incomparable constants passed to const_eq\n");
5967                 result = 0;
5968         }
5969         return result;
5970         
5971 }
5972
5973 int const_ucmp(struct compile_state *state, struct triple *ins,
5974         struct triple *left, struct triple *right)
5975 {
5976         int result;
5977         if (!is_const(left) || !is_const(right)) {
5978                 internal_error(state, ins, "non const past to ucmp_const\n");
5979                 result = -2;
5980         }
5981         else if (left == right) {
5982                 result = 0;
5983         }
5984         else if (is_simple_const(left) && is_simple_const(right)) {
5985                 ulong_t lval, rval;
5986                 lval = read_const(state, ins, left);
5987                 rval = read_const(state, ins, right);
5988                 result = 0;
5989                 if (lval > rval) {
5990                         result = 1;
5991                 } else if (rval > lval) {
5992                         result = -1;
5993                 }
5994         }
5995         else if ((left->op == OP_ADDRCONST) && 
5996                 (right->op == OP_ADDRCONST) &&
5997                 (MISC(left, 0) == MISC(right, 0))) {
5998                 result = 0;
5999                 if (left->u.cval > right->u.cval) {
6000                         result = 1;
6001                 } else if (left->u.cval < right->u.cval) {
6002                         result = -1;
6003                 }
6004         }
6005         else {
6006                 internal_error(state, ins, "incomparable constants passed to const_ucmp\n");
6007                 result = -2;
6008         }
6009         return result;
6010 }
6011
6012 int const_scmp(struct compile_state *state, struct triple *ins,
6013         struct triple *left, struct triple *right)
6014 {
6015         int result;
6016         if (!is_const(left) || !is_const(right)) {
6017                 internal_error(state, ins, "non const past to ucmp_const\n");
6018                 result = -2;
6019         }
6020         else if (left == right) {
6021                 result = 0;
6022         }
6023         else if (is_simple_const(left) && is_simple_const(right)) {
6024                 long_t lval, rval;
6025                 lval = read_sconst(state, ins, left);
6026                 rval = read_sconst(state, ins, right);
6027                 result = 0;
6028                 if (lval > rval) {
6029                         result = 1;
6030                 } else if (rval > lval) {
6031                         result = -1;
6032                 }
6033         }
6034         else {
6035                 internal_error(state, ins, "incomparable constants passed to const_scmp\n");
6036                 result = -2;
6037         }
6038         return result;
6039 }
6040
6041 static void unuse_rhs(struct compile_state *state, struct triple *ins)
6042 {
6043         struct triple **expr;
6044         expr = triple_rhs(state, ins, 0);
6045         for(;expr;expr = triple_rhs(state, ins, expr)) {
6046                 if (*expr) {
6047                         unuse_triple(*expr, ins);
6048                         *expr = 0;
6049                 }
6050         }
6051 }
6052
6053 static void unuse_lhs(struct compile_state *state, struct triple *ins)
6054 {
6055         struct triple **expr;
6056         expr = triple_lhs(state, ins, 0);
6057         for(;expr;expr = triple_lhs(state, ins, expr)) {
6058                 unuse_triple(*expr, ins);
6059                 *expr = 0;
6060         }
6061 }
6062
6063 static void check_lhs(struct compile_state *state, struct triple *ins)
6064 {
6065         struct triple **expr;
6066         expr = triple_lhs(state, ins, 0);
6067         for(;expr;expr = triple_lhs(state, ins, expr)) {
6068                 internal_error(state, ins, "unexpected lhs");
6069         }
6070         
6071 }
6072 static void check_targ(struct compile_state *state, struct triple *ins)
6073 {
6074         struct triple **expr;
6075         expr = triple_targ(state, ins, 0);
6076         for(;expr;expr = triple_targ(state, ins, expr)) {
6077                 internal_error(state, ins, "unexpected targ");
6078         }
6079 }
6080
6081 static void wipe_ins(struct compile_state *state, struct triple *ins)
6082 {
6083         /* Becareful which instructions you replace the wiped
6084          * instruction with, as there are not enough slots
6085          * in all instructions to hold all others.
6086          */
6087         check_targ(state, ins);
6088         unuse_rhs(state, ins);
6089         unuse_lhs(state, ins);
6090 }
6091
6092 static void mkcopy(struct compile_state *state, 
6093         struct triple *ins, struct triple *rhs)
6094 {
6095         struct block *block;
6096         block = block_of_triple(state, ins);
6097         wipe_ins(state, ins);
6098         ins->op = OP_COPY;
6099         ins->sizes = TRIPLE_SIZES(0, 1, 0, 0);
6100         ins->u.block = block;
6101         RHS(ins, 0) = rhs;
6102         use_triple(RHS(ins, 0), ins);
6103 }
6104
6105 static void mkconst(struct compile_state *state, 
6106         struct triple *ins, ulong_t value)
6107 {
6108         if (!is_integral(ins) && !is_pointer(ins)) {
6109                 internal_error(state, ins, "unknown type to make constant\n");
6110         }
6111         wipe_ins(state, ins);
6112         ins->op = OP_INTCONST;
6113         ins->sizes = TRIPLE_SIZES(0, 0, 0, 0);
6114         ins->u.cval = value;
6115 }
6116
6117 static void mkaddr_const(struct compile_state *state,
6118         struct triple *ins, struct triple *sdecl, ulong_t value)
6119 {
6120         if (sdecl->op != OP_SDECL) {
6121                 internal_error(state, ins, "bad base for addrconst");
6122         }
6123         wipe_ins(state, ins);
6124         ins->op = OP_ADDRCONST;
6125         ins->sizes = TRIPLE_SIZES(0, 0, 1, 0);
6126         MISC(ins, 0) = sdecl;
6127         ins->u.cval = value;
6128         use_triple(sdecl, ins);
6129 }
6130
6131 /* Transform multicomponent variables into simple register variables */
6132 static void flatten_structures(struct compile_state *state)
6133 {
6134         struct triple *ins, *first;
6135         first = state->first;
6136         ins = first;
6137         /* Pass one expand structure values into valvecs.
6138          */
6139         ins = first;
6140         do {
6141                 struct triple *next;
6142                 next = ins->next;
6143                 valid_ins(state, ins);
6144                 if ((ins->type->type & TYPE_MASK) == TYPE_STRUCT) {
6145                         if (ins->op == OP_VAL_VEC) {
6146                                 /* Do nothing */
6147                         }
6148                         else if ((ins->op == OP_LOAD) || (ins->op == OP_READ)) {
6149                                 struct triple *def, **vector;
6150                                 struct type *tptr;
6151                                 int op;
6152                                 ulong_t i;
6153
6154                                 op = ins->op;
6155                                 def = RHS(ins, 0);
6156                                 get_occurance(ins->occurance);
6157                                 next = alloc_triple(state, OP_VAL_VEC, ins->type, -1, -1,
6158                                         ins->occurance);
6159
6160                                 vector = &RHS(next, 0);
6161                                 tptr = next->type->left;
6162                                 for(i = 0; i < next->type->elements; i++) {
6163                                         struct triple *sfield;
6164                                         struct type *mtype;
6165                                         mtype = tptr;
6166                                         if ((mtype->type & TYPE_MASK) == TYPE_PRODUCT) {
6167                                                 mtype = mtype->left;
6168                                         }
6169                                         sfield = deref_field(state, def, mtype->field_ident);
6170                                         
6171                                         vector[i] = triple(
6172                                                 state, op, mtype, sfield, 0);
6173                                         put_occurance(vector[i]->occurance);
6174                                         get_occurance(next->occurance);
6175                                         vector[i]->occurance = next->occurance;
6176                                         tptr = tptr->right;
6177                                 }
6178                                 propogate_use(state, ins, next);
6179                                 flatten(state, ins, next);
6180                                 release_triple(state, ins);
6181                         }
6182                         else if ((ins->op == OP_STORE) || (ins->op == OP_WRITE)) {
6183                                 struct triple *src, *dst, **vector;
6184                                 struct type *tptr;
6185                                 int op;
6186                                 ulong_t i;
6187
6188                                 op = ins->op;
6189                                 src = RHS(ins, 1);
6190                                 dst = RHS(ins, 0);
6191                                 get_occurance(ins->occurance);
6192                                 next = alloc_triple(state, OP_VAL_VEC, ins->type, -1, -1,
6193                                         ins->occurance);
6194                                 
6195                                 vector = &RHS(next, 0);
6196                                 tptr = next->type->left;
6197                                 for(i = 0; i < ins->type->elements; i++) {
6198                                         struct triple *dfield, *sfield;
6199                                         struct type *mtype;
6200                                         mtype = tptr;
6201                                         if ((mtype->type & TYPE_MASK) == TYPE_PRODUCT) {
6202                                                 mtype = mtype->left;
6203                                         }
6204                                         sfield = deref_field(state, src, mtype->field_ident);
6205                                         dfield = deref_field(state, dst, mtype->field_ident);
6206                                         vector[i] = triple(
6207                                                 state, op, mtype, dfield, sfield);
6208                                         put_occurance(vector[i]->occurance);
6209                                         get_occurance(next->occurance);
6210                                         vector[i]->occurance = next->occurance;
6211                                         tptr = tptr->right;
6212                                 }
6213                                 propogate_use(state, ins, next);
6214                                 flatten(state, ins, next);
6215                                 release_triple(state, ins);
6216                         }
6217                 }
6218                 ins = next;
6219         } while(ins != first);
6220         /* Pass two flatten the valvecs.
6221          */
6222         ins = first;
6223         do {
6224                 struct triple *next;
6225                 next = ins->next;
6226                 if (ins->op == OP_VAL_VEC) {
6227                         if (ins->use) {
6228                                 internal_error(state, ins, "valvec used\n");
6229                         }
6230                         release_triple(state, ins);
6231                 } 
6232                 ins = next;
6233         } while(ins != first);
6234         /* Pass three verify the state and set ->id to 0.
6235          */
6236         ins = first;
6237         do {
6238                 ins->id &= ~TRIPLE_FLAG_FLATTENED;
6239                 if ((ins->op != OP_BLOBCONST) && (ins->op != OP_SDECL) &&
6240                         ((ins->type->type & TYPE_MASK) == TYPE_STRUCT)) {
6241                         internal_error(state, ins, "STRUCT_TYPE remains?");
6242                 }
6243                 if (ins->op == OP_DOT) {
6244                         internal_error(state, ins, "OP_DOT remains?");
6245                 }
6246                 if (ins->op == OP_VAL_VEC) {
6247                         internal_error(state, ins, "OP_VAL_VEC remains?");
6248                 }
6249                 ins = ins->next;
6250         } while(ins != first);
6251 }
6252
6253 /* For those operations that cannot be simplified */
6254 static void simplify_noop(struct compile_state *state, struct triple *ins)
6255 {
6256         return;
6257 }
6258
6259 static void simplify_smul(struct compile_state *state, struct triple *ins)
6260 {
6261         if (is_const(RHS(ins, 0)) && !is_const(RHS(ins, 1))) {
6262                 struct triple *tmp;
6263                 tmp = RHS(ins, 0);
6264                 RHS(ins, 0) = RHS(ins, 1);
6265                 RHS(ins, 1) = tmp;
6266         }
6267         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6268                 long_t left, right;
6269                 left  = read_sconst(state, ins, RHS(ins, 0));
6270                 right = read_sconst(state, ins, RHS(ins, 1));
6271                 mkconst(state, ins, left * right);
6272         }
6273         else if (is_zero(RHS(ins, 1))) {
6274                 mkconst(state, ins, 0);
6275         }
6276         else if (is_one(RHS(ins, 1))) {
6277                 mkcopy(state, ins, RHS(ins, 0));
6278         }
6279         else if (is_pow2(RHS(ins, 1))) {
6280                 struct triple *val;
6281                 val = int_const(state, ins->type, tlog2(RHS(ins, 1)));
6282                 ins->op = OP_SL;
6283                 insert_triple(state, state->global_pool, val);
6284                 unuse_triple(RHS(ins, 1), ins);
6285                 use_triple(val, ins);
6286                 RHS(ins, 1) = val;
6287         }
6288 }
6289
6290 static void simplify_umul(struct compile_state *state, struct triple *ins)
6291 {
6292         if (is_const(RHS(ins, 0)) && !is_const(RHS(ins, 1))) {
6293                 struct triple *tmp;
6294                 tmp = RHS(ins, 0);
6295                 RHS(ins, 0) = RHS(ins, 1);
6296                 RHS(ins, 1) = tmp;
6297         }
6298         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6299                 ulong_t left, right;
6300                 left  = read_const(state, ins, RHS(ins, 0));
6301                 right = read_const(state, ins, RHS(ins, 1));
6302                 mkconst(state, ins, left * right);
6303         }
6304         else if (is_zero(RHS(ins, 1))) {
6305                 mkconst(state, ins, 0);
6306         }
6307         else if (is_one(RHS(ins, 1))) {
6308                 mkcopy(state, ins, RHS(ins, 0));
6309         }
6310         else if (is_pow2(RHS(ins, 1))) {
6311                 struct triple *val;
6312                 val = int_const(state, ins->type, tlog2(RHS(ins, 1)));
6313                 ins->op = OP_SL;
6314                 insert_triple(state, state->global_pool, val);
6315                 unuse_triple(RHS(ins, 1), ins);
6316                 use_triple(val, ins);
6317                 RHS(ins, 1) = val;
6318         }
6319 }
6320
6321 static void simplify_sdiv(struct compile_state *state, struct triple *ins)
6322 {
6323         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6324                 long_t left, right;
6325                 left  = read_sconst(state, ins, RHS(ins, 0));
6326                 right = read_sconst(state, ins, RHS(ins, 1));
6327                 mkconst(state, ins, left / right);
6328         }
6329         else if (is_zero(RHS(ins, 0))) {
6330                 mkconst(state, ins, 0);
6331         }
6332         else if (is_zero(RHS(ins, 1))) {
6333                 error(state, ins, "division by zero");
6334         }
6335         else if (is_one(RHS(ins, 1))) {
6336                 mkcopy(state, ins, RHS(ins, 0));
6337         }
6338         else if (is_pow2(RHS(ins, 1))) {
6339                 struct triple *val;
6340                 val = int_const(state, ins->type, tlog2(RHS(ins, 1)));
6341                 ins->op = OP_SSR;
6342                 insert_triple(state, state->global_pool, val);
6343                 unuse_triple(RHS(ins, 1), ins);
6344                 use_triple(val, ins);
6345                 RHS(ins, 1) = val;
6346         }
6347 }
6348
6349 static void simplify_udiv(struct compile_state *state, struct triple *ins)
6350 {
6351         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6352                 ulong_t left, right;
6353                 left  = read_const(state, ins, RHS(ins, 0));
6354                 right = read_const(state, ins, RHS(ins, 1));
6355                 mkconst(state, ins, left / right);
6356         }
6357         else if (is_zero(RHS(ins, 0))) {
6358                 mkconst(state, ins, 0);
6359         }
6360         else if (is_zero(RHS(ins, 1))) {
6361                 error(state, ins, "division by zero");
6362         }
6363         else if (is_one(RHS(ins, 1))) {
6364                 mkcopy(state, ins, RHS(ins, 0));
6365         }
6366         else if (is_pow2(RHS(ins, 1))) {
6367                 struct triple *val;
6368                 val = int_const(state, ins->type, tlog2(RHS(ins, 1)));
6369                 ins->op = OP_USR;
6370                 insert_triple(state, state->global_pool, val);
6371                 unuse_triple(RHS(ins, 1), ins);
6372                 use_triple(val, ins);
6373                 RHS(ins, 1) = val;
6374         }
6375 }
6376
6377 static void simplify_smod(struct compile_state *state, struct triple *ins)
6378 {
6379         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6380                 long_t left, right;
6381                 left  = read_const(state, ins, RHS(ins, 0));
6382                 right = read_const(state, ins, RHS(ins, 1));
6383                 mkconst(state, ins, left % right);
6384         }
6385         else if (is_zero(RHS(ins, 0))) {
6386                 mkconst(state, ins, 0);
6387         }
6388         else if (is_zero(RHS(ins, 1))) {
6389                 error(state, ins, "division by zero");
6390         }
6391         else if (is_one(RHS(ins, 1))) {
6392                 mkconst(state, ins, 0);
6393         }
6394         else if (is_pow2(RHS(ins, 1))) {
6395                 struct triple *val;
6396                 val = int_const(state, ins->type, RHS(ins, 1)->u.cval - 1);
6397                 ins->op = OP_AND;
6398                 insert_triple(state, state->global_pool, val);
6399                 unuse_triple(RHS(ins, 1), ins);
6400                 use_triple(val, ins);
6401                 RHS(ins, 1) = val;
6402         }
6403 }
6404
6405 static void simplify_umod(struct compile_state *state, struct triple *ins)
6406 {
6407         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6408                 ulong_t left, right;
6409                 left  = read_const(state, ins, RHS(ins, 0));
6410                 right = read_const(state, ins, RHS(ins, 1));
6411                 mkconst(state, ins, left % right);
6412         }
6413         else if (is_zero(RHS(ins, 0))) {
6414                 mkconst(state, ins, 0);
6415         }
6416         else if (is_zero(RHS(ins, 1))) {
6417                 error(state, ins, "division by zero");
6418         }
6419         else if (is_one(RHS(ins, 1))) {
6420                 mkconst(state, ins, 0);
6421         }
6422         else if (is_pow2(RHS(ins, 1))) {
6423                 struct triple *val;
6424                 val = int_const(state, ins->type, RHS(ins, 1)->u.cval - 1);
6425                 ins->op = OP_AND;
6426                 insert_triple(state, state->global_pool, val);
6427                 unuse_triple(RHS(ins, 1), ins);
6428                 use_triple(val, ins);
6429                 RHS(ins, 1) = val;
6430         }
6431 }
6432
6433 static void simplify_add(struct compile_state *state, struct triple *ins)
6434 {
6435         /* start with the pointer on the left */
6436         if (is_pointer(RHS(ins, 1))) {
6437                 struct triple *tmp;
6438                 tmp = RHS(ins, 0);
6439                 RHS(ins, 0) = RHS(ins, 1);
6440                 RHS(ins, 1) = tmp;
6441         }
6442         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6443                 if (RHS(ins, 0)->op == OP_INTCONST) {
6444                         ulong_t left, right;
6445                         left  = read_const(state, ins, RHS(ins, 0));
6446                         right = read_const(state, ins, RHS(ins, 1));
6447                         mkconst(state, ins, left + right);
6448                 }
6449                 else if (RHS(ins, 0)->op == OP_ADDRCONST) {
6450                         struct triple *sdecl;
6451                         ulong_t left, right;
6452                         sdecl = MISC(RHS(ins, 0), 0);
6453                         left  = RHS(ins, 0)->u.cval;
6454                         right = RHS(ins, 1)->u.cval;
6455                         mkaddr_const(state, ins, sdecl, left + right);
6456                 }
6457                 else {
6458                         internal_warning(state, ins, "Optimize me!");
6459                 }
6460         }
6461         else if (is_const(RHS(ins, 0)) && !is_const(RHS(ins, 1))) {
6462                 struct triple *tmp;
6463                 tmp = RHS(ins, 1);
6464                 RHS(ins, 1) = RHS(ins, 0);
6465                 RHS(ins, 0) = tmp;
6466         }
6467 }
6468
6469 static void simplify_sub(struct compile_state *state, struct triple *ins)
6470 {
6471         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6472                 if (RHS(ins, 0)->op == OP_INTCONST) {
6473                         ulong_t left, right;
6474                         left  = read_const(state, ins, RHS(ins, 0));
6475                         right = read_const(state, ins, RHS(ins, 1));
6476                         mkconst(state, ins, left - right);
6477                 }
6478                 else if (RHS(ins, 0)->op == OP_ADDRCONST) {
6479                         struct triple *sdecl;
6480                         ulong_t left, right;
6481                         sdecl = MISC(RHS(ins, 0), 0);
6482                         left  = RHS(ins, 0)->u.cval;
6483                         right = RHS(ins, 1)->u.cval;
6484                         mkaddr_const(state, ins, sdecl, left - right);
6485                 }
6486                 else {
6487                         internal_warning(state, ins, "Optimize me!");
6488                 }
6489         }
6490 }
6491
6492 static void simplify_sl(struct compile_state *state, struct triple *ins)
6493 {
6494         if (is_const(RHS(ins, 1))) {
6495                 ulong_t right;
6496                 right = read_const(state, ins, RHS(ins, 1));
6497                 if (right >= (size_of(state, ins->type)*8)) {
6498                         warning(state, ins, "left shift count >= width of type");
6499                 }
6500         }
6501         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6502                 ulong_t left, right;
6503                 left  = read_const(state, ins, RHS(ins, 0));
6504                 right = read_const(state, ins, RHS(ins, 1));
6505                 mkconst(state, ins,  left << right);
6506         }
6507 }
6508
6509 static void simplify_usr(struct compile_state *state, struct triple *ins)
6510 {
6511         if (is_const(RHS(ins, 1))) {
6512                 ulong_t right;
6513                 right = read_const(state, ins, RHS(ins, 1));
6514                 if (right >= (size_of(state, ins->type)*8)) {
6515                         warning(state, ins, "right shift count >= width of type");
6516                 }
6517         }
6518         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6519                 ulong_t left, right;
6520                 left  = read_const(state, ins, RHS(ins, 0));
6521                 right = read_const(state, ins, RHS(ins, 1));
6522                 mkconst(state, ins, left >> right);
6523         }
6524 }
6525
6526 static void simplify_ssr(struct compile_state *state, struct triple *ins)
6527 {
6528         if (is_const(RHS(ins, 1))) {
6529                 ulong_t right;
6530                 right = read_const(state, ins, RHS(ins, 1));
6531                 if (right >= (size_of(state, ins->type)*8)) {
6532                         warning(state, ins, "right shift count >= width of type");
6533                 }
6534         }
6535         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6536                 long_t left, right;
6537                 left  = read_sconst(state, ins, RHS(ins, 0));
6538                 right = read_sconst(state, ins, RHS(ins, 1));
6539                 mkconst(state, ins, left >> right);
6540         }
6541 }
6542
6543 static void simplify_and(struct compile_state *state, struct triple *ins)
6544 {
6545         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6546                 ulong_t left, right;
6547                 left  = read_const(state, ins, RHS(ins, 0));
6548                 right = read_const(state, ins, RHS(ins, 1));
6549                 mkconst(state, ins, left & right);
6550         }
6551 }
6552
6553 static void simplify_or(struct compile_state *state, struct triple *ins)
6554 {
6555         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6556                 ulong_t left, right;
6557                 left  = read_const(state, ins, RHS(ins, 0));
6558                 right = read_const(state, ins, RHS(ins, 1));
6559                 mkconst(state, ins, left | right);
6560         }
6561 }
6562
6563 static void simplify_xor(struct compile_state *state, struct triple *ins)
6564 {
6565         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6566                 ulong_t left, right;
6567                 left  = read_const(state, ins, RHS(ins, 0));
6568                 right = read_const(state, ins, RHS(ins, 1));
6569                 mkconst(state, ins, left ^ right);
6570         }
6571 }
6572
6573 static void simplify_pos(struct compile_state *state, struct triple *ins)
6574 {
6575         if (is_const(RHS(ins, 0))) {
6576                 mkconst(state, ins, RHS(ins, 0)->u.cval);
6577         }
6578         else {
6579                 mkcopy(state, ins, RHS(ins, 0));
6580         }
6581 }
6582
6583 static void simplify_neg(struct compile_state *state, struct triple *ins)
6584 {
6585         if (is_const(RHS(ins, 0))) {
6586                 ulong_t left;
6587                 left = read_const(state, ins, RHS(ins, 0));
6588                 mkconst(state, ins, -left);
6589         }
6590         else if (RHS(ins, 0)->op == OP_NEG) {
6591                 mkcopy(state, ins, RHS(RHS(ins, 0), 0));
6592         }
6593 }
6594
6595 static void simplify_invert(struct compile_state *state, struct triple *ins)
6596 {
6597         if (is_const(RHS(ins, 0))) {
6598                 ulong_t left;
6599                 left = read_const(state, ins, RHS(ins, 0));
6600                 mkconst(state, ins, ~left);
6601         }
6602 }
6603
6604 static void simplify_eq(struct compile_state *state, struct triple *ins)
6605 {
6606         struct triple *left, *right;
6607         left = RHS(ins, 0);
6608         right = RHS(ins, 1);
6609
6610         if (is_const(left) && is_const(right)) {
6611                 mkconst(state, ins, const_eq(state, ins, left, right) == 1);
6612         }
6613         else if (left == right) {
6614                 mkconst(state, ins, 1);
6615         }
6616 }
6617
6618 static void simplify_noteq(struct compile_state *state, struct triple *ins)
6619 {
6620         struct triple *left, *right;
6621         left = RHS(ins, 0);
6622         right = RHS(ins, 1);
6623
6624         if (is_const(left) && is_const(right)) {
6625                 mkconst(state, ins, const_eq(state, ins, left, right) != 1);
6626         }
6627         if (left == right) {
6628                 mkconst(state, ins, 0);
6629         }
6630 }
6631
6632 static void simplify_sless(struct compile_state *state, struct triple *ins)
6633 {
6634         struct triple *left, *right;
6635         left = RHS(ins, 0);
6636         right = RHS(ins, 1);
6637
6638         if (is_const(left) && is_const(right)) {
6639                 mkconst(state, ins, const_scmp(state, ins, left, right) < 0);
6640         }
6641         else if (left == right) {
6642                 mkconst(state, ins, 0);
6643         }
6644 }
6645
6646 static void simplify_uless(struct compile_state *state, struct triple *ins)
6647 {
6648         struct triple *left, *right;
6649         left = RHS(ins, 0);
6650         right = RHS(ins, 1);
6651
6652         if (is_const(left) && is_const(right)) {
6653                 mkconst(state, ins, const_ucmp(state, ins, left, right) < 0);
6654         }
6655         else if (is_zero(right)) {
6656                 mkconst(state, ins, 0);
6657         }
6658         else if (left == right) {
6659                 mkconst(state, ins, 0);
6660         }
6661 }
6662
6663 static void simplify_smore(struct compile_state *state, struct triple *ins)
6664 {
6665         struct triple *left, *right;
6666         left = RHS(ins, 0);
6667         right = RHS(ins, 1);
6668
6669         if (is_const(left) && is_const(right)) {
6670                 mkconst(state, ins, const_scmp(state, ins, left, right) > 0);
6671         }
6672         else if (left == right) {
6673                 mkconst(state, ins, 0);
6674         }
6675 }
6676
6677 static void simplify_umore(struct compile_state *state, struct triple *ins)
6678 {
6679         struct triple *left, *right;
6680         left = RHS(ins, 0);
6681         right = RHS(ins, 1);
6682
6683         if (is_const(left) && is_const(right)) {
6684                 mkconst(state, ins, const_ucmp(state, ins, left, right) > 0);
6685         }
6686         else if (is_zero(left)) {
6687                 mkconst(state, ins, 0);
6688         }
6689         else if (left == right) {
6690                 mkconst(state, ins, 0);
6691         }
6692 }
6693
6694
6695 static void simplify_slesseq(struct compile_state *state, struct triple *ins)
6696 {
6697         struct triple *left, *right;
6698         left = RHS(ins, 0);
6699         right = RHS(ins, 1);
6700
6701         if (is_const(left) && is_const(right)) {
6702                 mkconst(state, ins, const_scmp(state, ins, left, right) <= 0);
6703         }
6704         else if (left == right) {
6705                 mkconst(state, ins, 1);
6706         }
6707 }
6708
6709 static void simplify_ulesseq(struct compile_state *state, struct triple *ins)
6710 {
6711         struct triple *left, *right;
6712         left = RHS(ins, 0);
6713         right = RHS(ins, 1);
6714
6715         if (is_const(left) && is_const(right)) {
6716                 mkconst(state, ins, const_ucmp(state, ins, left, right) <= 0);
6717         }
6718         else if (is_zero(left)) {
6719                 mkconst(state, ins, 1);
6720         }
6721         else if (left == right) {
6722                 mkconst(state, ins, 1);
6723         }
6724 }
6725
6726 static void simplify_smoreeq(struct compile_state *state, struct triple *ins)
6727 {
6728         struct triple *left, *right;
6729         left = RHS(ins, 0);
6730         right = RHS(ins, 1);
6731
6732         if (is_const(left) && is_const(right)) {
6733                 mkconst(state, ins, const_scmp(state, ins, left, right) >= 0);
6734         }
6735         else if (left == right) {
6736                 mkconst(state, ins, 1);
6737         }
6738 }
6739
6740 static void simplify_umoreeq(struct compile_state *state, struct triple *ins)
6741 {
6742         struct triple *left, *right;
6743         left = RHS(ins, 0);
6744         right = RHS(ins, 1);
6745
6746         if (is_const(left) && is_const(right)) {
6747                 mkconst(state, ins, const_ucmp(state, ins, left, right) >= 0);
6748         }
6749         else if (is_zero(right)) {
6750                 mkconst(state, ins, 1);
6751         }
6752         else if (left == right) {
6753                 mkconst(state, ins, 1);
6754         }
6755 }
6756
6757 static void simplify_lfalse(struct compile_state *state, struct triple *ins)
6758 {
6759         struct triple *rhs;
6760         rhs = RHS(ins, 0);
6761
6762         if (is_const(rhs)) {
6763                 mkconst(state, ins, !const_ltrue(state, ins, rhs));
6764         }
6765         /* Otherwise if I am the only user... */
6766         else if ((rhs->use) &&
6767                 (rhs->use->member == ins) && (rhs->use->next == 0)) {
6768                 int need_copy = 1;
6769                 /* Invert a boolean operation */
6770                 switch(rhs->op) {
6771                 case OP_LTRUE:   rhs->op = OP_LFALSE;  break;
6772                 case OP_LFALSE:  rhs->op = OP_LTRUE;   break;
6773                 case OP_EQ:      rhs->op = OP_NOTEQ;   break;
6774                 case OP_NOTEQ:   rhs->op = OP_EQ;      break;
6775                 case OP_SLESS:   rhs->op = OP_SMOREEQ; break;
6776                 case OP_ULESS:   rhs->op = OP_UMOREEQ; break;
6777                 case OP_SMORE:   rhs->op = OP_SLESSEQ; break;
6778                 case OP_UMORE:   rhs->op = OP_ULESSEQ; break;
6779                 case OP_SLESSEQ: rhs->op = OP_SMORE;   break;
6780                 case OP_ULESSEQ: rhs->op = OP_UMORE;   break;
6781                 case OP_SMOREEQ: rhs->op = OP_SLESS;   break;
6782                 case OP_UMOREEQ: rhs->op = OP_ULESS;   break;
6783                 default:
6784                         need_copy = 0;
6785                         break;
6786                 }
6787                 if (need_copy) {
6788                         mkcopy(state, ins, rhs);
6789                 }
6790         }
6791 }
6792
6793 static void simplify_ltrue (struct compile_state *state, struct triple *ins)
6794 {
6795         struct triple *rhs;
6796         rhs = RHS(ins, 0);
6797
6798         if (is_const(rhs)) {
6799                 mkconst(state, ins, const_ltrue(state, ins, rhs));
6800         }
6801         else switch(rhs->op) {
6802         case OP_LTRUE:   case OP_LFALSE:  case OP_EQ:      case OP_NOTEQ:
6803         case OP_SLESS:   case OP_ULESS:   case OP_SMORE:   case OP_UMORE:
6804         case OP_SLESSEQ: case OP_ULESSEQ: case OP_SMOREEQ: case OP_UMOREEQ:
6805                 mkcopy(state, ins, rhs);
6806         }
6807
6808 }
6809
6810 static void simplify_copy(struct compile_state *state, struct triple *ins)
6811 {
6812         if (is_const(RHS(ins, 0))) {
6813                 switch(RHS(ins, 0)->op) {
6814                 case OP_INTCONST:
6815                 {
6816                         ulong_t left;
6817                         left = read_const(state, ins, RHS(ins, 0));
6818                         mkconst(state, ins, left);
6819                         break;
6820                 }
6821                 case OP_ADDRCONST:
6822                 {
6823                         struct triple *sdecl;
6824                         ulong_t offset;
6825                         sdecl  = MISC(RHS(ins, 0), 0);
6826                         offset = RHS(ins, 0)->u.cval;
6827                         mkaddr_const(state, ins, sdecl, offset);
6828                         break;
6829                 }
6830                 default:
6831                         internal_error(state, ins, "uknown constant");
6832                         break;
6833                 }
6834         }
6835 }
6836
6837 static int phi_present(struct block *block)
6838 {
6839         struct triple *ptr;
6840         if (!block) {
6841                 return 0;
6842         }
6843         ptr = block->first;
6844         do {
6845                 if (ptr->op == OP_PHI) {
6846                         return 1;
6847                 }
6848                 ptr = ptr->next;
6849         } while(ptr != block->last);
6850         return 0;
6851 }
6852
6853 static int phi_dependency(struct block *block)
6854 {
6855         /* A block has a phi dependency if a phi function
6856          * depends on that block to exist, and makes a block
6857          * that is otherwise useless unsafe to remove.
6858          */
6859         if (block) {
6860                 struct block_set *edge;
6861                 for(edge = block->edges; edge; edge = edge->next) {
6862                         if (phi_present(edge->member)) {
6863                                 return 1;
6864                         }
6865                 }
6866         }
6867         return 0;
6868 }
6869
6870 static struct triple *branch_target(struct compile_state *state, struct triple *ins)
6871 {
6872         struct triple *targ;
6873         targ = TARG(ins, 0);
6874         /* During scc_transform temporary triples are allocated that
6875          * loop back onto themselves. If I see one don't advance the
6876          * target.
6877          */
6878         while(triple_is_structural(state, targ) && 
6879                 (targ->next != targ) && (targ->next != state->first)) {
6880                 targ = targ->next;
6881         }
6882         return targ;
6883 }
6884
6885
6886 static void simplify_branch(struct compile_state *state, struct triple *ins)
6887 {
6888         int simplified;
6889         if ((ins->op != OP_BRANCH) && (ins->op != OP_CBRANCH)) {
6890                 internal_error(state, ins, "not branch");
6891         }
6892         if (ins->use != 0) {
6893                 internal_error(state, ins, "branch use");
6894         }
6895         /* The challenge here with simplify branch is that I need to 
6896          * make modifications to the control flow graph as well
6897          * as to the branch instruction itself.  That is handled
6898          * by rebuilding the basic blocks after simplify all is called.
6899          */
6900
6901         /* If we have a branch to an unconditional branch update
6902          * our target.  But watch out for dependencies from phi
6903          * functions. 
6904          */
6905         do {
6906                 struct triple *targ;
6907                 simplified = 0;
6908                 targ = branch_target(state, ins);
6909                 if ((targ != ins) && (targ->op == OP_BRANCH) && 
6910                         !phi_dependency(targ->u.block))
6911                 {
6912                         unuse_triple(TARG(ins, 0), ins);
6913                         TARG(ins, 0) = TARG(targ, 0);
6914                         use_triple(TARG(ins, 0), ins);
6915                         simplified = 1;
6916                 }
6917         } while(simplified);
6918
6919         /* If we have a conditional branch with a constant condition
6920          * make it an unconditional branch.
6921          */
6922         if ((ins->op == OP_CBRANCH) && is_const(RHS(ins, 0))) {
6923                 struct triple *targ;
6924                 ulong_t value;
6925                 value = read_const(state, ins, RHS(ins, 0));
6926                 unuse_triple(RHS(ins, 0), ins);
6927                 targ = TARG(ins, 0);
6928                 ins->sizes = TRIPLE_SIZES(0, 0, 0, 1);
6929                 ins->op = OP_BRANCH;
6930                 if (value) {
6931                         unuse_triple(ins->next, ins);
6932                         TARG(ins, 0) = targ;
6933                 }
6934                 else {
6935                         unuse_triple(targ, ins);
6936                         TARG(ins, 0) = ins->next;
6937                 }
6938         }
6939         
6940         /* If we have a branch to the next instruction
6941          * make it a noop.
6942          */
6943         if (TARG(ins, 0) == ins->next) {
6944                 unuse_triple(ins->next, ins);
6945                 if (ins->op == OP_CBRANCH) {
6946                         unuse_triple(RHS(ins, 0), ins);
6947                         unuse_triple(ins->next, ins);
6948                 }
6949                 ins->sizes = TRIPLE_SIZES(0, 0, 0, 0);
6950                 ins->op = OP_NOOP;
6951                 if (ins->use) {
6952                         internal_error(state, ins, "noop use != 0");
6953                 }
6954         }
6955 }
6956
6957 static void simplify_label(struct compile_state *state, struct triple *ins)
6958 {
6959         /* Ignore volatile labels */
6960         if (!triple_is_pure(state, ins, ins->id)) {
6961                 return;
6962         }
6963         if (ins->use == 0) {
6964                 ins->op = OP_NOOP;
6965         }
6966         else if (ins->prev->op == OP_LABEL) {
6967                 /* In general it is not safe to merge one label that
6968                  * imediately follows another.  The problem is that the empty
6969                  * looking block may have phi functions that depend on it.
6970                  */
6971                 if (!phi_dependency(ins->prev->u.block)) {
6972                         struct triple_set *user, *next;
6973                         ins->op = OP_NOOP;
6974                         for(user = ins->use; user; user = next) {
6975                                 struct triple *use, **expr;
6976                                 next = user->next;
6977                                 use = user->member;
6978                                 expr = triple_targ(state, use, 0);
6979                                 for(;expr; expr = triple_targ(state, use, expr)) {
6980                                         if (*expr == ins) {
6981                                                 *expr = ins->prev;
6982                                                 unuse_triple(ins, use);
6983                                                 use_triple(ins->prev, use);
6984                                         }
6985                                         
6986                                 }
6987                         }
6988                         if (ins->use) {
6989                                 internal_error(state, ins, "noop use != 0");
6990                         }
6991                 }
6992         }
6993 }
6994
6995 static void simplify_phi(struct compile_state *state, struct triple *ins)
6996 {
6997         struct triple **slot;
6998         struct triple *value;
6999         int zrhs, i;
7000         ulong_t cvalue;
7001         slot = &RHS(ins, 0);
7002         zrhs = TRIPLE_RHS(ins->sizes);
7003         if (zrhs == 0) {
7004                 return;
7005         }
7006         /* See if all of the rhs members of a phi have the same value */
7007         if (slot[0] && is_simple_const(slot[0])) {
7008                 cvalue = read_const(state, ins, slot[0]);
7009                 for(i = 1; i < zrhs; i++) {
7010                         if (    !slot[i] ||
7011                                 !is_simple_const(slot[i]) ||
7012                                 (cvalue != read_const(state, ins, slot[i]))) {
7013                                 break;
7014                         }
7015                 }
7016                 if (i == zrhs) {
7017                         mkconst(state, ins, cvalue);
7018                         return;
7019                 }
7020         }
7021         
7022         /* See if all of rhs members of a phi are the same */
7023         value = slot[0];
7024         for(i = 1; i < zrhs; i++) {
7025                 if (slot[i] != value) {
7026                         break;
7027                 }
7028         }
7029         if (i == zrhs) {
7030                 /* If the phi has a single value just copy it */
7031                 mkcopy(state, ins, value);
7032                 return;
7033         }
7034 }
7035
7036
7037 static void simplify_bsf(struct compile_state *state, struct triple *ins)
7038 {
7039         if (is_const(RHS(ins, 0))) {
7040                 ulong_t left;
7041                 left = read_const(state, ins, RHS(ins, 0));
7042                 mkconst(state, ins, bsf(left));
7043         }
7044 }
7045
7046 static void simplify_bsr(struct compile_state *state, struct triple *ins)
7047 {
7048         if (is_const(RHS(ins, 0))) {
7049                 ulong_t left;
7050                 left = read_const(state, ins, RHS(ins, 0));
7051                 mkconst(state, ins, bsr(left));
7052         }
7053 }
7054
7055
7056 typedef void (*simplify_t)(struct compile_state *state, struct triple *ins);
7057 static const struct simplify_table {
7058         simplify_t func;
7059         unsigned long flag;
7060 } table_simplify[] = {
7061 #define simplify_sdivt    simplify_noop
7062 #define simplify_udivt    simplify_noop
7063 #define simplify_piece    simplify_noop
7064
7065 [OP_SDIVT      ] = { simplify_sdivt,    COMPILER_SIMPLIFY_ARITH },
7066 [OP_UDIVT      ] = { simplify_udivt,    COMPILER_SIMPLIFY_ARITH },
7067 [OP_SMUL       ] = { simplify_smul,     COMPILER_SIMPLIFY_ARITH },
7068 [OP_UMUL       ] = { simplify_umul,     COMPILER_SIMPLIFY_ARITH },
7069 [OP_SDIV       ] = { simplify_sdiv,     COMPILER_SIMPLIFY_ARITH },
7070 [OP_UDIV       ] = { simplify_udiv,     COMPILER_SIMPLIFY_ARITH },
7071 [OP_SMOD       ] = { simplify_smod,     COMPILER_SIMPLIFY_ARITH },
7072 [OP_UMOD       ] = { simplify_umod,     COMPILER_SIMPLIFY_ARITH },
7073 [OP_ADD        ] = { simplify_add,      COMPILER_SIMPLIFY_ARITH },
7074 [OP_SUB        ] = { simplify_sub,      COMPILER_SIMPLIFY_ARITH },
7075 [OP_SL         ] = { simplify_sl,       COMPILER_SIMPLIFY_SHIFT },
7076 [OP_USR        ] = { simplify_usr,      COMPILER_SIMPLIFY_SHIFT },
7077 [OP_SSR        ] = { simplify_ssr,      COMPILER_SIMPLIFY_SHIFT },
7078 [OP_AND        ] = { simplify_and,      COMPILER_SIMPLIFY_BITWISE },
7079 [OP_XOR        ] = { simplify_xor,      COMPILER_SIMPLIFY_BITWISE },
7080 [OP_OR         ] = { simplify_or,       COMPILER_SIMPLIFY_BITWISE },
7081 [OP_POS        ] = { simplify_pos,      COMPILER_SIMPLIFY_ARITH },
7082 [OP_NEG        ] = { simplify_neg,      COMPILER_SIMPLIFY_ARITH },
7083 [OP_INVERT     ] = { simplify_invert,   COMPILER_SIMPLIFY_BITWISE },
7084
7085 [OP_EQ         ] = { simplify_eq,       COMPILER_SIMPLIFY_LOGICAL },
7086 [OP_NOTEQ      ] = { simplify_noteq,    COMPILER_SIMPLIFY_LOGICAL },
7087 [OP_SLESS      ] = { simplify_sless,    COMPILER_SIMPLIFY_LOGICAL },
7088 [OP_ULESS      ] = { simplify_uless,    COMPILER_SIMPLIFY_LOGICAL },
7089 [OP_SMORE      ] = { simplify_smore,    COMPILER_SIMPLIFY_LOGICAL },
7090 [OP_UMORE      ] = { simplify_umore,    COMPILER_SIMPLIFY_LOGICAL },
7091 [OP_SLESSEQ    ] = { simplify_slesseq,  COMPILER_SIMPLIFY_LOGICAL },
7092 [OP_ULESSEQ    ] = { simplify_ulesseq,  COMPILER_SIMPLIFY_LOGICAL },
7093 [OP_SMOREEQ    ] = { simplify_smoreeq,  COMPILER_SIMPLIFY_LOGICAL },
7094 [OP_UMOREEQ    ] = { simplify_umoreeq,  COMPILER_SIMPLIFY_LOGICAL },
7095 [OP_LFALSE     ] = { simplify_lfalse,   COMPILER_SIMPLIFY_LOGICAL },
7096 [OP_LTRUE      ] = { simplify_ltrue,    COMPILER_SIMPLIFY_LOGICAL },
7097
7098 [OP_LOAD       ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
7099 [OP_STORE      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
7100
7101 [OP_NOOP       ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
7102
7103 [OP_INTCONST   ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
7104 [OP_BLOBCONST  ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
7105 [OP_ADDRCONST  ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
7106
7107 [OP_WRITE      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
7108 [OP_READ       ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
7109 [OP_COPY       ] = { simplify_copy,     COMPILER_SIMPLIFY_COPY },
7110 [OP_PIECE      ] = { simplify_piece,    COMPILER_SIMPLIFY_OP },
7111 [OP_ASM        ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
7112
7113 [OP_DOT        ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
7114 [OP_VAL_VEC    ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
7115
7116 [OP_LIST       ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
7117 [OP_BRANCH     ] = { simplify_branch,   COMPILER_SIMPLIFY_BRANCH },
7118 [OP_CBRANCH    ] = { simplify_branch,   COMPILER_SIMPLIFY_BRANCH },
7119 [OP_CALL       ] = { simplify_noop,     COMPILER_SIMPLIFY_BRANCH },
7120 [OP_RET        ] = { simplify_noop,     COMPILER_SIMPLIFY_BRANCH },
7121 [OP_LABEL      ] = { simplify_label,    COMPILER_SIMPLIFY_LABEL },
7122 [OP_ADECL      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
7123 [OP_SDECL      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
7124 [OP_PHI        ] = { simplify_phi,      COMPILER_SIMPLIFY_PHI },
7125
7126 [OP_INB        ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
7127 [OP_INW        ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
7128 [OP_INL        ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
7129 [OP_OUTB       ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
7130 [OP_OUTW       ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
7131 [OP_OUTL       ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
7132 [OP_BSF        ] = { simplify_bsf,      COMPILER_SIMPLIFY_OP },
7133 [OP_BSR        ] = { simplify_bsr,      COMPILER_SIMPLIFY_OP },
7134 [OP_RDMSR      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
7135 [OP_WRMSR      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },               
7136 [OP_HLT        ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
7137 };
7138
7139 static void simplify(struct compile_state *state, struct triple *ins)
7140 {
7141         int op;
7142         simplify_t do_simplify;
7143         do {
7144                 op = ins->op;
7145                 do_simplify = 0;
7146                 if ((op < 0) || (op > sizeof(table_simplify)/sizeof(table_simplify[0]))) {
7147                         do_simplify = 0;
7148                 }
7149                 else if (state->compiler->flags & table_simplify[op].flag) {
7150                         do_simplify = table_simplify[op].func;
7151                 }
7152                 else {
7153                         do_simplify = simplify_noop;
7154                 }
7155         
7156                 if (!do_simplify) {
7157                         internal_error(state, ins, "cannot simplify op: %d %s\n",
7158                                 op, tops(op));
7159                         return;
7160                 }
7161                 do_simplify(state, ins);
7162         } while(ins->op != op);
7163 }
7164
7165 static void rebuild_ssa_form(struct compile_state *state);
7166
7167 static void simplify_all(struct compile_state *state)
7168 {
7169         struct triple *ins, *first;
7170         if (!(state->compiler->flags & COMPILER_SIMPLIFY)) {
7171                 return;
7172         }
7173         first = state->first;
7174         ins = first->prev;
7175         do {
7176                 simplify(state, ins);
7177                 ins = ins->prev;
7178         } while(ins != first->prev);
7179         ins = first;
7180         do {
7181                 simplify(state, ins);
7182                 ins = ins->next;
7183         }while(ins != first);
7184         rebuild_ssa_form(state);
7185
7186         print_blocks(state, __func__, stdout);
7187 }
7188
7189 /*
7190  * Builtins....
7191  * ============================
7192  */
7193
7194 static void register_builtin_function(struct compile_state *state,
7195         const char *name, int op, struct type *rtype, ...)
7196 {
7197         struct type *ftype, *atype, *param, **next;
7198         struct triple *def, *arg, *result, *work, *last, *first, *retvar, *ret;
7199         struct hash_entry *ident;
7200         struct file_state file;
7201         int parameters;
7202         int name_len;
7203         va_list args;
7204         int i;
7205
7206         /* Dummy file state to get debug handling right */
7207         memset(&file, 0, sizeof(file));
7208         file.basename = "<built-in>";
7209         file.line = 1;
7210         file.report_line = 1;
7211         file.report_name = file.basename;
7212         file.prev = state->file;
7213         state->file = &file;
7214         state->function = name;
7215
7216         /* Find the Parameter count */
7217         valid_op(state, op);
7218         parameters = table_ops[op].rhs;
7219         if (parameters < 0 ) {
7220                 internal_error(state, 0, "Invalid builtin parameter count");
7221         }
7222
7223         /* Find the function type */
7224         ftype = new_type(TYPE_FUNCTION | STOR_INLINE | STOR_STATIC, rtype, 0);
7225         next = &ftype->right;
7226         va_start(args, rtype);
7227         for(i = 0; i < parameters; i++) {
7228                 atype = va_arg(args, struct type *);
7229                 if (!*next) {
7230                         *next = atype;
7231                 } else {
7232                         *next = new_type(TYPE_PRODUCT, *next, atype);
7233                         next = &((*next)->right);
7234                 }
7235         }
7236         if (!*next) {
7237                 *next = &void_type;
7238         }
7239         va_end(args);
7240
7241         /* Generate the needed triples */
7242         def = triple(state, OP_LIST, ftype, 0, 0);
7243         first = label(state);
7244         RHS(def, 0) = first;
7245         retvar = variable(state, &void_ptr_type);
7246         retvar = flatten(state, first, retvar);
7247         ret = triple(state, OP_RET, &void_type, read_expr(state, retvar), 0);
7248
7249         /* Now string them together */
7250         param = ftype->right;
7251         for(i = 0; i < parameters; i++) {
7252                 if ((param->type & TYPE_MASK) == TYPE_PRODUCT) {
7253                         atype = param->left;
7254                 } else {
7255                         atype = param;
7256                 }
7257                 arg = flatten(state, first, variable(state, atype));
7258                 param = param->right;
7259         }
7260         result = 0;
7261         if ((rtype->type & TYPE_MASK) != TYPE_VOID) {
7262                 result = flatten(state, first, variable(state, rtype));
7263         }
7264         MISC(def, 0) = result;
7265         work = new_triple(state, op, rtype, -1, parameters);
7266         for(i = 0, arg = first->next->next; i < parameters; i++, arg = arg->next) {
7267                 RHS(work, i) = read_expr(state, arg);
7268         }
7269         if (result && ((rtype->type & TYPE_MASK) == TYPE_STRUCT)) {
7270                 struct triple *val;
7271                 /* Populate the LHS with the target registers */
7272                 work = flatten(state, first, work);
7273                 work->type = &void_type;
7274                 param = rtype->left;
7275                 if (rtype->elements != TRIPLE_LHS(work->sizes)) {
7276                         internal_error(state, 0, "Invalid result type");
7277                 }
7278                 val = new_triple(state, OP_VAL_VEC, rtype, -1, -1);
7279                 for(i = 0; i < rtype->elements; i++) {
7280                         struct triple *piece;
7281                         atype = param;
7282                         if ((param->type & TYPE_MASK) == TYPE_PRODUCT) {
7283                                 atype = param->left;
7284                         }
7285                         if (!TYPE_ARITHMETIC(atype->type) &&
7286                                 !TYPE_PTR(atype->type)) {
7287                                 internal_error(state, 0, "Invalid lhs type");
7288                         }
7289                         piece = triple(state, OP_PIECE, atype, work, 0);
7290                         piece->u.cval = i;
7291                         LHS(work, i) = piece;
7292                         RHS(val, i) = piece;
7293                 }
7294                 work = val;
7295         }
7296         if (result) {
7297                 work = write_expr(state, result, work);
7298         }
7299         work = flatten(state, first, work);
7300         last = flatten(state, first, label(state));
7301         ret  = flatten(state, first, ret);
7302         name_len = strlen(name);
7303         ident = lookup(state, name, name_len);
7304         ftype->type_ident = ident;
7305         symbol(state, ident, &ident->sym_ident, def, ftype);
7306         
7307         state->file = file.prev;
7308         state->function = 0;
7309         
7310         if (!state->functions) {
7311                 state->functions = def;
7312         } else {
7313                 insert_triple(state, state->functions, def);
7314         }
7315         if (state->compiler->debug & DEBUG_INLINE) {
7316                 fprintf(stdout, "\n");
7317                 loc(stdout, state, 0);
7318                 fprintf(stdout, "\n__________ %s _________\n", __FUNCTION__);
7319                 display_func(stdout, def);
7320                 fprintf(stdout, "__________ %s _________ done\n\n", __FUNCTION__);
7321         }
7322 }
7323
7324 static struct type *partial_struct(struct compile_state *state,
7325         const char *field_name, struct type *type, struct type *rest)
7326 {
7327         struct hash_entry *field_ident;
7328         struct type *result;
7329         int field_name_len;
7330
7331         field_name_len = strlen(field_name);
7332         field_ident = lookup(state, field_name, field_name_len);
7333
7334         result = clone_type(0, type);
7335         result->field_ident = field_ident;
7336
7337         if (rest) {
7338                 result = new_type(TYPE_PRODUCT, result, rest);
7339         }
7340         return result;
7341 }
7342
7343 static struct type *register_builtin_type(struct compile_state *state,
7344         const char *name, struct type *type)
7345 {
7346         struct hash_entry *ident;
7347         int name_len;
7348
7349         name_len = strlen(name);
7350         ident = lookup(state, name, name_len);
7351         
7352         if ((type->type & TYPE_MASK) == TYPE_PRODUCT) {
7353                 ulong_t elements = 0;
7354                 struct type *field;
7355                 type = new_type(TYPE_STRUCT, type, 0);
7356                 field = type->left;
7357                 while((field->type & TYPE_MASK) == TYPE_PRODUCT) {
7358                         elements++;
7359                         field = field->right;
7360                 }
7361                 elements++;
7362                 symbol(state, ident, &ident->sym_tag, 0, type);
7363                 type->type_ident = ident;
7364                 type->elements = elements;
7365         }
7366         symbol(state, ident, &ident->sym_ident, 0, type);
7367         ident->tok = TOK_TYPE_NAME;
7368         return type;
7369 }
7370
7371
7372 static void register_builtins(struct compile_state *state)
7373 {
7374         struct type *div_type, *ldiv_type;
7375         struct type *udiv_type, *uldiv_type;
7376         struct type *msr_type;
7377
7378         div_type = register_builtin_type(state, "__builtin_div_t",
7379                 partial_struct(state, "quot", &int_type,
7380                 partial_struct(state, "rem",  &int_type, 0)));
7381         ldiv_type = register_builtin_type(state, "__builtin_ldiv_t",
7382                 partial_struct(state, "quot", &long_type,
7383                 partial_struct(state, "rem",  &long_type, 0)));
7384         udiv_type = register_builtin_type(state, "__builtin_udiv_t",
7385                 partial_struct(state, "quot", &uint_type,
7386                 partial_struct(state, "rem",  &uint_type, 0)));
7387         uldiv_type = register_builtin_type(state, "__builtin_uldiv_t",
7388                 partial_struct(state, "quot", &ulong_type,
7389                 partial_struct(state, "rem",  &ulong_type, 0)));
7390
7391         register_builtin_function(state, "__builtin_div",   OP_SDIVT, div_type,
7392                 &int_type, &int_type);
7393         register_builtin_function(state, "__builtin_ldiv",  OP_SDIVT, ldiv_type,
7394                 &long_type, &long_type);
7395         register_builtin_function(state, "__builtin_udiv",  OP_UDIVT, udiv_type,
7396                 &uint_type, &uint_type);
7397         register_builtin_function(state, "__builtin_uldiv", OP_UDIVT, uldiv_type,
7398                 &ulong_type, &ulong_type);
7399
7400         register_builtin_function(state, "__builtin_inb", OP_INB, &uchar_type, 
7401                 &ushort_type);
7402         register_builtin_function(state, "__builtin_inw", OP_INW, &ushort_type,
7403                 &ushort_type);
7404         register_builtin_function(state, "__builtin_inl", OP_INL, &uint_type,   
7405                 &ushort_type);
7406
7407         register_builtin_function(state, "__builtin_outb", OP_OUTB, &void_type, 
7408                 &uchar_type, &ushort_type);
7409         register_builtin_function(state, "__builtin_outw", OP_OUTW, &void_type, 
7410                 &ushort_type, &ushort_type);
7411         register_builtin_function(state, "__builtin_outl", OP_OUTL, &void_type, 
7412                 &uint_type, &ushort_type);
7413         
7414         register_builtin_function(state, "__builtin_bsf", OP_BSF, &int_type, 
7415                 &int_type);
7416         register_builtin_function(state, "__builtin_bsr", OP_BSR, &int_type, 
7417                 &int_type);
7418
7419         msr_type = register_builtin_type(state, "__builtin_msr_t",
7420                 partial_struct(state, "lo", &ulong_type,
7421                 partial_struct(state, "hi", &ulong_type, 0)));
7422
7423         register_builtin_function(state, "__builtin_rdmsr", OP_RDMSR, msr_type,
7424                 &ulong_type);
7425         register_builtin_function(state, "__builtin_wrmsr", OP_WRMSR, &void_type,
7426                 &ulong_type, &ulong_type, &ulong_type);
7427         
7428         register_builtin_function(state, "__builtin_hlt", OP_HLT, &void_type, 
7429                 &void_type);
7430 }
7431
7432 static struct type *declarator(
7433         struct compile_state *state, struct type *type, 
7434         struct hash_entry **ident, int need_ident);
7435 static void decl(struct compile_state *state, struct triple *first);
7436 static struct type *specifier_qualifier_list(struct compile_state *state);
7437 static int isdecl_specifier(int tok);
7438 static struct type *decl_specifiers(struct compile_state *state);
7439 static int istype(int tok);
7440 static struct triple *expr(struct compile_state *state);
7441 static struct triple *assignment_expr(struct compile_state *state);
7442 static struct type *type_name(struct compile_state *state);
7443 static void statement(struct compile_state *state, struct triple *fist);
7444
7445 static struct triple *call_expr(
7446         struct compile_state *state, struct triple *func)
7447 {
7448         struct triple *def;
7449         struct type *param, *type;
7450         ulong_t pvals, index;
7451
7452         if ((func->type->type & TYPE_MASK) != TYPE_FUNCTION) {
7453                 error(state, 0, "Called object is not a function");
7454         }
7455         if (func->op != OP_LIST) {
7456                 internal_error(state, 0, "improper function");
7457         }
7458         eat(state, TOK_LPAREN);
7459         /* Find the return type without any specifiers */
7460         type = clone_type(0, func->type->left);
7461         /* Count the number of rhs entries for OP_FCALL */
7462         param = func->type->right;
7463         pvals = 0;
7464         while((param->type & TYPE_MASK) == TYPE_PRODUCT) {
7465                 pvals++;
7466                 param = param->right;
7467         }
7468         if ((param->type & TYPE_MASK) != TYPE_VOID) {
7469                 pvals++;
7470         }
7471         def = new_triple(state, OP_FCALL, type, -1, pvals);
7472         MISC(def, 0) = func;
7473
7474         param = func->type->right;
7475         for(index = 0; index < pvals; index++) {
7476                 struct triple *val;
7477                 struct type *arg_type;
7478                 val = read_expr(state, assignment_expr(state));
7479                 arg_type = param;
7480                 if ((param->type & TYPE_MASK) == TYPE_PRODUCT) {
7481                         arg_type = param->left;
7482                 }
7483                 write_compatible(state, arg_type, val->type);
7484                 RHS(def, index) = val;
7485                 if (index != (pvals - 1)) {
7486                         eat(state, TOK_COMMA);
7487                         param = param->right;
7488                 }
7489         }
7490         eat(state, TOK_RPAREN);
7491         return def;
7492 }
7493
7494
7495 static struct triple *character_constant(struct compile_state *state)
7496 {
7497         struct triple *def;
7498         struct token *tk;
7499         const signed char *str, *end;
7500         int c;
7501         int str_len;
7502         eat(state, TOK_LIT_CHAR);
7503         tk = &state->token[0];
7504         str = tk->val.str + 1;
7505         str_len = tk->str_len - 2;
7506         if (str_len <= 0) {
7507                 error(state, 0, "empty character constant");
7508         }
7509         end = str + str_len;
7510         c = char_value(state, &str, end);
7511         if (str != end) {
7512                 error(state, 0, "multibyte character constant not supported");
7513         }
7514         def = int_const(state, &char_type, (ulong_t)((long_t)c));
7515         return def;
7516 }
7517
7518 static struct triple *string_constant(struct compile_state *state)
7519 {
7520         struct triple *def;
7521         struct token *tk;
7522         struct type *type;
7523         const signed char *str, *end;
7524         signed char *buf, *ptr;
7525         int str_len;
7526
7527         buf = 0;
7528         type = new_type(TYPE_ARRAY, &char_type, 0);
7529         type->elements = 0;
7530         /* The while loop handles string concatenation */
7531         do {
7532                 eat(state, TOK_LIT_STRING);
7533                 tk = &state->token[0];
7534                 str = tk->val.str + 1;
7535                 str_len = tk->str_len - 2;
7536                 if (str_len < 0) {
7537                         error(state, 0, "negative string constant length");
7538                 }
7539                 end = str + str_len;
7540                 ptr = buf;
7541                 buf = xmalloc(type->elements + str_len + 1, "string_constant");
7542                 memcpy(buf, ptr, type->elements);
7543                 ptr = buf + type->elements;
7544                 do {
7545                         *ptr++ = char_value(state, &str, end);
7546                 } while(str < end);
7547                 type->elements = ptr - buf;
7548         } while(peek(state) == TOK_LIT_STRING);
7549         *ptr = '\0';
7550         type->elements += 1;
7551         def = triple(state, OP_BLOBCONST, type, 0, 0);
7552         def->u.blob = buf;
7553         return def;
7554 }
7555
7556
7557 static struct triple *integer_constant(struct compile_state *state)
7558 {
7559         struct triple *def;
7560         unsigned long val;
7561         struct token *tk;
7562         char *end;
7563         int u, l, decimal;
7564         struct type *type;
7565
7566         eat(state, TOK_LIT_INT);
7567         tk = &state->token[0];
7568         errno = 0;
7569         decimal = (tk->val.str[0] != '0');
7570         val = strtoul(tk->val.str, &end, 0);
7571         if ((val > ULONG_T_MAX) || ((val == ULONG_MAX) && (errno == ERANGE))) {
7572                 error(state, 0, "Integer constant to large");
7573         }
7574         u = l = 0;
7575         if ((*end == 'u') || (*end == 'U')) {
7576                 u = 1;
7577                         end++;
7578         }
7579         if ((*end == 'l') || (*end == 'L')) {
7580                 l = 1;
7581                 end++;
7582         }
7583         if ((*end == 'u') || (*end == 'U')) {
7584                 u = 1;
7585                 end++;
7586         }
7587         if (*end) {
7588                 error(state, 0, "Junk at end of integer constant");
7589         }
7590         if (u && l)  {
7591                 type = &ulong_type;
7592         }
7593         else if (l) {
7594                 type = &long_type;
7595                 if (!decimal && (val > LONG_T_MAX)) {
7596                         type = &ulong_type;
7597                 }
7598         }
7599         else if (u) {
7600                 type = &uint_type;
7601                 if (val > UINT_T_MAX) {
7602                         type = &ulong_type;
7603                 }
7604         }
7605         else {
7606                 type = &int_type;
7607                 if (!decimal && (val > INT_T_MAX) && (val <= UINT_T_MAX)) {
7608                         type = &uint_type;
7609                 }
7610                 else if (!decimal && (val > LONG_T_MAX)) {
7611                         type = &ulong_type;
7612                 }
7613                 else if (val > INT_T_MAX) {
7614                         type = &long_type;
7615                 }
7616         }
7617         def = int_const(state, type, val);
7618         return def;
7619 }
7620
7621 static struct triple *primary_expr(struct compile_state *state)
7622 {
7623         struct triple *def;
7624         int tok;
7625         tok = peek(state);
7626         switch(tok) {
7627         case TOK_IDENT:
7628         {
7629                 struct hash_entry *ident;
7630                 /* Here ident is either:
7631                  * a varable name
7632                  * a function name
7633                  */
7634                 eat(state, TOK_IDENT);
7635                 ident = state->token[0].ident;
7636                 if (!ident->sym_ident) {
7637                         error(state, 0, "%s undeclared", ident->name);
7638                 }
7639                 def = ident->sym_ident->def;
7640                 break;
7641         }
7642         case TOK_ENUM_CONST:
7643         {
7644                 struct hash_entry *ident;
7645                 /* Here ident is an enumeration constant */
7646                 eat(state, TOK_ENUM_CONST);
7647                 ident = state->token[0].ident;
7648                 if (!ident->sym_ident) {
7649                         error(state, 0, "%s undeclared", ident->name);
7650                 }
7651                 def = ident->sym_ident->def;
7652                 break;
7653         }
7654         case TOK_LPAREN:
7655                 eat(state, TOK_LPAREN);
7656                 def = expr(state);
7657                 eat(state, TOK_RPAREN);
7658                 break;
7659         case TOK_LIT_INT:
7660                 def = integer_constant(state);
7661                 break;
7662         case TOK_LIT_FLOAT:
7663                 eat(state, TOK_LIT_FLOAT);
7664                 error(state, 0, "Floating point constants not supported");
7665                 def = 0;
7666                 FINISHME();
7667                 break;
7668         case TOK_LIT_CHAR:
7669                 def = character_constant(state);
7670                 break;
7671         case TOK_LIT_STRING:
7672                 def = string_constant(state);
7673                 break;
7674         default:
7675                 def = 0;
7676                 error(state, 0, "Unexpected token: %s\n", tokens[tok]);
7677         }
7678         return def;
7679 }
7680
7681 static struct triple *postfix_expr(struct compile_state *state)
7682 {
7683         struct triple *def;
7684         int postfix;
7685         def = primary_expr(state);
7686         do {
7687                 struct triple *left;
7688                 int tok;
7689                 postfix = 1;
7690                 left = def;
7691                 switch((tok = peek(state))) {
7692                 case TOK_LBRACKET:
7693                         eat(state, TOK_LBRACKET);
7694                         def = mk_subscript_expr(state, left, expr(state));
7695                         eat(state, TOK_RBRACKET);
7696                         break;
7697                 case TOK_LPAREN:
7698                         def = call_expr(state, def);
7699                         break;
7700                 case TOK_DOT:
7701                 {
7702                         struct hash_entry *field;
7703                         eat(state, TOK_DOT);
7704                         eat(state, TOK_IDENT);
7705                         field = state->token[0].ident;
7706                         def = deref_field(state, def, field);
7707                         break;
7708                 }
7709                 case TOK_ARROW:
7710                 {
7711                         struct hash_entry *field;
7712                         eat(state, TOK_ARROW);
7713                         eat(state, TOK_IDENT);
7714                         field = state->token[0].ident;
7715                         def = mk_deref_expr(state, read_expr(state, def));
7716                         def = deref_field(state, def, field);
7717                         break;
7718                 }
7719                 case TOK_PLUSPLUS:
7720                         eat(state, TOK_PLUSPLUS);
7721                         def = mk_post_inc_expr(state, left);
7722                         break;
7723                 case TOK_MINUSMINUS:
7724                         eat(state, TOK_MINUSMINUS);
7725                         def = mk_post_dec_expr(state, left);
7726                         break;
7727                 default:
7728                         postfix = 0;
7729                         break;
7730                 }
7731         } while(postfix);
7732         return def;
7733 }
7734
7735 static struct triple *cast_expr(struct compile_state *state);
7736
7737 static struct triple *unary_expr(struct compile_state *state)
7738 {
7739         struct triple *def, *right;
7740         int tok;
7741         switch((tok = peek(state))) {
7742         case TOK_PLUSPLUS:
7743                 eat(state, TOK_PLUSPLUS);
7744                 def = mk_pre_inc_expr(state, unary_expr(state));
7745                 break;
7746         case TOK_MINUSMINUS:
7747                 eat(state, TOK_MINUSMINUS);
7748                 def = mk_pre_dec_expr(state, unary_expr(state));
7749                 break;
7750         case TOK_AND:
7751                 eat(state, TOK_AND);
7752                 def = mk_addr_expr(state, cast_expr(state), 0);
7753                 break;
7754         case TOK_STAR:
7755                 eat(state, TOK_STAR);
7756                 def = mk_deref_expr(state, read_expr(state, cast_expr(state)));
7757                 break;
7758         case TOK_PLUS:
7759                 eat(state, TOK_PLUS);
7760                 right = read_expr(state, cast_expr(state));
7761                 arithmetic(state, right);
7762                 def = integral_promotion(state, right);
7763                 break;
7764         case TOK_MINUS:
7765                 eat(state, TOK_MINUS);
7766                 right = read_expr(state, cast_expr(state));
7767                 arithmetic(state, right);
7768                 def = integral_promotion(state, right);
7769                 def = triple(state, OP_NEG, def->type, def, 0);
7770                 break;
7771         case TOK_TILDE:
7772                 eat(state, TOK_TILDE);
7773                 right = read_expr(state, cast_expr(state));
7774                 integral(state, right);
7775                 def = integral_promotion(state, right);
7776                 def = triple(state, OP_INVERT, def->type, def, 0);
7777                 break;
7778         case TOK_BANG:
7779                 eat(state, TOK_BANG);
7780                 right = read_expr(state, cast_expr(state));
7781                 bool(state, right);
7782                 def = lfalse_expr(state, right);
7783                 break;
7784         case TOK_SIZEOF:
7785         {
7786                 struct type *type;
7787                 int tok1, tok2;
7788                 eat(state, TOK_SIZEOF);
7789                 tok1 = peek(state);
7790                 tok2 = peek2(state);
7791                 if ((tok1 == TOK_LPAREN) && istype(tok2)) {
7792                         eat(state, TOK_LPAREN);
7793                         type = type_name(state);
7794                         eat(state, TOK_RPAREN);
7795                 }
7796                 else {
7797                         struct triple *expr;
7798                         expr = unary_expr(state);
7799                         type = expr->type;
7800                         release_expr(state, expr);
7801                 }
7802                 def = int_const(state, &ulong_type, size_of(state, type));
7803                 break;
7804         }
7805         case TOK_ALIGNOF:
7806         {
7807                 struct type *type;
7808                 int tok1, tok2;
7809                 eat(state, TOK_ALIGNOF);
7810                 tok1 = peek(state);
7811                 tok2 = peek2(state);
7812                 if ((tok1 == TOK_LPAREN) && istype(tok2)) {
7813                         eat(state, TOK_LPAREN);
7814                         type = type_name(state);
7815                         eat(state, TOK_RPAREN);
7816                 }
7817                 else {
7818                         struct triple *expr;
7819                         expr = unary_expr(state);
7820                         type = expr->type;
7821                         release_expr(state, expr);
7822                 }
7823                 def = int_const(state, &ulong_type, align_of(state, type));
7824                 break;
7825         }
7826         default:
7827                 def = postfix_expr(state);
7828                 break;
7829         }
7830         return def;
7831 }
7832
7833 static struct triple *cast_expr(struct compile_state *state)
7834 {
7835         struct triple *def;
7836         int tok1, tok2;
7837         tok1 = peek(state);
7838         tok2 = peek2(state);
7839         if ((tok1 == TOK_LPAREN) && istype(tok2)) {
7840                 struct type *type;
7841                 eat(state, TOK_LPAREN);
7842                 type = type_name(state);
7843                 eat(state, TOK_RPAREN);
7844                 def = mk_cast_expr(state, type, cast_expr(state));
7845         }
7846         else {
7847                 def = unary_expr(state);
7848         }
7849         return def;
7850 }
7851
7852 static struct triple *mult_expr(struct compile_state *state)
7853 {
7854         struct triple *def;
7855         int done;
7856         def = cast_expr(state);
7857         do {
7858                 struct triple *left, *right;
7859                 struct type *result_type;
7860                 int tok, op, sign;
7861                 done = 0;
7862                 switch(tok = (peek(state))) {
7863                 case TOK_STAR:
7864                 case TOK_DIV:
7865                 case TOK_MOD:
7866                         left = read_expr(state, def);
7867                         arithmetic(state, left);
7868
7869                         eat(state, tok);
7870
7871                         right = read_expr(state, cast_expr(state));
7872                         arithmetic(state, right);
7873
7874                         result_type = arithmetic_result(state, left, right);
7875                         sign = is_signed(result_type);
7876                         op = -1;
7877                         switch(tok) {
7878                         case TOK_STAR: op = sign? OP_SMUL : OP_UMUL; break;
7879                         case TOK_DIV:  op = sign? OP_SDIV : OP_UDIV; break;
7880                         case TOK_MOD:  op = sign? OP_SMOD : OP_UMOD; break;
7881                         }
7882                         def = triple(state, op, result_type, left, right);
7883                         break;
7884                 default:
7885                         done = 1;
7886                         break;
7887                 }
7888         } while(!done);
7889         return def;
7890 }
7891
7892 static struct triple *add_expr(struct compile_state *state)
7893 {
7894         struct triple *def;
7895         int done;
7896         def = mult_expr(state);
7897         do {
7898                 done = 0;
7899                 switch( peek(state)) {
7900                 case TOK_PLUS:
7901                         eat(state, TOK_PLUS);
7902                         def = mk_add_expr(state, def, mult_expr(state));
7903                         break;
7904                 case TOK_MINUS:
7905                         eat(state, TOK_MINUS);
7906                         def = mk_sub_expr(state, def, mult_expr(state));
7907                         break;
7908                 default:
7909                         done = 1;
7910                         break;
7911                 }
7912         } while(!done);
7913         return def;
7914 }
7915
7916 static struct triple *shift_expr(struct compile_state *state)
7917 {
7918         struct triple *def;
7919         int done;
7920         def = add_expr(state);
7921         do {
7922                 struct triple *left, *right;
7923                 int tok, op;
7924                 done = 0;
7925                 switch((tok = peek(state))) {
7926                 case TOK_SL:
7927                 case TOK_SR:
7928                         left = read_expr(state, def);
7929                         integral(state, left);
7930                         left = integral_promotion(state, left);
7931
7932                         eat(state, tok);
7933
7934                         right = read_expr(state, add_expr(state));
7935                         integral(state, right);
7936                         right = integral_promotion(state, right);
7937                         
7938                         op = (tok == TOK_SL)? OP_SL : 
7939                                 is_signed(left->type)? OP_SSR: OP_USR;
7940
7941                         def = triple(state, op, left->type, left, right);
7942                         break;
7943                 default:
7944                         done = 1;
7945                         break;
7946                 }
7947         } while(!done);
7948         return def;
7949 }
7950
7951 static struct triple *relational_expr(struct compile_state *state)
7952 {
7953 #warning "Extend relational exprs to work on more than arithmetic types"
7954         struct triple *def;
7955         int done;
7956         def = shift_expr(state);
7957         do {
7958                 struct triple *left, *right;
7959                 struct type *arg_type;
7960                 int tok, op, sign;
7961                 done = 0;
7962                 switch((tok = peek(state))) {
7963                 case TOK_LESS:
7964                 case TOK_MORE:
7965                 case TOK_LESSEQ:
7966                 case TOK_MOREEQ:
7967                         left = read_expr(state, def);
7968                         arithmetic(state, left);
7969
7970                         eat(state, tok);
7971
7972                         right = read_expr(state, shift_expr(state));
7973                         arithmetic(state, right);
7974
7975                         arg_type = arithmetic_result(state, left, right);
7976                         sign = is_signed(arg_type);
7977                         op = -1;
7978                         switch(tok) {
7979                         case TOK_LESS:   op = sign? OP_SLESS : OP_ULESS; break;
7980                         case TOK_MORE:   op = sign? OP_SMORE : OP_UMORE; break;
7981                         case TOK_LESSEQ: op = sign? OP_SLESSEQ : OP_ULESSEQ; break;
7982                         case TOK_MOREEQ: op = sign? OP_SMOREEQ : OP_UMOREEQ; break;
7983                         }
7984                         def = triple(state, op, &int_type, left, right);
7985                         break;
7986                 default:
7987                         done = 1;
7988                         break;
7989                 }
7990         } while(!done);
7991         return def;
7992 }
7993
7994 static struct triple *equality_expr(struct compile_state *state)
7995 {
7996 #warning "Extend equality exprs to work on more than arithmetic types"
7997         struct triple *def;
7998         int done;
7999         def = relational_expr(state);
8000         do {
8001                 struct triple *left, *right;
8002                 int tok, op;
8003                 done = 0;
8004                 switch((tok = peek(state))) {
8005                 case TOK_EQEQ:
8006                 case TOK_NOTEQ:
8007                         left = read_expr(state, def);
8008                         arithmetic(state, left);
8009                         eat(state, tok);
8010                         right = read_expr(state, relational_expr(state));
8011                         arithmetic(state, right);
8012                         op = (tok == TOK_EQEQ) ? OP_EQ: OP_NOTEQ;
8013                         def = triple(state, op, &int_type, left, right);
8014                         break;
8015                 default:
8016                         done = 1;
8017                         break;
8018                 }
8019         } while(!done);
8020         return def;
8021 }
8022
8023 static struct triple *and_expr(struct compile_state *state)
8024 {
8025         struct triple *def;
8026         def = equality_expr(state);
8027         while(peek(state) == TOK_AND) {
8028                 struct triple *left, *right;
8029                 struct type *result_type;
8030                 left = read_expr(state, def);
8031                 integral(state, left);
8032                 eat(state, TOK_AND);
8033                 right = read_expr(state, equality_expr(state));
8034                 integral(state, right);
8035                 result_type = arithmetic_result(state, left, right);
8036                 def = triple(state, OP_AND, result_type, left, right);
8037         }
8038         return def;
8039 }
8040
8041 static struct triple *xor_expr(struct compile_state *state)
8042 {
8043         struct triple *def;
8044         def = and_expr(state);
8045         while(peek(state) == TOK_XOR) {
8046                 struct triple *left, *right;
8047                 struct type *result_type;
8048                 left = read_expr(state, def);
8049                 integral(state, left);
8050                 eat(state, TOK_XOR);
8051                 right = read_expr(state, and_expr(state));
8052                 integral(state, right);
8053                 result_type = arithmetic_result(state, left, right);
8054                 def = triple(state, OP_XOR, result_type, left, right);
8055         }
8056         return def;
8057 }
8058
8059 static struct triple *or_expr(struct compile_state *state)
8060 {
8061         struct triple *def;
8062         def = xor_expr(state);
8063         while(peek(state) == TOK_OR) {
8064                 struct triple *left, *right;
8065                 struct type *result_type;
8066                 left = read_expr(state, def);
8067                 integral(state, left);
8068                 eat(state, TOK_OR);
8069                 right = read_expr(state, xor_expr(state));
8070                 integral(state, right);
8071                 result_type = arithmetic_result(state, left, right);
8072                 def = triple(state, OP_OR, result_type, left, right);
8073         }
8074         return def;
8075 }
8076
8077 static struct triple *land_expr(struct compile_state *state)
8078 {
8079         struct triple *def;
8080         def = or_expr(state);
8081         while(peek(state) == TOK_LOGAND) {
8082                 struct triple *left, *right;
8083                 left = read_expr(state, def);
8084                 bool(state, left);
8085                 eat(state, TOK_LOGAND);
8086                 right = read_expr(state, or_expr(state));
8087                 bool(state, right);
8088
8089                 def = triple(state, OP_LAND, &int_type,
8090                         ltrue_expr(state, left),
8091                         ltrue_expr(state, right));
8092         }
8093         return def;
8094 }
8095
8096 static struct triple *lor_expr(struct compile_state *state)
8097 {
8098         struct triple *def;
8099         def = land_expr(state);
8100         while(peek(state) == TOK_LOGOR) {
8101                 struct triple *left, *right;
8102                 left = read_expr(state, def);
8103                 bool(state, left);
8104                 eat(state, TOK_LOGOR);
8105                 right = read_expr(state, land_expr(state));
8106                 bool(state, right);
8107                 
8108                 def = triple(state, OP_LOR, &int_type,
8109                         ltrue_expr(state, left),
8110                         ltrue_expr(state, right));
8111         }
8112         return def;
8113 }
8114
8115 static struct triple *conditional_expr(struct compile_state *state)
8116 {
8117         struct triple *def;
8118         def = lor_expr(state);
8119         if (peek(state) == TOK_QUEST) {
8120                 struct triple *test, *left, *right;
8121                 bool(state, def);
8122                 test = ltrue_expr(state, read_expr(state, def));
8123                 eat(state, TOK_QUEST);
8124                 left = read_expr(state, expr(state));
8125                 eat(state, TOK_COLON);
8126                 right = read_expr(state, conditional_expr(state));
8127
8128                 def = cond_expr(state, test, left, right);
8129         }
8130         return def;
8131 }
8132
8133 static struct triple *eval_const_expr(
8134         struct compile_state *state, struct triple *expr)
8135 {
8136         struct triple *def;
8137         if (is_const(expr)) {
8138                 def = expr;
8139         } 
8140         else {
8141                 /* If we don't start out as a constant simplify into one */
8142                 struct triple *head, *ptr;
8143                 head = label(state); /* dummy initial triple */
8144                 flatten(state, head, expr);
8145                 for(ptr = head->next; ptr != head; ptr = ptr->next) {
8146                         simplify(state, ptr);
8147                 }
8148                 /* Remove the constant value the tail of the list */
8149                 def = head->prev;
8150                 def->prev->next = def->next;
8151                 def->next->prev = def->prev;
8152                 def->next = def->prev = def;
8153                 if (!is_const(def)) {
8154                         error(state, 0, "Not a constant expression");
8155                 }
8156                 /* Free the intermediate expressions */
8157                 while(head->next != head) {
8158                         release_triple(state, head->next);
8159                 }
8160                 free_triple(state, head);
8161         }
8162         return def;
8163 }
8164
8165 static struct triple *constant_expr(struct compile_state *state)
8166 {
8167         return eval_const_expr(state, conditional_expr(state));
8168 }
8169
8170 static struct triple *assignment_expr(struct compile_state *state)
8171 {
8172         struct triple *def, *left, *right;
8173         int tok, op, sign;
8174         /* The C grammer in K&R shows assignment expressions
8175          * only taking unary expressions as input on their
8176          * left hand side.  But specifies the precedence of
8177          * assignemnt as the lowest operator except for comma.
8178          *
8179          * Allowing conditional expressions on the left hand side
8180          * of an assignement results in a grammar that accepts
8181          * a larger set of statements than standard C.   As long
8182          * as the subset of the grammar that is standard C behaves
8183          * correctly this should cause no problems.
8184          * 
8185          * For the extra token strings accepted by the grammar
8186          * none of them should produce a valid lvalue, so they
8187          * should not produce functioning programs.
8188          *
8189          * GCC has this bug as well, so surprises should be minimal.
8190          */
8191         def = conditional_expr(state);
8192         left = def;
8193         switch((tok = peek(state))) {
8194         case TOK_EQ:
8195                 lvalue(state, left);
8196                 eat(state, TOK_EQ);
8197                 def = write_expr(state, left, 
8198                         read_expr(state, assignment_expr(state)));
8199                 break;
8200         case TOK_TIMESEQ:
8201         case TOK_DIVEQ:
8202         case TOK_MODEQ:
8203                 lvalue(state, left);
8204                 arithmetic(state, left);
8205                 eat(state, tok);
8206                 right = read_expr(state, assignment_expr(state));
8207                 arithmetic(state, right);
8208
8209                 sign = is_signed(left->type);
8210                 op = -1;
8211                 switch(tok) {
8212                 case TOK_TIMESEQ: op = sign? OP_SMUL : OP_UMUL; break;
8213                 case TOK_DIVEQ:   op = sign? OP_SDIV : OP_UDIV; break;
8214                 case TOK_MODEQ:   op = sign? OP_SMOD : OP_UMOD; break;
8215                 }
8216                 def = write_expr(state, left,
8217                         triple(state, op, left->type, 
8218                                 read_expr(state, left), right));
8219                 break;
8220         case TOK_PLUSEQ:
8221                 lvalue(state, left);
8222                 eat(state, TOK_PLUSEQ);
8223                 def = write_expr(state, left,
8224                         mk_add_expr(state, left, assignment_expr(state)));
8225                 break;
8226         case TOK_MINUSEQ:
8227                 lvalue(state, left);
8228                 eat(state, TOK_MINUSEQ);
8229                 def = write_expr(state, left,
8230                         mk_sub_expr(state, left, assignment_expr(state)));
8231                 break;
8232         case TOK_SLEQ:
8233         case TOK_SREQ:
8234         case TOK_ANDEQ:
8235         case TOK_XOREQ:
8236         case TOK_OREQ:
8237                 lvalue(state, left);
8238                 integral(state, left);
8239                 eat(state, tok);
8240                 right = read_expr(state, assignment_expr(state));
8241                 integral(state, right);
8242                 right = integral_promotion(state, right);
8243                 sign = is_signed(left->type);
8244                 op = -1;
8245                 switch(tok) {
8246                 case TOK_SLEQ:  op = OP_SL; break;
8247                 case TOK_SREQ:  op = sign? OP_SSR: OP_USR; break;
8248                 case TOK_ANDEQ: op = OP_AND; break;
8249                 case TOK_XOREQ: op = OP_XOR; break;
8250                 case TOK_OREQ:  op = OP_OR; break;
8251                 }
8252                 def = write_expr(state, left,
8253                         triple(state, op, left->type, 
8254                                 read_expr(state, left), right));
8255                 break;
8256         }
8257         return def;
8258 }
8259
8260 static struct triple *expr(struct compile_state *state)
8261 {
8262         struct triple *def;
8263         def = assignment_expr(state);
8264         while(peek(state) == TOK_COMMA) {
8265                 struct triple *left, *right;
8266                 left = def;
8267                 eat(state, TOK_COMMA);
8268                 right = assignment_expr(state);
8269                 def = triple(state, OP_COMMA, right->type, left, right);
8270         }
8271         return def;
8272 }
8273
8274 static void expr_statement(struct compile_state *state, struct triple *first)
8275 {
8276         if (peek(state) != TOK_SEMI) {
8277                 /* lvalue conversions always apply except when certaion operators
8278                  * are applied so the values so apply them here as I know no more
8279                  * operators will be applied.
8280                  */
8281                 flatten(state, first, lvalue_conversion(state, expr(state)));
8282         }
8283         eat(state, TOK_SEMI);
8284 }
8285
8286 static void if_statement(struct compile_state *state, struct triple *first)
8287 {
8288         struct triple *test, *jmp1, *jmp2, *middle, *end;
8289
8290         jmp1 = jmp2 = middle = 0;
8291         eat(state, TOK_IF);
8292         eat(state, TOK_LPAREN);
8293         test = expr(state);
8294         bool(state, test);
8295         /* Cleanup and invert the test */
8296         test = lfalse_expr(state, read_expr(state, test));
8297         eat(state, TOK_RPAREN);
8298         /* Generate the needed pieces */
8299         middle = label(state);
8300         jmp1 = branch(state, middle, test);
8301         /* Thread the pieces together */
8302         flatten(state, first, test);
8303         flatten(state, first, jmp1);
8304         flatten(state, first, label(state));
8305         statement(state, first);
8306         if (peek(state) == TOK_ELSE) {
8307                 eat(state, TOK_ELSE);
8308                 /* Generate the rest of the pieces */
8309                 end = label(state);
8310                 jmp2 = branch(state, end, 0);
8311                 /* Thread them together */
8312                 flatten(state, first, jmp2);
8313                 flatten(state, first, middle);
8314                 statement(state, first);
8315                 flatten(state, first, end);
8316         }
8317         else {
8318                 flatten(state, first, middle);
8319         }
8320 }
8321
8322 static void for_statement(struct compile_state *state, struct triple *first)
8323 {
8324         struct triple *head, *test, *tail, *jmp1, *jmp2, *end;
8325         struct triple *label1, *label2, *label3;
8326         struct hash_entry *ident;
8327
8328         eat(state, TOK_FOR);
8329         eat(state, TOK_LPAREN);
8330         head = test = tail = jmp1 = jmp2 = 0;
8331         if (peek(state) != TOK_SEMI) {
8332                 head = expr(state);
8333         } 
8334         eat(state, TOK_SEMI);
8335         if (peek(state) != TOK_SEMI) {
8336                 test = expr(state);
8337                 bool(state, test);
8338                 test = ltrue_expr(state, read_expr(state, test));
8339         }
8340         eat(state, TOK_SEMI);
8341         if (peek(state) != TOK_RPAREN) {
8342                 tail = expr(state);
8343         }
8344         eat(state, TOK_RPAREN);
8345         /* Generate the needed pieces */
8346         label1 = label(state);
8347         label2 = label(state);
8348         label3 = label(state);
8349         if (test) {
8350                 jmp1 = branch(state, label3, 0);
8351                 jmp2 = branch(state, label1, test);
8352         }
8353         else {
8354                 jmp2 = branch(state, label1, 0);
8355         }
8356         end = label(state);
8357         /* Remember where break and continue go */
8358         start_scope(state);
8359         ident = state->i_break;
8360         symbol(state, ident, &ident->sym_ident, end, end->type);
8361         ident = state->i_continue;
8362         symbol(state, ident, &ident->sym_ident, label2, label2->type);
8363         /* Now include the body */
8364         flatten(state, first, head);
8365         flatten(state, first, jmp1);
8366         flatten(state, first, label1);
8367         statement(state, first);
8368         flatten(state, first, label2);
8369         flatten(state, first, tail);
8370         flatten(state, first, label3);
8371         flatten(state, first, test);
8372         flatten(state, first, jmp2);
8373         flatten(state, first, end);
8374         /* Cleanup the break/continue scope */
8375         end_scope(state);
8376 }
8377
8378 static void while_statement(struct compile_state *state, struct triple *first)
8379 {
8380         struct triple *label1, *test, *label2, *jmp1, *jmp2, *end;
8381         struct hash_entry *ident;
8382         eat(state, TOK_WHILE);
8383         eat(state, TOK_LPAREN);
8384         test = expr(state);
8385         bool(state, test);
8386         test = ltrue_expr(state, read_expr(state, test));
8387         eat(state, TOK_RPAREN);
8388         /* Generate the needed pieces */
8389         label1 = label(state);
8390         label2 = label(state);
8391         jmp1 = branch(state, label2, 0);
8392         jmp2 = branch(state, label1, test);
8393         end = label(state);
8394         /* Remember where break and continue go */
8395         start_scope(state);
8396         ident = state->i_break;
8397         symbol(state, ident, &ident->sym_ident, end, end->type);
8398         ident = state->i_continue;
8399         symbol(state, ident, &ident->sym_ident, label2, label2->type);
8400         /* Thread them together */
8401         flatten(state, first, jmp1);
8402         flatten(state, first, label1);
8403         statement(state, first);
8404         flatten(state, first, label2);
8405         flatten(state, first, test);
8406         flatten(state, first, jmp2);
8407         flatten(state, first, end);
8408         /* Cleanup the break/continue scope */
8409         end_scope(state);
8410 }
8411
8412 static void do_statement(struct compile_state *state, struct triple *first)
8413 {
8414         struct triple *label1, *label2, *test, *end;
8415         struct hash_entry *ident;
8416         eat(state, TOK_DO);
8417         /* Generate the needed pieces */
8418         label1 = label(state);
8419         label2 = label(state);
8420         end = label(state);
8421         /* Remember where break and continue go */
8422         start_scope(state);
8423         ident = state->i_break;
8424         symbol(state, ident, &ident->sym_ident, end, end->type);
8425         ident = state->i_continue;
8426         symbol(state, ident, &ident->sym_ident, label2, label2->type);
8427         /* Now include the body */
8428         flatten(state, first, label1);
8429         statement(state, first);
8430         /* Cleanup the break/continue scope */
8431         end_scope(state);
8432         /* Eat the rest of the loop */
8433         eat(state, TOK_WHILE);
8434         eat(state, TOK_LPAREN);
8435         test = read_expr(state, expr(state));
8436         bool(state, test);
8437         eat(state, TOK_RPAREN);
8438         eat(state, TOK_SEMI);
8439         /* Thread the pieces together */
8440         test = ltrue_expr(state, test);
8441         flatten(state, first, label2);
8442         flatten(state, first, test);
8443         flatten(state, first, branch(state, label1, test));
8444         flatten(state, first, end);
8445 }
8446
8447
8448 static void return_statement(struct compile_state *state, struct triple *first)
8449 {
8450         struct triple *jmp, *mv, *dest, *var, *val;
8451         int last;
8452         eat(state, TOK_RETURN);
8453
8454 #warning "FIXME implement a more general excess branch elimination"
8455         val = 0;
8456         /* If we have a return value do some more work */
8457         if (peek(state) != TOK_SEMI) {
8458                 val = read_expr(state, expr(state));
8459         }
8460         eat(state, TOK_SEMI);
8461
8462         /* See if this last statement in a function */
8463         last = ((peek(state) == TOK_RBRACE) && 
8464                 (state->scope_depth == GLOBAL_SCOPE_DEPTH +2));
8465
8466         /* Find the return variable */
8467         var = MISC(state->main_function, 0);
8468         /* Find the return destination */
8469         dest = state->i_return->sym_ident->def;
8470         mv = jmp = 0;
8471         /* If needed generate a jump instruction */
8472         if (!last) {
8473                 jmp = branch(state, dest, 0);
8474         }
8475         /* If needed generate an assignment instruction */
8476         if (val) {
8477                 mv = write_expr(state, var, val);
8478         }
8479         /* Now put the code together */
8480         if (mv) {
8481                 flatten(state, first, mv);
8482                 flatten(state, first, jmp);
8483         }
8484         else if (jmp) {
8485                 flatten(state, first, jmp);
8486         }
8487 }
8488
8489 static void break_statement(struct compile_state *state, struct triple *first)
8490 {
8491         struct triple *dest;
8492         eat(state, TOK_BREAK);
8493         eat(state, TOK_SEMI);
8494         if (!state->i_break->sym_ident) {
8495                 error(state, 0, "break statement not within loop or switch");
8496         }
8497         dest = state->i_break->sym_ident->def;
8498         flatten(state, first, branch(state, dest, 0));
8499 }
8500
8501 static void continue_statement(struct compile_state *state, struct triple *first)
8502 {
8503         struct triple *dest;
8504         eat(state, TOK_CONTINUE);
8505         eat(state, TOK_SEMI);
8506         if (!state->i_continue->sym_ident) {
8507                 error(state, 0, "continue statement outside of a loop");
8508         }
8509         dest = state->i_continue->sym_ident->def;
8510         flatten(state, first, branch(state, dest, 0));
8511 }
8512
8513 static void goto_statement(struct compile_state *state, struct triple *first)
8514 {
8515         struct hash_entry *ident;
8516         eat(state, TOK_GOTO);
8517         eat(state, TOK_IDENT);
8518         ident = state->token[0].ident;
8519         if (!ident->sym_label) {
8520                 /* If this is a forward branch allocate the label now,
8521                  * it will be flattend in the appropriate location later.
8522                  */
8523                 struct triple *ins;
8524                 ins = label(state);
8525                 label_symbol(state, ident, ins);
8526         }
8527         eat(state, TOK_SEMI);
8528
8529         flatten(state, first, branch(state, ident->sym_label->def, 0));
8530 }
8531
8532 static void labeled_statement(struct compile_state *state, struct triple *first)
8533 {
8534         struct triple *ins;
8535         struct hash_entry *ident;
8536         eat(state, TOK_IDENT);
8537
8538         ident = state->token[0].ident;
8539         if (ident->sym_label && ident->sym_label->def) {
8540                 ins = ident->sym_label->def;
8541                 put_occurance(ins->occurance);
8542                 ins->occurance = new_occurance(state);
8543         }
8544         else {
8545                 ins = label(state);
8546                 label_symbol(state, ident, ins);
8547         }
8548         if (ins->id & TRIPLE_FLAG_FLATTENED) {
8549                 error(state, 0, "label %s already defined", ident->name);
8550         }
8551         flatten(state, first, ins);
8552
8553         eat(state, TOK_COLON);
8554         statement(state, first);
8555 }
8556
8557 static void switch_statement(struct compile_state *state, struct triple *first)
8558 {
8559         struct triple *value, *top, *end, *dbranch;
8560         struct hash_entry *ident;
8561
8562         /* See if we have a valid switch statement */
8563         eat(state, TOK_SWITCH);
8564         eat(state, TOK_LPAREN);
8565         value = expr(state);
8566         integral(state, value);
8567         value = read_expr(state, value);
8568         eat(state, TOK_RPAREN);
8569         /* Generate the needed pieces */
8570         top = label(state);
8571         end = label(state);
8572         dbranch = branch(state, end, 0);
8573         /* Remember where case branches and break goes */
8574         start_scope(state);
8575         ident = state->i_switch;
8576         symbol(state, ident, &ident->sym_ident, value, value->type);
8577         ident = state->i_case;
8578         symbol(state, ident, &ident->sym_ident, top, top->type);
8579         ident = state->i_break;
8580         symbol(state, ident, &ident->sym_ident, end, end->type);
8581         ident = state->i_default;
8582         symbol(state, ident, &ident->sym_ident, dbranch, dbranch->type);
8583         /* Thread them together */
8584         flatten(state, first, value);
8585         flatten(state, first, top);
8586         flatten(state, first, dbranch);
8587         statement(state, first);
8588         flatten(state, first, end);
8589         /* Cleanup the switch scope */
8590         end_scope(state);
8591 }
8592
8593 static void case_statement(struct compile_state *state, struct triple *first)
8594 {
8595         struct triple *cvalue, *dest, *test, *jmp;
8596         struct triple *ptr, *value, *top, *dbranch;
8597
8598         /* See if w have a valid case statement */
8599         eat(state, TOK_CASE);
8600         cvalue = constant_expr(state);
8601         integral(state, cvalue);
8602         if (cvalue->op != OP_INTCONST) {
8603                 error(state, 0, "integer constant expected");
8604         }
8605         eat(state, TOK_COLON);
8606         if (!state->i_case->sym_ident) {
8607                 error(state, 0, "case statement not within a switch");
8608         }
8609
8610         /* Lookup the interesting pieces */
8611         top = state->i_case->sym_ident->def;
8612         value = state->i_switch->sym_ident->def;
8613         dbranch = state->i_default->sym_ident->def;
8614
8615         /* See if this case label has already been used */
8616         for(ptr = top; ptr != dbranch; ptr = ptr->next) {
8617                 if (ptr->op != OP_EQ) {
8618                         continue;
8619                 }
8620                 if (RHS(ptr, 1)->u.cval == cvalue->u.cval) {
8621                         error(state, 0, "duplicate case %d statement",
8622                                 cvalue->u.cval);
8623                 }
8624         }
8625         /* Generate the needed pieces */
8626         dest = label(state);
8627         test = triple(state, OP_EQ, &int_type, value, cvalue);
8628         jmp = branch(state, dest, test);
8629         /* Thread the pieces together */
8630         flatten(state, dbranch, test);
8631         flatten(state, dbranch, jmp);
8632         flatten(state, dbranch, label(state));
8633         flatten(state, first, dest);
8634         statement(state, first);
8635 }
8636
8637 static void default_statement(struct compile_state *state, struct triple *first)
8638 {
8639         struct triple *dest;
8640         struct triple *dbranch, *end;
8641
8642         /* See if we have a valid default statement */
8643         eat(state, TOK_DEFAULT);
8644         eat(state, TOK_COLON);
8645
8646         if (!state->i_case->sym_ident) {
8647                 error(state, 0, "default statement not within a switch");
8648         }
8649
8650         /* Lookup the interesting pieces */
8651         dbranch = state->i_default->sym_ident->def;
8652         end = state->i_break->sym_ident->def;
8653
8654         /* See if a default statement has already happened */
8655         if (TARG(dbranch, 0) != end) {
8656                 error(state, 0, "duplicate default statement");
8657         }
8658
8659         /* Generate the needed pieces */
8660         dest = label(state);
8661
8662         /* Thread the pieces together */
8663         TARG(dbranch, 0) = dest;
8664         flatten(state, first, dest);
8665         statement(state, first);
8666 }
8667
8668 static void asm_statement(struct compile_state *state, struct triple *first)
8669 {
8670         struct asm_info *info;
8671         struct {
8672                 struct triple *constraint;
8673                 struct triple *expr;
8674         } out_param[MAX_LHS], in_param[MAX_RHS], clob_param[MAX_LHS];
8675         struct triple *def, *asm_str;
8676         int out, in, clobbers, more, colons, i;
8677
8678         eat(state, TOK_ASM);
8679         /* For now ignore the qualifiers */
8680         switch(peek(state)) {
8681         case TOK_CONST:
8682                 eat(state, TOK_CONST);
8683                 break;
8684         case TOK_VOLATILE:
8685                 eat(state, TOK_VOLATILE);
8686                 break;
8687         }
8688         eat(state, TOK_LPAREN);
8689         asm_str = string_constant(state);
8690
8691         colons = 0;
8692         out = in = clobbers = 0;
8693         /* Outputs */
8694         if ((colons == 0) && (peek(state) == TOK_COLON)) {
8695                 eat(state, TOK_COLON);
8696                 colons++;
8697                 more = (peek(state) == TOK_LIT_STRING);
8698                 while(more) {
8699                         struct triple *var;
8700                         struct triple *constraint;
8701                         char *str;
8702                         more = 0;
8703                         if (out > MAX_LHS) {
8704                                 error(state, 0, "Maximum output count exceeded.");
8705                         }
8706                         constraint = string_constant(state);
8707                         str = constraint->u.blob;
8708                         if (str[0] != '=') {
8709                                 error(state, 0, "Output constraint does not start with =");
8710                         }
8711                         constraint->u.blob = str + 1;
8712                         eat(state, TOK_LPAREN);
8713                         var = conditional_expr(state);
8714                         eat(state, TOK_RPAREN);
8715
8716                         lvalue(state, var);
8717                         out_param[out].constraint = constraint;
8718                         out_param[out].expr       = var;
8719                         if (peek(state) == TOK_COMMA) {
8720                                 eat(state, TOK_COMMA);
8721                                 more = 1;
8722                         }
8723                         out++;
8724                 }
8725         }
8726         /* Inputs */
8727         if ((colons == 1) && (peek(state) == TOK_COLON)) {
8728                 eat(state, TOK_COLON);
8729                 colons++;
8730                 more = (peek(state) == TOK_LIT_STRING);
8731                 while(more) {
8732                         struct triple *val;
8733                         struct triple *constraint;
8734                         char *str;
8735                         more = 0;
8736                         if (in > MAX_RHS) {
8737                                 error(state, 0, "Maximum input count exceeded.");
8738                         }
8739                         constraint = string_constant(state);
8740                         str = constraint->u.blob;
8741                         if (digitp(str[0] && str[1] == '\0')) {
8742                                 int val;
8743                                 val = digval(str[0]);
8744                                 if ((val < 0) || (val >= out)) {
8745                                         error(state, 0, "Invalid input constraint %d", val);
8746                                 }
8747                         }
8748                         eat(state, TOK_LPAREN);
8749                         val = conditional_expr(state);
8750                         eat(state, TOK_RPAREN);
8751
8752                         in_param[in].constraint = constraint;
8753                         in_param[in].expr       = val;
8754                         if (peek(state) == TOK_COMMA) {
8755                                 eat(state, TOK_COMMA);
8756                                 more = 1;
8757                         }
8758                         in++;
8759                 }
8760         }
8761
8762         /* Clobber */
8763         if ((colons == 2) && (peek(state) == TOK_COLON)) {
8764                 eat(state, TOK_COLON);
8765                 colons++;
8766                 more = (peek(state) == TOK_LIT_STRING);
8767                 while(more) {
8768                         struct triple *clobber;
8769                         more = 0;
8770                         if ((clobbers + out) > MAX_LHS) {
8771                                 error(state, 0, "Maximum clobber limit exceeded.");
8772                         }
8773                         clobber = string_constant(state);
8774
8775                         clob_param[clobbers].constraint = clobber;
8776                         if (peek(state) == TOK_COMMA) {
8777                                 eat(state, TOK_COMMA);
8778                                 more = 1;
8779                         }
8780                         clobbers++;
8781                 }
8782         }
8783         eat(state, TOK_RPAREN);
8784         eat(state, TOK_SEMI);
8785
8786
8787         info = xcmalloc(sizeof(*info), "asm_info");
8788         info->str = asm_str->u.blob;
8789         free_triple(state, asm_str);
8790
8791         def = new_triple(state, OP_ASM, &void_type, clobbers + out, in);
8792         def->u.ainfo = info;
8793
8794         /* Find the register constraints */
8795         for(i = 0; i < out; i++) {
8796                 struct triple *constraint;
8797                 constraint = out_param[i].constraint;
8798                 info->tmpl.lhs[i] = arch_reg_constraint(state, 
8799                         out_param[i].expr->type, constraint->u.blob);
8800                 free_triple(state, constraint);
8801         }
8802         for(; i - out < clobbers; i++) {
8803                 struct triple *constraint;
8804                 constraint = clob_param[i - out].constraint;
8805                 info->tmpl.lhs[i] = arch_reg_clobber(state, constraint->u.blob);
8806                 free_triple(state, constraint);
8807         }
8808         for(i = 0; i < in; i++) {
8809                 struct triple *constraint;
8810                 const char *str;
8811                 constraint = in_param[i].constraint;
8812                 str = constraint->u.blob;
8813                 if (digitp(str[0]) && str[1] == '\0') {
8814                         struct reg_info cinfo;
8815                         int val;
8816                         val = digval(str[0]);
8817                         cinfo.reg = info->tmpl.lhs[val].reg;
8818                         cinfo.regcm = arch_type_to_regcm(state, in_param[i].expr->type);
8819                         cinfo.regcm &= info->tmpl.lhs[val].regcm;
8820                         if (cinfo.reg == REG_UNSET) {
8821                                 cinfo.reg = REG_VIRT0 + val;
8822                         }
8823                         if (cinfo.regcm == 0) {
8824                                 error(state, 0, "No registers for %d", val);
8825                         }
8826                         info->tmpl.lhs[val] = cinfo;
8827                         info->tmpl.rhs[i]   = cinfo;
8828                                 
8829                 } else {
8830                         info->tmpl.rhs[i] = arch_reg_constraint(state, 
8831                                 in_param[i].expr->type, str);
8832                 }
8833                 free_triple(state, constraint);
8834         }
8835
8836         /* Now build the helper expressions */
8837         for(i = 0; i < in; i++) {
8838                 RHS(def, i) = read_expr(state,in_param[i].expr);
8839         }
8840         flatten(state, first, def);
8841         for(i = 0; i < (out + clobbers); i++) {
8842                 struct type *type;
8843                 struct triple *piece;
8844                 type = (i < out)? out_param[i].expr->type : &void_type;
8845                 piece = triple(state, OP_PIECE, type, def, 0);
8846                 piece->u.cval = i;
8847                 LHS(def, i) = piece;
8848                 flatten(state, first, piece);
8849         }
8850         /* And write the helpers to their destinations */
8851         for(i = 0; i < out; i++) {
8852                 struct triple *piece;
8853                 piece = LHS(def, i);
8854                 flatten(state, first,
8855                         write_expr(state, out_param[i].expr, piece));
8856         }
8857 }
8858
8859
8860 static int isdecl(int tok)
8861 {
8862         switch(tok) {
8863         case TOK_AUTO:
8864         case TOK_REGISTER:
8865         case TOK_STATIC:
8866         case TOK_EXTERN:
8867         case TOK_TYPEDEF:
8868         case TOK_CONST:
8869         case TOK_RESTRICT:
8870         case TOK_VOLATILE:
8871         case TOK_VOID:
8872         case TOK_CHAR:
8873         case TOK_SHORT:
8874         case TOK_INT:
8875         case TOK_LONG:
8876         case TOK_FLOAT:
8877         case TOK_DOUBLE:
8878         case TOK_SIGNED:
8879         case TOK_UNSIGNED:
8880         case TOK_STRUCT:
8881         case TOK_UNION:
8882         case TOK_ENUM:
8883         case TOK_TYPE_NAME: /* typedef name */
8884                 return 1;
8885         default:
8886                 return 0;
8887         }
8888 }
8889
8890 static void compound_statement(struct compile_state *state, struct triple *first)
8891 {
8892         eat(state, TOK_LBRACE);
8893         start_scope(state);
8894
8895         /* statement-list opt */
8896         while (peek(state) != TOK_RBRACE) {
8897                 statement(state, first);
8898         }
8899         end_scope(state);
8900         eat(state, TOK_RBRACE);
8901 }
8902
8903 static void statement(struct compile_state *state, struct triple *first)
8904 {
8905         int tok;
8906         tok = peek(state);
8907         if (tok == TOK_LBRACE) {
8908                 compound_statement(state, first);
8909         }
8910         else if (tok == TOK_IF) {
8911                 if_statement(state, first); 
8912         }
8913         else if (tok == TOK_FOR) {
8914                 for_statement(state, first);
8915         }
8916         else if (tok == TOK_WHILE) {
8917                 while_statement(state, first);
8918         }
8919         else if (tok == TOK_DO) {
8920                 do_statement(state, first);
8921         }
8922         else if (tok == TOK_RETURN) {
8923                 return_statement(state, first);
8924         }
8925         else if (tok == TOK_BREAK) {
8926                 break_statement(state, first);
8927         }
8928         else if (tok == TOK_CONTINUE) {
8929                 continue_statement(state, first);
8930         }
8931         else if (tok == TOK_GOTO) {
8932                 goto_statement(state, first);
8933         }
8934         else if (tok == TOK_SWITCH) {
8935                 switch_statement(state, first);
8936         }
8937         else if (tok == TOK_ASM) {
8938                 asm_statement(state, first);
8939         }
8940         else if ((tok == TOK_IDENT) && (peek2(state) == TOK_COLON)) {
8941                 labeled_statement(state, first); 
8942         }
8943         else if (tok == TOK_CASE) {
8944                 case_statement(state, first);
8945         }
8946         else if (tok == TOK_DEFAULT) {
8947                 default_statement(state, first);
8948         }
8949         else if (isdecl(tok)) {
8950                 /* This handles C99 intermixing of statements and decls */
8951                 decl(state, first);
8952         }
8953         else {
8954                 expr_statement(state, first);
8955         }
8956 }
8957
8958 static struct type *param_decl(struct compile_state *state)
8959 {
8960         struct type *type;
8961         struct hash_entry *ident;
8962         /* Cheat so the declarator will know we are not global */
8963         start_scope(state); 
8964         ident = 0;
8965         type = decl_specifiers(state);
8966         type = declarator(state, type, &ident, 0);
8967         type->field_ident = ident;
8968         end_scope(state);
8969         return type;
8970 }
8971
8972 static struct type *param_type_list(struct compile_state *state, struct type *type)
8973 {
8974         struct type *ftype, **next;
8975         ftype = new_type(TYPE_FUNCTION | (type->type & STOR_MASK), type, param_decl(state));
8976         next = &ftype->right;
8977         while(peek(state) == TOK_COMMA) {
8978                 eat(state, TOK_COMMA);
8979                 if (peek(state) == TOK_DOTS) {
8980                         eat(state, TOK_DOTS);
8981                         error(state, 0, "variadic functions not supported");
8982                 }
8983                 else {
8984                         *next = new_type(TYPE_PRODUCT, *next, param_decl(state));
8985                         next = &((*next)->right);
8986                 }
8987         }
8988         return ftype;
8989 }
8990
8991
8992 static struct type *type_name(struct compile_state *state)
8993 {
8994         struct type *type;
8995         type = specifier_qualifier_list(state);
8996         /* abstract-declarator (may consume no tokens) */
8997         type = declarator(state, type, 0, 0);
8998         return type;
8999 }
9000
9001 static struct type *direct_declarator(
9002         struct compile_state *state, struct type *type, 
9003         struct hash_entry **ident, int need_ident)
9004 {
9005         struct type *outer;
9006         int op;
9007         outer = 0;
9008         arrays_complete(state, type);
9009         switch(peek(state)) {
9010         case TOK_IDENT:
9011                 eat(state, TOK_IDENT);
9012                 if (!ident) {
9013                         error(state, 0, "Unexpected identifier found");
9014                 }
9015                 /* The name of what we are declaring */
9016                 *ident = state->token[0].ident;
9017                 break;
9018         case TOK_LPAREN:
9019                 eat(state, TOK_LPAREN);
9020                 outer = declarator(state, type, ident, need_ident);
9021                 eat(state, TOK_RPAREN);
9022                 break;
9023         default:
9024                 if (need_ident) {
9025                         error(state, 0, "Identifier expected");
9026                 }
9027                 break;
9028         }
9029         do {
9030                 op = 1;
9031                 arrays_complete(state, type);
9032                 switch(peek(state)) {
9033                 case TOK_LPAREN:
9034                         eat(state, TOK_LPAREN);
9035                         type = param_type_list(state, type);
9036                         eat(state, TOK_RPAREN);
9037                         break;
9038                 case TOK_LBRACKET:
9039                 {
9040                         unsigned int qualifiers;
9041                         struct triple *value;
9042                         value = 0;
9043                         eat(state, TOK_LBRACKET);
9044                         if (peek(state) != TOK_RBRACKET) {
9045                                 value = constant_expr(state);
9046                                 integral(state, value);
9047                         }
9048                         eat(state, TOK_RBRACKET);
9049
9050                         qualifiers = type->type & (QUAL_MASK | STOR_MASK);
9051                         type = new_type(TYPE_ARRAY | qualifiers, type, 0);
9052                         if (value) {
9053                                 type->elements = value->u.cval;
9054                                 free_triple(state, value);
9055                         } else {
9056                                 type->elements = ELEMENT_COUNT_UNSPECIFIED;
9057                                 op = 0;
9058                         }
9059                 }
9060                         break;
9061                 default:
9062                         op = 0;
9063                         break;
9064                 }
9065         } while(op);
9066         if (outer) {
9067                 struct type *inner;
9068                 arrays_complete(state, type);
9069                 FINISHME();
9070                 for(inner = outer; inner->left; inner = inner->left)
9071                         ;
9072                 inner->left = type;
9073                 type = outer;
9074         }
9075         return type;
9076 }
9077
9078 static struct type *declarator(
9079         struct compile_state *state, struct type *type, 
9080         struct hash_entry **ident, int need_ident)
9081 {
9082         while(peek(state) == TOK_STAR) {
9083                 eat(state, TOK_STAR);
9084                 type = new_type(TYPE_POINTER | (type->type & STOR_MASK), type, 0);
9085         }
9086         type = direct_declarator(state, type, ident, need_ident);
9087         return type;
9088 }
9089
9090
9091 static struct type *typedef_name(
9092         struct compile_state *state, unsigned int specifiers)
9093 {
9094         struct hash_entry *ident;
9095         struct type *type;
9096         eat(state, TOK_TYPE_NAME);
9097         ident = state->token[0].ident;
9098         type = ident->sym_ident->type;
9099         specifiers |= type->type & QUAL_MASK;
9100         if ((specifiers & (STOR_MASK | QUAL_MASK)) != 
9101                 (type->type & (STOR_MASK | QUAL_MASK))) {
9102                 type = clone_type(specifiers, type);
9103         }
9104         return type;
9105 }
9106
9107 static struct type *enum_specifier(
9108         struct compile_state *state, unsigned int spec)
9109 {
9110         struct hash_entry *ident;
9111         ulong_t base;
9112         int tok;
9113         struct type *enum_type;
9114         enum_type = 0;
9115         ident = 0;
9116         eat(state, TOK_ENUM);
9117         tok = peek(state);
9118         if ((tok == TOK_IDENT) || (tok == TOK_ENUM_CONST) || (tok == TOK_TYPE_NAME)) {
9119                 eat(state, tok);
9120                 ident = state->token[0].ident;
9121                 
9122         }
9123         base = 0;
9124         if (!ident || (peek(state) == TOK_LBRACE)) {
9125                 struct type **next;
9126                 eat(state, TOK_LBRACE);
9127                 enum_type = new_type(TYPE_ENUM | spec, 0, 0);
9128                 enum_type->type_ident = ident;
9129                 next = &enum_type->right;
9130                 do {
9131                         struct hash_entry *eident;
9132                         struct triple *value;
9133                         struct type *entry;
9134                         eat(state, TOK_IDENT);
9135                         eident = state->token[0].ident;
9136                         if (eident->sym_ident) {
9137                                 error(state, 0, "%s already declared", 
9138                                         eident->name);
9139                         }
9140                         eident->tok = TOK_ENUM_CONST;
9141                         if (peek(state) == TOK_EQ) {
9142                                 struct triple *val;
9143                                 eat(state, TOK_EQ);
9144                                 val = constant_expr(state);
9145                                 integral(state, val);
9146                                 base = val->u.cval;
9147                         }
9148                         value = int_const(state, &int_type, base);
9149                         symbol(state, eident, &eident->sym_ident, value, &int_type);
9150                         entry = new_type(TYPE_LIST, 0, 0);
9151                         entry->field_ident = eident;
9152                         *next = entry;
9153                         next = &entry->right;
9154                         base += 1;
9155                         if (peek(state) == TOK_COMMA) {
9156                                 eat(state, TOK_COMMA);
9157                         }
9158                 } while(peek(state) != TOK_RBRACE);
9159                 eat(state, TOK_RBRACE);
9160                 if (ident) {
9161                         symbol(state, ident, &ident->sym_tag, 0, enum_type);
9162                 }
9163         }
9164         if (ident && ident->sym_tag &&
9165                 ident->sym_tag->type &&
9166                 ((ident->sym_tag->type->type & TYPE_MASK) == TYPE_ENUM)) {
9167                 enum_type = clone_type(spec, ident->sym_tag->type);
9168         }
9169         else if (ident && !enum_type) {
9170                 error(state, 0, "enum %s undeclared", ident->name);
9171         }
9172         return enum_type;
9173 }
9174
9175 static struct type *struct_declarator(
9176         struct compile_state *state, struct type *type, struct hash_entry **ident)
9177 {
9178         int tok;
9179         tok = peek(state);
9180         if (tok != TOK_COLON) {
9181                 type = declarator(state, type, ident, 1);
9182         }
9183         if ((tok == TOK_COLON) || (peek(state) == TOK_COLON)) {
9184                 struct triple *value;
9185                 eat(state, TOK_COLON);
9186                 value = constant_expr(state);
9187 #warning "FIXME implement bitfields to reduce register usage"
9188                 error(state, 0, "bitfields not yet implemented");
9189         }
9190         return type;
9191 }
9192
9193 static struct type *struct_or_union_specifier(
9194         struct compile_state *state, unsigned int spec)
9195 {
9196         struct type *struct_type;
9197         struct hash_entry *ident;
9198         unsigned int type_join;
9199         int tok;
9200         struct_type = 0;
9201         ident = 0;
9202         switch(peek(state)) {
9203         case TOK_STRUCT:
9204                 eat(state, TOK_STRUCT);
9205                 type_join = TYPE_PRODUCT;
9206                 break;
9207         case TOK_UNION:
9208                 eat(state, TOK_UNION);
9209                 type_join = TYPE_OVERLAP;
9210                 error(state, 0, "unions not yet supported\n");
9211                 break;
9212         default:
9213                 eat(state, TOK_STRUCT);
9214                 type_join = TYPE_PRODUCT;
9215                 break;
9216         }
9217         tok = peek(state);
9218         if ((tok == TOK_IDENT) || (tok == TOK_ENUM_CONST) || (tok == TOK_TYPE_NAME)) {
9219                 eat(state, tok);
9220                 ident = state->token[0].ident;
9221         }
9222         if (!ident || (peek(state) == TOK_LBRACE)) {
9223                 ulong_t elements;
9224                 struct type **next;
9225                 elements = 0;
9226                 eat(state, TOK_LBRACE);
9227                 next = &struct_type;
9228                 do {
9229                         struct type *base_type;
9230                         int done;
9231                         base_type = specifier_qualifier_list(state);
9232                         do {
9233                                 struct type *type;
9234                                 struct hash_entry *fident;
9235                                 done = 1;
9236                                 type = struct_declarator(state, base_type, &fident);
9237                                 elements++;
9238                                 if (peek(state) == TOK_COMMA) {
9239                                         done = 0;
9240                                         eat(state, TOK_COMMA);
9241                                 }
9242                                 type = clone_type(0, type);
9243                                 type->field_ident = fident;
9244                                 if (*next) {
9245                                         *next = new_type(type_join, *next, type);
9246                                         next = &((*next)->right);
9247                                 } else {
9248                                         *next = type;
9249                                 }
9250                         } while(!done);
9251                         eat(state, TOK_SEMI);
9252                 } while(peek(state) != TOK_RBRACE);
9253                 eat(state, TOK_RBRACE);
9254                 struct_type = new_type(TYPE_STRUCT | spec, struct_type, 0);
9255                 struct_type->type_ident = ident;
9256                 struct_type->elements = elements;
9257                 if (ident) {
9258                         symbol(state, ident, &ident->sym_tag, 0, struct_type);
9259                 }
9260         }
9261         if (ident && ident->sym_tag && 
9262                 ident->sym_tag->type && 
9263                 ((ident->sym_tag->type->type & TYPE_MASK) == TYPE_STRUCT)) {
9264                 struct_type = clone_type(spec, ident->sym_tag->type);
9265         }
9266         else if (ident && !struct_type) {
9267                 error(state, 0, "struct %s undeclared", ident->name);
9268         }
9269         return struct_type;
9270 }
9271
9272 static unsigned int storage_class_specifier_opt(struct compile_state *state)
9273 {
9274         unsigned int specifiers;
9275         switch(peek(state)) {
9276         case TOK_AUTO:
9277                 eat(state, TOK_AUTO);
9278                 specifiers = STOR_AUTO;
9279                 break;
9280         case TOK_REGISTER:
9281                 eat(state, TOK_REGISTER);
9282                 specifiers = STOR_REGISTER;
9283                 break;
9284         case TOK_STATIC:
9285                 eat(state, TOK_STATIC);
9286                 specifiers = STOR_STATIC;
9287                 break;
9288         case TOK_EXTERN:
9289                 eat(state, TOK_EXTERN);
9290                 specifiers = STOR_EXTERN;
9291                 break;
9292         case TOK_TYPEDEF:
9293                 eat(state, TOK_TYPEDEF);
9294                 specifiers = STOR_TYPEDEF;
9295                 break;
9296         default:
9297                 if (state->scope_depth <= GLOBAL_SCOPE_DEPTH) {
9298                         specifiers = STOR_LOCAL;
9299                 }
9300                 else {
9301                         specifiers = STOR_AUTO;
9302                 }
9303         }
9304         return specifiers;
9305 }
9306
9307 static unsigned int function_specifier_opt(struct compile_state *state)
9308 {
9309         /* Ignore the inline keyword */
9310         unsigned int specifiers;
9311         specifiers = 0;
9312         switch(peek(state)) {
9313         case TOK_INLINE:
9314                 eat(state, TOK_INLINE);
9315                 specifiers = STOR_INLINE;
9316         }
9317         return specifiers;
9318 }
9319
9320 static unsigned int type_qualifiers(struct compile_state *state)
9321 {
9322         unsigned int specifiers;
9323         int done;
9324         done = 0;
9325         specifiers = QUAL_NONE;
9326         do {
9327                 switch(peek(state)) {
9328                 case TOK_CONST:
9329                         eat(state, TOK_CONST);
9330                         specifiers = QUAL_CONST;
9331                         break;
9332                 case TOK_VOLATILE:
9333                         eat(state, TOK_VOLATILE);
9334                         specifiers = QUAL_VOLATILE;
9335                         break;
9336                 case TOK_RESTRICT:
9337                         eat(state, TOK_RESTRICT);
9338                         specifiers = QUAL_RESTRICT;
9339                         break;
9340                 default:
9341                         done = 1;
9342                         break;
9343                 }
9344         } while(!done);
9345         return specifiers;
9346 }
9347
9348 static struct type *type_specifier(
9349         struct compile_state *state, unsigned int spec)
9350 {
9351         struct type *type;
9352         type = 0;
9353         switch(peek(state)) {
9354         case TOK_VOID:
9355                 eat(state, TOK_VOID);
9356                 type = new_type(TYPE_VOID | spec, 0, 0);
9357                 break;
9358         case TOK_CHAR:
9359                 eat(state, TOK_CHAR);
9360                 type = new_type(TYPE_CHAR | spec, 0, 0);
9361                 break;
9362         case TOK_SHORT:
9363                 eat(state, TOK_SHORT);
9364                 if (peek(state) == TOK_INT) {
9365                         eat(state, TOK_INT);
9366                 }
9367                 type = new_type(TYPE_SHORT | spec, 0, 0);
9368                 break;
9369         case TOK_INT:
9370                 eat(state, TOK_INT);
9371                 type = new_type(TYPE_INT | spec, 0, 0);
9372                 break;
9373         case TOK_LONG:
9374                 eat(state, TOK_LONG);
9375                 switch(peek(state)) {
9376                 case TOK_LONG:
9377                         eat(state, TOK_LONG);
9378                         error(state, 0, "long long not supported");
9379                         break;
9380                 case TOK_DOUBLE:
9381                         eat(state, TOK_DOUBLE);
9382                         error(state, 0, "long double not supported");
9383                         break;
9384                 case TOK_INT:
9385                         eat(state, TOK_INT);
9386                         type = new_type(TYPE_LONG | spec, 0, 0);
9387                         break;
9388                 default:
9389                         type = new_type(TYPE_LONG | spec, 0, 0);
9390                         break;
9391                 }
9392                 break;
9393         case TOK_FLOAT:
9394                 eat(state, TOK_FLOAT);
9395                 error(state, 0, "type float not supported");
9396                 break;
9397         case TOK_DOUBLE:
9398                 eat(state, TOK_DOUBLE);
9399                 error(state, 0, "type double not supported");
9400                 break;
9401         case TOK_SIGNED:
9402                 eat(state, TOK_SIGNED);
9403                 switch(peek(state)) {
9404                 case TOK_LONG:
9405                         eat(state, TOK_LONG);
9406                         switch(peek(state)) {
9407                         case TOK_LONG:
9408                                 eat(state, TOK_LONG);
9409                                 error(state, 0, "type long long not supported");
9410                                 break;
9411                         case TOK_INT:
9412                                 eat(state, TOK_INT);
9413                                 type = new_type(TYPE_LONG | spec, 0, 0);
9414                                 break;
9415                         default:
9416                                 type = new_type(TYPE_LONG | spec, 0, 0);
9417                                 break;
9418                         }
9419                         break;
9420                 case TOK_INT:
9421                         eat(state, TOK_INT);
9422                         type = new_type(TYPE_INT | spec, 0, 0);
9423                         break;
9424                 case TOK_SHORT:
9425                         eat(state, TOK_SHORT);
9426                         type = new_type(TYPE_SHORT | spec, 0, 0);
9427                         break;
9428                 case TOK_CHAR:
9429                         eat(state, TOK_CHAR);
9430                         type = new_type(TYPE_CHAR | spec, 0, 0);
9431                         break;
9432                 default:
9433                         type = new_type(TYPE_INT | spec, 0, 0);
9434                         break;
9435                 }
9436                 break;
9437         case TOK_UNSIGNED:
9438                 eat(state, TOK_UNSIGNED);
9439                 switch(peek(state)) {
9440                 case TOK_LONG:
9441                         eat(state, TOK_LONG);
9442                         switch(peek(state)) {
9443                         case TOK_LONG:
9444                                 eat(state, TOK_LONG);
9445                                 error(state, 0, "unsigned long long not supported");
9446                                 break;
9447                         case TOK_INT:
9448                                 eat(state, TOK_INT);
9449                                 type = new_type(TYPE_ULONG | spec, 0, 0);
9450                                 break;
9451                         default:
9452                                 type = new_type(TYPE_ULONG | spec, 0, 0);
9453                                 break;
9454                         }
9455                         break;
9456                 case TOK_INT:
9457                         eat(state, TOK_INT);
9458                         type = new_type(TYPE_UINT | spec, 0, 0);
9459                         break;
9460                 case TOK_SHORT:
9461                         eat(state, TOK_SHORT);
9462                         type = new_type(TYPE_USHORT | spec, 0, 0);
9463                         break;
9464                 case TOK_CHAR:
9465                         eat(state, TOK_CHAR);
9466                         type = new_type(TYPE_UCHAR | spec, 0, 0);
9467                         break;
9468                 default:
9469                         type = new_type(TYPE_UINT | spec, 0, 0);
9470                         break;
9471                 }
9472                 break;
9473                 /* struct or union specifier */
9474         case TOK_STRUCT:
9475         case TOK_UNION:
9476                 type = struct_or_union_specifier(state, spec);
9477                 break;
9478                 /* enum-spefifier */
9479         case TOK_ENUM:
9480                 type = enum_specifier(state, spec);
9481                 break;
9482                 /* typedef name */
9483         case TOK_TYPE_NAME:
9484                 type = typedef_name(state, spec);
9485                 break;
9486         default:
9487                 error(state, 0, "bad type specifier %s", 
9488                         tokens[peek(state)]);
9489                 break;
9490         }
9491         return type;
9492 }
9493
9494 static int istype(int tok)
9495 {
9496         switch(tok) {
9497         case TOK_CONST:
9498         case TOK_RESTRICT:
9499         case TOK_VOLATILE:
9500         case TOK_VOID:
9501         case TOK_CHAR:
9502         case TOK_SHORT:
9503         case TOK_INT:
9504         case TOK_LONG:
9505         case TOK_FLOAT:
9506         case TOK_DOUBLE:
9507         case TOK_SIGNED:
9508         case TOK_UNSIGNED:
9509         case TOK_STRUCT:
9510         case TOK_UNION:
9511         case TOK_ENUM:
9512         case TOK_TYPE_NAME:
9513                 return 1;
9514         default:
9515                 return 0;
9516         }
9517 }
9518
9519
9520 static struct type *specifier_qualifier_list(struct compile_state *state)
9521 {
9522         struct type *type;
9523         unsigned int specifiers = 0;
9524
9525         /* type qualifiers */
9526         specifiers |= type_qualifiers(state);
9527
9528         /* type specifier */
9529         type = type_specifier(state, specifiers);
9530
9531         return type;
9532 }
9533
9534 static int isdecl_specifier(int tok)
9535 {
9536         switch(tok) {
9537                 /* storage class specifier */
9538         case TOK_AUTO:
9539         case TOK_REGISTER:
9540         case TOK_STATIC:
9541         case TOK_EXTERN:
9542         case TOK_TYPEDEF:
9543                 /* type qualifier */
9544         case TOK_CONST:
9545         case TOK_RESTRICT:
9546         case TOK_VOLATILE:
9547                 /* type specifiers */
9548         case TOK_VOID:
9549         case TOK_CHAR:
9550         case TOK_SHORT:
9551         case TOK_INT:
9552         case TOK_LONG:
9553         case TOK_FLOAT:
9554         case TOK_DOUBLE:
9555         case TOK_SIGNED:
9556         case TOK_UNSIGNED:
9557                 /* struct or union specifier */
9558         case TOK_STRUCT:
9559         case TOK_UNION:
9560                 /* enum-spefifier */
9561         case TOK_ENUM:
9562                 /* typedef name */
9563         case TOK_TYPE_NAME:
9564                 /* function specifiers */
9565         case TOK_INLINE:
9566                 return 1;
9567         default:
9568                 return 0;
9569         }
9570 }
9571
9572 static struct type *decl_specifiers(struct compile_state *state)
9573 {
9574         struct type *type;
9575         unsigned int specifiers;
9576         /* I am overly restrictive in the arragement of specifiers supported.
9577          * C is overly flexible in this department it makes interpreting
9578          * the parse tree difficult.
9579          */
9580         specifiers = 0;
9581
9582         /* storage class specifier */
9583         specifiers |= storage_class_specifier_opt(state);
9584
9585         /* function-specifier */
9586         specifiers |= function_specifier_opt(state);
9587
9588         /* type qualifier */
9589         specifiers |= type_qualifiers(state);
9590
9591         /* type specifier */
9592         type = type_specifier(state, specifiers);
9593         return type;
9594 }
9595
9596 struct field_info {
9597         struct type *type;
9598         size_t offset;
9599 };
9600
9601 static struct field_info designator(struct compile_state *state, struct type *type)
9602 {
9603         int tok;
9604         struct field_info info;
9605         info.offset = ~0U;
9606         info.type = 0;
9607         do {
9608                 switch(peek(state)) {
9609                 case TOK_LBRACKET:
9610                 {
9611                         struct triple *value;
9612                         if ((type->type & TYPE_MASK) != TYPE_ARRAY) {
9613                                 error(state, 0, "Array designator not in array initializer");
9614                         }
9615                         eat(state, TOK_LBRACKET);
9616                         value = constant_expr(state);
9617                         eat(state, TOK_RBRACKET);
9618
9619                         info.type = type->left;
9620                         info.offset = value->u.cval * size_of(state, info.type);
9621                         break;
9622                 }
9623                 case TOK_DOT:
9624                 {
9625                         struct hash_entry *field;
9626                         if ((type->type & TYPE_MASK) != TYPE_STRUCT) {
9627                                 error(state, 0, "Struct designator not in struct initializer");
9628                         }
9629                         eat(state, TOK_DOT);
9630                         eat(state, TOK_IDENT);
9631                         field = state->token[0].ident;
9632                         info.offset = field_offset(state, type, field);
9633                         info.type   = field_type(state, type, field);
9634                         break;
9635                 }
9636                 default:
9637                         error(state, 0, "Invalid designator");
9638                 }
9639                 tok = peek(state);
9640         } while((tok == TOK_LBRACKET) || (tok == TOK_DOT));
9641         eat(state, TOK_EQ);
9642         return info;
9643 }
9644
9645 static struct triple *initializer(
9646         struct compile_state *state, struct type *type)
9647 {
9648         struct triple *result;
9649 #warning "FIXME more consistent initializer handling (where should eval_const_expr go?"
9650         if (peek(state) != TOK_LBRACE) {
9651                 result = assignment_expr(state);
9652                 if (((type->type & TYPE_MASK) == TYPE_ARRAY) &&
9653                         (type->elements == ELEMENT_COUNT_UNSPECIFIED) &&
9654                         ((result->type->type & TYPE_MASK) == TYPE_ARRAY) &&
9655                         (result->type->elements != ELEMENT_COUNT_UNSPECIFIED) &&
9656                         (equiv_types(type->left, result->type->left))) {
9657                         type->elements = result->type->elements;
9658                 }
9659                 if (is_stable(state, result) && 
9660                         ((result->type->type & TYPE_MASK) == TYPE_ARRAY) &&
9661                         (type->type & TYPE_MASK) != TYPE_ARRAY)
9662                 {
9663                         result = lvalue_conversion(state, result);
9664                 }
9665                 if (!is_init_compatible(state, type, result->type)) {
9666                         error(state, 0, "Incompatible types in initializer");
9667                 }
9668                 if (!equiv_types(type, result->type)) {
9669                         result = mk_cast_expr(state, type, result);
9670                 }
9671         }
9672         else {
9673                 int comma;
9674                 size_t max_offset;
9675                 struct field_info info;
9676                 void *buf;
9677                 if (((type->type & TYPE_MASK) != TYPE_ARRAY) &&
9678                         ((type->type & TYPE_MASK) != TYPE_STRUCT)) {
9679                         internal_error(state, 0, "unknown initializer type");
9680                 }
9681                 info.offset = 0;
9682                 info.type = type->left;
9683                 if ((type->type & TYPE_MASK) == TYPE_STRUCT) {
9684                         info.type = next_field(state, type, 0);
9685                 }
9686                 if (type->elements == ELEMENT_COUNT_UNSPECIFIED) {
9687                         max_offset = 0;
9688                 } else {
9689                         max_offset = size_of(state, type);
9690                 }
9691                 buf = xcmalloc(max_offset, "initializer");
9692                 eat(state, TOK_LBRACE);
9693                 do {
9694                         struct triple *value;
9695                         struct type *value_type;
9696                         size_t value_size;
9697                         void *dest;
9698                         int tok;
9699                         comma = 0;
9700                         tok = peek(state);
9701                         if ((tok == TOK_LBRACKET) || (tok == TOK_DOT)) {
9702                                 info = designator(state, type);
9703                         }
9704                         if ((type->elements != ELEMENT_COUNT_UNSPECIFIED) &&
9705                                 (info.offset >= max_offset)) {
9706                                 error(state, 0, "element beyond bounds");
9707                         }
9708                         value_type = info.type;
9709                         value = eval_const_expr(state, initializer(state, value_type));
9710                         value_size = size_of(state, value_type);
9711                         if (((type->type & TYPE_MASK) == TYPE_ARRAY) &&
9712                                 (type->elements == ELEMENT_COUNT_UNSPECIFIED) &&
9713                                 (max_offset <= info.offset)) {
9714                                 void *old_buf;
9715                                 size_t old_size;
9716                                 old_buf = buf;
9717                                 old_size = max_offset;
9718                                 max_offset = info.offset + value_size;
9719                                 buf = xmalloc(max_offset, "initializer");
9720                                 memcpy(buf, old_buf, old_size);
9721                                 xfree(old_buf);
9722                         }
9723                         dest = ((char *)buf) + info.offset;
9724                         if (value->op == OP_BLOBCONST) {
9725                                 memcpy(dest, value->u.blob, value_size);
9726                         }
9727                         else if ((value->op == OP_INTCONST) && (value_size == 1)) {
9728                                 *((uint8_t *)dest) = value->u.cval & 0xff;
9729                         }
9730                         else if ((value->op == OP_INTCONST) && (value_size == 2)) {
9731                                 *((uint16_t *)dest) = value->u.cval & 0xffff;
9732                         }
9733                         else if ((value->op == OP_INTCONST) && (value_size == 4)) {
9734                                 *((uint32_t *)dest) = value->u.cval & 0xffffffff;
9735                         }
9736                         else {
9737                                 internal_error(state, 0, "unhandled constant initializer");
9738                         }
9739                         free_triple(state, value);
9740                         if (peek(state) == TOK_COMMA) {
9741                                 eat(state, TOK_COMMA);
9742                                 comma = 1;
9743                         }
9744                         info.offset += value_size;
9745                         if ((type->type & TYPE_MASK) == TYPE_STRUCT) {
9746                                 info.type = next_field(state, type, info.type);
9747                                 info.offset = field_offset(state, type, 
9748                                         info.type->field_ident);
9749                         }
9750                 } while(comma && (peek(state) != TOK_RBRACE));
9751                 if ((type->elements == ELEMENT_COUNT_UNSPECIFIED) &&
9752                         ((type->type & TYPE_MASK) == TYPE_ARRAY)) {
9753                         type->elements = max_offset / size_of(state, type->left);
9754                 }
9755                 eat(state, TOK_RBRACE);
9756                 result = triple(state, OP_BLOBCONST, type, 0, 0);
9757                 result->u.blob = buf;
9758         }
9759         return result;
9760 }
9761
9762 static void resolve_branches(struct compile_state *state)
9763 {
9764         /* Make a second pass and finish anything outstanding
9765          * with respect to branches.  The only outstanding item
9766          * is to see if there are goto to labels that have not
9767          * been defined and to error about them.
9768          */
9769         int i;
9770         for(i = 0; i < HASH_TABLE_SIZE; i++) {
9771                 struct hash_entry *entry;
9772                 for(entry = state->hash_table[i]; entry; entry = entry->next) {
9773                         struct triple *ins;
9774                         if (!entry->sym_label) {
9775                                 continue;
9776                         }
9777                         ins = entry->sym_label->def;
9778                         if (!(ins->id & TRIPLE_FLAG_FLATTENED)) {
9779                                 error(state, ins, "label `%s' used but not defined",
9780                                         entry->name);
9781                         }
9782                 }
9783         }
9784 }
9785
9786 static struct triple *function_definition(
9787         struct compile_state *state, struct type *type)
9788 {
9789         struct triple *def, *tmp, *first, *end, *retvar, *ret;
9790         struct hash_entry *ident;
9791         struct type *param;
9792         int i;
9793         if ((type->type &TYPE_MASK) != TYPE_FUNCTION) {
9794                 error(state, 0, "Invalid function header");
9795         }
9796
9797         /* Verify the function type */
9798         if (((type->right->type & TYPE_MASK) != TYPE_VOID)  &&
9799                 ((type->right->type & TYPE_MASK) != TYPE_PRODUCT) &&
9800                 (type->right->field_ident == 0)) {
9801                 error(state, 0, "Invalid function parameters");
9802         }
9803         param = type->right;
9804         i = 0;
9805         while((param->type & TYPE_MASK) == TYPE_PRODUCT) {
9806                 i++;
9807                 if (!param->left->field_ident) {
9808                         error(state, 0, "No identifier for parameter %d\n", i);
9809                 }
9810                 param = param->right;
9811         }
9812         i++;
9813         if (((param->type & TYPE_MASK) != TYPE_VOID) && !param->field_ident) {
9814                 error(state, 0, "No identifier for paramter %d\n", i);
9815         }
9816         
9817         /* Get a list of statements for this function. */
9818         def = triple(state, OP_LIST, type, 0, 0);
9819
9820         /* Start a new scope for the passed parameters */
9821         start_scope(state);
9822
9823         /* Put a label at the very start of a function */
9824         first = label(state);
9825         RHS(def, 0) = first;
9826
9827         /* Put a label at the very end of a function */
9828         end = label(state);
9829         flatten(state, first, end);
9830         /* Remember where return goes */
9831         ident = state->i_return;
9832         symbol(state, ident, &ident->sym_ident, end, end->type);
9833
9834         /* Allocate a variable for the return address */
9835         retvar = variable(state, &void_ptr_type);
9836         retvar = flatten(state, end, retvar);
9837
9838         /* Add in the return instruction */
9839         ret = triple(state, OP_RET, &void_type, read_expr(state, retvar), 0);
9840         ret = flatten(state, first, ret);
9841
9842         /* Walk through the parameters and create symbol table entries
9843          * for them.
9844          */
9845         param = type->right;
9846         while((param->type & TYPE_MASK) == TYPE_PRODUCT) {
9847                 ident = param->left->field_ident;
9848                 tmp = variable(state, param->left);
9849                 symbol(state, ident, &ident->sym_ident, tmp, tmp->type);
9850                 flatten(state, end, tmp);
9851                 param = param->right;
9852         }
9853         if ((param->type & TYPE_MASK) != TYPE_VOID) {
9854                 /* And don't forget the last parameter */
9855                 ident = param->field_ident;
9856                 tmp = variable(state, param);
9857                 symbol(state, ident, &ident->sym_ident, tmp, tmp->type);
9858                 flatten(state, end, tmp);
9859         }
9860         /* Add a variable for the return value */
9861         MISC(def, 0) = 0;
9862         if ((type->left->type & TYPE_MASK) != TYPE_VOID) {
9863                 /* Remove all type qualifiers from the return type */
9864                 tmp = variable(state, clone_type(0, type->left));
9865                 flatten(state, end, tmp);
9866                 /* Remember where the return value is */
9867                 MISC(def, 0) = tmp;
9868         }
9869
9870         /* Remember which function I am compiling.
9871          * Also assume the last defined function is the main function.
9872          */
9873         state->main_function = def;
9874
9875         /* Now get the actual function definition */
9876         compound_statement(state, end);
9877
9878         /* Finish anything unfinished with branches */
9879         resolve_branches(state);
9880
9881         /* Remove the parameter scope */
9882         end_scope(state);
9883
9884
9885         /* Remember I have defined a function */
9886         if (!state->functions) {
9887                 state->functions = def;
9888         } else {
9889                 insert_triple(state, state->functions, def);
9890         }
9891         if (state->compiler->debug & DEBUG_INLINE) {
9892                 fprintf(stdout, "\n");
9893                 loc(stdout, state, 0);
9894                 fprintf(stdout, "\n__________ %s _________\n", __FUNCTION__);
9895                 display_func(stdout, def);
9896                 fprintf(stdout, "__________ %s _________ done\n\n", __FUNCTION__);
9897         }
9898
9899         return def;
9900 }
9901
9902 static struct triple *do_decl(struct compile_state *state, 
9903         struct type *type, struct hash_entry *ident)
9904 {
9905         struct triple *def;
9906         def = 0;
9907         /* Clean up the storage types used */
9908         switch (type->type & STOR_MASK) {
9909         case STOR_AUTO:
9910         case STOR_STATIC:
9911                 /* These are the good types I am aiming for */
9912                 break;
9913         case STOR_REGISTER:
9914                 type->type &= ~STOR_MASK;
9915                 type->type |= STOR_AUTO;
9916                 break;
9917         case STOR_LOCAL:
9918         case STOR_EXTERN:
9919                 type->type &= ~STOR_MASK;
9920                 type->type |= STOR_STATIC;
9921                 break;
9922         case STOR_TYPEDEF:
9923                 if (!ident) {
9924                         error(state, 0, "typedef without name");
9925                 }
9926                 symbol(state, ident, &ident->sym_ident, 0, type);
9927                 ident->tok = TOK_TYPE_NAME;
9928                 return 0;
9929                 break;
9930         default:
9931                 internal_error(state, 0, "Undefined storage class");
9932         }
9933         if ((type->type & TYPE_MASK) == TYPE_FUNCTION) {
9934                 error(state, 0, "Function prototypes not supported");
9935         }
9936         if (ident && 
9937                 ((type->type & STOR_MASK) == STOR_STATIC) &&
9938                 ((type->type & QUAL_CONST) == 0)) {
9939                 error(state, 0, "non const static variables not supported");
9940         }
9941         if (ident) {
9942                 def = variable(state, type);
9943                 symbol(state, ident, &ident->sym_ident, def, type);
9944         }
9945         return def;
9946 }
9947
9948 static void decl(struct compile_state *state, struct triple *first)
9949 {
9950         struct type *base_type, *type;
9951         struct hash_entry *ident;
9952         struct triple *def;
9953         int global;
9954         global = (state->scope_depth <= GLOBAL_SCOPE_DEPTH);
9955         base_type = decl_specifiers(state);
9956         ident = 0;
9957         type = declarator(state, base_type, &ident, 0);
9958         if (global && ident && (peek(state) == TOK_LBRACE)) {
9959                 /* function */
9960                 type->type_ident = ident;
9961                 state->function = ident->name;
9962                 def = function_definition(state, type);
9963                 symbol(state, ident, &ident->sym_ident, def, type);
9964                 state->function = 0;
9965         }
9966         else {
9967                 int done;
9968                 flatten(state, first, do_decl(state, type, ident));
9969                 /* type or variable definition */
9970                 do {
9971                         done = 1;
9972                         if (peek(state) == TOK_EQ) {
9973                                 if (!ident) {
9974                                         error(state, 0, "cannot assign to a type");
9975                                 }
9976                                 eat(state, TOK_EQ);
9977                                 flatten(state, first,
9978                                         init_expr(state, 
9979                                                 ident->sym_ident->def, 
9980                                                 initializer(state, type)));
9981                         }
9982                         arrays_complete(state, type);
9983                         if (peek(state) == TOK_COMMA) {
9984                                 eat(state, TOK_COMMA);
9985                                 ident = 0;
9986                                 type = declarator(state, base_type, &ident, 0);
9987                                 flatten(state, first, do_decl(state, type, ident));
9988                                 done = 0;
9989                         }
9990                 } while(!done);
9991                 eat(state, TOK_SEMI);
9992         }
9993 }
9994
9995 static void decls(struct compile_state *state)
9996 {
9997         struct triple *list;
9998         int tok;
9999         list = label(state);
10000         while(1) {
10001                 tok = peek(state);
10002                 if (tok == TOK_EOF) {
10003                         return;
10004                 }
10005                 if (tok == TOK_SPACE) {
10006                         eat(state, TOK_SPACE);
10007                 }
10008                 decl(state, list);
10009                 if (list->next != list) {
10010                         error(state, 0, "global variables not supported");
10011                 }
10012         }
10013 }
10014
10015 /* 
10016  * Function inlining
10017  */
10018
10019 static struct triple *call(struct compile_state *state,
10020         struct triple *retvar, struct triple *ret_addr, 
10021         struct triple *targ, struct triple *ret)
10022 {
10023         struct triple *call;
10024
10025         if (!retvar || !is_lvalue(state, retvar)) {
10026                 internal_error(state, 0, "writing to a non lvalue?");
10027         }
10028         write_compatible(state, retvar->type, &void_ptr_type);
10029
10030         call = new_triple(state, OP_CALL, &void_type, 1, 0);
10031         TARG(call, 0) = targ;
10032         MISC(call, 0) = ret;
10033         if (!targ || (targ->op != OP_LABEL)) {
10034                 internal_error(state, 0, "call not to a label");
10035         }
10036         if (!ret || (ret->op != OP_RET)) {
10037                 internal_error(state, 0, "call not matched with return");
10038         }
10039         return call;
10040 }
10041
10042 static void mark_live_functions(struct compile_state *state, struct triple *first)
10043 {
10044         struct triple *ptr;
10045         ptr = first;
10046         do {
10047                 if (ptr->op == OP_FCALL) {
10048                         struct triple *func;
10049                         func = MISC(ptr, 0);
10050                         if (func->u.cval++ == 0) {
10051                                 mark_live_functions(state, RHS(func, 0));
10052                         }
10053                 }
10054                 ptr = ptr->next;
10055         } while(ptr != first);
10056 }
10057
10058 static void walk_functions(struct compile_state *state,
10059         void (*cb)(struct compile_state *state, struct triple *func, void *arg),
10060         void *arg)
10061 {
10062         struct triple *func, *first;
10063         func = first = state->functions;
10064         do {
10065                 cb(state, func, arg);
10066                 func = func->next;
10067         } while(func != first);
10068 }
10069
10070
10071 static int local_triple(struct compile_state *state, 
10072         struct triple *func, struct triple *ins)
10073 {
10074         int local = (ins->id & TRIPLE_FLAG_LOCAL);
10075 #if 0
10076         if (!local) {
10077                 fprintf(stderr, "global: ");
10078                 display_triple(stderr, ins);
10079         }
10080 #endif
10081         return local;
10082 }
10083
10084 struct triple *copy_func(struct compile_state *state, struct triple *ofunc, 
10085         struct occurance *base_occurance)
10086 {
10087         struct triple *nfunc;
10088         struct triple *nfirst, *ofirst;
10089         struct triple *new, *old;
10090
10091         if (state->compiler->debug & DEBUG_INLINE) {
10092                 fprintf(stdout, "\n");
10093                 loc(stdout, state, 0);
10094                 fprintf(stdout, "\n__________ %s _________\n", __FUNCTION__);
10095                 display_func(stdout, ofunc);
10096                 fprintf(stdout, "__________ %s _________ done\n\n", __FUNCTION__);
10097         }
10098
10099         /* Make a new copy of the old function */
10100         nfunc = triple(state, OP_LIST, ofunc->type, 0, 0);
10101         nfirst = 0;
10102         ofirst = old = RHS(ofunc, 0);
10103         do {
10104                 struct triple *new;
10105                 struct occurance *occurance;
10106                 int old_lhs, old_rhs;
10107                 old_lhs = TRIPLE_LHS(old->sizes);
10108                 old_rhs = TRIPLE_RHS(old->sizes);
10109                 occurance = inline_occurance(state, base_occurance, old->occurance);
10110                 if (ofunc->u.cval && (old->op == OP_FCALL)) {
10111                         MISC(old, 0)->u.cval += 1;
10112                 }
10113                 new = alloc_triple(state, old->op, old->type, old_lhs, old_rhs,
10114                         occurance);
10115                 if (!triple_stores_block(state, new)) {
10116                         memcpy(&new->u, &old->u, sizeof(new->u));
10117                 }
10118                 if (!nfirst) {
10119                         RHS(nfunc, 0) = nfirst = new;
10120                 }
10121                 else {
10122                         insert_triple(state, nfirst, new);
10123                 }
10124                 new->id |= TRIPLE_FLAG_FLATTENED;
10125                 
10126                 /* During the copy remember new as user of old */
10127                 use_triple(old, new);
10128
10129                 /* Populate the return type if present */
10130                 if (old == MISC(ofunc, 0)) {
10131                         MISC(nfunc, 0) = new;
10132                 }
10133                 /* Remember which instructions are local */
10134                 old->id |= TRIPLE_FLAG_LOCAL;
10135                 old = old->next;
10136         } while(old != ofirst);
10137
10138         /* Make a second pass to fix up any unresolved references */
10139         old = ofirst;
10140         new = nfirst;
10141         do {
10142                 struct triple **oexpr, **nexpr;
10143                 int count, i;
10144                 /* Lookup where the copy is, to join pointers */
10145                 count = TRIPLE_SIZE(old->sizes);
10146                 for(i = 0; i < count; i++) {
10147                         oexpr = &old->param[i];
10148                         nexpr = &new->param[i];
10149                         if (*oexpr && !*nexpr) {
10150                                 if (!local_triple(state, ofunc, *oexpr)) {
10151                                         *nexpr = *oexpr;
10152                                 }
10153                                 else if ((*oexpr)->use) {
10154                                         *nexpr = (*oexpr)->use->member;
10155                                 }
10156                                 if (*nexpr == old) {
10157                                         internal_error(state, 0, "new == old?");
10158                                 }
10159                                 use_triple(*nexpr, new);
10160                         }
10161                         if (!*nexpr && *oexpr) {
10162                                 internal_error(state, 0, "Could not copy %d\n", i);
10163                         }
10164                 }
10165                 old = old->next;
10166                 new = new->next;
10167         } while((old != ofirst) && (new != nfirst));
10168         
10169         /* Make a third pass to cleanup the extra useses */
10170         old = ofirst;
10171         new = nfirst;
10172         do {
10173                 unuse_triple(old, new);
10174                 /* Forget which instructions are local */
10175                 old->id &= ~TRIPLE_FLAG_LOCAL;
10176                 old = old->next;
10177                 new = new->next;
10178         } while ((old != ofirst) && (new != nfirst));
10179         return nfunc;
10180 }
10181
10182 static struct triple *flatten_inline_call(
10183         struct compile_state *state, struct triple *first, struct triple *ptr)
10184 {
10185         /* Inline the function call */
10186         struct type *ptype;
10187         struct triple *ofunc, *nfunc, *nfirst, *param, *result;
10188         struct triple *end, *nend;
10189         int pvals, i;
10190
10191         /* Find the triples */
10192         ofunc = MISC(ptr, 0);
10193         if (ofunc->op != OP_LIST) {
10194                 internal_error(state, 0, "improper function");
10195         }
10196         nfunc = copy_func(state, ofunc, ptr->occurance);
10197         nfirst = RHS(nfunc, 0)->next->next;
10198         /* Prepend the parameter reading into the new function list */
10199         ptype = nfunc->type->right;
10200         param = RHS(nfunc, 0)->next->next;
10201         pvals = TRIPLE_RHS(ptr->sizes);
10202         for(i = 0; i < pvals; i++) {
10203                 struct type *atype;
10204                 struct triple *arg;
10205                 atype = ptype;
10206                 if ((ptype->type & TYPE_MASK) == TYPE_PRODUCT) {
10207                         atype = ptype->left;
10208                 }
10209                 while((param->type->type & TYPE_MASK) != (atype->type & TYPE_MASK)) {
10210                         param = param->next;
10211                 }
10212                 arg = RHS(ptr, i);
10213                 flatten(state, nfirst, write_expr(state, param, arg));
10214                 ptype = ptype->right;
10215                 param = param->next;
10216         }
10217         result = 0;
10218         if ((nfunc->type->left->type & TYPE_MASK) != TYPE_VOID) {
10219                 result = read_expr(state, MISC(nfunc,0));
10220         }
10221         if (state->compiler->debug & DEBUG_INLINE) {
10222                 fprintf(stdout, "\n");
10223                 loc(stdout, state, 0);
10224                 fprintf(stdout, "\n__________ %s _________\n", __FUNCTION__);
10225                 display_func(stdout, nfunc);
10226                 fprintf(stdout, "__________ %s _________ done\n\n", __FUNCTION__);
10227         }
10228
10229         /* Get rid of the extra triples */
10230         nfirst = RHS(nfunc, 0)->next->next;
10231         release_triple(state, RHS(nfunc, 0)->prev->prev);
10232         release_triple(state, RHS(nfunc, 0)->prev);
10233         release_triple(state, RHS(nfunc, 0)->next);
10234         free_triple(state, RHS(nfunc, 0));
10235         RHS(nfunc, 0) = 0;
10236         free_triple(state, nfunc);
10237
10238         /* Append the new function list onto the return list */
10239         end = first->prev;
10240         nend = nfirst->prev;
10241         end->next    = nfirst;
10242         nfirst->prev = end;
10243         nend->next   = first;
10244         first->prev  = nend;
10245
10246         return result;
10247 }
10248
10249 static struct triple *flatten_function_call(
10250         struct compile_state *state, struct triple *first, struct triple *ptr)
10251 {
10252         /* Generate an ordinary function call */
10253         struct triple *func, *func_first, *func_last, *retvar;
10254         struct type *ptype;
10255         struct triple *param;
10256         struct triple *jmp;
10257         struct triple *ret_addr, *ret_loc, *ret_set;
10258         struct triple *result;
10259         int pvals, i;
10260
10261         FINISHME();
10262         /* Find the triples */
10263         func = MISC(ptr, 0);
10264         func_first = RHS(func, 0);
10265         retvar = func_first->next;
10266         func_last  = func_first->prev;
10267
10268         /* Generate some needed triples */
10269         ret_loc = label(state);
10270         ret_addr = triple(state, OP_ADDRCONST, &void_ptr_type, ret_loc, 0);
10271
10272         /* Pass the parameters to the new function */
10273         ptype = func->type->right;
10274         param = func_first->next->next;
10275         pvals = TRIPLE_RHS(ptr->sizes);
10276         for(i = 0; i < pvals; i++) {
10277                 struct type *atype;
10278                 struct triple *arg;
10279                 atype = ptype;
10280                 if ((ptype->type & TYPE_MASK) == TYPE_PRODUCT) {
10281                         atype = ptype->left;
10282                 }
10283                 while((param->type->type & TYPE_MASK) != (atype->type & TYPE_MASK)) {
10284                         param = param->next;
10285                 }
10286                 arg = RHS(ptr, i);
10287                 flatten(state, first, write_expr(state, param, arg));
10288                 ptype = ptype->right;
10289                 param = param->next;
10290         }
10291        
10292         /* Thread the triples together */
10293         ret_loc       = flatten(state, first, ret_loc);
10294         ret_addr      = flatten(state, ret_loc, ret_addr);
10295         ret_set       = flatten(state, ret_loc, write_expr(state, retvar, ret_addr));
10296         jmp           = flatten(state, ret_loc, 
10297                 call(state, retvar, ret_addr, func_first, func_last));
10298
10299         /* Find the result */
10300         result = 0;
10301         if ((func->type->left->type & TYPE_MASK) != TYPE_VOID) {
10302                 result = read_expr(state, MISC(func, 0));
10303         }
10304
10305         if (state->compiler->debug & DEBUG_INLINE) {
10306                 fprintf(stdout, "\n");
10307                 loc(stdout, state, 0);
10308                 fprintf(stdout, "\n__________ %s _________\n", __FUNCTION__);
10309                 display_func(stdout, func);
10310                 fprintf(stdout, "__________ %s _________ done\n\n", __FUNCTION__);
10311         }
10312
10313         return result;
10314 }
10315
10316 static void inline_functions(struct compile_state *state, struct triple *first)
10317 {
10318         struct triple *ptr, *next;
10319         ptr = next = first;
10320         do {
10321                 int do_inline;
10322                 struct triple *func, *prev, *new;
10323                 ptr = next;
10324                 prev = ptr->prev;
10325                 next = ptr->next;
10326                 if (ptr->op != OP_FCALL) {
10327                         continue;
10328                 }
10329                 func = MISC(ptr, 0);
10330                 /* See if the function should be inlined */
10331                 switch(func->type->type & STOR_MASK) {
10332                 case STOR_STATIC | STOR_INLINE:
10333                 case STOR_LOCAL  | STOR_INLINE:
10334                 case STOR_EXTERN | STOR_INLINE:
10335                         do_inline = 1;
10336                         break;
10337                 default:
10338                         do_inline = (func->u.cval == 1);
10339                         break;
10340                 }
10341                 if (state->compiler->flags & COMPILER_ALWAYS_INLINE) {
10342                         do_inline = 1;
10343                 }
10344                 if (!(state->compiler->flags & COMPILER_INLINE)) {
10345                         do_inline = 0;
10346                 }
10347                 if (!do_inline) {
10348                         continue;
10349                 }
10350                 if (state->compiler->debug & DEBUG_INLINE) {
10351                         fprintf(stderr, "inlining %s\n",
10352                                 func->type->type_ident->name);
10353                 }
10354
10355                 /* Update the function use counts */
10356                 func->u.cval -= 1;
10357                 /* Unhook the call and really inline it */
10358                 next->prev = prev;
10359                 prev->next = next;
10360                 ptr->next = ptr->prev = ptr;
10361                 
10362                 new = flatten(state, next, 
10363                         flatten_inline_call(state, next, ptr));
10364                 if (new) {
10365                         propogate_use(state, ptr, new);
10366                 }
10367                 release_triple(state, ptr);
10368                 next = prev->next;
10369         } while (next != first);
10370         ptr = next = first;
10371         do {
10372                 struct triple *func, *prev, *new;
10373                 ptr = next;
10374                 prev = ptr->prev;
10375                 next = ptr->next;
10376                 if (ptr->op != OP_FCALL) {
10377                         continue;
10378                 }
10379                 func = MISC(ptr, 0);
10380                 inline_functions(state, RHS(func, 0));
10381                 /* Unhook the call and really flatten it */
10382                 next->prev = prev;
10383                 prev->next = next;
10384                 ptr->next = ptr->prev = ptr;
10385                 new = flatten(state, next, 
10386                         flatten_function_call(state, next, ptr));
10387                 if (new) {
10388                         propogate_use(state, ptr, new);
10389                 }
10390                 release_triple(state, ptr);
10391                 next = prev->next;
10392         } while(next != first);
10393 }
10394         
10395 static void insert_function(struct compile_state *state,
10396         struct triple *func, void *arg)
10397 {
10398         struct triple *first, *end, *ffirst, *fend;
10399
10400         if (state->compiler->debug & DEBUG_INLINE) {
10401                 fprintf(stderr, "%s func count: %d\n", 
10402                         func->type->type_ident->name, func->u.cval);
10403         }
10404         if (func->u.cval == 0) {
10405                 return;
10406         }
10407         if (state->compiler->flags & COMPILER_ALWAYS_INLINE) {
10408                 internal_error(state, func, "always inline failed\n");
10409         }
10410
10411         /* Find the end points of the lists */
10412         first  = arg;
10413         end    = first->prev;
10414         ffirst = RHS(func, 0);
10415         fend   = ffirst->prev;
10416
10417         /* splice the lists together */
10418         end->next    = ffirst;
10419         ffirst->prev = end;
10420         fend->next   = first;
10421         first->prev  = fend;
10422 }
10423
10424 static void join_functions(struct compile_state *state)
10425 {
10426         struct triple *jmp, *start, *end, *call;
10427         struct file_state file;
10428
10429         /* Dummy file state to get debug handing right */
10430         memset(&file, 0, sizeof(file));
10431         file.basename = "";
10432         file.line = 0;
10433         file.report_line = 0;
10434         file.report_name = file.basename;
10435         file.prev = state->file;
10436         state->file = &file;
10437         state->function = "";
10438         
10439         /* Lay down the basic program structure */
10440         end = label(state);
10441         start = label(state);
10442         start = flatten(state, state->first, start);
10443         end = flatten(state, state->first, end);
10444         call = new_triple(state, OP_FCALL, &void_type, -1, 0);
10445         MISC(call, 0) = state->main_function;
10446         flatten(state, state->first, call);
10447         
10448         /* See which functions are called, and how often */
10449         mark_live_functions(state, state->first);
10450         inline_functions(state, state->first);
10451         walk_functions(state, insert_function, end);
10452
10453         if (start->next != end) {
10454                 jmp = flatten(state, start, branch(state, end, 0));
10455         }
10456
10457         /* Done now cleanup */
10458         state->file = file.prev;
10459         state->function = 0;
10460 }
10461
10462 /*
10463  * Data structurs for optimation.
10464  */
10465
10466
10467 static int do_use_block(
10468         struct block *used, struct block_set **head, struct block *user, 
10469         int front)
10470 {
10471         struct block_set **ptr, *new;
10472         if (!used)
10473                 return 0;
10474         if (!user)
10475                 return 0;
10476         ptr = head;
10477         while(*ptr) {
10478                 if ((*ptr)->member == user) {
10479                         return 0;
10480                 }
10481                 ptr = &(*ptr)->next;
10482         }
10483         new = xcmalloc(sizeof(*new), "block_set");
10484         new->member = user;
10485         if (front) {
10486                 new->next = *head;
10487                 *head = new;
10488         }
10489         else {
10490                 new->next = 0;
10491                 *ptr = new;
10492         }
10493         return 1;
10494 }
10495 static int do_unuse_block(
10496         struct block *used, struct block_set **head, struct block *unuser)
10497 {
10498         struct block_set *use, **ptr;
10499         int count;
10500         count = 0;
10501         ptr = head;
10502         while(*ptr) {
10503                 use = *ptr;
10504                 if (use->member == unuser) {
10505                         *ptr = use->next;
10506                         memset(use, -1, sizeof(*use));
10507                         xfree(use);
10508                         count += 1;
10509                 }
10510                 else {
10511                         ptr = &use->next;
10512                 }
10513         }
10514         return count;
10515 }
10516
10517 static void use_block(struct block *used, struct block *user)
10518 {
10519         int count;
10520         /* Append new to the head of the list, print_block
10521          * depends on this.
10522          */
10523         count = do_use_block(used, &used->use, user, 1); 
10524         used->users += count;
10525 }
10526 static void unuse_block(struct block *used, struct block *unuser)
10527 {
10528         int count;
10529         count = do_unuse_block(used, &used->use, unuser); 
10530         used->users -= count;
10531 }
10532
10533 static void add_block_edge(struct block *block, struct block *edge, int front)
10534 {
10535         int count;
10536         count = do_use_block(block, &block->edges, edge, front);
10537         block->edge_count += count;
10538 }
10539
10540 static void remove_block_edge(struct block *block, struct block *edge)
10541 {
10542         int count;
10543         count = do_unuse_block(block, &block->edges, edge);
10544         block->edge_count -= count;
10545 }
10546
10547 static void idom_block(struct block *idom, struct block *user)
10548 {
10549         do_use_block(idom, &idom->idominates, user, 0);
10550 }
10551
10552 static void unidom_block(struct block *idom, struct block *unuser)
10553 {
10554         do_unuse_block(idom, &idom->idominates, unuser);
10555 }
10556
10557 static void domf_block(struct block *block, struct block *domf)
10558 {
10559         do_use_block(block, &block->domfrontier, domf, 0);
10560 }
10561
10562 static void undomf_block(struct block *block, struct block *undomf)
10563 {
10564         do_unuse_block(block, &block->domfrontier, undomf);
10565 }
10566
10567 static void ipdom_block(struct block *ipdom, struct block *user)
10568 {
10569         do_use_block(ipdom, &ipdom->ipdominates, user, 0);
10570 }
10571
10572 static void unipdom_block(struct block *ipdom, struct block *unuser)
10573 {
10574         do_unuse_block(ipdom, &ipdom->ipdominates, unuser);
10575 }
10576
10577 static void ipdomf_block(struct block *block, struct block *ipdomf)
10578 {
10579         do_use_block(block, &block->ipdomfrontier, ipdomf, 0);
10580 }
10581
10582 static void unipdomf_block(struct block *block, struct block *unipdomf)
10583 {
10584         do_unuse_block(block, &block->ipdomfrontier, unipdomf);
10585 }
10586
10587 static int walk_triples(
10588         struct compile_state *state, 
10589         int (*cb)(struct compile_state *state, struct triple *ptr))
10590 {
10591         struct triple *ptr;
10592         int result;
10593         ptr = state->first;
10594         do {
10595                 result = cb(state, ptr);
10596                 if (ptr->next->prev != ptr) {
10597                         internal_error(state, ptr->next, "bad prev");
10598                 }
10599                 ptr = ptr->next;
10600         } while((result == 0) && (ptr != state->first));
10601         return result;
10602 }
10603
10604 #define PRINT_LIST 1
10605 static int do_print_triple(struct compile_state *state, struct triple *ins)
10606 {
10607         int op;
10608         op = ins->op;
10609         if (op == OP_LIST) {
10610 #if !PRINT_LIST
10611                 return 0;
10612 #endif
10613         }
10614         if ((op == OP_LABEL) && (ins->use)) {
10615                 printf("\n%p:\n", ins);
10616         }
10617         display_triple(stdout, ins);
10618
10619         if (triple_is_branch(state, ins) && ins->use && (ins->op != OP_RET)) {
10620                 internal_error(state, ins, "branch used?");
10621         }
10622         if (triple_is_branch(state, ins)) {
10623                 printf("\n");
10624         }
10625         return 0;
10626 }
10627
10628 static void print_triples(struct compile_state *state)
10629 {
10630         if (state->compiler->debug & DEBUG_TRIPLES) {
10631                 walk_triples(state, do_print_triple);
10632         }
10633 }
10634
10635 struct cf_block {
10636         struct block *block;
10637 };
10638 static void find_cf_blocks(struct cf_block *cf, struct block *block)
10639 {
10640         struct block_set *edge;
10641         if (!block || (cf[block->vertex].block == block)) {
10642                 return;
10643         }
10644         cf[block->vertex].block = block;
10645         for(edge = block->edges; edge; edge = edge->next) {
10646                 find_cf_blocks(cf, edge->member);
10647         }
10648 }
10649
10650 static void print_control_flow(struct compile_state *state)
10651 {
10652         struct cf_block *cf;
10653         int i;
10654         printf("\ncontrol flow\n");
10655         cf = xcmalloc(sizeof(*cf) * (state->last_vertex + 1), "cf_block");
10656         find_cf_blocks(cf, state->first_block);
10657
10658         for(i = 1; i <= state->last_vertex; i++) {
10659                 struct block *block;
10660                 struct block_set *edge;
10661                 block = cf[i].block;
10662                 if (!block)
10663                         continue;
10664                 printf("(%p) %d:", block, block->vertex);
10665                 for(edge = block->edges; edge; edge = edge->next) {
10666                         printf(" %d", edge->member->vertex);
10667                 }
10668                 printf("\n");
10669         }
10670
10671         xfree(cf);
10672 }
10673
10674
10675 static struct block *basic_block(struct compile_state *state, struct triple *first)
10676 {
10677         struct block *block;
10678         struct triple *ptr;
10679         if (first->op != OP_LABEL) {
10680                 internal_error(state, 0, "block does not start with a label");
10681         }
10682         /* See if this basic block has already been setup */
10683         if (first->u.block != 0) {
10684                 return first->u.block;
10685         }
10686         /* Allocate another basic block structure */
10687         state->last_vertex += 1;
10688         block = xcmalloc(sizeof(*block), "block");
10689         block->first = block->last = first;
10690         block->vertex = state->last_vertex;
10691         ptr = first;
10692         do {
10693                 if ((ptr != first) && (ptr->op == OP_LABEL) && (ptr->use)) { 
10694                         break;
10695                 }
10696                 block->last = ptr;
10697                 /* If ptr->u is not used remember where the baic block is */
10698                 if (triple_stores_block(state, ptr)) {
10699                         ptr->u.block = block;
10700                 }
10701                 if (triple_is_branch(state, ptr)) {
10702                         break;
10703                 }
10704                 ptr = ptr->next;
10705         } while (ptr != state->first);
10706         if (ptr == state->first) {
10707                 /* The block has no outflowing edges */
10708         }
10709         else if (ptr->op == OP_LABEL) {
10710                 struct block *next;
10711                 next = basic_block(state, ptr);
10712                 add_block_edge(block, next, 0);
10713                 use_block(next, block);
10714         }
10715         else if (triple_is_branch(state, ptr)) {
10716                 struct triple **expr, *first;
10717                 struct block *child;
10718                 /* Find the branch targets.
10719                  * I special case the first branch as that magically
10720                  * avoids some difficult cases for the register allocator.
10721                  */
10722                 expr = triple_targ(state, ptr, 0);
10723                 if (!expr) {
10724                         internal_error(state, ptr, "branch without targets");
10725                 }
10726                 first = *expr;
10727                 expr = triple_targ(state, ptr, expr);
10728                 for(; expr; expr = triple_targ(state, ptr, expr)) {
10729                         if (!*expr) continue;
10730                         child = basic_block(state, *expr);
10731                         use_block(child, block);
10732                         add_block_edge(block, child, 0);
10733                 }
10734                 if (first) {
10735                         child = basic_block(state, first);
10736                         use_block(child, block);
10737                         add_block_edge(block, child, 1);
10738                 }
10739         }
10740         else {
10741                 internal_error(state, 0, "Bad basic block split");
10742         }
10743 #if 0
10744 {
10745         struct block_set *edge;
10746         fprintf(stderr, "basic_block: %10p [%2d] ( %10p - %10p )",
10747                 block, block->vertex, 
10748                 block->first, block->last);
10749         for(edge = block->edges; edge; edge = edge->next) {
10750                 fprintf(stderr, " %10p [%2d]",
10751                         edge->member ? edge->member->first : 0,
10752                         edge->member ? edge->member->vertex : -1);
10753         }
10754         fprintf(stderr, "\n");
10755 }
10756 #endif
10757         return block;
10758 }
10759
10760
10761 static void walk_blocks(struct compile_state *state,
10762         void (*cb)(struct compile_state *state, struct block *block, void *arg),
10763         void *arg)
10764 {
10765         struct triple *ptr, *first;
10766         struct block *last_block;
10767         last_block = 0;
10768         first = state->first;
10769         ptr = first;
10770         do {
10771                 if (triple_stores_block(state, ptr)) {
10772                         struct block *block;
10773                         block = ptr->u.block;
10774                         if (block && (block != last_block)) {
10775                                 cb(state, block, arg);
10776                         }
10777                         last_block = block;
10778                 }
10779                 ptr = ptr->next;
10780         } while(ptr != first);
10781 }
10782
10783 static void print_block(
10784         struct compile_state *state, struct block *block, void *arg)
10785 {
10786         struct block_set *user, *edge;
10787         struct triple *ptr;
10788         FILE *fp = arg;
10789
10790         fprintf(fp, "\nblock: %p (%d) ",
10791                 block, 
10792                 block->vertex);
10793
10794         for(edge = block->edges; edge; edge = edge->next) {
10795                 fprintf(fp, " %p<-%p",
10796                         edge->member,
10797                         (edge->member && edge->member->use)?
10798                         edge->member->use->member : 0);
10799         }
10800         fprintf(fp, "\n");
10801         if (block->first->op == OP_LABEL) {
10802                 fprintf(fp, "%p:\n", block->first);
10803         }
10804         for(ptr = block->first; ; ptr = ptr->next) {
10805                 display_triple(fp, ptr);
10806                 if (ptr == block->last)
10807                         break;
10808         }
10809         fprintf(fp, "users %d: ", block->users);
10810         for(user = block->use; user; user = user->next) {
10811                 fprintf(fp, "%p (%d) ", 
10812                         user->member,
10813                         user->member->vertex);
10814         }
10815         fprintf(fp,"\n\n");
10816 }
10817
10818
10819 static void romcc_print_blocks(struct compile_state *state, FILE *fp)
10820 {
10821         fprintf(fp, "--------------- blocks ---------------\n");
10822         walk_blocks(state, print_block, fp);
10823 }
10824 static void print_blocks(struct compile_state *state, const char *func, FILE *fp)
10825 {
10826         if (state->compiler->debug & DEBUG_BASIC_BLOCKS) {
10827                 fprintf(fp, "After %s\n", func);
10828                 romcc_print_blocks(state, fp);
10829                 print_control_flow(state);
10830         }
10831 }
10832
10833 static void prune_nonblock_triples(struct compile_state *state)
10834 {
10835         struct block *block;
10836         struct triple *first, *ins, *next;
10837         /* Delete the triples not in a basic block */
10838         first = state->first;
10839         block = 0;
10840         ins = first;
10841         do {
10842                 next = ins->next;
10843                 if (ins->op == OP_LABEL) {
10844                         block = ins->u.block;
10845                 }
10846                 if (!block) {
10847                         release_triple(state, ins);
10848                 }
10849                 if (block && block->last == ins) {
10850                         block = 0;
10851                 }
10852                 ins = next;
10853         } while(ins != first);
10854 }
10855
10856 static void setup_basic_blocks(struct compile_state *state)
10857 {
10858         if (!triple_stores_block(state, state->first)) {
10859                 internal_error(state, 0, "ins will not store block?");
10860         }
10861         /* Find the basic blocks */
10862         state->last_vertex = 0;
10863         state->first_block = basic_block(state, state->first);
10864         /* Delete the triples not in a basic block */
10865         prune_nonblock_triples(state);
10866
10867         /* Find the last basic block.
10868          *
10869          * For purposes of reverse flow computation it is
10870          * important that the last basic block is empty.
10871          * This allows the control flow graph to be modified to
10872          * have one unique starting block and one unique final block.
10873          * With the insertion of a few extra edges.
10874          *
10875          * If the final block contained instructions it could contain
10876          * phi functions from edges that would never contribute a
10877          * value.  Which for now at least I consider a compile error.
10878          */
10879         state->last_block = block_of_triple(state, state->first->prev);
10880         if ((state->last_block->first != state->last_block->last) ||
10881                 (state->last_block->last->op != OP_LABEL))
10882         {
10883                 struct block *block, *prev_block;
10884                 struct triple *final;
10885
10886                 prev_block = state->last_block;
10887                 
10888                 final = label(state);
10889                 flatten(state, state->first, final);
10890                 final->id |= TRIPLE_FLAG_VOLATILE;
10891                 use_triple(final, final);
10892                 block = basic_block(state, final);
10893
10894                 state->last_block = block;
10895
10896                 add_block_edge(prev_block, block, 0);
10897                 use_block(block, prev_block);
10898         }
10899
10900 #if 0
10901         /* If we are debugging print what I have just done */
10902         if (state->compiler->debug & DEBUG_BASIC_BLOCKS) {
10903                 print_blocks(state, stdout);
10904                 print_control_flow(state);
10905         }
10906 #endif
10907 }
10908
10909 static void free_basic_block(struct compile_state *state, struct block *block)
10910 {
10911         struct block_set *edge, *entry;
10912         struct block *child;
10913         if (!block) {
10914                 return;
10915         }
10916         if (block->vertex == -1) {
10917                 return;
10918         }
10919         block->vertex = -1;
10920         for(edge = block->edges; edge; edge = edge->next) {
10921                 if (edge->member) {
10922                         unuse_block(edge->member, block);
10923                 }
10924         }
10925         if (block->idom) {
10926                 unidom_block(block->idom, block);
10927         }
10928         block->idom = 0;
10929         if (block->ipdom) {
10930                 unipdom_block(block->ipdom, block);
10931         }
10932         block->ipdom = 0;
10933         while((entry = block->use)) {
10934                 child = entry->member;
10935                 unuse_block(block, child);
10936                 if (child && (child->vertex != -1)) {
10937                         for(edge = child->edges; edge; edge = edge->next) {
10938                                 edge->member = 0;
10939                         }
10940                 }
10941         }
10942         while((entry = block->idominates)) {
10943                 child = entry->member;
10944                 unidom_block(block, child);
10945                 if (child && (child->vertex != -1)) {
10946                         child->idom = 0;
10947                 }
10948         }
10949         while((entry = block->domfrontier)) {
10950                 child = entry->member;
10951                 undomf_block(block, child);
10952         }
10953         while((entry = block->ipdominates)) {
10954                 child = entry->member;
10955                 unipdom_block(block, child);
10956                 if (child && (child->vertex != -1)) {
10957                         child->ipdom = 0;
10958                 }
10959         }
10960         while((entry = block->ipdomfrontier)) {
10961                 child = entry->member;
10962                 unipdomf_block(block, child);
10963         }
10964         if (block->users != 0) {
10965                 internal_error(state, 0, "block still has users");
10966         }
10967         while((edge = block->edges)) {
10968                 child = edge->member;
10969                 remove_block_edge(block, child);
10970                 
10971                 if (child && (child->vertex != -1)) {
10972                         free_basic_block(state, child);
10973                 }
10974         }
10975         memset(block, -1, sizeof(*block));
10976         xfree(block);
10977 }
10978
10979 static void free_basic_blocks(struct compile_state *state)
10980 {
10981         struct triple *first, *ins;
10982         free_basic_block(state, state->first_block);
10983         state->last_vertex = 0;
10984         state->first_block = state->last_block = 0;
10985         first = state->first;
10986         ins = first;
10987         do {
10988                 if (triple_stores_block(state, ins)) {
10989                         ins->u.block = 0;
10990                 }
10991                 ins = ins->next;
10992         } while(ins != first);
10993         
10994 }
10995
10996 struct sdom_block {
10997         struct block *block;
10998         struct sdom_block *sdominates;
10999         struct sdom_block *sdom_next;
11000         struct sdom_block *sdom;
11001         struct sdom_block *label;
11002         struct sdom_block *parent;
11003         struct sdom_block *ancestor;
11004         int vertex;
11005 };
11006
11007
11008 static void unsdom_block(struct sdom_block *block)
11009 {
11010         struct sdom_block **ptr;
11011         if (!block->sdom_next) {
11012                 return;
11013         }
11014         ptr = &block->sdom->sdominates;
11015         while(*ptr) {
11016                 if ((*ptr) == block) {
11017                         *ptr = block->sdom_next;
11018                         return;
11019                 }
11020                 ptr = &(*ptr)->sdom_next;
11021         }
11022 }
11023
11024 static void sdom_block(struct sdom_block *sdom, struct sdom_block *block)
11025 {
11026         unsdom_block(block);
11027         block->sdom = sdom;
11028         block->sdom_next = sdom->sdominates;
11029         sdom->sdominates = block;
11030 }
11031
11032
11033
11034 static int initialize_sdblock(struct sdom_block *sd,
11035         struct block *parent, struct block *block, int vertex)
11036 {
11037         struct block_set *edge;
11038         if (!block || (sd[block->vertex].block == block)) {
11039                 return vertex;
11040         }
11041         vertex += 1;
11042         /* Renumber the blocks in a convinient fashion */
11043         block->vertex = vertex;
11044         sd[vertex].block    = block;
11045         sd[vertex].sdom     = &sd[vertex];
11046         sd[vertex].label    = &sd[vertex];
11047         sd[vertex].parent   = parent? &sd[parent->vertex] : 0;
11048         sd[vertex].ancestor = 0;
11049         sd[vertex].vertex   = vertex;
11050         for(edge = block->edges; edge; edge = edge->next) {
11051                 vertex = initialize_sdblock(sd, block, edge->member, vertex);
11052         }
11053         return vertex;
11054 }
11055
11056 static int initialize_spdblock(
11057         struct compile_state *state, struct sdom_block *sd,
11058         struct block *parent, struct block *block, int vertex)
11059 {
11060         struct block_set *user;
11061         if (!block || (sd[block->vertex].block == block)) {
11062                 return vertex;
11063         }
11064         vertex += 1;
11065         /* Renumber the blocks in a convinient fashion */
11066         block->vertex = vertex;
11067         sd[vertex].block    = block;
11068         sd[vertex].sdom     = &sd[vertex];
11069         sd[vertex].label    = &sd[vertex];
11070         sd[vertex].parent   = parent? &sd[parent->vertex] : 0;
11071         sd[vertex].ancestor = 0;
11072         sd[vertex].vertex   = vertex;
11073         for(user = block->use; user; user = user->next) {
11074                 vertex = initialize_spdblock(state, sd, block, user->member, vertex);
11075         }
11076         return vertex;
11077 }
11078
11079 static int setup_spdblocks(struct compile_state *state, struct sdom_block *sd)
11080 {
11081         struct block *block;
11082         int vertex;
11083         /* Setup as many sdpblocks as possible without using fake edges */
11084         vertex = initialize_spdblock(state, sd, 0, state->last_block, 0);
11085
11086         /* Walk through the graph and find unconnected blocks.  Add a
11087          * fake edge from the unconnected blocks to the end of the
11088          * graph. 
11089          */
11090         block = state->first_block->last->next->u.block;
11091         for(; block && block != state->first_block; block = block->last->next->u.block) {
11092                 if (sd[block->vertex].block == block) {
11093                         continue;
11094                 }
11095 #if DEBUG_SDP_BLOCKS
11096                 fprintf(stderr, "Adding %d\n", vertex +1);
11097 #endif
11098                 add_block_edge(block, state->last_block, 0);
11099                 use_block(state->last_block, block);
11100
11101                 vertex = initialize_spdblock(state, sd, state->last_block, block, vertex);
11102         }
11103         return vertex;
11104 }
11105
11106 static void compress_ancestors(struct sdom_block *v)
11107 {
11108         /* This procedure assumes ancestor(v) != 0 */
11109         /* if (ancestor(ancestor(v)) != 0) {
11110          *      compress(ancestor(ancestor(v)));
11111          *      if (semi(label(ancestor(v))) < semi(label(v))) {
11112          *              label(v) = label(ancestor(v));
11113          *      }
11114          *      ancestor(v) = ancestor(ancestor(v));
11115          * }
11116          */
11117         if (!v->ancestor) {
11118                 return;
11119         }
11120         if (v->ancestor->ancestor) {
11121                 compress_ancestors(v->ancestor->ancestor);
11122                 if (v->ancestor->label->sdom->vertex < v->label->sdom->vertex) {
11123                         v->label = v->ancestor->label;
11124                 }
11125                 v->ancestor = v->ancestor->ancestor;
11126         }
11127 }
11128
11129 static void compute_sdom(struct compile_state *state, struct sdom_block *sd)
11130 {
11131         int i;
11132         /* // step 2 
11133          *  for each v <= pred(w) {
11134          *      u = EVAL(v);
11135          *      if (semi[u] < semi[w] { 
11136          *              semi[w] = semi[u]; 
11137          *      } 
11138          * }
11139          * add w to bucket(vertex(semi[w]));
11140          * LINK(parent(w), w);
11141          *
11142          * // step 3
11143          * for each v <= bucket(parent(w)) {
11144          *      delete v from bucket(parent(w));
11145          *      u = EVAL(v);
11146          *      dom(v) = (semi[u] < semi[v]) ? u : parent(w);
11147          * }
11148          */
11149         for(i = state->last_vertex; i >= 2; i--) {
11150                 struct sdom_block *v, *parent, *next;
11151                 struct block_set *user;
11152                 struct block *block;
11153                 block = sd[i].block;
11154                 parent = sd[i].parent;
11155                 /* Step 2 */
11156                 for(user = block->use; user; user = user->next) {
11157                         struct sdom_block *v, *u;
11158                         v = &sd[user->member->vertex];
11159                         u = !(v->ancestor)? v : (compress_ancestors(v), v->label);
11160                         if (u->sdom->vertex < sd[i].sdom->vertex) {
11161                                 sd[i].sdom = u->sdom;
11162                         }
11163                 }
11164                 sdom_block(sd[i].sdom, &sd[i]);
11165                 sd[i].ancestor = parent;
11166                 /* Step 3 */
11167                 for(v = parent->sdominates; v; v = next) {
11168                         struct sdom_block *u;
11169                         next = v->sdom_next;
11170                         unsdom_block(v);
11171                         u = (!v->ancestor) ? v : (compress_ancestors(v), v->label);
11172                         v->block->idom = (u->sdom->vertex < v->sdom->vertex)? 
11173                                 u->block : parent->block;
11174                 }
11175         }
11176 }
11177
11178 static void compute_spdom(struct compile_state *state, struct sdom_block *sd)
11179 {
11180         int i;
11181         /* // step 2 
11182          *  for each v <= pred(w) {
11183          *      u = EVAL(v);
11184          *      if (semi[u] < semi[w] { 
11185          *              semi[w] = semi[u]; 
11186          *      } 
11187          * }
11188          * add w to bucket(vertex(semi[w]));
11189          * LINK(parent(w), w);
11190          *
11191          * // step 3
11192          * for each v <= bucket(parent(w)) {
11193          *      delete v from bucket(parent(w));
11194          *      u = EVAL(v);
11195          *      dom(v) = (semi[u] < semi[v]) ? u : parent(w);
11196          * }
11197          */
11198         for(i = state->last_vertex; i >= 2; i--) {
11199                 struct sdom_block *u, *v, *parent, *next;
11200                 struct block_set *edge;
11201                 struct block *block;
11202                 block = sd[i].block;
11203                 parent = sd[i].parent;
11204                 /* Step 2 */
11205                 for(edge = block->edges; edge; edge = edge->next) {
11206                         v = &sd[edge->member->vertex];
11207                         u = !(v->ancestor)? v : (compress_ancestors(v), v->label);
11208                         if (u->sdom->vertex < sd[i].sdom->vertex) {
11209                                 sd[i].sdom = u->sdom;
11210                         }
11211                 }
11212                 sdom_block(sd[i].sdom, &sd[i]);
11213                 sd[i].ancestor = parent;
11214                 /* Step 3 */
11215                 for(v = parent->sdominates; v; v = next) {
11216                         struct sdom_block *u;
11217                         next = v->sdom_next;
11218                         unsdom_block(v);
11219                         u = (!v->ancestor) ? v : (compress_ancestors(v), v->label);
11220                         v->block->ipdom = (u->sdom->vertex < v->sdom->vertex)? 
11221                                 u->block : parent->block;
11222                 }
11223         }
11224 }
11225
11226 static void compute_idom(struct compile_state *state, struct sdom_block *sd)
11227 {
11228         int i;
11229         for(i = 2; i <= state->last_vertex; i++) {
11230                 struct block *block;
11231                 block = sd[i].block;
11232                 if (block->idom->vertex != sd[i].sdom->vertex) {
11233                         block->idom = block->idom->idom;
11234                 }
11235                 idom_block(block->idom, block);
11236         }
11237         sd[1].block->idom = 0;
11238 }
11239
11240 static void compute_ipdom(struct compile_state *state, struct sdom_block *sd)
11241 {
11242         int i;
11243         for(i = 2; i <= state->last_vertex; i++) {
11244                 struct block *block;
11245                 block = sd[i].block;
11246                 if (block->ipdom->vertex != sd[i].sdom->vertex) {
11247                         block->ipdom = block->ipdom->ipdom;
11248                 }
11249                 ipdom_block(block->ipdom, block);
11250         }
11251         sd[1].block->ipdom = 0;
11252 }
11253
11254         /* Theorem 1:
11255          *   Every vertex of a flowgraph G = (V, E, r) except r has
11256          *   a unique immediate dominator.  
11257          *   The edges {(idom(w), w) |w <= V - {r}} form a directed tree
11258          *   rooted at r, called the dominator tree of G, such that 
11259          *   v dominates w if and only if v is a proper ancestor of w in
11260          *   the dominator tree.
11261          */
11262         /* Lemma 1:  
11263          *   If v and w are vertices of G such that v <= w,
11264          *   than any path from v to w must contain a common ancestor
11265          *   of v and w in T.
11266          */
11267         /* Lemma 2:  For any vertex w != r, idom(w) -> w */
11268         /* Lemma 3:  For any vertex w != r, sdom(w) -> w */
11269         /* Lemma 4:  For any vertex w != r, idom(w) -> sdom(w) */
11270         /* Theorem 2:
11271          *   Let w != r.  Suppose every u for which sdom(w) -> u -> w satisfies
11272          *   sdom(u) >= sdom(w).  Then idom(w) = sdom(w).
11273          */
11274         /* Theorem 3:
11275          *   Let w != r and let u be a vertex for which sdom(u) is 
11276          *   minimum amoung vertices u satisfying sdom(w) -> u -> w.
11277          *   Then sdom(u) <= sdom(w) and idom(u) = idom(w).
11278          */
11279         /* Lemma 5:  Let vertices v,w satisfy v -> w.
11280          *           Then v -> idom(w) or idom(w) -> idom(v)
11281          */
11282
11283 static void find_immediate_dominators(struct compile_state *state)
11284 {
11285         struct sdom_block *sd;
11286         /* w->sdom = min{v| there is a path v = v0,v1,...,vk = w such that:
11287          *           vi > w for (1 <= i <= k - 1}
11288          */
11289         /* Theorem 4:
11290          *   For any vertex w != r.
11291          *   sdom(w) = min(
11292          *                 {v|(v,w) <= E  and v < w } U 
11293          *                 {sdom(u) | u > w and there is an edge (v, w) such that u -> v})
11294          */
11295         /* Corollary 1:
11296          *   Let w != r and let u be a vertex for which sdom(u) is 
11297          *   minimum amoung vertices u satisfying sdom(w) -> u -> w.
11298          *   Then:
11299          *                   { sdom(w) if sdom(w) = sdom(u),
11300          *        idom(w) = {
11301          *                   { idom(u) otherwise
11302          */
11303         /* The algorithm consists of the following 4 steps.
11304          * Step 1.  Carry out a depth-first search of the problem graph.  
11305          *    Number the vertices from 1 to N as they are reached during
11306          *    the search.  Initialize the variables used in succeeding steps.
11307          * Step 2.  Compute the semidominators of all vertices by applying
11308          *    theorem 4.   Carry out the computation vertex by vertex in
11309          *    decreasing order by number.
11310          * Step 3.  Implicitly define the immediate dominator of each vertex
11311          *    by applying Corollary 1.
11312          * Step 4.  Explicitly define the immediate dominator of each vertex,
11313          *    carrying out the computation vertex by vertex in increasing order
11314          *    by number.
11315          */
11316         /* Step 1 initialize the basic block information */
11317         sd = xcmalloc(sizeof(*sd) * (state->last_vertex + 1), "sdom_state");
11318         initialize_sdblock(sd, 0, state->first_block, 0);
11319 #if 0
11320         sd[1].size  = 0;
11321         sd[1].label = 0;
11322         sd[1].sdom  = 0;
11323 #endif
11324         /* Step 2 compute the semidominators */
11325         /* Step 3 implicitly define the immediate dominator of each vertex */
11326         compute_sdom(state, sd);
11327         /* Step 4 explicitly define the immediate dominator of each vertex */
11328         compute_idom(state, sd);
11329         xfree(sd);
11330 }
11331
11332 static void find_post_dominators(struct compile_state *state)
11333 {
11334         struct sdom_block *sd;
11335         int vertex;
11336         /* Step 1 initialize the basic block information */
11337         sd = xcmalloc(sizeof(*sd) * (state->last_vertex + 1), "sdom_state");
11338
11339         vertex = setup_spdblocks(state, sd);
11340         if (vertex != state->last_vertex) {
11341                 internal_error(state, 0, "missing %d blocks\n",
11342                         state->last_vertex - vertex);
11343         }
11344
11345         /* Step 2 compute the semidominators */
11346         /* Step 3 implicitly define the immediate dominator of each vertex */
11347         compute_spdom(state, sd);
11348         /* Step 4 explicitly define the immediate dominator of each vertex */
11349         compute_ipdom(state, sd);
11350         xfree(sd);
11351 }
11352
11353
11354
11355 static void find_block_domf(struct compile_state *state, struct block *block)
11356 {
11357         struct block *child;
11358         struct block_set *user, *edge;
11359         if (block->domfrontier != 0) {
11360                 internal_error(state, block->first, "domfrontier present?");
11361         }
11362         for(user = block->idominates; user; user = user->next) {
11363                 child = user->member;
11364                 if (child->idom != block) {
11365                         internal_error(state, block->first, "bad idom");
11366                 }
11367                 find_block_domf(state, child);
11368         }
11369         for(edge = block->edges; edge; edge = edge->next) {
11370                 if (edge->member->idom != block) {
11371                         domf_block(block, edge->member);
11372                 }
11373         }
11374         for(user = block->idominates; user; user = user->next) {
11375                 struct block_set *frontier;
11376                 child = user->member;
11377                 for(frontier = child->domfrontier; frontier; frontier = frontier->next) {
11378                         if (frontier->member->idom != block) {
11379                                 domf_block(block, frontier->member);
11380                         }
11381                 }
11382         }
11383 }
11384
11385 static void find_block_ipdomf(struct compile_state *state, struct block *block)
11386 {
11387         struct block *child;
11388         struct block_set *user;
11389         if (block->ipdomfrontier != 0) {
11390                 internal_error(state, block->first, "ipdomfrontier present?");
11391         }
11392         for(user = block->ipdominates; user; user = user->next) {
11393                 child = user->member;
11394                 if (child->ipdom != block) {
11395                         internal_error(state, block->first, "bad ipdom");
11396                 }
11397                 find_block_ipdomf(state, child);
11398         }
11399         for(user = block->use; user; user = user->next) {
11400                 if (user->member->ipdom != block) {
11401                         ipdomf_block(block, user->member);
11402                 }
11403         }
11404         for(user = block->ipdominates; user; user = user->next) {
11405                 struct block_set *frontier;
11406                 child = user->member;
11407                 for(frontier = child->ipdomfrontier; frontier; frontier = frontier->next) {
11408                         if (frontier->member->ipdom != block) {
11409                                 ipdomf_block(block, frontier->member);
11410                         }
11411                 }
11412         }
11413 }
11414
11415 static void print_dominated(
11416         struct compile_state *state, struct block *block, void *arg)
11417 {
11418         struct block_set *user;
11419         FILE *fp = arg;
11420
11421         fprintf(fp, "%d:", block->vertex);
11422         for(user = block->idominates; user; user = user->next) {
11423                 fprintf(fp, " %d", user->member->vertex);
11424                 if (user->member->idom != block) {
11425                         internal_error(state, user->member->first, "bad idom");
11426                 }
11427         }
11428         fprintf(fp,"\n");
11429 }
11430
11431 static void print_dominated2(
11432         struct compile_state *state, FILE *fp, int depth, struct block *block)
11433 {
11434         struct block_set *user;
11435         struct triple *ins;
11436         struct occurance *ptr, *ptr2;
11437         const char *filename1, *filename2;
11438         int equal_filenames;
11439         int i;
11440         for(i = 0; i < depth; i++) {
11441                 fprintf(fp, "   ");
11442         }
11443         fprintf(fp, "%3d: %p (%p - %p) @", 
11444                 block->vertex, block, block->first, block->last);
11445         ins = block->first;
11446         while(ins != block->last && (ins->occurance->line == 0)) {
11447                 ins = ins->next;
11448         }
11449         ptr = ins->occurance;
11450         ptr2 = block->last->occurance;
11451         filename1 = ptr->filename? ptr->filename : "";
11452         filename2 = ptr2->filename? ptr2->filename : "";
11453         equal_filenames = (strcmp(filename1, filename2) == 0);
11454         if ((ptr == ptr2) || (equal_filenames && ptr->line == ptr2->line)) {
11455                 fprintf(fp, " %s:%d", ptr->filename, ptr->line);
11456         } else if (equal_filenames) {
11457                 fprintf(fp, " %s:(%d - %d)",
11458                         ptr->filename, ptr->line, ptr2->line);
11459         } else {
11460                 fprintf(fp, " (%s:%d - %s:%d)",
11461                         ptr->filename, ptr->line,
11462                         ptr2->filename, ptr2->line);
11463         }
11464         fprintf(fp, "\n");
11465         for(user = block->idominates; user; user = user->next) {
11466                 print_dominated2(state, fp, depth + 1, user->member);
11467         }
11468 }
11469
11470 static void print_dominators(struct compile_state *state, FILE *fp)
11471 {
11472         fprintf(fp, "\ndominates\n");
11473         walk_blocks(state, print_dominated, fp);
11474         fprintf(fp, "dominates\n");
11475         print_dominated2(state, fp, 0, state->first_block);
11476 }
11477
11478
11479 static int print_frontiers(
11480         struct compile_state *state, struct block *block, int vertex)
11481 {
11482         struct block_set *user, *edge;
11483
11484         if (!block || (block->vertex != vertex + 1)) {
11485                 return vertex;
11486         }
11487         vertex += 1;
11488
11489         printf("%d:", block->vertex);
11490         for(user = block->domfrontier; user; user = user->next) {
11491                 printf(" %d", user->member->vertex);
11492         }
11493         printf("\n");
11494         
11495         for(edge = block->edges; edge; edge = edge->next) {
11496                 vertex = print_frontiers(state, edge->member, vertex);
11497         }
11498         return vertex;
11499 }
11500 static void print_dominance_frontiers(struct compile_state *state)
11501 {
11502         printf("\ndominance frontiers\n");
11503         print_frontiers(state, state->first_block, 0);
11504         
11505 }
11506
11507 static void analyze_idominators(struct compile_state *state)
11508 {
11509         /* Find the immediate dominators */
11510         find_immediate_dominators(state);
11511         /* Find the dominance frontiers */
11512         find_block_domf(state, state->first_block);
11513         /* If debuging print the print what I have just found */
11514         if (state->compiler->debug & DEBUG_FDOMINATORS) {
11515                 print_dominators(state, stdout);
11516                 print_dominance_frontiers(state);
11517                 print_control_flow(state);
11518         }
11519 }
11520
11521
11522
11523 static void print_ipdominated(
11524         struct compile_state *state, struct block *block, void *arg)
11525 {
11526         struct block_set *user;
11527         FILE *fp = arg;
11528
11529         fprintf(fp, "%d:", block->vertex);
11530         for(user = block->ipdominates; user; user = user->next) {
11531                 fprintf(fp, " %d", user->member->vertex);
11532                 if (user->member->ipdom != block) {
11533                         internal_error(state, user->member->first, "bad ipdom");
11534                 }
11535         }
11536         fprintf(fp, "\n");
11537 }
11538
11539 static void print_ipdominators(struct compile_state *state, FILE *fp)
11540 {
11541         fprintf(fp, "\nipdominates\n");
11542         walk_blocks(state, print_ipdominated, fp);
11543 }
11544
11545 static int print_pfrontiers(
11546         struct compile_state *state, struct block *block, int vertex)
11547 {
11548         struct block_set *user;
11549
11550         if (!block || (block->vertex != vertex + 1)) {
11551                 return vertex;
11552         }
11553         vertex += 1;
11554
11555         printf("%d:", block->vertex);
11556         for(user = block->ipdomfrontier; user; user = user->next) {
11557                 printf(" %d", user->member->vertex);
11558         }
11559         printf("\n");
11560         for(user = block->use; user; user = user->next) {
11561                 vertex = print_pfrontiers(state, user->member, vertex);
11562         }
11563         return vertex;
11564 }
11565 static void print_ipdominance_frontiers(struct compile_state *state)
11566 {
11567         printf("\nipdominance frontiers\n");
11568         print_pfrontiers(state, state->last_block, 0);
11569         
11570 }
11571
11572 static void analyze_ipdominators(struct compile_state *state)
11573 {
11574         /* Find the post dominators */
11575         find_post_dominators(state);
11576         /* Find the control dependencies (post dominance frontiers) */
11577         find_block_ipdomf(state, state->last_block);
11578         /* If debuging print the print what I have just found */
11579         if (state->compiler->debug & DEBUG_RDOMINATORS) {
11580                 print_ipdominators(state, stdout);
11581                 print_ipdominance_frontiers(state);
11582                 print_control_flow(state);
11583         }
11584 }
11585
11586 static int bdominates(struct compile_state *state,
11587         struct block *dom, struct block *sub)
11588 {
11589         while(sub && (sub != dom)) {
11590                 sub = sub->idom;
11591         }
11592         return sub == dom;
11593 }
11594
11595 static int tdominates(struct compile_state *state,
11596         struct triple *dom, struct triple *sub)
11597 {
11598         struct block *bdom, *bsub;
11599         int result;
11600         bdom = block_of_triple(state, dom);
11601         bsub = block_of_triple(state, sub);
11602         if (bdom != bsub) {
11603                 result = bdominates(state, bdom, bsub);
11604         } 
11605         else {
11606                 struct triple *ins;
11607                 ins = sub;
11608                 while((ins != bsub->first) && (ins != dom)) {
11609                         ins = ins->prev;
11610                 }
11611                 result = (ins == dom);
11612         }
11613         return result;
11614 }
11615
11616 static void analyze_basic_blocks(struct compile_state *state)
11617 {
11618         setup_basic_blocks(state);
11619         analyze_idominators(state);
11620         analyze_ipdominators(state);
11621 }
11622
11623 static void insert_phi_operations(struct compile_state *state)
11624 {
11625         size_t size;
11626         struct triple *first;
11627         int *has_already, *work;
11628         struct block *work_list, **work_list_tail;
11629         int iter;
11630         struct triple *var, *vnext;
11631
11632         size = sizeof(int) * (state->last_vertex + 1);
11633         has_already = xcmalloc(size, "has_already");
11634         work =        xcmalloc(size, "work");
11635         iter = 0;
11636
11637         first = state->first;
11638         for(var = first->next; var != first ; var = vnext) {
11639                 struct block *block;
11640                 struct triple_set *user, *unext;
11641                 vnext = var->next;
11642                 if ((var->op != OP_ADECL) || !var->use) {
11643                         continue;
11644                 }
11645                 iter += 1;
11646                 work_list = 0;
11647                 work_list_tail = &work_list;
11648                 for(user = var->use; user; user = unext) {
11649                         unext = user->next;
11650                         if (user->member->op == OP_READ) {
11651                                 continue;
11652                         }
11653                         if (user->member->op != OP_WRITE) {
11654                                 internal_error(state, user->member, 
11655                                         "bad variable access");
11656                         }
11657                         block = user->member->u.block;
11658                         if (!block) {
11659                                 warning(state, user->member, "dead code");
11660                                 release_triple(state, user->member);
11661                                 continue;
11662                         }
11663                         if (work[block->vertex] >= iter) {
11664                                 continue;
11665                         }
11666                         work[block->vertex] = iter;
11667                         *work_list_tail = block;
11668                         block->work_next = 0;
11669                         work_list_tail = &block->work_next;
11670                 }
11671                 for(block = work_list; block; block = block->work_next) {
11672                         struct block_set *df;
11673                         for(df = block->domfrontier; df; df = df->next) {
11674                                 struct triple *phi;
11675                                 struct block *front;
11676                                 int in_edges;
11677                                 front = df->member;
11678
11679                                 if (has_already[front->vertex] >= iter) {
11680                                         continue;
11681                                 }
11682                                 /* Count how many edges flow into this block */
11683                                 in_edges = front->users;
11684                                 /* Insert a phi function for this variable */
11685                                 get_occurance(var->occurance);
11686                                 phi = alloc_triple(
11687                                         state, OP_PHI, var->type, -1, in_edges, 
11688                                         var->occurance);
11689                                 phi->u.block = front;
11690                                 MISC(phi, 0) = var;
11691                                 use_triple(var, phi);
11692                                 /* Insert the phi functions immediately after the label */
11693                                 insert_triple(state, front->first->next, phi);
11694                                 if (front->first == front->last) {
11695                                         front->last = front->first->next;
11696                                 }
11697                                 has_already[front->vertex] = iter;
11698                                 transform_to_arch_instruction(state, phi);
11699
11700                                 /* If necessary plan to visit the basic block */
11701                                 if (work[front->vertex] >= iter) {
11702                                         continue;
11703                                 }
11704                                 work[front->vertex] = iter;
11705                                 *work_list_tail = front;
11706                                 front->work_next = 0;
11707                                 work_list_tail = &front->work_next;
11708                         }
11709                 }
11710         }
11711         xfree(has_already);
11712         xfree(work);
11713 }
11714
11715
11716 struct stack {
11717         struct triple_set *top;
11718         unsigned orig_id;
11719 };
11720
11721 static int count_adecls(struct compile_state *state)
11722 {
11723         struct triple *first, *ins;
11724         int adecls = 0;
11725         first = state->first;
11726         ins = first;
11727         do {
11728                 if (ins->op == OP_ADECL) {
11729                         adecls += 1;
11730                 }
11731                 ins = ins->next;
11732         } while(ins != first);
11733         return adecls;
11734 }
11735
11736 static void number_adecls(struct compile_state *state, struct stack *stacks)
11737 {
11738         struct triple *first, *ins;
11739         int adecls = 0;
11740         first = state->first;
11741         ins = first;
11742         do {
11743                 if (ins->op == OP_ADECL) {
11744                         adecls += 1;
11745                         stacks[adecls].orig_id = ins->id;
11746                         ins->id = adecls;
11747                 }
11748                 ins = ins->next;
11749         } while(ins != first);
11750 }
11751
11752 static void restore_adecls(struct compile_state *state, struct stack *stacks)
11753 {
11754         struct triple *first, *ins;
11755         first = state->first;
11756         ins = first;
11757         do {
11758                 if (ins->op == OP_ADECL) {
11759                         ins->id = stacks[ins->id].orig_id;
11760                 }
11761                 ins = ins->next;
11762         } while(ins != first);
11763 }
11764
11765 static struct triple *peek_triple(struct stack *stacks, struct triple *var)
11766 {
11767         struct triple_set *head;
11768         struct triple *top_val;
11769         top_val = 0;
11770         head = stacks[var->id].top;
11771         if (head) {
11772                 top_val = head->member;
11773         }
11774         return top_val;
11775 }
11776
11777 static void push_triple(struct stack *stacks, struct triple *var, struct triple *val)
11778 {
11779         struct triple_set *new;
11780         /* Append new to the head of the list,
11781          * it's the only sensible behavoir for a stack.
11782          */
11783         new = xcmalloc(sizeof(*new), "triple_set");
11784         new->member = val;
11785         new->next   = stacks[var->id].top;
11786         stacks[var->id].top = new;
11787 }
11788
11789 static void pop_triple(struct stack *stacks, struct triple *var, struct triple *oldval)
11790 {
11791         struct triple_set *set, **ptr;
11792         ptr = &stacks[var->id].top;
11793         while(*ptr) {
11794                 set = *ptr;
11795                 if (set->member == oldval) {
11796                         *ptr = set->next;
11797                         xfree(set);
11798                         /* Only free one occurance from the stack */
11799                         return;
11800                 }
11801                 else {
11802                         ptr = &set->next;
11803                 }
11804         }
11805 }
11806
11807 /*
11808  * C(V)
11809  * S(V)
11810  */
11811 static void fixup_block_phi_variables(
11812         struct compile_state *state, struct stack *stacks, struct block *parent, struct block *block)
11813 {
11814         struct block_set *set;
11815         struct triple *ptr;
11816         int edge;
11817         if (!parent || !block)
11818                 return;
11819         /* Find the edge I am coming in on */
11820         edge = 0;
11821         for(set = block->use; set; set = set->next, edge++) {
11822                 if (set->member == parent) {
11823                         break;
11824                 }
11825         }
11826         if (!set) {
11827                 internal_error(state, 0, "phi input is not on a control predecessor");
11828         }
11829         for(ptr = block->first; ; ptr = ptr->next) {
11830                 if (ptr->op == OP_PHI) {
11831                         struct triple *var, *val, **slot;
11832                         var = MISC(ptr, 0);
11833                         if (!var) {
11834                                 internal_error(state, ptr, "no var???");
11835                         }
11836                         /* Find the current value of the variable */
11837                         val = peek_triple(stacks, var);
11838                         if (val && ((val->op == OP_WRITE) || (val->op == OP_READ))) {
11839                                 internal_error(state, val, "bad value in phi");
11840                         }
11841                         if (edge >= TRIPLE_RHS(ptr->sizes)) {
11842                                 internal_error(state, ptr, "edges > phi rhs");
11843                         }
11844                         slot = &RHS(ptr, edge);
11845                         if ((*slot != 0) && (*slot != val)) {
11846                                 internal_error(state, ptr, "phi already bound on this edge");
11847                         }
11848                         *slot = val;
11849                         use_triple(val, ptr);
11850                 }
11851                 if (ptr == block->last) {
11852                         break;
11853                 }
11854         }
11855 }
11856
11857
11858 static void rename_block_variables(
11859         struct compile_state *state, struct stack *stacks, struct block *block)
11860 {
11861         struct block_set *user, *edge;
11862         struct triple *ptr, *next, *last;
11863         int done;
11864         if (!block)
11865                 return;
11866         last = block->first;
11867         done = 0;
11868         for(ptr = block->first; !done; ptr = next) {
11869                 next = ptr->next;
11870                 if (ptr == block->last) {
11871                         done = 1;
11872                 }
11873                 /* RHS(A) */
11874                 if (ptr->op == OP_READ) {
11875                         struct triple *var, *val;
11876                         var = RHS(ptr, 0);
11877                         unuse_triple(var, ptr);
11878                         /* Find the current value of the variable */
11879                         val = peek_triple(stacks, var);
11880                         if (!val) {
11881                                 error(state, ptr, "variable used without being set");
11882                         }
11883                         if ((val->op == OP_WRITE) || (val->op == OP_READ)) {
11884                                 internal_error(state, val, "bad value in read");
11885                         }
11886                         propogate_use(state, ptr, val);
11887                         release_triple(state, ptr);
11888                         continue;
11889                 }
11890                 /* LHS(A) */
11891                 if (ptr->op == OP_WRITE) {
11892                         struct triple *var, *val, *tval;
11893                         var = RHS(ptr, 0);
11894                         tval = val = RHS(ptr, 1);
11895                         if ((val->op == OP_WRITE) || (val->op == OP_READ)) {
11896                                 internal_error(state, ptr, "bad value in write");
11897                         }
11898                         /* Insert a copy if the types differ */
11899                         if (!equiv_types(ptr->type, val->type)) {
11900                                 if (val->op == OP_INTCONST) {
11901                                         tval = pre_triple(state, ptr, OP_INTCONST, ptr->type, 0, 0);
11902                                         tval->u.cval = val->u.cval;
11903                                 }
11904                                 else {
11905                                         tval = pre_triple(state, ptr, OP_COPY, ptr->type, val, 0);
11906                                         use_triple(val, tval);
11907                                 }
11908                                 transform_to_arch_instruction(state, tval);
11909                                 unuse_triple(val, ptr);
11910                                 RHS(ptr, 1) = tval;
11911                                 use_triple(tval, ptr);
11912                         }
11913                         propogate_use(state, ptr, tval);
11914                         unuse_triple(var, ptr);
11915                         /* Push OP_WRITE ptr->right onto a stack of variable uses */
11916                         push_triple(stacks, var, tval);
11917                 }
11918                 if (ptr->op == OP_PHI) {
11919                         struct triple *var;
11920                         var = MISC(ptr, 0);
11921                         /* Push OP_PHI onto a stack of variable uses */
11922                         push_triple(stacks, var, ptr);
11923                 }
11924                 last = ptr;
11925         }
11926         block->last = last;
11927
11928         /* Fixup PHI functions in the cf successors */
11929         for(edge = block->edges; edge; edge = edge->next) {
11930                 fixup_block_phi_variables(state, stacks, block, edge->member);
11931         }
11932         /* rename variables in the dominated nodes */
11933         for(user = block->idominates; user; user = user->next) {
11934                 rename_block_variables(state, stacks, user->member);
11935         }
11936         /* pop the renamed variable stack */
11937         last = block->first;
11938         done = 0;
11939         for(ptr = block->first; !done ; ptr = next) {
11940                 next = ptr->next;
11941                 if (ptr == block->last) {
11942                         done = 1;
11943                 }
11944                 if (ptr->op == OP_WRITE) {
11945                         struct triple *var;
11946                         var = RHS(ptr, 0);
11947                         /* Pop OP_WRITE ptr->right from the stack of variable uses */
11948                         pop_triple(stacks, var, RHS(ptr, 1));
11949                         release_triple(state, ptr);
11950                         continue;
11951                 }
11952                 if (ptr->op == OP_PHI) {
11953                         struct triple *var;
11954                         var = MISC(ptr, 0);
11955                         /* Pop OP_WRITE ptr->right from the stack of variable uses */
11956                         pop_triple(stacks, var, ptr);
11957                 }
11958                 last = ptr;
11959         }
11960         block->last = last;
11961 }
11962
11963 static void rename_variables(struct compile_state *state)
11964 {
11965         struct stack *stacks;
11966         int adecls;
11967
11968         /* Allocate stacks for the Variables */
11969         adecls = count_adecls(state);
11970         stacks = xcmalloc(sizeof(stacks[0])*(adecls + 1), "adecl stacks");
11971
11972         /* Give each adecl a stack */
11973         number_adecls(state, stacks);
11974
11975         /* Rename the variables */
11976         rename_block_variables(state, stacks, state->first_block);
11977
11978         /* Remove the stacks from the adecls */
11979         restore_adecls(state, stacks);
11980         xfree(stacks);
11981 }
11982
11983 static void prune_block_variables(struct compile_state *state,
11984         struct block *block)
11985 {
11986         struct block_set *user;
11987         struct triple *next, *last, *ptr;
11988         int done;
11989         last = block->first;
11990         done = 0;
11991         for(ptr = block->first; !done; ptr = next) {
11992                 next = ptr->next;
11993                 if (ptr == block->last) {
11994                         done = 1;
11995                 }
11996                 if (ptr->op == OP_ADECL) {
11997                         struct triple_set *user, *next;
11998                         for(user = ptr->use; user; user = next) {
11999                                 struct triple *use;
12000                                 next = user->next;
12001                                 use = user->member;
12002                                 if (use->op != OP_PHI) {
12003                                         internal_error(state, use, "decl still used");
12004                                 }
12005                                 if (MISC(use, 0) != ptr) {
12006                                         internal_error(state, use, "bad phi use of decl");
12007                                 }
12008                                 unuse_triple(ptr, use);
12009                                 MISC(use, 0) = 0;
12010                         }
12011                         release_triple(state, ptr);
12012                         continue;
12013                 }
12014                 last = ptr;
12015         }
12016         block->last = last;
12017         for(user = block->idominates; user; user = user->next) {
12018                 prune_block_variables(state, user->member);
12019         }
12020 }
12021
12022 struct phi_triple {
12023         struct triple *phi;
12024         unsigned orig_id;
12025         int alive;
12026 };
12027
12028 static void keep_phi(struct compile_state *state, struct phi_triple *live, struct triple *phi)
12029 {
12030         struct triple **slot;
12031         int zrhs, i;
12032         if (live[phi->id].alive) {
12033                 return;
12034         }
12035         live[phi->id].alive = 1;
12036         zrhs = TRIPLE_RHS(phi->sizes);
12037         slot = &RHS(phi, 0);
12038         for(i = 0; i < zrhs; i++) {
12039                 struct triple *used;
12040                 used = slot[i];
12041                 if (used && (used->op == OP_PHI)) {
12042                         keep_phi(state, live, used);
12043                 }
12044         }
12045 }
12046
12047 static void prune_unused_phis(struct compile_state *state)
12048 {
12049         struct triple *first, *phi;
12050         struct phi_triple *live;
12051         int phis, i;
12052         
12053         /* Find the first instruction */
12054         first = state->first;
12055
12056         /* Count how many phi functions I need to process */
12057         phis = 0;
12058         for(phi = first->next; phi != first; phi = phi->next) {
12059                 if (phi->op == OP_PHI) {
12060                         phis += 1;
12061                 }
12062         }
12063         
12064         /* Mark them all dead */
12065         live = xcmalloc(sizeof(*live) * (phis + 1), "phi_triple");
12066         phis = 0;
12067         for(phi = first->next; phi != first; phi = phi->next) {
12068                 if (phi->op != OP_PHI) {
12069                         continue;
12070                 }
12071                 live[phis].alive   = 0;
12072                 live[phis].orig_id = phi->id;
12073                 live[phis].phi     = phi;
12074                 phi->id = phis;
12075                 phis += 1;
12076         }
12077         
12078         /* Mark phis alive that are used by non phis */
12079         for(i = 0; i < phis; i++) {
12080                 struct triple_set *set;
12081                 for(set = live[i].phi->use; !live[i].alive && set; set = set->next) {
12082                         if (set->member->op != OP_PHI) {
12083                                 keep_phi(state, live, live[i].phi);
12084                                 break;
12085                         }
12086                 }
12087         }
12088
12089         /* Delete the extraneous phis */
12090         for(i = 0; i < phis; i++) {
12091                 struct triple **slot;
12092                 int zrhs, j;
12093                 if (!live[i].alive) {
12094                         release_triple(state, live[i].phi);
12095                         continue;
12096                 }
12097                 phi = live[i].phi;
12098                 slot = &RHS(phi, 0);
12099                 zrhs = TRIPLE_RHS(phi->sizes);
12100                 for(j = 0; j < zrhs; j++) {
12101                         if(!slot[j]) {
12102                                 error(state, phi, "variable not set on all paths to use");
12103                         }
12104                 }
12105         }
12106         xfree(live);
12107 }
12108
12109 static void transform_to_ssa_form(struct compile_state *state)
12110 {
12111         insert_phi_operations(state);
12112         rename_variables(state);
12113
12114         prune_block_variables(state, state->first_block);
12115         prune_unused_phis(state);
12116
12117         print_blocks(state, __func__, stdout);
12118 }
12119
12120
12121 static void clear_vertex(
12122         struct compile_state *state, struct block *block, void *arg)
12123 {
12124         /* Clear the current blocks vertex and the vertex of all
12125          * of the current blocks neighbors in case there are malformed
12126          * blocks with now instructions at this point.
12127          */
12128         struct block_set *user, *edge;
12129         block->vertex = 0;
12130         for(edge = block->edges; edge; edge = edge->next) {
12131                 edge->member->vertex = 0;
12132         }
12133         for(user = block->use; user; user = user->next) {
12134                 user->member->vertex = 0;
12135         }
12136 }
12137
12138 static void mark_live_block(
12139         struct compile_state *state, struct block *block, int *next_vertex)
12140 {
12141         /* See if this is a block that has not been marked */
12142         if (block->vertex != 0) {
12143                 return;
12144         }
12145         block->vertex = *next_vertex;
12146         *next_vertex += 1;
12147         if (triple_is_branch(state, block->last)) {
12148                 struct triple **targ;
12149                 targ = triple_targ(state, block->last, 0);
12150                 for(; targ; targ = triple_targ(state, block->last, targ)) {
12151                         if (!*targ) {
12152                                 continue;
12153                         }
12154                         if (!triple_stores_block(state, *targ)) {
12155                                 internal_error(state, 0, "bad targ");
12156                         }
12157                         mark_live_block(state, (*targ)->u.block, next_vertex);
12158                 }
12159         }
12160         else if (block->last->next != state->first) {
12161                 struct triple *ins;
12162                 ins = block->last->next;
12163                 if (!triple_stores_block(state, ins)) {
12164                         internal_error(state, 0, "bad block start");
12165                 }
12166                 mark_live_block(state, ins->u.block, next_vertex);
12167         }
12168 }
12169
12170 static void transform_from_ssa_form(struct compile_state *state)
12171 {
12172         /* To get out of ssa form we insert moves on the incoming
12173          * edges to blocks containting phi functions.
12174          */
12175         struct triple *first;
12176         struct triple *phi, *var, *next;
12177         int next_vertex;
12178
12179         /* Walk the control flow to see which blocks remain alive */
12180         walk_blocks(state, clear_vertex, 0);
12181         next_vertex = 1;
12182         mark_live_block(state, state->first_block, &next_vertex);
12183
12184         /* Walk all of the operations to find the phi functions */
12185         first = state->first;
12186         for(phi = first->next; phi != first ; phi = next) {
12187                 struct block_set *set;
12188                 struct block *block;
12189                 struct triple **slot;
12190                 struct triple *var;
12191                 struct triple_set *use, *use_next;
12192                 int edge, used;
12193                 next = phi->next;
12194                 if (phi->op != OP_PHI) {
12195                         continue;
12196                 }
12197
12198                 block = phi->u.block;
12199                 slot  = &RHS(phi, 0);
12200
12201                 /* If this phi is in a dead block just forget it */
12202                 if (block->vertex == 0) {
12203                         release_triple(state, phi);
12204                         continue;
12205                 }
12206
12207                 /* Forget uses from code in dead blocks */
12208                 for(use = phi->use; use; use = use_next) {
12209                         struct block *ublock;
12210                         struct triple **expr;
12211                         use_next = use->next;
12212                         ublock = block_of_triple(state, use->member);
12213                         if ((use->member == phi) || (ublock->vertex != 0)) {
12214                                 continue;
12215                         }
12216                         expr = triple_rhs(state, use->member, 0);
12217                         for(; expr; expr = triple_rhs(state, use->member, expr)) {
12218                                 if (*expr == phi) {
12219                                         *expr = 0;
12220                                 }
12221                         }
12222                         unuse_triple(phi, use->member);
12223                 }
12224                 /* A variable to replace the phi function */
12225                 var = post_triple(state, phi, OP_ADECL, phi->type, 0,0);
12226
12227                 /* Replaces use of phi with var */
12228                 propogate_use(state, phi, var);
12229
12230                 /* Walk all of the incoming edges/blocks and insert moves.
12231                  */
12232                 used = 0;
12233                 for(edge = 0, set = block->use; set; set = set->next, edge++) {
12234                         struct block *eblock, *vblock;
12235                         struct triple *move;
12236                         struct triple *val, *base;
12237                         eblock = set->member;
12238                         val = slot[edge];
12239                         slot[edge] = 0;
12240                         unuse_triple(val, phi);
12241                         vblock = block_of_triple(state, val);
12242
12243                         /* If we don't have a value that belongs in an OP_WRITE
12244                          * continue on.
12245                          */
12246                         if (!val || (val == &zero_triple) || (val == phi) || 
12247                                 (!vblock) || (vblock->vertex == 0)) {
12248                                 continue;
12249                         }
12250
12251                         /* If the value occurs in a dead block see if a replacement
12252                          * block can be found.
12253                          */
12254                         while(eblock && (eblock->vertex == 0)) {
12255                                 eblock = eblock->idom;
12256                         }
12257                         /* If not continue on with the next value. */
12258                         if (!eblock || (eblock->vertex == 0)) {
12259                                 continue;
12260                         }
12261
12262                         /* If we have an empty incoming block ignore it. */
12263                         if (!eblock->first) {
12264                                 internal_error(state, 0, "empty block?");
12265                         }
12266                         
12267                         /* Make certain the write is placed in the edge block... */
12268                         base = eblock->first;
12269                         if (block_of_triple(state, val) == eblock) {
12270                                 base = val;
12271                         }
12272                         move = post_triple(state, base, OP_WRITE, var->type, var, val);
12273                         use_triple(val, move);
12274                         use_triple(var, move);
12275                         used = 1;
12276                 }               
12277                 /* If var is not used free it */
12278                 if (!used) {
12279                         free_triple(state, var);
12280                 }
12281
12282                 /* Release the phi function */
12283                 release_triple(state, phi);
12284         }
12285         
12286         /* Walk all of the operations to find the adecls */
12287         for(var = first->next; var != first ; var = var->next) {
12288                 struct triple_set *use, *use_next;
12289                 if (var->op != OP_ADECL) {
12290                         continue;
12291                 }
12292
12293                 /* Walk through all of the rhs uses of var and
12294                  * replace them with read of var.
12295                  */
12296                 for(use = var->use; use; use = use_next) {
12297                         struct triple *read, *user;
12298                         struct triple **slot;
12299                         int zrhs, i, used;
12300                         use_next = use->next;
12301                         user = use->member;
12302                         
12303                         /* Generate a read of var */
12304                         read = pre_triple(state, user, OP_READ, var->type, var, 0);
12305                         use_triple(var, read);
12306
12307                         /* Find the rhs uses and see if they need to be replaced */
12308                         used = 0;
12309                         zrhs = TRIPLE_RHS(user->sizes);
12310                         slot = &RHS(user, 0);
12311                         for(i = 0; i < zrhs; i++) {
12312                                 if ((slot[i] == var) &&
12313                                         ((i != 0) || (user->op != OP_WRITE))) 
12314                                 {
12315                                         slot[i] = read;
12316                                         used = 1;
12317                                 }
12318                         }
12319                         /* If we did use it cleanup the uses */
12320                         if (used) {
12321                                 unuse_triple(var, user);
12322                                 use_triple(read, user);
12323                         } 
12324                         /* If we didn't use it release the extra triple */
12325                         else {
12326                                 release_triple(state, read);
12327                         }
12328                 }
12329         }
12330 }
12331
12332 #define HI() if (state->compiler->debug & DEBUG_REBUILD_SSA_FORM) { \
12333         fprintf(stderr, "@ %s:%d\n", __FILE__, __LINE__); romcc_print_blocks(state, stderr); \
12334         } 
12335
12336 static void rebuild_ssa_form(struct compile_state *state)
12337 {
12338 HI();
12339         transform_from_ssa_form(state);
12340 HI();
12341         free_basic_blocks(state);
12342         analyze_basic_blocks(state);
12343 HI();
12344         insert_phi_operations(state);
12345 HI();
12346         rename_variables(state);
12347 HI();
12348         
12349         prune_block_variables(state, state->first_block);
12350 HI();
12351         prune_unused_phis(state);
12352 HI();
12353 }
12354 #undef HI
12355
12356 /* 
12357  * Register conflict resolution
12358  * =========================================================
12359  */
12360
12361 static struct reg_info find_def_color(
12362         struct compile_state *state, struct triple *def)
12363 {
12364         struct triple_set *set;
12365         struct reg_info info;
12366         info.reg = REG_UNSET;
12367         info.regcm = 0;
12368         if (!triple_is_def(state, def)) {
12369                 return info;
12370         }
12371         info = arch_reg_lhs(state, def, 0);
12372         if (info.reg >= MAX_REGISTERS) {
12373                 info.reg = REG_UNSET;
12374         }
12375         for(set = def->use; set; set = set->next) {
12376                 struct reg_info tinfo;
12377                 int i;
12378                 i = find_rhs_use(state, set->member, def);
12379                 if (i < 0) {
12380                         continue;
12381                 }
12382                 tinfo = arch_reg_rhs(state, set->member, i);
12383                 if (tinfo.reg >= MAX_REGISTERS) {
12384                         tinfo.reg = REG_UNSET;
12385                 }
12386                 if ((tinfo.reg != REG_UNSET) && 
12387                         (info.reg != REG_UNSET) &&
12388                         (tinfo.reg != info.reg)) {
12389                         internal_error(state, def, "register conflict");
12390                 }
12391                 if ((info.regcm & tinfo.regcm) == 0) {
12392                         internal_error(state, def, "regcm conflict %x & %x == 0",
12393                                 info.regcm, tinfo.regcm);
12394                 }
12395                 if (info.reg == REG_UNSET) {
12396                         info.reg = tinfo.reg;
12397                 }
12398                 info.regcm &= tinfo.regcm;
12399         }
12400         if (info.reg >= MAX_REGISTERS) {
12401                 internal_error(state, def, "register out of range");
12402         }
12403         return info;
12404 }
12405
12406 static struct reg_info find_lhs_pre_color(
12407         struct compile_state *state, struct triple *ins, int index)
12408 {
12409         struct reg_info info;
12410         int zlhs, zrhs, i;
12411         zrhs = TRIPLE_RHS(ins->sizes);
12412         zlhs = TRIPLE_LHS(ins->sizes);
12413         if (!zlhs && triple_is_def(state, ins)) {
12414                 zlhs = 1;
12415         }
12416         if (index >= zlhs) {
12417                 internal_error(state, ins, "Bad lhs %d", index);
12418         }
12419         info = arch_reg_lhs(state, ins, index);
12420         for(i = 0; i < zrhs; i++) {
12421                 struct reg_info rinfo;
12422                 rinfo = arch_reg_rhs(state, ins, i);
12423                 if ((info.reg == rinfo.reg) &&
12424                         (rinfo.reg >= MAX_REGISTERS)) {
12425                         struct reg_info tinfo;
12426                         tinfo = find_lhs_pre_color(state, RHS(ins, index), 0);
12427                         info.reg = tinfo.reg;
12428                         info.regcm &= tinfo.regcm;
12429                         break;
12430                 }
12431         }
12432         if (info.reg >= MAX_REGISTERS) {
12433                 info.reg = REG_UNSET;
12434         }
12435         return info;
12436 }
12437
12438 static struct reg_info find_rhs_post_color(
12439         struct compile_state *state, struct triple *ins, int index);
12440
12441 static struct reg_info find_lhs_post_color(
12442         struct compile_state *state, struct triple *ins, int index)
12443 {
12444         struct triple_set *set;
12445         struct reg_info info;
12446         struct triple *lhs;
12447 #if DEBUG_TRIPLE_COLOR
12448         fprintf(stderr, "find_lhs_post_color(%p, %d)\n",
12449                 ins, index);
12450 #endif
12451         if ((index == 0) && triple_is_def(state, ins)) {
12452                 lhs = ins;
12453         }
12454         else if (index < TRIPLE_LHS(ins->sizes)) {
12455                 lhs = LHS(ins, index);
12456         }
12457         else {
12458                 internal_error(state, ins, "Bad lhs %d", index);
12459                 lhs = 0;
12460         }
12461         info = arch_reg_lhs(state, ins, index);
12462         if (info.reg >= MAX_REGISTERS) {
12463                 info.reg = REG_UNSET;
12464         }
12465         for(set = lhs->use; set; set = set->next) {
12466                 struct reg_info rinfo;
12467                 struct triple *user;
12468                 int zrhs, i;
12469                 user = set->member;
12470                 zrhs = TRIPLE_RHS(user->sizes);
12471                 for(i = 0; i < zrhs; i++) {
12472                         if (RHS(user, i) != lhs) {
12473                                 continue;
12474                         }
12475                         rinfo = find_rhs_post_color(state, user, i);
12476                         if ((info.reg != REG_UNSET) &&
12477                                 (rinfo.reg != REG_UNSET) &&
12478                                 (info.reg != rinfo.reg)) {
12479                                 internal_error(state, ins, "register conflict");
12480                         }
12481                         if ((info.regcm & rinfo.regcm) == 0) {
12482                                 internal_error(state, ins, "regcm conflict %x & %x == 0",
12483                                         info.regcm, rinfo.regcm);
12484                         }
12485                         if (info.reg == REG_UNSET) {
12486                                 info.reg = rinfo.reg;
12487                         }
12488                         info.regcm &= rinfo.regcm;
12489                 }
12490         }
12491 #if DEBUG_TRIPLE_COLOR
12492         fprintf(stderr, "find_lhs_post_color(%p, %d) -> ( %d, %x)\n",
12493                 ins, index, info.reg, info.regcm);
12494 #endif
12495         return info;
12496 }
12497
12498 static struct reg_info find_rhs_post_color(
12499         struct compile_state *state, struct triple *ins, int index)
12500 {
12501         struct reg_info info, rinfo;
12502         int zlhs, i;
12503 #if DEBUG_TRIPLE_COLOR
12504         fprintf(stderr, "find_rhs_post_color(%p, %d)\n",
12505                 ins, index);
12506 #endif
12507         rinfo = arch_reg_rhs(state, ins, index);
12508         zlhs = TRIPLE_LHS(ins->sizes);
12509         if (!zlhs && triple_is_def(state, ins)) {
12510                 zlhs = 1;
12511         }
12512         info = rinfo;
12513         if (info.reg >= MAX_REGISTERS) {
12514                 info.reg = REG_UNSET;
12515         }
12516         for(i = 0; i < zlhs; i++) {
12517                 struct reg_info linfo;
12518                 linfo = arch_reg_lhs(state, ins, i);
12519                 if ((linfo.reg == rinfo.reg) &&
12520                         (linfo.reg >= MAX_REGISTERS)) {
12521                         struct reg_info tinfo;
12522                         tinfo = find_lhs_post_color(state, ins, i);
12523                         if (tinfo.reg >= MAX_REGISTERS) {
12524                                 tinfo.reg = REG_UNSET;
12525                         }
12526                         info.regcm &= linfo.regcm;
12527                         info.regcm &= tinfo.regcm;
12528                         if (info.reg != REG_UNSET) {
12529                                 internal_error(state, ins, "register conflict");
12530                         }
12531                         if (info.regcm == 0) {
12532                                 internal_error(state, ins, "regcm conflict");
12533                         }
12534                         info.reg = tinfo.reg;
12535                 }
12536         }
12537 #if DEBUG_TRIPLE_COLOR
12538         fprintf(stderr, "find_rhs_post_color(%p, %d) -> ( %d, %x)\n",
12539                 ins, index, info.reg, info.regcm);
12540 #endif
12541         return info;
12542 }
12543
12544 static struct reg_info find_lhs_color(
12545         struct compile_state *state, struct triple *ins, int index)
12546 {
12547         struct reg_info pre, post, info;
12548 #if DEBUG_TRIPLE_COLOR
12549         fprintf(stderr, "find_lhs_color(%p, %d)\n",
12550                 ins, index);
12551 #endif
12552         pre = find_lhs_pre_color(state, ins, index);
12553         post = find_lhs_post_color(state, ins, index);
12554         if ((pre.reg != post.reg) &&
12555                 (pre.reg != REG_UNSET) &&
12556                 (post.reg != REG_UNSET)) {
12557                 internal_error(state, ins, "register conflict");
12558         }
12559         info.regcm = pre.regcm & post.regcm;
12560         info.reg = pre.reg;
12561         if (info.reg == REG_UNSET) {
12562                 info.reg = post.reg;
12563         }
12564 #if DEBUG_TRIPLE_COLOR
12565         fprintf(stderr, "find_lhs_color(%p, %d) -> ( %d, %x) ... (%d, %x) (%d, %x)\n",
12566                 ins, index, info.reg, info.regcm,
12567                 pre.reg, pre.regcm, post.reg, post.regcm);
12568 #endif
12569         return info;
12570 }
12571
12572 static struct triple *post_copy(struct compile_state *state, struct triple *ins)
12573 {
12574         struct triple_set *entry, *next;
12575         struct triple *out;
12576         struct reg_info info, rinfo;
12577
12578         info = arch_reg_lhs(state, ins, 0);
12579         out = post_triple(state, ins, OP_COPY, ins->type, ins, 0);
12580         use_triple(RHS(out, 0), out);
12581         /* Get the users of ins to use out instead */
12582         for(entry = ins->use; entry; entry = next) {
12583                 int i;
12584                 next = entry->next;
12585                 if (entry->member == out) {
12586                         continue;
12587                 }
12588                 i = find_rhs_use(state, entry->member, ins);
12589                 if (i < 0) {
12590                         continue;
12591                 }
12592                 rinfo = arch_reg_rhs(state, entry->member, i);
12593                 if ((info.reg == REG_UNNEEDED) && (rinfo.reg == REG_UNNEEDED)) {
12594                         continue;
12595                 }
12596                 replace_rhs_use(state, ins, out, entry->member);
12597         }
12598         transform_to_arch_instruction(state, out);
12599         return out;
12600 }
12601
12602 static struct triple *typed_pre_copy(
12603         struct compile_state *state, struct type *type, struct triple *ins, int index)
12604 {
12605         /* Carefully insert enough operations so that I can
12606          * enter any operation with a GPR32.
12607          */
12608         struct triple *in;
12609         struct triple **expr;
12610         unsigned classes;
12611         struct reg_info info;
12612         if (ins->op == OP_PHI) {
12613                 internal_error(state, ins, "pre_copy on a phi?");
12614         }
12615         classes = arch_type_to_regcm(state, type);
12616         info = arch_reg_rhs(state, ins, index);
12617         expr = &RHS(ins, index);
12618         if ((info.regcm & classes) == 0) {
12619                 internal_error(state, ins, "pre_copy with no register classes");
12620         }
12621         in = pre_triple(state, ins, OP_COPY, type, *expr, 0);
12622         unuse_triple(*expr, ins);
12623         *expr = in;
12624         use_triple(RHS(in, 0), in);
12625         use_triple(in, ins);
12626         transform_to_arch_instruction(state, in);
12627         return in;
12628         
12629 }
12630 static struct triple *pre_copy(
12631         struct compile_state *state, struct triple *ins, int index)
12632 {
12633         return typed_pre_copy(state, RHS(ins, index)->type, ins, index);
12634 }
12635
12636
12637 static void insert_copies_to_phi(struct compile_state *state)
12638 {
12639         /* To get out of ssa form we insert moves on the incoming
12640          * edges to blocks containting phi functions.
12641          */
12642         struct triple *first;
12643         struct triple *phi;
12644
12645         /* Walk all of the operations to find the phi functions */
12646         first = state->first;
12647         for(phi = first->next; phi != first ; phi = phi->next) {
12648                 struct block_set *set;
12649                 struct block *block;
12650                 struct triple **slot, *copy;
12651                 int edge;
12652                 if (phi->op != OP_PHI) {
12653                         continue;
12654                 }
12655                 phi->id |= TRIPLE_FLAG_POST_SPLIT;
12656                 block = phi->u.block;
12657                 slot  = &RHS(phi, 0);
12658                 /* Phi's that feed into mandatory live range joins
12659                  * cause nasty complications.  Insert a copy of
12660                  * the phi value so I never have to deal with
12661                  * that in the rest of the code.
12662                  */
12663                 copy = post_copy(state, phi);
12664                 copy->id |= TRIPLE_FLAG_PRE_SPLIT;
12665                 /* Walk all of the incoming edges/blocks and insert moves.
12666                  */
12667                 for(edge = 0, set = block->use; set; set = set->next, edge++) {
12668                         struct block *eblock;
12669                         struct triple *move;
12670                         struct triple *val;
12671                         struct triple *ptr;
12672                         eblock = set->member;
12673                         val = slot[edge];
12674
12675                         if (val == phi) {
12676                                 continue;
12677                         }
12678
12679                         get_occurance(val->occurance);
12680                         move = build_triple(state, OP_COPY, phi->type, val, 0,
12681                                 val->occurance);
12682                         move->u.block = eblock;
12683                         move->id |= TRIPLE_FLAG_PRE_SPLIT;
12684                         use_triple(val, move);
12685                         
12686                         slot[edge] = move;
12687                         unuse_triple(val, phi);
12688                         use_triple(move, phi);
12689
12690                         /* Walk up the dominator tree until I have found the appropriate block */
12691                         while(eblock && !tdominates(state, val, eblock->last)) {
12692                                 eblock = eblock->idom;
12693                         }
12694                         if (!eblock) {
12695                                 internal_error(state, phi, "Cannot find block dominated by %p",
12696                                         val);
12697                         }
12698
12699                         /* Walk through the block backwards to find
12700                          * an appropriate location for the OP_COPY.
12701                          */
12702                         for(ptr = eblock->last; ptr != eblock->first; ptr = ptr->prev) {
12703                                 struct triple **expr;
12704                                 if ((ptr == phi) || (ptr == val)) {
12705                                         goto out;
12706                                 }
12707                                 expr = triple_rhs(state, ptr, 0);
12708                                 for(;expr; expr = triple_rhs(state, ptr, expr)) {
12709                                         if ((*expr) == phi) {
12710                                                 goto out;
12711                                         }
12712                                 }
12713                         }
12714                 out:
12715                         if (triple_is_branch(state, ptr)) {
12716                                 internal_error(state, ptr,
12717                                         "Could not insert write to phi");
12718                         }
12719                         insert_triple(state, ptr->next, move);
12720                         if (eblock->last == ptr) {
12721                                 eblock->last = move;
12722                         }
12723                         transform_to_arch_instruction(state, move);
12724                 }
12725         }
12726         print_blocks(state, __func__, stdout);
12727 }
12728
12729 struct triple_reg_set {
12730         struct triple_reg_set *next;
12731         struct triple *member;
12732         struct triple *new;
12733 };
12734
12735 struct reg_block {
12736         struct block *block;
12737         struct triple_reg_set *in;
12738         struct triple_reg_set *out;
12739         int vertex;
12740 };
12741
12742 static int do_triple_set(struct triple_reg_set **head, 
12743         struct triple *member, struct triple *new_member)
12744 {
12745         struct triple_reg_set **ptr, *new;
12746         if (!member)
12747                 return 0;
12748         ptr = head;
12749         while(*ptr) {
12750                 if ((*ptr)->member == member) {
12751                         return 0;
12752                 }
12753                 ptr = &(*ptr)->next;
12754         }
12755         new = xcmalloc(sizeof(*new), "triple_set");
12756         new->member = member;
12757         new->new    = new_member;
12758         new->next   = *head;
12759         *head       = new;
12760         return 1;
12761 }
12762
12763 static void do_triple_unset(struct triple_reg_set **head, struct triple *member)
12764 {
12765         struct triple_reg_set *entry, **ptr;
12766         ptr = head;
12767         while(*ptr) {
12768                 entry = *ptr;
12769                 if (entry->member == member) {
12770                         *ptr = entry->next;
12771                         xfree(entry);
12772                         return;
12773                 }
12774                 else {
12775                         ptr = &entry->next;
12776                 }
12777         }
12778 }
12779
12780 static int in_triple(struct reg_block *rb, struct triple *in)
12781 {
12782         return do_triple_set(&rb->in, in, 0);
12783 }
12784 static void unin_triple(struct reg_block *rb, struct triple *unin)
12785 {
12786         do_triple_unset(&rb->in, unin);
12787 }
12788
12789 static int out_triple(struct reg_block *rb, struct triple *out)
12790 {
12791         return do_triple_set(&rb->out, out, 0);
12792 }
12793 static void unout_triple(struct reg_block *rb, struct triple *unout)
12794 {
12795         do_triple_unset(&rb->out, unout);
12796 }
12797
12798 static int initialize_regblock(struct reg_block *blocks,
12799         struct block *block, int vertex)
12800 {
12801         struct block_set *user;
12802         if (!block || (blocks[block->vertex].block == block)) {
12803                 return vertex;
12804         }
12805         vertex += 1;
12806         /* Renumber the blocks in a convinient fashion */
12807         block->vertex = vertex;
12808         blocks[vertex].block    = block;
12809         blocks[vertex].vertex   = vertex;
12810         for(user = block->use; user; user = user->next) {
12811                 vertex = initialize_regblock(blocks, user->member, vertex);
12812         }
12813         return vertex;
12814 }
12815
12816 static int phi_in(struct compile_state *state, struct reg_block *blocks,
12817         struct reg_block *rb, struct block *suc)
12818 {
12819         /* Read the conditional input set of a successor block
12820          * (i.e. the input to the phi nodes) and place it in the
12821          * current blocks output set.
12822          */
12823         struct block_set *set;
12824         struct triple *ptr;
12825         int edge;
12826         int done, change;
12827         change = 0;
12828         /* Find the edge I am coming in on */
12829         for(edge = 0, set = suc->use; set; set = set->next, edge++) {
12830                 if (set->member == rb->block) {
12831                         break;
12832                 }
12833         }
12834         if (!set) {
12835                 internal_error(state, 0, "Not coming on a control edge?");
12836         }
12837         for(done = 0, ptr = suc->first; !done; ptr = ptr->next) {
12838                 struct triple **slot, *expr, *ptr2;
12839                 int out_change, done2;
12840                 done = (ptr == suc->last);
12841                 if (ptr->op != OP_PHI) {
12842                         continue;
12843                 }
12844                 slot = &RHS(ptr, 0);
12845                 expr = slot[edge];
12846                 out_change = out_triple(rb, expr);
12847                 if (!out_change) {
12848                         continue;
12849                 }
12850                 /* If we don't define the variable also plast it
12851                  * in the current blocks input set.
12852                  */
12853                 ptr2 = rb->block->first;
12854                 for(done2 = 0; !done2; ptr2 = ptr2->next) {
12855                         if (ptr2 == expr) {
12856                                 break;
12857                         }
12858                         done2 = (ptr2 == rb->block->last);
12859                 }
12860                 if (!done2) {
12861                         continue;
12862                 }
12863                 change |= in_triple(rb, expr);
12864         }
12865         return change;
12866 }
12867
12868 static int reg_in(struct compile_state *state, struct reg_block *blocks,
12869         struct reg_block *rb, struct block *suc)
12870 {
12871         struct triple_reg_set *in_set;
12872         int change;
12873         change = 0;
12874         /* Read the input set of a successor block
12875          * and place it in the current blocks output set.
12876          */
12877         in_set = blocks[suc->vertex].in;
12878         for(; in_set; in_set = in_set->next) {
12879                 int out_change, done;
12880                 struct triple *first, *last, *ptr;
12881                 out_change = out_triple(rb, in_set->member);
12882                 if (!out_change) {
12883                         continue;
12884                 }
12885                 /* If we don't define the variable also place it
12886                  * in the current blocks input set.
12887                  */
12888                 first = rb->block->first;
12889                 last = rb->block->last;
12890                 done = 0;
12891                 for(ptr = first; !done; ptr = ptr->next) {
12892                         if (ptr == in_set->member) {
12893                                 break;
12894                         }
12895                         done = (ptr == last);
12896                 }
12897                 if (!done) {
12898                         continue;
12899                 }
12900                 change |= in_triple(rb, in_set->member);
12901         }
12902         change |= phi_in(state, blocks, rb, suc);
12903         return change;
12904 }
12905
12906
12907 static int use_in(struct compile_state *state, struct reg_block *rb)
12908 {
12909         /* Find the variables we use but don't define and add
12910          * it to the current blocks input set.
12911          */
12912 #warning "FIXME is this O(N^2) algorithm bad?"
12913         struct block *block;
12914         struct triple *ptr;
12915         int done;
12916         int change;
12917         block = rb->block;
12918         change = 0;
12919         for(done = 0, ptr = block->last; !done; ptr = ptr->prev) {
12920                 struct triple **expr;
12921                 done = (ptr == block->first);
12922                 /* The variable a phi function uses depends on the
12923                  * control flow, and is handled in phi_in, not
12924                  * here.
12925                  */
12926                 if (ptr->op == OP_PHI) {
12927                         continue;
12928                 }
12929                 expr = triple_rhs(state, ptr, 0);
12930                 for(;expr; expr = triple_rhs(state, ptr, expr)) {
12931                         struct triple *rhs, *test;
12932                         int tdone;
12933                         rhs = *expr;
12934                         if (!rhs) {
12935                                 continue;
12936                         }
12937                         /* See if rhs is defined in this block */
12938                         for(tdone = 0, test = ptr; !tdone; test = test->prev) {
12939                                 tdone = (test == block->first);
12940                                 if (test == rhs) {
12941                                         rhs = 0;
12942                                         break;
12943                                 }
12944                         }
12945                         /* If I still have a valid rhs add it to in */
12946                         change |= in_triple(rb, rhs);
12947                 }
12948         }
12949         return change;
12950 }
12951
12952 static struct reg_block *compute_variable_lifetimes(
12953         struct compile_state *state)
12954 {
12955         struct reg_block *blocks;
12956         int change;
12957         blocks = xcmalloc(
12958                 sizeof(*blocks)*(state->last_vertex + 1), "reg_block");
12959         initialize_regblock(blocks, state->last_block, 0);
12960         do {
12961                 int i;
12962                 change = 0;
12963                 for(i = 1; i <= state->last_vertex; i++) {
12964                         struct block_set *edge;
12965                         struct reg_block *rb;
12966                         rb = &blocks[i];
12967                         /* Add the all successor's input set to in */
12968                         for(edge = rb->block->edges; edge; edge = edge->next) {
12969                                 change |= reg_in(state, blocks, rb, edge->member);
12970                         }
12971                         /* Add use to in... */
12972                         change |= use_in(state, rb);
12973                 }
12974         } while(change);
12975         return blocks;
12976 }
12977
12978 static void free_variable_lifetimes(
12979         struct compile_state *state, struct reg_block *blocks)
12980 {
12981         int i;
12982         /* free in_set && out_set on each block */
12983         for(i = 1; i <= state->last_vertex; i++) {
12984                 struct triple_reg_set *entry, *next;
12985                 struct reg_block *rb;
12986                 rb = &blocks[i];
12987                 for(entry = rb->in; entry ; entry = next) {
12988                         next = entry->next;
12989                         do_triple_unset(&rb->in, entry->member);
12990                 }
12991                 for(entry = rb->out; entry; entry = next) {
12992                         next = entry->next;
12993                         do_triple_unset(&rb->out, entry->member);
12994                 }
12995         }
12996         xfree(blocks);
12997
12998 }
12999
13000 typedef void (*wvl_cb_t)(
13001         struct compile_state *state, 
13002         struct reg_block *blocks, struct triple_reg_set *live, 
13003         struct reg_block *rb, struct triple *ins, void *arg);
13004
13005 static void walk_variable_lifetimes(struct compile_state *state,
13006         struct reg_block *blocks, wvl_cb_t cb, void *arg)
13007 {
13008         int i;
13009         
13010         for(i = 1; i <= state->last_vertex; i++) {
13011                 struct triple_reg_set *live;
13012                 struct triple_reg_set *entry, *next;
13013                 struct triple *ptr, *prev;
13014                 struct reg_block *rb;
13015                 struct block *block;
13016                 int done;
13017
13018                 /* Get the blocks */
13019                 rb = &blocks[i];
13020                 block = rb->block;
13021
13022                 /* Copy out into live */
13023                 live = 0;
13024                 for(entry = rb->out; entry; entry = next) {
13025                         next = entry->next;
13026                         do_triple_set(&live, entry->member, entry->new);
13027                 }
13028                 /* Walk through the basic block calculating live */
13029                 for(done = 0, ptr = block->last; !done; ptr = prev) {
13030                         struct triple **expr;
13031
13032                         prev = ptr->prev;
13033                         done = (ptr == block->first);
13034
13035                         /* Ensure the current definition is in live */
13036                         if (triple_is_def(state, ptr)) {
13037                                 do_triple_set(&live, ptr, 0);
13038                         }
13039
13040                         /* Inform the callback function of what is
13041                          * going on.
13042                          */
13043                          cb(state, blocks, live, rb, ptr, arg);
13044                         
13045                         /* Remove the current definition from live */
13046                         do_triple_unset(&live, ptr);
13047
13048                         /* Add the current uses to live.
13049                          *
13050                          * It is safe to skip phi functions because they do
13051                          * not have any block local uses, and the block
13052                          * output sets already properly account for what
13053                          * control flow depedent uses phi functions do have.
13054                          */
13055                         if (ptr->op == OP_PHI) {
13056                                 continue;
13057                         }
13058                         expr = triple_rhs(state, ptr, 0);
13059                         for(;expr; expr = triple_rhs(state, ptr, expr)) {
13060                                 /* If the triple is not a definition skip it. */
13061                                 if (!*expr || !triple_is_def(state, *expr)) {
13062                                         continue;
13063                                 }
13064                                 do_triple_set(&live, *expr, 0);
13065                         }
13066                 }
13067                 /* Free live */
13068                 for(entry = live; entry; entry = next) {
13069                         next = entry->next;
13070                         do_triple_unset(&live, entry->member);
13071                 }
13072         }
13073 }
13074
13075 static int count_triples(struct compile_state *state)
13076 {
13077         struct triple *first, *ins;
13078         int triples = 0;
13079         first = state->first;
13080         ins = first;
13081         do {
13082                 triples++;
13083                 ins = ins->next;
13084         } while (ins != first);
13085         return triples;
13086 }
13087
13088
13089 struct dead_triple {
13090         struct triple *triple;
13091         struct dead_triple *work_next;
13092         struct block *block;
13093         int old_id;
13094         int flags;
13095 #define TRIPLE_FLAG_ALIVE 1
13096 };
13097
13098
13099 static void awaken(
13100         struct compile_state *state,
13101         struct dead_triple *dtriple, struct triple **expr,
13102         struct dead_triple ***work_list_tail)
13103 {
13104         struct triple *triple;
13105         struct dead_triple *dt;
13106         if (!expr) {
13107                 return;
13108         }
13109         triple = *expr;
13110         if (!triple) {
13111                 return;
13112         }
13113         if (triple->id <= 0)  {
13114                 internal_error(state, triple, "bad triple id: %d",
13115                         triple->id);
13116         }
13117         if (triple->op == OP_NOOP) {
13118                 internal_error(state, triple, "awakening noop?");
13119                 return;
13120         }
13121         dt = &dtriple[triple->id];
13122         if (!(dt->flags & TRIPLE_FLAG_ALIVE)) {
13123                 dt->flags |= TRIPLE_FLAG_ALIVE;
13124                 if (!dt->work_next) {
13125                         **work_list_tail = dt;
13126                         *work_list_tail = &dt->work_next;
13127                 }
13128         }
13129 }
13130
13131 static void eliminate_inefectual_code(struct compile_state *state)
13132 {
13133         struct block *block;
13134         struct dead_triple *dtriple, *work_list, **work_list_tail, *dt;
13135         int triples, i;
13136         struct triple *first, *final, *ins;
13137
13138         if (!(state->compiler->flags & COMPILER_ELIMINATE_INEFECTUAL_CODE)) {
13139                 return;
13140         }
13141
13142         /* Setup the work list */
13143         work_list = 0;
13144         work_list_tail = &work_list;
13145
13146         first = state->first;
13147         final = state->first->prev;
13148
13149         /* Count how many triples I have */
13150         triples = count_triples(state);
13151
13152         /* Now put then in an array and mark all of the triples dead */
13153         dtriple = xcmalloc(sizeof(*dtriple) * (triples + 1), "dtriples");
13154         
13155         ins = first;
13156         i = 1;
13157         block = 0;
13158         do {
13159                 dtriple[i].triple = ins;
13160                 dtriple[i].block  = block_of_triple(state, ins);
13161                 dtriple[i].flags  = 0;
13162                 dtriple[i].old_id = ins->id;
13163                 ins->id = i;
13164                 /* See if it is an operation we always keep */
13165                 if (!triple_is_pure(state, ins, dtriple[i].old_id)) {
13166                         awaken(state, dtriple, &ins, &work_list_tail);
13167                 }
13168                 i++;
13169                 ins = ins->next;
13170         } while(ins != first);
13171         while(work_list) {
13172                 struct block *block;
13173                 struct dead_triple *dt;
13174                 struct block_set *user;
13175                 struct triple **expr;
13176                 dt = work_list;
13177                 work_list = dt->work_next;
13178                 if (!work_list) {
13179                         work_list_tail = &work_list;
13180                 }
13181                 /* Make certain the block the current instruction is in lives */
13182                 block = block_of_triple(state, dt->triple);
13183                 awaken(state, dtriple, &block->first, &work_list_tail);
13184                 if (triple_is_branch(state, block->last)) {
13185                         awaken(state, dtriple, &block->last, &work_list_tail);
13186                 }
13187
13188                 /* Wake up the data depencencies of this triple */
13189                 expr = 0;
13190                 do {
13191                         expr = triple_rhs(state, dt->triple, expr);
13192                         awaken(state, dtriple, expr, &work_list_tail);
13193                 } while(expr);
13194                 do {
13195                         expr = triple_lhs(state, dt->triple, expr);
13196                         awaken(state, dtriple, expr, &work_list_tail);
13197                 } while(expr);
13198                 do {
13199                         expr = triple_misc(state, dt->triple, expr);
13200                         awaken(state, dtriple, expr, &work_list_tail);
13201                 } while(expr);
13202                 /* Wake up the forward control dependencies */
13203                 do {
13204                         expr = triple_targ(state, dt->triple, expr);
13205                         awaken(state, dtriple, expr, &work_list_tail);
13206                 } while(expr);
13207                 /* Wake up the reverse control dependencies of this triple */
13208                 for(user = dt->block->ipdomfrontier; user; user = user->next) {
13209                         struct triple *last;
13210                         last = user->member->last;
13211                         while((last->op == OP_NOOP) && (last != user->member->first)) {
13212                                 internal_warning(state, last, "awakening noop?");
13213                                 last = last->prev;
13214                         }
13215                         awaken(state, dtriple, &last, &work_list_tail);
13216                 }
13217         }
13218         for(dt = &dtriple[1]; dt <= &dtriple[triples]; dt++) {
13219                 if ((dt->triple->op == OP_NOOP) && 
13220                         (dt->flags & TRIPLE_FLAG_ALIVE)) {
13221                         internal_error(state, dt->triple, "noop effective?");
13222                 }
13223                 dt->triple->id = dt->old_id;    /* Restore the color */
13224                 if (!(dt->flags & TRIPLE_FLAG_ALIVE)) {
13225                         release_triple(state, dt->triple);
13226                 }
13227         }
13228         xfree(dtriple);
13229
13230         rebuild_ssa_form(state);
13231
13232         print_blocks(state, __func__, stdout);
13233 }
13234
13235
13236 static void insert_mandatory_copies(struct compile_state *state)
13237 {
13238         struct triple *ins, *first;
13239
13240         /* The object is with a minimum of inserted copies,
13241          * to resolve in fundamental register conflicts between
13242          * register value producers and consumers.
13243          * Theoretically we may be greater than minimal when we
13244          * are inserting copies before instructions but that
13245          * case should be rare.
13246          */
13247         first = state->first;
13248         ins = first;
13249         do {
13250                 struct triple_set *entry, *next;
13251                 struct triple *tmp;
13252                 struct reg_info info;
13253                 unsigned reg, regcm;
13254                 int do_post_copy, do_pre_copy;
13255                 tmp = 0;
13256                 if (!triple_is_def(state, ins)) {
13257                         goto next;
13258                 }
13259                 /* Find the architecture specific color information */
13260                 info = arch_reg_lhs(state, ins, 0);
13261                 if (info.reg >= MAX_REGISTERS) {
13262                         info.reg = REG_UNSET;
13263                 }
13264                 
13265                 reg = REG_UNSET;
13266                 regcm = arch_type_to_regcm(state, ins->type);
13267                 do_post_copy = do_pre_copy = 0;
13268
13269                 /* Walk through the uses of ins and check for conflicts */
13270                 for(entry = ins->use; entry; entry = next) {
13271                         struct reg_info rinfo;
13272                         int i;
13273                         next = entry->next;
13274                         i = find_rhs_use(state, entry->member, ins);
13275                         if (i < 0) {
13276                                 continue;
13277                         }
13278                         
13279                         /* Find the users color requirements */
13280                         rinfo = arch_reg_rhs(state, entry->member, i);
13281                         if (rinfo.reg >= MAX_REGISTERS) {
13282                                 rinfo.reg = REG_UNSET;
13283                         }
13284                         
13285                         /* See if I need a pre_copy */
13286                         if (rinfo.reg != REG_UNSET) {
13287                                 if ((reg != REG_UNSET) && (reg != rinfo.reg)) {
13288                                         do_pre_copy = 1;
13289                                 }
13290                                 reg = rinfo.reg;
13291                         }
13292                         regcm &= rinfo.regcm;
13293                         regcm = arch_regcm_normalize(state, regcm);
13294                         if (regcm == 0) {
13295                                 do_pre_copy = 1;
13296                         }
13297                         /* Always use pre_copies for constants.
13298                          * They do not take up any registers until a
13299                          * copy places them in one.
13300                          */
13301                         if ((info.reg == REG_UNNEEDED) && 
13302                                 (rinfo.reg != REG_UNNEEDED)) {
13303                                 do_pre_copy = 1;
13304                         }
13305                 }
13306                 do_post_copy =
13307                         !do_pre_copy &&
13308                         (((info.reg != REG_UNSET) && 
13309                                 (reg != REG_UNSET) &&
13310                                 (info.reg != reg)) ||
13311                         ((info.regcm & regcm) == 0));
13312
13313                 reg = info.reg;
13314                 regcm = info.regcm;
13315                 /* Walk through the uses of ins and do a pre_copy or see if a post_copy is warranted */
13316                 for(entry = ins->use; entry; entry = next) {
13317                         struct reg_info rinfo;
13318                         int i;
13319                         next = entry->next;
13320                         i = find_rhs_use(state, entry->member, ins);
13321                         if (i < 0) {
13322                                 continue;
13323                         }
13324                         
13325                         /* Find the users color requirements */
13326                         rinfo = arch_reg_rhs(state, entry->member, i);
13327                         if (rinfo.reg >= MAX_REGISTERS) {
13328                                 rinfo.reg = REG_UNSET;
13329                         }
13330
13331                         /* Now see if it is time to do the pre_copy */
13332                         if (rinfo.reg != REG_UNSET) {
13333                                 if (((reg != REG_UNSET) && (reg != rinfo.reg)) ||
13334                                         ((regcm & rinfo.regcm) == 0) ||
13335                                         /* Don't let a mandatory coalesce sneak
13336                                          * into a operation that is marked to prevent
13337                                          * coalescing.
13338                                          */
13339                                         ((reg != REG_UNNEEDED) &&
13340                                         ((ins->id & TRIPLE_FLAG_POST_SPLIT) ||
13341                                         (entry->member->id & TRIPLE_FLAG_PRE_SPLIT)))
13342                                         ) {
13343                                         if (do_pre_copy) {
13344                                                 struct triple *user;
13345                                                 user = entry->member;
13346                                                 if (RHS(user, i) != ins) {
13347                                                         internal_error(state, user, "bad rhs");
13348                                                 }
13349                                                 tmp = pre_copy(state, user, i);
13350                                                 tmp->id |= TRIPLE_FLAG_PRE_SPLIT;
13351                                                 continue;
13352                                         } else {
13353                                                 do_post_copy = 1;
13354                                         }
13355                                 }
13356                                 reg = rinfo.reg;
13357                         }
13358                         if ((regcm & rinfo.regcm) == 0) {
13359                                 if (do_pre_copy) {
13360                                         struct triple *user;
13361                                         user = entry->member;
13362                                         if (RHS(user, i) != ins) {
13363                                                 internal_error(state, user, "bad rhs");
13364                                         }
13365                                         tmp = pre_copy(state, user, i);
13366                                         tmp->id |= TRIPLE_FLAG_PRE_SPLIT;
13367                                         continue;
13368                                 } else {
13369                                         do_post_copy = 1;
13370                                 }
13371                         }
13372                         regcm &= rinfo.regcm;
13373                         
13374                 }
13375                 if (do_post_copy) {
13376                         struct reg_info pre, post;
13377                         tmp = post_copy(state, ins);
13378                         tmp->id |= TRIPLE_FLAG_PRE_SPLIT;
13379                         pre = arch_reg_lhs(state, ins, 0);
13380                         post = arch_reg_lhs(state, tmp, 0);
13381                         if ((pre.reg == post.reg) && (pre.regcm == post.regcm)) {
13382                                 internal_error(state, tmp, "useless copy");
13383                         }
13384                 }
13385         next:
13386                 ins = ins->next;
13387         } while(ins != first);
13388
13389         print_blocks(state, __func__, stdout);
13390 }
13391
13392
13393 struct live_range_edge;
13394 struct live_range_def;
13395 struct live_range {
13396         struct live_range_edge *edges;
13397         struct live_range_def *defs;
13398 /* Note. The list pointed to by defs is kept in order.
13399  * That is baring splits in the flow control
13400  * defs dominates defs->next wich dominates defs->next->next
13401  * etc.
13402  */
13403         unsigned color;
13404         unsigned classes;
13405         unsigned degree;
13406         unsigned length;
13407         struct live_range *group_next, **group_prev;
13408 };
13409
13410 struct live_range_edge {
13411         struct live_range_edge *next;
13412         struct live_range *node;
13413 };
13414
13415 struct live_range_def {
13416         struct live_range_def *next;
13417         struct live_range_def *prev;
13418         struct live_range *lr;
13419         struct triple *def;
13420         unsigned orig_id;
13421 };
13422
13423 #define LRE_HASH_SIZE 2048
13424 struct lre_hash {
13425         struct lre_hash *next;
13426         struct live_range *left;
13427         struct live_range *right;
13428 };
13429
13430
13431 struct reg_state {
13432         struct lre_hash *hash[LRE_HASH_SIZE];
13433         struct reg_block *blocks;
13434         struct live_range_def *lrd;
13435         struct live_range *lr;
13436         struct live_range *low, **low_tail;
13437         struct live_range *high, **high_tail;
13438         unsigned defs;
13439         unsigned ranges;
13440         int passes, max_passes;
13441 };
13442
13443
13444
13445 struct print_interference_block_info {
13446         struct reg_state *rstate;
13447         FILE *fp;
13448         int need_edges;
13449 };
13450 static void print_interference_block(
13451         struct compile_state *state, struct block *block, void *arg)
13452
13453 {
13454         struct print_interference_block_info *info = arg;
13455         struct reg_state *rstate = info->rstate;
13456         struct block_set *edge;
13457         FILE *fp = info->fp;
13458         struct reg_block *rb;
13459         struct triple *ptr;
13460         int phi_present;
13461         int done;
13462         rb = &rstate->blocks[block->vertex];
13463
13464         fprintf(fp, "\nblock: %p (%d),",
13465                 block,  block->vertex);
13466         for(edge = block->edges; edge; edge = edge->next) {
13467                 fprintf(fp, " %p<-%p",
13468                         edge->member, 
13469                         edge->member && edge->member->use?edge->member->use->member : 0);
13470         }
13471         fprintf(fp, "\n");
13472         if (rb->in) {
13473                 struct triple_reg_set *in_set;
13474                 fprintf(fp, "        in:");
13475                 for(in_set = rb->in; in_set; in_set = in_set->next) {
13476                         fprintf(fp, " %-10p", in_set->member);
13477                 }
13478                 fprintf(fp, "\n");
13479         }
13480         phi_present = 0;
13481         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
13482                 done = (ptr == block->last);
13483                 if (ptr->op == OP_PHI) {
13484                         phi_present = 1;
13485                         break;
13486                 }
13487         }
13488         if (phi_present) {
13489                 int edge;
13490                 for(edge = 0; edge < block->users; edge++) {
13491                         fprintf(fp, "     in(%d):", edge);
13492                         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
13493                                 struct triple **slot;
13494                                 done = (ptr == block->last);
13495                                 if (ptr->op != OP_PHI) {
13496                                         continue;
13497                                 }
13498                                 slot = &RHS(ptr, 0);
13499                                 fprintf(fp, " %-10p", slot[edge]);
13500                         }
13501                         fprintf(fp, "\n");
13502                 }
13503         }
13504         if (block->first->op == OP_LABEL) {
13505                 fprintf(fp, "%p:\n", block->first);
13506         }
13507         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
13508                 struct live_range *lr;
13509                 unsigned id;
13510                 int op;
13511                 op = ptr->op;
13512                 done = (ptr == block->last);
13513                 lr = rstate->lrd[ptr->id].lr;
13514                 
13515                 id = ptr->id;
13516                 ptr->id = rstate->lrd[id].orig_id;
13517                 SET_REG(ptr->id, lr->color);
13518                 display_triple(fp, ptr);
13519                 ptr->id = id;
13520
13521                 if (triple_is_def(state, ptr) && (lr->defs == 0)) {
13522                         internal_error(state, ptr, "lr has no defs!");
13523                 }
13524                 if (info->need_edges) {
13525                         if (lr->defs) {
13526                                 struct live_range_def *lrd;
13527                                 fprintf(fp, "       range:");
13528                                 lrd = lr->defs;
13529                                 do {
13530                                         fprintf(fp, " %-10p", lrd->def);
13531                                         lrd = lrd->next;
13532                                 } while(lrd != lr->defs);
13533                                 fprintf(fp, "\n");
13534                         }
13535                         if (lr->edges > 0) {
13536                                 struct live_range_edge *edge;
13537                                 fprintf(fp, "       edges:");
13538                                 for(edge = lr->edges; edge; edge = edge->next) {
13539                                         struct live_range_def *lrd;
13540                                         lrd = edge->node->defs;
13541                                         do {
13542                                                 fprintf(fp, " %-10p", lrd->def);
13543                                                 lrd = lrd->next;
13544                                         } while(lrd != edge->node->defs);
13545                                         fprintf(fp, "|");
13546                                 }
13547                                 fprintf(fp, "\n");
13548                         }
13549                 }
13550                 /* Do a bunch of sanity checks */
13551                 valid_ins(state, ptr);
13552                 if ((ptr->id < 0) || (ptr->id > rstate->defs)) {
13553                         internal_error(state, ptr, "Invalid triple id: %d",
13554                                 ptr->id);
13555                 }
13556         }
13557         if (rb->out) {
13558                 struct triple_reg_set *out_set;
13559                 fprintf(fp, "       out:");
13560                 for(out_set = rb->out; out_set; out_set = out_set->next) {
13561                         fprintf(fp, " %-10p", out_set->member);
13562                 }
13563                 fprintf(fp, "\n");
13564         }
13565         fprintf(fp, "\n");
13566 }
13567
13568 static void print_interference_blocks(
13569         struct compile_state *state, struct reg_state *rstate, FILE *fp, int need_edges)
13570 {
13571         struct print_interference_block_info info;
13572         info.rstate = rstate;
13573         info.fp = fp;
13574         info.need_edges = need_edges;
13575         fprintf(fp, "\nlive variables by block\n");
13576         walk_blocks(state, print_interference_block, &info);
13577
13578 }
13579
13580 static unsigned regc_max_size(struct compile_state *state, int classes)
13581 {
13582         unsigned max_size;
13583         int i;
13584         max_size = 0;
13585         for(i = 0; i < MAX_REGC; i++) {
13586                 if (classes & (1 << i)) {
13587                         unsigned size;
13588                         size = arch_regc_size(state, i);
13589                         if (size > max_size) {
13590                                 max_size = size;
13591                         }
13592                 }
13593         }
13594         return max_size;
13595 }
13596
13597 static int reg_is_reg(struct compile_state *state, int reg1, int reg2)
13598 {
13599         unsigned equivs[MAX_REG_EQUIVS];
13600         int i;
13601         if ((reg1 < 0) || (reg1 >= MAX_REGISTERS)) {
13602                 internal_error(state, 0, "invalid register");
13603         }
13604         if ((reg2 < 0) || (reg2 >= MAX_REGISTERS)) {
13605                 internal_error(state, 0, "invalid register");
13606         }
13607         arch_reg_equivs(state, equivs, reg1);
13608         for(i = 0; (i < MAX_REG_EQUIVS) && equivs[i] != REG_UNSET; i++) {
13609                 if (equivs[i] == reg2) {
13610                         return 1;
13611                 }
13612         }
13613         return 0;
13614 }
13615
13616 static void reg_fill_used(struct compile_state *state, char *used, int reg)
13617 {
13618         unsigned equivs[MAX_REG_EQUIVS];
13619         int i;
13620         if (reg == REG_UNNEEDED) {
13621                 return;
13622         }
13623         arch_reg_equivs(state, equivs, reg);
13624         for(i = 0; (i < MAX_REG_EQUIVS) && equivs[i] != REG_UNSET; i++) {
13625                 used[equivs[i]] = 1;
13626         }
13627         return;
13628 }
13629
13630 static void reg_inc_used(struct compile_state *state, char *used, int reg)
13631 {
13632         unsigned equivs[MAX_REG_EQUIVS];
13633         int i;
13634         if (reg == REG_UNNEEDED) {
13635                 return;
13636         }
13637         arch_reg_equivs(state, equivs, reg);
13638         for(i = 0; (i < MAX_REG_EQUIVS) && equivs[i] != REG_UNSET; i++) {
13639                 used[equivs[i]] += 1;
13640         }
13641         return;
13642 }
13643
13644 static unsigned int hash_live_edge(
13645         struct live_range *left, struct live_range *right)
13646 {
13647         unsigned int hash, val;
13648         unsigned long lval, rval;
13649         lval = ((unsigned long)left)/sizeof(struct live_range);
13650         rval = ((unsigned long)right)/sizeof(struct live_range);
13651         hash = 0;
13652         while(lval) {
13653                 val = lval & 0xff;
13654                 lval >>= 8;
13655                 hash = (hash *263) + val;
13656         }
13657         while(rval) {
13658                 val = rval & 0xff;
13659                 rval >>= 8;
13660                 hash = (hash *263) + val;
13661         }
13662         hash = hash & (LRE_HASH_SIZE - 1);
13663         return hash;
13664 }
13665
13666 static struct lre_hash **lre_probe(struct reg_state *rstate,
13667         struct live_range *left, struct live_range *right)
13668 {
13669         struct lre_hash **ptr;
13670         unsigned int index;
13671         /* Ensure left <= right */
13672         if (left > right) {
13673                 struct live_range *tmp;
13674                 tmp = left;
13675                 left = right;
13676                 right = tmp;
13677         }
13678         index = hash_live_edge(left, right);
13679         
13680         ptr = &rstate->hash[index];
13681         while(*ptr) {
13682                 if (((*ptr)->left == left) && ((*ptr)->right == right)) {
13683                         break;
13684                 }
13685                 ptr = &(*ptr)->next;
13686         }
13687         return ptr;
13688 }
13689
13690 static int interfere(struct reg_state *rstate,
13691         struct live_range *left, struct live_range *right)
13692 {
13693         struct lre_hash **ptr;
13694         ptr = lre_probe(rstate, left, right);
13695         return ptr && *ptr;
13696 }
13697
13698 static void add_live_edge(struct reg_state *rstate, 
13699         struct live_range *left, struct live_range *right)
13700 {
13701         /* FIXME the memory allocation overhead is noticeable here... */
13702         struct lre_hash **ptr, *new_hash;
13703         struct live_range_edge *edge;
13704
13705         if (left == right) {
13706                 return;
13707         }
13708         if ((left == &rstate->lr[0]) || (right == &rstate->lr[0])) {
13709                 return;
13710         }
13711         /* Ensure left <= right */
13712         if (left > right) {
13713                 struct live_range *tmp;
13714                 tmp = left;
13715                 left = right;
13716                 right = tmp;
13717         }
13718         ptr = lre_probe(rstate, left, right);
13719         if (*ptr) {
13720                 return;
13721         }
13722 #if 0
13723         fprintf(stderr, "new_live_edge(%p, %p)\n",
13724                 left, right);
13725 #endif
13726         new_hash = xmalloc(sizeof(*new_hash), "lre_hash");
13727         new_hash->next  = *ptr;
13728         new_hash->left  = left;
13729         new_hash->right = right;
13730         *ptr = new_hash;
13731
13732         edge = xmalloc(sizeof(*edge), "live_range_edge");
13733         edge->next   = left->edges;
13734         edge->node   = right;
13735         left->edges  = edge;
13736         left->degree += 1;
13737         
13738         edge = xmalloc(sizeof(*edge), "live_range_edge");
13739         edge->next    = right->edges;
13740         edge->node    = left;
13741         right->edges  = edge;
13742         right->degree += 1;
13743 }
13744
13745 static void remove_live_edge(struct reg_state *rstate,
13746         struct live_range *left, struct live_range *right)
13747 {
13748         struct live_range_edge *edge, **ptr;
13749         struct lre_hash **hptr, *entry;
13750         hptr = lre_probe(rstate, left, right);
13751         if (!hptr || !*hptr) {
13752                 return;
13753         }
13754         entry = *hptr;
13755         *hptr = entry->next;
13756         xfree(entry);
13757
13758         for(ptr = &left->edges; *ptr; ptr = &(*ptr)->next) {
13759                 edge = *ptr;
13760                 if (edge->node == right) {
13761                         *ptr = edge->next;
13762                         memset(edge, 0, sizeof(*edge));
13763                         xfree(edge);
13764                         right->degree--;
13765                         break;
13766                 }
13767         }
13768         for(ptr = &right->edges; *ptr; ptr = &(*ptr)->next) {
13769                 edge = *ptr;
13770                 if (edge->node == left) {
13771                         *ptr = edge->next;
13772                         memset(edge, 0, sizeof(*edge));
13773                         xfree(edge);
13774                         left->degree--;
13775                         break;
13776                 }
13777         }
13778 }
13779
13780 static void remove_live_edges(struct reg_state *rstate, struct live_range *range)
13781 {
13782         struct live_range_edge *edge, *next;
13783         for(edge = range->edges; edge; edge = next) {
13784                 next = edge->next;
13785                 remove_live_edge(rstate, range, edge->node);
13786         }
13787 }
13788
13789 static void transfer_live_edges(struct reg_state *rstate, 
13790         struct live_range *dest, struct live_range *src)
13791 {
13792         struct live_range_edge *edge, *next;
13793         for(edge = src->edges; edge; edge = next) {
13794                 struct live_range *other;
13795                 next = edge->next;
13796                 other = edge->node;
13797                 remove_live_edge(rstate, src, other);
13798                 add_live_edge(rstate, dest, other);
13799         }
13800 }
13801
13802
13803 /* Interference graph...
13804  * 
13805  * new(n) --- Return a graph with n nodes but no edges.
13806  * add(g,x,y) --- Return a graph including g with an between x and y
13807  * interfere(g, x, y) --- Return true if there exists an edge between the nodes
13808  *                x and y in the graph g
13809  * degree(g, x) --- Return the degree of the node x in the graph g
13810  * neighbors(g, x, f) --- Apply function f to each neighbor of node x in the graph g
13811  *
13812  * Implement with a hash table && a set of adjcency vectors.
13813  * The hash table supports constant time implementations of add and interfere.
13814  * The adjacency vectors support an efficient implementation of neighbors.
13815  */
13816
13817 /* 
13818  *     +---------------------------------------------------+
13819  *     |         +--------------+                          |
13820  *     v         v              |                          |
13821  * renumber -> build graph -> colalesce -> spill_costs -> simplify -> select 
13822  *
13823  * -- In simplify implment optimistic coloring... (No backtracking)
13824  * -- Implement Rematerialization it is the only form of spilling we can perform
13825  *    Essentially this means dropping a constant from a register because
13826  *    we can regenerate it later.
13827  *
13828  * --- Very conservative colalescing (don't colalesce just mark the opportunities)
13829  *     coalesce at phi points...
13830  * --- Bias coloring if at all possible do the coalesing a compile time.
13831  *
13832  *
13833  */
13834
13835 static void different_colored(
13836         struct compile_state *state, struct reg_state *rstate, 
13837         struct triple *parent, struct triple *ins)
13838 {
13839         struct live_range *lr;
13840         struct triple **expr;
13841         lr = rstate->lrd[ins->id].lr;
13842         expr = triple_rhs(state, ins, 0);
13843         for(;expr; expr = triple_rhs(state, ins, expr)) {
13844                 struct live_range *lr2;
13845                 if (!*expr || (*expr == parent) || (*expr == ins)) {
13846                         continue;
13847                 }
13848                 lr2 = rstate->lrd[(*expr)->id].lr;
13849                 if (lr->color == lr2->color) {
13850                         internal_error(state, ins, "live range too big");
13851                 }
13852         }
13853 }
13854
13855
13856 static struct live_range *coalesce_ranges(
13857         struct compile_state *state, struct reg_state *rstate,
13858         struct live_range *lr1, struct live_range *lr2)
13859 {
13860         struct live_range_def *head, *mid1, *mid2, *end, *lrd;
13861         unsigned color;
13862         unsigned classes;
13863         if (lr1 == lr2) {
13864                 return lr1;
13865         }
13866         if (!lr1->defs || !lr2->defs) {
13867                 internal_error(state, 0,
13868                         "cannot coalese dead live ranges");
13869         }
13870         if ((lr1->color == REG_UNNEEDED) ||
13871                 (lr2->color == REG_UNNEEDED)) {
13872                 internal_error(state, 0, 
13873                         "cannot coalesce live ranges without a possible color");
13874         }
13875         if ((lr1->color != lr2->color) &&
13876                 (lr1->color != REG_UNSET) &&
13877                 (lr2->color != REG_UNSET)) {
13878                 internal_error(state, lr1->defs->def, 
13879                         "cannot coalesce live ranges of different colors");
13880         }
13881         color = lr1->color;
13882         if (color == REG_UNSET) {
13883                 color = lr2->color;
13884         }
13885         classes = lr1->classes & lr2->classes;
13886         if (!classes) {
13887                 internal_error(state, lr1->defs->def,
13888                         "cannot coalesce live ranges with dissimilar register classes");
13889         }
13890         if (state->compiler->debug & DEBUG_COALESCING) {
13891                 fprintf(stderr, "coalescing:");
13892                 lrd = lr1->defs;
13893                 do {
13894                         fprintf(stderr, " %p", lrd->def);
13895                         lrd = lrd->next;
13896                 } while(lrd != lr1->defs);
13897                 fprintf(stderr, " |");
13898                 lrd = lr2->defs;
13899                 do {
13900                         fprintf(stderr, " %p", lrd->def);
13901                         lrd = lrd->next;
13902                 } while(lrd != lr2->defs);
13903                 fprintf(stderr, "\n");
13904         }
13905         /* If there is a clear dominate live range put it in lr1,
13906          * For purposes of this test phi functions are
13907          * considered dominated by the definitions that feed into
13908          * them. 
13909          */
13910         if ((lr1->defs->prev->def->op == OP_PHI) ||
13911                 ((lr2->defs->prev->def->op != OP_PHI) &&
13912                 tdominates(state, lr2->defs->def, lr1->defs->def))) {
13913                 struct live_range *tmp;
13914                 tmp = lr1;
13915                 lr1 = lr2;
13916                 lr2 = tmp;
13917         }
13918 #if 0
13919         if (lr1->defs->orig_id  & TRIPLE_FLAG_POST_SPLIT) {
13920                 fprintf(stderr, "lr1 post\n");
13921         }
13922         if (lr1->defs->orig_id & TRIPLE_FLAG_PRE_SPLIT) {
13923                 fprintf(stderr, "lr1 pre\n");
13924         }
13925         if (lr2->defs->orig_id  & TRIPLE_FLAG_POST_SPLIT) {
13926                 fprintf(stderr, "lr2 post\n");
13927         }
13928         if (lr2->defs->orig_id & TRIPLE_FLAG_PRE_SPLIT) {
13929                 fprintf(stderr, "lr2 pre\n");
13930         }
13931 #endif
13932 #if 0
13933         fprintf(stderr, "coalesce color1(%p): %3d color2(%p) %3d\n",
13934                 lr1->defs->def,
13935                 lr1->color,
13936                 lr2->defs->def,
13937                 lr2->color);
13938 #endif
13939         
13940         /* Append lr2 onto lr1 */
13941 #warning "FIXME should this be a merge instead of a splice?"
13942         /* This FIXME item applies to the correctness of live_range_end 
13943          * and to the necessity of making multiple passes of coalesce_live_ranges.
13944          * A failure to find some coalesce opportunities in coaleace_live_ranges
13945          * does not impact the correct of the compiler just the efficiency with
13946          * which registers are allocated.
13947          */
13948         head = lr1->defs;
13949         mid1 = lr1->defs->prev;
13950         mid2 = lr2->defs;
13951         end  = lr2->defs->prev;
13952         
13953         head->prev = end;
13954         end->next  = head;
13955
13956         mid1->next = mid2;
13957         mid2->prev = mid1;
13958
13959         /* Fixup the live range in the added live range defs */
13960         lrd = head;
13961         do {
13962                 lrd->lr = lr1;
13963                 lrd = lrd->next;
13964         } while(lrd != head);
13965
13966         /* Mark lr2 as free. */
13967         lr2->defs = 0;
13968         lr2->color = REG_UNNEEDED;
13969         lr2->classes = 0;
13970
13971         if (!lr1->defs) {
13972                 internal_error(state, 0, "lr1->defs == 0 ?");
13973         }
13974
13975         lr1->color   = color;
13976         lr1->classes = classes;
13977
13978         /* Keep the graph in sync by transfering the edges from lr2 to lr1 */
13979         transfer_live_edges(rstate, lr1, lr2);
13980
13981         return lr1;
13982 }
13983
13984 static struct live_range_def *live_range_head(
13985         struct compile_state *state, struct live_range *lr,
13986         struct live_range_def *last)
13987 {
13988         struct live_range_def *result;
13989         result = 0;
13990         if (last == 0) {
13991                 result = lr->defs;
13992         }
13993         else if (!tdominates(state, lr->defs->def, last->next->def)) {
13994                 result = last->next;
13995         }
13996         return result;
13997 }
13998
13999 static struct live_range_def *live_range_end(
14000         struct compile_state *state, struct live_range *lr,
14001         struct live_range_def *last)
14002 {
14003         struct live_range_def *result;
14004         result = 0;
14005         if (last == 0) {
14006                 result = lr->defs->prev;
14007         }
14008         else if (!tdominates(state, last->prev->def, lr->defs->prev->def)) {
14009                 result = last->prev;
14010         }
14011         return result;
14012 }
14013
14014
14015 static void initialize_live_ranges(
14016         struct compile_state *state, struct reg_state *rstate)
14017 {
14018         struct triple *ins, *first;
14019         size_t count, size;
14020         int i, j;
14021
14022         first = state->first;
14023         /* First count how many instructions I have.
14024          */
14025         count = count_triples(state);
14026         /* Potentially I need one live range definitions for each
14027          * instruction.
14028          */
14029         rstate->defs = count;
14030         /* Potentially I need one live range for each instruction
14031          * plus an extra for the dummy live range.
14032          */
14033         rstate->ranges = count + 1;
14034         size = sizeof(rstate->lrd[0]) * rstate->defs;
14035         rstate->lrd = xcmalloc(size, "live_range_def");
14036         size = sizeof(rstate->lr[0]) * rstate->ranges;
14037         rstate->lr  = xcmalloc(size, "live_range");
14038
14039         /* Setup the dummy live range */
14040         rstate->lr[0].classes = 0;
14041         rstate->lr[0].color = REG_UNSET;
14042         rstate->lr[0].defs = 0;
14043         i = j = 0;
14044         ins = first;
14045         do {
14046                 /* If the triple is a variable give it a live range */
14047                 if (triple_is_def(state, ins)) {
14048                         struct reg_info info;
14049                         /* Find the architecture specific color information */
14050                         info = find_def_color(state, ins);
14051                         i++;
14052                         rstate->lr[i].defs    = &rstate->lrd[j];
14053                         rstate->lr[i].color   = info.reg;
14054                         rstate->lr[i].classes = info.regcm;
14055                         rstate->lr[i].degree  = 0;
14056                         rstate->lrd[j].lr = &rstate->lr[i];
14057                 } 
14058                 /* Otherwise give the triple the dummy live range. */
14059                 else {
14060                         rstate->lrd[j].lr = &rstate->lr[0];
14061                 }
14062
14063                 /* Initalize the live_range_def */
14064                 rstate->lrd[j].next    = &rstate->lrd[j];
14065                 rstate->lrd[j].prev    = &rstate->lrd[j];
14066                 rstate->lrd[j].def     = ins;
14067                 rstate->lrd[j].orig_id = ins->id;
14068                 ins->id = j;
14069
14070                 j++;
14071                 ins = ins->next;
14072         } while(ins != first);
14073         rstate->ranges = i;
14074
14075         /* Make a second pass to handle achitecture specific register
14076          * constraints.
14077          */
14078         ins = first;
14079         do {
14080                 int zlhs, zrhs, i, j;
14081                 if (ins->id > rstate->defs) {
14082                         internal_error(state, ins, "bad id");
14083                 }
14084                 
14085                 /* Walk through the template of ins and coalesce live ranges */
14086                 zlhs = TRIPLE_LHS(ins->sizes);
14087                 if ((zlhs == 0) && triple_is_def(state, ins)) {
14088                         zlhs = 1;
14089                 }
14090                 zrhs = TRIPLE_RHS(ins->sizes);
14091
14092                 if (state->compiler->debug & DEBUG_COALESCING2) {
14093                         fprintf(stderr, "mandatory coalesce: %p %d %d\n",
14094                                 ins, zlhs, zrhs);
14095                 }
14096
14097                 for(i = 0; i < zlhs; i++) {
14098                         struct reg_info linfo;
14099                         struct live_range_def *lhs;
14100                         linfo = arch_reg_lhs(state, ins, i);
14101                         if (linfo.reg < MAX_REGISTERS) {
14102                                 continue;
14103                         }
14104                         if (triple_is_def(state, ins)) {
14105                                 lhs = &rstate->lrd[ins->id];
14106                         } else {
14107                                 lhs = &rstate->lrd[LHS(ins, i)->id];
14108                         }
14109
14110                         if (state->compiler->debug & DEBUG_COALESCING2) {
14111                                 fprintf(stderr, "coalesce lhs(%d): %p %d\n",
14112                                         i, lhs, linfo.reg);
14113                         }
14114
14115                         for(j = 0; j < zrhs; j++) {
14116                                 struct reg_info rinfo;
14117                                 struct live_range_def *rhs;
14118                                 rinfo = arch_reg_rhs(state, ins, j);
14119                                 if (rinfo.reg < MAX_REGISTERS) {
14120                                         continue;
14121                                 }
14122                                 rhs = &rstate->lrd[RHS(ins, j)->id];
14123
14124                                 if (state->compiler->debug & DEBUG_COALESCING2) {
14125                                         fprintf(stderr, "coalesce rhs(%d): %p %d\n",
14126                                                 j, rhs, rinfo.reg);
14127                                 }
14128
14129                                 if (rinfo.reg == linfo.reg) {
14130                                         coalesce_ranges(state, rstate, 
14131                                                 lhs->lr, rhs->lr);
14132                                 }
14133                         }
14134                 }
14135                 ins = ins->next;
14136         } while(ins != first);
14137 }
14138
14139 static void graph_ins(
14140         struct compile_state *state, 
14141         struct reg_block *blocks, struct triple_reg_set *live, 
14142         struct reg_block *rb, struct triple *ins, void *arg)
14143 {
14144         struct reg_state *rstate = arg;
14145         struct live_range *def;
14146         struct triple_reg_set *entry;
14147
14148         /* If the triple is not a definition
14149          * we do not have a definition to add to
14150          * the interference graph.
14151          */
14152         if (!triple_is_def(state, ins)) {
14153                 return;
14154         }
14155         def = rstate->lrd[ins->id].lr;
14156         
14157         /* Create an edge between ins and everything that is
14158          * alive, unless the live_range cannot share
14159          * a physical register with ins.
14160          */
14161         for(entry = live; entry; entry = entry->next) {
14162                 struct live_range *lr;
14163                 if ((entry->member->id < 0) || (entry->member->id > rstate->defs)) {
14164                         internal_error(state, 0, "bad entry?");
14165                 }
14166                 lr = rstate->lrd[entry->member->id].lr;
14167                 if (def == lr) {
14168                         continue;
14169                 }
14170                 if (!arch_regcm_intersect(def->classes, lr->classes)) {
14171                         continue;
14172                 }
14173                 add_live_edge(rstate, def, lr);
14174         }
14175         return;
14176 }
14177
14178 static struct live_range *get_verify_live_range(
14179         struct compile_state *state, struct reg_state *rstate, struct triple *ins)
14180 {
14181         struct live_range *lr;
14182         struct live_range_def *lrd;
14183         int ins_found;
14184         if ((ins->id < 0) || (ins->id > rstate->defs)) {
14185                 internal_error(state, ins, "bad ins?");
14186         }
14187         lr = rstate->lrd[ins->id].lr;
14188         ins_found = 0;
14189         lrd = lr->defs;
14190         do {
14191                 if (lrd->def == ins) {
14192                         ins_found = 1;
14193                 }
14194                 lrd = lrd->next;
14195         } while(lrd != lr->defs);
14196         if (!ins_found) {
14197                 internal_error(state, ins, "ins not in live range");
14198         }
14199         return lr;
14200 }
14201
14202 static void verify_graph_ins(
14203         struct compile_state *state, 
14204         struct reg_block *blocks, struct triple_reg_set *live, 
14205         struct reg_block *rb, struct triple *ins, void *arg)
14206 {
14207         struct reg_state *rstate = arg;
14208         struct triple_reg_set *entry1, *entry2;
14209
14210
14211         /* Compare live against edges and make certain the code is working */
14212         for(entry1 = live; entry1; entry1 = entry1->next) {
14213                 struct live_range *lr1;
14214                 lr1 = get_verify_live_range(state, rstate, entry1->member);
14215                 for(entry2 = live; entry2; entry2 = entry2->next) {
14216                         struct live_range *lr2;
14217                         struct live_range_edge *edge2;
14218                         int lr1_found;
14219                         int lr2_degree;
14220                         if (entry2 == entry1) {
14221                                 continue;
14222                         }
14223                         lr2 = get_verify_live_range(state, rstate, entry2->member);
14224                         if (lr1 == lr2) {
14225                                 internal_error(state, entry2->member, 
14226                                         "live range with 2 values simultaneously alive");
14227                         }
14228                         if (!arch_regcm_intersect(lr1->classes, lr2->classes)) {
14229                                 continue;
14230                         }
14231                         if (!interfere(rstate, lr1, lr2)) {
14232                                 internal_error(state, entry2->member, 
14233                                         "edges don't interfere?");
14234                         }
14235                                 
14236                         lr1_found = 0;
14237                         lr2_degree = 0;
14238                         for(edge2 = lr2->edges; edge2; edge2 = edge2->next) {
14239                                 lr2_degree++;
14240                                 if (edge2->node == lr1) {
14241                                         lr1_found = 1;
14242                                 }
14243                         }
14244                         if (lr2_degree != lr2->degree) {
14245                                 internal_error(state, entry2->member,
14246                                         "computed degree: %d does not match reported degree: %d\n",
14247                                         lr2_degree, lr2->degree);
14248                         }
14249                         if (!lr1_found) {
14250                                 internal_error(state, entry2->member, "missing edge");
14251                         }
14252                 }
14253         }
14254         return;
14255 }
14256
14257
14258 static void print_interference_ins(
14259         struct compile_state *state, 
14260         struct reg_block *blocks, struct triple_reg_set *live, 
14261         struct reg_block *rb, struct triple *ins, void *arg)
14262 {
14263         struct reg_state *rstate = arg;
14264         struct live_range *lr;
14265         unsigned id;
14266
14267         lr = rstate->lrd[ins->id].lr;
14268         id = ins->id;
14269         ins->id = rstate->lrd[id].orig_id;
14270         SET_REG(ins->id, lr->color);
14271         display_triple(stdout, ins);
14272         ins->id = id;
14273
14274         if (lr->defs) {
14275                 struct live_range_def *lrd;
14276                 printf("       range:");
14277                 lrd = lr->defs;
14278                 do {
14279                         printf(" %-10p", lrd->def);
14280                         lrd = lrd->next;
14281                 } while(lrd != lr->defs);
14282                 printf("\n");
14283         }
14284         if (live) {
14285                 struct triple_reg_set *entry;
14286                 printf("        live:");
14287                 for(entry = live; entry; entry = entry->next) {
14288                         printf(" %-10p", entry->member);
14289                 }
14290                 printf("\n");
14291         }
14292         if (lr->edges) {
14293                 struct live_range_edge *entry;
14294                 printf("       edges:");
14295                 for(entry = lr->edges; entry; entry = entry->next) {
14296                         struct live_range_def *lrd;
14297                         lrd = entry->node->defs;
14298                         do {
14299                                 printf(" %-10p", lrd->def);
14300                                 lrd = lrd->next;
14301                         } while(lrd != entry->node->defs);
14302                         printf("|");
14303                 }
14304                 printf("\n");
14305         }
14306         if (triple_is_branch(state, ins)) {
14307                 printf("\n");
14308         }
14309         return;
14310 }
14311
14312 static int coalesce_live_ranges(
14313         struct compile_state *state, struct reg_state *rstate)
14314 {
14315         /* At the point where a value is moved from one
14316          * register to another that value requires two
14317          * registers, thus increasing register pressure.
14318          * Live range coaleescing reduces the register
14319          * pressure by keeping a value in one register
14320          * longer.
14321          *
14322          * In the case of a phi function all paths leading
14323          * into it must be allocated to the same register
14324          * otherwise the phi function may not be removed.
14325          *
14326          * Forcing a value to stay in a single register
14327          * for an extended period of time does have
14328          * limitations when applied to non homogenous
14329          * register pool.  
14330          *
14331          * The two cases I have identified are:
14332          * 1) Two forced register assignments may
14333          *    collide.
14334          * 2) Registers may go unused because they
14335          *    are only good for storing the value
14336          *    and not manipulating it.
14337          *
14338          * Because of this I need to split live ranges,
14339          * even outside of the context of coalesced live
14340          * ranges.  The need to split live ranges does
14341          * impose some constraints on live range coalescing.
14342          *
14343          * - Live ranges may not be coalesced across phi
14344          *   functions.  This creates a 2 headed live
14345          *   range that cannot be sanely split.
14346          *
14347          * - phi functions (coalesced in initialize_live_ranges) 
14348          *   are handled as pre split live ranges so we will
14349          *   never attempt to split them.
14350          */
14351         int coalesced;
14352         int i;
14353
14354         coalesced = 0;
14355         for(i = 0; i <= rstate->ranges; i++) {
14356                 struct live_range *lr1;
14357                 struct live_range_def *lrd1;
14358                 lr1 = &rstate->lr[i];
14359                 if (!lr1->defs) {
14360                         continue;
14361                 }
14362                 lrd1 = live_range_end(state, lr1, 0);
14363                 for(; lrd1; lrd1 = live_range_end(state, lr1, lrd1)) {
14364                         struct triple_set *set;
14365                         if (lrd1->def->op != OP_COPY) {
14366                                 continue;
14367                         }
14368                         /* Skip copies that are the result of a live range split. */
14369                         if (lrd1->orig_id & TRIPLE_FLAG_POST_SPLIT) {
14370                                 continue;
14371                         }
14372                         for(set = lrd1->def->use; set; set = set->next) {
14373                                 struct live_range_def *lrd2;
14374                                 struct live_range *lr2, *res;
14375
14376                                 lrd2 = &rstate->lrd[set->member->id];
14377
14378                                 /* Don't coalesce with instructions
14379                                  * that are the result of a live range
14380                                  * split.
14381                                  */
14382                                 if (lrd2->orig_id & TRIPLE_FLAG_PRE_SPLIT) {
14383                                         continue;
14384                                 }
14385                                 lr2 = rstate->lrd[set->member->id].lr;
14386                                 if (lr1 == lr2) {
14387                                         continue;
14388                                 }
14389                                 if ((lr1->color != lr2->color) &&
14390                                         (lr1->color != REG_UNSET) &&
14391                                         (lr2->color != REG_UNSET)) {
14392                                         continue;
14393                                 }
14394                                 if ((lr1->classes & lr2->classes) == 0) {
14395                                         continue;
14396                                 }
14397                                 
14398                                 if (interfere(rstate, lr1, lr2)) {
14399                                         continue;
14400                                 }
14401
14402                                 res = coalesce_ranges(state, rstate, lr1, lr2);
14403                                 coalesced += 1;
14404                                 if (res != lr1) {
14405                                         goto next;
14406                                 }
14407                         }
14408                 }
14409         next:
14410                 ;
14411         }
14412         return coalesced;
14413 }
14414
14415
14416 static void fix_coalesce_conflicts(struct compile_state *state,
14417         struct reg_block *blocks, struct triple_reg_set *live,
14418         struct reg_block *rb, struct triple *ins, void *arg)
14419 {
14420         int *conflicts = arg;
14421         int zlhs, zrhs, i, j;
14422
14423         /* See if we have a mandatory coalesce operation between
14424          * a lhs and a rhs value.  If so and the rhs value is also
14425          * alive then this triple needs to be pre copied.  Otherwise
14426          * we would have two definitions in the same live range simultaneously
14427          * alive.
14428          */
14429         zlhs = TRIPLE_LHS(ins->sizes);
14430         if ((zlhs == 0) && triple_is_def(state, ins)) {
14431                 zlhs = 1;
14432         }
14433         zrhs = TRIPLE_RHS(ins->sizes);
14434         for(i = 0; i < zlhs; i++) {
14435                 struct reg_info linfo;
14436                 linfo = arch_reg_lhs(state, ins, i);
14437                 if (linfo.reg < MAX_REGISTERS) {
14438                         continue;
14439                 }
14440                 for(j = 0; j < zrhs; j++) {
14441                         struct reg_info rinfo;
14442                         struct triple *rhs;
14443                         struct triple_reg_set *set;
14444                         int found;
14445                         found = 0;
14446                         rinfo = arch_reg_rhs(state, ins, j);
14447                         if (rinfo.reg != linfo.reg) {
14448                                 continue;
14449                         }
14450                         rhs = RHS(ins, j);
14451                         for(set = live; set && !found; set = set->next) {
14452                                 if (set->member == rhs) {
14453                                         found = 1;
14454                                 }
14455                         }
14456                         if (found) {
14457                                 struct triple *copy;
14458                                 copy = pre_copy(state, ins, j);
14459                                 copy->id |= TRIPLE_FLAG_PRE_SPLIT;
14460                                 (*conflicts)++;
14461                         }
14462                 }
14463         }
14464         return;
14465 }
14466
14467 static int correct_coalesce_conflicts(
14468         struct compile_state *state, struct reg_block *blocks)
14469 {
14470         int conflicts;
14471         conflicts = 0;
14472         walk_variable_lifetimes(state, blocks, fix_coalesce_conflicts, &conflicts);
14473         return conflicts;
14474 }
14475
14476 static void replace_set_use(struct compile_state *state,
14477         struct triple_reg_set *head, struct triple *orig, struct triple *new)
14478 {
14479         struct triple_reg_set *set;
14480         for(set = head; set; set = set->next) {
14481                 if (set->member == orig) {
14482                         set->member = new;
14483                 }
14484         }
14485 }
14486
14487 static void replace_block_use(struct compile_state *state, 
14488         struct reg_block *blocks, struct triple *orig, struct triple *new)
14489 {
14490         int i;
14491 #warning "WISHLIST visit just those blocks that need it *"
14492         for(i = 1; i <= state->last_vertex; i++) {
14493                 struct reg_block *rb;
14494                 rb = &blocks[i];
14495                 replace_set_use(state, rb->in, orig, new);
14496                 replace_set_use(state, rb->out, orig, new);
14497         }
14498 }
14499
14500 static void color_instructions(struct compile_state *state)
14501 {
14502         struct triple *ins, *first;
14503         first = state->first;
14504         ins = first;
14505         do {
14506                 if (triple_is_def(state, ins)) {
14507                         struct reg_info info;
14508                         info = find_lhs_color(state, ins, 0);
14509                         if (info.reg >= MAX_REGISTERS) {
14510                                 info.reg = REG_UNSET;
14511                         }
14512                         SET_INFO(ins->id, info);
14513                 }
14514                 ins = ins->next;
14515         } while(ins != first);
14516 }
14517
14518 static struct reg_info read_lhs_color(
14519         struct compile_state *state, struct triple *ins, int index)
14520 {
14521         struct reg_info info;
14522         if ((index == 0) && triple_is_def(state, ins)) {
14523                 info.reg   = ID_REG(ins->id);
14524                 info.regcm = ID_REGCM(ins->id);
14525         }
14526         else if (index < TRIPLE_LHS(ins->sizes)) {
14527                 info = read_lhs_color(state, LHS(ins, index), 0);
14528         }
14529         else {
14530                 internal_error(state, ins, "Bad lhs %d", index);
14531                 info.reg = REG_UNSET;
14532                 info.regcm = 0;
14533         }
14534         return info;
14535 }
14536
14537 static struct triple *resolve_tangle(
14538         struct compile_state *state, struct triple *tangle)
14539 {
14540         struct reg_info info, uinfo;
14541         struct triple_set *set, *next;
14542         struct triple *copy;
14543
14544 #warning "WISHLIST recalculate all affected instructions colors"
14545         info = find_lhs_color(state, tangle, 0);
14546         for(set = tangle->use; set; set = next) {
14547                 struct triple *user;
14548                 int i, zrhs;
14549                 next = set->next;
14550                 user = set->member;
14551                 zrhs = TRIPLE_RHS(user->sizes);
14552                 for(i = 0; i < zrhs; i++) {
14553                         if (RHS(user, i) != tangle) {
14554                                 continue;
14555                         }
14556                         uinfo = find_rhs_post_color(state, user, i);
14557                         if (uinfo.reg == info.reg) {
14558                                 copy = pre_copy(state, user, i);
14559                                 copy->id |= TRIPLE_FLAG_PRE_SPLIT;
14560                                 SET_INFO(copy->id, uinfo);
14561                         }
14562                 }
14563         }
14564         copy = 0;
14565         uinfo = find_lhs_pre_color(state, tangle, 0);
14566         if (uinfo.reg == info.reg) {
14567                 struct reg_info linfo;
14568                 copy = post_copy(state, tangle);
14569                 copy->id |= TRIPLE_FLAG_PRE_SPLIT;
14570                 linfo = find_lhs_color(state, copy, 0);
14571                 SET_INFO(copy->id, linfo);
14572         }
14573         info = find_lhs_color(state, tangle, 0);
14574         SET_INFO(tangle->id, info);
14575         
14576         return copy;
14577 }
14578
14579
14580 static void fix_tangles(struct compile_state *state,
14581         struct reg_block *blocks, struct triple_reg_set *live,
14582         struct reg_block *rb, struct triple *ins, void *arg)
14583 {
14584         int *tangles = arg;
14585         struct triple *tangle;
14586         do {
14587                 char used[MAX_REGISTERS];
14588                 struct triple_reg_set *set;
14589                 tangle = 0;
14590
14591                 /* Find out which registers have multiple uses at this point */
14592                 memset(used, 0, sizeof(used));
14593                 for(set = live; set; set = set->next) {
14594                         struct reg_info info;
14595                         info = read_lhs_color(state, set->member, 0);
14596                         if (info.reg == REG_UNSET) {
14597                                 continue;
14598                         }
14599                         reg_inc_used(state, used, info.reg);
14600                 }
14601                 
14602                 /* Now find the least dominated definition of a register in
14603                  * conflict I have seen so far.
14604                  */
14605                 for(set = live; set; set = set->next) {
14606                         struct reg_info info;
14607                         info = read_lhs_color(state, set->member, 0);
14608                         if (used[info.reg] < 2) {
14609                                 continue;
14610                         }
14611                         /* Changing copies that feed into phi functions
14612                          * is incorrect.
14613                          */
14614                         if (set->member->use && 
14615                                 (set->member->use->member->op == OP_PHI)) {
14616                                 continue;
14617                         }
14618                         if (!tangle || tdominates(state, set->member, tangle)) {
14619                                 tangle = set->member;
14620                         }
14621                 }
14622                 /* If I have found a tangle resolve it */
14623                 if (tangle) {
14624                         struct triple *post_copy;
14625                         (*tangles)++;
14626                         post_copy = resolve_tangle(state, tangle);
14627                         if (post_copy) {
14628                                 replace_block_use(state, blocks, tangle, post_copy);
14629                         }
14630                         if (post_copy && (tangle != ins)) {
14631                                 replace_set_use(state, live, tangle, post_copy);
14632                         }
14633                 }
14634         } while(tangle);
14635         return;
14636 }
14637
14638 static int correct_tangles(
14639         struct compile_state *state, struct reg_block *blocks)
14640 {
14641         int tangles;
14642         tangles = 0;
14643         color_instructions(state);
14644         walk_variable_lifetimes(state, blocks, fix_tangles, &tangles);
14645         return tangles;
14646 }
14647
14648
14649 static void ids_from_rstate(struct compile_state *state, struct reg_state *rstate);
14650 static void cleanup_rstate(struct compile_state *state, struct reg_state *rstate);
14651
14652 struct triple *find_constrained_def(
14653         struct compile_state *state, struct live_range *range, struct triple *constrained)
14654 {
14655         struct live_range_def *lrd, *lrd_next;
14656         lrd_next = range->defs;
14657         do {
14658                 struct reg_info info;
14659                 unsigned regcm;
14660
14661                 lrd = lrd_next;
14662                 lrd_next = lrd->next;
14663
14664                 regcm = arch_type_to_regcm(state, lrd->def->type);
14665                 info = find_lhs_color(state, lrd->def, 0);
14666                 regcm      = arch_regcm_reg_normalize(state, regcm);
14667                 info.regcm = arch_regcm_reg_normalize(state, info.regcm);
14668                 /* If the 2 register class masks are equal then
14669                  * the current register class is not constrained.
14670                  */
14671                 if (regcm == info.regcm) {
14672                         continue;
14673                 }
14674                 
14675                 /* If there is just one use.
14676                  * That use cannot accept a larger register class.
14677                  * There are no intervening definitions except
14678                  * definitions that feed into that use.
14679                  * Then a triple is not constrained.
14680                  * FIXME handle this case!
14681                  */
14682 #warning "FIXME ignore cases that cannot be fixed (a definition followed by a use)"
14683                 
14684
14685                 /* Of the constrained live ranges deal with the
14686                  * least dominated one first.
14687                  */
14688                 if (state->compiler->debug & DEBUG_RANGE_CONFLICTS) {
14689                         fprintf(stderr, "canidate: %p %-8s regcm: %x %x\n",
14690                                 lrd->def, tops(lrd->def->op), regcm, info.regcm);
14691                 }
14692                 if (!constrained || 
14693                         tdominates(state, lrd->def, constrained))
14694                 {
14695                         constrained = lrd->def;
14696                 }
14697         } while(lrd_next != range->defs);
14698         return constrained;
14699 }
14700
14701 static int split_constrained_ranges(
14702         struct compile_state *state, struct reg_state *rstate, 
14703         struct live_range *range)
14704 {
14705         /* Walk through the edges in conflict and our current live
14706          * range, and find definitions that are more severly constrained
14707          * than they type of data they contain require.
14708          * 
14709          * Then pick one of those ranges and relax the constraints.
14710          */
14711         struct live_range_edge *edge;
14712         struct triple *constrained;
14713
14714         constrained = 0;
14715         for(edge = range->edges; edge; edge = edge->next) {
14716                 constrained = find_constrained_def(state, edge->node, constrained);
14717         }
14718 #warning "FIXME should I call find_constrained_def here only if no previous constrained def was found?"
14719         if (!constrained) {
14720                 constrained = find_constrained_def(state, range, constrained);
14721         }
14722
14723         if (state->compiler->debug & DEBUG_RANGE_CONFLICTS) {
14724                 fprintf(stderr, "constrained: %p %-8s\n",
14725                         constrained, tops(constrained->op));
14726         }
14727         if (constrained) {
14728                 ids_from_rstate(state, rstate);
14729                 cleanup_rstate(state, rstate);
14730                 resolve_tangle(state, constrained);
14731         }
14732         return !!constrained;
14733 }
14734         
14735 static int split_ranges(
14736         struct compile_state *state, struct reg_state *rstate,
14737         char *used, struct live_range *range)
14738 {
14739         int split;
14740         if (state->compiler->debug & DEBUG_RANGE_CONFLICTS) {
14741                 fprintf(stderr, "split_ranges %d %s %p\n", 
14742                         rstate->passes, tops(range->defs->def->op), range->defs->def);
14743         }
14744         if ((range->color == REG_UNNEEDED) ||
14745                 (rstate->passes >= rstate->max_passes)) {
14746                 return 0;
14747         }
14748         split = split_constrained_ranges(state, rstate, range);
14749
14750         /* Ideally I would split the live range that will not be used
14751          * for the longest period of time in hopes that this will 
14752          * (a) allow me to spill a register or
14753          * (b) allow me to place a value in another register.
14754          *
14755          * So far I don't have a test case for this, the resolving
14756          * of mandatory constraints has solved all of my
14757          * know issues.  So I have choosen not to write any
14758          * code until I cat get a better feel for cases where
14759          * it would be useful to have.
14760          *
14761          */
14762 #warning "WISHLIST implement live range splitting..."
14763         
14764         if (!split && (state->compiler->debug & DEBUG_RANGE_CONFLICTS2)) {
14765                 print_interference_blocks(state, rstate, stderr, 0);
14766                 print_dominators(state, stderr);
14767         }
14768         return split;
14769 }
14770
14771 static FILE *cgdebug_fp(struct compile_state *state)
14772 {
14773         FILE *fp;
14774         fp = 0;
14775         if (!fp && (state->compiler->debug & DEBUG_COLOR_GRAPH2)) {
14776                 fp = stderr;
14777         }
14778         if (!fp && (state->compiler->debug & DEBUG_COLOR_GRAPH)) {
14779                 fp = stdout;
14780         }
14781         return fp;
14782 }
14783
14784 static void cgdebug_printf(struct compile_state *state, const char *fmt, ...)
14785 {
14786         FILE *fp;
14787         fp = cgdebug_fp(state);
14788         if (fp) {
14789                 va_list args;
14790                 va_start(args, fmt);
14791                 vfprintf(fp, fmt, args);
14792                 va_end(args);
14793         }
14794 }
14795
14796 static void cgdebug_flush(struct compile_state *state)
14797 {
14798         FILE *fp;
14799         fp = cgdebug_fp(state);
14800         if (fp) {
14801                 fflush(fp);
14802         }
14803 }
14804
14805 static void cgdebug_loc(struct compile_state *state, struct triple *ins)
14806 {
14807         FILE *fp;
14808         fp = cgdebug_fp(state);
14809         if (fp) {
14810                 loc(fp, state, ins);
14811         }
14812 }
14813
14814 static int select_free_color(struct compile_state *state, 
14815         struct reg_state *rstate, struct live_range *range)
14816 {
14817         struct triple_set *entry;
14818         struct live_range_def *lrd;
14819         struct live_range_def *phi;
14820         struct live_range_edge *edge;
14821         char used[MAX_REGISTERS];
14822         struct triple **expr;
14823
14824         /* Instead of doing just the trivial color select here I try
14825          * a few extra things because a good color selection will help reduce
14826          * copies.
14827          */
14828
14829         /* Find the registers currently in use */
14830         memset(used, 0, sizeof(used));
14831         for(edge = range->edges; edge; edge = edge->next) {
14832                 if (edge->node->color == REG_UNSET) {
14833                         continue;
14834                 }
14835                 reg_fill_used(state, used, edge->node->color);
14836         }
14837
14838         if (state->compiler->debug & DEBUG_COLOR_GRAPH2) {
14839                 int i;
14840                 i = 0;
14841                 for(edge = range->edges; edge; edge = edge->next) {
14842                         i++;
14843                 }
14844                 cgdebug_printf(state, "\n%s edges: %d", 
14845                         tops(range->defs->def->op), i);
14846                 cgdebug_loc(state, range->defs->def);
14847                 cgdebug_printf(state, "\n");
14848                 for(i = 0; i < MAX_REGISTERS; i++) {
14849                         if (used[i]) {
14850                                 cgdebug_printf(state, "used: %s\n",
14851                                         arch_reg_str(i));
14852                         }
14853                 }
14854         }       
14855
14856         /* If a color is already assigned see if it will work */
14857         if (range->color != REG_UNSET) {
14858                 struct live_range_def *lrd;
14859                 if (!used[range->color]) {
14860                         return 1;
14861                 }
14862                 for(edge = range->edges; edge; edge = edge->next) {
14863                         if (edge->node->color != range->color) {
14864                                 continue;
14865                         }
14866                         warning(state, edge->node->defs->def, "edge: ");
14867                         lrd = edge->node->defs;
14868                         do {
14869                                 warning(state, lrd->def, " %p %s",
14870                                         lrd->def, tops(lrd->def->op));
14871                                 lrd = lrd->next;
14872                         } while(lrd != edge->node->defs);
14873                 }
14874                 lrd = range->defs;
14875                 warning(state, range->defs->def, "def: ");
14876                 do {
14877                         warning(state, lrd->def, " %p %s",
14878                                 lrd->def, tops(lrd->def->op));
14879                         lrd = lrd->next;
14880                 } while(lrd != range->defs);
14881                 internal_error(state, range->defs->def,
14882                         "live range with already used color %s",
14883                         arch_reg_str(range->color));
14884         }
14885
14886         /* If I feed into an expression reuse it's color.
14887          * This should help remove copies in the case of 2 register instructions
14888          * and phi functions.
14889          */
14890         phi = 0;
14891         lrd = live_range_end(state, range, 0);
14892         for(; (range->color == REG_UNSET) && lrd ; lrd = live_range_end(state, range, lrd)) {
14893                 entry = lrd->def->use;
14894                 for(;(range->color == REG_UNSET) && entry; entry = entry->next) {
14895                         struct live_range_def *insd;
14896                         unsigned regcm;
14897                         insd = &rstate->lrd[entry->member->id];
14898                         if (insd->lr->defs == 0) {
14899                                 continue;
14900                         }
14901                         if (!phi && (insd->def->op == OP_PHI) &&
14902                                 !interfere(rstate, range, insd->lr)) {
14903                                 phi = insd;
14904                         }
14905                         if (insd->lr->color == REG_UNSET) {
14906                                 continue;
14907                         }
14908                         regcm = insd->lr->classes;
14909                         if (((regcm & range->classes) == 0) ||
14910                                 (used[insd->lr->color])) {
14911                                 continue;
14912                         }
14913                         if (interfere(rstate, range, insd->lr)) {
14914                                 continue;
14915                         }
14916                         range->color = insd->lr->color;
14917                 }
14918         }
14919         /* If I feed into a phi function reuse it's color or the color
14920          * of something else that feeds into the phi function.
14921          */
14922         if (phi) {
14923                 if (phi->lr->color != REG_UNSET) {
14924                         if (used[phi->lr->color]) {
14925                                 range->color = phi->lr->color;
14926                         }
14927                 }
14928                 else {
14929                         expr = triple_rhs(state, phi->def, 0);
14930                         for(; expr; expr = triple_rhs(state, phi->def, expr)) {
14931                                 struct live_range *lr;
14932                                 unsigned regcm;
14933                                 if (!*expr) {
14934                                         continue;
14935                                 }
14936                                 lr = rstate->lrd[(*expr)->id].lr;
14937                                 if (lr->color == REG_UNSET) {
14938                                         continue;
14939                                 }
14940                                 regcm = lr->classes;
14941                                 if (((regcm & range->classes) == 0) ||
14942                                         (used[lr->color])) {
14943                                         continue;
14944                                 }
14945                                 if (interfere(rstate, range, lr)) {
14946                                         continue;
14947                                 }
14948                                 range->color = lr->color;
14949                         }
14950                 }
14951         }
14952         /* If I don't interfere with a rhs node reuse it's color */
14953         lrd = live_range_head(state, range, 0);
14954         for(; (range->color == REG_UNSET) && lrd ; lrd = live_range_head(state, range, lrd)) {
14955                 expr = triple_rhs(state, lrd->def, 0);
14956                 for(; expr; expr = triple_rhs(state, lrd->def, expr)) {
14957                         struct live_range *lr;
14958                         unsigned regcm;
14959                         if (!*expr) {
14960                                 continue;
14961                         }
14962                         lr = rstate->lrd[(*expr)->id].lr;
14963                         if (lr->color == REG_UNSET) {
14964                                 continue;
14965                         }
14966                         regcm = lr->classes;
14967                         if (((regcm & range->classes) == 0) ||
14968                                 (used[lr->color])) {
14969                                 continue;
14970                         }
14971                         if (interfere(rstate, range, lr)) {
14972                                 continue;
14973                         }
14974                         range->color = lr->color;
14975                         break;
14976                 }
14977         }
14978         /* If I have not opportunitically picked a useful color
14979          * pick the first color that is free.
14980          */
14981         if (range->color == REG_UNSET) {
14982                 range->color = 
14983                         arch_select_free_register(state, used, range->classes);
14984         }
14985         if (range->color == REG_UNSET) {
14986                 struct live_range_def *lrd;
14987                 int i;
14988                 if (split_ranges(state, rstate, used, range)) {
14989                         return 0;
14990                 }
14991                 for(edge = range->edges; edge; edge = edge->next) {
14992                         warning(state, edge->node->defs->def, "edge reg %s",
14993                                 arch_reg_str(edge->node->color));
14994                         lrd = edge->node->defs;
14995                         do {
14996                                 warning(state, lrd->def, " %s %p",
14997                                         tops(lrd->def->op), lrd->def);
14998                                 lrd = lrd->next;
14999                         } while(lrd != edge->node->defs);
15000                 }
15001                 warning(state, range->defs->def, "range: ");
15002                 lrd = range->defs;
15003                 do {
15004                         warning(state, lrd->def, " %s %p",
15005                                 tops(lrd->def->op), lrd->def);
15006                         lrd = lrd->next;
15007                 } while(lrd != range->defs);
15008                         
15009                 warning(state, range->defs->def, "classes: %x",
15010                         range->classes);
15011                 for(i = 0; i < MAX_REGISTERS; i++) {
15012                         if (used[i]) {
15013                                 warning(state, range->defs->def, "used: %s",
15014                                         arch_reg_str(i));
15015                         }
15016                 }
15017                 error(state, range->defs->def, "too few registers");
15018         }
15019         range->classes &= arch_reg_regcm(state, range->color);
15020         if ((range->color == REG_UNSET) || (range->classes == 0)) {
15021                 internal_error(state, range->defs->def, "select_free_color did not?");
15022         }
15023         return 1;
15024 }
15025
15026 static int color_graph(struct compile_state *state, struct reg_state *rstate)
15027 {
15028         int colored;
15029         struct live_range_edge *edge;
15030         struct live_range *range;
15031         if (rstate->low) {
15032                 cgdebug_printf(state, "Lo: ");
15033                 range = rstate->low;
15034                 if (*range->group_prev != range) {
15035                         internal_error(state, 0, "lo: *prev != range?");
15036                 }
15037                 *range->group_prev = range->group_next;
15038                 if (range->group_next) {
15039                         range->group_next->group_prev = range->group_prev;
15040                 }
15041                 if (&range->group_next == rstate->low_tail) {
15042                         rstate->low_tail = range->group_prev;
15043                 }
15044                 if (rstate->low == range) {
15045                         internal_error(state, 0, "low: next != prev?");
15046                 }
15047         }
15048         else if (rstate->high) {
15049                 cgdebug_printf(state, "Hi: ");
15050                 range = rstate->high;
15051                 if (*range->group_prev != range) {
15052                         internal_error(state, 0, "hi: *prev != range?");
15053                 }
15054                 *range->group_prev = range->group_next;
15055                 if (range->group_next) {
15056                         range->group_next->group_prev = range->group_prev;
15057                 }
15058                 if (&range->group_next == rstate->high_tail) {
15059                         rstate->high_tail = range->group_prev;
15060                 }
15061                 if (rstate->high == range) {
15062                         internal_error(state, 0, "high: next != prev?");
15063                 }
15064         }
15065         else {
15066                 return 1;
15067         }
15068         cgdebug_printf(state, " %d\n", range - rstate->lr);
15069         range->group_prev = 0;
15070         for(edge = range->edges; edge; edge = edge->next) {
15071                 struct live_range *node;
15072                 node = edge->node;
15073                 /* Move nodes from the high to the low list */
15074                 if (node->group_prev && (node->color == REG_UNSET) &&
15075                         (node->degree == regc_max_size(state, node->classes))) {
15076                         if (*node->group_prev != node) {
15077                                 internal_error(state, 0, "move: *prev != node?");
15078                         }
15079                         *node->group_prev = node->group_next;
15080                         if (node->group_next) {
15081                                 node->group_next->group_prev = node->group_prev;
15082                         }
15083                         if (&node->group_next == rstate->high_tail) {
15084                                 rstate->high_tail = node->group_prev;
15085                         }
15086                         cgdebug_printf(state, "Moving...%d to low\n", node - rstate->lr);
15087                         node->group_prev  = rstate->low_tail;
15088                         node->group_next  = 0;
15089                         *rstate->low_tail = node;
15090                         rstate->low_tail  = &node->group_next;
15091                         if (*node->group_prev != node) {
15092                                 internal_error(state, 0, "move2: *prev != node?");
15093                         }
15094                 }
15095                 node->degree -= 1;
15096         }
15097         colored = color_graph(state, rstate);
15098         if (colored) {
15099                 cgdebug_printf(state, "Coloring %d @", range - rstate->lr);
15100                 cgdebug_loc(state, range->defs->def);
15101                 cgdebug_flush(state);
15102                 colored = select_free_color(state, rstate, range);
15103                 cgdebug_printf(state, " %s\n", arch_reg_str(range->color));
15104         }
15105         return colored;
15106 }
15107
15108 static void verify_colors(struct compile_state *state, struct reg_state *rstate)
15109 {
15110         struct live_range *lr;
15111         struct live_range_edge *edge;
15112         struct triple *ins, *first;
15113         char used[MAX_REGISTERS];
15114         first = state->first;
15115         ins = first;
15116         do {
15117                 if (triple_is_def(state, ins)) {
15118                         if ((ins->id < 0) || (ins->id > rstate->defs)) {
15119                                 internal_error(state, ins, 
15120                                         "triple without a live range def");
15121                         }
15122                         lr = rstate->lrd[ins->id].lr;
15123                         if (lr->color == REG_UNSET) {
15124                                 internal_error(state, ins,
15125                                         "triple without a color");
15126                         }
15127                         /* Find the registers used by the edges */
15128                         memset(used, 0, sizeof(used));
15129                         for(edge = lr->edges; edge; edge = edge->next) {
15130                                 if (edge->node->color == REG_UNSET) {
15131                                         internal_error(state, 0,
15132                                                 "live range without a color");
15133                         }
15134                                 reg_fill_used(state, used, edge->node->color);
15135                         }
15136                         if (used[lr->color]) {
15137                                 internal_error(state, ins,
15138                                         "triple with already used color");
15139                         }
15140                 }
15141                 ins = ins->next;
15142         } while(ins != first);
15143 }
15144
15145 static void color_triples(struct compile_state *state, struct reg_state *rstate)
15146 {
15147         struct live_range *lr;
15148         struct triple *first, *ins;
15149         first = state->first;
15150         ins = first;
15151         do {
15152                 if ((ins->id < 0) || (ins->id > rstate->defs)) {
15153                         internal_error(state, ins, 
15154                                 "triple without a live range");
15155                 }
15156                 lr = rstate->lrd[ins->id].lr;
15157                 SET_REG(ins->id, lr->color);
15158                 ins = ins->next;
15159         } while (ins != first);
15160 }
15161
15162 static struct live_range *merge_sort_lr(
15163         struct live_range *first, struct live_range *last)
15164 {
15165         struct live_range *mid, *join, **join_tail, *pick;
15166         size_t size;
15167         size = (last - first) + 1;
15168         if (size >= 2) {
15169                 mid = first + size/2;
15170                 first = merge_sort_lr(first, mid -1);
15171                 mid   = merge_sort_lr(mid, last);
15172                 
15173                 join = 0;
15174                 join_tail = &join;
15175                 /* merge the two lists */
15176                 while(first && mid) {
15177                         if ((first->degree < mid->degree) ||
15178                                 ((first->degree == mid->degree) &&
15179                                         (first->length < mid->length))) {
15180                                 pick = first;
15181                                 first = first->group_next;
15182                                 if (first) {
15183                                         first->group_prev = 0;
15184                                 }
15185                         }
15186                         else {
15187                                 pick = mid;
15188                                 mid = mid->group_next;
15189                                 if (mid) {
15190                                         mid->group_prev = 0;
15191                                 }
15192                         }
15193                         pick->group_next = 0;
15194                         pick->group_prev = join_tail;
15195                         *join_tail = pick;
15196                         join_tail = &pick->group_next;
15197                 }
15198                 /* Splice the remaining list */
15199                 pick = (first)? first : mid;
15200                 *join_tail = pick;
15201                 if (pick) { 
15202                         pick->group_prev = join_tail;
15203                 }
15204         }
15205         else {
15206                 if (!first->defs) {
15207                         first = 0;
15208                 }
15209                 join = first;
15210         }
15211         return join;
15212 }
15213
15214 static void ids_from_rstate(struct compile_state *state, 
15215         struct reg_state *rstate)
15216 {
15217         struct triple *ins, *first;
15218         if (!rstate->defs) {
15219                 return;
15220         }
15221         /* Display the graph if desired */
15222         if (state->compiler->debug & DEBUG_INTERFERENCE) {
15223                 print_interference_blocks(state, rstate, stdout, 0);
15224                 print_control_flow(state);
15225                 fflush(stdout);
15226         }
15227         first = state->first;
15228         ins = first;
15229         do {
15230                 if (ins->id) {
15231                         struct live_range_def *lrd;
15232                         lrd = &rstate->lrd[ins->id];
15233                         ins->id = lrd->orig_id;
15234                 }
15235                 ins = ins->next;
15236         } while(ins != first);
15237 }
15238
15239 static void cleanup_live_edges(struct reg_state *rstate)
15240 {
15241         int i;
15242         /* Free the edges on each node */
15243         for(i = 1; i <= rstate->ranges; i++) {
15244                 remove_live_edges(rstate, &rstate->lr[i]);
15245         }
15246 }
15247
15248 static void cleanup_rstate(struct compile_state *state, struct reg_state *rstate)
15249 {
15250         cleanup_live_edges(rstate);
15251         xfree(rstate->lrd);
15252         xfree(rstate->lr);
15253
15254         /* Free the variable lifetime information */
15255         if (rstate->blocks) {
15256                 free_variable_lifetimes(state, rstate->blocks);
15257         }
15258         rstate->defs = 0;
15259         rstate->ranges = 0;
15260         rstate->lrd = 0;
15261         rstate->lr = 0;
15262         rstate->blocks = 0;
15263 }
15264
15265 static void verify_consistency(struct compile_state *state);
15266 static void allocate_registers(struct compile_state *state)
15267 {
15268         struct reg_state rstate;
15269         int colored;
15270
15271         /* Clear out the reg_state */
15272         memset(&rstate, 0, sizeof(rstate));
15273         rstate.max_passes = state->compiler->max_allocation_passes;
15274
15275         do {
15276                 struct live_range **point, **next;
15277                 int conflicts;
15278                 int tangles;
15279                 int coalesced;
15280
15281                 if (state->compiler->debug & DEBUG_RANGE_CONFLICTS) {
15282                         fprintf(stderr, "pass: %d\n", rstate.passes);
15283                         fflush(stderr);
15284                 }
15285
15286                 /* Restore ids */
15287                 ids_from_rstate(state, &rstate);
15288
15289                 /* Cleanup the temporary data structures */
15290                 cleanup_rstate(state, &rstate);
15291
15292                 /* Compute the variable lifetimes */
15293                 rstate.blocks = compute_variable_lifetimes(state);
15294
15295                 /* Fix invalid mandatory live range coalesce conflicts */
15296                 conflicts = correct_coalesce_conflicts(state, rstate.blocks);
15297
15298                 /* Fix two simultaneous uses of the same register.
15299                  * In a few pathlogical cases a partial untangle moves
15300                  * the tangle to a part of the graph we won't revisit.
15301                  * So we keep looping until we have no more tangle fixes
15302                  * to apply.
15303                  */
15304                 do {
15305                         tangles = correct_tangles(state, rstate.blocks);
15306                 } while(tangles);
15307
15308                 
15309                 print_blocks(state, "resolve_tangles", stdout);
15310                 verify_consistency(state);
15311                 
15312                 /* Allocate and initialize the live ranges */
15313                 initialize_live_ranges(state, &rstate);
15314
15315                 /* Note current doing coalescing in a loop appears to 
15316                  * buys me nothing.  The code is left this way in case
15317                  * there is some value in it.  Or if a future bugfix
15318                  *  yields some benefit.
15319                  */
15320                 do {
15321                         if (state->compiler->debug & DEBUG_COALESCING) {
15322                                 fprintf(stderr, "coalescing\n");
15323                         }
15324
15325                         /* Remove any previous live edge calculations */
15326                         cleanup_live_edges(&rstate);
15327
15328                         /* Compute the interference graph */
15329                         walk_variable_lifetimes(
15330                                 state, rstate.blocks, graph_ins, &rstate);
15331                         
15332                         /* Display the interference graph if desired */
15333                         if (state->compiler->debug & DEBUG_INTERFERENCE) {
15334                                 print_interference_blocks(state, &rstate, stdout, 1);
15335                                 printf("\nlive variables by instruction\n");
15336                                 walk_variable_lifetimes(
15337                                         state, rstate.blocks, 
15338                                         print_interference_ins, &rstate);
15339                         }
15340                         
15341                         coalesced = coalesce_live_ranges(state, &rstate);
15342
15343                         if (state->compiler->debug & DEBUG_COALESCING) {
15344                                 fprintf(stderr, "coalesced: %d\n", coalesced);
15345                         }
15346                 } while(coalesced);
15347
15348 #if DEBUG_CONSISTENCY > 1
15349 # if 0
15350                 fprintf(stderr, "verify_graph_ins...\n");
15351 # endif
15352                 /* Verify the interference graph */
15353                 walk_variable_lifetimes(
15354                         state, rstate.blocks, verify_graph_ins, &rstate);
15355 # if 0
15356                 fprintf(stderr, "verify_graph_ins done\n");
15357 #endif
15358 #endif
15359                         
15360                 /* Build the groups low and high.  But with the nodes
15361                  * first sorted by degree order.
15362                  */
15363                 rstate.low_tail  = &rstate.low;
15364                 rstate.high_tail = &rstate.high;
15365                 rstate.high = merge_sort_lr(&rstate.lr[1], &rstate.lr[rstate.ranges]);
15366                 if (rstate.high) {
15367                         rstate.high->group_prev = &rstate.high;
15368                 }
15369                 for(point = &rstate.high; *point; point = &(*point)->group_next)
15370                         ;
15371                 rstate.high_tail = point;
15372                 /* Walk through the high list and move everything that needs
15373                  * to be onto low.
15374                  */
15375                 for(point = &rstate.high; *point; point = next) {
15376                         struct live_range *range;
15377                         next = &(*point)->group_next;
15378                         range = *point;
15379                         
15380                         /* If it has a low degree or it already has a color
15381                          * place the node in low.
15382                          */
15383                         if ((range->degree < regc_max_size(state, range->classes)) ||
15384                                 (range->color != REG_UNSET)) {
15385                                 cgdebug_printf(state, "Lo: %5d degree %5d%s\n", 
15386                                         range - rstate.lr, range->degree,
15387                                         (range->color != REG_UNSET) ? " (colored)": "");
15388                                 *range->group_prev = range->group_next;
15389                                 if (range->group_next) {
15390                                         range->group_next->group_prev = range->group_prev;
15391                                 }
15392                                 if (&range->group_next == rstate.high_tail) {
15393                                         rstate.high_tail = range->group_prev;
15394                                 }
15395                                 range->group_prev  = rstate.low_tail;
15396                                 range->group_next  = 0;
15397                                 *rstate.low_tail   = range;
15398                                 rstate.low_tail    = &range->group_next;
15399                                 next = point;
15400                         }
15401                         else {
15402                                 cgdebug_printf(state, "hi: %5d degree %5d%s\n", 
15403                                         range - rstate.lr, range->degree,
15404                                         (range->color != REG_UNSET) ? " (colored)": "");
15405                         }
15406                 }
15407                 /* Color the live_ranges */
15408                 colored = color_graph(state, &rstate);
15409                 rstate.passes++;
15410         } while (!colored);
15411
15412         /* Verify the graph was properly colored */
15413         verify_colors(state, &rstate);
15414
15415         /* Move the colors from the graph to the triples */
15416         color_triples(state, &rstate);
15417
15418         /* Cleanup the temporary data structures */
15419         cleanup_rstate(state, &rstate);
15420
15421         /* Display the new graph */
15422         print_blocks(state, __func__, stdout);
15423 }
15424
15425 /* Sparce Conditional Constant Propogation
15426  * =========================================
15427  */
15428 struct ssa_edge;
15429 struct flow_block;
15430 struct lattice_node {
15431         unsigned old_id;
15432         struct triple *def;
15433         struct ssa_edge *out;
15434         struct flow_block *fblock;
15435         struct triple *val;
15436         /* lattice high   val && !is_const(val) 
15437          * lattice const  is_const(val)
15438          * lattice low    val == 0
15439          */
15440 };
15441 struct ssa_edge {
15442         struct lattice_node *src;
15443         struct lattice_node *dst;
15444         struct ssa_edge *work_next;
15445         struct ssa_edge *work_prev;
15446         struct ssa_edge *out_next;
15447 };
15448 struct flow_edge {
15449         struct flow_block *src;
15450         struct flow_block *dst;
15451         struct flow_edge *work_next;
15452         struct flow_edge *work_prev;
15453         struct flow_edge *in_next;
15454         struct flow_edge *out_next;
15455         int executable;
15456 };
15457 #define MAX_FLOW_BLOCK_EDGES 3
15458 struct flow_block {
15459         struct block *block;
15460         struct flow_edge *in;
15461         struct flow_edge *out;
15462         struct flow_edge *edges;
15463 };
15464
15465 struct scc_state {
15466         int ins_count;
15467         struct lattice_node *lattice;
15468         struct ssa_edge     *ssa_edges;
15469         struct flow_block   *flow_blocks;
15470         struct flow_edge    *flow_work_list;
15471         struct ssa_edge     *ssa_work_list;
15472 };
15473
15474
15475 static void scc_add_fedge(struct compile_state *state, struct scc_state *scc, 
15476         struct flow_edge *fedge)
15477 {
15478         if (state->compiler->debug & DEBUG_SCC_TRANSFORM2) {
15479                 fprintf(stderr, "adding fedge: %p (%4d -> %5d)\n",
15480                         fedge,
15481                         fedge->src->block?fedge->src->block->last->id: 0,
15482                         fedge->dst->block?fedge->dst->block->first->id: 0);
15483         }
15484         if ((fedge == scc->flow_work_list) ||
15485                 (fedge->work_next != fedge) ||
15486                 (fedge->work_prev != fedge)) {
15487
15488                 if (state->compiler->debug & DEBUG_SCC_TRANSFORM2) {
15489                         fprintf(stderr, "dupped fedge: %p\n",
15490                                 fedge);
15491                 }
15492                 return;
15493         }
15494         if (!scc->flow_work_list) {
15495                 scc->flow_work_list = fedge;
15496                 fedge->work_next = fedge->work_prev = fedge;
15497         }
15498         else {
15499                 struct flow_edge *ftail;
15500                 ftail = scc->flow_work_list->work_prev;
15501                 fedge->work_next = ftail->work_next;
15502                 fedge->work_prev = ftail;
15503                 fedge->work_next->work_prev = fedge;
15504                 fedge->work_prev->work_next = fedge;
15505         }
15506 }
15507
15508 static struct flow_edge *scc_next_fedge(
15509         struct compile_state *state, struct scc_state *scc)
15510 {
15511         struct flow_edge *fedge;
15512         fedge = scc->flow_work_list;
15513         if (fedge) {
15514                 fedge->work_next->work_prev = fedge->work_prev;
15515                 fedge->work_prev->work_next = fedge->work_next;
15516                 if (fedge->work_next != fedge) {
15517                         scc->flow_work_list = fedge->work_next;
15518                 } else {
15519                         scc->flow_work_list = 0;
15520                 }
15521                 fedge->work_next = fedge->work_prev = fedge;
15522         }
15523         return fedge;
15524 }
15525
15526 static void scc_add_sedge(struct compile_state *state, struct scc_state *scc,
15527         struct ssa_edge *sedge)
15528 {
15529         if (state->compiler->debug & DEBUG_SCC_TRANSFORM2) {
15530                 fprintf(stderr, "adding sedge: %5d (%4d -> %5d)\n",
15531                         sedge - scc->ssa_edges,
15532                         sedge->src->def->id,
15533                         sedge->dst->def->id);
15534         }
15535         if ((sedge == scc->ssa_work_list) ||
15536                 (sedge->work_next != sedge) ||
15537                 (sedge->work_prev != sedge)) {
15538
15539                 if (state->compiler->debug & DEBUG_SCC_TRANSFORM2) {
15540                         fprintf(stderr, "dupped sedge: %5d\n",
15541                                 sedge - scc->ssa_edges);
15542                 }
15543                 return;
15544         }
15545         if (!scc->ssa_work_list) {
15546                 scc->ssa_work_list = sedge;
15547                 sedge->work_next = sedge->work_prev = sedge;
15548         }
15549         else {
15550                 struct ssa_edge *stail;
15551                 stail = scc->ssa_work_list->work_prev;
15552                 sedge->work_next = stail->work_next;
15553                 sedge->work_prev = stail;
15554                 sedge->work_next->work_prev = sedge;
15555                 sedge->work_prev->work_next = sedge;
15556         }
15557 }
15558
15559 static struct ssa_edge *scc_next_sedge(
15560         struct compile_state *state, struct scc_state *scc)
15561 {
15562         struct ssa_edge *sedge;
15563         sedge = scc->ssa_work_list;
15564         if (sedge) {
15565                 sedge->work_next->work_prev = sedge->work_prev;
15566                 sedge->work_prev->work_next = sedge->work_next;
15567                 if (sedge->work_next != sedge) {
15568                         scc->ssa_work_list = sedge->work_next;
15569                 } else {
15570                         scc->ssa_work_list = 0;
15571                 }
15572                 sedge->work_next = sedge->work_prev = sedge;
15573         }
15574         return sedge;
15575 }
15576
15577 static void initialize_scc_state(
15578         struct compile_state *state, struct scc_state *scc)
15579 {
15580         int ins_count, ssa_edge_count;
15581         int ins_index, ssa_edge_index, fblock_index;
15582         struct triple *first, *ins;
15583         struct block *block;
15584         struct flow_block *fblock;
15585
15586         memset(scc, 0, sizeof(*scc));
15587
15588         /* Inialize pass zero find out how much memory we need */
15589         first = state->first;
15590         ins = first;
15591         ins_count = ssa_edge_count = 0;
15592         do {
15593                 struct triple_set *edge;
15594                 ins_count += 1;
15595                 for(edge = ins->use; edge; edge = edge->next) {
15596                         ssa_edge_count++;
15597                 }
15598                 ins = ins->next;
15599         } while(ins != first);
15600         if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
15601                 fprintf(stderr, "ins_count: %d ssa_edge_count: %d vertex_count: %d\n",
15602                         ins_count, ssa_edge_count, state->last_vertex);
15603         }
15604         scc->ins_count   = ins_count;
15605         scc->lattice     = 
15606                 xcmalloc(sizeof(*scc->lattice)*(ins_count + 1), "lattice");
15607         scc->ssa_edges   = 
15608                 xcmalloc(sizeof(*scc->ssa_edges)*(ssa_edge_count + 1), "ssa_edges");
15609         scc->flow_blocks = 
15610                 xcmalloc(sizeof(*scc->flow_blocks)*(state->last_vertex + 1), 
15611                         "flow_blocks");
15612
15613         /* Initialize pass one collect up the nodes */
15614         fblock = 0;
15615         block = 0;
15616         ins_index = ssa_edge_index = fblock_index = 0;
15617         ins = first;
15618         do {
15619                 if ((ins->op == OP_LABEL) && (block != ins->u.block)) {
15620                         block = ins->u.block;
15621                         if (!block) {
15622                                 internal_error(state, ins, "label without block");
15623                         }
15624                         fblock_index += 1;
15625                         block->vertex = fblock_index;
15626                         fblock = &scc->flow_blocks[fblock_index];
15627                         fblock->block = block;
15628                         fblock->edges = xcmalloc(sizeof(*fblock->edges)*block->edge_count,
15629                                 "flow_edges");
15630                 }
15631                 {
15632                         struct lattice_node *lnode;
15633                         ins_index += 1;
15634                         lnode = &scc->lattice[ins_index];
15635                         lnode->def = ins;
15636                         lnode->out = 0;
15637                         lnode->fblock = fblock;
15638                         lnode->val = ins; /* LATTICE HIGH */
15639                         lnode->old_id = ins->id;
15640                         ins->id = ins_index;
15641                 }
15642                 ins = ins->next;
15643         } while(ins != first);
15644         /* Initialize pass two collect up the edges */
15645         block = 0;
15646         fblock = 0;
15647         ins = first;
15648         do {
15649                 {
15650                         struct triple_set *edge;
15651                         struct ssa_edge **stail;
15652                         struct lattice_node *lnode;
15653                         lnode = &scc->lattice[ins->id];
15654                         lnode->out = 0;
15655                         stail = &lnode->out;
15656                         for(edge = ins->use; edge; edge = edge->next) {
15657                                 struct ssa_edge *sedge;
15658                                 ssa_edge_index += 1;
15659                                 sedge = &scc->ssa_edges[ssa_edge_index];
15660                                 *stail = sedge;
15661                                 stail = &sedge->out_next;
15662                                 sedge->src = lnode;
15663                                 sedge->dst = &scc->lattice[edge->member->id];
15664                                 sedge->work_next = sedge->work_prev = sedge;
15665                                 sedge->out_next = 0;
15666                         }
15667                 }
15668                 if ((ins->op == OP_LABEL) && (block != ins->u.block)) {
15669                         struct flow_edge *fedge, **ftail;
15670                         struct block_set *bedge;
15671                         block = ins->u.block;
15672                         fblock = &scc->flow_blocks[block->vertex];
15673                         fblock->in = 0;
15674                         fblock->out = 0;
15675                         ftail = &fblock->out;
15676
15677                         fedge = fblock->edges;
15678                         bedge = block->edges;
15679                         for(; bedge; bedge = bedge->next, fedge++) {
15680                                 fedge->dst = &scc->flow_blocks[bedge->member->vertex];
15681                                 if (fedge->dst->block != bedge->member) {
15682                                         internal_error(state, 0, "block mismatch");
15683                                 }
15684                                 *ftail = fedge;
15685                                 ftail = &fedge->out_next;
15686                                 fedge->out_next = 0;
15687                         }
15688                         for(fedge = fblock->out; fedge; fedge = fedge->out_next) {
15689                                 fedge->src = fblock;
15690                                 fedge->work_next = fedge->work_prev = fedge;
15691                                 fedge->executable = 0;
15692                         }
15693                 }
15694                 ins = ins->next;
15695         } while (ins != first);
15696         block = 0;
15697         fblock = 0;
15698         ins = first;
15699         do {
15700                 if ((ins->op  == OP_LABEL) && (block != ins->u.block)) {
15701                         struct flow_edge **ftail;
15702                         struct block_set *bedge;
15703                         block = ins->u.block;
15704                         fblock = &scc->flow_blocks[block->vertex];
15705                         ftail = &fblock->in;
15706                         for(bedge = block->use; bedge; bedge = bedge->next) {
15707                                 struct block *src_block;
15708                                 struct flow_block *sfblock;
15709                                 struct flow_edge *sfedge;
15710                                 src_block = bedge->member;
15711                                 sfblock = &scc->flow_blocks[src_block->vertex];
15712                                 for(sfedge = sfblock->out; sfedge; sfedge = sfedge->out_next) {
15713                                         if (sfedge->dst == fblock) {
15714                                                 break;
15715                                         }
15716                                 }
15717                                 if (!sfedge) {
15718                                         internal_error(state, 0, "edge mismatch");
15719                                 }
15720                                 *ftail = sfedge;
15721                                 ftail = &sfedge->in_next;
15722                                 sfedge->in_next = 0;
15723                         }
15724                 }
15725                 ins = ins->next;
15726         } while(ins != first);
15727         /* Setup a dummy block 0 as a node above the start node */
15728         {
15729                 struct flow_block *fblock, *dst;
15730                 struct flow_edge *fedge;
15731                 fblock = &scc->flow_blocks[0];
15732                 fblock->block = 0;
15733                 fblock->edges = xcmalloc(sizeof(*fblock->edges)*1, "flow_edges");
15734                 fblock->in = 0;
15735                 fblock->out = fblock->edges;
15736                 dst = &scc->flow_blocks[state->first_block->vertex];
15737                 fedge = fblock->edges;
15738                 fedge->src        = fblock;
15739                 fedge->dst        = dst;
15740                 fedge->work_next  = fedge;
15741                 fedge->work_prev  = fedge;
15742                 fedge->in_next    = fedge->dst->in;
15743                 fedge->out_next   = 0;
15744                 fedge->executable = 0;
15745                 fedge->dst->in = fedge;
15746                 
15747                 /* Initialize the work lists */
15748                 scc->flow_work_list = 0;
15749                 scc->ssa_work_list  = 0;
15750                 scc_add_fedge(state, scc, fedge);
15751         }
15752         if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
15753                 fprintf(stderr, "ins_index: %d ssa_edge_index: %d fblock_index: %d\n",
15754                         ins_index, ssa_edge_index, fblock_index);
15755         }
15756 }
15757
15758         
15759 static void free_scc_state(
15760         struct compile_state *state, struct scc_state *scc)
15761 {
15762         int i;
15763         for(i = 0; i < state->last_vertex + 1; i++) {
15764                 struct flow_block *fblock;
15765                 fblock = &scc->flow_blocks[i];
15766                 if (fblock->edges) {
15767                         xfree(fblock->edges);
15768                         fblock->edges = 0;
15769                 }
15770         }
15771         xfree(scc->flow_blocks);
15772         xfree(scc->ssa_edges);
15773         xfree(scc->lattice);
15774         
15775 }
15776
15777 static struct lattice_node *triple_to_lattice(
15778         struct compile_state *state, struct scc_state *scc, struct triple *ins)
15779 {
15780         if (ins->id <= 0) {
15781                 internal_error(state, ins, "bad id");
15782         }
15783         return &scc->lattice[ins->id];
15784 }
15785
15786 static struct triple *preserve_lval(
15787         struct compile_state *state, struct lattice_node *lnode)
15788 {
15789         struct triple *old;
15790         /* Preserve the original value */
15791         if (lnode->val) {
15792                 old = dup_triple(state, lnode->val);
15793                 if (lnode->val != lnode->def) {
15794                         xfree(lnode->val);
15795                 }
15796                 lnode->val = 0;
15797         } else {
15798                 old = 0;
15799         }
15800         return old;
15801 }
15802
15803 static int lval_changed(struct compile_state *state, 
15804         struct triple *old, struct lattice_node *lnode)
15805 {
15806         int changed;
15807         /* See if the lattice value has changed */
15808         changed = 1;
15809         if (!old && !lnode->val) {
15810                 changed = 0;
15811         }
15812         if (changed && lnode->val && !is_const(lnode->val)) {
15813                 changed = 0;
15814         }
15815         if (changed &&
15816                 lnode->val && old &&
15817                 (memcmp(lnode->val->param, old->param,
15818                         TRIPLE_SIZE(lnode->val->sizes) * sizeof(lnode->val->param[0])) == 0) &&
15819                 (memcmp(&lnode->val->u, &old->u, sizeof(old->u)) == 0)) {
15820                 changed = 0;
15821         }
15822         if (old) {
15823                 xfree(old);
15824         }
15825         return changed;
15826
15827 }
15828
15829 static void scc_debug_lnode(
15830         struct compile_state *state, struct lattice_node *lnode, int changed)
15831 {
15832         if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
15833                 FILE *fp = stderr;
15834                 struct triple *val, **expr;
15835                 val = lnode->val? lnode->val : lnode->def;
15836                 fprintf(fp, "%p %s %3d %10s (",
15837                         lnode->def, 
15838                         ((lnode->def->op == OP_PHI)? "phi: ": "expr:"),
15839                         lnode->def->id,
15840                         tops(lnode->def->op));
15841                 expr = triple_rhs(state, lnode->def, 0);
15842                 for(;expr;expr = triple_rhs(state, lnode->def, expr)) {
15843                         if (*expr) {
15844                                 fprintf(fp, " %d", (*expr)->id);
15845                         }
15846                 }
15847                 if (val->op == OP_INTCONST) {
15848                         fprintf(fp, " <0x%08lx>", (unsigned long)(val->u.cval));
15849                 }
15850                 fprintf(fp, " ) -> %s %s\n",
15851                         ((!lnode->val)? "lo": is_const(lnode->val)? "const": "hi"),
15852                         changed? "changed" : ""
15853                         );
15854         }
15855 }
15856
15857 static void scc_visit_phi(struct compile_state *state, struct scc_state *scc, 
15858         struct lattice_node *lnode)
15859 {
15860         struct lattice_node *tmp;
15861         struct triple **slot, *old;
15862         struct flow_edge *fedge;
15863         int changed;
15864         int index;
15865         if (lnode->def->op != OP_PHI) {
15866                 internal_error(state, lnode->def, "not phi");
15867         }
15868         /* Store the original value */
15869         old = preserve_lval(state, lnode);
15870
15871         /* default to lattice high */
15872         lnode->val = lnode->def;
15873         slot = &RHS(lnode->def, 0);
15874         index = 0;
15875         for(fedge = lnode->fblock->in; fedge; index++, fedge = fedge->in_next) {
15876                 if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
15877                         fprintf(stderr, "Examining edge: %d vertex: %d executable: %d\n", 
15878                                 index,
15879                                 fedge->dst->block->vertex,
15880                                 fedge->executable
15881                                 );
15882                 }
15883                 if (!fedge->executable) {
15884                         continue;
15885                 }
15886                 if (!slot[index]) {
15887                         internal_error(state, lnode->def, "no phi value");
15888                 }
15889                 tmp = triple_to_lattice(state, scc, slot[index]);
15890                 /* meet(X, lattice low) = lattice low */
15891                 if (!tmp->val) {
15892                         lnode->val = 0;
15893                 }
15894                 /* meet(X, lattice high) = X */
15895                 else if (!tmp->val) {
15896                         lnode->val = lnode->val;
15897                 }
15898                 /* meet(lattice high, X) = X */
15899                 else if (!is_const(lnode->val)) {
15900                         lnode->val = dup_triple(state, tmp->val);
15901                         lnode->val->type = lnode->def->type;
15902                 }
15903                 /* meet(const, const) = const or lattice low */
15904                 else if (!constants_equal(state, lnode->val, tmp->val)) {
15905                         lnode->val = 0;
15906                 }
15907                 if (!lnode->val) {
15908                         break;
15909                 }
15910         }
15911         changed = lval_changed(state, old, lnode);
15912         scc_debug_lnode(state, lnode, changed);
15913
15914         /* If the lattice value has changed update the work lists. */
15915         if (changed) {
15916                 struct ssa_edge *sedge;
15917                 for(sedge = lnode->out; sedge; sedge = sedge->out_next) {
15918                         scc_add_sedge(state, scc, sedge);
15919                 }
15920         }
15921 }
15922
15923 static int compute_lnode_val(struct compile_state *state, struct scc_state *scc,
15924         struct lattice_node *lnode)
15925 {
15926         int changed;
15927         struct triple *old, *scratch;
15928         struct triple **dexpr, **vexpr;
15929         int count, i;
15930         
15931         /* Store the original value */
15932         old = preserve_lval(state, lnode);
15933
15934         /* Reinitialize the value */
15935         lnode->val = scratch = dup_triple(state, lnode->def);
15936         scratch->id = lnode->old_id;
15937         scratch->next     = scratch;
15938         scratch->prev     = scratch;
15939         scratch->use      = 0;
15940
15941         count = TRIPLE_SIZE(scratch->sizes);
15942         for(i = 0; i < count; i++) {
15943                 dexpr = &lnode->def->param[i];
15944                 vexpr = &scratch->param[i];
15945                 *vexpr = *dexpr;
15946                 if (((i < TRIPLE_MISC_OFF(scratch->sizes)) ||
15947                         (i >= TRIPLE_TARG_OFF(scratch->sizes))) &&
15948                         *dexpr) {
15949                         struct lattice_node *tmp;
15950                         tmp = triple_to_lattice(state, scc, *dexpr);
15951                         *vexpr = (tmp->val)? tmp->val : tmp->def;
15952                 }
15953         }
15954         if (triple_is_branch(state, scratch)) {
15955                 scratch->next = lnode->def->next;
15956         }
15957         /* Recompute the value */
15958 #warning "FIXME see if simplify does anything bad"
15959         /* So far it looks like only the strength reduction
15960          * optimization are things I need to worry about.
15961          */
15962         simplify(state, scratch);
15963         /* Cleanup my value */
15964         if (scratch->use) {
15965                 internal_error(state, lnode->def, "scratch used?");
15966         }
15967         if ((scratch->prev != scratch) ||
15968                 ((scratch->next != scratch) &&
15969                         (!triple_is_branch(state, lnode->def) ||
15970                                 (scratch->next != lnode->def->next)))) {
15971                 internal_error(state, lnode->def, "scratch in list?");
15972         }
15973         /* undo any uses... */
15974         count = TRIPLE_SIZE(scratch->sizes);
15975         for(i = 0; i < count; i++) {
15976                 vexpr = &scratch->param[i];
15977                 if (*vexpr) {
15978                         unuse_triple(*vexpr, scratch);
15979                 }
15980         }
15981         if (!is_const(scratch)) {
15982                 for(i = 0; i < count; i++) {
15983                         dexpr = &lnode->def->param[i];
15984                         if (((i < TRIPLE_MISC_OFF(scratch->sizes)) ||
15985                                 (i >= TRIPLE_TARG_OFF(scratch->sizes))) &&
15986                                 *dexpr) {
15987                                 struct lattice_node *tmp;
15988                                 tmp = triple_to_lattice(state, scc, *dexpr);
15989                                 if (!tmp->val) {
15990                                         lnode->val = 0;
15991                                 }
15992                         }
15993                 }
15994         }
15995         if (lnode->val && 
15996                 (lnode->val->op == lnode->def->op) &&
15997                 (memcmp(lnode->val->param, lnode->def->param, 
15998                         count * sizeof(lnode->val->param[0])) == 0) &&
15999                 (memcmp(&lnode->val->u, &lnode->def->u, sizeof(lnode->def->u)) == 0)) {
16000                 lnode->val = lnode->def;
16001         }
16002         /* Find the cases that are always lattice lo */
16003         if (lnode->val && 
16004                 triple_is_def(state, lnode->val) &&
16005                 !triple_is_pure(state, lnode->val, lnode->old_id)) {
16006                 lnode->val = 0;
16007         }
16008         /* See if the lattice value has changed */
16009         changed = lval_changed(state, old, lnode);
16010         /* See if this value should not change */
16011         if (lnode->val && 
16012                 ((      !triple_is_def(state, lnode->def)  &&
16013                         !triple_is_cond_branch(state, lnode->def)) ||
16014                         (lnode->def->op == OP_PIECE))) {
16015 #warning "FIXME constant propogate through expressions with multiple left hand sides"
16016                 if (changed) {
16017                         internal_warning(state, lnode->def, "non def changes value?");
16018                 }
16019                 lnode->val = 0;
16020         }
16021         /* Report what has just happened */
16022         if (state->compiler->debug & DEBUG_SCC_TRANSFORM2) {
16023                 display_triple_changes(stderr, scratch, lnode->def);
16024         }
16025
16026         /* See if we need to free the scratch value */
16027         if (lnode->val != scratch) {
16028                 xfree(scratch);
16029         }
16030         return changed;
16031 }
16032
16033 static void scc_visit_branch(struct compile_state *state, struct scc_state *scc,
16034         struct lattice_node *lnode)
16035 {
16036         struct lattice_node *cond;
16037         struct flow_edge *left, *right;
16038         if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
16039                 struct flow_edge *fedge;
16040                 fprintf(stderr, "%s: %d (",
16041                         tops(lnode->def->op),
16042                         lnode->def->id);
16043                 
16044                 for(fedge = lnode->fblock->out; fedge; fedge = fedge->out_next) {
16045                         fprintf(stderr, " %d", fedge->dst->block->vertex);
16046                 }
16047                 fprintf(stderr, " )");
16048                 if (TRIPLE_RHS(lnode->def->sizes) > 0) {
16049                         fprintf(stderr, " <- %d",
16050                                 RHS(lnode->def, 0)->id);
16051                 }
16052                 fprintf(stderr, "\n");
16053         }
16054         if (!triple_is_branch(state, lnode->def)) {
16055                 internal_error(state, lnode->def, "not branch");
16056         }
16057         /* This only applies to conditional branches */
16058         if (!triple_is_cond_branch(state, lnode->def)) {
16059                 return;
16060         }
16061         cond = triple_to_lattice(state, scc, RHS(lnode->def,0));
16062         for(left = cond->fblock->out; left; left = left->out_next) {
16063                 if (left->dst->block->first == lnode->def->next) {
16064                         break;
16065                 }
16066         }
16067         if (!left) {
16068                 internal_error(state, lnode->def, "Cannot find left branch edge");
16069         }
16070         for(right = cond->fblock->out; right; right = right->out_next) {
16071                 if (right->dst->block->first == TARG(lnode->def, 0)) {
16072                         break;
16073                 }
16074         }
16075         if (!right) {
16076                 internal_error(state, lnode->def, "Cannot find right branch edge");
16077         }
16078         if (cond->val && !is_const(cond->val)) {
16079 #warning "FIXME do I need to do something here?"
16080                 warning(state, cond->def, "condition not constant?");
16081                 return;
16082         }
16083         if (cond->val == 0) {
16084                 scc_add_fedge(state, scc, left);
16085                 scc_add_fedge(state, scc, right);
16086         }
16087         else if (cond->val->u.cval) {
16088                 scc_add_fedge(state, scc, right);
16089         } else {
16090                 scc_add_fedge(state, scc, left);
16091         }
16092
16093 }
16094
16095 static void scc_visit_expr(struct compile_state *state, struct scc_state *scc,
16096         struct lattice_node *lnode)
16097 {
16098         int changed;
16099
16100         changed = compute_lnode_val(state, scc, lnode);
16101         scc_debug_lnode(state, lnode, changed);
16102
16103         if (triple_is_branch(state, lnode->def)) {
16104                 scc_visit_branch(state, scc, lnode);
16105         }
16106         else if (changed) {
16107                 struct ssa_edge *sedge;
16108                 for(sedge = lnode->out; sedge; sedge = sedge->out_next) {
16109                         scc_add_sedge(state, scc, sedge);
16110                 }
16111         }
16112 }
16113
16114 static void scc_writeback_values(
16115         struct compile_state *state, struct scc_state *scc)
16116 {
16117         struct triple *first, *ins;
16118         first = state->first;
16119         ins = first;
16120         do {
16121                 struct lattice_node *lnode;
16122                 lnode = triple_to_lattice(state, scc, ins);
16123
16124                 if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
16125                         if (lnode->val && 
16126                                 !is_const(lnode->val) &&
16127                                 !triple_is_uncond_branch(state, lnode->val) &&
16128                                 (lnode->val->op != OP_NOOP)) 
16129                         {
16130                                 struct flow_edge *fedge;
16131                                 int executable;
16132                                 executable = 0;
16133                                 for(fedge = lnode->fblock->in; 
16134                                     !executable && fedge; fedge = fedge->in_next) {
16135                                         executable |= fedge->executable;
16136                                 }
16137                                 if (executable) {
16138                                         internal_warning(state, lnode->val,
16139                                                 "lattice node %d %s->%s still high?",
16140                                                 ins->id, 
16141                                                 tops(lnode->def->op),
16142                                                 tops(lnode->val->op));
16143                                 }
16144                         }
16145                 }
16146
16147                 /* Restore id */
16148                 ins->id = lnode->old_id;
16149                 if (lnode->val && (lnode->val != ins)) {
16150                         /* See if it something I know how to write back */
16151                         switch(lnode->val->op) {
16152                         case OP_INTCONST:
16153                                 mkconst(state, ins, lnode->val->u.cval);
16154                                 break;
16155                         case OP_ADDRCONST:
16156                                 mkaddr_const(state, ins, 
16157                                         MISC(lnode->val, 0), lnode->val->u.cval);
16158                                 break;
16159                         default:
16160                                 /* By default don't copy the changes,
16161                                  * recompute them in place instead.
16162                                  */
16163                                 simplify(state, ins);
16164                                 break;
16165                         }
16166                         if (is_const(lnode->val) &&
16167                                 !constants_equal(state, lnode->val, ins)) {
16168                                 internal_error(state, 0, "constants not equal");
16169                         }
16170                         /* Free the lattice nodes */
16171                         xfree(lnode->val);
16172                         lnode->val = 0;
16173                 }
16174                 ins = ins->next;
16175         } while(ins != first);
16176 }
16177
16178 static void scc_transform(struct compile_state *state)
16179 {
16180         struct scc_state scc;
16181         if (!(state->compiler->flags & COMPILER_SCC_TRANSFORM)) {
16182                 return;
16183         }
16184
16185         initialize_scc_state(state, &scc);
16186
16187         while(scc.flow_work_list || scc.ssa_work_list) {
16188                 struct flow_edge *fedge;
16189                 struct ssa_edge *sedge;
16190                 struct flow_edge *fptr;
16191                 while((fedge = scc_next_fedge(state, &scc))) {
16192                         struct block *block;
16193                         struct triple *ptr;
16194                         struct flow_block *fblock;
16195                         int reps;
16196                         int done;
16197                         if (fedge->executable) {
16198                                 continue;
16199                         }
16200                         if (!fedge->dst) {
16201                                 internal_error(state, 0, "fedge without dst");
16202                         }
16203                         if (!fedge->src) {
16204                                 internal_error(state, 0, "fedge without src");
16205                         }
16206                         fedge->executable = 1;
16207                         fblock = fedge->dst;
16208                         block = fblock->block;
16209                         reps = 0;
16210                         for(fptr = fblock->in; fptr; fptr = fptr->in_next) {
16211                                 if (fptr->executable) {
16212                                         reps++;
16213                                 }
16214                         }
16215                         
16216                         if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
16217                                 fprintf(stderr, "vertex: %d reps: %d\n", 
16218                                         block->vertex, reps);
16219                         }
16220
16221                         done = 0;
16222                         for(ptr = block->first; !done; ptr = ptr->next) {
16223                                 struct lattice_node *lnode;
16224                                 done = (ptr == block->last);
16225                                 lnode = &scc.lattice[ptr->id];
16226                                 if (ptr->op == OP_PHI) {
16227                                         scc_visit_phi(state, &scc, lnode);
16228                                 }
16229                                 else if (reps == 1) {
16230                                         scc_visit_expr(state, &scc, lnode);
16231                                 }
16232                         }
16233                         /* Add unconditional branch edges */
16234                         if (!triple_is_cond_branch(state, fblock->block->last)) {
16235                                 struct flow_edge *out;
16236                                 for(out = fblock->out; out; out = out->out_next) {
16237                                         scc_add_fedge(state, &scc, out);
16238                                 }
16239                         }
16240                 }
16241                 while((sedge = scc_next_sedge(state, &scc))) {
16242                         struct lattice_node *lnode;
16243                         struct flow_block *fblock;
16244                         lnode = sedge->dst;
16245                         fblock = lnode->fblock;
16246
16247                         if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
16248                                 fprintf(stderr, "sedge: %5d (%5d -> %5d)\n",
16249                                         sedge - scc.ssa_edges,
16250                                         sedge->src->def->id,
16251                                         sedge->dst->def->id);
16252                         }
16253
16254                         if (lnode->def->op == OP_PHI) {
16255                                 scc_visit_phi(state, &scc, lnode);
16256                         }
16257                         else {
16258                                 for(fptr = fblock->in; fptr; fptr = fptr->in_next) {
16259                                         if (fptr->executable) {
16260                                                 break;
16261                                         }
16262                                 }
16263                                 if (fptr) {
16264                                         scc_visit_expr(state, &scc, lnode);
16265                                 }
16266                         }
16267                 }
16268         }
16269         
16270         scc_writeback_values(state, &scc);
16271         free_scc_state(state, &scc);
16272         rebuild_ssa_form(state);
16273         
16274         print_blocks(state, __func__, stdout);
16275 }
16276
16277
16278 static void transform_to_arch_instructions(struct compile_state *state)
16279 {
16280         struct triple *ins, *first;
16281         first = state->first;
16282         ins = first;
16283         do {
16284                 ins = transform_to_arch_instruction(state, ins);
16285         } while(ins != first);
16286         
16287         print_blocks(state, __func__, stdout);
16288 }
16289
16290 #if DEBUG_CONSISTENCY
16291 static void verify_uses(struct compile_state *state)
16292 {
16293         struct triple *first, *ins;
16294         struct triple_set *set;
16295         first = state->first;
16296         ins = first;
16297         do {
16298                 struct triple **expr;
16299                 expr = triple_rhs(state, ins, 0);
16300                 for(; expr; expr = triple_rhs(state, ins, expr)) {
16301                         struct triple *rhs;
16302                         rhs = *expr;
16303                         for(set = rhs?rhs->use:0; set; set = set->next) {
16304                                 if (set->member == ins) {
16305                                         break;
16306                                 }
16307                         }
16308                         if (!set) {
16309                                 internal_error(state, ins, "rhs not used");
16310                         }
16311                 }
16312                 expr = triple_lhs(state, ins, 0);
16313                 for(; expr; expr = triple_lhs(state, ins, expr)) {
16314                         struct triple *lhs;
16315                         lhs = *expr;
16316                         for(set =  lhs?lhs->use:0; set; set = set->next) {
16317                                 if (set->member == ins) {
16318                                         break;
16319                                 }
16320                         }
16321                         if (!set) {
16322                                 internal_error(state, ins, "lhs not used");
16323                         }
16324                 }
16325                 ins = ins->next;
16326         } while(ins != first);
16327         
16328 }
16329 static void verify_blocks_present(struct compile_state *state)
16330 {
16331         struct triple *first, *ins;
16332         if (!state->first_block) {
16333                 return;
16334         }
16335         first = state->first;
16336         ins = first;
16337         do {
16338                 valid_ins(state, ins);
16339                 if (triple_stores_block(state, ins)) {
16340                         if (!ins->u.block) {
16341                                 internal_error(state, ins, 
16342                                         "%p not in a block?\n", ins);
16343                         }
16344                 }
16345                 ins = ins->next;
16346         } while(ins != first);
16347         
16348         
16349 }
16350
16351 static int edge_present(struct compile_state *state, struct block *block, struct triple *edge)
16352 {
16353         struct block_set *bedge;
16354         struct block *targ;
16355         targ = block_of_triple(state, edge);
16356         for(bedge = block->edges; bedge; bedge = bedge->next) {
16357                 if (bedge->member == targ) {
16358                         return 1;
16359                 }
16360         }
16361         return 0;
16362 }
16363
16364 static void verify_blocks(struct compile_state *state)
16365 {
16366         struct triple *ins;
16367         struct block *block;
16368         int blocks;
16369         block = state->first_block;
16370         if (!block) {
16371                 return;
16372         }
16373         blocks = 0;
16374         do {
16375                 int users;
16376                 struct block_set *user, *edge;
16377                 blocks++;
16378                 for(ins = block->first; ins != block->last->next; ins = ins->next) {
16379                         if (triple_stores_block(state, ins) && (ins->u.block != block)) {
16380                                 internal_error(state, ins, "inconsitent block specified");
16381                         }
16382                         valid_ins(state, ins);
16383                 }
16384                 users = 0;
16385                 for(user = block->use; user; user = user->next) {
16386                         users++;
16387                         if (!user->member->first) {
16388                                 internal_error(state, block->first, "user is empty");
16389                         }
16390                         if ((block == state->last_block) &&
16391                                 (user->member == state->first_block)) {
16392                                 continue;
16393                         }
16394                         for(edge = user->member->edges; edge; edge = edge->next) {
16395                                 if (edge->member == block) {
16396                                         break;
16397                                 }
16398                         }
16399                         if (!edge) {
16400                                 internal_error(state, user->member->first,
16401                                         "user does not use block");
16402                         }
16403                 }
16404                 if (triple_is_branch(state, block->last)) {
16405                         struct triple **expr;
16406                         expr = triple_targ(state, block->last, 0);
16407                         for(;expr; expr = triple_targ(state, block->last, expr)) {
16408                                 if (*expr && !edge_present(state, block, *expr)) {
16409                                         internal_error(state, block->last, "no edge to targ");
16410                                 }
16411                         }
16412                 }
16413                 if (!triple_is_uncond_branch(state, block->last) &&
16414                         (block != state->last_block) &&
16415                         !edge_present(state, block, block->last->next)) {
16416                         internal_error(state, block->last, "no edge to block->last->next");
16417                 }
16418                 for(edge = block->edges; edge; edge = edge->next) {
16419                         for(user = edge->member->use; user; user = user->next) {
16420                                 if (user->member == block) {
16421                                         break;
16422                                 }
16423                         }
16424                         if (!user || user->member != block) {
16425                                 internal_error(state, block->first,
16426                                         "block does not use edge");
16427                         }
16428                         if (!edge->member->first) {
16429                                 internal_error(state, block->first, "edge block is empty");
16430                         }
16431                 }
16432                 if (block->users != users) {
16433                         internal_error(state, block->first, 
16434                                 "computed users %d != stored users %d\n",
16435                                 users, block->users);
16436                 }
16437                 if (!triple_stores_block(state, block->last->next)) {
16438                         internal_error(state, block->last->next, 
16439                                 "cannot find next block");
16440                 }
16441                 block = block->last->next->u.block;
16442                 if (!block) {
16443                         internal_error(state, block->last->next,
16444                                 "bad next block");
16445                 }
16446         } while(block != state->first_block);
16447         if (blocks != state->last_vertex) {
16448                 internal_error(state, 0, "computed blocks != stored blocks %d\n",
16449                         blocks, state->last_vertex);
16450         }
16451 }
16452
16453 static void verify_domination(struct compile_state *state)
16454 {
16455         struct triple *first, *ins;
16456         struct triple_set *set;
16457         if (!state->first_block) {
16458                 return;
16459         }
16460         
16461         first = state->first;
16462         ins = first;
16463         do {
16464                 for(set = ins->use; set; set = set->next) {
16465                         struct triple **slot;
16466                         struct triple *use_point;
16467                         int i, zrhs;
16468                         use_point = 0;
16469                         zrhs = TRIPLE_RHS(set->member->sizes);
16470                         slot = &RHS(set->member, 0);
16471                         /* See if the use is on the right hand side */
16472                         for(i = 0; i < zrhs; i++) {
16473                                 if (slot[i] == ins) {
16474                                         break;
16475                                 }
16476                         }
16477                         if (i < zrhs) {
16478                                 use_point = set->member;
16479                                 if (set->member->op == OP_PHI) {
16480                                         struct block_set *bset;
16481                                         int edge;
16482                                         bset = set->member->u.block->use;
16483                                         for(edge = 0; bset && (edge < i); edge++) {
16484                                                 bset = bset->next;
16485                                         }
16486                                         if (!bset) {
16487                                                 internal_error(state, set->member, 
16488                                                         "no edge for phi rhs %d\n", i);
16489                                         }
16490                                         use_point = bset->member->last;
16491                                 }
16492                         }
16493                         if (use_point &&
16494                                 !tdominates(state, ins, use_point)) {
16495                                 internal_error(state, use_point, 
16496                                         "non dominated rhs use point?");
16497                         }
16498                 }
16499                 ins = ins->next;
16500         } while(ins != first);
16501 }
16502
16503 static void verify_rhs(struct compile_state *state)
16504 {
16505         struct triple *first, *ins;
16506         first = state->first;
16507         ins = first;
16508         do {
16509                 struct triple **slot;
16510                 int zrhs, i;
16511                 zrhs = TRIPLE_RHS(ins->sizes);
16512                 slot = &RHS(ins, 0);
16513                 for(i = 0; i < zrhs; i++) {
16514                         if (slot[i] == 0) {
16515                                 internal_error(state, ins,
16516                                         "missing rhs %d on %s",
16517                                         i, tops(ins->op));
16518                         }
16519                         if ((ins->op != OP_PHI) && (slot[i] == ins)) {
16520                                 internal_error(state, ins,
16521                                         "ins == rhs[%d] on %s",
16522                                         i, tops(ins->op));
16523                         }
16524                 }
16525                 ins = ins->next;
16526         } while(ins != first);
16527 }
16528
16529 static void verify_piece(struct compile_state *state)
16530 {
16531         struct triple *first, *ins;
16532         first = state->first;
16533         ins = first;
16534         do {
16535                 struct triple *ptr;
16536                 int lhs, i;
16537                 lhs = TRIPLE_LHS(ins->sizes);
16538                 for(ptr = ins->next, i = 0; i < lhs; i++, ptr = ptr->next) {
16539                         if (ptr != LHS(ins, i)) {
16540                                 internal_error(state, ins, "malformed lhs on %s",
16541                                         tops(ins->op));
16542                         }
16543                         if (ptr->op != OP_PIECE) {
16544                                 internal_error(state, ins, "bad lhs op %s at %d on %s",
16545                                         tops(ptr->op), i, tops(ins->op));
16546                         }
16547                         if (ptr->u.cval != i) {
16548                                 internal_error(state, ins, "bad u.cval of %d %d expected",
16549                                         ptr->u.cval, i);
16550                         }
16551                 }
16552                 ins = ins->next;
16553         } while(ins != first);
16554 }
16555
16556 static void verify_ins_colors(struct compile_state *state)
16557 {
16558         struct triple *first, *ins;
16559         
16560         first = state->first;
16561         ins = first;
16562         do {
16563                 ins = ins->next;
16564         } while(ins != first);
16565 }
16566 static void verify_consistency(struct compile_state *state)
16567 {
16568         verify_uses(state);
16569         verify_blocks_present(state);
16570         verify_blocks(state);
16571         verify_domination(state);
16572         verify_rhs(state);
16573         verify_piece(state);
16574         verify_ins_colors(state);
16575 }
16576 #else 
16577 static void verify_consistency(struct compile_state *state) {}
16578 #endif /* DEBUG_CONSISTENCY */
16579
16580 static void optimize(struct compile_state *state)
16581 {
16582         /* Dump what the instruction graph intially looks like */
16583         print_triples(state);
16584
16585         /* Replace structures with simpler data types */
16586         flatten_structures(state);
16587         print_triples(state);
16588
16589         verify_consistency(state);
16590         /* Analize the intermediate code */
16591         analyze_basic_blocks(state);
16592
16593         /* Transform the code to ssa form. */
16594         /*
16595          * The transformation to ssa form puts a phi function
16596          * on each of edge of a dominance frontier where that
16597          * phi function might be needed.  At -O2 if we don't
16598          * eleminate the excess phi functions we can get an
16599          * exponential code size growth.  So I kill the extra
16600          * phi functions early and I kill them often.
16601          */
16602         transform_to_ssa_form(state);
16603         verify_consistency(state);
16604
16605         /* Remove dead code */
16606         eliminate_inefectual_code(state);
16607         verify_consistency(state);
16608
16609         /* Do strength reduction and simple constant optimizations */
16610         simplify_all(state);
16611         verify_consistency(state);
16612         /* Propogate constants throughout the code */
16613         scc_transform(state);
16614         verify_consistency(state);
16615 #warning "WISHLIST implement single use constants (least possible register pressure)"
16616 #warning "WISHLIST implement induction variable elimination"
16617         /* Select architecture instructions and an initial partial
16618          * coloring based on architecture constraints.
16619          */
16620         transform_to_arch_instructions(state);
16621         verify_consistency(state);
16622
16623         /* Remove dead code */
16624         eliminate_inefectual_code(state);
16625         verify_consistency(state);
16626
16627         /* Color all of the variables to see if they will fit in registers */
16628         insert_copies_to_phi(state);
16629         verify_consistency(state);
16630
16631         insert_mandatory_copies(state);
16632         verify_consistency(state);
16633
16634         allocate_registers(state);
16635         verify_consistency(state);
16636
16637         /* Remove the optimization information.
16638          * This is more to check for memory consistency than to free memory.
16639          */
16640         free_basic_blocks(state);
16641 }
16642
16643 static void print_op_asm(struct compile_state *state,
16644         struct triple *ins, FILE *fp)
16645 {
16646         struct asm_info *info;
16647         const char *ptr;
16648         unsigned lhs, rhs, i;
16649         info = ins->u.ainfo;
16650         lhs = TRIPLE_LHS(ins->sizes);
16651         rhs = TRIPLE_RHS(ins->sizes);
16652         /* Don't count the clobbers in lhs */
16653         for(i = 0; i < lhs; i++) {
16654                 if (LHS(ins, i)->type == &void_type) {
16655                         break;
16656                 }
16657         }
16658         lhs = i;
16659         fprintf(fp, "#ASM\n");
16660         fputc('\t', fp);
16661         for(ptr = info->str; *ptr; ptr++) {
16662                 char *next;
16663                 unsigned long param;
16664                 struct triple *piece;
16665                 if (*ptr != '%') {
16666                         fputc(*ptr, fp);
16667                         continue;
16668                 }
16669                 ptr++;
16670                 if (*ptr == '%') {
16671                         fputc('%', fp);
16672                         continue;
16673                 }
16674                 param = strtoul(ptr, &next, 10);
16675                 if (ptr == next) {
16676                         error(state, ins, "Invalid asm template");
16677                 }
16678                 if (param >= (lhs + rhs)) {
16679                         error(state, ins, "Invalid param %%%u in asm template",
16680                                 param);
16681                 }
16682                 piece = (param < lhs)? LHS(ins, param) : RHS(ins, param - lhs);
16683                 fprintf(fp, "%s", 
16684                         arch_reg_str(ID_REG(piece->id)));
16685                 ptr = next -1;
16686         }
16687         fprintf(fp, "\n#NOT ASM\n");
16688 }
16689
16690
16691 /* Only use the low x86 byte registers.  This allows me
16692  * allocate the entire register when a byte register is used.
16693  */
16694 #define X86_4_8BIT_GPRS 1
16695
16696 /* x86 featrues */
16697 #define X86_MMX_REGS (1<<0)
16698 #define X86_XMM_REGS (1<<1)
16699
16700 /* The x86 register classes */
16701 #define REGC_FLAGS       0
16702 #define REGC_GPR8        1
16703 #define REGC_GPR16       2
16704 #define REGC_GPR32       3
16705 #define REGC_DIVIDEND64  4
16706 #define REGC_DIVIDEND32  5
16707 #define REGC_MMX         6
16708 #define REGC_XMM         7
16709 #define REGC_GPR32_8     8
16710 #define REGC_GPR16_8     9
16711 #define REGC_GPR8_LO    10
16712 #define REGC_IMM32      11
16713 #define REGC_IMM16      12
16714 #define REGC_IMM8       13
16715 #define LAST_REGC  REGC_IMM8
16716 #if LAST_REGC >= MAX_REGC
16717 #error "MAX_REGC is to low"
16718 #endif
16719
16720 /* Register class masks */
16721 #define REGCM_FLAGS      (1 << REGC_FLAGS)
16722 #define REGCM_GPR8       (1 << REGC_GPR8)
16723 #define REGCM_GPR16      (1 << REGC_GPR16)
16724 #define REGCM_GPR32      (1 << REGC_GPR32)
16725 #define REGCM_DIVIDEND64 (1 << REGC_DIVIDEND64)
16726 #define REGCM_DIVIDEND32 (1 << REGC_DIVIDEND32)
16727 #define REGCM_MMX        (1 << REGC_MMX)
16728 #define REGCM_XMM        (1 << REGC_XMM)
16729 #define REGCM_GPR32_8    (1 << REGC_GPR32_8)
16730 #define REGCM_GPR16_8    (1 << REGC_GPR16_8)
16731 #define REGCM_GPR8_LO    (1 << REGC_GPR8_LO)
16732 #define REGCM_IMM32      (1 << REGC_IMM32)
16733 #define REGCM_IMM16      (1 << REGC_IMM16)
16734 #define REGCM_IMM8       (1 << REGC_IMM8)
16735 #define REGCM_ALL        ((1 << (LAST_REGC + 1)) - 1)
16736
16737 /* The x86 registers */
16738 #define REG_EFLAGS  2
16739 #define REGC_FLAGS_FIRST REG_EFLAGS
16740 #define REGC_FLAGS_LAST  REG_EFLAGS
16741 #define REG_AL      3
16742 #define REG_BL      4
16743 #define REG_CL      5
16744 #define REG_DL      6
16745 #define REG_AH      7
16746 #define REG_BH      8
16747 #define REG_CH      9
16748 #define REG_DH      10
16749 #define REGC_GPR8_LO_FIRST REG_AL
16750 #define REGC_GPR8_LO_LAST  REG_DL
16751 #define REGC_GPR8_FIRST  REG_AL
16752 #define REGC_GPR8_LAST   REG_DH
16753 #define REG_AX     11
16754 #define REG_BX     12
16755 #define REG_CX     13
16756 #define REG_DX     14
16757 #define REG_SI     15
16758 #define REG_DI     16
16759 #define REG_BP     17
16760 #define REG_SP     18
16761 #define REGC_GPR16_FIRST REG_AX
16762 #define REGC_GPR16_LAST  REG_SP
16763 #define REG_EAX    19
16764 #define REG_EBX    20
16765 #define REG_ECX    21
16766 #define REG_EDX    22
16767 #define REG_ESI    23
16768 #define REG_EDI    24
16769 #define REG_EBP    25
16770 #define REG_ESP    26
16771 #define REGC_GPR32_FIRST REG_EAX
16772 #define REGC_GPR32_LAST  REG_ESP
16773 #define REG_EDXEAX 27
16774 #define REGC_DIVIDEND64_FIRST REG_EDXEAX
16775 #define REGC_DIVIDEND64_LAST  REG_EDXEAX
16776 #define REG_DXAX   28
16777 #define REGC_DIVIDEND32_FIRST REG_DXAX
16778 #define REGC_DIVIDEND32_LAST  REG_DXAX
16779 #define REG_MMX0   29
16780 #define REG_MMX1   30
16781 #define REG_MMX2   31
16782 #define REG_MMX3   32
16783 #define REG_MMX4   33
16784 #define REG_MMX5   34
16785 #define REG_MMX6   35
16786 #define REG_MMX7   36
16787 #define REGC_MMX_FIRST REG_MMX0
16788 #define REGC_MMX_LAST  REG_MMX7
16789 #define REG_XMM0   37
16790 #define REG_XMM1   38
16791 #define REG_XMM2   39
16792 #define REG_XMM3   40
16793 #define REG_XMM4   41
16794 #define REG_XMM5   42
16795 #define REG_XMM6   43
16796 #define REG_XMM7   44
16797 #define REGC_XMM_FIRST REG_XMM0
16798 #define REGC_XMM_LAST  REG_XMM7
16799 #warning "WISHLIST figure out how to use pinsrw and pextrw to better use extended regs"
16800 #define LAST_REG   REG_XMM7
16801
16802 #define REGC_GPR32_8_FIRST REG_EAX
16803 #define REGC_GPR32_8_LAST  REG_EDX
16804 #define REGC_GPR16_8_FIRST REG_AX
16805 #define REGC_GPR16_8_LAST  REG_DX
16806
16807 #define REGC_IMM8_FIRST    -1
16808 #define REGC_IMM8_LAST     -1
16809 #define REGC_IMM16_FIRST   -2
16810 #define REGC_IMM16_LAST    -1
16811 #define REGC_IMM32_FIRST   -4
16812 #define REGC_IMM32_LAST    -1
16813
16814 #if LAST_REG >= MAX_REGISTERS
16815 #error "MAX_REGISTERS to low"
16816 #endif
16817
16818
16819 static unsigned regc_size[LAST_REGC +1] = {
16820         [REGC_FLAGS]      = REGC_FLAGS_LAST      - REGC_FLAGS_FIRST + 1,
16821         [REGC_GPR8]       = REGC_GPR8_LAST       - REGC_GPR8_FIRST + 1,
16822         [REGC_GPR16]      = REGC_GPR16_LAST      - REGC_GPR16_FIRST + 1,
16823         [REGC_GPR32]      = REGC_GPR32_LAST      - REGC_GPR32_FIRST + 1,
16824         [REGC_DIVIDEND64] = REGC_DIVIDEND64_LAST - REGC_DIVIDEND64_FIRST + 1,
16825         [REGC_DIVIDEND32] = REGC_DIVIDEND32_LAST - REGC_DIVIDEND32_FIRST + 1,
16826         [REGC_MMX]        = REGC_MMX_LAST        - REGC_MMX_FIRST + 1,
16827         [REGC_XMM]        = REGC_XMM_LAST        - REGC_XMM_FIRST + 1,
16828         [REGC_GPR32_8]    = REGC_GPR32_8_LAST    - REGC_GPR32_8_FIRST + 1,
16829         [REGC_GPR16_8]    = REGC_GPR16_8_LAST    - REGC_GPR16_8_FIRST + 1,
16830         [REGC_GPR8_LO]    = REGC_GPR8_LO_LAST    - REGC_GPR8_LO_FIRST + 1,
16831         [REGC_IMM32]      = 0,
16832         [REGC_IMM16]      = 0,
16833         [REGC_IMM8]       = 0,
16834 };
16835
16836 static const struct {
16837         int first, last;
16838 } regcm_bound[LAST_REGC + 1] = {
16839         [REGC_FLAGS]      = { REGC_FLAGS_FIRST,      REGC_FLAGS_LAST },
16840         [REGC_GPR8]       = { REGC_GPR8_FIRST,       REGC_GPR8_LAST },
16841         [REGC_GPR16]      = { REGC_GPR16_FIRST,      REGC_GPR16_LAST },
16842         [REGC_GPR32]      = { REGC_GPR32_FIRST,      REGC_GPR32_LAST },
16843         [REGC_DIVIDEND64] = { REGC_DIVIDEND64_FIRST, REGC_DIVIDEND64_LAST },
16844         [REGC_DIVIDEND32] = { REGC_DIVIDEND32_FIRST, REGC_DIVIDEND32_LAST },
16845         [REGC_MMX]        = { REGC_MMX_FIRST,        REGC_MMX_LAST },
16846         [REGC_XMM]        = { REGC_XMM_FIRST,        REGC_XMM_LAST },
16847         [REGC_GPR32_8]    = { REGC_GPR32_8_FIRST,    REGC_GPR32_8_LAST },
16848         [REGC_GPR16_8]    = { REGC_GPR16_8_FIRST,    REGC_GPR16_8_LAST },
16849         [REGC_GPR8_LO]    = { REGC_GPR8_LO_FIRST,    REGC_GPR8_LO_LAST },
16850         [REGC_IMM32]      = { REGC_IMM32_FIRST,      REGC_IMM32_LAST },
16851         [REGC_IMM16]      = { REGC_IMM16_FIRST,      REGC_IMM16_LAST },
16852         [REGC_IMM8]       = { REGC_IMM8_FIRST,       REGC_IMM8_LAST },
16853 };
16854
16855 static void init_arch_state(struct arch_state *arch)
16856 {
16857         memset(arch, 0, sizeof(*arch));
16858         arch->features = 0;
16859 }
16860
16861 static int arch_encode_flag(struct arch_state *arch, const char *flag)
16862 {
16863         static const struct compiler_flag flags[] = {
16864                 { "mmx", X86_MMX_REGS },
16865                 { "sse", X86_XMM_REGS },
16866                 { 0,     0 },
16867         };
16868         static const struct compiler_flag cpus[] = {
16869                 { "i386", 0 },
16870                 { "p2",   X86_MMX_REGS },
16871                 { "p3",   X86_MMX_REGS | X86_XMM_REGS },
16872                 { "p4",   X86_MMX_REGS | X86_XMM_REGS },
16873                 { "k7",   X86_MMX_REGS },
16874                 { "k8",   X86_MMX_REGS | X86_XMM_REGS },
16875                 { "c3",   X86_MMX_REGS },
16876                 { "c3-2", X86_MMX_REGS | X86_XMM_REGS }, /* Nehemiah */
16877                 {  0,     0 }
16878         };
16879         int result;
16880         int act;
16881
16882         act = 1;
16883         result = -1;
16884         if (strncmp(flag, "no-", 3) == 0) {
16885                 flag += 3;
16886                 act = 0;
16887         }
16888         if (act && strncmp(flag, "cpu=", 4) == 0) {
16889                 flag += 4;
16890                 result = set_flag(cpus, &arch->features, 1, flag);
16891         }
16892         else {
16893                 result = set_flag(flags, &arch->features, act, flag);
16894         }
16895         return result;
16896 }
16897
16898 static unsigned arch_regc_size(struct compile_state *state, int class)
16899 {
16900         if ((class < 0) || (class > LAST_REGC)) {
16901                 return 0;
16902         }
16903         return regc_size[class];
16904 }
16905
16906 static int arch_regcm_intersect(unsigned regcm1, unsigned regcm2)
16907 {
16908         /* See if two register classes may have overlapping registers */
16909         unsigned gpr_mask = REGCM_GPR8 | REGCM_GPR8_LO | REGCM_GPR16_8 | REGCM_GPR16 |
16910                 REGCM_GPR32_8 | REGCM_GPR32 | 
16911                 REGCM_DIVIDEND32 | REGCM_DIVIDEND64;
16912
16913         /* Special case for the immediates */
16914         if ((regcm1 & (REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8)) &&
16915                 ((regcm1 & ~(REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8)) == 0) &&
16916                 (regcm2 & (REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8)) &&
16917                 ((regcm2 & ~(REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8)) == 0)) { 
16918                 return 0;
16919         }
16920         return (regcm1 & regcm2) ||
16921                 ((regcm1 & gpr_mask) && (regcm2 & gpr_mask));
16922 }
16923
16924 static void arch_reg_equivs(
16925         struct compile_state *state, unsigned *equiv, int reg)
16926 {
16927         if ((reg < 0) || (reg > LAST_REG)) {
16928                 internal_error(state, 0, "invalid register");
16929         }
16930         *equiv++ = reg;
16931         switch(reg) {
16932         case REG_AL:
16933 #if X86_4_8BIT_GPRS
16934                 *equiv++ = REG_AH;
16935 #endif
16936                 *equiv++ = REG_AX;
16937                 *equiv++ = REG_EAX;
16938                 *equiv++ = REG_DXAX;
16939                 *equiv++ = REG_EDXEAX;
16940                 break;
16941         case REG_AH:
16942 #if X86_4_8BIT_GPRS
16943                 *equiv++ = REG_AL;
16944 #endif
16945                 *equiv++ = REG_AX;
16946                 *equiv++ = REG_EAX;
16947                 *equiv++ = REG_DXAX;
16948                 *equiv++ = REG_EDXEAX;
16949                 break;
16950         case REG_BL:  
16951 #if X86_4_8BIT_GPRS
16952                 *equiv++ = REG_BH;
16953 #endif
16954                 *equiv++ = REG_BX;
16955                 *equiv++ = REG_EBX;
16956                 break;
16957
16958         case REG_BH:
16959 #if X86_4_8BIT_GPRS
16960                 *equiv++ = REG_BL;
16961 #endif
16962                 *equiv++ = REG_BX;
16963                 *equiv++ = REG_EBX;
16964                 break;
16965         case REG_CL:
16966 #if X86_4_8BIT_GPRS
16967                 *equiv++ = REG_CH;
16968 #endif
16969                 *equiv++ = REG_CX;
16970                 *equiv++ = REG_ECX;
16971                 break;
16972
16973         case REG_CH:
16974 #if X86_4_8BIT_GPRS
16975                 *equiv++ = REG_CL;
16976 #endif
16977                 *equiv++ = REG_CX;
16978                 *equiv++ = REG_ECX;
16979                 break;
16980         case REG_DL:
16981 #if X86_4_8BIT_GPRS
16982                 *equiv++ = REG_DH;
16983 #endif
16984                 *equiv++ = REG_DX;
16985                 *equiv++ = REG_EDX;
16986                 *equiv++ = REG_DXAX;
16987                 *equiv++ = REG_EDXEAX;
16988                 break;
16989         case REG_DH:
16990 #if X86_4_8BIT_GPRS
16991                 *equiv++ = REG_DL;
16992 #endif
16993                 *equiv++ = REG_DX;
16994                 *equiv++ = REG_EDX;
16995                 *equiv++ = REG_DXAX;
16996                 *equiv++ = REG_EDXEAX;
16997                 break;
16998         case REG_AX:
16999                 *equiv++ = REG_AL;
17000                 *equiv++ = REG_AH;
17001                 *equiv++ = REG_EAX;
17002                 *equiv++ = REG_DXAX;
17003                 *equiv++ = REG_EDXEAX;
17004                 break;
17005         case REG_BX:
17006                 *equiv++ = REG_BL;
17007                 *equiv++ = REG_BH;
17008                 *equiv++ = REG_EBX;
17009                 break;
17010         case REG_CX:  
17011                 *equiv++ = REG_CL;
17012                 *equiv++ = REG_CH;
17013                 *equiv++ = REG_ECX;
17014                 break;
17015         case REG_DX:  
17016                 *equiv++ = REG_DL;
17017                 *equiv++ = REG_DH;
17018                 *equiv++ = REG_EDX;
17019                 *equiv++ = REG_DXAX;
17020                 *equiv++ = REG_EDXEAX;
17021                 break;
17022         case REG_SI:  
17023                 *equiv++ = REG_ESI;
17024                 break;
17025         case REG_DI:
17026                 *equiv++ = REG_EDI;
17027                 break;
17028         case REG_BP:
17029                 *equiv++ = REG_EBP;
17030                 break;
17031         case REG_SP:
17032                 *equiv++ = REG_ESP;
17033                 break;
17034         case REG_EAX:
17035                 *equiv++ = REG_AL;
17036                 *equiv++ = REG_AH;
17037                 *equiv++ = REG_AX;
17038                 *equiv++ = REG_DXAX;
17039                 *equiv++ = REG_EDXEAX;
17040                 break;
17041         case REG_EBX:
17042                 *equiv++ = REG_BL;
17043                 *equiv++ = REG_BH;
17044                 *equiv++ = REG_BX;
17045                 break;
17046         case REG_ECX:
17047                 *equiv++ = REG_CL;
17048                 *equiv++ = REG_CH;
17049                 *equiv++ = REG_CX;
17050                 break;
17051         case REG_EDX:
17052                 *equiv++ = REG_DL;
17053                 *equiv++ = REG_DH;
17054                 *equiv++ = REG_DX;
17055                 *equiv++ = REG_DXAX;
17056                 *equiv++ = REG_EDXEAX;
17057                 break;
17058         case REG_ESI: 
17059                 *equiv++ = REG_SI;
17060                 break;
17061         case REG_EDI: 
17062                 *equiv++ = REG_DI;
17063                 break;
17064         case REG_EBP: 
17065                 *equiv++ = REG_BP;
17066                 break;
17067         case REG_ESP: 
17068                 *equiv++ = REG_SP;
17069                 break;
17070         case REG_DXAX: 
17071                 *equiv++ = REG_AL;
17072                 *equiv++ = REG_AH;
17073                 *equiv++ = REG_DL;
17074                 *equiv++ = REG_DH;
17075                 *equiv++ = REG_AX;
17076                 *equiv++ = REG_DX;
17077                 *equiv++ = REG_EAX;
17078                 *equiv++ = REG_EDX;
17079                 *equiv++ = REG_EDXEAX;
17080                 break;
17081         case REG_EDXEAX: 
17082                 *equiv++ = REG_AL;
17083                 *equiv++ = REG_AH;
17084                 *equiv++ = REG_DL;
17085                 *equiv++ = REG_DH;
17086                 *equiv++ = REG_AX;
17087                 *equiv++ = REG_DX;
17088                 *equiv++ = REG_EAX;
17089                 *equiv++ = REG_EDX;
17090                 *equiv++ = REG_DXAX;
17091                 break;
17092         }
17093         *equiv++ = REG_UNSET; 
17094 }
17095
17096 static unsigned arch_avail_mask(struct compile_state *state)
17097 {
17098         unsigned avail_mask;
17099         /* REGCM_GPR8 is not available */
17100         avail_mask = REGCM_GPR8_LO | REGCM_GPR16_8 | REGCM_GPR16 | 
17101                 REGCM_GPR32 | REGCM_GPR32_8 | 
17102                 REGCM_DIVIDEND32 | REGCM_DIVIDEND64 |
17103                 REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8 | REGCM_FLAGS;
17104         if (state->arch->features & X86_MMX_REGS) {
17105                 avail_mask |= REGCM_MMX;
17106         }
17107         if (state->arch->features & X86_XMM_REGS) {
17108                 avail_mask |= REGCM_XMM;
17109         }
17110         return avail_mask;
17111 }
17112
17113 static unsigned arch_regcm_normalize(struct compile_state *state, unsigned regcm)
17114 {
17115         unsigned mask, result;
17116         int class, class2;
17117         result = regcm;
17118
17119         for(class = 0, mask = 1; mask; mask <<= 1, class++) {
17120                 if ((result & mask) == 0) {
17121                         continue;
17122                 }
17123                 if (class > LAST_REGC) {
17124                         result &= ~mask;
17125                 }
17126                 for(class2 = 0; class2 <= LAST_REGC; class2++) {
17127                         if ((regcm_bound[class2].first >= regcm_bound[class].first) &&
17128                                 (regcm_bound[class2].last <= regcm_bound[class].last)) {
17129                                 result |= (1 << class2);
17130                         }
17131                 }
17132         }
17133         result &= arch_avail_mask(state);
17134         return result;
17135 }
17136
17137 static unsigned arch_regcm_reg_normalize(struct compile_state *state, unsigned regcm)
17138 {
17139         /* Like arch_regcm_normalize except immediate register classes are excluded */
17140         regcm = arch_regcm_normalize(state, regcm);
17141         /* Remove the immediate register classes */
17142         regcm &= ~(REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8);
17143         return regcm;
17144         
17145 }
17146
17147 static unsigned arch_reg_regcm(struct compile_state *state, int reg)
17148 {
17149         unsigned mask;
17150         int class;
17151         mask = 0;
17152         for(class = 0; class <= LAST_REGC; class++) {
17153                 if ((reg >= regcm_bound[class].first) &&
17154                         (reg <= regcm_bound[class].last)) {
17155                         mask |= (1 << class);
17156                 }
17157         }
17158         if (!mask) {
17159                 internal_error(state, 0, "reg %d not in any class", reg);
17160         }
17161         return mask;
17162 }
17163
17164 static struct reg_info arch_reg_constraint(
17165         struct compile_state *state, struct type *type, const char *constraint)
17166 {
17167         static const struct {
17168                 char class;
17169                 unsigned int mask;
17170                 unsigned int reg;
17171         } constraints[] = {
17172                 { 'r', REGCM_GPR32,   REG_UNSET },
17173                 { 'g', REGCM_GPR32,   REG_UNSET },
17174                 { 'p', REGCM_GPR32,   REG_UNSET },
17175                 { 'q', REGCM_GPR8_LO, REG_UNSET },
17176                 { 'Q', REGCM_GPR32_8, REG_UNSET },
17177                 { 'x', REGCM_XMM,     REG_UNSET },
17178                 { 'y', REGCM_MMX,     REG_UNSET },
17179                 { 'a', REGCM_GPR32,   REG_EAX },
17180                 { 'b', REGCM_GPR32,   REG_EBX },
17181                 { 'c', REGCM_GPR32,   REG_ECX },
17182                 { 'd', REGCM_GPR32,   REG_EDX },
17183                 { 'D', REGCM_GPR32,   REG_EDI },
17184                 { 'S', REGCM_GPR32,   REG_ESI },
17185                 { '\0', 0, REG_UNSET },
17186         };
17187         unsigned int regcm;
17188         unsigned int mask, reg;
17189         struct reg_info result;
17190         const char *ptr;
17191         regcm = arch_type_to_regcm(state, type);
17192         reg = REG_UNSET;
17193         mask = 0;
17194         for(ptr = constraint; *ptr; ptr++) {
17195                 int i;
17196                 if (*ptr ==  ' ') {
17197                         continue;
17198                 }
17199                 for(i = 0; constraints[i].class != '\0'; i++) {
17200                         if (constraints[i].class == *ptr) {
17201                                 break;
17202                         }
17203                 }
17204                 if (constraints[i].class == '\0') {
17205                         error(state, 0, "invalid register constraint ``%c''", *ptr);
17206                         break;
17207                 }
17208                 if ((constraints[i].mask & regcm) == 0) {
17209                         error(state, 0, "invalid register class %c specified",
17210                                 *ptr);
17211                 }
17212                 mask |= constraints[i].mask;
17213                 if (constraints[i].reg != REG_UNSET) {
17214                         if ((reg != REG_UNSET) && (reg != constraints[i].reg)) {
17215                                 error(state, 0, "Only one register may be specified");
17216                         }
17217                         reg = constraints[i].reg;
17218                 }
17219         }
17220         result.reg = reg;
17221         result.regcm = mask;
17222         return result;
17223 }
17224
17225 static struct reg_info arch_reg_clobber(
17226         struct compile_state *state, const char *clobber)
17227 {
17228         struct reg_info result;
17229         if (strcmp(clobber, "memory") == 0) {
17230                 result.reg = REG_UNSET;
17231                 result.regcm = 0;
17232         }
17233         else if (strcmp(clobber, "%eax") == 0) {
17234                 result.reg = REG_EAX;
17235                 result.regcm = REGCM_GPR32;
17236         }
17237         else if (strcmp(clobber, "%ebx") == 0) {
17238                 result.reg = REG_EBX;
17239                 result.regcm = REGCM_GPR32;
17240         }
17241         else if (strcmp(clobber, "%ecx") == 0) {
17242                 result.reg = REG_ECX;
17243                 result.regcm = REGCM_GPR32;
17244         }
17245         else if (strcmp(clobber, "%edx") == 0) {
17246                 result.reg = REG_EDX;
17247                 result.regcm = REGCM_GPR32;
17248         }
17249         else if (strcmp(clobber, "%esi") == 0) {
17250                 result.reg = REG_ESI;
17251                 result.regcm = REGCM_GPR32;
17252         }
17253         else if (strcmp(clobber, "%edi") == 0) {
17254                 result.reg = REG_EDI;
17255                 result.regcm = REGCM_GPR32;
17256         }
17257         else if (strcmp(clobber, "%ebp") == 0) {
17258                 result.reg = REG_EBP;
17259                 result.regcm = REGCM_GPR32;
17260         }
17261         else if (strcmp(clobber, "%esp") == 0) {
17262                 result.reg = REG_ESP;
17263                 result.regcm = REGCM_GPR32;
17264         }
17265         else if (strcmp(clobber, "cc") == 0) {
17266                 result.reg = REG_EFLAGS;
17267                 result.regcm = REGCM_FLAGS;
17268         }
17269         else if ((strncmp(clobber, "xmm", 3) == 0)  &&
17270                 octdigitp(clobber[3]) && (clobber[4] == '\0')) {
17271                 result.reg = REG_XMM0 + octdigval(clobber[3]);
17272                 result.regcm = REGCM_XMM;
17273         }
17274         else if ((strncmp(clobber, "mmx", 3) == 0) &&
17275                 octdigitp(clobber[3]) && (clobber[4] == '\0')) {
17276                 result.reg = REG_MMX0 + octdigval(clobber[3]);
17277                 result.regcm = REGCM_MMX;
17278         }
17279         else {
17280                 error(state, 0, "Invalid register clobber");
17281                 result.reg = REG_UNSET;
17282                 result.regcm = 0;
17283         }
17284         return result;
17285 }
17286
17287 static int do_select_reg(struct compile_state *state, 
17288         char *used, int reg, unsigned classes)
17289 {
17290         unsigned mask;
17291         if (used[reg]) {
17292                 return REG_UNSET;
17293         }
17294         mask = arch_reg_regcm(state, reg);
17295         return (classes & mask) ? reg : REG_UNSET;
17296 }
17297
17298 static int arch_select_free_register(
17299         struct compile_state *state, char *used, int classes)
17300 {
17301         /* Live ranges with the most neighbors are colored first.
17302          *
17303          * Generally it does not matter which colors are given
17304          * as the register allocator attempts to color live ranges
17305          * in an order where you are guaranteed not to run out of colors.
17306          *
17307          * Occasionally the register allocator cannot find an order
17308          * of register selection that will find a free color.  To
17309          * increase the odds the register allocator will work when
17310          * it guesses first give out registers from register classes
17311          * least likely to run out of registers.
17312          * 
17313          */
17314         int i, reg;
17315         reg = REG_UNSET;
17316         for(i = REGC_XMM_FIRST; (reg == REG_UNSET) && (i <= REGC_XMM_LAST); i++) {
17317                 reg = do_select_reg(state, used, i, classes);
17318         }
17319         for(i = REGC_MMX_FIRST; (reg == REG_UNSET) && (i <= REGC_MMX_LAST); i++) {
17320                 reg = do_select_reg(state, used, i, classes);
17321         }
17322         for(i = REGC_GPR32_LAST; (reg == REG_UNSET) && (i >= REGC_GPR32_FIRST); i--) {
17323                 reg = do_select_reg(state, used, i, classes);
17324         }
17325         for(i = REGC_GPR16_FIRST; (reg == REG_UNSET) && (i <= REGC_GPR16_LAST); i++) {
17326                 reg = do_select_reg(state, used, i, classes);
17327         }
17328         for(i = REGC_GPR8_FIRST; (reg == REG_UNSET) && (i <= REGC_GPR8_LAST); i++) {
17329                 reg = do_select_reg(state, used, i, classes);
17330         }
17331         for(i = REGC_GPR8_LO_FIRST; (reg == REG_UNSET) && (i <= REGC_GPR8_LO_LAST); i++) {
17332                 reg = do_select_reg(state, used, i, classes);
17333         }
17334         for(i = REGC_DIVIDEND32_FIRST; (reg == REG_UNSET) && (i <= REGC_DIVIDEND32_LAST); i++) {
17335                 reg = do_select_reg(state, used, i, classes);
17336         }
17337         for(i = REGC_DIVIDEND64_FIRST; (reg == REG_UNSET) && (i <= REGC_DIVIDEND64_LAST); i++) {
17338                 reg = do_select_reg(state, used, i, classes);
17339         }
17340         for(i = REGC_FLAGS_FIRST; (reg == REG_UNSET) && (i <= REGC_FLAGS_LAST); i++) {
17341                 reg = do_select_reg(state, used, i, classes);
17342         }
17343         return reg;
17344 }
17345
17346
17347 static unsigned arch_type_to_regcm(struct compile_state *state, struct type *type) 
17348 {
17349 #warning "FIXME force types smaller (if legal) before I get here"
17350         unsigned mask;
17351         mask = 0;
17352         switch(type->type & TYPE_MASK) {
17353         case TYPE_ARRAY:
17354         case TYPE_VOID: 
17355                 mask = 0; 
17356                 break;
17357         case TYPE_CHAR:
17358         case TYPE_UCHAR:
17359                 mask = REGCM_GPR8 | REGCM_GPR8_LO |
17360                         REGCM_GPR16 | REGCM_GPR16_8 | 
17361                         REGCM_GPR32 | REGCM_GPR32_8 |
17362                         REGCM_DIVIDEND32 | REGCM_DIVIDEND64 |
17363                         REGCM_MMX | REGCM_XMM |
17364                         REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8;
17365                 break;
17366         case TYPE_SHORT:
17367         case TYPE_USHORT:
17368                 mask =  REGCM_GPR16 | REGCM_GPR16_8 |
17369                         REGCM_GPR32 | REGCM_GPR32_8 |
17370                         REGCM_DIVIDEND32 | REGCM_DIVIDEND64 |
17371                         REGCM_MMX | REGCM_XMM |
17372                         REGCM_IMM32 | REGCM_IMM16;
17373                 break;
17374         case TYPE_INT:
17375         case TYPE_UINT:
17376         case TYPE_LONG:
17377         case TYPE_ULONG:
17378         case TYPE_POINTER:
17379                 mask =  REGCM_GPR32 | REGCM_GPR32_8 |
17380                         REGCM_DIVIDEND32 | REGCM_DIVIDEND64 |
17381                         REGCM_MMX | REGCM_XMM |
17382                         REGCM_IMM32;
17383                 break;
17384         default:
17385                 internal_error(state, 0, "no register class for type");
17386                 break;
17387         }
17388         mask = arch_regcm_normalize(state, mask);
17389         return mask;
17390 }
17391
17392 static int is_imm32(struct triple *imm)
17393 {
17394         return ((imm->op == OP_INTCONST) && (imm->u.cval <= 0xffffffffUL)) ||
17395                 (imm->op == OP_ADDRCONST);
17396         
17397 }
17398 static int is_imm16(struct triple *imm)
17399 {
17400         return ((imm->op == OP_INTCONST) && (imm->u.cval <= 0xffff));
17401 }
17402 static int is_imm8(struct triple *imm)
17403 {
17404         return ((imm->op == OP_INTCONST) && (imm->u.cval <= 0xff));
17405 }
17406
17407 static int get_imm32(struct triple *ins, struct triple **expr)
17408 {
17409         struct triple *imm;
17410         imm = *expr;
17411         while(imm->op == OP_COPY) {
17412                 imm = RHS(imm, 0);
17413         }
17414         if (!is_imm32(imm)) {
17415                 return 0;
17416         }
17417         unuse_triple(*expr, ins);
17418         use_triple(imm, ins);
17419         *expr = imm;
17420         return 1;
17421 }
17422
17423 static int get_imm8(struct triple *ins, struct triple **expr)
17424 {
17425         struct triple *imm;
17426         imm = *expr;
17427         while(imm->op == OP_COPY) {
17428                 imm = RHS(imm, 0);
17429         }
17430         if (!is_imm8(imm)) {
17431                 return 0;
17432         }
17433         unuse_triple(*expr, ins);
17434         use_triple(imm, ins);
17435         *expr = imm;
17436         return 1;
17437 }
17438
17439 #define TEMPLATE_NOP           0
17440 #define TEMPLATE_INTCONST8     1
17441 #define TEMPLATE_INTCONST32    2
17442 #define TEMPLATE_COPY8_REG     3
17443 #define TEMPLATE_COPY16_REG    4
17444 #define TEMPLATE_COPY32_REG    5
17445 #define TEMPLATE_COPY_IMM8     6
17446 #define TEMPLATE_COPY_IMM16    7
17447 #define TEMPLATE_COPY_IMM32    8
17448 #define TEMPLATE_PHI8          9
17449 #define TEMPLATE_PHI16        10
17450 #define TEMPLATE_PHI32        11
17451 #define TEMPLATE_STORE8       12
17452 #define TEMPLATE_STORE16      13
17453 #define TEMPLATE_STORE32      14
17454 #define TEMPLATE_LOAD8        15
17455 #define TEMPLATE_LOAD16       16
17456 #define TEMPLATE_LOAD32       17
17457 #define TEMPLATE_BINARY8_REG  18
17458 #define TEMPLATE_BINARY16_REG 19
17459 #define TEMPLATE_BINARY32_REG 20
17460 #define TEMPLATE_BINARY8_IMM  21
17461 #define TEMPLATE_BINARY16_IMM 22
17462 #define TEMPLATE_BINARY32_IMM 23
17463 #define TEMPLATE_SL8_CL       24
17464 #define TEMPLATE_SL16_CL      25
17465 #define TEMPLATE_SL32_CL      26
17466 #define TEMPLATE_SL8_IMM      27
17467 #define TEMPLATE_SL16_IMM     28
17468 #define TEMPLATE_SL32_IMM     29
17469 #define TEMPLATE_UNARY8       30
17470 #define TEMPLATE_UNARY16      31
17471 #define TEMPLATE_UNARY32      32
17472 #define TEMPLATE_CMP8_REG     33
17473 #define TEMPLATE_CMP16_REG    34
17474 #define TEMPLATE_CMP32_REG    35
17475 #define TEMPLATE_CMP8_IMM     36
17476 #define TEMPLATE_CMP16_IMM    37
17477 #define TEMPLATE_CMP32_IMM    38
17478 #define TEMPLATE_TEST8        39
17479 #define TEMPLATE_TEST16       40
17480 #define TEMPLATE_TEST32       41
17481 #define TEMPLATE_SET          42
17482 #define TEMPLATE_JMP          43
17483 #define TEMPLATE_RET          44
17484 #define TEMPLATE_INB_DX       45
17485 #define TEMPLATE_INB_IMM      46
17486 #define TEMPLATE_INW_DX       47
17487 #define TEMPLATE_INW_IMM      48
17488 #define TEMPLATE_INL_DX       49
17489 #define TEMPLATE_INL_IMM      50
17490 #define TEMPLATE_OUTB_DX      51
17491 #define TEMPLATE_OUTB_IMM     52
17492 #define TEMPLATE_OUTW_DX      53
17493 #define TEMPLATE_OUTW_IMM     54
17494 #define TEMPLATE_OUTL_DX      55
17495 #define TEMPLATE_OUTL_IMM     56
17496 #define TEMPLATE_BSF          57
17497 #define TEMPLATE_RDMSR        58
17498 #define TEMPLATE_WRMSR        59
17499 #define TEMPLATE_UMUL8        60
17500 #define TEMPLATE_UMUL16       61
17501 #define TEMPLATE_UMUL32       62
17502 #define TEMPLATE_DIV8         63
17503 #define TEMPLATE_DIV16        64
17504 #define TEMPLATE_DIV32        65
17505 #define LAST_TEMPLATE       TEMPLATE_DIV32
17506 #if LAST_TEMPLATE >= MAX_TEMPLATES
17507 #error "MAX_TEMPLATES to low"
17508 #endif
17509
17510 #define COPY8_REGCM     (REGCM_DIVIDEND64 | REGCM_DIVIDEND32 | REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO | REGCM_MMX | REGCM_XMM)
17511 #define COPY16_REGCM    (REGCM_DIVIDEND64 | REGCM_DIVIDEND32 | REGCM_GPR32 | REGCM_GPR16 | REGCM_MMX | REGCM_XMM)  
17512 #define COPY32_REGCM    (REGCM_DIVIDEND64 | REGCM_DIVIDEND32 | REGCM_GPR32 | REGCM_MMX | REGCM_XMM)
17513
17514
17515 static struct ins_template templates[] = {
17516         [TEMPLATE_NOP]      = {},
17517         [TEMPLATE_INTCONST8] = { 
17518                 .lhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
17519         },
17520         [TEMPLATE_INTCONST32] = { 
17521                 .lhs = { [0] = { REG_UNNEEDED, REGCM_IMM32 } },
17522         },
17523         [TEMPLATE_COPY8_REG] = {
17524                 .lhs = { [0] = { REG_UNSET, COPY8_REGCM } },
17525                 .rhs = { [0] = { REG_UNSET, COPY8_REGCM }  },
17526         },
17527         [TEMPLATE_COPY16_REG] = {
17528                 .lhs = { [0] = { REG_UNSET, COPY16_REGCM } },
17529                 .rhs = { [0] = { REG_UNSET, COPY16_REGCM }  },
17530         },
17531         [TEMPLATE_COPY32_REG] = {
17532                 .lhs = { [0] = { REG_UNSET, COPY32_REGCM } },
17533                 .rhs = { [0] = { REG_UNSET, COPY32_REGCM }  },
17534         },
17535         [TEMPLATE_COPY_IMM8] = {
17536                 .lhs = { [0] = { REG_UNSET, COPY8_REGCM } },
17537                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
17538         },
17539         [TEMPLATE_COPY_IMM16] = {
17540                 .lhs = { [0] = { REG_UNSET, COPY16_REGCM } },
17541                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM16 | REGCM_IMM8 } },
17542         },
17543         [TEMPLATE_COPY_IMM32] = {
17544                 .lhs = { [0] = { REG_UNSET, COPY32_REGCM } },
17545                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8 } },
17546         },
17547         [TEMPLATE_PHI8] = { 
17548                 .lhs = { [0] = { REG_VIRT0, COPY8_REGCM } },
17549                 .rhs = { 
17550                         [ 0] = { REG_VIRT0, COPY8_REGCM },
17551                         [ 1] = { REG_VIRT0, COPY8_REGCM },
17552                         [ 2] = { REG_VIRT0, COPY8_REGCM },
17553                         [ 3] = { REG_VIRT0, COPY8_REGCM },
17554                         [ 4] = { REG_VIRT0, COPY8_REGCM },
17555                         [ 5] = { REG_VIRT0, COPY8_REGCM },
17556                         [ 6] = { REG_VIRT0, COPY8_REGCM },
17557                         [ 7] = { REG_VIRT0, COPY8_REGCM },
17558                         [ 8] = { REG_VIRT0, COPY8_REGCM },
17559                         [ 9] = { REG_VIRT0, COPY8_REGCM },
17560                         [10] = { REG_VIRT0, COPY8_REGCM },
17561                         [11] = { REG_VIRT0, COPY8_REGCM },
17562                         [12] = { REG_VIRT0, COPY8_REGCM },
17563                         [13] = { REG_VIRT0, COPY8_REGCM },
17564                         [14] = { REG_VIRT0, COPY8_REGCM },
17565                         [15] = { REG_VIRT0, COPY8_REGCM },
17566                 }, },
17567         [TEMPLATE_PHI16] = { 
17568                 .lhs = { [0] = { REG_VIRT0, COPY16_REGCM } },
17569                 .rhs = { 
17570                         [ 0] = { REG_VIRT0, COPY16_REGCM },
17571                         [ 1] = { REG_VIRT0, COPY16_REGCM },
17572                         [ 2] = { REG_VIRT0, COPY16_REGCM },
17573                         [ 3] = { REG_VIRT0, COPY16_REGCM },
17574                         [ 4] = { REG_VIRT0, COPY16_REGCM },
17575                         [ 5] = { REG_VIRT0, COPY16_REGCM },
17576                         [ 6] = { REG_VIRT0, COPY16_REGCM },
17577                         [ 7] = { REG_VIRT0, COPY16_REGCM },
17578                         [ 8] = { REG_VIRT0, COPY16_REGCM },
17579                         [ 9] = { REG_VIRT0, COPY16_REGCM },
17580                         [10] = { REG_VIRT0, COPY16_REGCM },
17581                         [11] = { REG_VIRT0, COPY16_REGCM },
17582                         [12] = { REG_VIRT0, COPY16_REGCM },
17583                         [13] = { REG_VIRT0, COPY16_REGCM },
17584                         [14] = { REG_VIRT0, COPY16_REGCM },
17585                         [15] = { REG_VIRT0, COPY16_REGCM },
17586                 }, },
17587         [TEMPLATE_PHI32] = { 
17588                 .lhs = { [0] = { REG_VIRT0, COPY32_REGCM } },
17589                 .rhs = { 
17590                         [ 0] = { REG_VIRT0, COPY32_REGCM },
17591                         [ 1] = { REG_VIRT0, COPY32_REGCM },
17592                         [ 2] = { REG_VIRT0, COPY32_REGCM },
17593                         [ 3] = { REG_VIRT0, COPY32_REGCM },
17594                         [ 4] = { REG_VIRT0, COPY32_REGCM },
17595                         [ 5] = { REG_VIRT0, COPY32_REGCM },
17596                         [ 6] = { REG_VIRT0, COPY32_REGCM },
17597                         [ 7] = { REG_VIRT0, COPY32_REGCM },
17598                         [ 8] = { REG_VIRT0, COPY32_REGCM },
17599                         [ 9] = { REG_VIRT0, COPY32_REGCM },
17600                         [10] = { REG_VIRT0, COPY32_REGCM },
17601                         [11] = { REG_VIRT0, COPY32_REGCM },
17602                         [12] = { REG_VIRT0, COPY32_REGCM },
17603                         [13] = { REG_VIRT0, COPY32_REGCM },
17604                         [14] = { REG_VIRT0, COPY32_REGCM },
17605                         [15] = { REG_VIRT0, COPY32_REGCM },
17606                 }, },
17607         [TEMPLATE_STORE8] = {
17608                 .rhs = { 
17609                         [0] = { REG_UNSET, REGCM_GPR32 },
17610                         [1] = { REG_UNSET, REGCM_GPR8_LO },
17611                 },
17612         },
17613         [TEMPLATE_STORE16] = {
17614                 .rhs = { 
17615                         [0] = { REG_UNSET, REGCM_GPR32 },
17616                         [1] = { REG_UNSET, REGCM_GPR16 },
17617                 },
17618         },
17619         [TEMPLATE_STORE32] = {
17620                 .rhs = { 
17621                         [0] = { REG_UNSET, REGCM_GPR32 },
17622                         [1] = { REG_UNSET, REGCM_GPR32 },
17623                 },
17624         },
17625         [TEMPLATE_LOAD8] = {
17626                 .lhs = { [0] = { REG_UNSET, REGCM_GPR8_LO } },
17627                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
17628         },
17629         [TEMPLATE_LOAD16] = {
17630                 .lhs = { [0] = { REG_UNSET, REGCM_GPR16 } },
17631                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
17632         },
17633         [TEMPLATE_LOAD32] = {
17634                 .lhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
17635                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
17636         },
17637         [TEMPLATE_BINARY8_REG] = {
17638                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
17639                 .rhs = { 
17640                         [0] = { REG_VIRT0, REGCM_GPR8_LO },
17641                         [1] = { REG_UNSET, REGCM_GPR8_LO },
17642                 },
17643         },
17644         [TEMPLATE_BINARY16_REG] = {
17645                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
17646                 .rhs = { 
17647                         [0] = { REG_VIRT0, REGCM_GPR16 },
17648                         [1] = { REG_UNSET, REGCM_GPR16 },
17649                 },
17650         },
17651         [TEMPLATE_BINARY32_REG] = {
17652                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
17653                 .rhs = { 
17654                         [0] = { REG_VIRT0, REGCM_GPR32 },
17655                         [1] = { REG_UNSET, REGCM_GPR32 },
17656                 },
17657         },
17658         [TEMPLATE_BINARY8_IMM] = {
17659                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
17660                 .rhs = { 
17661                         [0] = { REG_VIRT0,    REGCM_GPR8_LO },
17662                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
17663                 },
17664         },
17665         [TEMPLATE_BINARY16_IMM] = {
17666                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
17667                 .rhs = { 
17668                         [0] = { REG_VIRT0,    REGCM_GPR16 },
17669                         [1] = { REG_UNNEEDED, REGCM_IMM16 },
17670                 },
17671         },
17672         [TEMPLATE_BINARY32_IMM] = {
17673                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
17674                 .rhs = { 
17675                         [0] = { REG_VIRT0,    REGCM_GPR32 },
17676                         [1] = { REG_UNNEEDED, REGCM_IMM32 },
17677                 },
17678         },
17679         [TEMPLATE_SL8_CL] = {
17680                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
17681                 .rhs = { 
17682                         [0] = { REG_VIRT0, REGCM_GPR8_LO },
17683                         [1] = { REG_CL, REGCM_GPR8_LO },
17684                 },
17685         },
17686         [TEMPLATE_SL16_CL] = {
17687                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
17688                 .rhs = { 
17689                         [0] = { REG_VIRT0, REGCM_GPR16 },
17690                         [1] = { REG_CL, REGCM_GPR8_LO },
17691                 },
17692         },
17693         [TEMPLATE_SL32_CL] = {
17694                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
17695                 .rhs = { 
17696                         [0] = { REG_VIRT0, REGCM_GPR32 },
17697                         [1] = { REG_CL, REGCM_GPR8_LO },
17698                 },
17699         },
17700         [TEMPLATE_SL8_IMM] = {
17701                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
17702                 .rhs = { 
17703                         [0] = { REG_VIRT0,    REGCM_GPR8_LO },
17704                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
17705                 },
17706         },
17707         [TEMPLATE_SL16_IMM] = {
17708                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
17709                 .rhs = { 
17710                         [0] = { REG_VIRT0,    REGCM_GPR16 },
17711                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
17712                 },
17713         },
17714         [TEMPLATE_SL32_IMM] = {
17715                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
17716                 .rhs = { 
17717                         [0] = { REG_VIRT0,    REGCM_GPR32 },
17718                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
17719                 },
17720         },
17721         [TEMPLATE_UNARY8] = {
17722                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
17723                 .rhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
17724         },
17725         [TEMPLATE_UNARY16] = {
17726                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
17727                 .rhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
17728         },
17729         [TEMPLATE_UNARY32] = {
17730                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
17731                 .rhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
17732         },
17733         [TEMPLATE_CMP8_REG] = {
17734                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
17735                 .rhs = {
17736                         [0] = { REG_UNSET, REGCM_GPR8_LO },
17737                         [1] = { REG_UNSET, REGCM_GPR8_LO },
17738                 },
17739         },
17740         [TEMPLATE_CMP16_REG] = {
17741                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
17742                 .rhs = {
17743                         [0] = { REG_UNSET, REGCM_GPR16 },
17744                         [1] = { REG_UNSET, REGCM_GPR16 },
17745                 },
17746         },
17747         [TEMPLATE_CMP32_REG] = {
17748                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
17749                 .rhs = {
17750                         [0] = { REG_UNSET, REGCM_GPR32 },
17751                         [1] = { REG_UNSET, REGCM_GPR32 },
17752                 },
17753         },
17754         [TEMPLATE_CMP8_IMM] = {
17755                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
17756                 .rhs = {
17757                         [0] = { REG_UNSET, REGCM_GPR8_LO },
17758                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
17759                 },
17760         },
17761         [TEMPLATE_CMP16_IMM] = {
17762                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
17763                 .rhs = {
17764                         [0] = { REG_UNSET, REGCM_GPR16 },
17765                         [1] = { REG_UNNEEDED, REGCM_IMM16 },
17766                 },
17767         },
17768         [TEMPLATE_CMP32_IMM] = {
17769                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
17770                 .rhs = {
17771                         [0] = { REG_UNSET, REGCM_GPR32 },
17772                         [1] = { REG_UNNEEDED, REGCM_IMM32 },
17773                 },
17774         },
17775         [TEMPLATE_TEST8] = {
17776                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
17777                 .rhs = { [0] = { REG_UNSET, REGCM_GPR8_LO } },
17778         },
17779         [TEMPLATE_TEST16] = {
17780                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
17781                 .rhs = { [0] = { REG_UNSET, REGCM_GPR16 } },
17782         },
17783         [TEMPLATE_TEST32] = {
17784                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
17785                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
17786         },
17787         [TEMPLATE_SET] = {
17788                 .lhs = { [0] = { REG_UNSET, REGCM_GPR8_LO } },
17789                 .rhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
17790         },
17791         [TEMPLATE_JMP] = {
17792                 .rhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
17793         },
17794         [TEMPLATE_RET] = {
17795                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
17796         },
17797         [TEMPLATE_INB_DX] = {
17798                 .lhs = { [0] = { REG_AL,  REGCM_GPR8_LO } },  
17799                 .rhs = { [0] = { REG_DX, REGCM_GPR16 } },
17800         },
17801         [TEMPLATE_INB_IMM] = {
17802                 .lhs = { [0] = { REG_AL,  REGCM_GPR8_LO } },  
17803                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
17804         },
17805         [TEMPLATE_INW_DX]  = { 
17806                 .lhs = { [0] = { REG_AX,  REGCM_GPR16 } }, 
17807                 .rhs = { [0] = { REG_DX, REGCM_GPR16 } },
17808         },
17809         [TEMPLATE_INW_IMM] = { 
17810                 .lhs = { [0] = { REG_AX,  REGCM_GPR16 } }, 
17811                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
17812         },
17813         [TEMPLATE_INL_DX]  = {
17814                 .lhs = { [0] = { REG_EAX, REGCM_GPR32 } },
17815                 .rhs = { [0] = { REG_DX, REGCM_GPR16 } },
17816         },
17817         [TEMPLATE_INL_IMM] = {
17818                 .lhs = { [0] = { REG_EAX, REGCM_GPR32 } },
17819                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
17820         },
17821         [TEMPLATE_OUTB_DX] = { 
17822                 .rhs = {
17823                         [0] = { REG_AL,  REGCM_GPR8_LO },
17824                         [1] = { REG_DX, REGCM_GPR16 },
17825                 },
17826         },
17827         [TEMPLATE_OUTB_IMM] = { 
17828                 .rhs = {
17829                         [0] = { REG_AL,  REGCM_GPR8_LO },  
17830                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
17831                 },
17832         },
17833         [TEMPLATE_OUTW_DX] = { 
17834                 .rhs = {
17835                         [0] = { REG_AX,  REGCM_GPR16 },
17836                         [1] = { REG_DX, REGCM_GPR16 },
17837                 },
17838         },
17839         [TEMPLATE_OUTW_IMM] = {
17840                 .rhs = {
17841                         [0] = { REG_AX,  REGCM_GPR16 }, 
17842                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
17843                 },
17844         },
17845         [TEMPLATE_OUTL_DX] = { 
17846                 .rhs = {
17847                         [0] = { REG_EAX, REGCM_GPR32 },
17848                         [1] = { REG_DX, REGCM_GPR16 },
17849                 },
17850         },
17851         [TEMPLATE_OUTL_IMM] = { 
17852                 .rhs = {
17853                         [0] = { REG_EAX, REGCM_GPR32 }, 
17854                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
17855                 },
17856         },
17857         [TEMPLATE_BSF] = {
17858                 .lhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
17859                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
17860         },
17861         [TEMPLATE_RDMSR] = {
17862                 .lhs = { 
17863                         [0] = { REG_EAX, REGCM_GPR32 },
17864                         [1] = { REG_EDX, REGCM_GPR32 },
17865                 },
17866                 .rhs = { [0] = { REG_ECX, REGCM_GPR32 } },
17867         },
17868         [TEMPLATE_WRMSR] = {
17869                 .rhs = {
17870                         [0] = { REG_ECX, REGCM_GPR32 },
17871                         [1] = { REG_EAX, REGCM_GPR32 },
17872                         [2] = { REG_EDX, REGCM_GPR32 },
17873                 },
17874         },
17875         [TEMPLATE_UMUL8] = {
17876                 .lhs = { [0] = { REG_AX, REGCM_GPR16 } },
17877                 .rhs = { 
17878                         [0] = { REG_AL, REGCM_GPR8_LO },
17879                         [1] = { REG_UNSET, REGCM_GPR8_LO },
17880                 },
17881         },
17882         [TEMPLATE_UMUL16] = {
17883                 .lhs = { [0] = { REG_DXAX, REGCM_DIVIDEND32 } },
17884                 .rhs = { 
17885                         [0] = { REG_AX, REGCM_GPR16 },
17886                         [1] = { REG_UNSET, REGCM_GPR16 },
17887                 },
17888         },
17889         [TEMPLATE_UMUL32] = {
17890                 .lhs = { [0] = { REG_EDXEAX, REGCM_DIVIDEND64 } },
17891                 .rhs = { 
17892                         [0] = { REG_EAX, REGCM_GPR32 },
17893                         [1] = { REG_UNSET, REGCM_GPR32 },
17894                 },
17895         },
17896         [TEMPLATE_DIV8] = {
17897                 .lhs = { 
17898                         [0] = { REG_AL, REGCM_GPR8_LO },
17899                         [1] = { REG_AH, REGCM_GPR8 },
17900                 },
17901                 .rhs = {
17902                         [0] = { REG_AX, REGCM_GPR16 },
17903                         [1] = { REG_UNSET, REGCM_GPR8_LO },
17904                 },
17905         },
17906         [TEMPLATE_DIV16] = {
17907                 .lhs = { 
17908                         [0] = { REG_AX, REGCM_GPR16 },
17909                         [1] = { REG_DX, REGCM_GPR16 },
17910                 },
17911                 .rhs = {
17912                         [0] = { REG_DXAX, REGCM_DIVIDEND32 },
17913                         [1] = { REG_UNSET, REGCM_GPR16 },
17914                 },
17915         },
17916         [TEMPLATE_DIV32] = {
17917                 .lhs = { 
17918                         [0] = { REG_EAX, REGCM_GPR32 },
17919                         [1] = { REG_EDX, REGCM_GPR32 },
17920                 },
17921                 .rhs = {
17922                         [0] = { REG_EDXEAX, REGCM_DIVIDEND64 },
17923                         [1] = { REG_UNSET, REGCM_GPR32 },
17924                 },
17925         },
17926 };
17927
17928 static void fixup_branch(struct compile_state *state,
17929         struct triple *branch, int jmp_op, int cmp_op, struct type *cmp_type,
17930         struct triple *left, struct triple *right)
17931 {
17932         struct triple *test;
17933         if (!left) {
17934                 internal_error(state, branch, "no branch test?");
17935         }
17936         test = pre_triple(state, branch,
17937                 cmp_op, cmp_type, left, right);
17938         test->template_id = TEMPLATE_TEST32; 
17939         if (cmp_op == OP_CMP) {
17940                 test->template_id = TEMPLATE_CMP32_REG;
17941                 if (get_imm32(test, &RHS(test, 1))) {
17942                         test->template_id = TEMPLATE_CMP32_IMM;
17943                 }
17944         }
17945         use_triple(RHS(test, 0), test);
17946         use_triple(RHS(test, 1), test);
17947         unuse_triple(RHS(branch, 0), branch);
17948         RHS(branch, 0) = test;
17949         branch->op = jmp_op;
17950         branch->template_id = TEMPLATE_JMP;
17951         use_triple(RHS(branch, 0), branch);
17952 }
17953
17954 static void fixup_branches(struct compile_state *state,
17955         struct triple *cmp, struct triple *use, int jmp_op)
17956 {
17957         struct triple_set *entry, *next;
17958         for(entry = use->use; entry; entry = next) {
17959                 next = entry->next;
17960                 if (entry->member->op == OP_COPY) {
17961                         fixup_branches(state, cmp, entry->member, jmp_op);
17962                 }
17963                 else if (entry->member->op == OP_CBRANCH) {
17964                         struct triple *branch;
17965                         struct triple *left, *right;
17966                         left = right = 0;
17967                         left = RHS(cmp, 0);
17968                         if (TRIPLE_RHS(cmp->sizes) > 1) {
17969                                 right = RHS(cmp, 1);
17970                         }
17971                         branch = entry->member;
17972                         fixup_branch(state, branch, jmp_op, 
17973                                 cmp->op, cmp->type, left, right);
17974                 }
17975         }
17976 }
17977
17978 static void bool_cmp(struct compile_state *state, 
17979         struct triple *ins, int cmp_op, int jmp_op, int set_op)
17980 {
17981         struct triple_set *entry, *next;
17982         struct triple *set;
17983
17984         /* Put a barrier up before the cmp which preceeds the
17985          * copy instruction.  If a set actually occurs this gives
17986          * us a chance to move variables in registers out of the way.
17987          */
17988
17989         /* Modify the comparison operator */
17990         ins->op = cmp_op;
17991         ins->template_id = TEMPLATE_TEST32;
17992         if (cmp_op == OP_CMP) {
17993                 ins->template_id = TEMPLATE_CMP32_REG;
17994                 if (get_imm32(ins, &RHS(ins, 1))) {
17995                         ins->template_id =  TEMPLATE_CMP32_IMM;
17996                 }
17997         }
17998         /* Generate the instruction sequence that will transform the
17999          * result of the comparison into a logical value.
18000          */
18001         set = post_triple(state, ins, set_op, &char_type, ins, 0);
18002         use_triple(ins, set);
18003         set->template_id = TEMPLATE_SET;
18004
18005         for(entry = ins->use; entry; entry = next) {
18006                 next = entry->next;
18007                 if (entry->member == set) {
18008                         continue;
18009                 }
18010                 replace_rhs_use(state, ins, set, entry->member);
18011         }
18012         fixup_branches(state, ins, set, jmp_op);
18013 }
18014
18015 static struct triple *after_lhs(struct compile_state *state, struct triple *ins)
18016 {
18017         struct triple *next;
18018         int lhs, i;
18019         lhs = TRIPLE_LHS(ins->sizes);
18020         for(next = ins->next, i = 0; i < lhs; i++, next = next->next) {
18021                 if (next != LHS(ins, i)) {
18022                         internal_error(state, ins, "malformed lhs on %s",
18023                                 tops(ins->op));
18024                 }
18025                 if (next->op != OP_PIECE) {
18026                         internal_error(state, ins, "bad lhs op %s at %d on %s",
18027                                 tops(next->op), i, tops(ins->op));
18028                 }
18029                 if (next->u.cval != i) {
18030                         internal_error(state, ins, "bad u.cval of %d %d expected",
18031                                 next->u.cval, i);
18032                 }
18033         }
18034         return next;
18035 }
18036
18037 struct reg_info arch_reg_lhs(struct compile_state *state, struct triple *ins, int index)
18038 {
18039         struct ins_template *template;
18040         struct reg_info result;
18041         int zlhs;
18042         if (ins->op == OP_PIECE) {
18043                 index = ins->u.cval;
18044                 ins = MISC(ins, 0);
18045         }
18046         zlhs = TRIPLE_LHS(ins->sizes);
18047         if (triple_is_def(state, ins)) {
18048                 zlhs = 1;
18049         }
18050         if (index >= zlhs) {
18051                 internal_error(state, ins, "index %d out of range for %s\n",
18052                         index, tops(ins->op));
18053         }
18054         switch(ins->op) {
18055         case OP_ASM:
18056                 template = &ins->u.ainfo->tmpl;
18057                 break;
18058         default:
18059                 if (ins->template_id > LAST_TEMPLATE) {
18060                         internal_error(state, ins, "bad template number %d", 
18061                                 ins->template_id);
18062                 }
18063                 template = &templates[ins->template_id];
18064                 break;
18065         }
18066         result = template->lhs[index];
18067         result.regcm = arch_regcm_normalize(state, result.regcm);
18068         if (result.reg != REG_UNNEEDED) {
18069                 result.regcm &= ~(REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8);
18070         }
18071         if (result.regcm == 0) {
18072                 internal_error(state, ins, "lhs %d regcm == 0", index);
18073         }
18074         return result;
18075 }
18076
18077 struct reg_info arch_reg_rhs(struct compile_state *state, struct triple *ins, int index)
18078 {
18079         struct reg_info result;
18080         struct ins_template *template;
18081         if ((index > TRIPLE_RHS(ins->sizes)) ||
18082                 (ins->op == OP_PIECE)) {
18083                 internal_error(state, ins, "index %d out of range for %s\n",
18084                         index, tops(ins->op));
18085         }
18086         switch(ins->op) {
18087         case OP_ASM:
18088                 template = &ins->u.ainfo->tmpl;
18089                 break;
18090         default:
18091                 if (ins->template_id > LAST_TEMPLATE) {
18092                         internal_error(state, ins, "bad template number %d", 
18093                                 ins->template_id);
18094                 }
18095                 template = &templates[ins->template_id];
18096                 break;
18097         }
18098         result = template->rhs[index];
18099         result.regcm = arch_regcm_normalize(state, result.regcm);
18100         if (result.regcm == 0) {
18101                 internal_error(state, ins, "rhs %d regcm == 0", index);
18102         }
18103         return result;
18104 }
18105
18106 static struct triple *mod_div(struct compile_state *state,
18107         struct triple *ins, int div_op, int index)
18108 {
18109         struct triple *div, *piece0, *piece1;
18110         
18111         /* Generate a piece to hold the remainder */
18112         piece1 = post_triple(state, ins, OP_PIECE, ins->type, 0, 0);
18113         piece1->u.cval = 1;
18114
18115         /* Generate a piece to hold the quotient */
18116         piece0 = post_triple(state, ins, OP_PIECE, ins->type, 0, 0);
18117         piece0->u.cval = 0;
18118
18119         /* Generate the appropriate division instruction */
18120         div = post_triple(state, ins, div_op, ins->type, 0, 0);
18121         RHS(div, 0) = RHS(ins, 0);
18122         RHS(div, 1) = RHS(ins, 1);
18123         LHS(div, 0) = piece0;
18124         LHS(div, 1) = piece1;
18125         div->template_id  = TEMPLATE_DIV32;
18126         use_triple(RHS(div, 0), div);
18127         use_triple(RHS(div, 1), div);
18128         use_triple(LHS(div, 0), div);
18129         use_triple(LHS(div, 1), div);
18130
18131         /* Hook on piece0 */
18132         MISC(piece0, 0) = div;
18133         use_triple(div, piece0);
18134
18135         /* Hook on piece1 */
18136         MISC(piece1, 0) = div;
18137         use_triple(div, piece1);
18138         
18139         /* Replate uses of ins with the appropriate piece of the div */
18140         propogate_use(state, ins, LHS(div, index));
18141         release_triple(state, ins);
18142
18143         /* Return the address of the next instruction */
18144         return piece1->next;
18145 }
18146
18147 static struct triple *transform_to_arch_instruction(
18148         struct compile_state *state, struct triple *ins)
18149 {
18150         /* Transform from generic 3 address instructions
18151          * to archtecture specific instructions.
18152          * And apply architecture specific constraints to instructions.
18153          * Copies are inserted to preserve the register flexibility
18154          * of 3 address instructions.
18155          */
18156         struct triple *next;
18157         size_t size;
18158         next = ins->next;
18159         switch(ins->op) {
18160         case OP_INTCONST:
18161                 ins->template_id = TEMPLATE_INTCONST32;
18162                 if (ins->u.cval < 256) {
18163                         ins->template_id = TEMPLATE_INTCONST8;
18164                 }
18165                 break;
18166         case OP_ADDRCONST:
18167                 ins->template_id = TEMPLATE_INTCONST32;
18168                 break;
18169         case OP_NOOP:
18170         case OP_SDECL:
18171         case OP_BLOBCONST:
18172         case OP_LABEL:
18173                 ins->template_id = TEMPLATE_NOP;
18174                 break;
18175         case OP_COPY:
18176                 size = size_of(state, ins->type);
18177                 if (is_imm8(RHS(ins, 0)) && (size <= 1)) {
18178                         ins->template_id = TEMPLATE_COPY_IMM8;
18179                 }
18180                 else if (is_imm16(RHS(ins, 0)) && (size <= 2)) {
18181                         ins->template_id = TEMPLATE_COPY_IMM16;
18182                 }
18183                 else if (is_imm32(RHS(ins, 0)) && (size <= 4)) {
18184                         ins->template_id = TEMPLATE_COPY_IMM32;
18185                 }
18186                 else if (is_const(RHS(ins, 0))) {
18187                         internal_error(state, ins, "bad constant passed to copy");
18188                 }
18189                 else if (size <= 1) {
18190                         ins->template_id = TEMPLATE_COPY8_REG;
18191                 }
18192                 else if (size <= 2) {
18193                         ins->template_id = TEMPLATE_COPY16_REG;
18194                 }
18195                 else if (size <= 4) {
18196                         ins->template_id = TEMPLATE_COPY32_REG;
18197                 }
18198                 else {
18199                         internal_error(state, ins, "bad type passed to copy");
18200                 }
18201                 break;
18202         case OP_PHI:
18203                 size = size_of(state, ins->type);
18204                 if (size <= 1) {
18205                         ins->template_id = TEMPLATE_PHI8;
18206                 }
18207                 else if (size <= 2) {
18208                         ins->template_id = TEMPLATE_PHI16;
18209                 }
18210                 else if (size <= 4) {
18211                         ins->template_id = TEMPLATE_PHI32;
18212                 }
18213                 else {
18214                         internal_error(state, ins, "bad type passed to phi");
18215                 }
18216                 break;
18217         case OP_STORE:
18218                 switch(ins->type->type & TYPE_MASK) {
18219                 case TYPE_CHAR:    case TYPE_UCHAR:
18220                         ins->template_id = TEMPLATE_STORE8;
18221                         break;
18222                 case TYPE_SHORT:   case TYPE_USHORT:
18223                         ins->template_id = TEMPLATE_STORE16;
18224                         break;
18225                 case TYPE_INT:     case TYPE_UINT:
18226                 case TYPE_LONG:    case TYPE_ULONG:
18227                 case TYPE_POINTER:
18228                         ins->template_id = TEMPLATE_STORE32;
18229                         break;
18230                 default:
18231                         internal_error(state, ins, "unknown type in store");
18232                         break;
18233                 }
18234                 break;
18235         case OP_LOAD:
18236                 switch(ins->type->type & TYPE_MASK) {
18237                 case TYPE_CHAR:   case TYPE_UCHAR:
18238                 case TYPE_SHORT:  case TYPE_USHORT:
18239                 case TYPE_INT:    case TYPE_UINT:
18240                 case TYPE_LONG:   case TYPE_ULONG:
18241                 case TYPE_POINTER:
18242                         break;
18243                 default:
18244                         internal_error(state, ins, "unknown type in load");
18245                         break;
18246                 }
18247                 ins->template_id = TEMPLATE_LOAD32;
18248                 break;
18249         case OP_ADD:
18250         case OP_SUB:
18251         case OP_AND:
18252         case OP_XOR:
18253         case OP_OR:
18254         case OP_SMUL:
18255                 ins->template_id = TEMPLATE_BINARY32_REG;
18256                 if (get_imm32(ins, &RHS(ins, 1))) {
18257                         ins->template_id = TEMPLATE_BINARY32_IMM;
18258                 }
18259                 break;
18260         case OP_SDIVT:
18261         case OP_UDIVT:
18262                 ins->template_id = TEMPLATE_DIV32;
18263                 next = after_lhs(state, ins);
18264                 break;
18265                 /* FIXME UMUL does not work yet.. */
18266         case OP_UMUL:
18267                 ins->template_id = TEMPLATE_UMUL32;
18268                 break;
18269         case OP_UDIV:
18270                 next = mod_div(state, ins, OP_UDIVT, 0);
18271                 break;
18272         case OP_SDIV:
18273                 next = mod_div(state, ins, OP_SDIVT, 0);
18274                 break;
18275         case OP_UMOD:
18276                 next = mod_div(state, ins, OP_UDIVT, 1);
18277                 break;
18278         case OP_SMOD:
18279                 next = mod_div(state, ins, OP_SDIVT, 1);
18280                 break;
18281         case OP_SL:
18282         case OP_SSR:
18283         case OP_USR:
18284                 ins->template_id = TEMPLATE_SL32_CL;
18285                 if (get_imm8(ins, &RHS(ins, 1))) {
18286                         ins->template_id = TEMPLATE_SL32_IMM;
18287                 } else if (size_of(state, RHS(ins, 1)->type) > 1) {
18288                         typed_pre_copy(state, &char_type, ins, 1);
18289                 }
18290                 break;
18291         case OP_INVERT:
18292         case OP_NEG:
18293                 ins->template_id = TEMPLATE_UNARY32;
18294                 break;
18295         case OP_EQ: 
18296                 bool_cmp(state, ins, OP_CMP, OP_JMP_EQ, OP_SET_EQ); 
18297                 break;
18298         case OP_NOTEQ:
18299                 bool_cmp(state, ins, OP_CMP, OP_JMP_NOTEQ, OP_SET_NOTEQ);
18300                 break;
18301         case OP_SLESS:
18302                 bool_cmp(state, ins, OP_CMP, OP_JMP_SLESS, OP_SET_SLESS);
18303                 break;
18304         case OP_ULESS:
18305                 bool_cmp(state, ins, OP_CMP, OP_JMP_ULESS, OP_SET_ULESS);
18306                 break;
18307         case OP_SMORE:
18308                 bool_cmp(state, ins, OP_CMP, OP_JMP_SMORE, OP_SET_SMORE);
18309                 break;
18310         case OP_UMORE:
18311                 bool_cmp(state, ins, OP_CMP, OP_JMP_UMORE, OP_SET_UMORE);
18312                 break;
18313         case OP_SLESSEQ:
18314                 bool_cmp(state, ins, OP_CMP, OP_JMP_SLESSEQ, OP_SET_SLESSEQ);
18315                 break;
18316         case OP_ULESSEQ:
18317                 bool_cmp(state, ins, OP_CMP, OP_JMP_ULESSEQ, OP_SET_ULESSEQ);
18318                 break;
18319         case OP_SMOREEQ:
18320                 bool_cmp(state, ins, OP_CMP, OP_JMP_SMOREEQ, OP_SET_SMOREEQ);
18321                 break;
18322         case OP_UMOREEQ:
18323                 bool_cmp(state, ins, OP_CMP, OP_JMP_UMOREEQ, OP_SET_UMOREEQ);
18324                 break;
18325         case OP_LTRUE:
18326                 bool_cmp(state, ins, OP_TEST, OP_JMP_NOTEQ, OP_SET_NOTEQ);
18327                 break;
18328         case OP_LFALSE:
18329                 bool_cmp(state, ins, OP_TEST, OP_JMP_EQ, OP_SET_EQ);
18330                 break;
18331         case OP_BRANCH:
18332                 ins->op = OP_JMP;
18333                 ins->template_id = TEMPLATE_NOP;
18334                 break;
18335         case OP_CBRANCH:
18336                 fixup_branch(state, ins, OP_JMP_NOTEQ, OP_TEST, 
18337                         RHS(ins, 0)->type, RHS(ins, 0), 0);
18338                 break;
18339         case OP_CALL:
18340                 ins->template_id = TEMPLATE_NOP;
18341                 break;
18342         case OP_RET:
18343                 ins->template_id = TEMPLATE_RET;
18344                 break;
18345         case OP_INB:
18346         case OP_INW:
18347         case OP_INL:
18348                 switch(ins->op) {
18349                 case OP_INB: ins->template_id = TEMPLATE_INB_DX; break;
18350                 case OP_INW: ins->template_id = TEMPLATE_INW_DX; break;
18351                 case OP_INL: ins->template_id = TEMPLATE_INL_DX; break;
18352                 }
18353                 if (get_imm8(ins, &RHS(ins, 0))) {
18354                         ins->template_id += 1;
18355                 }
18356                 break;
18357         case OP_OUTB:
18358         case OP_OUTW:
18359         case OP_OUTL:
18360                 switch(ins->op) {
18361                 case OP_OUTB: ins->template_id = TEMPLATE_OUTB_DX; break;
18362                 case OP_OUTW: ins->template_id = TEMPLATE_OUTW_DX; break;
18363                 case OP_OUTL: ins->template_id = TEMPLATE_OUTL_DX; break;
18364                 }
18365                 if (get_imm8(ins, &RHS(ins, 1))) {
18366                         ins->template_id += 1;
18367                 }
18368                 break;
18369         case OP_BSF:
18370         case OP_BSR:
18371                 ins->template_id = TEMPLATE_BSF;
18372                 break;
18373         case OP_RDMSR:
18374                 ins->template_id = TEMPLATE_RDMSR;
18375                 next = after_lhs(state, ins);
18376                 break;
18377         case OP_WRMSR:
18378                 ins->template_id = TEMPLATE_WRMSR;
18379                 break;
18380         case OP_HLT:
18381                 ins->template_id = TEMPLATE_NOP;
18382                 break;
18383         case OP_ASM:
18384                 ins->template_id = TEMPLATE_NOP;
18385                 next = after_lhs(state, ins);
18386                 break;
18387                 /* Already transformed instructions */
18388         case OP_TEST:
18389                 ins->template_id = TEMPLATE_TEST32;
18390                 break;
18391         case OP_CMP:
18392                 ins->template_id = TEMPLATE_CMP32_REG;
18393                 if (get_imm32(ins, &RHS(ins, 1))) {
18394                         ins->template_id = TEMPLATE_CMP32_IMM;
18395                 }
18396                 break;
18397         case OP_JMP:
18398                 ins->template_id = TEMPLATE_NOP;
18399                 break;
18400         case OP_JMP_EQ:      case OP_JMP_NOTEQ:
18401         case OP_JMP_SLESS:   case OP_JMP_ULESS:
18402         case OP_JMP_SMORE:   case OP_JMP_UMORE:
18403         case OP_JMP_SLESSEQ: case OP_JMP_ULESSEQ:
18404         case OP_JMP_SMOREEQ: case OP_JMP_UMOREEQ:
18405                 ins->template_id = TEMPLATE_JMP;
18406                 break;
18407         case OP_SET_EQ:      case OP_SET_NOTEQ:
18408         case OP_SET_SLESS:   case OP_SET_ULESS:
18409         case OP_SET_SMORE:   case OP_SET_UMORE:
18410         case OP_SET_SLESSEQ: case OP_SET_ULESSEQ:
18411         case OP_SET_SMOREEQ: case OP_SET_UMOREEQ:
18412                 ins->template_id = TEMPLATE_SET;
18413                 break;
18414                 /* Unhandled instructions */
18415         case OP_PIECE:
18416         default:
18417                 internal_error(state, ins, "unhandled ins: %d %s\n",
18418                         ins->op, tops(ins->op));
18419                 break;
18420         }
18421         return next;
18422 }
18423
18424 static long next_label(struct compile_state *state)
18425 {
18426         static long label_counter = 0;
18427         return ++label_counter;
18428 }
18429 static void generate_local_labels(struct compile_state *state)
18430 {
18431         struct triple *first, *label;
18432         first = state->first;
18433         label = first;
18434         do {
18435                 if ((label->op == OP_LABEL) || 
18436                         (label->op == OP_SDECL)) {
18437                         if (label->use) {
18438                                 label->u.cval = next_label(state);
18439                         } else {
18440                                 label->u.cval = 0;
18441                         }
18442                         
18443                 }
18444                 label = label->next;
18445         } while(label != first);
18446 }
18447
18448 static int check_reg(struct compile_state *state, 
18449         struct triple *triple, int classes)
18450 {
18451         unsigned mask;
18452         int reg;
18453         reg = ID_REG(triple->id);
18454         if (reg == REG_UNSET) {
18455                 internal_error(state, triple, "register not set");
18456         }
18457         mask = arch_reg_regcm(state, reg);
18458         if (!(classes & mask)) {
18459                 internal_error(state, triple, "reg %d in wrong class",
18460                         reg);
18461         }
18462         return reg;
18463 }
18464
18465 static const char *arch_reg_str(int reg)
18466 {
18467 #if REG_XMM7 != 44
18468 #error "Registers have renumberd fix arch_reg_str"
18469 #endif
18470         static const char *regs[] = {
18471                 "%unset",
18472                 "%unneeded",
18473                 "%eflags",
18474                 "%al", "%bl", "%cl", "%dl", "%ah", "%bh", "%ch", "%dh",
18475                 "%ax", "%bx", "%cx", "%dx", "%si", "%di", "%bp", "%sp",
18476                 "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi", "%ebp", "%esp",
18477                 "%edx:%eax",
18478                 "%dx:%ax",
18479                 "%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7",
18480                 "%xmm0", "%xmm1", "%xmm2", "%xmm3", 
18481                 "%xmm4", "%xmm5", "%xmm6", "%xmm7",
18482         };
18483         if (!((reg >= REG_EFLAGS) && (reg <= REG_XMM7))) {
18484                 reg = 0;
18485         }
18486         return regs[reg];
18487 }
18488
18489
18490 static const char *reg(struct compile_state *state, struct triple *triple,
18491         int classes)
18492 {
18493         int reg;
18494         reg = check_reg(state, triple, classes);
18495         return arch_reg_str(reg);
18496 }
18497
18498 const char *type_suffix(struct compile_state *state, struct type *type)
18499 {
18500         const char *suffix;
18501         switch(size_of(state, type)) {
18502         case 1: suffix = "b"; break;
18503         case 2: suffix = "w"; break;
18504         case 4: suffix = "l"; break;
18505         default:
18506                 internal_error(state, 0, "unknown suffix");
18507                 suffix = 0;
18508                 break;
18509         }
18510         return suffix;
18511 }
18512
18513 static void print_const_val(
18514         struct compile_state *state, struct triple *ins, FILE *fp)
18515 {
18516         switch(ins->op) {
18517         case OP_INTCONST:
18518                 fprintf(fp, " $%ld ", 
18519                         (long)(ins->u.cval));
18520                 break;
18521         case OP_ADDRCONST:
18522                 if ((MISC(ins, 0)->op != OP_SDECL) &&
18523                         (MISC(ins, 0)->op != OP_LABEL))
18524                 {
18525                         internal_error(state, ins, "bad base for addrconst");
18526                 }
18527                 if (MISC(ins, 0)->u.cval <= 0) {
18528                         internal_error(state, ins, "unlabeled constant");
18529                 }
18530                 fprintf(fp, " $L%s%lu+%lu ",
18531                         state->compiler->label_prefix, 
18532                         (unsigned long)(MISC(ins, 0)->u.cval),
18533                         (unsigned long)(ins->u.cval));
18534                 break;
18535         default:
18536                 internal_error(state, ins, "unknown constant type");
18537                 break;
18538         }
18539 }
18540
18541 static void print_const(struct compile_state *state,
18542         struct triple *ins, FILE *fp)
18543 {
18544         switch(ins->op) {
18545         case OP_INTCONST:
18546                 switch(ins->type->type & TYPE_MASK) {
18547                 case TYPE_CHAR:
18548                 case TYPE_UCHAR:
18549                         fprintf(fp, ".byte 0x%02lx\n", 
18550                                 (unsigned long)(ins->u.cval));
18551                         break;
18552                 case TYPE_SHORT:
18553                 case TYPE_USHORT:
18554                         fprintf(fp, ".short 0x%04lx\n", 
18555                                 (unsigned long)(ins->u.cval));
18556                         break;
18557                 case TYPE_INT:
18558                 case TYPE_UINT:
18559                 case TYPE_LONG:
18560                 case TYPE_ULONG:
18561                 case TYPE_POINTER:
18562                         fprintf(fp, ".int %lu\n", 
18563                                 (unsigned long)(ins->u.cval));
18564                         break;
18565                 default:
18566                         internal_error(state, ins, "Unknown constant type");
18567                 }
18568                 break;
18569         case OP_ADDRCONST:
18570                 if ((MISC(ins, 0)->op != OP_SDECL) &&
18571                         (MISC(ins, 0)->op != OP_LABEL)) {
18572                         internal_error(state, ins, "bad base for addrconst");
18573                 }
18574                 if (MISC(ins, 0)->u.cval <= 0) {
18575                         internal_error(state, ins, "unlabeled constant");
18576                 }
18577                 fprintf(fp, ".int L%s%lu+%lu\n",
18578                         state->compiler->label_prefix,
18579                         (unsigned long)(MISC(ins, 0)->u.cval),
18580                         (unsigned long)(ins->u.cval));
18581                 break;
18582         case OP_BLOBCONST:
18583         {
18584                 unsigned char *blob;
18585                 size_t size, i;
18586                 size = size_of(state, ins->type);
18587                 blob = ins->u.blob;
18588                 for(i = 0; i < size; i++) {
18589                         fprintf(fp, ".byte 0x%02x\n",
18590                                 blob[i]);
18591                 }
18592                 break;
18593         }
18594         default:
18595                 internal_error(state, ins, "Unknown constant type");
18596                 break;
18597         }
18598 }
18599
18600 #define TEXT_SECTION ".rom.text"
18601 #define DATA_SECTION ".rom.data"
18602
18603 static long get_const_pool_ref(
18604         struct compile_state *state, struct triple *ins, FILE *fp)
18605 {
18606         long ref;
18607         ref = next_label(state);
18608         fprintf(fp, ".section \"" DATA_SECTION "\"\n");
18609         fprintf(fp, ".balign %d\n", align_of(state, ins->type));
18610         fprintf(fp, "L%s%lu:\n", state->compiler->label_prefix, ref);
18611         print_const(state, ins, fp);
18612         fprintf(fp, ".section \"" TEXT_SECTION "\"\n");
18613         return ref;
18614 }
18615
18616 static void print_binary_op(struct compile_state *state,
18617         const char *op, struct triple *ins, FILE *fp) 
18618 {
18619         unsigned mask;
18620         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO;
18621         if (ID_REG(RHS(ins, 0)->id) != ID_REG(ins->id)) {
18622                 internal_error(state, ins, "invalid register assignment");
18623         }
18624         if (is_const(RHS(ins, 1))) {
18625                 fprintf(fp, "\t%s ", op);
18626                 print_const_val(state, RHS(ins, 1), fp);
18627                 fprintf(fp, ", %s\n",
18628                         reg(state, RHS(ins, 0), mask));
18629         }
18630         else {
18631                 unsigned lmask, rmask;
18632                 int lreg, rreg;
18633                 lreg = check_reg(state, RHS(ins, 0), mask);
18634                 rreg = check_reg(state, RHS(ins, 1), mask);
18635                 lmask = arch_reg_regcm(state, lreg);
18636                 rmask = arch_reg_regcm(state, rreg);
18637                 mask = lmask & rmask;
18638                 fprintf(fp, "\t%s %s, %s\n",
18639                         op,
18640                         reg(state, RHS(ins, 1), mask),
18641                         reg(state, RHS(ins, 0), mask));
18642         }
18643 }
18644 static void print_unary_op(struct compile_state *state, 
18645         const char *op, struct triple *ins, FILE *fp)
18646 {
18647         unsigned mask;
18648         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO;
18649         fprintf(fp, "\t%s %s\n",
18650                 op,
18651                 reg(state, RHS(ins, 0), mask));
18652 }
18653
18654 static void print_op_shift(struct compile_state *state,
18655         const char *op, struct triple *ins, FILE *fp)
18656 {
18657         unsigned mask;
18658         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO;
18659         if (ID_REG(RHS(ins, 0)->id) != ID_REG(ins->id)) {
18660                 internal_error(state, ins, "invalid register assignment");
18661         }
18662         if (is_const(RHS(ins, 1))) {
18663                 fprintf(fp, "\t%s ", op);
18664                 print_const_val(state, RHS(ins, 1), fp);
18665                 fprintf(fp, ", %s\n",
18666                         reg(state, RHS(ins, 0), mask));
18667         }
18668         else {
18669                 fprintf(fp, "\t%s %s, %s\n",
18670                         op,
18671                         reg(state, RHS(ins, 1), REGCM_GPR8_LO),
18672                         reg(state, RHS(ins, 0), mask));
18673         }
18674 }
18675
18676 static void print_op_in(struct compile_state *state, struct triple *ins, FILE *fp)
18677 {
18678         const char *op;
18679         int mask;
18680         int dreg;
18681         mask = 0;
18682         switch(ins->op) {
18683         case OP_INB: op = "inb", mask = REGCM_GPR8_LO; break;
18684         case OP_INW: op = "inw", mask = REGCM_GPR16; break;
18685         case OP_INL: op = "inl", mask = REGCM_GPR32; break;
18686         default:
18687                 internal_error(state, ins, "not an in operation");
18688                 op = 0;
18689                 break;
18690         }
18691         dreg = check_reg(state, ins, mask);
18692         if (!reg_is_reg(state, dreg, REG_EAX)) {
18693                 internal_error(state, ins, "dst != %%eax");
18694         }
18695         if (is_const(RHS(ins, 0))) {
18696                 fprintf(fp, "\t%s ", op);
18697                 print_const_val(state, RHS(ins, 0), fp);
18698                 fprintf(fp, ", %s\n",
18699                         reg(state, ins, mask));
18700         }
18701         else {
18702                 int addr_reg;
18703                 addr_reg = check_reg(state, RHS(ins, 0), REGCM_GPR16);
18704                 if (!reg_is_reg(state, addr_reg, REG_DX)) {
18705                         internal_error(state, ins, "src != %%dx");
18706                 }
18707                 fprintf(fp, "\t%s %s, %s\n",
18708                         op, 
18709                         reg(state, RHS(ins, 0), REGCM_GPR16),
18710                         reg(state, ins, mask));
18711         }
18712 }
18713
18714 static void print_op_out(struct compile_state *state, struct triple *ins, FILE *fp)
18715 {
18716         const char *op;
18717         int mask;
18718         int lreg;
18719         mask = 0;
18720         switch(ins->op) {
18721         case OP_OUTB: op = "outb", mask = REGCM_GPR8_LO; break;
18722         case OP_OUTW: op = "outw", mask = REGCM_GPR16; break;
18723         case OP_OUTL: op = "outl", mask = REGCM_GPR32; break;
18724         default:
18725                 internal_error(state, ins, "not an out operation");
18726                 op = 0;
18727                 break;
18728         }
18729         lreg = check_reg(state, RHS(ins, 0), mask);
18730         if (!reg_is_reg(state, lreg, REG_EAX)) {
18731                 internal_error(state, ins, "src != %%eax");
18732         }
18733         if (is_const(RHS(ins, 1))) {
18734                 fprintf(fp, "\t%s %s,", 
18735                         op, reg(state, RHS(ins, 0), mask));
18736                 print_const_val(state, RHS(ins, 1), fp);
18737                 fprintf(fp, "\n");
18738         }
18739         else {
18740                 int addr_reg;
18741                 addr_reg = check_reg(state, RHS(ins, 1), REGCM_GPR16);
18742                 if (!reg_is_reg(state, addr_reg, REG_DX)) {
18743                         internal_error(state, ins, "dst != %%dx");
18744                 }
18745                 fprintf(fp, "\t%s %s, %s\n",
18746                         op, 
18747                         reg(state, RHS(ins, 0), mask),
18748                         reg(state, RHS(ins, 1), REGCM_GPR16));
18749         }
18750 }
18751
18752 static void print_op_move(struct compile_state *state,
18753         struct triple *ins, FILE *fp)
18754 {
18755         /* op_move is complex because there are many types
18756          * of registers we can move between.
18757          * Because OP_COPY will be introduced in arbitrary locations
18758          * OP_COPY must not affect flags.
18759          */
18760         int omit_copy = 1; /* Is it o.k. to omit a noop copy? */
18761         struct triple *dst, *src;
18762         if (ins->op == OP_COPY) {
18763                 src = RHS(ins, 0);
18764                 dst = ins;
18765         }
18766         else {
18767                 internal_error(state, ins, "unknown move operation");
18768                 src = dst = 0;
18769         }
18770         if (!is_const(src)) {
18771                 int src_reg, dst_reg;
18772                 int src_regcm, dst_regcm;
18773                 src_reg   = ID_REG(src->id);
18774                 dst_reg   = ID_REG(dst->id);
18775                 src_regcm = arch_reg_regcm(state, src_reg);
18776                 dst_regcm = arch_reg_regcm(state, dst_reg);
18777                 /* If the class is the same just move the register */
18778                 if (src_regcm & dst_regcm & 
18779                         (REGCM_GPR8_LO | REGCM_GPR16 | REGCM_GPR32)) {
18780                         if ((src_reg != dst_reg) || !omit_copy) {
18781                                 fprintf(fp, "\tmov %s, %s\n",
18782                                         reg(state, src, src_regcm),
18783                                         reg(state, dst, dst_regcm));
18784                         }
18785                 }
18786                 /* Move 32bit to 16bit */
18787                 else if ((src_regcm & REGCM_GPR32) &&
18788                         (dst_regcm & REGCM_GPR16)) {
18789                         src_reg = (src_reg - REGC_GPR32_FIRST) + REGC_GPR16_FIRST;
18790                         if ((src_reg != dst_reg) || !omit_copy) {
18791                                 fprintf(fp, "\tmovw %s, %s\n",
18792                                         arch_reg_str(src_reg), 
18793                                         arch_reg_str(dst_reg));
18794                         }
18795                 }
18796                 /* Move from 32bit gprs to 16bit gprs */
18797                 else if ((src_regcm & REGCM_GPR32) &&
18798                         (dst_regcm & REGCM_GPR16)) {
18799                         dst_reg = (dst_reg - REGC_GPR16_FIRST) + REGC_GPR32_FIRST;
18800                         if ((src_reg != dst_reg) || !omit_copy) {
18801                                 fprintf(fp, "\tmov %s, %s\n",
18802                                         arch_reg_str(src_reg),
18803                                         arch_reg_str(dst_reg));
18804                         }
18805                 }
18806                 /* Move 32bit to 8bit */
18807                 else if ((src_regcm & REGCM_GPR32_8) &&
18808                         (dst_regcm & REGCM_GPR8_LO))
18809                 {
18810                         src_reg = (src_reg - REGC_GPR32_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 16bit to 8bit */
18818                 else if ((src_regcm & REGCM_GPR16_8) &&
18819                         (dst_regcm & REGCM_GPR8_LO))
18820                 {
18821                         src_reg = (src_reg - REGC_GPR16_8_FIRST) + REGC_GPR8_FIRST;
18822                         if ((src_reg != dst_reg) || !omit_copy) {
18823                                 fprintf(fp, "\tmovb %s, %s\n",
18824                                         arch_reg_str(src_reg),
18825                                         arch_reg_str(dst_reg));
18826                         }
18827                 }
18828                 /* Move 8/16bit to 16/32bit */
18829                 else if ((src_regcm & (REGCM_GPR8_LO | REGCM_GPR16)) && 
18830                         (dst_regcm & (REGCM_GPR16 | REGCM_GPR32))) {
18831                         const char *op;
18832                         op = is_signed(src->type)? "movsx": "movzx";
18833                         fprintf(fp, "\t%s %s, %s\n",
18834                                 op,
18835                                 reg(state, src, src_regcm),
18836                                 reg(state, dst, dst_regcm));
18837                 }
18838                 /* Move between sse registers */
18839                 else if ((src_regcm & dst_regcm & REGCM_XMM)) {
18840                         if ((src_reg != dst_reg) || !omit_copy) {
18841                                 fprintf(fp, "\tmovdqa %s, %s\n",
18842                                         reg(state, src, src_regcm),
18843                                         reg(state, dst, dst_regcm));
18844                         }
18845                 }
18846                 /* Move between mmx registers */
18847                 else if ((src_regcm & dst_regcm & REGCM_MMX)) {
18848                         if ((src_reg != dst_reg) || !omit_copy) {
18849                                 fprintf(fp, "\tmovq %s, %s\n",
18850                                         reg(state, src, src_regcm),
18851                                         reg(state, dst, dst_regcm));
18852                         }
18853                 }
18854                 /* Move from sse to mmx registers */
18855                 else if ((src_regcm & REGCM_XMM) && (dst_regcm & REGCM_MMX)) {
18856                         fprintf(fp, "\tmovdq2q %s, %s\n",
18857                                 reg(state, src, src_regcm),
18858                                 reg(state, dst, dst_regcm));
18859                 }
18860                 /* Move from mmx to sse registers */
18861                 else if ((src_regcm & REGCM_MMX) && (dst_regcm & REGCM_XMM)) {
18862                         fprintf(fp, "\tmovq2dq %s, %s\n",
18863                                 reg(state, src, src_regcm),
18864                                 reg(state, dst, dst_regcm));
18865                 }
18866                 /* Move between 32bit gprs & mmx/sse registers */
18867                 else if ((src_regcm & (REGCM_GPR32 | REGCM_MMX | REGCM_XMM)) &&
18868                         (dst_regcm & (REGCM_GPR32 | REGCM_MMX | REGCM_XMM))) {
18869                         fprintf(fp, "\tmovd %s, %s\n",
18870                                 reg(state, src, src_regcm),
18871                                 reg(state, dst, dst_regcm));
18872                 }
18873                 /* Move from 16bit gprs &  mmx/sse registers */
18874                 else if ((src_regcm & REGCM_GPR16) &&
18875                         (dst_regcm & (REGCM_MMX | REGCM_XMM))) {
18876                         const char *op;
18877                         int mid_reg;
18878                         op = is_signed(src->type)? "movsx":"movzx";
18879                         mid_reg = (src_reg - REGC_GPR16_FIRST) + REGC_GPR32_FIRST;
18880                         fprintf(fp, "\t%s %s, %s\n\tmovd %s, %s\n",
18881                                 op,
18882                                 arch_reg_str(src_reg),
18883                                 arch_reg_str(mid_reg),
18884                                 arch_reg_str(mid_reg),
18885                                 arch_reg_str(dst_reg));
18886                 }
18887                 /* Move from mmx/sse registers to 16bit gprs */
18888                 else if ((src_regcm & (REGCM_MMX | REGCM_XMM)) &&
18889                         (dst_regcm & REGCM_GPR16)) {
18890                         dst_reg = (dst_reg - REGC_GPR16_FIRST) + REGC_GPR32_FIRST;
18891                         fprintf(fp, "\tmovd %s, %s\n",
18892                                 arch_reg_str(src_reg),
18893                                 arch_reg_str(dst_reg));
18894                 }
18895                 /* Move from gpr to 64bit dividend */
18896                 else if ((src_regcm & (REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO))  &&
18897                         (dst_regcm & REGCM_DIVIDEND64)) {
18898                         const char *extend;
18899                         extend = is_signed(src->type)? "cltd":"movl $0, %edx";
18900                         fprintf(fp, "\tmov %s, %%eax\n\t%s\n",
18901                                 arch_reg_str(src_reg), 
18902                                 extend);
18903                 }
18904                 /* Move from 64bit gpr to gpr */
18905                 else if ((src_regcm & REGCM_DIVIDEND64) &&
18906                         (dst_regcm & (REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO))) {
18907                         if (dst_regcm & REGCM_GPR32) {
18908                                 src_reg = REG_EAX;
18909                         } 
18910                         else if (dst_regcm & REGCM_GPR16) {
18911                                 src_reg = REG_AX;
18912                         }
18913                         else if (dst_regcm & REGCM_GPR8_LO) {
18914                                 src_reg = REG_AL;
18915                         }
18916                         fprintf(fp, "\tmov %s, %s\n",
18917                                 arch_reg_str(src_reg),
18918                                 arch_reg_str(dst_reg));
18919                 }
18920                 /* Move from mmx/sse registers to 64bit gpr */
18921                 else if ((src_regcm & (REGCM_MMX | REGCM_XMM)) &&
18922                         (dst_regcm & REGCM_DIVIDEND64)) {
18923                         const char *extend;
18924                         extend = is_signed(src->type)? "cltd": "movl $0, %edx";
18925                         fprintf(fp, "\tmovd %s, %%eax\n\t%s\n",
18926                                 arch_reg_str(src_reg),
18927                                 extend);
18928                 }
18929                 /* Move from 64bit gpr to mmx/sse register */
18930                 else if ((src_regcm & REGCM_DIVIDEND64) &&
18931                         (dst_regcm & (REGCM_XMM | REGCM_MMX))) {
18932                         fprintf(fp, "\tmovd %%eax, %s\n",
18933                                 arch_reg_str(dst_reg));
18934                 }
18935 #if X86_4_8BIT_GPRS
18936                 /* Move from 8bit gprs to  mmx/sse registers */
18937                 else if ((src_regcm & REGCM_GPR8_LO) && (src_reg <= REG_DL) &&
18938                         (dst_regcm & (REGCM_MMX | REGCM_XMM))) {
18939                         const char *op;
18940                         int mid_reg;
18941                         op = is_signed(src->type)? "movsx":"movzx";
18942                         mid_reg = (src_reg - REGC_GPR8_FIRST) + REGC_GPR32_FIRST;
18943                         fprintf(fp, "\t%s %s, %s\n\tmovd %s, %s\n",
18944                                 op,
18945                                 reg(state, src, src_regcm),
18946                                 arch_reg_str(mid_reg),
18947                                 arch_reg_str(mid_reg),
18948                                 reg(state, dst, dst_regcm));
18949                 }
18950                 /* Move from mmx/sse registers and 8bit gprs */
18951                 else if ((src_regcm & (REGCM_MMX | REGCM_XMM)) &&
18952                         (dst_regcm & REGCM_GPR8_LO) && (dst_reg <= REG_DL)) {
18953                         int mid_reg;
18954                         mid_reg = (dst_reg - REGC_GPR8_FIRST) + REGC_GPR32_FIRST;
18955                         fprintf(fp, "\tmovd %s, %s\n",
18956                                 reg(state, src, src_regcm),
18957                                 arch_reg_str(mid_reg));
18958                 }
18959                 /* Move from 32bit gprs to 8bit gprs */
18960                 else if ((src_regcm & REGCM_GPR32) &&
18961                         (dst_regcm & REGCM_GPR8_LO)) {
18962                         dst_reg = (dst_reg - REGC_GPR8_FIRST) + REGC_GPR32_FIRST;
18963                         if ((src_reg != dst_reg) || !omit_copy) {
18964                                 fprintf(fp, "\tmov %s, %s\n",
18965                                         arch_reg_str(src_reg),
18966                                         arch_reg_str(dst_reg));
18967                         }
18968                 }
18969                 /* Move from 16bit gprs to 8bit gprs */
18970                 else if ((src_regcm & REGCM_GPR16) &&
18971                         (dst_regcm & REGCM_GPR8_LO)) {
18972                         dst_reg = (dst_reg - REGC_GPR8_FIRST) + REGC_GPR16_FIRST;
18973                         if ((src_reg != dst_reg) || !omit_copy) {
18974                                 fprintf(fp, "\tmov %s, %s\n",
18975                                         arch_reg_str(src_reg),
18976                                         arch_reg_str(dst_reg));
18977                         }
18978                 }
18979 #endif /* X86_4_8BIT_GPRS */
18980                 else {
18981                         internal_error(state, ins, "unknown copy type");
18982                 }
18983         }
18984         else {
18985                 int dst_reg;
18986                 int dst_regcm;
18987                 dst_reg = ID_REG(dst->id);
18988                 dst_regcm = arch_reg_regcm(state, dst_reg);
18989                 if (dst_regcm & (REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO)) {
18990                         fprintf(fp, "\tmov ");
18991                         print_const_val(state, src, fp);
18992                         fprintf(fp, ", %s\n",
18993                                 reg(state, dst, REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO));
18994                 }
18995                 else if (dst_regcm & REGCM_DIVIDEND64) {
18996                         if (size_of(state, dst->type) > 4) {
18997                                 internal_error(state, ins, "64bit constant...");
18998                         }
18999                         fprintf(fp, "\tmov $0, %%edx\n");
19000                         fprintf(fp, "\tmov ");
19001                         print_const_val(state, src, fp);
19002                         fprintf(fp, ", %%eax\n");
19003                 }
19004                 else if (dst_regcm & REGCM_DIVIDEND32) {
19005                         if (size_of(state, dst->type) > 2) {
19006                                 internal_error(state, ins, "32bit constant...");
19007                         }
19008                         fprintf(fp, "\tmov $0, %%dx\n");
19009                         fprintf(fp, "\tmov ");
19010                         print_const_val(state, src, fp);
19011                         fprintf(fp, ", %%ax");
19012                 }
19013                 else if (dst_regcm & (REGCM_XMM | REGCM_MMX)) {
19014                         long ref;
19015                         ref = get_const_pool_ref(state, src, fp);
19016                         fprintf(fp, "\tmovd L%s%lu, %s\n",
19017                                 state->compiler->label_prefix, ref,
19018                                 reg(state, dst, (REGCM_XMM | REGCM_MMX)));
19019                 }
19020                 else {
19021                         internal_error(state, ins, "unknown copy immediate type");
19022                 }
19023         }
19024 }
19025
19026 static void print_op_load(struct compile_state *state,
19027         struct triple *ins, FILE *fp)
19028 {
19029         struct triple *dst, *src;
19030         const char *op;
19031         dst = ins;
19032         src = RHS(ins, 0);
19033         if (is_const(src) || is_const(dst)) {
19034                 internal_error(state, ins, "unknown load operation");
19035         }
19036         switch(ins->type->type & TYPE_MASK) {
19037         case TYPE_CHAR:   op = "movsbl"; break;
19038         case TYPE_UCHAR:  op = "movzbl"; break;
19039         case TYPE_SHORT:  op = "movswl"; break;
19040         case TYPE_USHORT: op = "movzwl"; break;
19041         case TYPE_INT:    case TYPE_UINT:
19042         case TYPE_LONG:   case TYPE_ULONG:
19043         case TYPE_POINTER:
19044                 op = "movl"; 
19045                 break;
19046         default:
19047                 internal_error(state, ins, "unknown type in load");
19048                 op = "<invalid opcode>";
19049                 break;
19050         }
19051         fprintf(fp, "\t%s (%s), %s\n",
19052                 op, 
19053                 reg(state, src, REGCM_GPR32),
19054                 reg(state, dst, REGCM_GPR32));
19055 }
19056
19057
19058 static void print_op_store(struct compile_state *state,
19059         struct triple *ins, FILE *fp)
19060 {
19061         struct triple *dst, *src;
19062         dst = RHS(ins, 0);
19063         src = RHS(ins, 1);
19064         if (is_const(src) && (src->op == OP_INTCONST)) {
19065                 long_t value;
19066                 value = (long_t)(src->u.cval);
19067                 fprintf(fp, "\tmov%s $%ld, (%s)\n",
19068                         type_suffix(state, src->type),
19069                         (long)(value),
19070                         reg(state, dst, REGCM_GPR32));
19071         }
19072         else if (is_const(dst) && (dst->op == OP_INTCONST)) {
19073                 fprintf(fp, "\tmov%s %s, 0x%08lx\n",
19074                         type_suffix(state, src->type),
19075                         reg(state, src, REGCM_GPR8_LO | REGCM_GPR16 | REGCM_GPR32),
19076                         (unsigned long)(dst->u.cval));
19077         }
19078         else {
19079                 if (is_const(src) || is_const(dst)) {
19080                         internal_error(state, ins, "unknown store operation");
19081                 }
19082                 fprintf(fp, "\tmov%s %s, (%s)\n",
19083                         type_suffix(state, src->type),
19084                         reg(state, src, REGCM_GPR8_LO | REGCM_GPR16 | REGCM_GPR32),
19085                         reg(state, dst, REGCM_GPR32));
19086         }
19087         
19088         
19089 }
19090
19091 static void print_op_smul(struct compile_state *state,
19092         struct triple *ins, FILE *fp)
19093 {
19094         if (!is_const(RHS(ins, 1))) {
19095                 fprintf(fp, "\timul %s, %s\n",
19096                         reg(state, RHS(ins, 1), REGCM_GPR32),
19097                         reg(state, RHS(ins, 0), REGCM_GPR32));
19098         }
19099         else {
19100                 fprintf(fp, "\timul ");
19101                 print_const_val(state, RHS(ins, 1), fp);
19102                 fprintf(fp, ", %s\n", reg(state, RHS(ins, 0), REGCM_GPR32));
19103         }
19104 }
19105
19106 static void print_op_cmp(struct compile_state *state,
19107         struct triple *ins, FILE *fp)
19108 {
19109         unsigned mask;
19110         int dreg;
19111         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO;
19112         dreg = check_reg(state, ins, REGCM_FLAGS);
19113         if (!reg_is_reg(state, dreg, REG_EFLAGS)) {
19114                 internal_error(state, ins, "bad dest register for cmp");
19115         }
19116         if (is_const(RHS(ins, 1))) {
19117                 fprintf(fp, "\tcmp ");
19118                 print_const_val(state, RHS(ins, 1), fp);
19119                 fprintf(fp, ", %s\n", reg(state, RHS(ins, 0), mask));
19120         }
19121         else {
19122                 unsigned lmask, rmask;
19123                 int lreg, rreg;
19124                 lreg = check_reg(state, RHS(ins, 0), mask);
19125                 rreg = check_reg(state, RHS(ins, 1), mask);
19126                 lmask = arch_reg_regcm(state, lreg);
19127                 rmask = arch_reg_regcm(state, rreg);
19128                 mask = lmask & rmask;
19129                 fprintf(fp, "\tcmp %s, %s\n",
19130                         reg(state, RHS(ins, 1), mask),
19131                         reg(state, RHS(ins, 0), mask));
19132         }
19133 }
19134
19135 static void print_op_test(struct compile_state *state,
19136         struct triple *ins, FILE *fp)
19137 {
19138         unsigned mask;
19139         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO;
19140         fprintf(fp, "\ttest %s, %s\n",
19141                 reg(state, RHS(ins, 0), mask),
19142                 reg(state, RHS(ins, 0), mask));
19143 }
19144
19145 static void print_op_branch(struct compile_state *state,
19146         struct triple *branch, FILE *fp)
19147 {
19148         const char *bop = "j";
19149         if ((branch->op == OP_JMP) || (branch->op == OP_CALL)) {
19150                 if (TRIPLE_RHS(branch->sizes) != 0) {
19151                         internal_error(state, branch, "jmp with condition?");
19152                 }
19153                 bop = "jmp";
19154         }
19155         else {
19156                 struct triple *ptr;
19157                 if (TRIPLE_RHS(branch->sizes) != 1) {
19158                         internal_error(state, branch, "jmpcc without condition?");
19159                 }
19160                 check_reg(state, RHS(branch, 0), REGCM_FLAGS);
19161                 if ((RHS(branch, 0)->op != OP_CMP) &&
19162                         (RHS(branch, 0)->op != OP_TEST)) {
19163                         internal_error(state, branch, "bad branch test");
19164                 }
19165 #warning "FIXME I have observed instructions between the test and branch instructions"
19166                 ptr = RHS(branch, 0);
19167                 for(ptr = RHS(branch, 0)->next; ptr != branch; ptr = ptr->next) {
19168                         if (ptr->op != OP_COPY) {
19169                                 internal_error(state, branch, "branch does not follow test");
19170                         }
19171                 }
19172                 switch(branch->op) {
19173                 case OP_JMP_EQ:       bop = "jz";  break;
19174                 case OP_JMP_NOTEQ:    bop = "jnz"; break;
19175                 case OP_JMP_SLESS:    bop = "jl";  break;
19176                 case OP_JMP_ULESS:    bop = "jb";  break;
19177                 case OP_JMP_SMORE:    bop = "jg";  break;
19178                 case OP_JMP_UMORE:    bop = "ja";  break;
19179                 case OP_JMP_SLESSEQ:  bop = "jle"; break;
19180                 case OP_JMP_ULESSEQ:  bop = "jbe"; break;
19181                 case OP_JMP_SMOREEQ:  bop = "jge"; break;
19182                 case OP_JMP_UMOREEQ:  bop = "jae"; break;
19183                 default:
19184                         internal_error(state, branch, "Invalid branch op");
19185                         break;
19186                 }
19187                 
19188         }
19189         fprintf(fp, "\t%s L%s%lu\n",
19190                 bop, 
19191                 state->compiler->label_prefix,
19192                 (unsigned long)(TARG(branch, 0)->u.cval));
19193 }
19194
19195 static void print_op_ret(struct compile_state *state,
19196         struct triple *branch, FILE *fp)
19197 {
19198         fprintf(fp, "\tjmp *%s\n",
19199                 reg(state, RHS(branch, 0), REGCM_GPR32));
19200 }
19201
19202 static void print_op_set(struct compile_state *state,
19203         struct triple *set, FILE *fp)
19204 {
19205         const char *sop = "set";
19206         if (TRIPLE_RHS(set->sizes) != 1) {
19207                 internal_error(state, set, "setcc without condition?");
19208         }
19209         check_reg(state, RHS(set, 0), REGCM_FLAGS);
19210         if ((RHS(set, 0)->op != OP_CMP) &&
19211                 (RHS(set, 0)->op != OP_TEST)) {
19212                 internal_error(state, set, "bad set test");
19213         }
19214         if (RHS(set, 0)->next != set) {
19215                 internal_error(state, set, "set does not follow test");
19216         }
19217         switch(set->op) {
19218         case OP_SET_EQ:       sop = "setz";  break;
19219         case OP_SET_NOTEQ:    sop = "setnz"; break;
19220         case OP_SET_SLESS:    sop = "setl";  break;
19221         case OP_SET_ULESS:    sop = "setb";  break;
19222         case OP_SET_SMORE:    sop = "setg";  break;
19223         case OP_SET_UMORE:    sop = "seta";  break;
19224         case OP_SET_SLESSEQ:  sop = "setle"; break;
19225         case OP_SET_ULESSEQ:  sop = "setbe"; break;
19226         case OP_SET_SMOREEQ:  sop = "setge"; break;
19227         case OP_SET_UMOREEQ:  sop = "setae"; break;
19228         default:
19229                 internal_error(state, set, "Invalid set op");
19230                 break;
19231         }
19232         fprintf(fp, "\t%s %s\n",
19233                 sop, reg(state, set, REGCM_GPR8_LO));
19234 }
19235
19236 static void print_op_bit_scan(struct compile_state *state, 
19237         struct triple *ins, FILE *fp) 
19238 {
19239         const char *op;
19240         switch(ins->op) {
19241         case OP_BSF: op = "bsf"; break;
19242         case OP_BSR: op = "bsr"; break;
19243         default: 
19244                 internal_error(state, ins, "unknown bit scan");
19245                 op = 0;
19246                 break;
19247         }
19248         fprintf(fp, 
19249                 "\t%s %s, %s\n"
19250                 "\tjnz 1f\n"
19251                 "\tmovl $-1, %s\n"
19252                 "1:\n",
19253                 op,
19254                 reg(state, RHS(ins, 0), REGCM_GPR32),
19255                 reg(state, ins, REGCM_GPR32),
19256                 reg(state, ins, REGCM_GPR32));
19257 }
19258
19259
19260 static void print_sdecl(struct compile_state *state,
19261         struct triple *ins, FILE *fp)
19262 {
19263         fprintf(fp, ".section \"" DATA_SECTION "\"\n");
19264         fprintf(fp, ".balign %d\n", align_of(state, ins->type));
19265         fprintf(fp, "L%s%lu:\n", 
19266                 state->compiler->label_prefix, (unsigned long)(ins->u.cval));
19267         print_const(state, MISC(ins, 0), fp);
19268         fprintf(fp, ".section \"" TEXT_SECTION "\"\n");
19269                 
19270 }
19271
19272 static void print_instruction(struct compile_state *state,
19273         struct triple *ins, FILE *fp)
19274 {
19275         /* Assumption: after I have exted the register allocator
19276          * everything is in a valid register. 
19277          */
19278         switch(ins->op) {
19279         case OP_ASM:
19280                 print_op_asm(state, ins, fp);
19281                 break;
19282         case OP_ADD:    print_binary_op(state, "add", ins, fp); break;
19283         case OP_SUB:    print_binary_op(state, "sub", ins, fp); break;
19284         case OP_AND:    print_binary_op(state, "and", ins, fp); break;
19285         case OP_XOR:    print_binary_op(state, "xor", ins, fp); break;
19286         case OP_OR:     print_binary_op(state, "or",  ins, fp); break;
19287         case OP_SL:     print_op_shift(state, "shl", ins, fp); break;
19288         case OP_USR:    print_op_shift(state, "shr", ins, fp); break;
19289         case OP_SSR:    print_op_shift(state, "sar", ins, fp); break;
19290         case OP_POS:    break;
19291         case OP_NEG:    print_unary_op(state, "neg", ins, fp); break;
19292         case OP_INVERT: print_unary_op(state, "not", ins, fp); break;
19293         case OP_INTCONST:
19294         case OP_ADDRCONST:
19295         case OP_BLOBCONST:
19296                 /* Don't generate anything here for constants */
19297         case OP_PHI:
19298                 /* Don't generate anything for variable declarations. */
19299                 break;
19300         case OP_SDECL:
19301                 print_sdecl(state, ins, fp);
19302                 break;
19303         case OP_COPY:   
19304                 print_op_move(state, ins, fp);
19305                 break;
19306         case OP_LOAD:
19307                 print_op_load(state, ins, fp);
19308                 break;
19309         case OP_STORE:
19310                 print_op_store(state, ins, fp);
19311                 break;
19312         case OP_SMUL:
19313                 print_op_smul(state, ins, fp);
19314                 break;
19315         case OP_CMP:    print_op_cmp(state, ins, fp); break;
19316         case OP_TEST:   print_op_test(state, ins, fp); break;
19317         case OP_JMP:
19318         case OP_JMP_EQ:      case OP_JMP_NOTEQ:
19319         case OP_JMP_SLESS:   case OP_JMP_ULESS:
19320         case OP_JMP_SMORE:   case OP_JMP_UMORE:
19321         case OP_JMP_SLESSEQ: case OP_JMP_ULESSEQ:
19322         case OP_JMP_SMOREEQ: case OP_JMP_UMOREEQ:
19323         case OP_CALL:
19324                 print_op_branch(state, ins, fp);
19325                 break;
19326         case OP_RET:
19327                 print_op_ret(state, ins, fp);
19328                 break;
19329         case OP_SET_EQ:      case OP_SET_NOTEQ:
19330         case OP_SET_SLESS:   case OP_SET_ULESS:
19331         case OP_SET_SMORE:   case OP_SET_UMORE:
19332         case OP_SET_SLESSEQ: case OP_SET_ULESSEQ:
19333         case OP_SET_SMOREEQ: case OP_SET_UMOREEQ:
19334                 print_op_set(state, ins, fp);
19335                 break;
19336         case OP_INB:  case OP_INW:  case OP_INL:
19337                 print_op_in(state, ins, fp); 
19338                 break;
19339         case OP_OUTB: case OP_OUTW: case OP_OUTL:
19340                 print_op_out(state, ins, fp); 
19341                 break;
19342         case OP_BSF:
19343         case OP_BSR:
19344                 print_op_bit_scan(state, ins, fp);
19345                 break;
19346         case OP_RDMSR:
19347                 after_lhs(state, ins);
19348                 fprintf(fp, "\trdmsr\n");
19349                 break;
19350         case OP_WRMSR:
19351                 fprintf(fp, "\twrmsr\n");
19352                 break;
19353         case OP_HLT:
19354                 fprintf(fp, "\thlt\n");
19355                 break;
19356         case OP_SDIVT:
19357                 fprintf(fp, "\tidiv %s\n", reg(state, RHS(ins, 1), REGCM_GPR32));
19358                 break;
19359         case OP_UDIVT:
19360                 fprintf(fp, "\tdiv %s\n", reg(state, RHS(ins, 1), REGCM_GPR32));
19361                 break;
19362         case OP_UMUL:
19363                 fprintf(fp, "\tmul %s\n", reg(state, RHS(ins, 1), REGCM_GPR32));
19364                 break;
19365         case OP_LABEL:
19366                 if (!ins->use) {
19367                         return;
19368                 }
19369                 fprintf(fp, "L%s%lu:\n", 
19370                         state->compiler->label_prefix, (unsigned long)(ins->u.cval));
19371                 break;
19372                 /* Ignore OP_PIECE */
19373         case OP_PIECE:
19374                 break;
19375                 /* Operations that should never get here */
19376         case OP_SDIV: case OP_UDIV:
19377         case OP_SMOD: case OP_UMOD:
19378         case OP_LTRUE:   case OP_LFALSE:  case OP_EQ:      case OP_NOTEQ:
19379         case OP_SLESS:   case OP_ULESS:   case OP_SMORE:   case OP_UMORE:
19380         case OP_SLESSEQ: case OP_ULESSEQ: case OP_SMOREEQ: case OP_UMOREEQ:
19381         default:
19382                 internal_error(state, ins, "unknown op: %d %s",
19383                         ins->op, tops(ins->op));
19384                 break;
19385         }
19386 }
19387
19388 static void print_instructions(struct compile_state *state)
19389 {
19390         struct triple *first, *ins;
19391         int print_location;
19392         struct occurance *last_occurance;
19393         FILE *fp;
19394         int max_inline_depth;
19395         max_inline_depth = 0;
19396         print_location = 1;
19397         last_occurance = 0;
19398         fp = state->output;
19399         fprintf(fp, ".section \"" TEXT_SECTION "\"\n");
19400         first = state->first;
19401         ins = first;
19402         do {
19403                 if (print_location && 
19404                         last_occurance != ins->occurance) {
19405                         if (!ins->occurance->parent) {
19406                                 fprintf(fp, "\t/* %s,%s:%d.%d */\n",
19407                                         ins->occurance->function,
19408                                         ins->occurance->filename,
19409                                         ins->occurance->line,
19410                                         ins->occurance->col);
19411                         }
19412                         else {
19413                                 struct occurance *ptr;
19414                                 int inline_depth;
19415                                 fprintf(fp, "\t/*\n");
19416                                 inline_depth = 0;
19417                                 for(ptr = ins->occurance; ptr; ptr = ptr->parent) {
19418                                         inline_depth++;
19419                                         fprintf(fp, "\t * %s,%s:%d.%d\n",
19420                                                 ptr->function,
19421                                                 ptr->filename,
19422                                                 ptr->line,
19423                                                 ptr->col);
19424                                 }
19425                                 fprintf(fp, "\t */\n");
19426                                 if (inline_depth > max_inline_depth) {
19427                                         max_inline_depth = inline_depth;
19428                                 }
19429                         }
19430                         if (last_occurance) {
19431                                 put_occurance(last_occurance);
19432                         }
19433                         get_occurance(ins->occurance);
19434                         last_occurance = ins->occurance;
19435                 }
19436
19437                 print_instruction(state, ins, fp);
19438                 ins = ins->next;
19439         } while(ins != first);
19440         if (print_location) {
19441                 fprintf(fp, "/* max inline depth %d */\n",
19442                         max_inline_depth);
19443         }
19444 }
19445
19446 static void generate_code(struct compile_state *state)
19447 {
19448         generate_local_labels(state);
19449         print_instructions(state);
19450         
19451 }
19452
19453 static void print_tokens(struct compile_state *state)
19454 {
19455         struct token *tk;
19456         tk = &state->token[0];
19457         do {
19458 #if 1
19459                 token(state, 0);
19460 #else
19461                 next_token(state, 0);
19462 #endif
19463                 loc(stdout, state, 0);
19464                 printf("%s <- `%s'\n",
19465                         tokens[tk->tok],
19466                         tk->ident ? tk->ident->name :
19467                         tk->str_len ? tk->val.str : "");
19468                 
19469         } while(tk->tok != TOK_EOF);
19470 }
19471
19472 static void compile(const char *filename, 
19473         struct compiler_state *compiler, struct arch_state *arch)
19474 {
19475         int i;
19476         struct compile_state state;
19477         struct triple *ptr;
19478         memset(&state, 0, sizeof(state));
19479         state.compiler = compiler;
19480         state.arch     = arch;
19481         state.file = 0;
19482         for(i = 0; i < sizeof(state.token)/sizeof(state.token[0]); i++) {
19483                 memset(&state.token[i], 0, sizeof(state.token[i]));
19484                 state.token[i].tok = -1;
19485         }
19486         /* Remember the output filename */
19487         state.output    = fopen(state.compiler->ofilename, "w");
19488         if (!state.output) {
19489                 error(&state, 0, "Cannot open output file %s\n",
19490                         state.compiler->ofilename);
19491         }
19492         /* Prep the preprocessor */
19493         state.if_depth = 0;
19494         state.if_value = 0;
19495         /* register the C keywords */
19496         register_keywords(&state);
19497         /* register the keywords the macro preprocessor knows */
19498         register_macro_keywords(&state);
19499         /* Memorize where some special keywords are. */
19500         state.i_switch   = lookup(&state, "switch", 6);
19501         state.i_case     = lookup(&state, "case", 4);
19502         state.i_continue = lookup(&state, "continue", 8);
19503         state.i_break    = lookup(&state, "break", 5);
19504         state.i_default  = lookup(&state, "default", 7);
19505         state.i_return   = lookup(&state, "return", 6);
19506
19507         /* Allocate beginning bounding labels for the function list */
19508         state.first = label(&state);
19509         state.first->id |= TRIPLE_FLAG_VOLATILE;
19510         use_triple(state.first, state.first);
19511         ptr = label(&state);
19512         ptr->id |= TRIPLE_FLAG_VOLATILE;
19513         use_triple(ptr, ptr);
19514         flatten(&state, state.first, ptr);
19515
19516         /* Allocate a label for the pool of global variables */
19517         state.global_pool = label(&state);
19518         state.global_pool->id |= TRIPLE_FLAG_VOLATILE;
19519         flatten(&state, state.first, state.global_pool);
19520
19521
19522         /* Enter the globl definition scope */
19523         start_scope(&state);
19524         register_builtins(&state);
19525         compile_file(&state, filename, 1);
19526 #if 0
19527         print_tokens(&state);
19528 #endif  
19529         decls(&state);
19530
19531         /* Exit the global definition scope */
19532         end_scope(&state);
19533
19534         /* Join all of the functions into one giant function */
19535         join_functions(&state);
19536
19537         /* Now that basic compilation has happened 
19538          * optimize the intermediate code 
19539          */
19540         optimize(&state);
19541
19542         generate_code(&state);
19543         if (state.compiler->debug) {
19544                 fprintf(stderr, "done\n");
19545         }
19546 }
19547
19548 static void version(void)
19549 {
19550         printf("romcc " VERSION " released " RELEASE_DATE "\n");
19551 }
19552
19553 static void usage(void)
19554 {
19555         version();
19556         printf(
19557                 "Usage: romcc <source>.c\n"
19558                 "Compile a C source file without using ram\n"
19559         );
19560 }
19561
19562 static void arg_error(char *fmt, ...)
19563 {
19564         va_list args;
19565         va_start(args, fmt);
19566         vfprintf(stderr, fmt, args);
19567         va_end(args);
19568         usage();
19569         exit(1);
19570 }
19571
19572 int main(int argc, char **argv)
19573 {
19574         const char *filename;
19575         struct compiler_state compiler;
19576         struct arch_state arch;
19577         int all_opts;
19578         init_compiler_state(&compiler);
19579         init_arch_state(&arch);
19580         filename = 0;
19581         all_opts = 0;
19582         while(argc > 1) {
19583                 if (!all_opts && (strcmp(argv[1], "-o") == 0) && (argc > 2)) {
19584                         compiler.ofilename = argv[2];
19585                         argv += 2;
19586                         argc -= 2;
19587                 }
19588                 else if (!all_opts && argv[1][0] == '-') {
19589                         int result;
19590                         result = -1;
19591                         if (strcmp(argv[1], "--") == 0) {
19592                                 result = 0;
19593                                 all_opts = 1;
19594                         }
19595                         else if (strncmp(argv[1],"-O", 2) == 0) {
19596                                 result = compiler_encode_flag(&compiler, argv[1]);
19597                         }
19598                         else if (strncmp(argv[1], "--label-prefix=", 15) == 0) {
19599                                 result = compiler_encode_flag(&compiler, argv[1]+2);
19600                         }
19601                         else if (strncmp(argv[1], "-f", 2) == 0) {
19602                                 result = compiler_encode_flag(&compiler, argv[1]+2);
19603                         }
19604                         else if (strncmp(argv[1], "-m", 2) == 0) {
19605                                 result = arch_encode_flag(&arch, argv[1]+2);
19606                         }
19607                         if (result < 0) {
19608                                 arg_error("Invalid option specified: %s\n",
19609                                         argv[1]);
19610                         }
19611                         argv++;
19612                         argc--;
19613                 }
19614                 else {
19615                         if (filename) {
19616                                 arg_error("Only one filename may be specified\n");
19617                         }
19618                         filename = argv[1];
19619                         argv++;
19620                         argc--;
19621                 }
19622         }
19623         if (!filename) {
19624                 arg_error("No filename specified\n");
19625         }
19626         compile(filename, &compiler, &arch);
19627
19628         return 0;
19629 }