- Moved 2 of the test cases into tests for failure
[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 DEBUG_ERROR_MESSAGES 0
15 #define DEBUG_COLOR_GRAPH 0
16 #define DEBUG_SCC 0
17 #define DEBUG_CONSISTENCY 2
18 #define DEBUG_RANGE_CONFLICTS 0
19 #define DEBUG_COALESCING 0
20 #define DEBUG_SDP_BLOCKS 0
21 #define DEBUG_TRIPLE_COLOR 0
22
23 #warning "FIXME boundary cases with small types in larger registers"
24 #warning "FIXME give clear error messages about unused variables"
25 #warning "FIXME properly handle multi dimensional arrays"
26
27 /*  Control flow graph of a loop without goto.
28  * 
29  *        AAA
30  *   +---/
31  *  /
32  * / +--->CCC
33  * | |    / \
34  * | |  DDD EEE    break;
35  * | |    \    \
36  * | |    FFF   \
37  *  \|    / \    \
38  *   |\ GGG HHH   |   continue;
39  *   | \  \   |   |
40  *   |  \ III |  /
41  *   |   \ | /  / 
42  *   |    vvv  /  
43  *   +----BBB /   
44  *         | /
45  *         vv
46  *        JJJ
47  *
48  * 
49  *             AAA
50  *     +-----+  |  +----+
51  *     |      \ | /     |
52  *     |       BBB  +-+ |
53  *     |       / \ /  | |
54  *     |     CCC JJJ / /
55  *     |     / \    / / 
56  *     |   DDD EEE / /  
57  *     |    |   +-/ /
58  *     |   FFF     /    
59  *     |   / \    /     
60  *     | GGG HHH /      
61  *     |  |   +-/
62  *     | III
63  *     +--+ 
64  *
65  * 
66  * DFlocal(X) = { Y <- Succ(X) | idom(Y) != X }
67  * DFup(Z)    = { Y <- DF(Z) | idom(Y) != X }
68  *
69  *
70  * [] == DFlocal(X) U DF(X)
71  * () == DFup(X)
72  *
73  * Dominator graph of the same nodes.
74  *
75  *           AAA     AAA: [ ] ()
76  *          /   \
77  *        BBB    JJJ BBB: [ JJJ ] ( JJJ )  JJJ: [ ] ()
78  *         |
79  *        CCC        CCC: [ ] ( BBB, JJJ )
80  *        / \
81  *     DDD   EEE     DDD: [ ] ( BBB ) EEE: [ JJJ ] ()
82  *      |
83  *     FFF           FFF: [ ] ( BBB )
84  *     / \         
85  *  GGG   HHH        GGG: [ ] ( BBB ) HHH: [ BBB ] ()
86  *   |
87  *  III              III: [ BBB ] ()
88  *
89  *
90  * BBB and JJJ are definitely the dominance frontier.
91  * Where do I place phi functions and how do I make that decision.
92  *   
93  */
94 static void die(char *fmt, ...)
95 {
96         va_list args;
97
98         va_start(args, fmt);
99         vfprintf(stderr, fmt, args);
100         va_end(args);
101         fflush(stdout);
102         fflush(stderr);
103         exit(1);
104 }
105
106 #define MALLOC_STRONG_DEBUG
107 static void *xmalloc(size_t size, const char *name)
108 {
109         void *buf;
110         buf = malloc(size);
111         if (!buf) {
112                 die("Cannot malloc %ld bytes to hold %s: %s\n",
113                         size + 0UL, name, strerror(errno));
114         }
115         return buf;
116 }
117
118 static void *xcmalloc(size_t size, const char *name)
119 {
120         void *buf;
121         buf = xmalloc(size, name);
122         memset(buf, 0, size);
123         return buf;
124 }
125
126 static void xfree(const void *ptr)
127 {
128         free((void *)ptr);
129 }
130
131 static char *xstrdup(const char *str)
132 {
133         char *new;
134         int len;
135         len = strlen(str);
136         new = xmalloc(len + 1, "xstrdup string");
137         memcpy(new, str, len);
138         new[len] = '\0';
139         return new;
140 }
141
142 static void xchdir(const char *path)
143 {
144         if (chdir(path) != 0) {
145                 die("chdir to %s failed: %s\n",
146                         path, strerror(errno));
147         }
148 }
149
150 static int exists(const char *dirname, const char *filename)
151 {
152         int does_exist = 1;
153         xchdir(dirname);
154         if (access(filename, O_RDONLY) < 0) {
155                 if ((errno != EACCES) && (errno != EROFS)) {
156                         does_exist = 0;
157                 }
158         }
159         return does_exist;
160 }
161
162
163 static char *slurp_file(const char *dirname, const char *filename, off_t *r_size)
164 {
165         int fd;
166         char *buf;
167         off_t size, progress;
168         ssize_t result;
169         struct stat stats;
170         
171         if (!filename) {
172                 *r_size = 0;
173                 return 0;
174         }
175         xchdir(dirname);
176         fd = open(filename, O_RDONLY);
177         if (fd < 0) {
178                 die("Cannot open '%s' : %s\n",
179                         filename, strerror(errno));
180         }
181         result = fstat(fd, &stats);
182         if (result < 0) {
183                 die("Cannot stat: %s: %s\n",
184                         filename, strerror(errno));
185         }
186         size = stats.st_size;
187         *r_size = size +1;
188         buf = xmalloc(size +2, filename);
189         buf[size] = '\n'; /* Make certain the file is newline terminated */
190         buf[size+1] = '\0'; /* Null terminate the file for good measure */
191         progress = 0;
192         while(progress < size) {
193                 result = read(fd, buf + progress, size - progress);
194                 if (result < 0) {
195                         if ((errno == EINTR) || (errno == EAGAIN))
196                                 continue;
197                         die("read on %s of %ld bytes failed: %s\n",
198                                 filename, (size - progress)+ 0UL, strerror(errno));
199                 }
200                 progress += result;
201         }
202         result = close(fd);
203         if (result < 0) {
204                 die("Close of %s failed: %s\n",
205                         filename, strerror(errno));
206         }
207         return buf;
208 }
209
210 /* Long on the destination platform */
211 typedef unsigned long ulong_t;
212 typedef long long_t;
213
214 struct file_state {
215         struct file_state *prev;
216         const char *basename;
217         char *dirname;
218         char *buf;
219         off_t size;
220         char *pos;
221         int line;
222         char *line_start;
223         int report_line;
224         const char *report_name;
225         const char *report_dir;
226 };
227 struct hash_entry;
228 struct token {
229         int tok;
230         struct hash_entry *ident;
231         int str_len;
232         union {
233                 ulong_t integer;
234                 const char *str;
235         } val;
236 };
237
238 /* I have two classes of types:
239  * Operational types.
240  * Logical types.  (The type the C standard says the operation is of)
241  *
242  * The operational types are:
243  * chars
244  * shorts
245  * ints
246  * longs
247  *
248  * floats
249  * doubles
250  * long doubles
251  *
252  * pointer
253  */
254
255
256 /* Machine model.
257  * No memory is useable by the compiler.
258  * There is no floating point support.
259  * All operations take place in general purpose registers.
260  * There is one type of general purpose register.
261  * Unsigned longs are stored in that general purpose register.
262  */
263
264 /* Operations on general purpose registers.
265  */
266
267 #define OP_SDIVT      0
268 #define OP_UDIVT      1
269 #define OP_SMUL       2
270 #define OP_UMUL       3
271 #define OP_SDIV       4
272 #define OP_UDIV       5
273 #define OP_SMOD       6
274 #define OP_UMOD       7
275 #define OP_ADD        8
276 #define OP_SUB        9
277 #define OP_SL        10
278 #define OP_USR       11
279 #define OP_SSR       12 
280 #define OP_AND       13 
281 #define OP_XOR       14
282 #define OP_OR        15
283 #define OP_POS       16 /* Dummy positive operator don't use it */
284 #define OP_NEG       17
285 #define OP_INVERT    18
286                      
287 #define OP_EQ        20
288 #define OP_NOTEQ     21
289 #define OP_SLESS     22
290 #define OP_ULESS     23
291 #define OP_SMORE     24
292 #define OP_UMORE     25
293 #define OP_SLESSEQ   26
294 #define OP_ULESSEQ   27
295 #define OP_SMOREEQ   28
296 #define OP_UMOREEQ   29
297                      
298 #define OP_LFALSE    30  /* Test if the expression is logically false */
299 #define OP_LTRUE     31  /* Test if the expression is logcially true */
300
301 #define OP_LOAD      32
302 #define OP_STORE     33
303 /* For OP_STORE ->type holds the type
304  * RHS(0) holds the destination address
305  * RHS(1) holds the value to store.
306  */
307
308 #define OP_NOOP      34
309
310 #define OP_MIN_CONST 50
311 #define OP_MAX_CONST 59
312 #define IS_CONST_OP(X) (((X) >= OP_MIN_CONST) && ((X) <= OP_MAX_CONST))
313 #define OP_INTCONST  50
314 /* For OP_INTCONST ->type holds the type.
315  * ->u.cval holds the constant value.
316  */
317 #define OP_BLOBCONST 51
318 /* For OP_BLOBCONST ->type holds the layout and size
319  * information.  u.blob holds a pointer to the raw binary
320  * data for the constant initializer.
321  */
322 #define OP_ADDRCONST 52
323 /* For OP_ADDRCONST ->type holds the type.
324  * MISC(0) holds the reference to the static variable.
325  * ->u.cval holds an offset from that value.
326  */
327
328 #define OP_WRITE     60 
329 /* OP_WRITE moves one pseudo register to another.
330  * RHS(0) holds the destination pseudo register, which must be an OP_DECL.
331  * RHS(1) holds the psuedo to move.
332  */
333
334 #define OP_READ      61
335 /* OP_READ reads the value of a variable and makes
336  * it available for the pseudo operation.
337  * Useful for things like def-use chains.
338  * RHS(0) holds points to the triple to read from.
339  */
340 #define OP_COPY      62
341 /* OP_COPY makes a copy of the psedo register or constant in RHS(0).
342  */
343 #define OP_PIECE     63
344 /* OP_PIECE returns one piece of a instruction that returns a structure.
345  * MISC(0) is the instruction
346  * u.cval is the LHS piece of the instruction to return.
347  */
348 #define OP_ASM       64
349 /* OP_ASM holds a sequence of assembly instructions, the result
350  * of a C asm directive.
351  * RHS(x) holds input value x to the assembly sequence.
352  * LHS(x) holds the output value x from the assembly sequence.
353  * u.blob holds the string of assembly instructions.
354  */
355
356 #define OP_DEREF     65
357 /* OP_DEREF generates an lvalue from a pointer.
358  * RHS(0) holds the pointer value.
359  * OP_DEREF serves as a place holder to indicate all necessary
360  * checks have been done to indicate a value is an lvalue.
361  */
362 #define OP_DOT       66
363 /* OP_DOT references a submember of a structure lvalue.
364  * RHS(0) holds the lvalue.
365  * ->u.field holds the name of the field we want.
366  *
367  * Not seen outside of expressions.
368  */
369 #define OP_VAL       67
370 /* OP_VAL returns the value of a subexpression of the current expression.
371  * Useful for operators that have side effects.
372  * RHS(0) holds the expression.
373  * MISC(0) holds the subexpression of RHS(0) that is the
374  * value of the expression.
375  *
376  * Not seen outside of expressions.
377  */
378 #define OP_LAND      68
379 /* OP_LAND performs a C logical and between RHS(0) and RHS(1).
380  * Not seen outside of expressions.
381  */
382 #define OP_LOR       69
383 /* OP_LOR performs a C logical or between RHS(0) and RHS(1).
384  * Not seen outside of expressions.
385  */
386 #define OP_COND      70
387 /* OP_CODE performas a C ? : operation. 
388  * RHS(0) holds the test.
389  * RHS(1) holds the expression to evaluate if the test returns true.
390  * RHS(2) holds the expression to evaluate if the test returns false.
391  * Not seen outside of expressions.
392  */
393 #define OP_COMMA     71
394 /* OP_COMMA performacs a C comma operation.
395  * That is RHS(0) is evaluated, then RHS(1)
396  * and the value of RHS(1) is returned.
397  * Not seen outside of expressions.
398  */
399
400 #define OP_CALL      72
401 /* OP_CALL performs a procedure call. 
402  * MISC(0) holds a pointer to the OP_LIST of a function
403  * RHS(x) holds argument x of a function
404  * 
405  * Currently not seen outside of expressions.
406  */
407 #define OP_VAL_VEC   74
408 /* OP_VAL_VEC is an array of triples that are either variable
409  * or values for a structure or an array.
410  * RHS(x) holds element x of the vector.
411  * triple->type->elements holds the size of the vector.
412  */
413
414 /* statements */
415 #define OP_LIST      80
416 /* OP_LIST Holds a list of statements, and a result value.
417  * RHS(0) holds the list of statements.
418  * MISC(0) holds the value of the statements.
419  */
420
421 #define OP_BRANCH    81 /* branch */
422 /* For branch instructions
423  * TARG(0) holds the branch target.
424  * RHS(0) if present holds the branch condition.
425  * ->next holds where to branch to if the branch is not taken.
426  * The branch target can only be a decl...
427  */
428
429 #define OP_LABEL     83
430 /* OP_LABEL is a triple that establishes an target for branches.
431  * ->use is the list of all branches that use this label.
432  */
433
434 #define OP_ADECL     84 
435 /* OP_DECL is a triple that establishes an lvalue for assignments.
436  * ->use is a list of statements that use the variable.
437  */
438
439 #define OP_SDECL     85
440 /* OP_SDECL is a triple that establishes a variable of static
441  * storage duration.
442  * ->use is a list of statements that use the variable.
443  * MISC(0) holds the initializer expression.
444  */
445
446
447 #define OP_PHI       86
448 /* OP_PHI is a triple used in SSA form code.  
449  * It is used when multiple code paths merge and a variable needs
450  * a single assignment from any of those code paths.
451  * The operation is a cross between OP_DECL and OP_WRITE, which
452  * is what OP_PHI is geneared from.
453  * 
454  * RHS(x) points to the value from code path x
455  * The number of RHS entries is the number of control paths into the block
456  * in which OP_PHI resides.  The elements of the array point to point
457  * to the variables OP_PHI is derived from.
458  *
459  * MISC(0) holds a pointer to the orginal OP_DECL node.
460  */
461
462 /* Architecture specific instructions */
463 #define OP_CMP         100
464 #define OP_TEST        101
465 #define OP_SET_EQ      102
466 #define OP_SET_NOTEQ   103
467 #define OP_SET_SLESS   104
468 #define OP_SET_ULESS   105
469 #define OP_SET_SMORE   106
470 #define OP_SET_UMORE   107
471 #define OP_SET_SLESSEQ 108
472 #define OP_SET_ULESSEQ 109
473 #define OP_SET_SMOREEQ 110
474 #define OP_SET_UMOREEQ 111
475
476 #define OP_JMP         112
477 #define OP_JMP_EQ      113
478 #define OP_JMP_NOTEQ   114
479 #define OP_JMP_SLESS   115
480 #define OP_JMP_ULESS   116
481 #define OP_JMP_SMORE   117
482 #define OP_JMP_UMORE   118
483 #define OP_JMP_SLESSEQ 119
484 #define OP_JMP_ULESSEQ 120
485 #define OP_JMP_SMOREEQ 121
486 #define OP_JMP_UMOREEQ 122
487
488 /* Builtin operators that it is just simpler to use the compiler for */
489 #define OP_INB         130
490 #define OP_INW         131
491 #define OP_INL         132
492 #define OP_OUTB        133
493 #define OP_OUTW        134
494 #define OP_OUTL        135
495 #define OP_BSF         136
496 #define OP_BSR         137
497 #define OP_RDMSR       138
498 #define OP_WRMSR       139
499 #define OP_HLT         140
500
501 struct op_info {
502         const char *name;
503         unsigned flags;
504 #define PURE   1
505 #define IMPURE 2
506 #define PURE_BITS(FLAGS) ((FLAGS) & 0x3)
507 #define DEF    4
508 #define BLOCK  8 /* Triple stores the current block */
509         unsigned char lhs, rhs, misc, targ;
510 };
511
512 #define OP(LHS, RHS, MISC, TARG, FLAGS, NAME) { \
513         .name = (NAME), \
514         .flags = (FLAGS), \
515         .lhs = (LHS), \
516         .rhs = (RHS), \
517         .misc = (MISC), \
518         .targ = (TARG), \
519          }
520 static const struct op_info table_ops[] = {
521 [OP_SDIVT      ] = OP( 2,  2, 0, 0, PURE | BLOCK , "sdivt"),
522 [OP_UDIVT      ] = OP( 2,  2, 0, 0, PURE | BLOCK , "udivt"),
523 [OP_SMUL       ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "smul"),
524 [OP_UMUL       ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "umul"),
525 [OP_SDIV       ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "sdiv"),
526 [OP_UDIV       ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "udiv"),
527 [OP_SMOD       ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "smod"),
528 [OP_UMOD       ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "umod"),
529 [OP_ADD        ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "add"),
530 [OP_SUB        ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "sub"),
531 [OP_SL         ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "sl"),
532 [OP_USR        ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "usr"),
533 [OP_SSR        ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "ssr"),
534 [OP_AND        ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "and"),
535 [OP_XOR        ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "xor"),
536 [OP_OR         ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "or"),
537 [OP_POS        ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK , "pos"),
538 [OP_NEG        ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK , "neg"),
539 [OP_INVERT     ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK , "invert"),
540
541 [OP_EQ         ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "eq"),
542 [OP_NOTEQ      ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "noteq"),
543 [OP_SLESS      ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "sless"),
544 [OP_ULESS      ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "uless"),
545 [OP_SMORE      ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "smore"),
546 [OP_UMORE      ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "umore"),
547 [OP_SLESSEQ    ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "slesseq"),
548 [OP_ULESSEQ    ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "ulesseq"),
549 [OP_SMOREEQ    ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "smoreeq"),
550 [OP_UMOREEQ    ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "umoreeq"),
551 [OP_LFALSE     ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK , "lfalse"),
552 [OP_LTRUE      ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK , "ltrue"),
553
554 [OP_LOAD       ] = OP( 0,  1, 0, 0, IMPURE | DEF | BLOCK, "load"),
555 [OP_STORE      ] = OP( 0,  2, 0, 0, IMPURE | BLOCK , "store"),
556
557 [OP_NOOP       ] = OP( 0,  0, 0, 0, PURE | BLOCK, "noop"),
558
559 [OP_INTCONST   ] = OP( 0,  0, 0, 0, PURE | DEF, "intconst"),
560 [OP_BLOBCONST  ] = OP( 0,  0, 0, 0, PURE, "blobconst"),
561 [OP_ADDRCONST  ] = OP( 0,  0, 1, 0, PURE | DEF, "addrconst"),
562
563 [OP_WRITE      ] = OP( 0,  2, 0, 0, PURE | BLOCK, "write"),
564 [OP_READ       ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "read"),
565 [OP_COPY       ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "copy"),
566 [OP_PIECE      ] = OP( 0,  0, 1, 0, PURE | DEF, "piece"),
567 [OP_ASM        ] = OP(-1, -1, 0, 0, IMPURE, "asm"),
568 [OP_DEREF      ] = OP( 0,  1, 0, 0, 0 | DEF | BLOCK, "deref"), 
569 [OP_DOT        ] = OP( 0,  1, 0, 0, 0 | DEF | BLOCK, "dot"),
570
571 [OP_VAL        ] = OP( 0,  1, 1, 0, 0 | DEF | BLOCK, "val"),
572 [OP_LAND       ] = OP( 0,  2, 0, 0, 0 | DEF | BLOCK, "land"),
573 [OP_LOR        ] = OP( 0,  2, 0, 0, 0 | DEF | BLOCK, "lor"),
574 [OP_COND       ] = OP( 0,  3, 0, 0, 0 | DEF | BLOCK, "cond"),
575 [OP_COMMA      ] = OP( 0,  2, 0, 0, 0 | DEF | BLOCK, "comma"),
576 /* Call is special most it can stand in for anything so it depends on context */
577 [OP_CALL       ] = OP(-1, -1, 1, 0, 0 | BLOCK, "call"),
578 /* The sizes of OP_CALL and OP_VAL_VEC depend upon context */
579 [OP_VAL_VEC    ] = OP( 0, -1, 0, 0, 0 | BLOCK, "valvec"),
580
581 [OP_LIST       ] = OP( 0,  1, 1, 0, 0 | DEF, "list"),
582 /* The number of targets for OP_BRANCH depends on context */
583 [OP_BRANCH     ] = OP( 0, -1, 0, 1, PURE | BLOCK, "branch"),
584 [OP_LABEL      ] = OP( 0,  0, 0, 0, PURE | BLOCK, "label"),
585 [OP_ADECL      ] = OP( 0,  0, 0, 0, PURE | BLOCK, "adecl"),
586 [OP_SDECL      ] = OP( 0,  0, 1, 0, PURE | BLOCK, "sdecl"),
587 /* The number of RHS elements of OP_PHI depend upon context */
588 [OP_PHI        ] = OP( 0, -1, 1, 0, PURE | DEF | BLOCK, "phi"),
589
590 [OP_CMP        ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK, "cmp"),
591 [OP_TEST       ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "test"),
592 [OP_SET_EQ     ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_eq"),
593 [OP_SET_NOTEQ  ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_noteq"),
594 [OP_SET_SLESS  ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_sless"),
595 [OP_SET_ULESS  ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_uless"),
596 [OP_SET_SMORE  ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_smore"),
597 [OP_SET_UMORE  ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_umore"),
598 [OP_SET_SLESSEQ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_slesseq"),
599 [OP_SET_ULESSEQ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_ulesseq"),
600 [OP_SET_SMOREEQ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_smoreq"),
601 [OP_SET_UMOREEQ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_umoreq"),
602 [OP_JMP        ] = OP( 0,  0, 0, 1, PURE | BLOCK, "jmp"),
603 [OP_JMP_EQ     ] = OP( 0,  1, 0, 1, PURE | BLOCK, "jmp_eq"),
604 [OP_JMP_NOTEQ  ] = OP( 0,  1, 0, 1, PURE | BLOCK, "jmp_noteq"),
605 [OP_JMP_SLESS  ] = OP( 0,  1, 0, 1, PURE | BLOCK, "jmp_sless"),
606 [OP_JMP_ULESS  ] = OP( 0,  1, 0, 1, PURE | BLOCK, "jmp_uless"),
607 [OP_JMP_SMORE  ] = OP( 0,  1, 0, 1, PURE | BLOCK, "jmp_smore"),
608 [OP_JMP_UMORE  ] = OP( 0,  1, 0, 1, PURE | BLOCK, "jmp_umore"),
609 [OP_JMP_SLESSEQ] = OP( 0,  1, 0, 1, PURE | BLOCK, "jmp_slesseq"),
610 [OP_JMP_ULESSEQ] = OP( 0,  1, 0, 1, PURE | BLOCK, "jmp_ulesseq"),
611 [OP_JMP_SMOREEQ] = OP( 0,  1, 0, 1, PURE | BLOCK, "jmp_smoreq"),
612 [OP_JMP_UMOREEQ] = OP( 0,  1, 0, 1, PURE | BLOCK, "jmp_umoreq"),
613
614 [OP_INB        ] = OP( 0,  1, 0, 0, IMPURE | DEF | BLOCK, "__inb"),
615 [OP_INW        ] = OP( 0,  1, 0, 0, IMPURE | DEF | BLOCK, "__inw"),
616 [OP_INL        ] = OP( 0,  1, 0, 0, IMPURE | DEF | BLOCK, "__inl"),
617 [OP_OUTB       ] = OP( 0,  2, 0, 0, IMPURE| BLOCK, "__outb"),
618 [OP_OUTW       ] = OP( 0,  2, 0, 0, IMPURE| BLOCK, "__outw"),
619 [OP_OUTL       ] = OP( 0,  2, 0, 0, IMPURE| BLOCK, "__outl"),
620 [OP_BSF        ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "__bsf"),
621 [OP_BSR        ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "__bsr"),
622 [OP_RDMSR      ] = OP( 2,  1, 0, 0, IMPURE | BLOCK, "__rdmsr"),
623 [OP_WRMSR      ] = OP( 0,  3, 0, 0, IMPURE | BLOCK, "__wrmsr"),
624 [OP_HLT        ] = OP( 0,  0, 0, 0, IMPURE | BLOCK, "__hlt"),
625 };
626 #undef OP
627 #define OP_MAX      (sizeof(table_ops)/sizeof(table_ops[0]))
628
629 static const char *tops(int index) 
630 {
631         static const char unknown[] = "unknown op";
632         if (index < 0) {
633                 return unknown;
634         }
635         if (index > OP_MAX) {
636                 return unknown;
637         }
638         return table_ops[index].name;
639 }
640
641 struct asm_info;
642 struct triple;
643 struct block;
644 struct triple_set {
645         struct triple_set *next;
646         struct triple *member;
647 };
648
649 #define MAX_LHS  15
650 #define MAX_RHS  250
651 #define MAX_MISC 3
652 #define MAX_TARG 3
653
654 struct occurance {
655         int count;
656         const char *filename;
657         const char *function;
658         int line;
659         int col;
660         struct occurance *parent;
661 };
662 struct triple {
663         struct triple *next, *prev;
664         struct triple_set *use;
665         struct type *type;
666         unsigned char op;
667         unsigned char template_id;
668         unsigned short sizes;
669 #define TRIPLE_LHS(SIZES)  (((SIZES) >>  0) & 0x0f)
670 #define TRIPLE_RHS(SIZES)  (((SIZES) >>  4) & 0xff)
671 #define TRIPLE_MISC(SIZES) (((SIZES) >> 12) & 0x03)
672 #define TRIPLE_TARG(SIZES) (((SIZES) >> 14) & 0x03)
673 #define TRIPLE_SIZE(SIZES) \
674         (TRIPLE_LHS(SIZES)  + \
675          TRIPLE_RHS(SIZES)  + \
676          TRIPLE_MISC(SIZES) + \
677          TRIPLE_TARG(SIZES))
678 #define TRIPLE_SIZES(LHS, RHS, MISC, TARG) \
679         ((((LHS) & 0x0f) <<  0) | \
680         (((RHS)  & 0xff) <<  4) | \
681         (((MISC) & 0x03) << 12) | \
682         (((TARG) & 0x03) << 14))
683 #define TRIPLE_LHS_OFF(SIZES)  (0)
684 #define TRIPLE_RHS_OFF(SIZES)  (TRIPLE_LHS_OFF(SIZES) + TRIPLE_LHS(SIZES))
685 #define TRIPLE_MISC_OFF(SIZES) (TRIPLE_RHS_OFF(SIZES) + TRIPLE_RHS(SIZES))
686 #define TRIPLE_TARG_OFF(SIZES) (TRIPLE_MISC_OFF(SIZES) + TRIPLE_MISC(SIZES))
687 #define LHS(PTR,INDEX) ((PTR)->param[TRIPLE_LHS_OFF((PTR)->sizes) + (INDEX)])
688 #define RHS(PTR,INDEX) ((PTR)->param[TRIPLE_RHS_OFF((PTR)->sizes) + (INDEX)])
689 #define TARG(PTR,INDEX) ((PTR)->param[TRIPLE_TARG_OFF((PTR)->sizes) + (INDEX)])
690 #define MISC(PTR,INDEX) ((PTR)->param[TRIPLE_MISC_OFF((PTR)->sizes) + (INDEX)])
691         unsigned id; /* A scratch value and finally the register */
692 #define TRIPLE_FLAG_FLATTENED   (1 << 31)
693 #define TRIPLE_FLAG_PRE_SPLIT   (1 << 30)
694 #define TRIPLE_FLAG_POST_SPLIT  (1 << 29)
695         struct occurance *occurance;
696         union {
697                 ulong_t cval;
698                 struct block  *block;
699                 void *blob;
700                 struct hash_entry *field;
701                 struct asm_info *ainfo;
702         } u;
703         struct triple *param[2];
704 };
705
706 struct reg_info {
707         unsigned reg;
708         unsigned regcm;
709 };
710 struct ins_template {
711         struct reg_info lhs[MAX_LHS + 1], rhs[MAX_RHS + 1];
712 };
713
714 struct asm_info {
715         struct ins_template tmpl;
716         char *str;
717 };
718
719 struct block_set {
720         struct block_set *next;
721         struct block *member;
722 };
723 struct block {
724         struct block *work_next;
725         struct block *left, *right;
726         struct triple *first, *last;
727         int users;
728         struct block_set *use;
729         struct block_set *idominates;
730         struct block_set *domfrontier;
731         struct block *idom;
732         struct block_set *ipdominates;
733         struct block_set *ipdomfrontier;
734         struct block *ipdom;
735         int vertex;
736         
737 };
738
739 struct symbol {
740         struct symbol *next;
741         struct hash_entry *ident;
742         struct triple *def;
743         struct type *type;
744         int scope_depth;
745 };
746
747 struct macro {
748         struct hash_entry *ident;
749         char *buf;
750         int buf_len;
751 };
752
753 struct hash_entry {
754         struct hash_entry *next;
755         const char *name;
756         int name_len;
757         int tok;
758         struct macro *sym_define;
759         struct symbol *sym_label;
760         struct symbol *sym_struct;
761         struct symbol *sym_ident;
762 };
763
764 #define HASH_TABLE_SIZE 2048
765
766 struct compile_state {
767         const char *label_prefix;
768         const char *ofilename;
769         FILE *output;
770         struct file_state *file;
771         struct occurance *last_occurance;
772         const char *function;
773         struct token token[4];
774         struct hash_entry *hash_table[HASH_TABLE_SIZE];
775         struct hash_entry *i_continue;
776         struct hash_entry *i_break;
777         int scope_depth;
778         int if_depth, if_value;
779         int macro_line;
780         struct file_state *macro_file;
781         struct triple *main_function;
782         struct block *first_block, *last_block;
783         int last_vertex;
784         int cpu;
785         int debug;
786         int optimize;
787 };
788
789 /* visibility global/local */
790 /* static/auto duration */
791 /* typedef, register, inline */
792 #define STOR_SHIFT         0
793 #define STOR_MASK     0x000f
794 /* Visibility */
795 #define STOR_GLOBAL   0x0001
796 /* Duration */
797 #define STOR_PERM     0x0002
798 /* Storage specifiers */
799 #define STOR_AUTO     0x0000
800 #define STOR_STATIC   0x0002
801 #define STOR_EXTERN   0x0003
802 #define STOR_REGISTER 0x0004
803 #define STOR_TYPEDEF  0x0008
804 #define STOR_INLINE   0x000c
805
806 #define QUAL_SHIFT         4
807 #define QUAL_MASK     0x0070
808 #define QUAL_NONE     0x0000
809 #define QUAL_CONST    0x0010
810 #define QUAL_VOLATILE 0x0020
811 #define QUAL_RESTRICT 0x0040
812
813 #define TYPE_SHIFT         8
814 #define TYPE_MASK     0x1f00
815 #define TYPE_INTEGER(TYPE)    (((TYPE) >= TYPE_CHAR) && ((TYPE) <= TYPE_ULLONG))
816 #define TYPE_ARITHMETIC(TYPE) (((TYPE) >= TYPE_CHAR) && ((TYPE) <= TYPE_LDOUBLE))
817 #define TYPE_UNSIGNED(TYPE)   ((TYPE) & 0x0100)
818 #define TYPE_SIGNED(TYPE)     (!TYPE_UNSIGNED(TYPE))
819 #define TYPE_MKUNSIGNED(TYPE) ((TYPE) | 0x0100)
820 #define TYPE_RANK(TYPE)       ((TYPE) & ~0x0100)
821 #define TYPE_PTR(TYPE)        (((TYPE) & TYPE_MASK) == TYPE_POINTER)
822 #define TYPE_DEFAULT  0x0000
823 #define TYPE_VOID     0x0100
824 #define TYPE_CHAR     0x0200
825 #define TYPE_UCHAR    0x0300
826 #define TYPE_SHORT    0x0400
827 #define TYPE_USHORT   0x0500
828 #define TYPE_INT      0x0600
829 #define TYPE_UINT     0x0700
830 #define TYPE_LONG     0x0800
831 #define TYPE_ULONG    0x0900
832 #define TYPE_LLONG    0x0a00 /* long long */
833 #define TYPE_ULLONG   0x0b00
834 #define TYPE_FLOAT    0x0c00
835 #define TYPE_DOUBLE   0x0d00
836 #define TYPE_LDOUBLE  0x0e00 /* long double */
837 #define TYPE_STRUCT   0x1000
838 #define TYPE_ENUM     0x1100
839 #define TYPE_POINTER  0x1200 
840 /* For TYPE_POINTER:
841  * type->left holds the type pointed to.
842  */
843 #define TYPE_FUNCTION 0x1300 
844 /* For TYPE_FUNCTION:
845  * type->left holds the return type.
846  * type->right holds the...
847  */
848 #define TYPE_PRODUCT  0x1400
849 /* TYPE_PRODUCT is a basic building block when defining structures
850  * type->left holds the type that appears first in memory.
851  * type->right holds the type that appears next in memory.
852  */
853 #define TYPE_OVERLAP  0x1500
854 /* TYPE_OVERLAP is a basic building block when defining unions
855  * type->left and type->right holds to types that overlap
856  * each other in memory.
857  */
858 #define TYPE_ARRAY    0x1600
859 /* TYPE_ARRAY is a basic building block when definitng arrays.
860  * type->left holds the type we are an array of.
861  * type-> holds the number of elements.
862  */
863
864 #define ELEMENT_COUNT_UNSPECIFIED (~0UL)
865
866 struct type {
867         unsigned int type;
868         struct type *left, *right;
869         ulong_t elements;
870         struct hash_entry *field_ident;
871         struct hash_entry *type_ident;
872 };
873
874 #define MAX_REGISTERS      75
875 #define MAX_REG_EQUIVS     16
876 #define REGISTER_BITS      16
877 #define MAX_VIRT_REGISTERS (1<<REGISTER_BITS)
878 #define TEMPLATE_BITS      7
879 #define MAX_TEMPLATES      (1<<TEMPLATE_BITS)
880 #define MAX_REGC           14
881 #define REG_UNSET          0
882 #define REG_UNNEEDED       1
883 #define REG_VIRT0          (MAX_REGISTERS + 0)
884 #define REG_VIRT1          (MAX_REGISTERS + 1)
885 #define REG_VIRT2          (MAX_REGISTERS + 2)
886 #define REG_VIRT3          (MAX_REGISTERS + 3)
887 #define REG_VIRT4          (MAX_REGISTERS + 4)
888 #define REG_VIRT5          (MAX_REGISTERS + 5)
889 #define REG_VIRT6          (MAX_REGISTERS + 5)
890 #define REG_VIRT7          (MAX_REGISTERS + 5)
891 #define REG_VIRT8          (MAX_REGISTERS + 5)
892 #define REG_VIRT9          (MAX_REGISTERS + 5)
893
894 /* Provision for 8 register classes */
895 #define REG_SHIFT  0
896 #define REGC_SHIFT REGISTER_BITS
897 #define REGC_MASK (((1 << MAX_REGC) - 1) << REGISTER_BITS)
898 #define REG_MASK (MAX_VIRT_REGISTERS -1)
899 #define ID_REG(ID)              ((ID) & REG_MASK)
900 #define SET_REG(ID, REG)        ((ID) = (((ID) & ~REG_MASK) | ((REG) & REG_MASK)))
901 #define ID_REGCM(ID)            (((ID) & REGC_MASK) >> REGC_SHIFT)
902 #define SET_REGCM(ID, REGCM)    ((ID) = (((ID) & ~REGC_MASK) | (((REGCM) << REGC_SHIFT) & REGC_MASK)))
903 #define SET_INFO(ID, INFO)      ((ID) = (((ID) & ~(REG_MASK | REGC_MASK)) | \
904                 (((INFO).reg) & REG_MASK) | ((((INFO).regcm) << REGC_SHIFT) & REGC_MASK)))
905
906 static unsigned arch_reg_regcm(struct compile_state *state, int reg);
907 static unsigned arch_regcm_normalize(struct compile_state *state, unsigned regcm);
908 static unsigned arch_regcm_reg_normalize(struct compile_state *state, unsigned regcm);
909 static void arch_reg_equivs(
910         struct compile_state *state, unsigned *equiv, int reg);
911 static int arch_select_free_register(
912         struct compile_state *state, char *used, int classes);
913 static unsigned arch_regc_size(struct compile_state *state, int class);
914 static int arch_regcm_intersect(unsigned regcm1, unsigned regcm2);
915 static unsigned arch_type_to_regcm(struct compile_state *state, struct type *type);
916 static const char *arch_reg_str(int reg);
917 static struct reg_info arch_reg_constraint(
918         struct compile_state *state, struct type *type, const char *constraint);
919 static struct reg_info arch_reg_clobber(
920         struct compile_state *state, const char *clobber);
921 static struct reg_info arch_reg_lhs(struct compile_state *state, 
922         struct triple *ins, int index);
923 static struct reg_info arch_reg_rhs(struct compile_state *state, 
924         struct triple *ins, int index);
925 static struct triple *transform_to_arch_instruction(
926         struct compile_state *state, struct triple *ins);
927
928
929
930 #define DEBUG_ABORT_ON_ERROR    0x0001
931 #define DEBUG_INTERMEDIATE_CODE 0x0002
932 #define DEBUG_CONTROL_FLOW      0x0004
933 #define DEBUG_BASIC_BLOCKS      0x0008
934 #define DEBUG_FDOMINATORS       0x0010
935 #define DEBUG_RDOMINATORS       0x0020
936 #define DEBUG_TRIPLES           0x0040
937 #define DEBUG_INTERFERENCE      0x0080
938 #define DEBUG_ARCH_CODE         0x0100
939 #define DEBUG_CODE_ELIMINATION  0x0200
940 #define DEBUG_INSERTED_COPIES   0x0400
941
942 #define GLOBAL_SCOPE_DEPTH   1
943 #define FUNCTION_SCOPE_DEPTH (GLOBAL_SCOPE_DEPTH + 1)
944
945 static void compile_file(struct compile_state *old_state, const char *filename, int local);
946
947 static void do_cleanup(struct compile_state *state)
948 {
949         if (state->output) {
950                 fclose(state->output);
951                 unlink(state->ofilename);
952         }
953 }
954
955 static int get_col(struct file_state *file)
956 {
957         int col;
958         char *ptr, *end;
959         ptr = file->line_start;
960         end = file->pos;
961         for(col = 0; ptr < end; ptr++) {
962                 if (*ptr != '\t') {
963                         col++;
964                 } 
965                 else {
966                         col = (col & ~7) + 8;
967                 }
968         }
969         return col;
970 }
971
972 static void loc(FILE *fp, struct compile_state *state, struct triple *triple)
973 {
974         int col;
975         if (triple && triple->occurance) {
976                 struct occurance *spot;
977                 spot = triple->occurance;
978                 while(spot->parent) {
979                         spot = spot->parent;
980                 }
981                 fprintf(fp, "%s:%d.%d: ", 
982                         spot->filename, spot->line, spot->col);
983                 return;
984         }
985         if (!state->file) {
986                 return;
987         }
988         col = get_col(state->file);
989         fprintf(fp, "%s:%d.%d: ", 
990                 state->file->report_name, state->file->report_line, col);
991 }
992
993 static void __internal_error(struct compile_state *state, struct triple *ptr, 
994         char *fmt, ...)
995 {
996         va_list args;
997         va_start(args, fmt);
998         loc(stderr, state, ptr);
999         if (ptr) {
1000                 fprintf(stderr, "%p %s ", ptr, tops(ptr->op));
1001         }
1002         fprintf(stderr, "Internal compiler error: ");
1003         vfprintf(stderr, fmt, args);
1004         fprintf(stderr, "\n");
1005         va_end(args);
1006         do_cleanup(state);
1007         abort();
1008 }
1009
1010
1011 static void __internal_warning(struct compile_state *state, struct triple *ptr, 
1012         char *fmt, ...)
1013 {
1014         va_list args;
1015         va_start(args, fmt);
1016         loc(stderr, state, ptr);
1017         if (ptr) {
1018                 fprintf(stderr, "%p %s ", ptr, tops(ptr->op));
1019         }
1020         fprintf(stderr, "Internal compiler warning: ");
1021         vfprintf(stderr, fmt, args);
1022         fprintf(stderr, "\n");
1023         va_end(args);
1024 }
1025
1026
1027
1028 static void __error(struct compile_state *state, struct triple *ptr, 
1029         char *fmt, ...)
1030 {
1031         va_list args;
1032         va_start(args, fmt);
1033         loc(stderr, state, ptr);
1034         vfprintf(stderr, fmt, args);
1035         va_end(args);
1036         fprintf(stderr, "\n");
1037         do_cleanup(state);
1038         if (state->debug & DEBUG_ABORT_ON_ERROR) {
1039                 abort();
1040         }
1041         exit(1);
1042 }
1043
1044 static void __warning(struct compile_state *state, struct triple *ptr, 
1045         char *fmt, ...)
1046 {
1047         va_list args;
1048         va_start(args, fmt);
1049         loc(stderr, state, ptr);
1050         fprintf(stderr, "warning: "); 
1051         vfprintf(stderr, fmt, args);
1052         fprintf(stderr, "\n");
1053         va_end(args);
1054 }
1055
1056 #if DEBUG_ERROR_MESSAGES 
1057 #  define internal_error fprintf(stderr,  "@ %s.%s:%d \t", __FILE__, __func__, __LINE__),__internal_error
1058 #  define internal_warning fprintf(stderr,  "@ %s.%s:%d \t", __FILE__, __func__, __LINE__),__internal_warning
1059 #  define error fprintf(stderr, "@ %s.%s:%d \t", __FILE__, __func__, __LINE__),__error
1060 #  define warning fprintf(stderr, "@ %s.%s:%d \t", __FILE__, __func__, __LINE__),__warning
1061 #else
1062 #  define internal_error __internal_error
1063 #  define internal_warning __internal_warning
1064 #  define error __error
1065 #  define warning __warning
1066 #endif
1067 #define FINISHME() warning(state, 0, "FINISHME @ %s.%s:%d", __FILE__, __func__, __LINE__)
1068
1069 static void valid_op(struct compile_state *state, int op)
1070 {
1071         char *fmt = "invalid op: %d";
1072         if (op >= OP_MAX) {
1073                 internal_error(state, 0, fmt, op);
1074         }
1075         if (op < 0) {
1076                 internal_error(state, 0, fmt, op);
1077         }
1078 }
1079
1080 static void valid_ins(struct compile_state *state, struct triple *ptr)
1081 {
1082         valid_op(state, ptr->op);
1083 }
1084
1085 static void process_trigraphs(struct compile_state *state)
1086 {
1087         char *src, *dest, *end;
1088         struct file_state *file;
1089         file = state->file;
1090         src = dest = file->buf;
1091         end = file->buf + file->size;
1092         while((end - src) >= 3) {
1093                 if ((src[0] == '?') && (src[1] == '?')) {
1094                         int c = -1;
1095                         switch(src[2]) {
1096                         case '=': c = '#'; break;
1097                         case '/': c = '\\'; break;
1098                         case '\'': c = '^'; break;
1099                         case '(': c = '['; break;
1100                         case ')': c = ']'; break;
1101                         case '!': c = '!'; break;
1102                         case '<': c = '{'; break;
1103                         case '>': c = '}'; break;
1104                         case '-': c = '~'; break;
1105                         }
1106                         if (c != -1) {
1107                                 *dest++ = c;
1108                                 src += 3;
1109                         }
1110                         else {
1111                                 *dest++ = *src++;
1112                         }
1113                 }
1114                 else {
1115                         *dest++ = *src++;
1116                 }
1117         }
1118         while(src != end) {
1119                 *dest++ = *src++;
1120         }
1121         file->size = dest - file->buf;
1122 }
1123
1124 static void splice_lines(struct compile_state *state)
1125 {
1126         char *src, *dest, *end;
1127         struct file_state *file;
1128         file = state->file;
1129         src = dest = file->buf;
1130         end = file->buf + file->size;
1131         while((end - src) >= 2) {
1132                 if ((src[0] == '\\') && (src[1] == '\n')) {
1133                         src += 2;
1134                 }
1135                 else {
1136                         *dest++ = *src++;
1137                 }
1138         }
1139         while(src != end) {
1140                 *dest++ = *src++;
1141         }
1142         file->size = dest - file->buf;
1143 }
1144
1145 static struct type void_type;
1146 static void use_triple(struct triple *used, struct triple *user)
1147 {
1148         struct triple_set **ptr, *new;
1149         if (!used)
1150                 return;
1151         if (!user)
1152                 return;
1153         ptr = &used->use;
1154         while(*ptr) {
1155                 if ((*ptr)->member == user) {
1156                         return;
1157                 }
1158                 ptr = &(*ptr)->next;
1159         }
1160         /* Append new to the head of the list, 
1161          * copy_func and rename_block_variables
1162          * depends on this.
1163          */
1164         new = xcmalloc(sizeof(*new), "triple_set");
1165         new->member = user;
1166         new->next   = used->use;
1167         used->use   = new;
1168 }
1169
1170 static void unuse_triple(struct triple *used, struct triple *unuser)
1171 {
1172         struct triple_set *use, **ptr;
1173         if (!used) {
1174                 return;
1175         }
1176         ptr = &used->use;
1177         while(*ptr) {
1178                 use = *ptr;
1179                 if (use->member == unuser) {
1180                         *ptr = use->next;
1181                         xfree(use);
1182                 }
1183                 else {
1184                         ptr = &use->next;
1185                 }
1186         }
1187 }
1188
1189 static void put_occurance(struct occurance *occurance)
1190 {
1191         occurance->count -= 1;
1192         if (occurance->count <= 0) {
1193                 if (occurance->parent) {
1194                         put_occurance(occurance->parent);
1195                 }
1196                 xfree(occurance);
1197         }
1198 }
1199
1200 static void get_occurance(struct occurance *occurance)
1201 {
1202         occurance->count += 1;
1203 }
1204
1205
1206 static struct occurance *new_occurance(struct compile_state *state)
1207 {
1208         struct occurance *result, *last;
1209         const char *filename;
1210         const char *function;
1211         int line, col;
1212
1213         function = "";
1214         filename = 0;
1215         line = 0;
1216         col  = 0;
1217         if (state->file) {
1218                 filename = state->file->report_name;
1219                 line     = state->file->report_line;
1220                 col      = get_col(state->file);
1221         }
1222         if (state->function) {
1223                 function = state->function;
1224         }
1225         last = state->last_occurance;
1226         if (last &&
1227                 (last->col == col) &&
1228                 (last->line == line) &&
1229                 (last->function == function) &&
1230                 (strcmp(last->filename, filename) == 0)) {
1231                 get_occurance(last);
1232                 return last;
1233         }
1234         if (last) {
1235                 state->last_occurance = 0;
1236                 put_occurance(last);
1237         }
1238         result = xmalloc(sizeof(*result), "occurance");
1239         result->count    = 2;
1240         result->filename = filename;
1241         result->function = function;
1242         result->line     = line;
1243         result->col      = col;
1244         result->parent   = 0;
1245         state->last_occurance = result;
1246         return result;
1247 }
1248
1249 static struct occurance *inline_occurance(struct compile_state *state,
1250         struct occurance *new, struct occurance *orig)
1251 {
1252         struct occurance *result, *last;
1253         last = state->last_occurance;
1254         if (last &&
1255                 (last->parent   == orig) &&
1256                 (last->col      == new->col) &&
1257                 (last->line     == new->line) &&
1258                 (last->function == new->function) &&
1259                 (last->filename == new->filename)) {
1260                 get_occurance(last);
1261                 return last;
1262         }
1263         if (last) {
1264                 state->last_occurance = 0;
1265                 put_occurance(last);
1266         }
1267         get_occurance(orig);
1268         result = xmalloc(sizeof(*result), "occurance");
1269         result->count    = 2;
1270         result->filename = new->filename;
1271         result->function = new->function;
1272         result->line     = new->line;
1273         result->col      = new->col;
1274         result->parent   = orig;
1275         state->last_occurance = result;
1276         return result;
1277 }
1278         
1279
1280 static struct occurance dummy_occurance = {
1281         .count    = 2,
1282         .filename = __FILE__,
1283         .function = "",
1284         .line     = __LINE__,
1285         .col      = 0,
1286         .parent   = 0,
1287 };
1288
1289 /* The zero triple is used as a place holder when we are removing pointers
1290  * from a triple.  Having allows certain sanity checks to pass even
1291  * when the original triple that was pointed to is gone.
1292  */
1293 static struct triple zero_triple = {
1294         .next      = &zero_triple,
1295         .prev      = &zero_triple,
1296         .use       = 0,
1297         .op        = OP_INTCONST,
1298         .sizes     = TRIPLE_SIZES(0, 0, 0, 0),
1299         .id        = -1, /* An invalid id */
1300         .u = { .cval = 0, },
1301         .occurance = &dummy_occurance,
1302         .param = { [0] = 0, [1] = 0, },
1303 };
1304
1305
1306 static unsigned short triple_sizes(struct compile_state *state,
1307         int op, struct type *type, int lhs_wanted, int rhs_wanted,
1308         struct occurance *occurance)
1309 {
1310         int lhs, rhs, misc, targ;
1311         struct triple dummy;
1312         dummy.op = op;
1313         dummy.occurance = occurance;
1314         valid_op(state, op);
1315         lhs = table_ops[op].lhs;
1316         rhs = table_ops[op].rhs;
1317         misc = table_ops[op].misc;
1318         targ = table_ops[op].targ;
1319         
1320         
1321         if (op == OP_CALL) {
1322                 struct type *param;
1323                 rhs = 0;
1324                 param = type->right;
1325                 while((param->type & TYPE_MASK) == TYPE_PRODUCT) {
1326                         rhs++;
1327                         param = param->right;
1328                 }
1329                 if ((param->type & TYPE_MASK) != TYPE_VOID) {
1330                         rhs++;
1331                 }
1332                 lhs = 0;
1333                 if ((type->left->type & TYPE_MASK) == TYPE_STRUCT) {
1334                         lhs = type->left->elements;
1335                 }
1336         }
1337         else if (op == OP_VAL_VEC) {
1338                 rhs = type->elements;
1339         }
1340         else if ((op == OP_BRANCH) || (op == OP_PHI)) {
1341                 rhs = rhs_wanted;
1342         }
1343         else if (op == OP_ASM) {
1344                 rhs = rhs_wanted;
1345                 lhs = lhs_wanted;
1346         }
1347         if ((rhs < 0) || (rhs > MAX_RHS)) {
1348                 internal_error(state, &dummy, "bad rhs %d", rhs);
1349         }
1350         if ((lhs < 0) || (lhs > MAX_LHS)) {
1351                 internal_error(state, &dummy, "bad lhs");
1352         }
1353         if ((misc < 0) || (misc > MAX_MISC)) {
1354                 internal_error(state, &dummy, "bad misc");
1355         }
1356         if ((targ < 0) || (targ > MAX_TARG)) {
1357                 internal_error(state, &dummy, "bad targs");
1358         }
1359         return TRIPLE_SIZES(lhs, rhs, misc, targ);
1360 }
1361
1362 static struct triple *alloc_triple(struct compile_state *state, 
1363         int op, struct type *type, int lhs, int rhs,
1364         struct occurance *occurance)
1365 {
1366         size_t size, sizes, extra_count, min_count;
1367         struct triple *ret;
1368         sizes = triple_sizes(state, op, type, lhs, rhs, occurance);
1369
1370         min_count = sizeof(ret->param)/sizeof(ret->param[0]);
1371         extra_count = TRIPLE_SIZE(sizes);
1372         extra_count = (extra_count < min_count)? 0 : extra_count - min_count;
1373
1374         size = sizeof(*ret) + sizeof(ret->param[0]) * extra_count;
1375         ret = xcmalloc(size, "tripple");
1376         ret->op        = op;
1377         ret->sizes     = sizes;
1378         ret->type      = type;
1379         ret->next      = ret;
1380         ret->prev      = ret;
1381         ret->occurance = occurance;
1382         return ret;
1383 }
1384
1385 struct triple *dup_triple(struct compile_state *state, struct triple *src)
1386 {
1387         struct triple *dup;
1388         int src_lhs, src_rhs, src_size;
1389         src_lhs = TRIPLE_LHS(src->sizes);
1390         src_rhs = TRIPLE_RHS(src->sizes);
1391         src_size = TRIPLE_SIZE(src->sizes);
1392         get_occurance(src->occurance);
1393         dup = alloc_triple(state, src->op, src->type, src_lhs, src_rhs,
1394                 src->occurance);
1395         memcpy(dup, src, sizeof(*src));
1396         memcpy(dup->param, src->param, src_size * sizeof(src->param[0]));
1397         return dup;
1398 }
1399
1400 static struct triple *new_triple(struct compile_state *state, 
1401         int op, struct type *type, int lhs, int rhs)
1402 {
1403         struct triple *ret;
1404         struct occurance *occurance;
1405         occurance = new_occurance(state);
1406         ret = alloc_triple(state, op, type, lhs, rhs, occurance);
1407         return ret;
1408 }
1409
1410 static struct triple *build_triple(struct compile_state *state, 
1411         int op, struct type *type, struct triple *left, struct triple *right,
1412         struct occurance *occurance)
1413 {
1414         struct triple *ret;
1415         size_t count;
1416         ret = alloc_triple(state, op, type, -1, -1, occurance);
1417         count = TRIPLE_SIZE(ret->sizes);
1418         if (count > 0) {
1419                 ret->param[0] = left;
1420         }
1421         if (count > 1) {
1422                 ret->param[1] = right;
1423         }
1424         return ret;
1425 }
1426
1427 static struct triple *triple(struct compile_state *state, 
1428         int op, struct type *type, struct triple *left, struct triple *right)
1429 {
1430         struct triple *ret;
1431         size_t count;
1432         ret = new_triple(state, op, type, -1, -1);
1433         count = TRIPLE_SIZE(ret->sizes);
1434         if (count >= 1) {
1435                 ret->param[0] = left;
1436         }
1437         if (count >= 2) {
1438                 ret->param[1] = right;
1439         }
1440         return ret;
1441 }
1442
1443 static struct triple *branch(struct compile_state *state, 
1444         struct triple *targ, struct triple *test)
1445 {
1446         struct triple *ret;
1447         ret = new_triple(state, OP_BRANCH, &void_type, -1, test?1:0);
1448         if (test) {
1449                 RHS(ret, 0) = test;
1450         }
1451         TARG(ret, 0) = targ;
1452         /* record the branch target was used */
1453         if (!targ || (targ->op != OP_LABEL)) {
1454                 internal_error(state, 0, "branch not to label");
1455                 use_triple(targ, ret);
1456         }
1457         return ret;
1458 }
1459
1460
1461 static void insert_triple(struct compile_state *state,
1462         struct triple *first, struct triple *ptr)
1463 {
1464         if (ptr) {
1465                 if ((ptr->id & TRIPLE_FLAG_FLATTENED) || (ptr->next != ptr)) {
1466                         internal_error(state, ptr, "expression already used");
1467                 }
1468                 ptr->next       = first;
1469                 ptr->prev       = first->prev;
1470                 ptr->prev->next = ptr;
1471                 ptr->next->prev = ptr;
1472                 if ((ptr->prev->op == OP_BRANCH) && 
1473                         TRIPLE_RHS(ptr->prev->sizes)) {
1474                         unuse_triple(first, ptr->prev);
1475                         use_triple(ptr, ptr->prev);
1476                 }
1477         }
1478 }
1479
1480 static int triple_stores_block(struct compile_state *state, struct triple *ins)
1481 {
1482         /* This function is used to determine if u.block 
1483          * is utilized to store the current block number.
1484          */
1485         int stores_block;
1486         valid_ins(state, ins);
1487         stores_block = (table_ops[ins->op].flags & BLOCK) == BLOCK;
1488         return stores_block;
1489 }
1490
1491 static struct block *block_of_triple(struct compile_state *state, 
1492         struct triple *ins)
1493 {
1494         struct triple *first;
1495         first = RHS(state->main_function, 0);
1496         while(ins != first && !triple_stores_block(state, ins)) {
1497                 if (ins == ins->prev) {
1498                         internal_error(state, 0, "ins == ins->prev?");
1499                 }
1500                 ins = ins->prev;
1501         }
1502         if (!triple_stores_block(state, ins)) {
1503                 internal_error(state, ins, "Cannot find block");
1504         }
1505         return ins->u.block;
1506 }
1507
1508 static struct triple *pre_triple(struct compile_state *state,
1509         struct triple *base,
1510         int op, struct type *type, struct triple *left, struct triple *right)
1511 {
1512         struct block *block;
1513         struct triple *ret;
1514         /* If I am an OP_PIECE jump to the real instruction */
1515         if (base->op == OP_PIECE) {
1516                 base = MISC(base, 0);
1517         }
1518         block = block_of_triple(state, base);
1519         get_occurance(base->occurance);
1520         ret = build_triple(state, op, type, left, right, base->occurance);
1521         if (triple_stores_block(state, ret)) {
1522                 ret->u.block = block;
1523         }
1524         insert_triple(state, base, ret);
1525         if (block->first == base) {
1526                 block->first = ret;
1527         }
1528         return ret;
1529 }
1530
1531 static struct triple *post_triple(struct compile_state *state,
1532         struct triple *base,
1533         int op, struct type *type, struct triple *left, struct triple *right)
1534 {
1535         struct block *block;
1536         struct triple *ret;
1537         int zlhs;
1538         /* If I am an OP_PIECE jump to the real instruction */
1539         if (base->op == OP_PIECE) {
1540                 base = MISC(base, 0);
1541         }
1542         /* If I have a left hand side skip over it */
1543         zlhs = TRIPLE_LHS(base->sizes);
1544         if (zlhs) {
1545                 base = LHS(base, zlhs - 1);
1546         }
1547
1548         block = block_of_triple(state, base);
1549         get_occurance(base->occurance);
1550         ret = build_triple(state, op, type, left, right, base->occurance);
1551         if (triple_stores_block(state, ret)) {
1552                 ret->u.block = block;
1553         }
1554         insert_triple(state, base->next, ret);
1555         if (block->last == base) {
1556                 block->last = ret;
1557         }
1558         return ret;
1559 }
1560
1561 static struct triple *label(struct compile_state *state)
1562 {
1563         /* Labels don't get a type */
1564         struct triple *result;
1565         result = triple(state, OP_LABEL, &void_type, 0, 0);
1566         return result;
1567 }
1568
1569 static void display_triple(FILE *fp, struct triple *ins)
1570 {
1571         struct occurance *ptr;
1572         const char *reg;
1573         char pre, post;
1574         pre = post = ' ';
1575         if (ins->id & TRIPLE_FLAG_PRE_SPLIT) {
1576                 pre = '^';
1577         }
1578         if (ins->id & TRIPLE_FLAG_POST_SPLIT) {
1579                 post = 'v';
1580         }
1581         reg = arch_reg_str(ID_REG(ins->id));
1582         if (ins->op == OP_INTCONST) {
1583                 fprintf(fp, "(%p) %c%c %-7s %-2d %-10s <0x%08lx>         ",
1584                         ins, pre, post, reg, ins->template_id, tops(ins->op), 
1585                         ins->u.cval);
1586         }
1587         else if (ins->op == OP_ADDRCONST) {
1588                 fprintf(fp, "(%p) %c%c %-7s %-2d %-10s %-10p <0x%08lx>",
1589                         ins, pre, post, reg, ins->template_id, tops(ins->op), 
1590                         MISC(ins, 0), ins->u.cval);
1591         }
1592         else {
1593                 int i, count;
1594                 fprintf(fp, "(%p) %c%c %-7s %-2d %-10s", 
1595                         ins, pre, post, reg, ins->template_id, tops(ins->op));
1596                 count = TRIPLE_SIZE(ins->sizes);
1597                 for(i = 0; i < count; i++) {
1598                         fprintf(fp, " %-10p", ins->param[i]);
1599                 }
1600                 for(; i < 2; i++) {
1601                         fprintf(fp, "           ");
1602                 }
1603         }
1604         fprintf(fp, " @");
1605         for(ptr = ins->occurance; ptr; ptr = ptr->parent) {
1606                 fprintf(fp, " %s,%s:%d.%d",
1607                         ptr->function, 
1608                         ptr->filename,
1609                         ptr->line, 
1610                         ptr->col);
1611         }
1612         fprintf(fp, "\n");
1613 #if 0
1614         {
1615                 struct triple_set *user;
1616                 for(user = ptr->use; user; user = user->next) {
1617                         fprintf(fp, "use: %p\n", user->member);
1618                 }
1619         }
1620 #endif
1621         fflush(fp);
1622 }
1623
1624 static int triple_is_pure(struct compile_state *state, struct triple *ins)
1625 {
1626         /* Does the triple have no side effects.
1627          * I.e. Rexecuting the triple with the same arguments 
1628          * gives the same value.
1629          */
1630         unsigned pure;
1631         valid_ins(state, ins);
1632         pure = PURE_BITS(table_ops[ins->op].flags);
1633         if ((pure != PURE) && (pure != IMPURE)) {
1634                 internal_error(state, 0, "Purity of %s not known\n",
1635                         tops(ins->op));
1636         }
1637         return pure == PURE;
1638 }
1639
1640 static int triple_is_branch(struct compile_state *state, struct triple *ins)
1641 {
1642         /* This function is used to determine which triples need
1643          * a register.
1644          */
1645         int is_branch;
1646         valid_ins(state, ins);
1647         is_branch = (table_ops[ins->op].targ != 0);
1648         return is_branch;
1649 }
1650
1651 static int triple_is_cond_branch(struct compile_state *state, struct triple *ins)
1652 {
1653         /* A conditional branch has the condition argument as a single
1654          * RHS parameter.
1655          */
1656         return triple_is_branch(state, ins) &&
1657                 (TRIPLE_RHS(ins->sizes) == 1);
1658 }
1659
1660 static int triple_is_uncond_branch(struct compile_state *state, struct triple *ins)
1661 {
1662         /* A unconditional branch has no RHS parameters.
1663          */
1664         return triple_is_branch(state, ins) &&
1665                 (TRIPLE_RHS(ins->sizes) == 0);
1666 }
1667
1668 static int triple_is_def(struct compile_state *state, struct triple *ins)
1669 {
1670         /* This function is used to determine which triples need
1671          * a register.
1672          */
1673         int is_def;
1674         valid_ins(state, ins);
1675         is_def = (table_ops[ins->op].flags & DEF) == DEF;
1676         return is_def;
1677 }
1678
1679 static struct triple **triple_iter(struct compile_state *state,
1680         size_t count, struct triple **vector,
1681         struct triple *ins, struct triple **last)
1682 {
1683         struct triple **ret;
1684         ret = 0;
1685         if (count) {
1686                 if (!last) {
1687                         ret = vector;
1688                 }
1689                 else if ((last >= vector) && (last < (vector + count - 1))) {
1690                         ret = last + 1;
1691                 }
1692         }
1693         return ret;
1694         
1695 }
1696
1697 static struct triple **triple_lhs(struct compile_state *state,
1698         struct triple *ins, struct triple **last)
1699 {
1700         return triple_iter(state, TRIPLE_LHS(ins->sizes), &LHS(ins,0), 
1701                 ins, last);
1702 }
1703
1704 static struct triple **triple_rhs(struct compile_state *state,
1705         struct triple *ins, struct triple **last)
1706 {
1707         return triple_iter(state, TRIPLE_RHS(ins->sizes), &RHS(ins,0), 
1708                 ins, last);
1709 }
1710
1711 static struct triple **triple_misc(struct compile_state *state,
1712         struct triple *ins, struct triple **last)
1713 {
1714         return triple_iter(state, TRIPLE_MISC(ins->sizes), &MISC(ins,0), 
1715                 ins, last);
1716 }
1717
1718 static struct triple **triple_targ(struct compile_state *state,
1719         struct triple *ins, struct triple **last)
1720 {
1721         size_t count;
1722         struct triple **ret, **vector;
1723         ret = 0;
1724         count = TRIPLE_TARG(ins->sizes);
1725         vector = &TARG(ins, 0);
1726         if (count) {
1727                 if (!last) {
1728                         ret = vector;
1729                 }
1730                 else if ((last >= vector) && (last < (vector + count - 1))) {
1731                         ret = last + 1;
1732                 }
1733                 else if ((last == (vector + count - 1)) && 
1734                         TRIPLE_RHS(ins->sizes)) {
1735                         ret = &ins->next;
1736                 }
1737         }
1738         return ret;
1739 }
1740
1741
1742 static void verify_use(struct compile_state *state,
1743         struct triple *user, struct triple *used)
1744 {
1745         int size, i;
1746         size = TRIPLE_SIZE(user->sizes);
1747         for(i = 0; i < size; i++) {
1748                 if (user->param[i] == used) {
1749                         break;
1750                 }
1751         }
1752         if (triple_is_branch(state, user)) {
1753                 if (user->next == used) {
1754                         i = -1;
1755                 }
1756         }
1757         if (i == size) {
1758                 internal_error(state, user, "%s(%p) does not use %s(%p)",
1759                         tops(user->op), user, tops(used->op), used);
1760         }
1761 }
1762
1763 static int find_rhs_use(struct compile_state *state, 
1764         struct triple *user, struct triple *used)
1765 {
1766         struct triple **param;
1767         int size, i;
1768         verify_use(state, user, used);
1769         size = TRIPLE_RHS(user->sizes);
1770         param = &RHS(user, 0);
1771         for(i = 0; i < size; i++) {
1772                 if (param[i] == used) {
1773                         return i;
1774                 }
1775         }
1776         return -1;
1777 }
1778
1779 static void free_triple(struct compile_state *state, struct triple *ptr)
1780 {
1781         size_t size;
1782         size = sizeof(*ptr) - sizeof(ptr->param) +
1783                 (sizeof(ptr->param[0])*TRIPLE_SIZE(ptr->sizes));
1784         ptr->prev->next = ptr->next;
1785         ptr->next->prev = ptr->prev;
1786         if (ptr->use) {
1787                 internal_error(state, ptr, "ptr->use != 0");
1788         }
1789         put_occurance(ptr->occurance);
1790         memset(ptr, -1, size);
1791         xfree(ptr);
1792 }
1793
1794 static void release_triple(struct compile_state *state, struct triple *ptr)
1795 {
1796         struct triple_set *set, *next;
1797         struct triple **expr;
1798         struct block *block;
1799         /* Make certain the we are not the first or last element of a block */
1800         block = block_of_triple(state, ptr);
1801         if (block && (block->last == ptr)) {
1802                 block->last = ptr->prev;
1803         }
1804         if (block && (block->first == ptr)) {
1805                 block->first = ptr->next;
1806         }
1807         /* Remove ptr from use chains where it is the user */
1808         expr = triple_rhs(state, ptr, 0);
1809         for(; expr; expr = triple_rhs(state, ptr, expr)) {
1810                 if (*expr) {
1811                         unuse_triple(*expr, ptr);
1812                 }
1813         }
1814         expr = triple_lhs(state, ptr, 0);
1815         for(; expr; expr = triple_lhs(state, ptr, expr)) {
1816                 if (*expr) {
1817                         unuse_triple(*expr, ptr);
1818                 }
1819         }
1820         expr = triple_misc(state, ptr, 0);
1821         for(; expr; expr = triple_misc(state, ptr, expr)) {
1822                 if (*expr) {
1823                         unuse_triple(*expr, ptr);
1824                 }
1825         }
1826         expr = triple_targ(state, ptr, 0);
1827         for(; expr; expr = triple_targ(state, ptr, expr)) {
1828                 if (*expr) {
1829                         unuse_triple(*expr, ptr);
1830                 }
1831         }
1832         /* Reomve ptr from use chains where it is used */
1833         for(set = ptr->use; set; set = next) {
1834                 next = set->next;
1835                 expr = triple_rhs(state, set->member, 0);
1836                 for(; expr; expr = triple_rhs(state, set->member, expr)) {
1837                         if (*expr == ptr) {
1838                                 *expr = &zero_triple;
1839                         }
1840                 }
1841                 expr = triple_lhs(state, set->member, 0);
1842                 for(; expr; expr = triple_lhs(state, set->member, expr)) {
1843                         if (*expr == ptr) {
1844                                 *expr = &zero_triple;
1845                         }
1846                 }
1847                 expr = triple_misc(state, set->member, 0);
1848                 for(; expr; expr = triple_misc(state, set->member, expr)) {
1849                         if (*expr == ptr) {
1850                                 *expr = &zero_triple;
1851                         }
1852                 }
1853                 expr = triple_targ(state, set->member, 0);
1854                 for(; expr; expr = triple_targ(state, set->member, expr)) {
1855                         if (*expr == ptr) {
1856                                 *expr = &zero_triple;
1857                         }
1858                 }
1859                 unuse_triple(ptr, set->member);
1860         }
1861         free_triple(state, ptr);
1862 }
1863
1864 static void print_triple(struct compile_state *state, struct triple *ptr);
1865
1866 #define TOK_UNKNOWN     0
1867 #define TOK_SPACE       1
1868 #define TOK_SEMI        2
1869 #define TOK_LBRACE      3
1870 #define TOK_RBRACE      4
1871 #define TOK_COMMA       5
1872 #define TOK_EQ          6
1873 #define TOK_COLON       7
1874 #define TOK_LBRACKET    8
1875 #define TOK_RBRACKET    9
1876 #define TOK_LPAREN      10
1877 #define TOK_RPAREN      11
1878 #define TOK_STAR        12
1879 #define TOK_DOTS        13
1880 #define TOK_MORE        14
1881 #define TOK_LESS        15
1882 #define TOK_TIMESEQ     16
1883 #define TOK_DIVEQ       17
1884 #define TOK_MODEQ       18
1885 #define TOK_PLUSEQ      19
1886 #define TOK_MINUSEQ     20
1887 #define TOK_SLEQ        21
1888 #define TOK_SREQ        22
1889 #define TOK_ANDEQ       23
1890 #define TOK_XOREQ       24
1891 #define TOK_OREQ        25
1892 #define TOK_EQEQ        26
1893 #define TOK_NOTEQ       27
1894 #define TOK_QUEST       28
1895 #define TOK_LOGOR       29
1896 #define TOK_LOGAND      30
1897 #define TOK_OR          31
1898 #define TOK_AND         32
1899 #define TOK_XOR         33
1900 #define TOK_LESSEQ      34
1901 #define TOK_MOREEQ      35
1902 #define TOK_SL          36
1903 #define TOK_SR          37
1904 #define TOK_PLUS        38
1905 #define TOK_MINUS       39
1906 #define TOK_DIV         40
1907 #define TOK_MOD         41
1908 #define TOK_PLUSPLUS    42
1909 #define TOK_MINUSMINUS  43
1910 #define TOK_BANG        44
1911 #define TOK_ARROW       45
1912 #define TOK_DOT         46
1913 #define TOK_TILDE       47
1914 #define TOK_LIT_STRING  48
1915 #define TOK_LIT_CHAR    49
1916 #define TOK_LIT_INT     50
1917 #define TOK_LIT_FLOAT   51
1918 #define TOK_MACRO       52
1919 #define TOK_CONCATENATE 53
1920
1921 #define TOK_IDENT       54
1922 #define TOK_STRUCT_NAME 55
1923 #define TOK_ENUM_CONST  56
1924 #define TOK_TYPE_NAME   57
1925
1926 #define TOK_AUTO        58
1927 #define TOK_BREAK       59
1928 #define TOK_CASE        60
1929 #define TOK_CHAR        61
1930 #define TOK_CONST       62
1931 #define TOK_CONTINUE    63
1932 #define TOK_DEFAULT     64
1933 #define TOK_DO          65
1934 #define TOK_DOUBLE      66
1935 #define TOK_ELSE        67
1936 #define TOK_ENUM        68
1937 #define TOK_EXTERN      69
1938 #define TOK_FLOAT       70
1939 #define TOK_FOR         71
1940 #define TOK_GOTO        72
1941 #define TOK_IF          73
1942 #define TOK_INLINE      74
1943 #define TOK_INT         75
1944 #define TOK_LONG        76
1945 #define TOK_REGISTER    77
1946 #define TOK_RESTRICT    78
1947 #define TOK_RETURN      79
1948 #define TOK_SHORT       80
1949 #define TOK_SIGNED      81
1950 #define TOK_SIZEOF      82
1951 #define TOK_STATIC      83
1952 #define TOK_STRUCT      84
1953 #define TOK_SWITCH      85
1954 #define TOK_TYPEDEF     86
1955 #define TOK_UNION       87
1956 #define TOK_UNSIGNED    88
1957 #define TOK_VOID        89
1958 #define TOK_VOLATILE    90
1959 #define TOK_WHILE       91
1960 #define TOK_ASM         92
1961 #define TOK_ATTRIBUTE   93
1962 #define TOK_ALIGNOF     94
1963 #define TOK_FIRST_KEYWORD TOK_AUTO
1964 #define TOK_LAST_KEYWORD  TOK_ALIGNOF
1965
1966 #define TOK_DEFINE      100
1967 #define TOK_UNDEF       101
1968 #define TOK_INCLUDE     102
1969 #define TOK_LINE        103
1970 #define TOK_ERROR       104
1971 #define TOK_WARNING     105
1972 #define TOK_PRAGMA      106
1973 #define TOK_IFDEF       107
1974 #define TOK_IFNDEF      108
1975 #define TOK_ELIF        109
1976 #define TOK_ENDIF       110
1977
1978 #define TOK_FIRST_MACRO TOK_DEFINE
1979 #define TOK_LAST_MACRO  TOK_ENDIF
1980          
1981 #define TOK_EOF         111
1982
1983 static const char *tokens[] = {
1984 [TOK_UNKNOWN     ] = "unknown",
1985 [TOK_SPACE       ] = ":space:",
1986 [TOK_SEMI        ] = ";",
1987 [TOK_LBRACE      ] = "{",
1988 [TOK_RBRACE      ] = "}",
1989 [TOK_COMMA       ] = ",",
1990 [TOK_EQ          ] = "=",
1991 [TOK_COLON       ] = ":",
1992 [TOK_LBRACKET    ] = "[",
1993 [TOK_RBRACKET    ] = "]",
1994 [TOK_LPAREN      ] = "(",
1995 [TOK_RPAREN      ] = ")",
1996 [TOK_STAR        ] = "*",
1997 [TOK_DOTS        ] = "...",
1998 [TOK_MORE        ] = ">",
1999 [TOK_LESS        ] = "<",
2000 [TOK_TIMESEQ     ] = "*=",
2001 [TOK_DIVEQ       ] = "/=",
2002 [TOK_MODEQ       ] = "%=",
2003 [TOK_PLUSEQ      ] = "+=",
2004 [TOK_MINUSEQ     ] = "-=",
2005 [TOK_SLEQ        ] = "<<=",
2006 [TOK_SREQ        ] = ">>=",
2007 [TOK_ANDEQ       ] = "&=",
2008 [TOK_XOREQ       ] = "^=",
2009 [TOK_OREQ        ] = "|=",
2010 [TOK_EQEQ        ] = "==",
2011 [TOK_NOTEQ       ] = "!=",
2012 [TOK_QUEST       ] = "?",
2013 [TOK_LOGOR       ] = "||",
2014 [TOK_LOGAND      ] = "&&",
2015 [TOK_OR          ] = "|",
2016 [TOK_AND         ] = "&",
2017 [TOK_XOR         ] = "^",
2018 [TOK_LESSEQ      ] = "<=",
2019 [TOK_MOREEQ      ] = ">=",
2020 [TOK_SL          ] = "<<",
2021 [TOK_SR          ] = ">>",
2022 [TOK_PLUS        ] = "+",
2023 [TOK_MINUS       ] = "-",
2024 [TOK_DIV         ] = "/",
2025 [TOK_MOD         ] = "%",
2026 [TOK_PLUSPLUS    ] = "++",
2027 [TOK_MINUSMINUS  ] = "--",
2028 [TOK_BANG        ] = "!",
2029 [TOK_ARROW       ] = "->",
2030 [TOK_DOT         ] = ".",
2031 [TOK_TILDE       ] = "~",
2032 [TOK_LIT_STRING  ] = ":string:",
2033 [TOK_IDENT       ] = ":ident:",
2034 [TOK_TYPE_NAME   ] = ":typename:",
2035 [TOK_LIT_CHAR    ] = ":char:",
2036 [TOK_LIT_INT     ] = ":integer:",
2037 [TOK_LIT_FLOAT   ] = ":float:",
2038 [TOK_MACRO       ] = "#",
2039 [TOK_CONCATENATE ] = "##",
2040
2041 [TOK_AUTO        ] = "auto",
2042 [TOK_BREAK       ] = "break",
2043 [TOK_CASE        ] = "case",
2044 [TOK_CHAR        ] = "char",
2045 [TOK_CONST       ] = "const",
2046 [TOK_CONTINUE    ] = "continue",
2047 [TOK_DEFAULT     ] = "default",
2048 [TOK_DO          ] = "do",
2049 [TOK_DOUBLE      ] = "double",
2050 [TOK_ELSE        ] = "else",
2051 [TOK_ENUM        ] = "enum",
2052 [TOK_EXTERN      ] = "extern",
2053 [TOK_FLOAT       ] = "float",
2054 [TOK_FOR         ] = "for",
2055 [TOK_GOTO        ] = "goto",
2056 [TOK_IF          ] = "if",
2057 [TOK_INLINE      ] = "inline",
2058 [TOK_INT         ] = "int",
2059 [TOK_LONG        ] = "long",
2060 [TOK_REGISTER    ] = "register",
2061 [TOK_RESTRICT    ] = "restrict",
2062 [TOK_RETURN      ] = "return",
2063 [TOK_SHORT       ] = "short",
2064 [TOK_SIGNED      ] = "signed",
2065 [TOK_SIZEOF      ] = "sizeof",
2066 [TOK_STATIC      ] = "static",
2067 [TOK_STRUCT      ] = "struct",
2068 [TOK_SWITCH      ] = "switch",
2069 [TOK_TYPEDEF     ] = "typedef",
2070 [TOK_UNION       ] = "union",
2071 [TOK_UNSIGNED    ] = "unsigned",
2072 [TOK_VOID        ] = "void",
2073 [TOK_VOLATILE    ] = "volatile",
2074 [TOK_WHILE       ] = "while",
2075 [TOK_ASM         ] = "asm",
2076 [TOK_ATTRIBUTE   ] = "__attribute__",
2077 [TOK_ALIGNOF     ] = "__alignof__",
2078
2079 [TOK_DEFINE      ] = "define",
2080 [TOK_UNDEF       ] = "undef",
2081 [TOK_INCLUDE     ] = "include",
2082 [TOK_LINE        ] = "line",
2083 [TOK_ERROR       ] = "error",
2084 [TOK_WARNING     ] = "warning",
2085 [TOK_PRAGMA      ] = "pragma",
2086 [TOK_IFDEF       ] = "ifdef",
2087 [TOK_IFNDEF      ] = "ifndef",
2088 [TOK_ELIF        ] = "elif",
2089 [TOK_ENDIF       ] = "endif",
2090
2091 [TOK_EOF         ] = "EOF",
2092 };
2093
2094 static unsigned int hash(const char *str, int str_len)
2095 {
2096         unsigned int hash;
2097         const char *end;
2098         end = str + str_len;
2099         hash = 0;
2100         for(; str < end; str++) {
2101                 hash = (hash *263) + *str;
2102         }
2103         hash = hash & (HASH_TABLE_SIZE -1);
2104         return hash;
2105 }
2106
2107 static struct hash_entry *lookup(
2108         struct compile_state *state, const char *name, int name_len)
2109 {
2110         struct hash_entry *entry;
2111         unsigned int index;
2112         index = hash(name, name_len);
2113         entry = state->hash_table[index];
2114         while(entry && 
2115                 ((entry->name_len != name_len) ||
2116                         (memcmp(entry->name, name, name_len) != 0))) {
2117                 entry = entry->next;
2118         }
2119         if (!entry) {
2120                 char *new_name;
2121                 /* Get a private copy of the name */
2122                 new_name = xmalloc(name_len + 1, "hash_name");
2123                 memcpy(new_name, name, name_len);
2124                 new_name[name_len] = '\0';
2125
2126                 /* Create a new hash entry */
2127                 entry = xcmalloc(sizeof(*entry), "hash_entry");
2128                 entry->next = state->hash_table[index];
2129                 entry->name = new_name;
2130                 entry->name_len = name_len;
2131
2132                 /* Place the new entry in the hash table */
2133                 state->hash_table[index] = entry;
2134         }
2135         return entry;
2136 }
2137
2138 static void ident_to_keyword(struct compile_state *state, struct token *tk)
2139 {
2140         struct hash_entry *entry;
2141         entry = tk->ident;
2142         if (entry && ((entry->tok == TOK_TYPE_NAME) ||
2143                 (entry->tok == TOK_ENUM_CONST) ||
2144                 ((entry->tok >= TOK_FIRST_KEYWORD) && 
2145                         (entry->tok <= TOK_LAST_KEYWORD)))) {
2146                 tk->tok = entry->tok;
2147         }
2148 }
2149
2150 static void ident_to_macro(struct compile_state *state, struct token *tk)
2151 {
2152         struct hash_entry *entry;
2153         entry = tk->ident;
2154         if (entry && 
2155                 (entry->tok >= TOK_FIRST_MACRO) &&
2156                 (entry->tok <= TOK_LAST_MACRO)) {
2157                 tk->tok = entry->tok;
2158         }
2159 }
2160
2161 static void hash_keyword(
2162         struct compile_state *state, const char *keyword, int tok)
2163 {
2164         struct hash_entry *entry;
2165         entry = lookup(state, keyword, strlen(keyword));
2166         if (entry && entry->tok != TOK_UNKNOWN) {
2167                 die("keyword %s already hashed", keyword);
2168         }
2169         entry->tok  = tok;
2170 }
2171
2172 static void symbol(
2173         struct compile_state *state, struct hash_entry *ident,
2174         struct symbol **chain, struct triple *def, struct type *type)
2175 {
2176         struct symbol *sym;
2177         if (*chain && ((*chain)->scope_depth == state->scope_depth)) {
2178                 error(state, 0, "%s already defined", ident->name);
2179         }
2180         sym = xcmalloc(sizeof(*sym), "symbol");
2181         sym->ident = ident;
2182         sym->def   = def;
2183         sym->type  = type;
2184         sym->scope_depth = state->scope_depth;
2185         sym->next = *chain;
2186         *chain    = sym;
2187 }
2188
2189 static void label_symbol(struct compile_state *state, 
2190         struct hash_entry *ident, struct triple *label)
2191 {
2192         struct symbol *sym;
2193         if (ident->sym_label) {
2194                 error(state, 0, "label %s already defined", ident->name);
2195         }
2196         sym = xcmalloc(sizeof(*sym), "label");
2197         sym->ident = ident;
2198         sym->def   = label;
2199         sym->type  = &void_type;
2200         sym->scope_depth = FUNCTION_SCOPE_DEPTH;
2201         sym->next  = 0;
2202         ident->sym_label = sym;
2203 }
2204
2205 static void start_scope(struct compile_state *state)
2206 {
2207         state->scope_depth++;
2208 }
2209
2210 static void end_scope_syms(struct symbol **chain, int depth)
2211 {
2212         struct symbol *sym, *next;
2213         sym = *chain;
2214         while(sym && (sym->scope_depth == depth)) {
2215                 next = sym->next;
2216                 xfree(sym);
2217                 sym = next;
2218         }
2219         *chain = sym;
2220 }
2221
2222 static void end_scope(struct compile_state *state)
2223 {
2224         int i;
2225         int depth;
2226         /* Walk through the hash table and remove all symbols
2227          * in the current scope. 
2228          */
2229         depth = state->scope_depth;
2230         for(i = 0; i < HASH_TABLE_SIZE; i++) {
2231                 struct hash_entry *entry;
2232                 entry = state->hash_table[i];
2233                 while(entry) {
2234                         end_scope_syms(&entry->sym_label,  depth);
2235                         end_scope_syms(&entry->sym_struct, depth);
2236                         end_scope_syms(&entry->sym_ident,  depth);
2237                         entry = entry->next;
2238                 }
2239         }
2240         state->scope_depth = depth - 1;
2241 }
2242
2243 static void register_keywords(struct compile_state *state)
2244 {
2245         hash_keyword(state, "auto",          TOK_AUTO);
2246         hash_keyword(state, "break",         TOK_BREAK);
2247         hash_keyword(state, "case",          TOK_CASE);
2248         hash_keyword(state, "char",          TOK_CHAR);
2249         hash_keyword(state, "const",         TOK_CONST);
2250         hash_keyword(state, "continue",      TOK_CONTINUE);
2251         hash_keyword(state, "default",       TOK_DEFAULT);
2252         hash_keyword(state, "do",            TOK_DO);
2253         hash_keyword(state, "double",        TOK_DOUBLE);
2254         hash_keyword(state, "else",          TOK_ELSE);
2255         hash_keyword(state, "enum",          TOK_ENUM);
2256         hash_keyword(state, "extern",        TOK_EXTERN);
2257         hash_keyword(state, "float",         TOK_FLOAT);
2258         hash_keyword(state, "for",           TOK_FOR);
2259         hash_keyword(state, "goto",          TOK_GOTO);
2260         hash_keyword(state, "if",            TOK_IF);
2261         hash_keyword(state, "inline",        TOK_INLINE);
2262         hash_keyword(state, "int",           TOK_INT);
2263         hash_keyword(state, "long",          TOK_LONG);
2264         hash_keyword(state, "register",      TOK_REGISTER);
2265         hash_keyword(state, "restrict",      TOK_RESTRICT);
2266         hash_keyword(state, "return",        TOK_RETURN);
2267         hash_keyword(state, "short",         TOK_SHORT);
2268         hash_keyword(state, "signed",        TOK_SIGNED);
2269         hash_keyword(state, "sizeof",        TOK_SIZEOF);
2270         hash_keyword(state, "static",        TOK_STATIC);
2271         hash_keyword(state, "struct",        TOK_STRUCT);
2272         hash_keyword(state, "switch",        TOK_SWITCH);
2273         hash_keyword(state, "typedef",       TOK_TYPEDEF);
2274         hash_keyword(state, "union",         TOK_UNION);
2275         hash_keyword(state, "unsigned",      TOK_UNSIGNED);
2276         hash_keyword(state, "void",          TOK_VOID);
2277         hash_keyword(state, "volatile",      TOK_VOLATILE);
2278         hash_keyword(state, "__volatile__",  TOK_VOLATILE);
2279         hash_keyword(state, "while",         TOK_WHILE);
2280         hash_keyword(state, "asm",           TOK_ASM);
2281         hash_keyword(state, "__asm__",       TOK_ASM);
2282         hash_keyword(state, "__attribute__", TOK_ATTRIBUTE);
2283         hash_keyword(state, "__alignof__",   TOK_ALIGNOF);
2284 }
2285
2286 static void register_macro_keywords(struct compile_state *state)
2287 {
2288         hash_keyword(state, "define",        TOK_DEFINE);
2289         hash_keyword(state, "undef",         TOK_UNDEF);
2290         hash_keyword(state, "include",       TOK_INCLUDE);
2291         hash_keyword(state, "line",          TOK_LINE);
2292         hash_keyword(state, "error",         TOK_ERROR);
2293         hash_keyword(state, "warning",       TOK_WARNING);
2294         hash_keyword(state, "pragma",        TOK_PRAGMA);
2295         hash_keyword(state, "ifdef",         TOK_IFDEF);
2296         hash_keyword(state, "ifndef",        TOK_IFNDEF);
2297         hash_keyword(state, "elif",          TOK_ELIF);
2298         hash_keyword(state, "endif",         TOK_ENDIF);
2299 }
2300
2301 static int spacep(int c)
2302 {
2303         int ret = 0;
2304         switch(c) {
2305         case ' ':
2306         case '\t':
2307         case '\f':
2308         case '\v':
2309         case '\r':
2310         case '\n':
2311                 ret = 1;
2312                 break;
2313         }
2314         return ret;
2315 }
2316
2317 static int digitp(int c)
2318 {
2319         int ret = 0;
2320         switch(c) {
2321         case '0': case '1': case '2': case '3': case '4': 
2322         case '5': case '6': case '7': case '8': case '9':
2323                 ret = 1;
2324                 break;
2325         }
2326         return ret;
2327 }
2328 static int digval(int c)
2329 {
2330         int val = -1;
2331         if ((c >= '0') && (c <= '9')) {
2332                 val = c - '0';
2333         }
2334         return val;
2335 }
2336
2337 static int hexdigitp(int c)
2338 {
2339         int ret = 0;
2340         switch(c) {
2341         case '0': case '1': case '2': case '3': case '4': 
2342         case '5': case '6': case '7': case '8': case '9':
2343         case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
2344         case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
2345                 ret = 1;
2346                 break;
2347         }
2348         return ret;
2349 }
2350 static int hexdigval(int c) 
2351 {
2352         int val = -1;
2353         if ((c >= '0') && (c <= '9')) {
2354                 val = c - '0';
2355         }
2356         else if ((c >= 'A') && (c <= 'F')) {
2357                 val = 10 + (c - 'A');
2358         }
2359         else if ((c >= 'a') && (c <= 'f')) {
2360                 val = 10 + (c - 'a');
2361         }
2362         return val;
2363 }
2364
2365 static int octdigitp(int c)
2366 {
2367         int ret = 0;
2368         switch(c) {
2369         case '0': case '1': case '2': case '3': 
2370         case '4': case '5': case '6': case '7':
2371                 ret = 1;
2372                 break;
2373         }
2374         return ret;
2375 }
2376 static int octdigval(int c)
2377 {
2378         int val = -1;
2379         if ((c >= '0') && (c <= '7')) {
2380                 val = c - '0';
2381         }
2382         return val;
2383 }
2384
2385 static int letterp(int c)
2386 {
2387         int ret = 0;
2388         switch(c) {
2389         case 'a': case 'b': case 'c': case 'd': case 'e':
2390         case 'f': case 'g': case 'h': case 'i': case 'j':
2391         case 'k': case 'l': case 'm': case 'n': case 'o':
2392         case 'p': case 'q': case 'r': case 's': case 't':
2393         case 'u': case 'v': case 'w': case 'x': case 'y':
2394         case 'z':
2395         case 'A': case 'B': case 'C': case 'D': case 'E':
2396         case 'F': case 'G': case 'H': case 'I': case 'J':
2397         case 'K': case 'L': case 'M': case 'N': case 'O':
2398         case 'P': case 'Q': case 'R': case 'S': case 'T':
2399         case 'U': case 'V': case 'W': case 'X': case 'Y':
2400         case 'Z':
2401         case '_':
2402                 ret = 1;
2403                 break;
2404         }
2405         return ret;
2406 }
2407
2408 static int char_value(struct compile_state *state,
2409         const signed char **strp, const signed char *end)
2410 {
2411         const signed char *str;
2412         int c;
2413         str = *strp;
2414         c = *str++;
2415         if ((c == '\\') && (str < end)) {
2416                 switch(*str) {
2417                 case 'n':  c = '\n'; str++; break;
2418                 case 't':  c = '\t'; str++; break;
2419                 case 'v':  c = '\v'; str++; break;
2420                 case 'b':  c = '\b'; str++; break;
2421                 case 'r':  c = '\r'; str++; break;
2422                 case 'f':  c = '\f'; str++; break;
2423                 case 'a':  c = '\a'; str++; break;
2424                 case '\\': c = '\\'; str++; break;
2425                 case '?':  c = '?';  str++; break;
2426                 case '\'': c = '\''; str++; break;
2427                 case '"':  c = '"';  break;
2428                 case 'x': 
2429                         c = 0;
2430                         str++;
2431                         while((str < end) && hexdigitp(*str)) {
2432                                 c <<= 4;
2433                                 c += hexdigval(*str);
2434                                 str++;
2435                         }
2436                         break;
2437                 case '0': case '1': case '2': case '3': 
2438                 case '4': case '5': case '6': case '7':
2439                         c = 0;
2440                         while((str < end) && octdigitp(*str)) {
2441                                 c <<= 3;
2442                                 c += octdigval(*str);
2443                                 str++;
2444                         }
2445                         break;
2446                 default:
2447                         error(state, 0, "Invalid character constant");
2448                         break;
2449                 }
2450         }
2451         *strp = str;
2452         return c;
2453 }
2454
2455 static char *after_digits(char *ptr, char *end)
2456 {
2457         while((ptr < end) && digitp(*ptr)) {
2458                 ptr++;
2459         }
2460         return ptr;
2461 }
2462
2463 static char *after_octdigits(char *ptr, char *end)
2464 {
2465         while((ptr < end) && octdigitp(*ptr)) {
2466                 ptr++;
2467         }
2468         return ptr;
2469 }
2470
2471 static char *after_hexdigits(char *ptr, char *end)
2472 {
2473         while((ptr < end) && hexdigitp(*ptr)) {
2474                 ptr++;
2475         }
2476         return ptr;
2477 }
2478
2479 static void save_string(struct compile_state *state, 
2480         struct token *tk, char *start, char *end, const char *id)
2481 {
2482         char *str;
2483         int str_len;
2484         /* Create a private copy of the string */
2485         str_len = end - start + 1;
2486         str = xmalloc(str_len + 1, id);
2487         memcpy(str, start, str_len);
2488         str[str_len] = '\0';
2489
2490         /* Store the copy in the token */
2491         tk->val.str = str;
2492         tk->str_len = str_len;
2493 }
2494 static void next_token(struct compile_state *state, int index)
2495 {
2496         struct file_state *file;
2497         struct token *tk;
2498         char *token;
2499         int c, c1, c2, c3;
2500         char *tokp, *end;
2501         int tok;
2502 next_token:
2503         file = state->file;
2504         tk = &state->token[index];
2505         tk->str_len = 0;
2506         tk->ident = 0;
2507         token = tokp = file->pos;
2508         end = file->buf + file->size;
2509         tok = TOK_UNKNOWN;
2510         c = -1;
2511         if (tokp < end) {
2512                 c = *tokp;
2513         }
2514         c1 = -1;
2515         if ((tokp + 1) < end) {
2516                 c1 = tokp[1];
2517         }
2518         c2 = -1;
2519         if ((tokp + 2) < end) {
2520                 c2 = tokp[2];
2521         }
2522         c3 = -1;
2523         if ((tokp + 3) < end) {
2524                 c3 = tokp[3];
2525         }
2526         if (tokp >= end) {
2527                 tok = TOK_EOF;
2528                 tokp = end;
2529         }
2530         /* Whitespace */
2531         else if (spacep(c)) {
2532                 tok = TOK_SPACE;
2533                 while ((tokp < end) && spacep(c)) {
2534                         if (c == '\n') {
2535                                 file->line++;
2536                                 file->report_line++;
2537                                 file->line_start = tokp + 1;
2538                         }
2539                         c = *(++tokp);
2540                 }
2541                 if (!spacep(c)) {
2542                         tokp--;
2543                 }
2544         }
2545         /* EOL Comments */
2546         else if ((c == '/') && (c1 == '/')) {
2547                 tok = TOK_SPACE;
2548                 for(tokp += 2; tokp < end; tokp++) {
2549                         c = *tokp;
2550                         if (c == '\n') {
2551                                 file->line++;
2552                                 file->report_line++;
2553                                 file->line_start = tokp +1;
2554                                 break;
2555                         }
2556                 }
2557         }
2558         /* Comments */
2559         else if ((c == '/') && (c1 == '*')) {
2560                 int line;
2561                 char *line_start;
2562                 line = file->line;
2563                 line_start = file->line_start;
2564                 for(tokp += 2; (end - tokp) >= 2; tokp++) {
2565                         c = *tokp;
2566                         if (c == '\n') {
2567                                 line++;
2568                                 line_start = tokp +1;
2569                         }
2570                         else if ((c == '*') && (tokp[1] == '/')) {
2571                                 tok = TOK_SPACE;
2572                                 tokp += 1;
2573                                 break;
2574                         }
2575                 }
2576                 if (tok == TOK_UNKNOWN) {
2577                         error(state, 0, "unterminated comment");
2578                 }
2579                 file->report_line += line - file->line;
2580                 file->line = line;
2581                 file->line_start = line_start;
2582         }
2583         /* string constants */
2584         else if ((c == '"') ||
2585                 ((c == 'L') && (c1 == '"'))) {
2586                 int line;
2587                 char *line_start;
2588                 int wchar;
2589                 line = file->line;
2590                 line_start = file->line_start;
2591                 wchar = 0;
2592                 if (c == 'L') {
2593                         wchar = 1;
2594                         tokp++;
2595                 }
2596                 for(tokp += 1; tokp < end; tokp++) {
2597                         c = *tokp;
2598                         if (c == '\n') {
2599                                 line++;
2600                                 line_start = tokp + 1;
2601                         }
2602                         else if ((c == '\\') && (tokp +1 < end)) {
2603                                 tokp++;
2604                         }
2605                         else if (c == '"') {
2606                                 tok = TOK_LIT_STRING;
2607                                 break;
2608                         }
2609                 }
2610                 if (tok == TOK_UNKNOWN) {
2611                         error(state, 0, "unterminated string constant");
2612                 }
2613                 if (line != file->line) {
2614                         warning(state, 0, "multiline string constant");
2615                 }
2616                 file->report_line += line - file->line;
2617                 file->line = line;
2618                 file->line_start = line_start;
2619
2620                 /* Save the string value */
2621                 save_string(state, tk, token, tokp, "literal string");
2622         }
2623         /* character constants */
2624         else if ((c == '\'') ||
2625                 ((c == 'L') && (c1 == '\''))) {
2626                 int line;
2627                 char *line_start;
2628                 int wchar;
2629                 line = file->line;
2630                 line_start = file->line_start;
2631                 wchar = 0;
2632                 if (c == 'L') {
2633                         wchar = 1;
2634                         tokp++;
2635                 }
2636                 for(tokp += 1; tokp < end; tokp++) {
2637                         c = *tokp;
2638                         if (c == '\n') {
2639                                 line++;
2640                                 line_start = tokp + 1;
2641                         }
2642                         else if ((c == '\\') && (tokp +1 < end)) {
2643                                 tokp++;
2644                         }
2645                         else if (c == '\'') {
2646                                 tok = TOK_LIT_CHAR;
2647                                 break;
2648                         }
2649                 }
2650                 if (tok == TOK_UNKNOWN) {
2651                         error(state, 0, "unterminated character constant");
2652                 }
2653                 if (line != file->line) {
2654                         warning(state, 0, "multiline character constant");
2655                 }
2656                 file->report_line += line - file->line;
2657                 file->line = line;
2658                 file->line_start = line_start;
2659
2660                 /* Save the character value */
2661                 save_string(state, tk, token, tokp, "literal character");
2662         }
2663         /* integer and floating constants 
2664          * Integer Constants
2665          * {digits}
2666          * 0[Xx]{hexdigits}
2667          * 0{octdigit}+
2668          * 
2669          * Floating constants
2670          * {digits}.{digits}[Ee][+-]?{digits}
2671          * {digits}.{digits}
2672          * {digits}[Ee][+-]?{digits}
2673          * .{digits}[Ee][+-]?{digits}
2674          * .{digits}
2675          */
2676         
2677         else if (digitp(c) || ((c == '.') && (digitp(c1)))) {
2678                 char *next, *new;
2679                 int is_float;
2680                 is_float = 0;
2681                 if (c != '.') {
2682                         next = after_digits(tokp, end);
2683                 }
2684                 else {
2685                         next = tokp;
2686                 }
2687                 if (next[0] == '.') {
2688                         new = after_digits(next, end);
2689                         is_float = (new != next);
2690                         next = new;
2691                 }
2692                 if ((next[0] == 'e') || (next[0] == 'E')) {
2693                         if (((next + 1) < end) && 
2694                                 ((next[1] == '+') || (next[1] == '-'))) {
2695                                 next++;
2696                         }
2697                         new = after_digits(next, end);
2698                         is_float = (new != next);
2699                         next = new;
2700                 }
2701                 if (is_float) {
2702                         tok = TOK_LIT_FLOAT;
2703                         if ((next < end) && (
2704                                 (next[0] == 'f') ||
2705                                 (next[0] == 'F') ||
2706                                 (next[0] == 'l') ||
2707                                 (next[0] == 'L'))
2708                                 ) {
2709                                 next++;
2710                         }
2711                 }
2712                 if (!is_float && digitp(c)) {
2713                         tok = TOK_LIT_INT;
2714                         if ((c == '0') && ((c1 == 'x') || (c1 == 'X'))) {
2715                                 next = after_hexdigits(tokp + 2, end);
2716                         }
2717                         else if (c == '0') {
2718                                 next = after_octdigits(tokp, end);
2719                         }
2720                         else {
2721                                 next = after_digits(tokp, end);
2722                         }
2723                         /* crazy integer suffixes */
2724                         if ((next < end) && 
2725                                 ((next[0] == 'u') || (next[0] == 'U'))) { 
2726                                 next++;
2727                                 if ((next < end) &&
2728                                         ((next[0] == 'l') || (next[0] == 'L'))) {
2729                                         next++;
2730                                 }
2731                         }
2732                         else if ((next < end) &&
2733                                 ((next[0] == 'l') || (next[0] == 'L'))) {
2734                                 next++;
2735                                 if ((next < end) && 
2736                                         ((next[0] == 'u') || (next[0] == 'U'))) { 
2737                                         next++;
2738                                 }
2739                         }
2740                 }
2741                 tokp = next - 1;
2742
2743                 /* Save the integer/floating point value */
2744                 save_string(state, tk, token, tokp, "literal number");
2745         }
2746         /* identifiers */
2747         else if (letterp(c)) {
2748                 tok = TOK_IDENT;
2749                 for(tokp += 1; tokp < end; tokp++) {
2750                         c = *tokp;
2751                         if (!letterp(c) && !digitp(c)) {
2752                                 break;
2753                         }
2754                 }
2755                 tokp -= 1;
2756                 tk->ident = lookup(state, token, tokp +1 - token);
2757         }
2758         /* C99 alternate macro characters */
2759         else if ((c == '%') && (c1 == ':') && (c2 == '%') && (c3 == ':')) { 
2760                 tokp += 3; 
2761                 tok = TOK_CONCATENATE; 
2762         }
2763         else if ((c == '.') && (c1 == '.') && (c2 == '.')) { tokp += 2; tok = TOK_DOTS; }
2764         else if ((c == '<') && (c1 == '<') && (c2 == '=')) { tokp += 2; tok = TOK_SLEQ; }
2765         else if ((c == '>') && (c1 == '>') && (c2 == '=')) { tokp += 2; tok = TOK_SREQ; }
2766         else if ((c == '*') && (c1 == '=')) { tokp += 1; tok = TOK_TIMESEQ; }
2767         else if ((c == '/') && (c1 == '=')) { tokp += 1; tok = TOK_DIVEQ; }
2768         else if ((c == '%') && (c1 == '=')) { tokp += 1; tok = TOK_MODEQ; }
2769         else if ((c == '+') && (c1 == '=')) { tokp += 1; tok = TOK_PLUSEQ; }
2770         else if ((c == '-') && (c1 == '=')) { tokp += 1; tok = TOK_MINUSEQ; }
2771         else if ((c == '&') && (c1 == '=')) { tokp += 1; tok = TOK_ANDEQ; }
2772         else if ((c == '^') && (c1 == '=')) { tokp += 1; tok = TOK_XOREQ; }
2773         else if ((c == '|') && (c1 == '=')) { tokp += 1; tok = TOK_OREQ; }
2774         else if ((c == '=') && (c1 == '=')) { tokp += 1; tok = TOK_EQEQ; }
2775         else if ((c == '!') && (c1 == '=')) { tokp += 1; tok = TOK_NOTEQ; }
2776         else if ((c == '|') && (c1 == '|')) { tokp += 1; tok = TOK_LOGOR; }
2777         else if ((c == '&') && (c1 == '&')) { tokp += 1; tok = TOK_LOGAND; }
2778         else if ((c == '<') && (c1 == '=')) { tokp += 1; tok = TOK_LESSEQ; }
2779         else if ((c == '>') && (c1 == '=')) { tokp += 1; tok = TOK_MOREEQ; }
2780         else if ((c == '<') && (c1 == '<')) { tokp += 1; tok = TOK_SL; }
2781         else if ((c == '>') && (c1 == '>')) { tokp += 1; tok = TOK_SR; }
2782         else if ((c == '+') && (c1 == '+')) { tokp += 1; tok = TOK_PLUSPLUS; }
2783         else if ((c == '-') && (c1 == '-')) { tokp += 1; tok = TOK_MINUSMINUS; }
2784         else if ((c == '-') && (c1 == '>')) { tokp += 1; tok = TOK_ARROW; }
2785         else if ((c == '<') && (c1 == ':')) { tokp += 1; tok = TOK_LBRACKET; }
2786         else if ((c == ':') && (c1 == '>')) { tokp += 1; tok = TOK_RBRACKET; }
2787         else if ((c == '<') && (c1 == '%')) { tokp += 1; tok = TOK_LBRACE; }
2788         else if ((c == '%') && (c1 == '>')) { tokp += 1; tok = TOK_RBRACE; }
2789         else if ((c == '%') && (c1 == ':')) { tokp += 1; tok = TOK_MACRO; }
2790         else if ((c == '#') && (c1 == '#')) { tokp += 1; tok = TOK_CONCATENATE; }
2791         else if (c == ';') { tok = TOK_SEMI; }
2792         else if (c == '{') { tok = TOK_LBRACE; }
2793         else if (c == '}') { tok = TOK_RBRACE; }
2794         else if (c == ',') { tok = TOK_COMMA; }
2795         else if (c == '=') { tok = TOK_EQ; }
2796         else if (c == ':') { tok = TOK_COLON; }
2797         else if (c == '[') { tok = TOK_LBRACKET; }
2798         else if (c == ']') { tok = TOK_RBRACKET; }
2799         else if (c == '(') { tok = TOK_LPAREN; }
2800         else if (c == ')') { tok = TOK_RPAREN; }
2801         else if (c == '*') { tok = TOK_STAR; }
2802         else if (c == '>') { tok = TOK_MORE; }
2803         else if (c == '<') { tok = TOK_LESS; }
2804         else if (c == '?') { tok = TOK_QUEST; }
2805         else if (c == '|') { tok = TOK_OR; }
2806         else if (c == '&') { tok = TOK_AND; }
2807         else if (c == '^') { tok = TOK_XOR; }
2808         else if (c == '+') { tok = TOK_PLUS; }
2809         else if (c == '-') { tok = TOK_MINUS; }
2810         else if (c == '/') { tok = TOK_DIV; }
2811         else if (c == '%') { tok = TOK_MOD; }
2812         else if (c == '!') { tok = TOK_BANG; }
2813         else if (c == '.') { tok = TOK_DOT; }
2814         else if (c == '~') { tok = TOK_TILDE; }
2815         else if (c == '#') { tok = TOK_MACRO; }
2816         if (tok == TOK_MACRO) {
2817                 /* Only match preprocessor directives at the start of a line */
2818                 char *ptr;
2819                 for(ptr = file->line_start; spacep(*ptr); ptr++)
2820                         ;
2821                 if (ptr != tokp) {
2822                         tok = TOK_UNKNOWN;
2823                 }
2824         }
2825         if (tok == TOK_UNKNOWN) {
2826                 error(state, 0, "unknown token");
2827         }
2828
2829         file->pos = tokp + 1;
2830         tk->tok = tok;
2831         if (tok == TOK_IDENT) {
2832                 ident_to_keyword(state, tk);
2833         }
2834         /* Don't return space tokens. */
2835         if (tok == TOK_SPACE) {
2836                 goto next_token;
2837         }
2838 }
2839
2840 static void compile_macro(struct compile_state *state, struct token *tk)
2841 {
2842         struct file_state *file;
2843         struct hash_entry *ident;
2844         ident = tk->ident;
2845         file = xmalloc(sizeof(*file), "file_state");
2846         file->basename = xstrdup(tk->ident->name);
2847         file->dirname = xstrdup("");
2848         file->size = ident->sym_define->buf_len;
2849         file->buf = xmalloc(file->size +2,  file->basename);
2850         memcpy(file->buf, ident->sym_define->buf, file->size);
2851         file->buf[file->size] = '\n';
2852         file->buf[file->size + 1] = '\0';
2853         file->pos = file->buf;
2854         file->line_start = file->pos;
2855         file->line = 1;
2856         file->report_line = 1;
2857         file->report_name = file->basename;
2858         file->report_dir  = file->dirname;
2859         file->prev = state->file;
2860         state->file = file;
2861 }
2862
2863
2864 static int mpeek(struct compile_state *state, int index)
2865 {
2866         struct token *tk;
2867         int rescan;
2868         tk = &state->token[index + 1];
2869         if (tk->tok == -1) {
2870                 next_token(state, index + 1);
2871         }
2872         do {
2873                 rescan = 0;
2874                 if ((tk->tok == TOK_EOF) && 
2875                         (state->file != state->macro_file) &&
2876                         (state->file->prev)) {
2877                         struct file_state *file = state->file;
2878                         state->file = file->prev;
2879                         /* file->basename is used keep it */
2880                         if (file->report_dir != file->dirname) {
2881                                 xfree(file->report_dir);
2882                         }
2883                         xfree(file->dirname);
2884                         xfree(file->buf);
2885                         xfree(file);
2886                         next_token(state, index + 1);
2887                         rescan = 1;
2888                 }
2889                 else if (tk->ident && tk->ident->sym_define) {
2890                         compile_macro(state, tk);
2891                         next_token(state, index + 1);
2892                         rescan = 1;
2893                 }
2894         } while(rescan);
2895         /* Don't show the token on the next line */
2896         if (state->macro_line < state->macro_file->line) {
2897                 return TOK_EOF;
2898         }
2899         return state->token[index +1].tok;
2900 }
2901
2902 static void meat(struct compile_state *state, int index, int tok)
2903 {
2904         int next_tok;
2905         int i;
2906         next_tok = mpeek(state, index);
2907         if (next_tok != tok) {
2908                 const char *name1, *name2;
2909                 name1 = tokens[next_tok];
2910                 name2 = "";
2911                 if (next_tok == TOK_IDENT) {
2912                         name2 = state->token[index + 1].ident->name;
2913                 }
2914                 error(state, 0, "found %s %s expected %s", 
2915                         name1, name2, tokens[tok]);
2916         }
2917         /* Free the old token value */
2918         if (state->token[index].str_len) {
2919                 memset((void *)(state->token[index].val.str), -1, 
2920                         state->token[index].str_len);
2921                 xfree(state->token[index].val.str);
2922         }
2923         for(i = index; i < sizeof(state->token)/sizeof(state->token[0]) - 1; i++) {
2924                 state->token[i] = state->token[i + 1];
2925         }
2926         memset(&state->token[i], 0, sizeof(state->token[i]));
2927         state->token[i].tok = -1;
2928 }
2929
2930 static long_t mcexpr(struct compile_state *state, int index);
2931
2932 static long_t mprimary_expr(struct compile_state *state, int index)
2933 {
2934         long_t val;
2935         int tok;
2936         tok = mpeek(state, index);
2937         while(state->token[index + 1].ident && 
2938                 state->token[index + 1].ident->sym_define) {
2939                 meat(state, index, tok);
2940                 compile_macro(state, &state->token[index]);
2941                 tok = mpeek(state, index);
2942         }
2943         switch(tok) {
2944         case TOK_LPAREN:
2945                 meat(state, index, TOK_LPAREN);
2946                 val = mcexpr(state, index);
2947                 meat(state, index, TOK_RPAREN);
2948                 break;
2949         case TOK_LIT_INT:
2950         {
2951                 char *end;
2952                 meat(state, index, TOK_LIT_INT);
2953                 errno = 0;
2954                 val = strtol(state->token[index].val.str, &end, 0);
2955                 if (((val == LONG_MIN) || (val == LONG_MAX)) &&
2956                         (errno == ERANGE)) {
2957                         error(state, 0, "Integer constant to large");
2958                 }
2959                 break;
2960         }
2961         default:
2962                 meat(state, index, TOK_LIT_INT);
2963                 val = 0;
2964         }
2965         return val;
2966 }
2967 static long_t munary_expr(struct compile_state *state, int index)
2968 {
2969         long_t val;
2970         switch(mpeek(state, index)) {
2971         case TOK_PLUS:
2972                 meat(state, index, TOK_PLUS);
2973                 val = munary_expr(state, index);
2974                 val = + val;
2975                 break;
2976         case TOK_MINUS:
2977                 meat(state, index, TOK_MINUS);
2978                 val = munary_expr(state, index);
2979                 val = - val;
2980                 break;
2981         case TOK_TILDE:
2982                 meat(state, index, TOK_BANG);
2983                 val = munary_expr(state, index);
2984                 val = ~ val;
2985                 break;
2986         case TOK_BANG:
2987                 meat(state, index, TOK_BANG);
2988                 val = munary_expr(state, index);
2989                 val = ! val;
2990                 break;
2991         default:
2992                 val = mprimary_expr(state, index);
2993                 break;
2994         }
2995         return val;
2996         
2997 }
2998 static long_t mmul_expr(struct compile_state *state, int index)
2999 {
3000         long_t val;
3001         int done;
3002         val = munary_expr(state, index);
3003         do {
3004                 long_t right;
3005                 done = 0;
3006                 switch(mpeek(state, index)) {
3007                 case TOK_STAR:
3008                         meat(state, index, TOK_STAR);
3009                         right = munary_expr(state, index);
3010                         val = val * right;
3011                         break;
3012                 case TOK_DIV:
3013                         meat(state, index, TOK_DIV);
3014                         right = munary_expr(state, index);
3015                         val = val / right;
3016                         break;
3017                 case TOK_MOD:
3018                         meat(state, index, TOK_MOD);
3019                         right = munary_expr(state, index);
3020                         val = val % right;
3021                         break;
3022                 default:
3023                         done = 1;
3024                         break;
3025                 }
3026         } while(!done);
3027
3028         return val;
3029 }
3030
3031 static long_t madd_expr(struct compile_state *state, int index)
3032 {
3033         long_t val;
3034         int done;
3035         val = mmul_expr(state, index);
3036         do {
3037                 long_t right;
3038                 done = 0;
3039                 switch(mpeek(state, index)) {
3040                 case TOK_PLUS:
3041                         meat(state, index, TOK_PLUS);
3042                         right = mmul_expr(state, index);
3043                         val = val + right;
3044                         break;
3045                 case TOK_MINUS:
3046                         meat(state, index, TOK_MINUS);
3047                         right = mmul_expr(state, index);
3048                         val = val - right;
3049                         break;
3050                 default:
3051                         done = 1;
3052                         break;
3053                 }
3054         } while(!done);
3055
3056         return val;
3057 }
3058
3059 static long_t mshift_expr(struct compile_state *state, int index)
3060 {
3061         long_t val;
3062         int done;
3063         val = madd_expr(state, index);
3064         do {
3065                 long_t right;
3066                 done = 0;
3067                 switch(mpeek(state, index)) {
3068                 case TOK_SL:
3069                         meat(state, index, TOK_SL);
3070                         right = madd_expr(state, index);
3071                         val = val << right;
3072                         break;
3073                 case TOK_SR:
3074                         meat(state, index, TOK_SR);
3075                         right = madd_expr(state, index);
3076                         val = val >> right;
3077                         break;
3078                 default:
3079                         done = 1;
3080                         break;
3081                 }
3082         } while(!done);
3083
3084         return val;
3085 }
3086
3087 static long_t mrel_expr(struct compile_state *state, int index)
3088 {
3089         long_t val;
3090         int done;
3091         val = mshift_expr(state, index);
3092         do {
3093                 long_t right;
3094                 done = 0;
3095                 switch(mpeek(state, index)) {
3096                 case TOK_LESS:
3097                         meat(state, index, TOK_LESS);
3098                         right = mshift_expr(state, index);
3099                         val = val < right;
3100                         break;
3101                 case TOK_MORE:
3102                         meat(state, index, TOK_MORE);
3103                         right = mshift_expr(state, index);
3104                         val = val > right;
3105                         break;
3106                 case TOK_LESSEQ:
3107                         meat(state, index, TOK_LESSEQ);
3108                         right = mshift_expr(state, index);
3109                         val = val <= right;
3110                         break;
3111                 case TOK_MOREEQ:
3112                         meat(state, index, TOK_MOREEQ);
3113                         right = mshift_expr(state, index);
3114                         val = val >= right;
3115                         break;
3116                 default:
3117                         done = 1;
3118                         break;
3119                 }
3120         } while(!done);
3121         return val;
3122 }
3123
3124 static long_t meq_expr(struct compile_state *state, int index)
3125 {
3126         long_t val;
3127         int done;
3128         val = mrel_expr(state, index);
3129         do {
3130                 long_t right;
3131                 done = 0;
3132                 switch(mpeek(state, index)) {
3133                 case TOK_EQEQ:
3134                         meat(state, index, TOK_EQEQ);
3135                         right = mrel_expr(state, index);
3136                         val = val == right;
3137                         break;
3138                 case TOK_NOTEQ:
3139                         meat(state, index, TOK_NOTEQ);
3140                         right = mrel_expr(state, index);
3141                         val = val != right;
3142                         break;
3143                 default:
3144                         done = 1;
3145                         break;
3146                 }
3147         } while(!done);
3148         return val;
3149 }
3150
3151 static long_t mand_expr(struct compile_state *state, int index)
3152 {
3153         long_t val;
3154         val = meq_expr(state, index);
3155         if (mpeek(state, index) == TOK_AND) {
3156                 long_t right;
3157                 meat(state, index, TOK_AND);
3158                 right = meq_expr(state, index);
3159                 val = val & right;
3160         }
3161         return val;
3162 }
3163
3164 static long_t mxor_expr(struct compile_state *state, int index)
3165 {
3166         long_t val;
3167         val = mand_expr(state, index);
3168         if (mpeek(state, index) == TOK_XOR) {
3169                 long_t right;
3170                 meat(state, index, TOK_XOR);
3171                 right = mand_expr(state, index);
3172                 val = val ^ right;
3173         }
3174         return val;
3175 }
3176
3177 static long_t mor_expr(struct compile_state *state, int index)
3178 {
3179         long_t val;
3180         val = mxor_expr(state, index);
3181         if (mpeek(state, index) == TOK_OR) {
3182                 long_t right;
3183                 meat(state, index, TOK_OR);
3184                 right = mxor_expr(state, index);
3185                 val = val | right;
3186         }
3187         return val;
3188 }
3189
3190 static long_t mland_expr(struct compile_state *state, int index)
3191 {
3192         long_t val;
3193         val = mor_expr(state, index);
3194         if (mpeek(state, index) == TOK_LOGAND) {
3195                 long_t right;
3196                 meat(state, index, TOK_LOGAND);
3197                 right = mor_expr(state, index);
3198                 val = val && right;
3199         }
3200         return val;
3201 }
3202 static long_t mlor_expr(struct compile_state *state, int index)
3203 {
3204         long_t val;
3205         val = mland_expr(state, index);
3206         if (mpeek(state, index) == TOK_LOGOR) {
3207                 long_t right;
3208                 meat(state, index, TOK_LOGOR);
3209                 right = mland_expr(state, index);
3210                 val = val || right;
3211         }
3212         return val;
3213 }
3214
3215 static long_t mcexpr(struct compile_state *state, int index)
3216 {
3217         return mlor_expr(state, index);
3218 }
3219 static void preprocess(struct compile_state *state, int index)
3220 {
3221         /* Doing much more with the preprocessor would require
3222          * a parser and a major restructuring.
3223          * Postpone that for later.
3224          */
3225         struct file_state *file;
3226         struct token *tk;
3227         int line;
3228         int tok;
3229         
3230         file = state->file;
3231         tk = &state->token[index];
3232         state->macro_line = line = file->line;
3233         state->macro_file = file;
3234
3235         next_token(state, index);
3236         ident_to_macro(state, tk);
3237         if (tk->tok == TOK_IDENT) {
3238                 error(state, 0, "undefined preprocessing directive `%s'",
3239                         tk->ident->name);
3240         }
3241         switch(tk->tok) {
3242         case TOK_LIT_INT:
3243         {
3244                 int override_line;
3245                 override_line = strtoul(tk->val.str, 0, 10);
3246                 next_token(state, index);
3247                 /* I have a cpp line marker parse it */
3248                 if (tk->tok == TOK_LIT_STRING) {
3249                         const char *token, *base;
3250                         char *name, *dir;
3251                         int name_len, dir_len;
3252                         name = xmalloc(tk->str_len, "report_name");
3253                         token = tk->val.str + 1;
3254                         base = strrchr(token, '/');
3255                         name_len = tk->str_len -2;
3256                         if (base != 0) {
3257                                 dir_len = base - token;
3258                                 base++;
3259                                 name_len -= base - token;
3260                         } else {
3261                                 dir_len = 0;
3262                                 base = token;
3263                         }
3264                         memcpy(name, base, name_len);
3265                         name[name_len] = '\0';
3266                         dir = xmalloc(dir_len + 1, "report_dir");
3267                         memcpy(dir, token, dir_len);
3268                         dir[dir_len] = '\0';
3269                         file->report_line = override_line - 1;
3270                         file->report_name = name;
3271                         file->report_dir = dir;
3272                 }
3273         }
3274                 break;
3275         case TOK_LINE:
3276                 meat(state, index, TOK_LINE);
3277                 meat(state, index, TOK_LIT_INT);
3278                 file->report_line = strtoul(tk->val.str, 0, 10) -1;
3279                 if (mpeek(state, index) == TOK_LIT_STRING) {
3280                         const char *token, *base;
3281                         char *name, *dir;
3282                         int name_len, dir_len;
3283                         meat(state, index, TOK_LIT_STRING);
3284                         name = xmalloc(tk->str_len, "report_name");
3285                         token = tk->val.str + 1;
3286                         name_len = tk->str_len - 2;
3287                         if (base != 0) {
3288                                 dir_len = base - token;
3289                                 base++;
3290                                 name_len -= base - token;
3291                         } else {
3292                                 dir_len = 0;
3293                                 base = token;
3294                         }
3295                         memcpy(name, base, name_len);
3296                         name[name_len] = '\0';
3297                         dir = xmalloc(dir_len + 1, "report_dir");
3298                         memcpy(dir, token, dir_len);
3299                         dir[dir_len] = '\0';
3300                         file->report_name = name;
3301                         file->report_dir = dir;
3302                 }
3303                 break;
3304         case TOK_UNDEF:
3305         case TOK_PRAGMA:
3306                 if (state->if_value < 0) {
3307                         break;
3308                 }
3309                 warning(state, 0, "Ignoring preprocessor directive: %s", 
3310                         tk->ident->name);
3311                 break;
3312         case TOK_ELIF:
3313                 error(state, 0, "#elif not supported");
3314 #warning "FIXME multiple #elif and #else in an #if do not work properly"
3315                 if (state->if_depth == 0) {
3316                         error(state, 0, "#elif without #if");
3317                 }
3318                 /* If the #if was taken the #elif just disables the following code */
3319                 if (state->if_value >= 0) {
3320                         state->if_value = - state->if_value;
3321                 }
3322                 /* If the previous #if was not taken see if the #elif enables the 
3323                  * trailing code.
3324                  */
3325                 else if ((state->if_value < 0) && 
3326                         (state->if_depth == - state->if_value))
3327                 {
3328                         if (mcexpr(state, index) != 0) {
3329                                 state->if_value = state->if_depth;
3330                         }
3331                         else {
3332                                 state->if_value = - state->if_depth;
3333                         }
3334                 }
3335                 break;
3336         case TOK_IF:
3337                 state->if_depth++;
3338                 if (state->if_value < 0) {
3339                         break;
3340                 }
3341                 if (mcexpr(state, index) != 0) {
3342                         state->if_value = state->if_depth;
3343                 }
3344                 else {
3345                         state->if_value = - state->if_depth;
3346                 }
3347                 break;
3348         case TOK_IFNDEF:
3349                 state->if_depth++;
3350                 if (state->if_value < 0) {
3351                         break;
3352                 }
3353                 next_token(state, index);
3354                 if ((line != file->line) || (tk->tok != TOK_IDENT)) {
3355                         error(state, 0, "Invalid macro name");
3356                 }
3357                 if (tk->ident->sym_define == 0) {
3358                         state->if_value = state->if_depth;
3359                 } 
3360                 else {
3361                         state->if_value = - state->if_depth;
3362                 }
3363                 break;
3364         case TOK_IFDEF:
3365                 state->if_depth++;
3366                 if (state->if_value < 0) {
3367                         break;
3368                 }
3369                 next_token(state, index);
3370                 if ((line != file->line) || (tk->tok != TOK_IDENT)) {
3371                         error(state, 0, "Invalid macro name");
3372                 }
3373                 if (tk->ident->sym_define != 0) {
3374                         state->if_value = state->if_depth;
3375                 }
3376                 else {
3377                         state->if_value = - state->if_depth;
3378                 }
3379                 break;
3380         case TOK_ELSE:
3381                 if (state->if_depth == 0) {
3382                         error(state, 0, "#else without #if");
3383                 }
3384                 if ((state->if_value >= 0) ||
3385                         ((state->if_value < 0) && 
3386                                 (state->if_depth == -state->if_value)))
3387                 {
3388                         state->if_value = - state->if_value;
3389                 }
3390                 break;
3391         case TOK_ENDIF:
3392                 if (state->if_depth == 0) {
3393                         error(state, 0, "#endif without #if");
3394                 }
3395                 if ((state->if_value >= 0) ||
3396                         ((state->if_value < 0) &&
3397                                 (state->if_depth == -state->if_value))) 
3398                 {
3399                         state->if_value = state->if_depth - 1;
3400                 }
3401                 state->if_depth--;
3402                 break;
3403         case TOK_DEFINE:
3404         {
3405                 struct hash_entry *ident;
3406                 struct macro *macro;
3407                 char *ptr;
3408                 
3409                 if (state->if_value < 0) /* quit early when #if'd out */
3410                         break;
3411
3412                 meat(state, index, TOK_IDENT);
3413                 ident = tk->ident;
3414                 
3415
3416                 if (*file->pos == '(') {
3417 #warning "FIXME macros with arguments not supported"
3418                         error(state, 0, "Macros with arguments not supported");
3419                 }
3420
3421                 /* Find the end of the line to get an estimate of
3422                  * the macro's length.
3423                  */
3424                 for(ptr = file->pos; *ptr != '\n'; ptr++)  
3425                         ;
3426
3427                 if (ident->sym_define != 0) {
3428                         error(state, 0, "macro %s already defined\n", ident->name);
3429                 }
3430                 macro = xmalloc(sizeof(*macro), "macro");
3431                 macro->ident = ident;
3432                 macro->buf_len = ptr - file->pos +1;
3433                 macro->buf = xmalloc(macro->buf_len +2, "macro buf");
3434
3435                 memcpy(macro->buf, file->pos, macro->buf_len);
3436                 macro->buf[macro->buf_len] = '\n';
3437                 macro->buf[macro->buf_len +1] = '\0';
3438
3439                 ident->sym_define = macro;
3440                 break;
3441         }
3442         case TOK_ERROR:
3443         {
3444                 char *end;
3445                 int len;
3446                 /* Find the end of the line */
3447                 for(end = file->pos; *end != '\n'; end++)
3448                         ;
3449                 len = (end - file->pos);
3450                 if (state->if_value >= 0) {
3451                         error(state, 0, "%*.*s", len, len, file->pos);
3452                 }
3453                 file->pos = end;
3454                 break;
3455         }
3456         case TOK_WARNING:
3457         {
3458                 char *end;
3459                 int len;
3460                 /* Find the end of the line */
3461                 for(end = file->pos; *end != '\n'; end++)
3462                         ;
3463                 len = (end - file->pos);
3464                 if (state->if_value >= 0) {
3465                         warning(state, 0, "%*.*s", len, len, file->pos);
3466                 }
3467                 file->pos = end;
3468                 break;
3469         }
3470         case TOK_INCLUDE:
3471         {
3472                 char *name;
3473                 char *ptr;
3474                 int local;
3475                 local = 0;
3476                 name = 0;
3477                 next_token(state, index);
3478                 if (tk->tok == TOK_LIT_STRING) {
3479                         const char *token;
3480                         int name_len;
3481                         name = xmalloc(tk->str_len, "include");
3482                         token = tk->val.str +1;
3483                         name_len = tk->str_len -2;
3484                         if (*token == '"') {
3485                                 token++;
3486                                 name_len--;
3487                         }
3488                         memcpy(name, token, name_len);
3489                         name[name_len] = '\0';
3490                         local = 1;
3491                 }
3492                 else if (tk->tok == TOK_LESS) {
3493                         char *start, *end;
3494                         start = file->pos;
3495                         for(end = start; *end != '\n'; end++) {
3496                                 if (*end == '>') {
3497                                         break;
3498                                 }
3499                         }
3500                         if (*end == '\n') {
3501                                 error(state, 0, "Unterminated included directive");
3502                         }
3503                         name = xmalloc(end - start + 1, "include");
3504                         memcpy(name, start, end - start);
3505                         name[end - start] = '\0';
3506                         file->pos = end +1;
3507                         local = 0;
3508                 }
3509                 else {
3510                         error(state, 0, "Invalid include directive");
3511                 }
3512                 /* Error if there are any characters after the include */
3513                 for(ptr = file->pos; *ptr != '\n'; ptr++) {
3514                         switch(*ptr) {
3515                         case ' ':
3516                         case '\t':
3517                         case '\v':
3518                                 break;
3519                         default:
3520                                 error(state, 0, "garbage after include directive");
3521                         }
3522                 }
3523                 if (state->if_value >= 0) {
3524                         compile_file(state, name, local);
3525                 }
3526                 xfree(name);
3527                 next_token(state, index);
3528                 return;
3529         }
3530         default:
3531                 /* Ignore # without a following ident */
3532                 if (tk->tok == TOK_IDENT) {
3533                         error(state, 0, "Invalid preprocessor directive: %s", 
3534                                 tk->ident->name);
3535                 }
3536                 break;
3537         }
3538         /* Consume the rest of the macro line */
3539         do {
3540                 tok = mpeek(state, index);
3541                 meat(state, index, tok);
3542         } while(tok != TOK_EOF);
3543         return;
3544 }
3545
3546 static void token(struct compile_state *state, int index)
3547 {
3548         struct file_state *file;
3549         struct token *tk;
3550         int rescan;
3551
3552         tk = &state->token[index];
3553         next_token(state, index);
3554         do {
3555                 rescan = 0;
3556                 file = state->file;
3557                 if (tk->tok == TOK_EOF && file->prev) {
3558                         state->file = file->prev;
3559                         /* file->basename is used keep it */
3560                         xfree(file->dirname);
3561                         xfree(file->buf);
3562                         xfree(file);
3563                         next_token(state, index);
3564                         rescan = 1;
3565                 }
3566                 else if (tk->tok == TOK_MACRO) {
3567                         preprocess(state, index);
3568                         rescan = 1;
3569                 }
3570                 else if (tk->ident && tk->ident->sym_define) {
3571                         compile_macro(state, tk);
3572                         next_token(state, index);
3573                         rescan = 1;
3574                 }
3575                 else if (state->if_value < 0) {
3576                         next_token(state, index);
3577                         rescan = 1;
3578                 }
3579         } while(rescan);
3580 }
3581
3582 static int peek(struct compile_state *state)
3583 {
3584         if (state->token[1].tok == -1) {
3585                 token(state, 1);
3586         }
3587         return state->token[1].tok;
3588 }
3589
3590 static int peek2(struct compile_state *state)
3591 {
3592         if (state->token[1].tok == -1) {
3593                 token(state, 1);
3594         }
3595         if (state->token[2].tok == -1) {
3596                 token(state, 2);
3597         }
3598         return state->token[2].tok;
3599 }
3600
3601 static void eat(struct compile_state *state, int tok)
3602 {
3603         int next_tok;
3604         int i;
3605         next_tok = peek(state);
3606         if (next_tok != tok) {
3607                 const char *name1, *name2;
3608                 name1 = tokens[next_tok];
3609                 name2 = "";
3610                 if (next_tok == TOK_IDENT) {
3611                         name2 = state->token[1].ident->name;
3612                 }
3613                 error(state, 0, "\tfound %s %s expected %s",
3614                         name1, name2 ,tokens[tok]);
3615         }
3616         /* Free the old token value */
3617         if (state->token[0].str_len) {
3618                 xfree((void *)(state->token[0].val.str));
3619         }
3620         for(i = 0; i < sizeof(state->token)/sizeof(state->token[0]) - 1; i++) {
3621                 state->token[i] = state->token[i + 1];
3622         }
3623         memset(&state->token[i], 0, sizeof(state->token[i]));
3624         state->token[i].tok = -1;
3625 }
3626
3627 #warning "FIXME do not hardcode the include paths"
3628 static char *include_paths[] = {
3629         "/home/eric/projects/linuxbios/checkin/solo/freebios2/src/include",
3630         "/home/eric/projects/linuxbios/checkin/solo/freebios2/src/arch/i386/include",
3631         "/home/eric/projects/linuxbios/checkin/solo/freebios2/src",
3632         0
3633 };
3634
3635 static void compile_file(struct compile_state *state, const char *filename, int local)
3636 {
3637         char cwd[4096];
3638         const char *subdir, *base;
3639         int subdir_len;
3640         struct file_state *file;
3641         char *basename;
3642         file = xmalloc(sizeof(*file), "file_state");
3643
3644         base = strrchr(filename, '/');
3645         subdir = filename;
3646         if (base != 0) {
3647                 subdir_len = base - filename;
3648                 base++;
3649         }
3650         else {
3651                 base = filename;
3652                 subdir_len = 0;
3653         }
3654         basename = xmalloc(strlen(base) +1, "basename");
3655         strcpy(basename, base);
3656         file->basename = basename;
3657
3658         if (getcwd(cwd, sizeof(cwd)) == 0) {
3659                 die("cwd buffer to small");
3660         }
3661         
3662         if (subdir[0] == '/') {
3663                 file->dirname = xmalloc(subdir_len + 1, "dirname");
3664                 memcpy(file->dirname, subdir, subdir_len);
3665                 file->dirname[subdir_len] = '\0';
3666         }
3667         else {
3668                 char *dir;
3669                 int dirlen;
3670                 char **path;
3671                 /* Find the appropriate directory... */
3672                 dir = 0;
3673                 if (!state->file && exists(cwd, filename)) {
3674                         dir = cwd;
3675                 }
3676                 if (local && state->file && exists(state->file->dirname, filename)) {
3677                         dir = state->file->dirname;
3678                 }
3679                 for(path = include_paths; !dir && *path; path++) {
3680                         if (exists(*path, filename)) {
3681                                 dir = *path;
3682                         }
3683                 }
3684                 if (!dir) {
3685                         error(state, 0, "Cannot find `%s'\n", filename);
3686                 }
3687                 dirlen = strlen(dir);
3688                 file->dirname = xmalloc(dirlen + 1 + subdir_len + 1, "dirname");
3689                 memcpy(file->dirname, dir, dirlen);
3690                 file->dirname[dirlen] = '/';
3691                 memcpy(file->dirname + dirlen + 1, subdir, subdir_len);
3692                 file->dirname[dirlen + 1 + subdir_len] = '\0';
3693         }
3694         file->buf = slurp_file(file->dirname, file->basename, &file->size);
3695         xchdir(cwd);
3696
3697         file->pos = file->buf;
3698         file->line_start = file->pos;
3699         file->line = 1;
3700
3701         file->report_line = 1;
3702         file->report_name = file->basename;
3703         file->report_dir  = file->dirname;
3704
3705         file->prev = state->file;
3706         state->file = file;
3707         
3708         process_trigraphs(state);
3709         splice_lines(state);
3710 }
3711
3712 /* Type helper functions */
3713
3714 static struct type *new_type(
3715         unsigned int type, struct type *left, struct type *right)
3716 {
3717         struct type *result;
3718         result = xmalloc(sizeof(*result), "type");
3719         result->type = type;
3720         result->left = left;
3721         result->right = right;
3722         result->field_ident = 0;
3723         result->type_ident = 0;
3724         return result;
3725 }
3726
3727 static struct type *clone_type(unsigned int specifiers, struct type *old)
3728 {
3729         struct type *result;
3730         result = xmalloc(sizeof(*result), "type");
3731         memcpy(result, old, sizeof(*result));
3732         result->type &= TYPE_MASK;
3733         result->type |= specifiers;
3734         return result;
3735 }
3736
3737 #define SIZEOF_SHORT 2
3738 #define SIZEOF_INT   4
3739 #define SIZEOF_LONG  (sizeof(long_t))
3740
3741 #define ALIGNOF_SHORT 2
3742 #define ALIGNOF_INT   4
3743 #define ALIGNOF_LONG  (sizeof(long_t))
3744
3745 #define MASK_UCHAR(X)    ((X) & ((ulong_t)0xff))
3746 #define MASK_USHORT(X)   ((X) & (((ulong_t)1 << (SIZEOF_SHORT*8)) - 1))
3747 static inline ulong_t mask_uint(ulong_t x)
3748 {
3749         if (SIZEOF_INT < SIZEOF_LONG) {
3750                 ulong_t mask = (((ulong_t)1) << ((ulong_t)(SIZEOF_INT*8))) -1;
3751                 x &= mask;
3752         }
3753         return x;
3754 }
3755 #define MASK_UINT(X)      (mask_uint(X))
3756 #define MASK_ULONG(X)    (X)
3757
3758 static struct type void_type   = { .type  = TYPE_VOID };
3759 static struct type char_type   = { .type  = TYPE_CHAR };
3760 static struct type uchar_type  = { .type  = TYPE_UCHAR };
3761 static struct type short_type  = { .type  = TYPE_SHORT };
3762 static struct type ushort_type = { .type  = TYPE_USHORT };
3763 static struct type int_type    = { .type  = TYPE_INT };
3764 static struct type uint_type   = { .type  = TYPE_UINT };
3765 static struct type long_type   = { .type  = TYPE_LONG };
3766 static struct type ulong_type  = { .type  = TYPE_ULONG };
3767
3768 static struct triple *variable(struct compile_state *state, struct type *type)
3769 {
3770         struct triple *result;
3771         if ((type->type & STOR_MASK) != STOR_PERM) {
3772                 if ((type->type & TYPE_MASK) != TYPE_STRUCT) {
3773                         result = triple(state, OP_ADECL, type, 0, 0);
3774                 } else {
3775                         struct type *field;
3776                         struct triple **vector;
3777                         ulong_t index;
3778                         result = new_triple(state, OP_VAL_VEC, type, -1, -1);
3779                         vector = &result->param[0];
3780
3781                         field = type->left;
3782                         index = 0;
3783                         while((field->type & TYPE_MASK) == TYPE_PRODUCT) {
3784                                 vector[index] = variable(state, field->left);
3785                                 field = field->right;
3786                                 index++;
3787                         }
3788                         vector[index] = variable(state, field);
3789                 }
3790         }
3791         else {
3792                 result = triple(state, OP_SDECL, type, 0, 0);
3793         }
3794         return result;
3795 }
3796
3797 static void stor_of(FILE *fp, struct type *type)
3798 {
3799         switch(type->type & STOR_MASK) {
3800         case STOR_AUTO:
3801                 fprintf(fp, "auto ");
3802                 break;
3803         case STOR_STATIC:
3804                 fprintf(fp, "static ");
3805                 break;
3806         case STOR_EXTERN:
3807                 fprintf(fp, "extern ");
3808                 break;
3809         case STOR_REGISTER:
3810                 fprintf(fp, "register ");
3811                 break;
3812         case STOR_TYPEDEF:
3813                 fprintf(fp, "typedef ");
3814                 break;
3815         case STOR_INLINE:
3816                 fprintf(fp, "inline ");
3817                 break;
3818         }
3819 }
3820 static void qual_of(FILE *fp, struct type *type)
3821 {
3822         if (type->type & QUAL_CONST) {
3823                 fprintf(fp, " const");
3824         }
3825         if (type->type & QUAL_VOLATILE) {
3826                 fprintf(fp, " volatile");
3827         }
3828         if (type->type & QUAL_RESTRICT) {
3829                 fprintf(fp, " restrict");
3830         }
3831 }
3832
3833 static void name_of(FILE *fp, struct type *type)
3834 {
3835         stor_of(fp, type);
3836         switch(type->type & TYPE_MASK) {
3837         case TYPE_VOID:
3838                 fprintf(fp, "void");
3839                 qual_of(fp, type);
3840                 break;
3841         case TYPE_CHAR:
3842                 fprintf(fp, "signed char");
3843                 qual_of(fp, type);
3844                 break;
3845         case TYPE_UCHAR:
3846                 fprintf(fp, "unsigned char");
3847                 qual_of(fp, type);
3848                 break;
3849         case TYPE_SHORT:
3850                 fprintf(fp, "signed short");
3851                 qual_of(fp, type);
3852                 break;
3853         case TYPE_USHORT:
3854                 fprintf(fp, "unsigned short");
3855                 qual_of(fp, type);
3856                 break;
3857         case TYPE_INT:
3858                 fprintf(fp, "signed int");
3859                 qual_of(fp, type);
3860                 break;
3861         case TYPE_UINT:
3862                 fprintf(fp, "unsigned int");
3863                 qual_of(fp, type);
3864                 break;
3865         case TYPE_LONG:
3866                 fprintf(fp, "signed long");
3867                 qual_of(fp, type);
3868                 break;
3869         case TYPE_ULONG:
3870                 fprintf(fp, "unsigned long");
3871                 qual_of(fp, type);
3872                 break;
3873         case TYPE_POINTER:
3874                 name_of(fp, type->left);
3875                 fprintf(fp, " * ");
3876                 qual_of(fp, type);
3877                 break;
3878         case TYPE_PRODUCT:
3879         case TYPE_OVERLAP:
3880                 name_of(fp, type->left);
3881                 fprintf(fp, ", ");
3882                 name_of(fp, type->right);
3883                 break;
3884         case TYPE_ENUM:
3885                 fprintf(fp, "enum %s", type->type_ident->name);
3886                 qual_of(fp, type);
3887                 break;
3888         case TYPE_STRUCT:
3889                 fprintf(fp, "struct %s", type->type_ident->name);
3890                 qual_of(fp, type);
3891                 break;
3892         case TYPE_FUNCTION:
3893         {
3894                 name_of(fp, type->left);
3895                 fprintf(fp, " (*)(");
3896                 name_of(fp, type->right);
3897                 fprintf(fp, ")");
3898                 break;
3899         }
3900         case TYPE_ARRAY:
3901                 name_of(fp, type->left);
3902                 fprintf(fp, " [%ld]", type->elements);
3903                 break;
3904         default:
3905                 fprintf(fp, "????: %x", type->type & TYPE_MASK);
3906                 break;
3907         }
3908 }
3909
3910 static size_t align_of(struct compile_state *state, struct type *type)
3911 {
3912         size_t align;
3913         align = 0;
3914         switch(type->type & TYPE_MASK) {
3915         case TYPE_VOID:
3916                 align = 1;
3917                 break;
3918         case TYPE_CHAR:
3919         case TYPE_UCHAR:
3920                 align = 1;
3921                 break;
3922         case TYPE_SHORT:
3923         case TYPE_USHORT:
3924                 align = ALIGNOF_SHORT;
3925                 break;
3926         case TYPE_INT:
3927         case TYPE_UINT:
3928         case TYPE_ENUM:
3929                 align = ALIGNOF_INT;
3930                 break;
3931         case TYPE_LONG:
3932         case TYPE_ULONG:
3933         case TYPE_POINTER:
3934                 align = ALIGNOF_LONG;
3935                 break;
3936         case TYPE_PRODUCT:
3937         case TYPE_OVERLAP:
3938         {
3939                 size_t left_align, right_align;
3940                 left_align  = align_of(state, type->left);
3941                 right_align = align_of(state, type->right);
3942                 align = (left_align >= right_align) ? left_align : right_align;
3943                 break;
3944         }
3945         case TYPE_ARRAY:
3946                 align = align_of(state, type->left);
3947                 break;
3948         case TYPE_STRUCT:
3949                 align = align_of(state, type->left);
3950                 break;
3951         default:
3952                 error(state, 0, "alignof not yet defined for type\n");
3953                 break;
3954         }
3955         return align;
3956 }
3957
3958 static size_t needed_padding(size_t offset, size_t align)
3959 {
3960         size_t padding;
3961         padding = 0;
3962         if (offset % align) {
3963                 padding = align - (offset % align);
3964         }
3965         return padding;
3966 }
3967 static size_t size_of(struct compile_state *state, struct type *type)
3968 {
3969         size_t size;
3970         size = 0;
3971         switch(type->type & TYPE_MASK) {
3972         case TYPE_VOID:
3973                 size = 0;
3974                 break;
3975         case TYPE_CHAR:
3976         case TYPE_UCHAR:
3977                 size = 1;
3978                 break;
3979         case TYPE_SHORT:
3980         case TYPE_USHORT:
3981                 size = SIZEOF_SHORT;
3982                 break;
3983         case TYPE_INT:
3984         case TYPE_UINT:
3985         case TYPE_ENUM:
3986                 size = SIZEOF_INT;
3987                 break;
3988         case TYPE_LONG:
3989         case TYPE_ULONG:
3990         case TYPE_POINTER:
3991                 size = SIZEOF_LONG;
3992                 break;
3993         case TYPE_PRODUCT:
3994         {
3995                 size_t align, pad;
3996                 size = 0;
3997                 while((type->type & TYPE_MASK) == TYPE_PRODUCT) {
3998                         align = align_of(state, type->left);
3999                         pad = needed_padding(size, align);
4000                         size = size + pad + size_of(state, type->left);
4001                         type = type->right;
4002                 }
4003                 align = align_of(state, type);
4004                 pad = needed_padding(size, align);
4005                 size = size + pad + sizeof(type);
4006                 break;
4007         }
4008         case TYPE_OVERLAP:
4009         {
4010                 size_t size_left, size_right;
4011                 size_left = size_of(state, type->left);
4012                 size_right = size_of(state, type->right);
4013                 size = (size_left >= size_right)? size_left : size_right;
4014                 break;
4015         }
4016         case TYPE_ARRAY:
4017                 if (type->elements == ELEMENT_COUNT_UNSPECIFIED) {
4018                         internal_error(state, 0, "Invalid array type");
4019                 } else {
4020                         size = size_of(state, type->left) * type->elements;
4021                 }
4022                 break;
4023         case TYPE_STRUCT:
4024                 size = size_of(state, type->left);
4025                 break;
4026         default:
4027                 internal_error(state, 0, "sizeof not yet defined for type\n");
4028                 break;
4029         }
4030         return size;
4031 }
4032
4033 static size_t field_offset(struct compile_state *state, 
4034         struct type *type, struct hash_entry *field)
4035 {
4036         struct type *member;
4037         size_t size, align;
4038         if ((type->type & TYPE_MASK) != TYPE_STRUCT) {
4039                 internal_error(state, 0, "field_offset only works on structures");
4040         }
4041         size = 0;
4042         member = type->left;
4043         while((member->type & TYPE_MASK) == TYPE_PRODUCT) {
4044                 align = align_of(state, member->left);
4045                 size += needed_padding(size, align);
4046                 if (member->left->field_ident == field) {
4047                         member = member->left;
4048                         break;
4049                 }
4050                 size += size_of(state, member->left);
4051                 member = member->right;
4052         }
4053         align = align_of(state, member);
4054         size += needed_padding(size, align);
4055         if (member->field_ident != field) {
4056                 error(state, 0, "member %s not present", field->name);
4057         }
4058         return size;
4059 }
4060
4061 static struct type *field_type(struct compile_state *state, 
4062         struct type *type, struct hash_entry *field)
4063 {
4064         struct type *member;
4065         if ((type->type & TYPE_MASK) != TYPE_STRUCT) {
4066                 internal_error(state, 0, "field_type only works on structures");
4067         }
4068         member = type->left;
4069         while((member->type & TYPE_MASK) == TYPE_PRODUCT) {
4070                 if (member->left->field_ident == field) {
4071                         member = member->left;
4072                         break;
4073                 }
4074                 member = member->right;
4075         }
4076         if (member->field_ident != field) {
4077                 error(state, 0, "member %s not present", field->name);
4078         }
4079         return member;
4080 }
4081
4082 static struct type *next_field(struct compile_state *state,
4083         struct type *type, struct type *prev_member) 
4084 {
4085         struct type *member;
4086         if ((type->type & TYPE_MASK) != TYPE_STRUCT) {
4087                 internal_error(state, 0, "next_field only works on structures");
4088         }
4089         member = type->left;
4090         while((member->type & TYPE_MASK) == TYPE_PRODUCT) {
4091                 if (!prev_member) {
4092                         member = member->left;
4093                         break;
4094                 }
4095                 if (member->left == prev_member) {
4096                         prev_member = 0;
4097                 }
4098                 member = member->right;
4099         }
4100         if (member == prev_member) {
4101                 prev_member = 0;
4102         }
4103         if (prev_member) {
4104                 internal_error(state, 0, "prev_member %s not present", 
4105                         prev_member->field_ident->name);
4106         }
4107         return member;
4108 }
4109
4110 static struct triple *struct_field(struct compile_state *state,
4111         struct triple *decl, struct hash_entry *field)
4112 {
4113         struct triple **vector;
4114         struct type *type;
4115         ulong_t index;
4116         type = decl->type;
4117         if ((type->type & TYPE_MASK) != TYPE_STRUCT) {
4118                 return decl;
4119         }
4120         if (decl->op != OP_VAL_VEC) {
4121                 internal_error(state, 0, "Invalid struct variable");
4122         }
4123         if (!field) {
4124                 internal_error(state, 0, "Missing structure field");
4125         }
4126         type = type->left;
4127         vector = &RHS(decl, 0);
4128         index = 0;
4129         while((type->type & TYPE_MASK) == TYPE_PRODUCT) {
4130                 if (type->left->field_ident == field) {
4131                         type = type->left;
4132                         break;
4133                 }
4134                 index += 1;
4135                 type = type->right;
4136         }
4137         if (type->field_ident != field) {
4138                 internal_error(state, 0, "field %s not found?", field->name);
4139         }
4140         return vector[index];
4141 }
4142
4143 static void arrays_complete(struct compile_state *state, struct type *type)
4144 {
4145         if ((type->type & TYPE_MASK) == TYPE_ARRAY) {
4146                 if (type->elements == ELEMENT_COUNT_UNSPECIFIED) {
4147                         error(state, 0, "array size not specified");
4148                 }
4149                 arrays_complete(state, type->left);
4150         }
4151 }
4152
4153 static unsigned int do_integral_promotion(unsigned int type)
4154 {
4155         type &= TYPE_MASK;
4156         if (TYPE_INTEGER(type) && 
4157                 TYPE_RANK(type) < TYPE_RANK(TYPE_INT)) {
4158                 type = TYPE_INT;
4159         }
4160         return type;
4161 }
4162
4163 static unsigned int do_arithmetic_conversion(
4164         unsigned int left, unsigned int right)
4165 {
4166         left &= TYPE_MASK;
4167         right &= TYPE_MASK;
4168         if ((left == TYPE_LDOUBLE) || (right == TYPE_LDOUBLE)) {
4169                 return TYPE_LDOUBLE;
4170         }
4171         else if ((left == TYPE_DOUBLE) || (right == TYPE_DOUBLE)) {
4172                 return TYPE_DOUBLE;
4173         }
4174         else if ((left == TYPE_FLOAT) || (right == TYPE_FLOAT)) {
4175                 return TYPE_FLOAT;
4176         }
4177         left = do_integral_promotion(left);
4178         right = do_integral_promotion(right);
4179         /* If both operands have the same size done */
4180         if (left == right) {
4181                 return left;
4182         }
4183         /* If both operands have the same signedness pick the larger */
4184         else if (!!TYPE_UNSIGNED(left) == !!TYPE_UNSIGNED(right)) {
4185                 return (TYPE_RANK(left) >= TYPE_RANK(right)) ? left : right;
4186         }
4187         /* If the signed type can hold everything use it */
4188         else if (TYPE_SIGNED(left) && (TYPE_RANK(left) > TYPE_RANK(right))) {
4189                 return left;
4190         }
4191         else if (TYPE_SIGNED(right) && (TYPE_RANK(right) > TYPE_RANK(left))) {
4192                 return right;
4193         }
4194         /* Convert to the unsigned type with the same rank as the signed type */
4195         else if (TYPE_SIGNED(left)) {
4196                 return TYPE_MKUNSIGNED(left);
4197         }
4198         else {
4199                 return TYPE_MKUNSIGNED(right);
4200         }
4201 }
4202
4203 /* see if two types are the same except for qualifiers */
4204 static int equiv_types(struct type *left, struct type *right)
4205 {
4206         unsigned int type;
4207         /* Error if the basic types do not match */
4208         if ((left->type & TYPE_MASK) != (right->type & TYPE_MASK)) {
4209                 return 0;
4210         }
4211         type = left->type & TYPE_MASK;
4212         /* If the basic types match and it is a void type we are done */
4213         if (type == TYPE_VOID) {
4214                 return 1;
4215         }
4216         /* if the basic types match and it is an arithmetic type we are done */
4217         if (TYPE_ARITHMETIC(type)) {
4218                 return 1;
4219         }
4220         /* If it is a pointer type recurse and keep testing */
4221         if (type == TYPE_POINTER) {
4222                 return equiv_types(left->left, right->left);
4223         }
4224         else if (type == TYPE_ARRAY) {
4225                 return (left->elements == right->elements) &&
4226                         equiv_types(left->left, right->left);
4227         }
4228         /* test for struct/union equality */
4229         else if (type == TYPE_STRUCT) {
4230                 return left->type_ident == right->type_ident;
4231         }
4232         /* Test for equivalent functions */
4233         else if (type == TYPE_FUNCTION) {
4234                 return equiv_types(left->left, right->left) &&
4235                         equiv_types(left->right, right->right);
4236         }
4237         /* We only see TYPE_PRODUCT as part of function equivalence matching */
4238         else if (type == TYPE_PRODUCT) {
4239                 return equiv_types(left->left, right->left) &&
4240                         equiv_types(left->right, right->right);
4241         }
4242         /* We should see TYPE_OVERLAP */
4243         else {
4244                 return 0;
4245         }
4246 }
4247
4248 static int equiv_ptrs(struct type *left, struct type *right)
4249 {
4250         if (((left->type & TYPE_MASK) != TYPE_POINTER) ||
4251                 ((right->type & TYPE_MASK) != TYPE_POINTER)) {
4252                 return 0;
4253         }
4254         return equiv_types(left->left, right->left);
4255 }
4256
4257 static struct type *compatible_types(struct type *left, struct type *right)
4258 {
4259         struct type *result;
4260         unsigned int type, qual_type;
4261         /* Error if the basic types do not match */
4262         if ((left->type & TYPE_MASK) != (right->type & TYPE_MASK)) {
4263                 return 0;
4264         }
4265         type = left->type & TYPE_MASK;
4266         qual_type = (left->type & ~STOR_MASK) | (right->type & ~STOR_MASK);
4267         result = 0;
4268         /* if the basic types match and it is an arithmetic type we are done */
4269         if (TYPE_ARITHMETIC(type)) {
4270                 result = new_type(qual_type, 0, 0);
4271         }
4272         /* If it is a pointer type recurse and keep testing */
4273         else if (type == TYPE_POINTER) {
4274                 result = compatible_types(left->left, right->left);
4275                 if (result) {
4276                         result = new_type(qual_type, result, 0);
4277                 }
4278         }
4279         /* test for struct/union equality */
4280         else if (type == TYPE_STRUCT) {
4281                 if (left->type_ident == right->type_ident) {
4282                         result = left;
4283                 }
4284         }
4285         /* Test for equivalent functions */
4286         else if (type == TYPE_FUNCTION) {
4287                 struct type *lf, *rf;
4288                 lf = compatible_types(left->left, right->left);
4289                 rf = compatible_types(left->right, right->right);
4290                 if (lf && rf) {
4291                         result = new_type(qual_type, lf, rf);
4292                 }
4293         }
4294         /* We only see TYPE_PRODUCT as part of function equivalence matching */
4295         else if (type == TYPE_PRODUCT) {
4296                 struct type *lf, *rf;
4297                 lf = compatible_types(left->left, right->left);
4298                 rf = compatible_types(left->right, right->right);
4299                 if (lf && rf) {
4300                         result = new_type(qual_type, lf, rf);
4301                 }
4302         }
4303         else {
4304                 /* Nothing else is compatible */
4305         }
4306         return result;
4307 }
4308
4309 static struct type *compatible_ptrs(struct type *left, struct type *right)
4310 {
4311         struct type *result;
4312         if (((left->type & TYPE_MASK) != TYPE_POINTER) ||
4313                 ((right->type & TYPE_MASK) != TYPE_POINTER)) {
4314                 return 0;
4315         }
4316         result = compatible_types(left->left, right->left);
4317         if (result) {
4318                 unsigned int qual_type;
4319                 qual_type = (left->type & ~STOR_MASK) | (right->type & ~STOR_MASK);
4320                 result = new_type(qual_type, result, 0);
4321         }
4322         return result;
4323         
4324 }
4325 static struct triple *integral_promotion(
4326         struct compile_state *state, struct triple *def)
4327 {
4328         struct type *type;
4329         type = def->type;
4330         /* As all operations are carried out in registers
4331          * the values are converted on load I just convert
4332          * logical type of the operand.
4333          */
4334         if (TYPE_INTEGER(type->type)) {
4335                 unsigned int int_type;
4336                 int_type = type->type & ~TYPE_MASK;
4337                 int_type |= do_integral_promotion(type->type);
4338                 if (int_type != type->type) {
4339                         def->type = new_type(int_type, 0, 0);
4340                 }
4341         }
4342         return def;
4343 }
4344
4345
4346 static void arithmetic(struct compile_state *state, struct triple *def)
4347 {
4348         if (!TYPE_ARITHMETIC(def->type->type)) {
4349                 error(state, 0, "arithmetic type expexted");
4350         }
4351 }
4352
4353 static void ptr_arithmetic(struct compile_state *state, struct triple *def)
4354 {
4355         if (!TYPE_PTR(def->type->type) && !TYPE_ARITHMETIC(def->type->type)) {
4356                 error(state, def, "pointer or arithmetic type expected");
4357         }
4358 }
4359
4360 static int is_integral(struct triple *ins)
4361 {
4362         return TYPE_INTEGER(ins->type->type);
4363 }
4364
4365 static void integral(struct compile_state *state, struct triple *def)
4366 {
4367         if (!is_integral(def)) {
4368                 error(state, 0, "integral type expected");
4369         }
4370 }
4371
4372
4373 static void bool(struct compile_state *state, struct triple *def)
4374 {
4375         if (!TYPE_ARITHMETIC(def->type->type) &&
4376                 ((def->type->type & TYPE_MASK) != TYPE_POINTER)) {
4377                 error(state, 0, "arithmetic or pointer type expected");
4378         }
4379 }
4380
4381 static int is_signed(struct type *type)
4382 {
4383         return !!TYPE_SIGNED(type->type);
4384 }
4385
4386 /* Is this value located in a register otherwise it must be in memory */
4387 static int is_in_reg(struct compile_state *state, struct triple *def)
4388 {
4389         int in_reg;
4390         if (def->op == OP_ADECL) {
4391                 in_reg = 1;
4392         }
4393         else if ((def->op == OP_SDECL) || (def->op == OP_DEREF)) {
4394                 in_reg = 0;
4395         }
4396         else if (def->op == OP_VAL_VEC) {
4397                 in_reg = is_in_reg(state, RHS(def, 0));
4398         }
4399         else if (def->op == OP_DOT) {
4400                 in_reg = is_in_reg(state, RHS(def, 0));
4401         }
4402         else {
4403                 internal_error(state, 0, "unknown expr storage location");
4404                 in_reg = -1;
4405         }
4406         return in_reg;
4407 }
4408
4409 /* Is this a stable variable location otherwise it must be a temporary */
4410 static int is_stable(struct compile_state *state, struct triple *def)
4411 {
4412         int ret;
4413         ret = 0;
4414         if (!def) {
4415                 return 0;
4416         }
4417         if ((def->op == OP_ADECL) || 
4418                 (def->op == OP_SDECL) || 
4419                 (def->op == OP_DEREF) ||
4420                 (def->op == OP_BLOBCONST)) {
4421                 ret = 1;
4422         }
4423         else if (def->op == OP_DOT) {
4424                 ret = is_stable(state, RHS(def, 0));
4425         }
4426         else if (def->op == OP_VAL_VEC) {
4427                 struct triple **vector;
4428                 ulong_t i;
4429                 ret = 1;
4430                 vector = &RHS(def, 0);
4431                 for(i = 0; i < def->type->elements; i++) {
4432                         if (!is_stable(state, vector[i])) {
4433                                 ret = 0;
4434                                 break;
4435                         }
4436                 }
4437         }
4438         return ret;
4439 }
4440
4441 static int is_lvalue(struct compile_state *state, struct triple *def)
4442 {
4443         int ret;
4444         ret = 1;
4445         if (!def) {
4446                 return 0;
4447         }
4448         if (!is_stable(state, def)) {
4449                 return 0;
4450         }
4451         if (def->op == OP_DOT) {
4452                 ret = is_lvalue(state, RHS(def, 0));
4453         }
4454         return ret;
4455 }
4456
4457 static void clvalue(struct compile_state *state, struct triple *def)
4458 {
4459         if (!def) {
4460                 internal_error(state, def, "nothing where lvalue expected?");
4461         }
4462         if (!is_lvalue(state, def)) { 
4463                 error(state, def, "lvalue expected");
4464         }
4465 }
4466 static void lvalue(struct compile_state *state, struct triple *def)
4467 {
4468         clvalue(state, def);
4469         if (def->type->type & QUAL_CONST) {
4470                 error(state, def, "modifable lvalue expected");
4471         }
4472 }
4473
4474 static int is_pointer(struct triple *def)
4475 {
4476         return (def->type->type & TYPE_MASK) == TYPE_POINTER;
4477 }
4478
4479 static void pointer(struct compile_state *state, struct triple *def)
4480 {
4481         if (!is_pointer(def)) {
4482                 error(state, def, "pointer expected");
4483         }
4484 }
4485
4486 static struct triple *int_const(
4487         struct compile_state *state, struct type *type, ulong_t value)
4488 {
4489         struct triple *result;
4490         switch(type->type & TYPE_MASK) {
4491         case TYPE_CHAR:
4492         case TYPE_INT:   case TYPE_UINT:
4493         case TYPE_LONG:  case TYPE_ULONG:
4494                 break;
4495         default:
4496                 internal_error(state, 0, "constant for unkown type");
4497         }
4498         result = triple(state, OP_INTCONST, type, 0, 0);
4499         result->u.cval = value;
4500         return result;
4501 }
4502
4503
4504 static struct triple *do_mk_addr_expr(struct compile_state *state, 
4505         struct triple *expr, struct type *type, ulong_t offset)
4506 {
4507         struct triple *result;
4508         clvalue(state, expr);
4509
4510         type = new_type(TYPE_POINTER | (type->type & QUAL_MASK), type, 0);
4511
4512         result = 0;
4513         if (expr->op == OP_ADECL) {
4514                 error(state, expr, "address of auto variables not supported");
4515         }
4516         else if (expr->op == OP_SDECL) {
4517                 result = triple(state, OP_ADDRCONST, type, 0, 0);
4518                 MISC(result, 0) = expr;
4519                 result->u.cval = offset;
4520         }
4521         else if (expr->op == OP_DEREF) {
4522                 result = triple(state, OP_ADD, type,
4523                         RHS(expr, 0),
4524                         int_const(state, &ulong_type, offset));
4525         }
4526         return result;
4527 }
4528
4529 static struct triple *mk_addr_expr(
4530         struct compile_state *state, struct triple *expr, ulong_t offset)
4531 {
4532         return do_mk_addr_expr(state, expr, expr->type, offset);
4533 }
4534
4535 static struct triple *mk_deref_expr(
4536         struct compile_state *state, struct triple *expr)
4537 {
4538         struct type *base_type;
4539         pointer(state, expr);
4540         base_type = expr->type->left;
4541         return triple(state, OP_DEREF, base_type, expr, 0);
4542 }
4543
4544 static struct triple *array_to_pointer(struct compile_state *state, struct triple *def)
4545 {
4546         if ((def->type->type & TYPE_MASK) == TYPE_ARRAY) {
4547                 struct type *type;
4548                 type = new_type(
4549                         TYPE_POINTER | (def->type->type & QUAL_MASK),
4550                         def->type->left, 0);
4551                 if ((def->op == OP_SDECL) || IS_CONST_OP(def->op)) {
4552                         struct triple *addrconst;
4553                         if ((def->op != OP_SDECL) && (def->op != OP_BLOBCONST)) {
4554                                 internal_error(state, def, "bad array constant");
4555                         }
4556                         addrconst = triple(state, OP_ADDRCONST, type, 0, 0);
4557                         MISC(addrconst, 0) = def;
4558                         def = addrconst;
4559                 }
4560                 else {
4561                         def = triple(state, OP_COPY, type, def, 0);
4562                 }
4563         }
4564         return def;
4565 }
4566
4567 static struct triple *deref_field(
4568         struct compile_state *state, struct triple *expr, struct hash_entry *field)
4569 {
4570         struct triple *result;
4571         struct type *type, *member;
4572         if (!field) {
4573                 internal_error(state, 0, "No field passed to deref_field");
4574         }
4575         result = 0;
4576         type = expr->type;
4577         if ((type->type & TYPE_MASK) != TYPE_STRUCT) {
4578                 error(state, 0, "request for member %s in something not a struct or union",
4579                         field->name);
4580         }
4581         member = field_type(state, type, field);
4582         if ((type->type & STOR_MASK) == STOR_PERM) {
4583                 /* Do the pointer arithmetic to get a deref the field */
4584                 ulong_t offset;
4585                 offset = field_offset(state, type, field);
4586                 result = do_mk_addr_expr(state, expr, member, offset);
4587                 result = mk_deref_expr(state, result);
4588         }
4589         else {
4590                 /* Find the variable for the field I want. */
4591                 result = triple(state, OP_DOT, member, expr, 0);
4592                 result->u.field = field;
4593         }
4594         return result;
4595 }
4596
4597 static struct triple *read_expr(struct compile_state *state, struct triple *def)
4598 {
4599         int op;
4600         if  (!def) {
4601                 return 0;
4602         }
4603         if (!is_stable(state, def)) {
4604                 return def;
4605         }
4606         /* Tranform an array to a pointer to the first element */
4607         
4608 #warning "CHECK_ME is this the right place to transform arrays to pointers?"
4609         if ((def->type->type & TYPE_MASK) == TYPE_ARRAY) {
4610                 return array_to_pointer(state, def);
4611         }
4612         if (is_in_reg(state, def)) {
4613                 op = OP_READ;
4614         } else {
4615                 op = OP_LOAD;
4616         }
4617         return triple(state, op, def->type, def, 0);
4618 }
4619
4620 static void write_compatible(struct compile_state *state,
4621         struct type *dest, struct type *rval)
4622 {
4623         int compatible = 0;
4624         /* Both operands have arithmetic type */
4625         if (TYPE_ARITHMETIC(dest->type) && TYPE_ARITHMETIC(rval->type)) {
4626                 compatible = 1;
4627         }
4628         /* One operand is a pointer and the other is a pointer to void */
4629         else if (((dest->type & TYPE_MASK) == TYPE_POINTER) &&
4630                 ((rval->type & TYPE_MASK) == TYPE_POINTER) &&
4631                 (((dest->left->type & TYPE_MASK) == TYPE_VOID) ||
4632                         ((rval->left->type & TYPE_MASK) == TYPE_VOID))) {
4633                 compatible = 1;
4634         }
4635         /* If both types are the same without qualifiers we are good */
4636         else if (equiv_ptrs(dest, rval)) {
4637                 compatible = 1;
4638         }
4639         /* test for struct/union equality  */
4640         else if (((dest->type & TYPE_MASK) == TYPE_STRUCT) &&
4641                 ((rval->type & TYPE_MASK) == TYPE_STRUCT) &&
4642                 (dest->type_ident == rval->type_ident)) {
4643                 compatible = 1;
4644         }
4645         if (!compatible) {
4646                 error(state, 0, "Incompatible types in assignment");
4647         }
4648 }
4649
4650 static struct triple *write_expr(
4651         struct compile_state *state, struct triple *dest, struct triple *rval)
4652 {
4653         struct triple *def;
4654         int op;
4655
4656         def = 0;
4657         if (!rval) {
4658                 internal_error(state, 0, "missing rval");
4659         }
4660
4661         if (rval->op == OP_LIST) {
4662                 internal_error(state, 0, "expression of type OP_LIST?");
4663         }
4664         if (!is_lvalue(state, dest)) {
4665                 internal_error(state, 0, "writing to a non lvalue?");
4666         }
4667         if (dest->type->type & QUAL_CONST) {
4668                 internal_error(state, 0, "modifable lvalue expexted");
4669         }
4670
4671         write_compatible(state, dest->type, rval->type);
4672
4673         /* Now figure out which assignment operator to use */
4674         op = -1;
4675         if (is_in_reg(state, dest)) {
4676                 op = OP_WRITE;
4677         } else {
4678                 op = OP_STORE;
4679         }
4680         def = triple(state, op, dest->type, dest, rval);
4681         return def;
4682 }
4683
4684 static struct triple *init_expr(
4685         struct compile_state *state, struct triple *dest, struct triple *rval)
4686 {
4687         struct triple *def;
4688
4689         def = 0;
4690         if (!rval) {
4691                 internal_error(state, 0, "missing rval");
4692         }
4693         if ((dest->type->type & STOR_MASK) != STOR_PERM) {
4694                 rval = read_expr(state, rval);
4695                 def = write_expr(state, dest, rval);
4696         }
4697         else {
4698                 /* Fill in the array size if necessary */
4699                 if (((dest->type->type & TYPE_MASK) == TYPE_ARRAY) &&
4700                         ((rval->type->type & TYPE_MASK) == TYPE_ARRAY)) {
4701                         if (dest->type->elements == ELEMENT_COUNT_UNSPECIFIED) {
4702                                 dest->type->elements = rval->type->elements;
4703                         }
4704                 }
4705                 if (!equiv_types(dest->type, rval->type)) {
4706                         error(state, 0, "Incompatible types in inializer");
4707                 }
4708                 MISC(dest, 0) = rval;
4709                 insert_triple(state, dest, rval);
4710                 rval->id |= TRIPLE_FLAG_FLATTENED;
4711                 use_triple(MISC(dest, 0), dest);
4712         }
4713         return def;
4714 }
4715
4716 struct type *arithmetic_result(
4717         struct compile_state *state, struct triple *left, struct triple *right)
4718 {
4719         struct type *type;
4720         /* Sanity checks to ensure I am working with arithmetic types */
4721         arithmetic(state, left);
4722         arithmetic(state, right);
4723         type = new_type(
4724                 do_arithmetic_conversion(
4725                         left->type->type, 
4726                         right->type->type), 0, 0);
4727         return type;
4728 }
4729
4730 struct type *ptr_arithmetic_result(
4731         struct compile_state *state, struct triple *left, struct triple *right)
4732 {
4733         struct type *type;
4734         /* Sanity checks to ensure I am working with the proper types */
4735         ptr_arithmetic(state, left);
4736         arithmetic(state, right);
4737         if (TYPE_ARITHMETIC(left->type->type) && 
4738                 TYPE_ARITHMETIC(right->type->type)) {
4739                 type = arithmetic_result(state, left, right);
4740         }
4741         else if (TYPE_PTR(left->type->type)) {
4742                 type = left->type;
4743         }
4744         else {
4745                 internal_error(state, 0, "huh?");
4746                 type = 0;
4747         }
4748         return type;
4749 }
4750
4751
4752 /* boolean helper function */
4753
4754 static struct triple *ltrue_expr(struct compile_state *state, 
4755         struct triple *expr)
4756 {
4757         switch(expr->op) {
4758         case OP_LTRUE:   case OP_LFALSE:  case OP_EQ:      case OP_NOTEQ:
4759         case OP_SLESS:   case OP_ULESS:   case OP_SMORE:   case OP_UMORE:
4760         case OP_SLESSEQ: case OP_ULESSEQ: case OP_SMOREEQ: case OP_UMOREEQ:
4761                 /* If the expression is already boolean do nothing */
4762                 break;
4763         default:
4764                 expr = triple(state, OP_LTRUE, &int_type, expr, 0);
4765                 break;
4766         }
4767         return expr;
4768 }
4769
4770 static struct triple *lfalse_expr(struct compile_state *state, 
4771         struct triple *expr)
4772 {
4773         return triple(state, OP_LFALSE, &int_type, expr, 0);
4774 }
4775
4776 static struct triple *cond_expr(
4777         struct compile_state *state, 
4778         struct triple *test, struct triple *left, struct triple *right)
4779 {
4780         struct triple *def;
4781         struct type *result_type;
4782         unsigned int left_type, right_type;
4783         bool(state, test);
4784         left_type = left->type->type;
4785         right_type = right->type->type;
4786         result_type = 0;
4787         /* Both operands have arithmetic type */
4788         if (TYPE_ARITHMETIC(left_type) && TYPE_ARITHMETIC(right_type)) {
4789                 result_type = arithmetic_result(state, left, right);
4790         }
4791         /* Both operands have void type */
4792         else if (((left_type & TYPE_MASK) == TYPE_VOID) &&
4793                 ((right_type & TYPE_MASK) == TYPE_VOID)) {
4794                 result_type = &void_type;
4795         }
4796         /* pointers to the same type... */
4797         else if ((result_type = compatible_ptrs(left->type, right->type))) {
4798                 ;
4799         }
4800         /* Both operands are pointers and left is a pointer to void */
4801         else if (((left_type & TYPE_MASK) == TYPE_POINTER) &&
4802                 ((right_type & TYPE_MASK) == TYPE_POINTER) &&
4803                 ((left->type->left->type & TYPE_MASK) == TYPE_VOID)) {
4804                 result_type = right->type;
4805         }
4806         /* Both operands are pointers and right is a pointer to void */
4807         else if (((left_type & TYPE_MASK) == TYPE_POINTER) &&
4808                 ((right_type & TYPE_MASK) == TYPE_POINTER) &&
4809                 ((right->type->left->type & TYPE_MASK) == TYPE_VOID)) {
4810                 result_type = left->type;
4811         }
4812         if (!result_type) {
4813                 error(state, 0, "Incompatible types in conditional expression");
4814         }
4815         /* Cleanup and invert the test */
4816         test = lfalse_expr(state, read_expr(state, test));
4817         def = new_triple(state, OP_COND, result_type, 0, 3);
4818         def->param[0] = test;
4819         def->param[1] = left;
4820         def->param[2] = right;
4821         return def;
4822 }
4823
4824
4825 static int expr_depth(struct compile_state *state, struct triple *ins)
4826 {
4827         int count;
4828         count = 0;
4829         if (!ins || (ins->id & TRIPLE_FLAG_FLATTENED)) {
4830                 count = 0;
4831         }
4832         else if (ins->op == OP_DEREF) {
4833                 count = expr_depth(state, RHS(ins, 0)) - 1;
4834         }
4835         else if (ins->op == OP_VAL) {
4836                 count = expr_depth(state, RHS(ins, 0)) - 1;
4837         }
4838         else if (ins->op == OP_COMMA) {
4839                 int ldepth, rdepth;
4840                 ldepth = expr_depth(state, RHS(ins, 0));
4841                 rdepth = expr_depth(state, RHS(ins, 1));
4842                 count = (ldepth >= rdepth)? ldepth : rdepth;
4843         }
4844         else if (ins->op == OP_CALL) {
4845                 /* Don't figure the depth of a call just guess it is huge */
4846                 count = 1000;
4847         }
4848         else {
4849                 struct triple **expr;
4850                 expr = triple_rhs(state, ins, 0);
4851                 for(;expr; expr = triple_rhs(state, ins, expr)) {
4852                         if (*expr) {
4853                                 int depth;
4854                                 depth = expr_depth(state, *expr);
4855                                 if (depth > count) {
4856                                         count = depth;
4857                                 }
4858                         }
4859                 }
4860         }
4861         return count + 1;
4862 }
4863
4864 static struct triple *flatten(
4865         struct compile_state *state, struct triple *first, struct triple *ptr);
4866
4867 static struct triple *flatten_generic(
4868         struct compile_state *state, struct triple *first, struct triple *ptr)
4869 {
4870         struct rhs_vector {
4871                 int depth;
4872                 struct triple **ins;
4873         } vector[MAX_RHS];
4874         int i, rhs, lhs;
4875         /* Only operations with just a rhs should come here */
4876         rhs = TRIPLE_RHS(ptr->sizes);
4877         lhs = TRIPLE_LHS(ptr->sizes);
4878         if (TRIPLE_SIZE(ptr->sizes) != lhs + rhs) {
4879                 internal_error(state, ptr, "unexpected args for: %d %s",
4880                         ptr->op, tops(ptr->op));
4881         }
4882         /* Find the depth of the rhs elements */
4883         for(i = 0; i < rhs; i++) {
4884                 vector[i].ins = &RHS(ptr, i);
4885                 vector[i].depth = expr_depth(state, *vector[i].ins);
4886         }
4887         /* Selection sort the rhs */
4888         for(i = 0; i < rhs; i++) {
4889                 int j, max = i;
4890                 for(j = i + 1; j < rhs; j++ ) {
4891                         if (vector[j].depth > vector[max].depth) {
4892                                 max = j;
4893                         }
4894                 }
4895                 if (max != i) {
4896                         struct rhs_vector tmp;
4897                         tmp = vector[i];
4898                         vector[i] = vector[max];
4899                         vector[max] = tmp;
4900                 }
4901         }
4902         /* Now flatten the rhs elements */
4903         for(i = 0; i < rhs; i++) {
4904                 *vector[i].ins = flatten(state, first, *vector[i].ins);
4905                 use_triple(*vector[i].ins, ptr);
4906         }
4907         
4908         /* Now flatten the lhs elements */
4909         for(i = 0; i < lhs; i++) {
4910                 struct triple **ins = &LHS(ptr, i);
4911                 *ins = flatten(state, first, *ins);
4912                 use_triple(*ins, ptr);
4913         }
4914         return ptr;
4915 }
4916
4917 static struct triple *flatten_land(
4918         struct compile_state *state, struct triple *first, struct triple *ptr)
4919 {
4920         struct triple *left, *right;
4921         struct triple *val, *test, *jmp, *label1, *end;
4922
4923         /* Find the triples */
4924         left = RHS(ptr, 0);
4925         right = RHS(ptr, 1);
4926
4927         /* Generate the needed triples */
4928         end = label(state);
4929
4930         /* Thread the triples together */
4931         val          = flatten(state, first, variable(state, ptr->type));
4932         left         = flatten(state, first, write_expr(state, val, left));
4933         test         = flatten(state, first, 
4934                 lfalse_expr(state, read_expr(state, val)));
4935         jmp          = flatten(state, first, branch(state, end, test));
4936         label1       = flatten(state, first, label(state));
4937         right        = flatten(state, first, write_expr(state, val, right));
4938         TARG(jmp, 0) = flatten(state, first, end); 
4939         
4940         /* Now give the caller something to chew on */
4941         return read_expr(state, val);
4942 }
4943
4944 static struct triple *flatten_lor(
4945         struct compile_state *state, struct triple *first, struct triple *ptr)
4946 {
4947         struct triple *left, *right;
4948         struct triple *val, *jmp, *label1, *end;
4949
4950         /* Find the triples */
4951         left = RHS(ptr, 0);
4952         right = RHS(ptr, 1);
4953
4954         /* Generate the needed triples */
4955         end = label(state);
4956
4957         /* Thread the triples together */
4958         val          = flatten(state, first, variable(state, ptr->type));
4959         left         = flatten(state, first, write_expr(state, val, left));
4960         jmp          = flatten(state, first, branch(state, end, left));
4961         label1       = flatten(state, first, label(state));
4962         right        = flatten(state, first, write_expr(state, val, right));
4963         TARG(jmp, 0) = flatten(state, first, end);
4964        
4965         
4966         /* Now give the caller something to chew on */
4967         return read_expr(state, val);
4968 }
4969
4970 static struct triple *flatten_cond(
4971         struct compile_state *state, struct triple *first, struct triple *ptr)
4972 {
4973         struct triple *test, *left, *right;
4974         struct triple *val, *mv1, *jmp1, *label1, *mv2, *middle, *jmp2, *end;
4975
4976         /* Find the triples */
4977         test = RHS(ptr, 0);
4978         left = RHS(ptr, 1);
4979         right = RHS(ptr, 2);
4980
4981         /* Generate the needed triples */
4982         end = label(state);
4983         middle = label(state);
4984
4985         /* Thread the triples together */
4986         val           = flatten(state, first, variable(state, ptr->type));
4987         test          = flatten(state, first, test);
4988         jmp1          = flatten(state, first, branch(state, middle, test));
4989         label1        = flatten(state, first, label(state));
4990         left          = flatten(state, first, left);
4991         mv1           = flatten(state, first, write_expr(state, val, left));
4992         jmp2          = flatten(state, first, branch(state, end, 0));
4993         TARG(jmp1, 0) = flatten(state, first, middle);
4994         right         = flatten(state, first, right);
4995         mv2           = flatten(state, first, write_expr(state, val, right));
4996         TARG(jmp2, 0) = flatten(state, first, end);
4997         
4998         /* Now give the caller something to chew on */
4999         return read_expr(state, val);
5000 }
5001
5002 struct triple *copy_func(struct compile_state *state, struct triple *ofunc, 
5003         struct occurance *base_occurance)
5004 {
5005         struct triple *nfunc;
5006         struct triple *nfirst, *ofirst;
5007         struct triple *new, *old;
5008
5009 #if 0
5010         fprintf(stdout, "\n");
5011         loc(stdout, state, 0);
5012         fprintf(stdout, "\n__________ copy_func _________\n");
5013         print_triple(state, ofunc);
5014         fprintf(stdout, "__________ copy_func _________ done\n\n");
5015 #endif
5016
5017         /* Make a new copy of the old function */
5018         nfunc = triple(state, OP_LIST, ofunc->type, 0, 0);
5019         nfirst = 0;
5020         ofirst = old = RHS(ofunc, 0);
5021         do {
5022                 struct triple *new;
5023                 struct occurance *occurance;
5024                 int old_lhs, old_rhs;
5025                 old_lhs = TRIPLE_LHS(old->sizes);
5026                 old_rhs = TRIPLE_RHS(old->sizes);
5027                 occurance = inline_occurance(state, base_occurance, old->occurance);
5028                 new = alloc_triple(state, old->op, old->type, old_lhs, old_rhs,
5029                         occurance);
5030                 if (!triple_stores_block(state, new)) {
5031                         memcpy(&new->u, &old->u, sizeof(new->u));
5032                 }
5033                 if (!nfirst) {
5034                         RHS(nfunc, 0) = nfirst = new;
5035                 }
5036                 else {
5037                         insert_triple(state, nfirst, new);
5038                 }
5039                 new->id |= TRIPLE_FLAG_FLATTENED;
5040                 
5041                 /* During the copy remember new as user of old */
5042                 use_triple(old, new);
5043
5044                 /* Populate the return type if present */
5045                 if (old == MISC(ofunc, 0)) {
5046                         MISC(nfunc, 0) = new;
5047                 }
5048                 old = old->next;
5049         } while(old != ofirst);
5050
5051         /* Make a second pass to fix up any unresolved references */
5052         old = ofirst;
5053         new = nfirst;
5054         do {
5055                 struct triple **oexpr, **nexpr;
5056                 int count, i;
5057                 /* Lookup where the copy is, to join pointers */
5058                 count = TRIPLE_SIZE(old->sizes);
5059                 for(i = 0; i < count; i++) {
5060                         oexpr = &old->param[i];
5061                         nexpr = &new->param[i];
5062                         if (!*nexpr && *oexpr && (*oexpr)->use) {
5063                                 *nexpr = (*oexpr)->use->member;
5064                                 if (*nexpr == old) {
5065                                         internal_error(state, 0, "new == old?");
5066                                 }
5067                                 use_triple(*nexpr, new);
5068                         }
5069                         if (!*nexpr && *oexpr) {
5070                                 internal_error(state, 0, "Could not copy %d\n", i);
5071                         }
5072                 }
5073                 old = old->next;
5074                 new = new->next;
5075         } while((old != ofirst) && (new != nfirst));
5076         
5077         /* Make a third pass to cleanup the extra useses */
5078         old = ofirst;
5079         new = nfirst;
5080         do {
5081                 unuse_triple(old, new);
5082                 old = old->next;
5083                 new = new->next;
5084         } while ((old != ofirst) && (new != nfirst));
5085         return nfunc;
5086 }
5087
5088 static struct triple *flatten_call(
5089         struct compile_state *state, struct triple *first, struct triple *ptr)
5090 {
5091         /* Inline the function call */
5092         struct type *ptype;
5093         struct triple *ofunc, *nfunc, *nfirst, *param, *result;
5094         struct triple *end, *nend;
5095         int pvals, i;
5096
5097         /* Find the triples */
5098         ofunc = MISC(ptr, 0);
5099         if (ofunc->op != OP_LIST) {
5100                 internal_error(state, 0, "improper function");
5101         }
5102         nfunc = copy_func(state, ofunc, ptr->occurance);
5103         nfirst = RHS(nfunc, 0)->next;
5104         /* Prepend the parameter reading into the new function list */
5105         ptype = nfunc->type->right;
5106         param = RHS(nfunc, 0)->next;
5107         pvals = TRIPLE_RHS(ptr->sizes);
5108         for(i = 0; i < pvals; i++) {
5109                 struct type *atype;
5110                 struct triple *arg;
5111                 atype = ptype;
5112                 if ((ptype->type & TYPE_MASK) == TYPE_PRODUCT) {
5113                         atype = ptype->left;
5114                 }
5115                 while((param->type->type & TYPE_MASK) != (atype->type & TYPE_MASK)) {
5116                         param = param->next;
5117                 }
5118                 arg = RHS(ptr, i);
5119                 flatten(state, nfirst, write_expr(state, param, arg));
5120                 ptype = ptype->right;
5121                 param = param->next;
5122         }
5123         result = 0;
5124         if ((nfunc->type->left->type & TYPE_MASK) != TYPE_VOID) {
5125                 result = read_expr(state, MISC(nfunc,0));
5126         }
5127 #if 0
5128         fprintf(stdout, "\n");
5129         loc(stdout, state, 0);
5130         fprintf(stdout, "\n__________ flatten_call _________\n");
5131         print_triple(state, nfunc);
5132         fprintf(stdout, "__________ flatten_call _________ done\n\n");
5133 #endif
5134
5135         /* Get rid of the extra triples */
5136         nfirst = RHS(nfunc, 0)->next;
5137         free_triple(state, RHS(nfunc, 0));
5138         RHS(nfunc, 0) = 0;
5139         free_triple(state, nfunc);
5140
5141         /* Append the new function list onto the return list */
5142         end = first->prev;
5143         nend = nfirst->prev;
5144         end->next    = nfirst;
5145         nfirst->prev = end;
5146         nend->next   = first;
5147         first->prev  = nend;
5148
5149         return result;
5150 }
5151
5152 static struct triple *flatten(
5153         struct compile_state *state, struct triple *first, struct triple *ptr)
5154 {
5155         struct triple *orig_ptr;
5156         if (!ptr)
5157                 return 0;
5158         do {
5159                 orig_ptr = ptr;
5160                 /* Only flatten triples once */
5161                 if (ptr->id & TRIPLE_FLAG_FLATTENED) {
5162                         return ptr;
5163                 }
5164                 switch(ptr->op) {
5165                 case OP_COMMA:
5166                         RHS(ptr, 0) = flatten(state, first, RHS(ptr, 0));
5167                         ptr = RHS(ptr, 1);
5168                         break;
5169                 case OP_VAL:
5170                         RHS(ptr, 0) = flatten(state, first, RHS(ptr, 0));
5171                         return MISC(ptr, 0);
5172                         break;
5173                 case OP_LAND:
5174                         ptr = flatten_land(state, first, ptr);
5175                         break;
5176                 case OP_LOR:
5177                         ptr = flatten_lor(state, first, ptr);
5178                         break;
5179                 case OP_COND:
5180                         ptr = flatten_cond(state, first, ptr);
5181                         break;
5182                 case OP_CALL:
5183                         ptr = flatten_call(state, first, ptr);
5184                         break;
5185                 case OP_READ:
5186                 case OP_LOAD:
5187                         RHS(ptr, 0) = flatten(state, first, RHS(ptr, 0));
5188                         use_triple(RHS(ptr, 0), ptr);
5189                         break;
5190                 case OP_BRANCH:
5191                         use_triple(TARG(ptr, 0), ptr);
5192                         if (TRIPLE_RHS(ptr->sizes)) {
5193                                 use_triple(RHS(ptr, 0), ptr);
5194                                 if (ptr->next != ptr) {
5195                                         use_triple(ptr->next, ptr);
5196                                 }
5197                         }
5198                         break;
5199                 case OP_BLOBCONST:
5200                         insert_triple(state, first, ptr);
5201                         ptr->id |= TRIPLE_FLAG_FLATTENED;
5202                         ptr = triple(state, OP_SDECL, ptr->type, ptr, 0);
5203                         use_triple(MISC(ptr, 0), ptr);
5204                         break;
5205                 case OP_DEREF:
5206                         /* Since OP_DEREF is just a marker delete it when I flatten it */
5207                         ptr = RHS(ptr, 0);
5208                         RHS(orig_ptr, 0) = 0;
5209                         free_triple(state, orig_ptr);
5210                         break;
5211                 case OP_DOT:
5212                 {
5213                         struct triple *base;
5214                         base = RHS(ptr, 0);
5215                         if (base->op == OP_DEREF) {
5216                                 struct triple *left;
5217                                 ulong_t offset;
5218                                 offset = field_offset(state, base->type, ptr->u.field);
5219                                 left = RHS(base, 0);
5220                                 ptr = triple(state, OP_ADD, left->type, 
5221                                         read_expr(state, left),
5222                                         int_const(state, &ulong_type, offset));
5223                                 free_triple(state, base);
5224                         }
5225                         else if (base->op == OP_VAL_VEC) {
5226                                 base = flatten(state, first, base);
5227                                 ptr = struct_field(state, base, ptr->u.field);
5228                         }
5229                         break;
5230                 }
5231                 case OP_PIECE:
5232                         MISC(ptr, 0) = flatten(state, first, MISC(ptr, 0));
5233                         use_triple(MISC(ptr, 0), ptr);
5234                         use_triple(ptr, MISC(ptr, 0));
5235                         break;
5236                 case OP_ADDRCONST:
5237                 case OP_SDECL:
5238                         MISC(ptr, 0) = flatten(state, first, MISC(ptr, 0));
5239                         use_triple(MISC(ptr, 0), ptr);
5240                         break;
5241                 case OP_ADECL:
5242                         break;
5243                 default:
5244                         /* Flatten the easy cases we don't override */
5245                         ptr = flatten_generic(state, first, ptr);
5246                         break;
5247                 }
5248         } while(ptr && (ptr != orig_ptr));
5249         if (ptr) {
5250                 insert_triple(state, first, ptr);
5251                 ptr->id |= TRIPLE_FLAG_FLATTENED;
5252         }
5253         return ptr;
5254 }
5255
5256 static void release_expr(struct compile_state *state, struct triple *expr)
5257 {
5258         struct triple *head;
5259         head = label(state);
5260         flatten(state, head, expr);
5261         while(head->next != head) {
5262                 release_triple(state, head->next);
5263         }
5264         free_triple(state, head);
5265 }
5266
5267 static int replace_rhs_use(struct compile_state *state,
5268         struct triple *orig, struct triple *new, struct triple *use)
5269 {
5270         struct triple **expr;
5271         int found;
5272         found = 0;
5273         expr = triple_rhs(state, use, 0);
5274         for(;expr; expr = triple_rhs(state, use, expr)) {
5275                 if (*expr == orig) {
5276                         *expr = new;
5277                         found = 1;
5278                 }
5279         }
5280         if (found) {
5281                 unuse_triple(orig, use);
5282                 use_triple(new, use);
5283         }
5284         return found;
5285 }
5286
5287 static int replace_lhs_use(struct compile_state *state,
5288         struct triple *orig, struct triple *new, struct triple *use)
5289 {
5290         struct triple **expr;
5291         int found;
5292         found = 0;
5293         expr = triple_lhs(state, use, 0);
5294         for(;expr; expr = triple_lhs(state, use, expr)) {
5295                 if (*expr == orig) {
5296                         *expr = new;
5297                         found = 1;
5298                 }
5299         }
5300         if (found) {
5301                 unuse_triple(orig, use);
5302                 use_triple(new, use);
5303         }
5304         return found;
5305 }
5306
5307 static void propogate_use(struct compile_state *state,
5308         struct triple *orig, struct triple *new)
5309 {
5310         struct triple_set *user, *next;
5311         for(user = orig->use; user; user = next) {
5312                 struct triple *use;
5313                 int found;
5314                 next = user->next;
5315                 use = user->member;
5316                 found = 0;
5317                 found |= replace_rhs_use(state, orig, new, use);
5318                 found |= replace_lhs_use(state, orig, new, use);
5319                 if (!found) {
5320                         internal_error(state, use, "use without use");
5321                 }
5322         }
5323         if (orig->use) {
5324                 internal_error(state, orig, "used after propogate_use");
5325         }
5326 }
5327
5328 /*
5329  * Code generators
5330  * ===========================
5331  */
5332
5333 static struct triple *mk_add_expr(
5334         struct compile_state *state, struct triple *left, struct triple *right)
5335 {
5336         struct type *result_type;
5337         /* Put pointer operands on the left */
5338         if (is_pointer(right)) {
5339                 struct triple *tmp;
5340                 tmp = left;
5341                 left = right;
5342                 right = tmp;
5343         }
5344         left  = read_expr(state, left);
5345         right = read_expr(state, right);
5346         result_type = ptr_arithmetic_result(state, left, right);
5347         if (is_pointer(left)) {
5348                 right = triple(state, 
5349                         is_signed(right->type)? OP_SMUL : OP_UMUL, 
5350                         &ulong_type, 
5351                         right, 
5352                         int_const(state, &ulong_type, 
5353                                 size_of(state, left->type->left)));
5354         }
5355         return triple(state, OP_ADD, result_type, left, right);
5356 }
5357
5358 static struct triple *mk_sub_expr(
5359         struct compile_state *state, struct triple *left, struct triple *right)
5360 {
5361         struct type *result_type;
5362         result_type = ptr_arithmetic_result(state, left, right);
5363         left  = read_expr(state, left);
5364         right = read_expr(state, right);
5365         if (is_pointer(left)) {
5366                 right = triple(state, 
5367                         is_signed(right->type)? OP_SMUL : OP_UMUL, 
5368                         &ulong_type, 
5369                         right, 
5370                         int_const(state, &ulong_type, 
5371                                 size_of(state, left->type->left)));
5372         }
5373         return triple(state, OP_SUB, result_type, left, right);
5374 }
5375
5376 static struct triple *mk_pre_inc_expr(
5377         struct compile_state *state, struct triple *def)
5378 {
5379         struct triple *val;
5380         lvalue(state, def);
5381         val = mk_add_expr(state, def, int_const(state, &int_type, 1));
5382         return triple(state, OP_VAL, def->type,
5383                 write_expr(state, def, val),
5384                 val);
5385 }
5386
5387 static struct triple *mk_pre_dec_expr(
5388         struct compile_state *state, struct triple *def)
5389 {
5390         struct triple *val;
5391         lvalue(state, def);
5392         val = mk_sub_expr(state, def, int_const(state, &int_type, 1));
5393         return triple(state, OP_VAL, def->type,
5394                 write_expr(state, def, val),
5395                 val);
5396 }
5397
5398 static struct triple *mk_post_inc_expr(
5399         struct compile_state *state, struct triple *def)
5400 {
5401         struct triple *val;
5402         lvalue(state, def);
5403         val = read_expr(state, def);
5404         return triple(state, OP_VAL, def->type,
5405                 write_expr(state, def,
5406                         mk_add_expr(state, val, int_const(state, &int_type, 1)))
5407                 , val);
5408 }
5409
5410 static struct triple *mk_post_dec_expr(
5411         struct compile_state *state, struct triple *def)
5412 {
5413         struct triple *val;
5414         lvalue(state, def);
5415         val = read_expr(state, def);
5416         return triple(state, OP_VAL, def->type, 
5417                 write_expr(state, def,
5418                         mk_sub_expr(state, val, int_const(state, &int_type, 1)))
5419                 , val);
5420 }
5421
5422 static struct triple *mk_subscript_expr(
5423         struct compile_state *state, struct triple *left, struct triple *right)
5424 {
5425         left  = read_expr(state, left);
5426         right = read_expr(state, right);
5427         if (!is_pointer(left) && !is_pointer(right)) {
5428                 error(state, left, "subscripted value is not a pointer");
5429         }
5430         return mk_deref_expr(state, mk_add_expr(state, left, right));
5431 }
5432
5433 /*
5434  * Compile time evaluation
5435  * ===========================
5436  */
5437 static int is_const(struct triple *ins)
5438 {
5439         return IS_CONST_OP(ins->op);
5440 }
5441
5442 static int constants_equal(struct compile_state *state, 
5443         struct triple *left, struct triple *right)
5444 {
5445         int equal;
5446         if (!is_const(left) || !is_const(right)) {
5447                 equal = 0;
5448         }
5449         else if (left->op != right->op) {
5450                 equal = 0;
5451         }
5452         else if (!equiv_types(left->type, right->type)) {
5453                 equal = 0;
5454         }
5455         else {
5456                 equal = 0;
5457                 switch(left->op) {
5458                 case OP_INTCONST:
5459                         if (left->u.cval == right->u.cval) {
5460                                 equal = 1;
5461                         }
5462                         break;
5463                 case OP_BLOBCONST:
5464                 {
5465                         size_t lsize, rsize;
5466                         lsize = size_of(state, left->type);
5467                         rsize = size_of(state, right->type);
5468                         if (lsize != rsize) {
5469                                 break;
5470                         }
5471                         if (memcmp(left->u.blob, right->u.blob, lsize) == 0) {
5472                                 equal = 1;
5473                         }
5474                         break;
5475                 }
5476                 case OP_ADDRCONST:
5477                         if ((MISC(left, 0) == MISC(right, 0)) &&
5478                                 (left->u.cval == right->u.cval)) {
5479                                 equal = 1;
5480                         }
5481                         break;
5482                 default:
5483                         internal_error(state, left, "uknown constant type");
5484                         break;
5485                 }
5486         }
5487         return equal;
5488 }
5489
5490 static int is_zero(struct triple *ins)
5491 {
5492         return is_const(ins) && (ins->u.cval == 0);
5493 }
5494
5495 static int is_one(struct triple *ins)
5496 {
5497         return is_const(ins) && (ins->u.cval == 1);
5498 }
5499
5500 static long_t bit_count(ulong_t value)
5501 {
5502         int count;
5503         int i;
5504         count = 0;
5505         for(i = (sizeof(ulong_t)*8) -1; i >= 0; i--) {
5506                 ulong_t mask;
5507                 mask = 1;
5508                 mask <<= i;
5509                 if (value & mask) {
5510                         count++;
5511                 }
5512         }
5513         return count;
5514         
5515 }
5516 static long_t bsr(ulong_t value)
5517 {
5518         int i;
5519         for(i = (sizeof(ulong_t)*8) -1; i >= 0; i--) {
5520                 ulong_t mask;
5521                 mask = 1;
5522                 mask <<= i;
5523                 if (value & mask) {
5524                         return i;
5525                 }
5526         }
5527         return -1;
5528 }
5529
5530 static long_t bsf(ulong_t value)
5531 {
5532         int i;
5533         for(i = 0; i < (sizeof(ulong_t)*8); i++) {
5534                 ulong_t mask;
5535                 mask = 1;
5536                 mask <<= 1;
5537                 if (value & mask) {
5538                         return i;
5539                 }
5540         }
5541         return -1;
5542 }
5543
5544 static long_t log2(ulong_t value)
5545 {
5546         return bsr(value);
5547 }
5548
5549 static long_t tlog2(struct triple *ins)
5550 {
5551         return log2(ins->u.cval);
5552 }
5553
5554 static int is_pow2(struct triple *ins)
5555 {
5556         ulong_t value, mask;
5557         long_t log;
5558         if (!is_const(ins)) {
5559                 return 0;
5560         }
5561         value = ins->u.cval;
5562         log = log2(value);
5563         if (log == -1) {
5564                 return 0;
5565         }
5566         mask = 1;
5567         mask <<= log;
5568         return  ((value & mask) == value);
5569 }
5570
5571 static ulong_t read_const(struct compile_state *state,
5572         struct triple *ins, struct triple **expr)
5573 {
5574         struct triple *rhs;
5575         rhs = *expr;
5576         switch(rhs->type->type &TYPE_MASK) {
5577         case TYPE_CHAR:   
5578         case TYPE_SHORT:
5579         case TYPE_INT:
5580         case TYPE_LONG:
5581         case TYPE_UCHAR:   
5582         case TYPE_USHORT:  
5583         case TYPE_UINT:
5584         case TYPE_ULONG:
5585         case TYPE_POINTER:
5586                 break;
5587         default:
5588                 internal_error(state, rhs, "bad type to read_const\n");
5589                 break;
5590         }
5591         return rhs->u.cval;
5592 }
5593
5594 static long_t read_sconst(struct triple *ins, struct triple **expr)
5595 {
5596         struct triple *rhs;
5597         rhs = *expr;
5598         return (long_t)(rhs->u.cval);
5599 }
5600
5601 static void unuse_rhs(struct compile_state *state, struct triple *ins)
5602 {
5603         struct triple **expr;
5604         expr = triple_rhs(state, ins, 0);
5605         for(;expr;expr = triple_rhs(state, ins, expr)) {
5606                 if (*expr) {
5607                         unuse_triple(*expr, ins);
5608                         *expr = 0;
5609                 }
5610         }
5611 }
5612
5613 static void unuse_lhs(struct compile_state *state, struct triple *ins)
5614 {
5615         struct triple **expr;
5616         expr = triple_lhs(state, ins, 0);
5617         for(;expr;expr = triple_lhs(state, ins, expr)) {
5618                 unuse_triple(*expr, ins);
5619                 *expr = 0;
5620         }
5621 }
5622
5623 static void check_lhs(struct compile_state *state, struct triple *ins)
5624 {
5625         struct triple **expr;
5626         expr = triple_lhs(state, ins, 0);
5627         for(;expr;expr = triple_lhs(state, ins, expr)) {
5628                 internal_error(state, ins, "unexpected lhs");
5629         }
5630         
5631 }
5632 static void check_targ(struct compile_state *state, struct triple *ins)
5633 {
5634         struct triple **expr;
5635         expr = triple_targ(state, ins, 0);
5636         for(;expr;expr = triple_targ(state, ins, expr)) {
5637                 internal_error(state, ins, "unexpected targ");
5638         }
5639 }
5640
5641 static void wipe_ins(struct compile_state *state, struct triple *ins)
5642 {
5643         /* Becareful which instructions you replace the wiped
5644          * instruction with, as there are not enough slots
5645          * in all instructions to hold all others.
5646          */
5647         check_targ(state, ins);
5648         unuse_rhs(state, ins);
5649         unuse_lhs(state, ins);
5650 }
5651
5652 static void mkcopy(struct compile_state *state, 
5653         struct triple *ins, struct triple *rhs)
5654 {
5655         wipe_ins(state, ins);
5656         ins->op = OP_COPY;
5657         ins->sizes = TRIPLE_SIZES(0, 1, 0, 0);
5658         RHS(ins, 0) = rhs;
5659         use_triple(RHS(ins, 0), ins);
5660 }
5661
5662 static void mkconst(struct compile_state *state, 
5663         struct triple *ins, ulong_t value)
5664 {
5665         if (!is_integral(ins) && !is_pointer(ins)) {
5666                 internal_error(state, ins, "unknown type to make constant\n");
5667         }
5668         wipe_ins(state, ins);
5669         ins->op = OP_INTCONST;
5670         ins->sizes = TRIPLE_SIZES(0, 0, 0, 0);
5671         ins->u.cval = value;
5672 }
5673
5674 static void mkaddr_const(struct compile_state *state,
5675         struct triple *ins, struct triple *sdecl, ulong_t value)
5676 {
5677         if (sdecl->op != OP_SDECL) {
5678                 internal_error(state, ins, "bad base for addrconst");
5679         }
5680         wipe_ins(state, ins);
5681         ins->op = OP_ADDRCONST;
5682         ins->sizes = TRIPLE_SIZES(0, 0, 1, 0);
5683         MISC(ins, 0) = sdecl;
5684         ins->u.cval = value;
5685         use_triple(sdecl, ins);
5686 }
5687
5688 /* Transform multicomponent variables into simple register variables */
5689 static void flatten_structures(struct compile_state *state)
5690 {
5691         struct triple *ins, *first;
5692         first = RHS(state->main_function, 0);
5693         ins = first;
5694         /* Pass one expand structure values into valvecs.
5695          */
5696         ins = first;
5697         do {
5698                 struct triple *next;
5699                 next = ins->next;
5700                 if ((ins->type->type & TYPE_MASK) == TYPE_STRUCT) {
5701                         if (ins->op == OP_VAL_VEC) {
5702                                 /* Do nothing */
5703                         }
5704                         else if ((ins->op == OP_LOAD) || (ins->op == OP_READ)) {
5705                                 struct triple *def, **vector;
5706                                 struct type *tptr;
5707                                 int op;
5708                                 ulong_t i;
5709
5710                                 op = ins->op;
5711                                 def = RHS(ins, 0);
5712                                 get_occurance(ins->occurance);
5713                                 next = alloc_triple(state, OP_VAL_VEC, ins->type, -1, -1,
5714                                         ins->occurance);
5715
5716                                 vector = &RHS(next, 0);
5717                                 tptr = next->type->left;
5718                                 for(i = 0; i < next->type->elements; i++) {
5719                                         struct triple *sfield;
5720                                         struct type *mtype;
5721                                         mtype = tptr;
5722                                         if ((mtype->type & TYPE_MASK) == TYPE_PRODUCT) {
5723                                                 mtype = mtype->left;
5724                                         }
5725                                         sfield = deref_field(state, def, mtype->field_ident);
5726                                         
5727                                         vector[i] = triple(
5728                                                 state, op, mtype, sfield, 0);
5729                                         put_occurance(vector[i]->occurance);
5730                                         get_occurance(next->occurance);
5731                                         vector[i]->occurance = next->occurance;
5732                                         tptr = tptr->right;
5733                                 }
5734                                 propogate_use(state, ins, next);
5735                                 flatten(state, ins, next);
5736                                 free_triple(state, ins);
5737                         }
5738                         else if ((ins->op == OP_STORE) || (ins->op == OP_WRITE)) {
5739                                 struct triple *src, *dst, **vector;
5740                                 struct type *tptr;
5741                                 int op;
5742                                 ulong_t i;
5743
5744                                 op = ins->op;
5745                                 src = RHS(ins, 1);
5746                                 dst = RHS(ins, 0);
5747                                 get_occurance(ins->occurance);
5748                                 next = alloc_triple(state, OP_VAL_VEC, ins->type, -1, -1,
5749                                         ins->occurance);
5750                                 
5751                                 vector = &RHS(next, 0);
5752                                 tptr = next->type->left;
5753                                 for(i = 0; i < ins->type->elements; i++) {
5754                                         struct triple *dfield, *sfield;
5755                                         struct type *mtype;
5756                                         mtype = tptr;
5757                                         if ((mtype->type & TYPE_MASK) == TYPE_PRODUCT) {
5758                                                 mtype = mtype->left;
5759                                         }
5760                                         sfield = deref_field(state, src, mtype->field_ident);
5761                                         dfield = deref_field(state, dst, mtype->field_ident);
5762                                         vector[i] = triple(
5763                                                 state, op, mtype, dfield, sfield);
5764                                         put_occurance(vector[i]->occurance);
5765                                         get_occurance(next->occurance);
5766                                         vector[i]->occurance = next->occurance;
5767                                         tptr = tptr->right;
5768                                 }
5769                                 propogate_use(state, ins, next);
5770                                 flatten(state, ins, next);
5771                                 free_triple(state, ins);
5772                         }
5773                 }
5774                 ins = next;
5775         } while(ins != first);
5776         /* Pass two flatten the valvecs.
5777          */
5778         ins = first;
5779         do {
5780                 struct triple *next;
5781                 next = ins->next;
5782                 if (ins->op == OP_VAL_VEC) {
5783                         release_triple(state, ins);
5784                 } 
5785                 ins = next;
5786         } while(ins != first);
5787         /* Pass three verify the state and set ->id to 0.
5788          */
5789         ins = first;
5790         do {
5791                 ins->id &= ~TRIPLE_FLAG_FLATTENED;
5792                 if ((ins->op != OP_BLOBCONST) && (ins->op != OP_SDECL) &&
5793                         ((ins->type->type & TYPE_MASK) == TYPE_STRUCT)) {
5794                         internal_error(state, ins, "STRUCT_TYPE remains?");
5795                 }
5796                 if (ins->op == OP_DOT) {
5797                         internal_error(state, ins, "OP_DOT remains?");
5798                 }
5799                 if (ins->op == OP_VAL_VEC) {
5800                         internal_error(state, ins, "OP_VAL_VEC remains?");
5801                 }
5802                 ins = ins->next;
5803         } while(ins != first);
5804 }
5805
5806 /* For those operations that cannot be simplified */
5807 static void simplify_noop(struct compile_state *state, struct triple *ins)
5808 {
5809         return;
5810 }
5811
5812 static void simplify_smul(struct compile_state *state, struct triple *ins)
5813 {
5814         if (is_const(RHS(ins, 0)) && !is_const(RHS(ins, 1))) {
5815                 struct triple *tmp;
5816                 tmp = RHS(ins, 0);
5817                 RHS(ins, 0) = RHS(ins, 1);
5818                 RHS(ins, 1) = tmp;
5819         }
5820         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
5821                 long_t left, right;
5822                 left  = read_sconst(ins, &RHS(ins, 0));
5823                 right = read_sconst(ins, &RHS(ins, 1));
5824                 mkconst(state, ins, left * right);
5825         }
5826         else if (is_zero(RHS(ins, 1))) {
5827                 mkconst(state, ins, 0);
5828         }
5829         else if (is_one(RHS(ins, 1))) {
5830                 mkcopy(state, ins, RHS(ins, 0));
5831         }
5832         else if (is_pow2(RHS(ins, 1))) {
5833                 struct triple *val;
5834                 val = int_const(state, ins->type, tlog2(RHS(ins, 1)));
5835                 ins->op = OP_SL;
5836                 insert_triple(state, ins, val);
5837                 unuse_triple(RHS(ins, 1), ins);
5838                 use_triple(val, ins);
5839                 RHS(ins, 1) = val;
5840         }
5841 }
5842
5843 static void simplify_umul(struct compile_state *state, struct triple *ins)
5844 {
5845         if (is_const(RHS(ins, 0)) && !is_const(RHS(ins, 1))) {
5846                 struct triple *tmp;
5847                 tmp = RHS(ins, 0);
5848                 RHS(ins, 0) = RHS(ins, 1);
5849                 RHS(ins, 1) = tmp;
5850         }
5851         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
5852                 ulong_t left, right;
5853                 left  = read_const(state, ins, &RHS(ins, 0));
5854                 right = read_const(state, ins, &RHS(ins, 1));
5855                 mkconst(state, ins, left * right);
5856         }
5857         else if (is_zero(RHS(ins, 1))) {
5858                 mkconst(state, ins, 0);
5859         }
5860         else if (is_one(RHS(ins, 1))) {
5861                 mkcopy(state, ins, RHS(ins, 0));
5862         }
5863         else if (is_pow2(RHS(ins, 1))) {
5864                 struct triple *val;
5865                 val = int_const(state, ins->type, tlog2(RHS(ins, 1)));
5866                 ins->op = OP_SL;
5867                 insert_triple(state, ins, val);
5868                 unuse_triple(RHS(ins, 1), ins);
5869                 use_triple(val, ins);
5870                 RHS(ins, 1) = val;
5871         }
5872 }
5873
5874 static void simplify_sdiv(struct compile_state *state, struct triple *ins)
5875 {
5876         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
5877                 long_t left, right;
5878                 left  = read_sconst(ins, &RHS(ins, 0));
5879                 right = read_sconst(ins, &RHS(ins, 1));
5880                 mkconst(state, ins, left / right);
5881         }
5882         else if (is_zero(RHS(ins, 0))) {
5883                 mkconst(state, ins, 0);
5884         }
5885         else if (is_zero(RHS(ins, 1))) {
5886                 error(state, ins, "division by zero");
5887         }
5888         else if (is_one(RHS(ins, 1))) {
5889                 mkcopy(state, ins, RHS(ins, 0));
5890         }
5891         else if (is_pow2(RHS(ins, 1))) {
5892                 struct triple *val;
5893                 val = int_const(state, ins->type, tlog2(RHS(ins, 1)));
5894                 ins->op = OP_SSR;
5895                 insert_triple(state, ins, val);
5896                 unuse_triple(RHS(ins, 1), ins);
5897                 use_triple(val, ins);
5898                 RHS(ins, 1) = val;
5899         }
5900 }
5901
5902 static void simplify_udiv(struct compile_state *state, struct triple *ins)
5903 {
5904         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
5905                 ulong_t left, right;
5906                 left  = read_const(state, ins, &RHS(ins, 0));
5907                 right = read_const(state, ins, &RHS(ins, 1));
5908                 mkconst(state, ins, left / right);
5909         }
5910         else if (is_zero(RHS(ins, 0))) {
5911                 mkconst(state, ins, 0);
5912         }
5913         else if (is_zero(RHS(ins, 1))) {
5914                 error(state, ins, "division by zero");
5915         }
5916         else if (is_one(RHS(ins, 1))) {
5917                 mkcopy(state, ins, RHS(ins, 0));
5918         }
5919         else if (is_pow2(RHS(ins, 1))) {
5920                 struct triple *val;
5921                 val = int_const(state, ins->type, tlog2(RHS(ins, 1)));
5922                 ins->op = OP_USR;
5923                 insert_triple(state, ins, val);
5924                 unuse_triple(RHS(ins, 1), ins);
5925                 use_triple(val, ins);
5926                 RHS(ins, 1) = val;
5927         }
5928 }
5929
5930 static void simplify_smod(struct compile_state *state, struct triple *ins)
5931 {
5932         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
5933                 long_t left, right;
5934                 left  = read_const(state, ins, &RHS(ins, 0));
5935                 right = read_const(state, ins, &RHS(ins, 1));
5936                 mkconst(state, ins, left % right);
5937         }
5938         else if (is_zero(RHS(ins, 0))) {
5939                 mkconst(state, ins, 0);
5940         }
5941         else if (is_zero(RHS(ins, 1))) {
5942                 error(state, ins, "division by zero");
5943         }
5944         else if (is_one(RHS(ins, 1))) {
5945                 mkconst(state, ins, 0);
5946         }
5947         else if (is_pow2(RHS(ins, 1))) {
5948                 struct triple *val;
5949                 val = int_const(state, ins->type, RHS(ins, 1)->u.cval - 1);
5950                 ins->op = OP_AND;
5951                 insert_triple(state, ins, val);
5952                 unuse_triple(RHS(ins, 1), ins);
5953                 use_triple(val, ins);
5954                 RHS(ins, 1) = val;
5955         }
5956 }
5957 static void simplify_umod(struct compile_state *state, struct triple *ins)
5958 {
5959         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
5960                 ulong_t left, right;
5961                 left  = read_const(state, ins, &RHS(ins, 0));
5962                 right = read_const(state, ins, &RHS(ins, 1));
5963                 mkconst(state, ins, left % right);
5964         }
5965         else if (is_zero(RHS(ins, 0))) {
5966                 mkconst(state, ins, 0);
5967         }
5968         else if (is_zero(RHS(ins, 1))) {
5969                 error(state, ins, "division by zero");
5970         }
5971         else if (is_one(RHS(ins, 1))) {
5972                 mkconst(state, ins, 0);
5973         }
5974         else if (is_pow2(RHS(ins, 1))) {
5975                 struct triple *val;
5976                 val = int_const(state, ins->type, RHS(ins, 1)->u.cval - 1);
5977                 ins->op = OP_AND;
5978                 insert_triple(state, ins, val);
5979                 unuse_triple(RHS(ins, 1), ins);
5980                 use_triple(val, ins);
5981                 RHS(ins, 1) = val;
5982         }
5983 }
5984
5985 static void simplify_add(struct compile_state *state, struct triple *ins)
5986 {
5987         /* start with the pointer on the left */
5988         if (is_pointer(RHS(ins, 1))) {
5989                 struct triple *tmp;
5990                 tmp = RHS(ins, 0);
5991                 RHS(ins, 0) = RHS(ins, 1);
5992                 RHS(ins, 1) = tmp;
5993         }
5994         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
5995                 if (RHS(ins, 0)->op == OP_INTCONST) {
5996                         ulong_t left, right;
5997                         left  = read_const(state, ins, &RHS(ins, 0));
5998                         right = read_const(state, ins, &RHS(ins, 1));
5999                         mkconst(state, ins, left + right);
6000                 }
6001                 else if (RHS(ins, 0)->op == OP_ADDRCONST) {
6002                         struct triple *sdecl;
6003                         ulong_t left, right;
6004                         sdecl = MISC(RHS(ins, 0), 0);
6005                         left  = RHS(ins, 0)->u.cval;
6006                         right = RHS(ins, 1)->u.cval;
6007                         mkaddr_const(state, ins, sdecl, left + right);
6008                 }
6009                 else {
6010                         internal_warning(state, ins, "Optimize me!");
6011                 }
6012         }
6013         else if (is_const(RHS(ins, 0)) && !is_const(RHS(ins, 1))) {
6014                 struct triple *tmp;
6015                 tmp = RHS(ins, 1);
6016                 RHS(ins, 1) = RHS(ins, 0);
6017                 RHS(ins, 0) = tmp;
6018         }
6019 }
6020
6021 static void simplify_sub(struct compile_state *state, struct triple *ins)
6022 {
6023         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6024                 if (RHS(ins, 0)->op == OP_INTCONST) {
6025                         ulong_t left, right;
6026                         left  = read_const(state, ins, &RHS(ins, 0));
6027                         right = read_const(state, ins, &RHS(ins, 1));
6028                         mkconst(state, ins, left - right);
6029                 }
6030                 else if (RHS(ins, 0)->op == OP_ADDRCONST) {
6031                         struct triple *sdecl;
6032                         ulong_t left, right;
6033                         sdecl = MISC(RHS(ins, 0), 0);
6034                         left  = RHS(ins, 0)->u.cval;
6035                         right = RHS(ins, 1)->u.cval;
6036                         mkaddr_const(state, ins, sdecl, left - right);
6037                 }
6038                 else {
6039                         internal_warning(state, ins, "Optimize me!");
6040                 }
6041         }
6042 }
6043
6044 static void simplify_sl(struct compile_state *state, struct triple *ins)
6045 {
6046         if (is_const(RHS(ins, 1))) {
6047                 ulong_t right;
6048                 right = read_const(state, ins, &RHS(ins, 1));
6049                 if (right >= (size_of(state, ins->type)*8)) {
6050                         warning(state, ins, "left shift count >= width of type");
6051                 }
6052         }
6053         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6054                 ulong_t left, right;
6055                 left  = read_const(state, ins, &RHS(ins, 0));
6056                 right = read_const(state, ins, &RHS(ins, 1));
6057                 mkconst(state, ins,  left << right);
6058         }
6059 }
6060
6061 static void simplify_usr(struct compile_state *state, struct triple *ins)
6062 {
6063         if (is_const(RHS(ins, 1))) {
6064                 ulong_t right;
6065                 right = read_const(state, ins, &RHS(ins, 1));
6066                 if (right >= (size_of(state, ins->type)*8)) {
6067                         warning(state, ins, "right shift count >= width of type");
6068                 }
6069         }
6070         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6071                 ulong_t left, right;
6072                 left  = read_const(state, ins, &RHS(ins, 0));
6073                 right = read_const(state, ins, &RHS(ins, 1));
6074                 mkconst(state, ins, left >> right);
6075         }
6076 }
6077
6078 static void simplify_ssr(struct compile_state *state, struct triple *ins)
6079 {
6080         if (is_const(RHS(ins, 1))) {
6081                 ulong_t right;
6082                 right = read_const(state, ins, &RHS(ins, 1));
6083                 if (right >= (size_of(state, ins->type)*8)) {
6084                         warning(state, ins, "right shift count >= width of type");
6085                 }
6086         }
6087         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6088                 long_t left, right;
6089                 left  = read_sconst(ins, &RHS(ins, 0));
6090                 right = read_sconst(ins, &RHS(ins, 1));
6091                 mkconst(state, ins, left >> right);
6092         }
6093 }
6094
6095 static void simplify_and(struct compile_state *state, struct triple *ins)
6096 {
6097         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6098                 ulong_t left, right;
6099                 left  = read_const(state, ins, &RHS(ins, 0));
6100                 right = read_const(state, ins, &RHS(ins, 1));
6101                 mkconst(state, ins, left & right);
6102         }
6103 }
6104
6105 static void simplify_or(struct compile_state *state, struct triple *ins)
6106 {
6107         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6108                 ulong_t left, right;
6109                 left  = read_const(state, ins, &RHS(ins, 0));
6110                 right = read_const(state, ins, &RHS(ins, 1));
6111                 mkconst(state, ins, left | right);
6112         }
6113 }
6114
6115 static void simplify_xor(struct compile_state *state, struct triple *ins)
6116 {
6117         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6118                 ulong_t left, right;
6119                 left  = read_const(state, ins, &RHS(ins, 0));
6120                 right = read_const(state, ins, &RHS(ins, 1));
6121                 mkconst(state, ins, left ^ right);
6122         }
6123 }
6124
6125 static void simplify_pos(struct compile_state *state, struct triple *ins)
6126 {
6127         if (is_const(RHS(ins, 0))) {
6128                 mkconst(state, ins, RHS(ins, 0)->u.cval);
6129         }
6130         else {
6131                 mkcopy(state, ins, RHS(ins, 0));
6132         }
6133 }
6134
6135 static void simplify_neg(struct compile_state *state, struct triple *ins)
6136 {
6137         if (is_const(RHS(ins, 0))) {
6138                 ulong_t left;
6139                 left = read_const(state, ins, &RHS(ins, 0));
6140                 mkconst(state, ins, -left);
6141         }
6142         else if (RHS(ins, 0)->op == OP_NEG) {
6143                 mkcopy(state, ins, RHS(RHS(ins, 0), 0));
6144         }
6145 }
6146
6147 static void simplify_invert(struct compile_state *state, struct triple *ins)
6148 {
6149         if (is_const(RHS(ins, 0))) {
6150                 ulong_t left;
6151                 left = read_const(state, ins, &RHS(ins, 0));
6152                 mkconst(state, ins, ~left);
6153         }
6154 }
6155
6156 static void simplify_eq(struct compile_state *state, struct triple *ins)
6157 {
6158         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6159                 ulong_t left, right;
6160                 left  = read_const(state, ins, &RHS(ins, 0));
6161                 right = read_const(state, ins, &RHS(ins, 1));
6162                 mkconst(state, ins, left == right);
6163         }
6164         else if (RHS(ins, 0) == RHS(ins, 1)) {
6165                 mkconst(state, ins, 1);
6166         }
6167 }
6168
6169 static void simplify_noteq(struct compile_state *state, struct triple *ins)
6170 {
6171         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6172                 ulong_t left, right;
6173                 left  = read_const(state, ins, &RHS(ins, 0));
6174                 right = read_const(state, ins, &RHS(ins, 1));
6175                 mkconst(state, ins, left != right);
6176         }
6177         else if (RHS(ins, 0) == RHS(ins, 1)) {
6178                 mkconst(state, ins, 0);
6179         }
6180 }
6181
6182 static void simplify_sless(struct compile_state *state, struct triple *ins)
6183 {
6184         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6185                 long_t left, right;
6186                 left  = read_sconst(ins, &RHS(ins, 0));
6187                 right = read_sconst(ins, &RHS(ins, 1));
6188                 mkconst(state, ins, left < right);
6189         }
6190         else if (RHS(ins, 0) == RHS(ins, 1)) {
6191                 mkconst(state, ins, 0);
6192         }
6193 }
6194
6195 static void simplify_uless(struct compile_state *state, struct triple *ins)
6196 {
6197         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6198                 ulong_t left, right;
6199                 left  = read_const(state, ins, &RHS(ins, 0));
6200                 right = read_const(state, ins, &RHS(ins, 1));
6201                 mkconst(state, ins, left < right);
6202         }
6203         else if (is_zero(RHS(ins, 0))) {
6204                 mkconst(state, ins, 1);
6205         }
6206         else if (RHS(ins, 0) == RHS(ins, 1)) {
6207                 mkconst(state, ins, 0);
6208         }
6209 }
6210
6211 static void simplify_smore(struct compile_state *state, struct triple *ins)
6212 {
6213         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6214                 long_t left, right;
6215                 left  = read_sconst(ins, &RHS(ins, 0));
6216                 right = read_sconst(ins, &RHS(ins, 1));
6217                 mkconst(state, ins, left > right);
6218         }
6219         else if (RHS(ins, 0) == RHS(ins, 1)) {
6220                 mkconst(state, ins, 0);
6221         }
6222 }
6223
6224 static void simplify_umore(struct compile_state *state, struct triple *ins)
6225 {
6226         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6227                 ulong_t left, right;
6228                 left  = read_const(state, ins, &RHS(ins, 0));
6229                 right = read_const(state, ins, &RHS(ins, 1));
6230                 mkconst(state, ins, left > right);
6231         }
6232         else if (is_zero(RHS(ins, 1))) {
6233                 mkconst(state, ins, 1);
6234         }
6235         else if (RHS(ins, 0) == RHS(ins, 1)) {
6236                 mkconst(state, ins, 0);
6237         }
6238 }
6239
6240
6241 static void simplify_slesseq(struct compile_state *state, struct triple *ins)
6242 {
6243         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6244                 long_t left, right;
6245                 left  = read_sconst(ins, &RHS(ins, 0));
6246                 right = read_sconst(ins, &RHS(ins, 1));
6247                 mkconst(state, ins, left <= right);
6248         }
6249         else if (RHS(ins, 0) == RHS(ins, 1)) {
6250                 mkconst(state, ins, 1);
6251         }
6252 }
6253
6254 static void simplify_ulesseq(struct compile_state *state, struct triple *ins)
6255 {
6256         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6257                 ulong_t left, right;
6258                 left  = read_const(state, ins, &RHS(ins, 0));
6259                 right = read_const(state, ins, &RHS(ins, 1));
6260                 mkconst(state, ins, left <= right);
6261         }
6262         else if (is_zero(RHS(ins, 0))) {
6263                 mkconst(state, ins, 1);
6264         }
6265         else if (RHS(ins, 0) == RHS(ins, 1)) {
6266                 mkconst(state, ins, 1);
6267         }
6268 }
6269
6270 static void simplify_smoreeq(struct compile_state *state, struct triple *ins)
6271 {
6272         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 0))) {
6273                 long_t left, right;
6274                 left  = read_sconst(ins, &RHS(ins, 0));
6275                 right = read_sconst(ins, &RHS(ins, 1));
6276                 mkconst(state, ins, left >= right);
6277         }
6278         else if (RHS(ins, 0) == RHS(ins, 1)) {
6279                 mkconst(state, ins, 1);
6280         }
6281 }
6282
6283 static void simplify_umoreeq(struct compile_state *state, struct triple *ins)
6284 {
6285         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6286                 ulong_t left, right;
6287                 left  = read_const(state, ins, &RHS(ins, 0));
6288                 right = read_const(state, ins, &RHS(ins, 1));
6289                 mkconst(state, ins, left >= right);
6290         }
6291         else if (is_zero(RHS(ins, 1))) {
6292                 mkconst(state, ins, 1);
6293         }
6294         else if (RHS(ins, 0) == RHS(ins, 1)) {
6295                 mkconst(state, ins, 1);
6296         }
6297 }
6298
6299 static void simplify_lfalse(struct compile_state *state, struct triple *ins)
6300 {
6301         if (is_const(RHS(ins, 0))) {
6302                 ulong_t left;
6303                 left = read_const(state, ins, &RHS(ins, 0));
6304                 mkconst(state, ins, left == 0);
6305         }
6306         /* Otherwise if I am the only user... */
6307         else if ((RHS(ins, 0)->use->member == ins) && (RHS(ins, 0)->use->next == 0)) {
6308                 int need_copy = 1;
6309                 /* Invert a boolean operation */
6310                 switch(RHS(ins, 0)->op) {
6311                 case OP_LTRUE:   RHS(ins, 0)->op = OP_LFALSE;  break;
6312                 case OP_LFALSE:  RHS(ins, 0)->op = OP_LTRUE;   break;
6313                 case OP_EQ:      RHS(ins, 0)->op = OP_NOTEQ;   break;
6314                 case OP_NOTEQ:   RHS(ins, 0)->op = OP_EQ;      break;
6315                 case OP_SLESS:   RHS(ins, 0)->op = OP_SMOREEQ; break;
6316                 case OP_ULESS:   RHS(ins, 0)->op = OP_UMOREEQ; break;
6317                 case OP_SMORE:   RHS(ins, 0)->op = OP_SLESSEQ; break;
6318                 case OP_UMORE:   RHS(ins, 0)->op = OP_ULESSEQ; break;
6319                 case OP_SLESSEQ: RHS(ins, 0)->op = OP_SMORE;   break;
6320                 case OP_ULESSEQ: RHS(ins, 0)->op = OP_UMORE;   break;
6321                 case OP_SMOREEQ: RHS(ins, 0)->op = OP_SLESS;   break;
6322                 case OP_UMOREEQ: RHS(ins, 0)->op = OP_ULESS;   break;
6323                 default:
6324                         need_copy = 0;
6325                         break;
6326                 }
6327                 if (need_copy) {
6328                         mkcopy(state, ins, RHS(ins, 0));
6329                 }
6330         }
6331 }
6332
6333 static void simplify_ltrue (struct compile_state *state, struct triple *ins)
6334 {
6335         if (is_const(RHS(ins, 0))) {
6336                 ulong_t left;
6337                 left = read_const(state, ins, &RHS(ins, 0));
6338                 mkconst(state, ins, left != 0);
6339         }
6340         else switch(RHS(ins, 0)->op) {
6341         case OP_LTRUE:   case OP_LFALSE:  case OP_EQ:      case OP_NOTEQ:
6342         case OP_SLESS:   case OP_ULESS:   case OP_SMORE:   case OP_UMORE:
6343         case OP_SLESSEQ: case OP_ULESSEQ: case OP_SMOREEQ: case OP_UMOREEQ:
6344                 mkcopy(state, ins, RHS(ins, 0));
6345         }
6346
6347 }
6348
6349 static void simplify_copy(struct compile_state *state, struct triple *ins)
6350 {
6351         if (is_const(RHS(ins, 0))) {
6352                 switch(RHS(ins, 0)->op) {
6353                 case OP_INTCONST:
6354                 {
6355                         ulong_t left;
6356                         left = read_const(state, ins, &RHS(ins, 0));
6357                         mkconst(state, ins, left);
6358                         break;
6359                 }
6360                 case OP_ADDRCONST:
6361                 {
6362                         struct triple *sdecl;
6363                         ulong_t offset;
6364                         sdecl  = MISC(RHS(ins, 0), 0);
6365                         offset = RHS(ins, 0)->u.cval;
6366                         mkaddr_const(state, ins, sdecl, offset);
6367                         break;
6368                 }
6369                 default:
6370                         internal_error(state, ins, "uknown constant");
6371                         break;
6372                 }
6373         }
6374 }
6375
6376 static void simplify_branch(struct compile_state *state, struct triple *ins)
6377 {
6378         struct block *block;
6379         if (ins->op != OP_BRANCH) {
6380                 internal_error(state, ins, "not branch");
6381         }
6382         if (ins->use != 0) {
6383                 internal_error(state, ins, "branch use");
6384         }
6385 #warning "FIXME implement simplify branch."
6386         /* The challenge here with simplify branch is that I need to 
6387          * make modifications to the control flow graph as well
6388          * as to the branch instruction itself.
6389          */
6390         block = ins->u.block;
6391         
6392         if (TRIPLE_RHS(ins->sizes) && is_const(RHS(ins, 0))) {
6393                 struct triple *targ;
6394                 ulong_t value;
6395                 value = read_const(state, ins, &RHS(ins, 0));
6396                 unuse_triple(RHS(ins, 0), ins);
6397                 targ = TARG(ins, 0);
6398                 ins->sizes = TRIPLE_SIZES(0, 0, 0, 1);
6399                 if (value) {
6400                         unuse_triple(ins->next, ins);
6401                         TARG(ins, 0) = targ;
6402                 }
6403                 else {
6404                         unuse_triple(targ, ins);
6405                         TARG(ins, 0) = ins->next;
6406                 }
6407 #warning "FIXME handle the case of making a branch unconditional"
6408         }
6409         if (TARG(ins, 0) == ins->next) {
6410                 unuse_triple(ins->next, ins);
6411                 if (TRIPLE_RHS(ins->sizes)) {
6412                         unuse_triple(RHS(ins, 0), ins);
6413                         unuse_triple(ins->next, ins);
6414                 }
6415                 ins->sizes = TRIPLE_SIZES(0, 0, 0, 0);
6416                 ins->op = OP_NOOP;
6417                 if (ins->use) {
6418                         internal_error(state, ins, "noop use != 0");
6419                 }
6420 #warning "FIXME handle the case of killing a branch"
6421         }
6422 }
6423
6424 int phi_present(struct block *block)
6425 {
6426         struct triple *ptr;
6427         if (!block) {
6428                 return 0;
6429         }
6430         ptr = block->first;
6431         do {
6432                 if (ptr->op == OP_PHI) {
6433                         return 1;
6434                 }
6435                 ptr = ptr->next;
6436         } while(ptr != block->last);
6437         return 0;
6438 }
6439
6440 static void simplify_label(struct compile_state *state, struct triple *ins)
6441 {
6442 #warning "FIXME enable simplify_label"
6443         struct triple *first, *last;
6444         first = RHS(state->main_function, 0);
6445         last = first->prev;
6446         /* Ignore the first and last instructions */
6447         if ((ins == first) || (ins == last)) {
6448                 return;
6449         }
6450         if (ins->use == 0) {
6451                 ins->op = OP_NOOP;
6452         }
6453         else if (ins->prev->op == OP_LABEL) {
6454                 struct block *block;
6455                 block = ins->prev->u.block;
6456                 /* In general it is not safe to merge one label that
6457                  * imediately follows another.  The problem is that the empty
6458                  * looking block may have phi functions that depend on it.
6459                  */
6460                 if (!block || 
6461                         (!phi_present(block->left) && 
6462                         !phi_present(block->right))) 
6463                 {
6464                         struct triple_set *user, *next;
6465                         ins->op = OP_NOOP;
6466                         for(user = ins->use; user; user = next) {
6467                                 struct triple *use;
6468                                 next = user->next;
6469                                 use = user->member;
6470                                 if (TARG(use, 0) == ins) {
6471                                         TARG(use, 0) = ins->prev;
6472                                         unuse_triple(ins, use);
6473                                         use_triple(ins->prev, use);
6474                                 }
6475                         }
6476                         if (ins->use) {
6477                                 internal_error(state, ins, "noop use != 0");
6478                         }
6479                 }
6480         }
6481 }
6482
6483 static void simplify_phi(struct compile_state *state, struct triple *ins)
6484 {
6485         struct triple **expr;
6486         ulong_t value;
6487         expr = triple_rhs(state, ins, 0);
6488         if (!*expr || !is_const(*expr)) {
6489                 return;
6490         }
6491         value = read_const(state, ins, expr);
6492         for(;expr;expr = triple_rhs(state, ins, expr)) {
6493                 if (!*expr || !is_const(*expr)) {
6494                         return;
6495                 }
6496                 if (value != read_const(state, ins, expr)) {
6497                         return;
6498                 }
6499         }
6500         mkconst(state, ins, value);
6501 }
6502
6503
6504 static void simplify_bsf(struct compile_state *state, struct triple *ins)
6505 {
6506         if (is_const(RHS(ins, 0))) {
6507                 ulong_t left;
6508                 left = read_const(state, ins, &RHS(ins, 0));
6509                 mkconst(state, ins, bsf(left));
6510         }
6511 }
6512
6513 static void simplify_bsr(struct compile_state *state, struct triple *ins)
6514 {
6515         if (is_const(RHS(ins, 0))) {
6516                 ulong_t left;
6517                 left = read_const(state, ins, &RHS(ins, 0));
6518                 mkconst(state, ins, bsr(left));
6519         }
6520 }
6521
6522
6523 typedef void (*simplify_t)(struct compile_state *state, struct triple *ins);
6524 static const simplify_t table_simplify[] = {
6525 #if 1
6526 #define simplify_sdivt    simplify_noop
6527 #define simplify_udivt    simplify_noop
6528 #endif
6529 #if 0
6530 #define simplify_smul     simplify_noop
6531 #define simplify_umul     simplify_noop
6532 #define simplify_sdiv     simplify_noop
6533 #define simplify_udiv     simplify_noop
6534 #define simplify_smod     simplify_noop
6535 #define simplify_umod     simplify_noop
6536 #endif
6537 #if 0
6538 #define simplify_add      simplify_noop
6539 #define simplify_sub      simplify_noop
6540 #endif
6541 #if 0
6542 #define simplify_sl       simplify_noop
6543 #define simplify_usr      simplify_noop
6544 #define simplify_ssr      simplify_noop
6545 #endif
6546 #if 0
6547 #define simplify_and      simplify_noop
6548 #define simplify_xor      simplify_noop
6549 #define simplify_or       simplify_noop
6550 #endif
6551 #if 0
6552 #define simplify_pos      simplify_noop
6553 #define simplify_neg      simplify_noop
6554 #define simplify_invert   simplify_noop
6555 #endif
6556
6557 #if 0
6558 #define simplify_eq       simplify_noop
6559 #define simplify_noteq    simplify_noop
6560 #endif
6561 #if 0
6562 #define simplify_sless    simplify_noop
6563 #define simplify_uless    simplify_noop
6564 #define simplify_smore    simplify_noop
6565 #define simplify_umore    simplify_noop
6566 #endif
6567 #if 0
6568 #define simplify_slesseq  simplify_noop
6569 #define simplify_ulesseq  simplify_noop
6570 #define simplify_smoreeq  simplify_noop
6571 #define simplify_umoreeq  simplify_noop
6572 #endif
6573 #if 0
6574 #define simplify_lfalse   simplify_noop
6575 #endif
6576 #if 0
6577 #define simplify_ltrue    simplify_noop
6578 #endif
6579
6580 #if 0
6581 #define simplify_copy     simplify_noop
6582 #endif
6583
6584 #if 0
6585 #define simplify_branch   simplify_noop
6586 #endif
6587 #if 1
6588 #define simplify_label    simplify_noop
6589 #endif
6590
6591 #if 0
6592 #define simplify_phi      simplify_noop
6593 #endif
6594
6595 #if 0
6596 #define simplify_bsf      simplify_noop
6597 #define simplify_bsr      simplify_noop
6598 #endif
6599
6600 [OP_SDIVT      ] = simplify_sdivt,
6601 [OP_UDIVT      ] = simplify_udivt,
6602 [OP_SMUL       ] = simplify_smul,
6603 [OP_UMUL       ] = simplify_umul,
6604 [OP_SDIV       ] = simplify_sdiv,
6605 [OP_UDIV       ] = simplify_udiv,
6606 [OP_SMOD       ] = simplify_smod,
6607 [OP_UMOD       ] = simplify_umod,
6608 [OP_ADD        ] = simplify_add,
6609 [OP_SUB        ] = simplify_sub,
6610 [OP_SL         ] = simplify_sl,
6611 [OP_USR        ] = simplify_usr,
6612 [OP_SSR        ] = simplify_ssr,
6613 [OP_AND        ] = simplify_and,
6614 [OP_XOR        ] = simplify_xor,
6615 [OP_OR         ] = simplify_or,
6616 [OP_POS        ] = simplify_pos,
6617 [OP_NEG        ] = simplify_neg,
6618 [OP_INVERT     ] = simplify_invert,
6619
6620 [OP_EQ         ] = simplify_eq,
6621 [OP_NOTEQ      ] = simplify_noteq,
6622 [OP_SLESS      ] = simplify_sless,
6623 [OP_ULESS      ] = simplify_uless,
6624 [OP_SMORE      ] = simplify_smore,
6625 [OP_UMORE      ] = simplify_umore,
6626 [OP_SLESSEQ    ] = simplify_slesseq,
6627 [OP_ULESSEQ    ] = simplify_ulesseq,
6628 [OP_SMOREEQ    ] = simplify_smoreeq,
6629 [OP_UMOREEQ    ] = simplify_umoreeq,
6630 [OP_LFALSE     ] = simplify_lfalse,
6631 [OP_LTRUE      ] = simplify_ltrue,
6632
6633 [OP_LOAD       ] = simplify_noop,
6634 [OP_STORE      ] = simplify_noop,
6635
6636 [OP_NOOP       ] = simplify_noop,
6637
6638 [OP_INTCONST   ] = simplify_noop,
6639 [OP_BLOBCONST  ] = simplify_noop,
6640 [OP_ADDRCONST  ] = simplify_noop,
6641
6642 [OP_WRITE      ] = simplify_noop,
6643 [OP_READ       ] = simplify_noop,
6644 [OP_COPY       ] = simplify_copy,
6645 [OP_PIECE      ] = simplify_noop,
6646 [OP_ASM        ] = simplify_noop,
6647
6648 [OP_DOT        ] = simplify_noop,
6649 [OP_VAL_VEC    ] = simplify_noop,
6650
6651 [OP_LIST       ] = simplify_noop,
6652 [OP_BRANCH     ] = simplify_branch,
6653 [OP_LABEL      ] = simplify_label,
6654 [OP_ADECL      ] = simplify_noop,
6655 [OP_SDECL      ] = simplify_noop,
6656 [OP_PHI        ] = simplify_phi,
6657
6658 [OP_INB        ] = simplify_noop,
6659 [OP_INW        ] = simplify_noop,
6660 [OP_INL        ] = simplify_noop,
6661 [OP_OUTB       ] = simplify_noop,
6662 [OP_OUTW       ] = simplify_noop,
6663 [OP_OUTL       ] = simplify_noop,
6664 [OP_BSF        ] = simplify_bsf,
6665 [OP_BSR        ] = simplify_bsr,
6666 [OP_RDMSR      ] = simplify_noop,
6667 [OP_WRMSR      ] = simplify_noop,                    
6668 [OP_HLT        ] = simplify_noop,
6669 };
6670
6671 static void simplify(struct compile_state *state, struct triple *ins)
6672 {
6673         int op;
6674         simplify_t do_simplify;
6675         do {
6676                 op = ins->op;
6677                 do_simplify = 0;
6678                 if ((op < 0) || (op > sizeof(table_simplify)/sizeof(table_simplify[0]))) {
6679                         do_simplify = 0;
6680                 }
6681                 else {
6682                         do_simplify = table_simplify[op];
6683                 }
6684                 if (!do_simplify) {
6685                         internal_error(state, ins, "cannot simplify op: %d %s\n",
6686                                 op, tops(op));
6687                         return;
6688                 }
6689                 do_simplify(state, ins);
6690         } while(ins->op != op);
6691 }
6692
6693 static void simplify_all(struct compile_state *state)
6694 {
6695         struct triple *ins, *first;
6696         first = RHS(state->main_function, 0);
6697         ins = first;
6698         do {
6699                 simplify(state, ins);
6700                 ins = ins->next;
6701         }while(ins != first);
6702 }
6703
6704 /*
6705  * Builtins....
6706  * ============================
6707  */
6708
6709 static void register_builtin_function(struct compile_state *state,
6710         const char *name, int op, struct type *rtype, ...)
6711 {
6712         struct type *ftype, *atype, *param, **next;
6713         struct triple *def, *arg, *result, *work, *last, *first;
6714         struct hash_entry *ident;
6715         struct file_state file;
6716         int parameters;
6717         int name_len;
6718         va_list args;
6719         int i;
6720
6721         /* Dummy file state to get debug handling right */
6722         memset(&file, 0, sizeof(file));
6723         file.basename = "<built-in>";
6724         file.line = 1;
6725         file.report_line = 1;
6726         file.report_name = file.basename;
6727         file.prev = state->file;
6728         state->file = &file;
6729         state->function = name;
6730
6731         /* Find the Parameter count */
6732         valid_op(state, op);
6733         parameters = table_ops[op].rhs;
6734         if (parameters < 0 ) {
6735                 internal_error(state, 0, "Invalid builtin parameter count");
6736         }
6737
6738         /* Find the function type */
6739         ftype = new_type(TYPE_FUNCTION, rtype, 0);
6740         next = &ftype->right;
6741         va_start(args, rtype);
6742         for(i = 0; i < parameters; i++) {
6743                 atype = va_arg(args, struct type *);
6744                 if (!*next) {
6745                         *next = atype;
6746                 } else {
6747                         *next = new_type(TYPE_PRODUCT, *next, atype);
6748                         next = &((*next)->right);
6749                 }
6750         }
6751         if (!*next) {
6752                 *next = &void_type;
6753         }
6754         va_end(args);
6755
6756         /* Generate the needed triples */
6757         def = triple(state, OP_LIST, ftype, 0, 0);
6758         first = label(state);
6759         RHS(def, 0) = first;
6760
6761         /* Now string them together */
6762         param = ftype->right;
6763         for(i = 0; i < parameters; i++) {
6764                 if ((param->type & TYPE_MASK) == TYPE_PRODUCT) {
6765                         atype = param->left;
6766                 } else {
6767                         atype = param;
6768                 }
6769                 arg = flatten(state, first, variable(state, atype));
6770                 param = param->right;
6771         }
6772         result = 0;
6773         if ((rtype->type & TYPE_MASK) != TYPE_VOID) {
6774                 result = flatten(state, first, variable(state, rtype));
6775         }
6776         MISC(def, 0) = result;
6777         work = new_triple(state, op, rtype, -1, parameters);
6778         for(i = 0, arg = first->next; i < parameters; i++, arg = arg->next) {
6779                 RHS(work, i) = read_expr(state, arg);
6780         }
6781         if (result && ((rtype->type & TYPE_MASK) == TYPE_STRUCT)) {
6782                 struct triple *val;
6783                 /* Populate the LHS with the target registers */
6784                 work = flatten(state, first, work);
6785                 work->type = &void_type;
6786                 param = rtype->left;
6787                 if (rtype->elements != TRIPLE_LHS(work->sizes)) {
6788                         internal_error(state, 0, "Invalid result type");
6789                 }
6790                 val = new_triple(state, OP_VAL_VEC, rtype, -1, -1);
6791                 for(i = 0; i < rtype->elements; i++) {
6792                         struct triple *piece;
6793                         atype = param;
6794                         if ((param->type & TYPE_MASK) == TYPE_PRODUCT) {
6795                                 atype = param->left;
6796                         }
6797                         if (!TYPE_ARITHMETIC(atype->type) &&
6798                                 !TYPE_PTR(atype->type)) {
6799                                 internal_error(state, 0, "Invalid lhs type");
6800                         }
6801                         piece = triple(state, OP_PIECE, atype, work, 0);
6802                         piece->u.cval = i;
6803                         LHS(work, i) = piece;
6804                         RHS(val, i) = piece;
6805                 }
6806                 work = val;
6807         }
6808         if (result) {
6809                 work = write_expr(state, result, work);
6810         }
6811         work = flatten(state, first, work);
6812         last = flatten(state, first, label(state));
6813         name_len = strlen(name);
6814         ident = lookup(state, name, name_len);
6815         symbol(state, ident, &ident->sym_ident, def, ftype);
6816         
6817         state->file = file.prev;
6818         state->function = 0;
6819 #if 0
6820         fprintf(stdout, "\n");
6821         loc(stdout, state, 0);
6822         fprintf(stdout, "\n__________ builtin_function _________\n");
6823         print_triple(state, def);
6824         fprintf(stdout, "__________ builtin_function _________ done\n\n");
6825 #endif
6826 }
6827
6828 static struct type *partial_struct(struct compile_state *state,
6829         const char *field_name, struct type *type, struct type *rest)
6830 {
6831         struct hash_entry *field_ident;
6832         struct type *result;
6833         int field_name_len;
6834
6835         field_name_len = strlen(field_name);
6836         field_ident = lookup(state, field_name, field_name_len);
6837
6838         result = clone_type(0, type);
6839         result->field_ident = field_ident;
6840
6841         if (rest) {
6842                 result = new_type(TYPE_PRODUCT, result, rest);
6843         }
6844         return result;
6845 }
6846
6847 static struct type *register_builtin_type(struct compile_state *state,
6848         const char *name, struct type *type)
6849 {
6850         struct hash_entry *ident;
6851         int name_len;
6852
6853         name_len = strlen(name);
6854         ident = lookup(state, name, name_len);
6855         
6856         if ((type->type & TYPE_MASK) == TYPE_PRODUCT) {
6857                 ulong_t elements = 0;
6858                 struct type *field;
6859                 type = new_type(TYPE_STRUCT, type, 0);
6860                 field = type->left;
6861                 while((field->type & TYPE_MASK) == TYPE_PRODUCT) {
6862                         elements++;
6863                         field = field->right;
6864                 }
6865                 elements++;
6866                 symbol(state, ident, &ident->sym_struct, 0, type);
6867                 type->type_ident = ident;
6868                 type->elements = elements;
6869         }
6870         symbol(state, ident, &ident->sym_ident, 0, type);
6871         ident->tok = TOK_TYPE_NAME;
6872         return type;
6873 }
6874
6875
6876 static void register_builtins(struct compile_state *state)
6877 {
6878         struct type *div_type, *ldiv_type;
6879         struct type *udiv_type, *uldiv_type;
6880         struct type *msr_type;
6881
6882         div_type = register_builtin_type(state, "__builtin_div_t",
6883                 partial_struct(state, "quot", &int_type,
6884                 partial_struct(state, "rem",  &int_type, 0)));
6885         ldiv_type = register_builtin_type(state, "__builtin_ldiv_t",
6886                 partial_struct(state, "quot", &long_type,
6887                 partial_struct(state, "rem",  &long_type, 0)));
6888         udiv_type = register_builtin_type(state, "__builtin_udiv_t",
6889                 partial_struct(state, "quot", &uint_type,
6890                 partial_struct(state, "rem",  &uint_type, 0)));
6891         uldiv_type = register_builtin_type(state, "__builtin_uldiv_t",
6892                 partial_struct(state, "quot", &ulong_type,
6893                 partial_struct(state, "rem",  &ulong_type, 0)));
6894
6895         register_builtin_function(state, "__builtin_div",   OP_SDIVT, div_type,
6896                 &int_type, &int_type);
6897         register_builtin_function(state, "__builtin_ldiv",  OP_SDIVT, ldiv_type,
6898                 &long_type, &long_type);
6899         register_builtin_function(state, "__builtin_udiv",  OP_UDIVT, udiv_type,
6900                 &uint_type, &uint_type);
6901         register_builtin_function(state, "__builtin_uldiv", OP_UDIVT, uldiv_type,
6902                 &ulong_type, &ulong_type);
6903
6904         register_builtin_function(state, "__builtin_inb", OP_INB, &uchar_type, 
6905                 &ushort_type);
6906         register_builtin_function(state, "__builtin_inw", OP_INW, &ushort_type,
6907                 &ushort_type);
6908         register_builtin_function(state, "__builtin_inl", OP_INL, &uint_type,   
6909                 &ushort_type);
6910
6911         register_builtin_function(state, "__builtin_outb", OP_OUTB, &void_type, 
6912                 &uchar_type, &ushort_type);
6913         register_builtin_function(state, "__builtin_outw", OP_OUTW, &void_type, 
6914                 &ushort_type, &ushort_type);
6915         register_builtin_function(state, "__builtin_outl", OP_OUTL, &void_type, 
6916                 &uint_type, &ushort_type);
6917         
6918         register_builtin_function(state, "__builtin_bsf", OP_BSF, &int_type, 
6919                 &int_type);
6920         register_builtin_function(state, "__builtin_bsr", OP_BSR, &int_type, 
6921                 &int_type);
6922
6923         msr_type = register_builtin_type(state, "__builtin_msr_t",
6924                 partial_struct(state, "lo", &ulong_type,
6925                 partial_struct(state, "hi", &ulong_type, 0)));
6926
6927         register_builtin_function(state, "__builtin_rdmsr", OP_RDMSR, msr_type,
6928                 &ulong_type);
6929         register_builtin_function(state, "__builtin_wrmsr", OP_WRMSR, &void_type,
6930                 &ulong_type, &ulong_type, &ulong_type);
6931         
6932         register_builtin_function(state, "__builtin_hlt", OP_HLT, &void_type, 
6933                 &void_type);
6934 }
6935
6936 static struct type *declarator(
6937         struct compile_state *state, struct type *type, 
6938         struct hash_entry **ident, int need_ident);
6939 static void decl(struct compile_state *state, struct triple *first);
6940 static struct type *specifier_qualifier_list(struct compile_state *state);
6941 static int isdecl_specifier(int tok);
6942 static struct type *decl_specifiers(struct compile_state *state);
6943 static int istype(int tok);
6944 static struct triple *expr(struct compile_state *state);
6945 static struct triple *assignment_expr(struct compile_state *state);
6946 static struct type *type_name(struct compile_state *state);
6947 static void statement(struct compile_state *state, struct triple *fist);
6948
6949 static struct triple *call_expr(
6950         struct compile_state *state, struct triple *func)
6951 {
6952         struct triple *def;
6953         struct type *param, *type;
6954         ulong_t pvals, index;
6955
6956         if ((func->type->type & TYPE_MASK) != TYPE_FUNCTION) {
6957                 error(state, 0, "Called object is not a function");
6958         }
6959         if (func->op != OP_LIST) {
6960                 internal_error(state, 0, "improper function");
6961         }
6962         eat(state, TOK_LPAREN);
6963         /* Find the return type without any specifiers */
6964         type = clone_type(0, func->type->left);
6965         def = new_triple(state, OP_CALL, func->type, -1, -1);
6966         def->type = type;
6967
6968         pvals = TRIPLE_RHS(def->sizes);
6969         MISC(def, 0) = func;
6970
6971         param = func->type->right;
6972         for(index = 0; index < pvals; index++) {
6973                 struct triple *val;
6974                 struct type *arg_type;
6975                 val = read_expr(state, assignment_expr(state));
6976                 arg_type = param;
6977                 if ((param->type & TYPE_MASK) == TYPE_PRODUCT) {
6978                         arg_type = param->left;
6979                 }
6980                 write_compatible(state, arg_type, val->type);
6981                 RHS(def, index) = val;
6982                 if (index != (pvals - 1)) {
6983                         eat(state, TOK_COMMA);
6984                         param = param->right;
6985                 }
6986         }
6987         eat(state, TOK_RPAREN);
6988         return def;
6989 }
6990
6991
6992 static struct triple *character_constant(struct compile_state *state)
6993 {
6994         struct triple *def;
6995         struct token *tk;
6996         const signed char *str, *end;
6997         int c;
6998         int str_len;
6999         eat(state, TOK_LIT_CHAR);
7000         tk = &state->token[0];
7001         str = tk->val.str + 1;
7002         str_len = tk->str_len - 2;
7003         if (str_len <= 0) {
7004                 error(state, 0, "empty character constant");
7005         }
7006         end = str + str_len;
7007         c = char_value(state, &str, end);
7008         if (str != end) {
7009                 error(state, 0, "multibyte character constant not supported");
7010         }
7011         def = int_const(state, &char_type, (ulong_t)((long_t)c));
7012         return def;
7013 }
7014
7015 static struct triple *string_constant(struct compile_state *state)
7016 {
7017         struct triple *def;
7018         struct token *tk;
7019         struct type *type;
7020         const signed char *str, *end;
7021         signed char *buf, *ptr;
7022         int str_len;
7023
7024         buf = 0;
7025         type = new_type(TYPE_ARRAY, &char_type, 0);
7026         type->elements = 0;
7027         /* The while loop handles string concatenation */
7028         do {
7029                 eat(state, TOK_LIT_STRING);
7030                 tk = &state->token[0];
7031                 str = tk->val.str + 1;
7032                 str_len = tk->str_len - 2;
7033                 if (str_len < 0) {
7034                         error(state, 0, "negative string constant length");
7035                 }
7036                 end = str + str_len;
7037                 ptr = buf;
7038                 buf = xmalloc(type->elements + str_len + 1, "string_constant");
7039                 memcpy(buf, ptr, type->elements);
7040                 ptr = buf + type->elements;
7041                 do {
7042                         *ptr++ = char_value(state, &str, end);
7043                 } while(str < end);
7044                 type->elements = ptr - buf;
7045         } while(peek(state) == TOK_LIT_STRING);
7046         *ptr = '\0';
7047         type->elements += 1;
7048         def = triple(state, OP_BLOBCONST, type, 0, 0);
7049         def->u.blob = buf;
7050         return def;
7051 }
7052
7053
7054 static struct triple *integer_constant(struct compile_state *state)
7055 {
7056         struct triple *def;
7057         unsigned long val;
7058         struct token *tk;
7059         char *end;
7060         int u, l, decimal;
7061         struct type *type;
7062
7063         eat(state, TOK_LIT_INT);
7064         tk = &state->token[0];
7065         errno = 0;
7066         decimal = (tk->val.str[0] != '0');
7067         val = strtoul(tk->val.str, &end, 0);
7068         if ((val == ULONG_MAX) && (errno == ERANGE)) {
7069                 error(state, 0, "Integer constant to large");
7070         }
7071         u = l = 0;
7072         if ((*end == 'u') || (*end == 'U')) {
7073                 u = 1;
7074                         end++;
7075         }
7076         if ((*end == 'l') || (*end == 'L')) {
7077                 l = 1;
7078                 end++;
7079         }
7080         if ((*end == 'u') || (*end == 'U')) {
7081                 u = 1;
7082                 end++;
7083         }
7084         if (*end) {
7085                 error(state, 0, "Junk at end of integer constant");
7086         }
7087         if (u && l)  {
7088                 type = &ulong_type;
7089         }
7090         else if (l) {
7091                 type = &long_type;
7092                 if (!decimal && (val > LONG_MAX)) {
7093                         type = &ulong_type;
7094                 }
7095         }
7096         else if (u) {
7097                 type = &uint_type;
7098                 if (val > UINT_MAX) {
7099                         type = &ulong_type;
7100                 }
7101         }
7102         else {
7103                 type = &int_type;
7104                 if (!decimal && (val > INT_MAX) && (val <= UINT_MAX)) {
7105                         type = &uint_type;
7106                 }
7107                 else if (!decimal && (val > LONG_MAX)) {
7108                         type = &ulong_type;
7109                 }
7110                 else if (val > INT_MAX) {
7111                         type = &long_type;
7112                 }
7113         }
7114         def = int_const(state, type, val);
7115         return def;
7116 }
7117
7118 static struct triple *primary_expr(struct compile_state *state)
7119 {
7120         struct triple *def;
7121         int tok;
7122         tok = peek(state);
7123         switch(tok) {
7124         case TOK_IDENT:
7125         {
7126                 struct hash_entry *ident;
7127                 /* Here ident is either:
7128                  * a varable name
7129                  * a function name
7130                  * an enumeration constant.
7131                  */
7132                 eat(state, TOK_IDENT);
7133                 ident = state->token[0].ident;
7134                 if (!ident->sym_ident) {
7135                         error(state, 0, "%s undeclared", ident->name);
7136                 }
7137                 def = ident->sym_ident->def;
7138                 break;
7139         }
7140         case TOK_ENUM_CONST:
7141                 /* Here ident is an enumeration constant */
7142                 eat(state, TOK_ENUM_CONST);
7143                 def = 0;
7144                 FINISHME();
7145                 break;
7146         case TOK_LPAREN:
7147                 eat(state, TOK_LPAREN);
7148                 def = expr(state);
7149                 eat(state, TOK_RPAREN);
7150                 break;
7151         case TOK_LIT_INT:
7152                 def = integer_constant(state);
7153                 break;
7154         case TOK_LIT_FLOAT:
7155                 eat(state, TOK_LIT_FLOAT);
7156                 error(state, 0, "Floating point constants not supported");
7157                 def = 0;
7158                 FINISHME();
7159                 break;
7160         case TOK_LIT_CHAR:
7161                 def = character_constant(state);
7162                 break;
7163         case TOK_LIT_STRING:
7164                 def = string_constant(state);
7165                 break;
7166         default:
7167                 def = 0;
7168                 error(state, 0, "Unexpected token: %s\n", tokens[tok]);
7169         }
7170         return def;
7171 }
7172
7173 static struct triple *postfix_expr(struct compile_state *state)
7174 {
7175         struct triple *def;
7176         int postfix;
7177         def = primary_expr(state);
7178         do {
7179                 struct triple *left;
7180                 int tok;
7181                 postfix = 1;
7182                 left = def;
7183                 switch((tok = peek(state))) {
7184                 case TOK_LBRACKET:
7185                         eat(state, TOK_LBRACKET);
7186                         def = mk_subscript_expr(state, left, expr(state));
7187                         eat(state, TOK_RBRACKET);
7188                         break;
7189                 case TOK_LPAREN:
7190                         def = call_expr(state, def);
7191                         break;
7192                 case TOK_DOT:
7193                 {
7194                         struct hash_entry *field;
7195                         eat(state, TOK_DOT);
7196                         eat(state, TOK_IDENT);
7197                         field = state->token[0].ident;
7198                         def = deref_field(state, def, field);
7199                         break;
7200                 }
7201                 case TOK_ARROW:
7202                 {
7203                         struct hash_entry *field;
7204                         eat(state, TOK_ARROW);
7205                         eat(state, TOK_IDENT);
7206                         field = state->token[0].ident;
7207                         def = mk_deref_expr(state, read_expr(state, def));
7208                         def = deref_field(state, def, field);
7209                         break;
7210                 }
7211                 case TOK_PLUSPLUS:
7212                         eat(state, TOK_PLUSPLUS);
7213                         def = mk_post_inc_expr(state, left);
7214                         break;
7215                 case TOK_MINUSMINUS:
7216                         eat(state, TOK_MINUSMINUS);
7217                         def = mk_post_dec_expr(state, left);
7218                         break;
7219                 default:
7220                         postfix = 0;
7221                         break;
7222                 }
7223         } while(postfix);
7224         return def;
7225 }
7226
7227 static struct triple *cast_expr(struct compile_state *state);
7228
7229 static struct triple *unary_expr(struct compile_state *state)
7230 {
7231         struct triple *def, *right;
7232         int tok;
7233         switch((tok = peek(state))) {
7234         case TOK_PLUSPLUS:
7235                 eat(state, TOK_PLUSPLUS);
7236                 def = mk_pre_inc_expr(state, unary_expr(state));
7237                 break;
7238         case TOK_MINUSMINUS:
7239                 eat(state, TOK_MINUSMINUS);
7240                 def = mk_pre_dec_expr(state, unary_expr(state));
7241                 break;
7242         case TOK_AND:
7243                 eat(state, TOK_AND);
7244                 def = mk_addr_expr(state, cast_expr(state), 0);
7245                 break;
7246         case TOK_STAR:
7247                 eat(state, TOK_STAR);
7248                 def = mk_deref_expr(state, read_expr(state, cast_expr(state)));
7249                 break;
7250         case TOK_PLUS:
7251                 eat(state, TOK_PLUS);
7252                 right = read_expr(state, cast_expr(state));
7253                 arithmetic(state, right);
7254                 def = integral_promotion(state, right);
7255                 break;
7256         case TOK_MINUS:
7257                 eat(state, TOK_MINUS);
7258                 right = read_expr(state, cast_expr(state));
7259                 arithmetic(state, right);
7260                 def = integral_promotion(state, right);
7261                 def = triple(state, OP_NEG, def->type, def, 0);
7262                 break;
7263         case TOK_TILDE:
7264                 eat(state, TOK_TILDE);
7265                 right = read_expr(state, cast_expr(state));
7266                 integral(state, right);
7267                 def = integral_promotion(state, right);
7268                 def = triple(state, OP_INVERT, def->type, def, 0);
7269                 break;
7270         case TOK_BANG:
7271                 eat(state, TOK_BANG);
7272                 right = read_expr(state, cast_expr(state));
7273                 bool(state, right);
7274                 def = lfalse_expr(state, right);
7275                 break;
7276         case TOK_SIZEOF:
7277         {
7278                 struct type *type;
7279                 int tok1, tok2;
7280                 eat(state, TOK_SIZEOF);
7281                 tok1 = peek(state);
7282                 tok2 = peek2(state);
7283                 if ((tok1 == TOK_LPAREN) && istype(tok2)) {
7284                         eat(state, TOK_LPAREN);
7285                         type = type_name(state);
7286                         eat(state, TOK_RPAREN);
7287                 }
7288                 else {
7289                         struct triple *expr;
7290                         expr = unary_expr(state);
7291                         type = expr->type;
7292                         release_expr(state, expr);
7293                 }
7294                 def = int_const(state, &ulong_type, size_of(state, type));
7295                 break;
7296         }
7297         case TOK_ALIGNOF:
7298         {
7299                 struct type *type;
7300                 int tok1, tok2;
7301                 eat(state, TOK_ALIGNOF);
7302                 tok1 = peek(state);
7303                 tok2 = peek2(state);
7304                 if ((tok1 == TOK_LPAREN) && istype(tok2)) {
7305                         eat(state, TOK_LPAREN);
7306                         type = type_name(state);
7307                         eat(state, TOK_RPAREN);
7308                 }
7309                 else {
7310                         struct triple *expr;
7311                         expr = unary_expr(state);
7312                         type = expr->type;
7313                         release_expr(state, expr);
7314                 }
7315                 def = int_const(state, &ulong_type, align_of(state, type));
7316                 break;
7317         }
7318         default:
7319                 def = postfix_expr(state);
7320                 break;
7321         }
7322         return def;
7323 }
7324
7325 static struct triple *cast_expr(struct compile_state *state)
7326 {
7327         struct triple *def;
7328         int tok1, tok2;
7329         tok1 = peek(state);
7330         tok2 = peek2(state);
7331         if ((tok1 == TOK_LPAREN) && istype(tok2)) {
7332                 struct type *type;
7333                 eat(state, TOK_LPAREN);
7334                 type = type_name(state);
7335                 eat(state, TOK_RPAREN);
7336                 def = read_expr(state, cast_expr(state));
7337                 def = triple(state, OP_COPY, type, def, 0);
7338         }
7339         else {
7340                 def = unary_expr(state);
7341         }
7342         return def;
7343 }
7344
7345 static struct triple *mult_expr(struct compile_state *state)
7346 {
7347         struct triple *def;
7348         int done;
7349         def = cast_expr(state);
7350         do {
7351                 struct triple *left, *right;
7352                 struct type *result_type;
7353                 int tok, op, sign;
7354                 done = 0;
7355                 switch(tok = (peek(state))) {
7356                 case TOK_STAR:
7357                 case TOK_DIV:
7358                 case TOK_MOD:
7359                         left = read_expr(state, def);
7360                         arithmetic(state, left);
7361
7362                         eat(state, tok);
7363
7364                         right = read_expr(state, cast_expr(state));
7365                         arithmetic(state, right);
7366
7367                         result_type = arithmetic_result(state, left, right);
7368                         sign = is_signed(result_type);
7369                         op = -1;
7370                         switch(tok) {
7371                         case TOK_STAR: op = sign? OP_SMUL : OP_UMUL; break;
7372                         case TOK_DIV:  op = sign? OP_SDIV : OP_UDIV; break;
7373                         case TOK_MOD:  op = sign? OP_SMOD : OP_UMOD; break;
7374                         }
7375                         def = triple(state, op, result_type, left, right);
7376                         break;
7377                 default:
7378                         done = 1;
7379                         break;
7380                 }
7381         } while(!done);
7382         return def;
7383 }
7384
7385 static struct triple *add_expr(struct compile_state *state)
7386 {
7387         struct triple *def;
7388         int done;
7389         def = mult_expr(state);
7390         do {
7391                 done = 0;
7392                 switch( peek(state)) {
7393                 case TOK_PLUS:
7394                         eat(state, TOK_PLUS);
7395                         def = mk_add_expr(state, def, mult_expr(state));
7396                         break;
7397                 case TOK_MINUS:
7398                         eat(state, TOK_MINUS);
7399                         def = mk_sub_expr(state, def, mult_expr(state));
7400                         break;
7401                 default:
7402                         done = 1;
7403                         break;
7404                 }
7405         } while(!done);
7406         return def;
7407 }
7408
7409 static struct triple *shift_expr(struct compile_state *state)
7410 {
7411         struct triple *def;
7412         int done;
7413         def = add_expr(state);
7414         do {
7415                 struct triple *left, *right;
7416                 int tok, op;
7417                 done = 0;
7418                 switch((tok = peek(state))) {
7419                 case TOK_SL:
7420                 case TOK_SR:
7421                         left = read_expr(state, def);
7422                         integral(state, left);
7423                         left = integral_promotion(state, left);
7424
7425                         eat(state, tok);
7426
7427                         right = read_expr(state, add_expr(state));
7428                         integral(state, right);
7429                         right = integral_promotion(state, right);
7430                         
7431                         op = (tok == TOK_SL)? OP_SL : 
7432                                 is_signed(left->type)? OP_SSR: OP_USR;
7433
7434                         def = triple(state, op, left->type, left, right);
7435                         break;
7436                 default:
7437                         done = 1;
7438                         break;
7439                 }
7440         } while(!done);
7441         return def;
7442 }
7443
7444 static struct triple *relational_expr(struct compile_state *state)
7445 {
7446 #warning "Extend relational exprs to work on more than arithmetic types"
7447         struct triple *def;
7448         int done;
7449         def = shift_expr(state);
7450         do {
7451                 struct triple *left, *right;
7452                 struct type *arg_type;
7453                 int tok, op, sign;
7454                 done = 0;
7455                 switch((tok = peek(state))) {
7456                 case TOK_LESS:
7457                 case TOK_MORE:
7458                 case TOK_LESSEQ:
7459                 case TOK_MOREEQ:
7460                         left = read_expr(state, def);
7461                         arithmetic(state, left);
7462
7463                         eat(state, tok);
7464
7465                         right = read_expr(state, shift_expr(state));
7466                         arithmetic(state, right);
7467
7468                         arg_type = arithmetic_result(state, left, right);
7469                         sign = is_signed(arg_type);
7470                         op = -1;
7471                         switch(tok) {
7472                         case TOK_LESS:   op = sign? OP_SLESS : OP_ULESS; break;
7473                         case TOK_MORE:   op = sign? OP_SMORE : OP_UMORE; break;
7474                         case TOK_LESSEQ: op = sign? OP_SLESSEQ : OP_ULESSEQ; break;
7475                         case TOK_MOREEQ: op = sign? OP_SMOREEQ : OP_UMOREEQ; break;
7476                         }
7477                         def = triple(state, op, &int_type, left, right);
7478                         break;
7479                 default:
7480                         done = 1;
7481                         break;
7482                 }
7483         } while(!done);
7484         return def;
7485 }
7486
7487 static struct triple *equality_expr(struct compile_state *state)
7488 {
7489 #warning "Extend equality exprs to work on more than arithmetic types"
7490         struct triple *def;
7491         int done;
7492         def = relational_expr(state);
7493         do {
7494                 struct triple *left, *right;
7495                 int tok, op;
7496                 done = 0;
7497                 switch((tok = peek(state))) {
7498                 case TOK_EQEQ:
7499                 case TOK_NOTEQ:
7500                         left = read_expr(state, def);
7501                         arithmetic(state, left);
7502                         eat(state, tok);
7503                         right = read_expr(state, relational_expr(state));
7504                         arithmetic(state, right);
7505                         op = (tok == TOK_EQEQ) ? OP_EQ: OP_NOTEQ;
7506                         def = triple(state, op, &int_type, left, right);
7507                         break;
7508                 default:
7509                         done = 1;
7510                         break;
7511                 }
7512         } while(!done);
7513         return def;
7514 }
7515
7516 static struct triple *and_expr(struct compile_state *state)
7517 {
7518         struct triple *def;
7519         def = equality_expr(state);
7520         while(peek(state) == TOK_AND) {
7521                 struct triple *left, *right;
7522                 struct type *result_type;
7523                 left = read_expr(state, def);
7524                 integral(state, left);
7525                 eat(state, TOK_AND);
7526                 right = read_expr(state, equality_expr(state));
7527                 integral(state, right);
7528                 result_type = arithmetic_result(state, left, right);
7529                 def = triple(state, OP_AND, result_type, left, right);
7530         }
7531         return def;
7532 }
7533
7534 static struct triple *xor_expr(struct compile_state *state)
7535 {
7536         struct triple *def;
7537         def = and_expr(state);
7538         while(peek(state) == TOK_XOR) {
7539                 struct triple *left, *right;
7540                 struct type *result_type;
7541                 left = read_expr(state, def);
7542                 integral(state, left);
7543                 eat(state, TOK_XOR);
7544                 right = read_expr(state, and_expr(state));
7545                 integral(state, right);
7546                 result_type = arithmetic_result(state, left, right);
7547                 def = triple(state, OP_XOR, result_type, left, right);
7548         }
7549         return def;
7550 }
7551
7552 static struct triple *or_expr(struct compile_state *state)
7553 {
7554         struct triple *def;
7555         def = xor_expr(state);
7556         while(peek(state) == TOK_OR) {
7557                 struct triple *left, *right;
7558                 struct type *result_type;
7559                 left = read_expr(state, def);
7560                 integral(state, left);
7561                 eat(state, TOK_OR);
7562                 right = read_expr(state, xor_expr(state));
7563                 integral(state, right);
7564                 result_type = arithmetic_result(state, left, right);
7565                 def = triple(state, OP_OR, result_type, left, right);
7566         }
7567         return def;
7568 }
7569
7570 static struct triple *land_expr(struct compile_state *state)
7571 {
7572         struct triple *def;
7573         def = or_expr(state);
7574         while(peek(state) == TOK_LOGAND) {
7575                 struct triple *left, *right;
7576                 left = read_expr(state, def);
7577                 bool(state, left);
7578                 eat(state, TOK_LOGAND);
7579                 right = read_expr(state, or_expr(state));
7580                 bool(state, right);
7581
7582                 def = triple(state, OP_LAND, &int_type,
7583                         ltrue_expr(state, left),
7584                         ltrue_expr(state, right));
7585         }
7586         return def;
7587 }
7588
7589 static struct triple *lor_expr(struct compile_state *state)
7590 {
7591         struct triple *def;
7592         def = land_expr(state);
7593         while(peek(state) == TOK_LOGOR) {
7594                 struct triple *left, *right;
7595                 left = read_expr(state, def);
7596                 bool(state, left);
7597                 eat(state, TOK_LOGOR);
7598                 right = read_expr(state, land_expr(state));
7599                 bool(state, right);
7600                 
7601                 def = triple(state, OP_LOR, &int_type,
7602                         ltrue_expr(state, left),
7603                         ltrue_expr(state, right));
7604         }
7605         return def;
7606 }
7607
7608 static struct triple *conditional_expr(struct compile_state *state)
7609 {
7610         struct triple *def;
7611         def = lor_expr(state);
7612         if (peek(state) == TOK_QUEST) {
7613                 struct triple *test, *left, *right;
7614                 bool(state, def);
7615                 test = ltrue_expr(state, read_expr(state, def));
7616                 eat(state, TOK_QUEST);
7617                 left = read_expr(state, expr(state));
7618                 eat(state, TOK_COLON);
7619                 right = read_expr(state, conditional_expr(state));
7620
7621                 def = cond_expr(state, test, left, right);
7622         }
7623         return def;
7624 }
7625
7626 static struct triple *eval_const_expr(
7627         struct compile_state *state, struct triple *expr)
7628 {
7629         struct triple *def;
7630         if (is_const(expr)) {
7631                 def = expr;
7632         } 
7633         else {
7634                 /* If we don't start out as a constant simplify into one */
7635                 struct triple *head, *ptr;
7636                 head = label(state); /* dummy initial triple */
7637                 flatten(state, head, expr);
7638                 for(ptr = head->next; ptr != head; ptr = ptr->next) {
7639                         simplify(state, ptr);
7640                 }
7641                 /* Remove the constant value the tail of the list */
7642                 def = head->prev;
7643                 def->prev->next = def->next;
7644                 def->next->prev = def->prev;
7645                 def->next = def->prev = def;
7646                 if (!is_const(def)) {
7647                         error(state, 0, "Not a constant expression");
7648                 }
7649                 /* Free the intermediate expressions */
7650                 while(head->next != head) {
7651                         release_triple(state, head->next);
7652                 }
7653                 free_triple(state, head);
7654         }
7655         return def;
7656 }
7657
7658 static struct triple *constant_expr(struct compile_state *state)
7659 {
7660         return eval_const_expr(state, conditional_expr(state));
7661 }
7662
7663 static struct triple *assignment_expr(struct compile_state *state)
7664 {
7665         struct triple *def, *left, *right;
7666         int tok, op, sign;
7667         /* The C grammer in K&R shows assignment expressions
7668          * only taking unary expressions as input on their
7669          * left hand side.  But specifies the precedence of
7670          * assignemnt as the lowest operator except for comma.
7671          *
7672          * Allowing conditional expressions on the left hand side
7673          * of an assignement results in a grammar that accepts
7674          * a larger set of statements than standard C.   As long
7675          * as the subset of the grammar that is standard C behaves
7676          * correctly this should cause no problems.
7677          * 
7678          * For the extra token strings accepted by the grammar
7679          * none of them should produce a valid lvalue, so they
7680          * should not produce functioning programs.
7681          *
7682          * GCC has this bug as well, so surprises should be minimal.
7683          */
7684         def = conditional_expr(state);
7685         left = def;
7686         switch((tok = peek(state))) {
7687         case TOK_EQ:
7688                 lvalue(state, left);
7689                 eat(state, TOK_EQ);
7690                 def = write_expr(state, left, 
7691                         read_expr(state, assignment_expr(state)));
7692                 break;
7693         case TOK_TIMESEQ:
7694         case TOK_DIVEQ:
7695         case TOK_MODEQ:
7696                 lvalue(state, left);
7697                 arithmetic(state, left);
7698                 eat(state, tok);
7699                 right = read_expr(state, assignment_expr(state));
7700                 arithmetic(state, right);
7701
7702                 sign = is_signed(left->type);
7703                 op = -1;
7704                 switch(tok) {
7705                 case TOK_TIMESEQ: op = sign? OP_SMUL : OP_UMUL; break;
7706                 case TOK_DIVEQ:   op = sign? OP_SDIV : OP_UDIV; break;
7707                 case TOK_MODEQ:   op = sign? OP_SMOD : OP_UMOD; break;
7708                 }
7709                 def = write_expr(state, left,
7710                         triple(state, op, left->type, 
7711                                 read_expr(state, left), right));
7712                 break;
7713         case TOK_PLUSEQ:
7714                 lvalue(state, left);
7715                 eat(state, TOK_PLUSEQ);
7716                 def = write_expr(state, left,
7717                         mk_add_expr(state, left, assignment_expr(state)));
7718                 break;
7719         case TOK_MINUSEQ:
7720                 lvalue(state, left);
7721                 eat(state, TOK_MINUSEQ);
7722                 def = write_expr(state, left,
7723                         mk_sub_expr(state, left, assignment_expr(state)));
7724                 break;
7725         case TOK_SLEQ:
7726         case TOK_SREQ:
7727         case TOK_ANDEQ:
7728         case TOK_XOREQ:
7729         case TOK_OREQ:
7730                 lvalue(state, left);
7731                 integral(state, left);
7732                 eat(state, tok);
7733                 right = read_expr(state, assignment_expr(state));
7734                 integral(state, right);
7735                 right = integral_promotion(state, right);
7736                 sign = is_signed(left->type);
7737                 op = -1;
7738                 switch(tok) {
7739                 case TOK_SLEQ:  op = OP_SL; break;
7740                 case TOK_SREQ:  op = sign? OP_SSR: OP_USR; break;
7741                 case TOK_ANDEQ: op = OP_AND; break;
7742                 case TOK_XOREQ: op = OP_XOR; break;
7743                 case TOK_OREQ:  op = OP_OR; break;
7744                 }
7745                 def = write_expr(state, left,
7746                         triple(state, op, left->type, 
7747                                 read_expr(state, left), right));
7748                 break;
7749         }
7750         return def;
7751 }
7752
7753 static struct triple *expr(struct compile_state *state)
7754 {
7755         struct triple *def;
7756         def = assignment_expr(state);
7757         while(peek(state) == TOK_COMMA) {
7758                 struct triple *left, *right;
7759                 left = def;
7760                 eat(state, TOK_COMMA);
7761                 right = assignment_expr(state);
7762                 def = triple(state, OP_COMMA, right->type, left, right);
7763         }
7764         return def;
7765 }
7766
7767 static void expr_statement(struct compile_state *state, struct triple *first)
7768 {
7769         if (peek(state) != TOK_SEMI) {
7770                 flatten(state, first, expr(state));
7771         }
7772         eat(state, TOK_SEMI);
7773 }
7774
7775 static void if_statement(struct compile_state *state, struct triple *first)
7776 {
7777         struct triple *test, *jmp1, *jmp2, *middle, *end;
7778
7779         jmp1 = jmp2 = middle = 0;
7780         eat(state, TOK_IF);
7781         eat(state, TOK_LPAREN);
7782         test = expr(state);
7783         bool(state, test);
7784         /* Cleanup and invert the test */
7785         test = lfalse_expr(state, read_expr(state, test));
7786         eat(state, TOK_RPAREN);
7787         /* Generate the needed pieces */
7788         middle = label(state);
7789         jmp1 = branch(state, middle, test);
7790         /* Thread the pieces together */
7791         flatten(state, first, test);
7792         flatten(state, first, jmp1);
7793         flatten(state, first, label(state));
7794         statement(state, first);
7795         if (peek(state) == TOK_ELSE) {
7796                 eat(state, TOK_ELSE);
7797                 /* Generate the rest of the pieces */
7798                 end = label(state);
7799                 jmp2 = branch(state, end, 0);
7800                 /* Thread them together */
7801                 flatten(state, first, jmp2);
7802                 flatten(state, first, middle);
7803                 statement(state, first);
7804                 flatten(state, first, end);
7805         }
7806         else {
7807                 flatten(state, first, middle);
7808         }
7809 }
7810
7811 static void for_statement(struct compile_state *state, struct triple *first)
7812 {
7813         struct triple *head, *test, *tail, *jmp1, *jmp2, *end;
7814         struct triple *label1, *label2, *label3;
7815         struct hash_entry *ident;
7816
7817         eat(state, TOK_FOR);
7818         eat(state, TOK_LPAREN);
7819         head = test = tail = jmp1 = jmp2 = 0;
7820         if (peek(state) != TOK_SEMI) {
7821                 head = expr(state);
7822         } 
7823         eat(state, TOK_SEMI);
7824         if (peek(state) != TOK_SEMI) {
7825                 test = expr(state);
7826                 bool(state, test);
7827                 test = ltrue_expr(state, read_expr(state, test));
7828         }
7829         eat(state, TOK_SEMI);
7830         if (peek(state) != TOK_RPAREN) {
7831                 tail = expr(state);
7832         }
7833         eat(state, TOK_RPAREN);
7834         /* Generate the needed pieces */
7835         label1 = label(state);
7836         label2 = label(state);
7837         label3 = label(state);
7838         if (test) {
7839                 jmp1 = branch(state, label3, 0);
7840                 jmp2 = branch(state, label1, test);
7841         }
7842         else {
7843                 jmp2 = branch(state, label1, 0);
7844         }
7845         end = label(state);
7846         /* Remember where break and continue go */
7847         start_scope(state);
7848         ident = state->i_break;
7849         symbol(state, ident, &ident->sym_ident, end, end->type);
7850         ident = state->i_continue;
7851         symbol(state, ident, &ident->sym_ident, label2, label2->type);
7852         /* Now include the body */
7853         flatten(state, first, head);
7854         flatten(state, first, jmp1);
7855         flatten(state, first, label1);
7856         statement(state, first);
7857         flatten(state, first, label2);
7858         flatten(state, first, tail);
7859         flatten(state, first, label3);
7860         flatten(state, first, test);
7861         flatten(state, first, jmp2);
7862         flatten(state, first, end);
7863         /* Cleanup the break/continue scope */
7864         end_scope(state);
7865 }
7866
7867 static void while_statement(struct compile_state *state, struct triple *first)
7868 {
7869         struct triple *label1, *test, *label2, *jmp1, *jmp2, *end;
7870         struct hash_entry *ident;
7871         eat(state, TOK_WHILE);
7872         eat(state, TOK_LPAREN);
7873         test = expr(state);
7874         bool(state, test);
7875         test = ltrue_expr(state, read_expr(state, test));
7876         eat(state, TOK_RPAREN);
7877         /* Generate the needed pieces */
7878         label1 = label(state);
7879         label2 = label(state);
7880         jmp1 = branch(state, label2, 0);
7881         jmp2 = branch(state, label1, test);
7882         end = label(state);
7883         /* Remember where break and continue go */
7884         start_scope(state);
7885         ident = state->i_break;
7886         symbol(state, ident, &ident->sym_ident, end, end->type);
7887         ident = state->i_continue;
7888         symbol(state, ident, &ident->sym_ident, label2, label2->type);
7889         /* Thread them together */
7890         flatten(state, first, jmp1);
7891         flatten(state, first, label1);
7892         statement(state, first);
7893         flatten(state, first, label2);
7894         flatten(state, first, test);
7895         flatten(state, first, jmp2);
7896         flatten(state, first, end);
7897         /* Cleanup the break/continue scope */
7898         end_scope(state);
7899 }
7900
7901 static void do_statement(struct compile_state *state, struct triple *first)
7902 {
7903         struct triple *label1, *label2, *test, *end;
7904         struct hash_entry *ident;
7905         eat(state, TOK_DO);
7906         /* Generate the needed pieces */
7907         label1 = label(state);
7908         label2 = label(state);
7909         end = label(state);
7910         /* Remember where break and continue go */
7911         start_scope(state);
7912         ident = state->i_break;
7913         symbol(state, ident, &ident->sym_ident, end, end->type);
7914         ident = state->i_continue;
7915         symbol(state, ident, &ident->sym_ident, label2, label2->type);
7916         /* Now include the body */
7917         flatten(state, first, label1);
7918         statement(state, first);
7919         /* Cleanup the break/continue scope */
7920         end_scope(state);
7921         /* Eat the rest of the loop */
7922         eat(state, TOK_WHILE);
7923         eat(state, TOK_LPAREN);
7924         test = read_expr(state, expr(state));
7925         bool(state, test);
7926         eat(state, TOK_RPAREN);
7927         eat(state, TOK_SEMI);
7928         /* Thread the pieces together */
7929         test = ltrue_expr(state, test);
7930         flatten(state, first, label2);
7931         flatten(state, first, test);
7932         flatten(state, first, branch(state, label1, test));
7933         flatten(state, first, end);
7934 }
7935
7936
7937 static void return_statement(struct compile_state *state, struct triple *first)
7938 {
7939         struct triple *jmp, *mv, *dest, *var, *val;
7940         int last;
7941         eat(state, TOK_RETURN);
7942
7943 #warning "FIXME implement a more general excess branch elimination"
7944         val = 0;
7945         /* If we have a return value do some more work */
7946         if (peek(state) != TOK_SEMI) {
7947                 val = read_expr(state, expr(state));
7948         }
7949         eat(state, TOK_SEMI);
7950
7951         /* See if this last statement in a function */
7952         last = ((peek(state) == TOK_RBRACE) && 
7953                 (state->scope_depth == GLOBAL_SCOPE_DEPTH +2));
7954
7955         /* Find the return variable */
7956         var = MISC(state->main_function, 0);
7957         /* Find the return destination */
7958         dest = RHS(state->main_function, 0)->prev;
7959         mv = jmp = 0;
7960         /* If needed generate a jump instruction */
7961         if (!last) {
7962                 jmp = branch(state, dest, 0);
7963         }
7964         /* If needed generate an assignment instruction */
7965         if (val) {
7966                 mv = write_expr(state, var, val);
7967         }
7968         /* Now put the code together */
7969         if (mv) {
7970                 flatten(state, first, mv);
7971                 flatten(state, first, jmp);
7972         }
7973         else if (jmp) {
7974                 flatten(state, first, jmp);
7975         }
7976 }
7977
7978 static void break_statement(struct compile_state *state, struct triple *first)
7979 {
7980         struct triple *dest;
7981         eat(state, TOK_BREAK);
7982         eat(state, TOK_SEMI);
7983         if (!state->i_break->sym_ident) {
7984                 error(state, 0, "break statement not within loop or switch");
7985         }
7986         dest = state->i_break->sym_ident->def;
7987         flatten(state, first, branch(state, dest, 0));
7988 }
7989
7990 static void continue_statement(struct compile_state *state, struct triple *first)
7991 {
7992         struct triple *dest;
7993         eat(state, TOK_CONTINUE);
7994         eat(state, TOK_SEMI);
7995         if (!state->i_continue->sym_ident) {
7996                 error(state, 0, "continue statement outside of a loop");
7997         }
7998         dest = state->i_continue->sym_ident->def;
7999         flatten(state, first, branch(state, dest, 0));
8000 }
8001
8002 static void goto_statement(struct compile_state *state, struct triple *first)
8003 {
8004         struct hash_entry *ident;
8005         eat(state, TOK_GOTO);
8006         eat(state, TOK_IDENT);
8007         ident = state->token[0].ident;
8008         if (!ident->sym_label) {
8009                 /* If this is a forward branch allocate the label now,
8010                  * it will be flattend in the appropriate location later.
8011                  */
8012                 struct triple *ins;
8013                 ins = label(state);
8014                 label_symbol(state, ident, ins);
8015         }
8016         eat(state, TOK_SEMI);
8017
8018         flatten(state, first, branch(state, ident->sym_label->def, 0));
8019 }
8020
8021 static void labeled_statement(struct compile_state *state, struct triple *first)
8022 {
8023         struct triple *ins;
8024         struct hash_entry *ident;
8025         eat(state, TOK_IDENT);
8026
8027         ident = state->token[0].ident;
8028         if (ident->sym_label && ident->sym_label->def) {
8029                 ins = ident->sym_label->def;
8030                 put_occurance(ins->occurance);
8031                 ins->occurance = new_occurance(state);
8032         }
8033         else {
8034                 ins = label(state);
8035                 label_symbol(state, ident, ins);
8036         }
8037         if (ins->id & TRIPLE_FLAG_FLATTENED) {
8038                 error(state, 0, "label %s already defined", ident->name);
8039         }
8040         flatten(state, first, ins);
8041
8042         eat(state, TOK_COLON);
8043         statement(state, first);
8044 }
8045
8046 static void switch_statement(struct compile_state *state, struct triple *first)
8047 {
8048         FINISHME();
8049         eat(state, TOK_SWITCH);
8050         eat(state, TOK_LPAREN);
8051         expr(state);
8052         eat(state, TOK_RPAREN);
8053         statement(state, first);
8054         error(state, 0, "switch statements are not implemented");
8055         FINISHME();
8056 }
8057
8058 static void case_statement(struct compile_state *state, struct triple *first)
8059 {
8060         FINISHME();
8061         eat(state, TOK_CASE);
8062         constant_expr(state);
8063         eat(state, TOK_COLON);
8064         statement(state, first);
8065         error(state, 0, "case statements are not implemented");
8066         FINISHME();
8067 }
8068
8069 static void default_statement(struct compile_state *state, struct triple *first)
8070 {
8071         FINISHME();
8072         eat(state, TOK_DEFAULT);
8073         eat(state, TOK_COLON);
8074         statement(state, first);
8075         error(state, 0, "default statements are not implemented");
8076         FINISHME();
8077 }
8078
8079 static void asm_statement(struct compile_state *state, struct triple *first)
8080 {
8081         struct asm_info *info;
8082         struct {
8083                 struct triple *constraint;
8084                 struct triple *expr;
8085         } out_param[MAX_LHS], in_param[MAX_RHS], clob_param[MAX_LHS];
8086         struct triple *def, *asm_str;
8087         int out, in, clobbers, more, colons, i;
8088
8089         eat(state, TOK_ASM);
8090         /* For now ignore the qualifiers */
8091         switch(peek(state)) {
8092         case TOK_CONST:
8093                 eat(state, TOK_CONST);
8094                 break;
8095         case TOK_VOLATILE:
8096                 eat(state, TOK_VOLATILE);
8097                 break;
8098         }
8099         eat(state, TOK_LPAREN);
8100         asm_str = string_constant(state);
8101
8102         colons = 0;
8103         out = in = clobbers = 0;
8104         /* Outputs */
8105         if ((colons == 0) && (peek(state) == TOK_COLON)) {
8106                 eat(state, TOK_COLON);
8107                 colons++;
8108                 more = (peek(state) == TOK_LIT_STRING);
8109                 while(more) {
8110                         struct triple *var;
8111                         struct triple *constraint;
8112                         char *str;
8113                         more = 0;
8114                         if (out > MAX_LHS) {
8115                                 error(state, 0, "Maximum output count exceeded.");
8116                         }
8117                         constraint = string_constant(state);
8118                         str = constraint->u.blob;
8119                         if (str[0] != '=') {
8120                                 error(state, 0, "Output constraint does not start with =");
8121                         }
8122                         constraint->u.blob = str + 1;
8123                         eat(state, TOK_LPAREN);
8124                         var = conditional_expr(state);
8125                         eat(state, TOK_RPAREN);
8126
8127                         lvalue(state, var);
8128                         out_param[out].constraint = constraint;
8129                         out_param[out].expr       = var;
8130                         if (peek(state) == TOK_COMMA) {
8131                                 eat(state, TOK_COMMA);
8132                                 more = 1;
8133                         }
8134                         out++;
8135                 }
8136         }
8137         /* Inputs */
8138         if ((colons == 1) && (peek(state) == TOK_COLON)) {
8139                 eat(state, TOK_COLON);
8140                 colons++;
8141                 more = (peek(state) == TOK_LIT_STRING);
8142                 while(more) {
8143                         struct triple *val;
8144                         struct triple *constraint;
8145                         char *str;
8146                         more = 0;
8147                         if (in > MAX_RHS) {
8148                                 error(state, 0, "Maximum input count exceeded.");
8149                         }
8150                         constraint = string_constant(state);
8151                         str = constraint->u.blob;
8152                         if (digitp(str[0] && str[1] == '\0')) {
8153                                 int val;
8154                                 val = digval(str[0]);
8155                                 if ((val < 0) || (val >= out)) {
8156                                         error(state, 0, "Invalid input constraint %d", val);
8157                                 }
8158                         }
8159                         eat(state, TOK_LPAREN);
8160                         val = conditional_expr(state);
8161                         eat(state, TOK_RPAREN);
8162
8163                         in_param[in].constraint = constraint;
8164                         in_param[in].expr       = val;
8165                         if (peek(state) == TOK_COMMA) {
8166                                 eat(state, TOK_COMMA);
8167                                 more = 1;
8168                         }
8169                         in++;
8170                 }
8171         }
8172
8173         /* Clobber */
8174         if ((colons == 2) && (peek(state) == TOK_COLON)) {
8175                 eat(state, TOK_COLON);
8176                 colons++;
8177                 more = (peek(state) == TOK_LIT_STRING);
8178                 while(more) {
8179                         struct triple *clobber;
8180                         more = 0;
8181                         if ((clobbers + out) > MAX_LHS) {
8182                                 error(state, 0, "Maximum clobber limit exceeded.");
8183                         }
8184                         clobber = string_constant(state);
8185                         eat(state, TOK_RPAREN);
8186
8187                         clob_param[clobbers].constraint = clobber;
8188                         if (peek(state) == TOK_COMMA) {
8189                                 eat(state, TOK_COMMA);
8190                                 more = 1;
8191                         }
8192                         clobbers++;
8193                 }
8194         }
8195         eat(state, TOK_RPAREN);
8196         eat(state, TOK_SEMI);
8197
8198
8199         info = xcmalloc(sizeof(*info), "asm_info");
8200         info->str = asm_str->u.blob;
8201         free_triple(state, asm_str);
8202
8203         def = new_triple(state, OP_ASM, &void_type, clobbers + out, in);
8204         def->u.ainfo = info;
8205
8206         /* Find the register constraints */
8207         for(i = 0; i < out; i++) {
8208                 struct triple *constraint;
8209                 constraint = out_param[i].constraint;
8210                 info->tmpl.lhs[i] = arch_reg_constraint(state, 
8211                         out_param[i].expr->type, constraint->u.blob);
8212                 free_triple(state, constraint);
8213         }
8214         for(; i - out < clobbers; i++) {
8215                 struct triple *constraint;
8216                 constraint = clob_param[i - out].constraint;
8217                 info->tmpl.lhs[i] = arch_reg_clobber(state, constraint->u.blob);
8218                 free_triple(state, constraint);
8219         }
8220         for(i = 0; i < in; i++) {
8221                 struct triple *constraint;
8222                 const char *str;
8223                 constraint = in_param[i].constraint;
8224                 str = constraint->u.blob;
8225                 if (digitp(str[0]) && str[1] == '\0') {
8226                         struct reg_info cinfo;
8227                         int val;
8228                         val = digval(str[0]);
8229                         cinfo.reg = info->tmpl.lhs[val].reg;
8230                         cinfo.regcm = arch_type_to_regcm(state, in_param[i].expr->type);
8231                         cinfo.regcm &= info->tmpl.lhs[val].regcm;
8232                         if (cinfo.reg == REG_UNSET) {
8233                                 cinfo.reg = REG_VIRT0 + val;
8234                         }
8235                         if (cinfo.regcm == 0) {
8236                                 error(state, 0, "No registers for %d", val);
8237                         }
8238                         info->tmpl.lhs[val] = cinfo;
8239                         info->tmpl.rhs[i]   = cinfo;
8240                                 
8241                 } else {
8242                         info->tmpl.rhs[i] = arch_reg_constraint(state, 
8243                                 in_param[i].expr->type, str);
8244                 }
8245                 free_triple(state, constraint);
8246         }
8247
8248         /* Now build the helper expressions */
8249         for(i = 0; i < in; i++) {
8250                 RHS(def, i) = read_expr(state,in_param[i].expr);
8251         }
8252         flatten(state, first, def);
8253         for(i = 0; i < out; i++) {
8254                 struct triple *piece;
8255                 piece = triple(state, OP_PIECE, out_param[i].expr->type, def, 0);
8256                 piece->u.cval = i;
8257                 LHS(def, i) = piece;
8258                 flatten(state, first,
8259                         write_expr(state, out_param[i].expr, piece));
8260         }
8261         for(; i - out < clobbers; i++) {
8262                 struct triple *piece;
8263                 piece = triple(state, OP_PIECE, &void_type, def, 0);
8264                 piece->u.cval = i;
8265                 LHS(def, i) = piece;
8266                 flatten(state, first, piece);
8267         }
8268 }
8269
8270
8271 static int isdecl(int tok)
8272 {
8273         switch(tok) {
8274         case TOK_AUTO:
8275         case TOK_REGISTER:
8276         case TOK_STATIC:
8277         case TOK_EXTERN:
8278         case TOK_TYPEDEF:
8279         case TOK_CONST:
8280         case TOK_RESTRICT:
8281         case TOK_VOLATILE:
8282         case TOK_VOID:
8283         case TOK_CHAR:
8284         case TOK_SHORT:
8285         case TOK_INT:
8286         case TOK_LONG:
8287         case TOK_FLOAT:
8288         case TOK_DOUBLE:
8289         case TOK_SIGNED:
8290         case TOK_UNSIGNED:
8291         case TOK_STRUCT:
8292         case TOK_UNION:
8293         case TOK_ENUM:
8294         case TOK_TYPE_NAME: /* typedef name */
8295                 return 1;
8296         default:
8297                 return 0;
8298         }
8299 }
8300
8301 static void compound_statement(struct compile_state *state, struct triple *first)
8302 {
8303         eat(state, TOK_LBRACE);
8304         start_scope(state);
8305
8306         /* statement-list opt */
8307         while (peek(state) != TOK_RBRACE) {
8308                 statement(state, first);
8309         }
8310         end_scope(state);
8311         eat(state, TOK_RBRACE);
8312 }
8313
8314 static void statement(struct compile_state *state, struct triple *first)
8315 {
8316         int tok;
8317         tok = peek(state);
8318         if (tok == TOK_LBRACE) {
8319                 compound_statement(state, first);
8320         }
8321         else if (tok == TOK_IF) {
8322                 if_statement(state, first); 
8323         }
8324         else if (tok == TOK_FOR) {
8325                 for_statement(state, first);
8326         }
8327         else if (tok == TOK_WHILE) {
8328                 while_statement(state, first);
8329         }
8330         else if (tok == TOK_DO) {
8331                 do_statement(state, first);
8332         }
8333         else if (tok == TOK_RETURN) {
8334                 return_statement(state, first);
8335         }
8336         else if (tok == TOK_BREAK) {
8337                 break_statement(state, first);
8338         }
8339         else if (tok == TOK_CONTINUE) {
8340                 continue_statement(state, first);
8341         }
8342         else if (tok == TOK_GOTO) {
8343                 goto_statement(state, first);
8344         }
8345         else if (tok == TOK_SWITCH) {
8346                 switch_statement(state, first);
8347         }
8348         else if (tok == TOK_ASM) {
8349                 asm_statement(state, first);
8350         }
8351         else if ((tok == TOK_IDENT) && (peek2(state) == TOK_COLON)) {
8352                 labeled_statement(state, first); 
8353         }
8354         else if (tok == TOK_CASE) {
8355                 case_statement(state, first);
8356         }
8357         else if (tok == TOK_DEFAULT) {
8358                 default_statement(state, first);
8359         }
8360         else if (isdecl(tok)) {
8361                 /* This handles C99 intermixing of statements and decls */
8362                 decl(state, first);
8363         }
8364         else {
8365                 expr_statement(state, first);
8366         }
8367 }
8368
8369 static struct type *param_decl(struct compile_state *state)
8370 {
8371         struct type *type;
8372         struct hash_entry *ident;
8373         /* Cheat so the declarator will know we are not global */
8374         start_scope(state); 
8375         ident = 0;
8376         type = decl_specifiers(state);
8377         type = declarator(state, type, &ident, 0);
8378         type->field_ident = ident;
8379         end_scope(state);
8380         return type;
8381 }
8382
8383 static struct type *param_type_list(struct compile_state *state, struct type *type)
8384 {
8385         struct type *ftype, **next;
8386         ftype = new_type(TYPE_FUNCTION, type, param_decl(state));
8387         next = &ftype->right;
8388         while(peek(state) == TOK_COMMA) {
8389                 eat(state, TOK_COMMA);
8390                 if (peek(state) == TOK_DOTS) {
8391                         eat(state, TOK_DOTS);
8392                         error(state, 0, "variadic functions not supported");
8393                 }
8394                 else {
8395                         *next = new_type(TYPE_PRODUCT, *next, param_decl(state));
8396                         next = &((*next)->right);
8397                 }
8398         }
8399         return ftype;
8400 }
8401
8402
8403 static struct type *type_name(struct compile_state *state)
8404 {
8405         struct type *type;
8406         type = specifier_qualifier_list(state);
8407         /* abstract-declarator (may consume no tokens) */
8408         type = declarator(state, type, 0, 0);
8409         return type;
8410 }
8411
8412 static struct type *direct_declarator(
8413         struct compile_state *state, struct type *type, 
8414         struct hash_entry **ident, int need_ident)
8415 {
8416         struct type *outer;
8417         int op;
8418         outer = 0;
8419         arrays_complete(state, type);
8420         switch(peek(state)) {
8421         case TOK_IDENT:
8422                 eat(state, TOK_IDENT);
8423                 if (!ident) {
8424                         error(state, 0, "Unexpected identifier found");
8425                 }
8426                 /* The name of what we are declaring */
8427                 *ident = state->token[0].ident;
8428                 break;
8429         case TOK_LPAREN:
8430                 eat(state, TOK_LPAREN);
8431                 outer = declarator(state, type, ident, need_ident);
8432                 eat(state, TOK_RPAREN);
8433                 break;
8434         default:
8435                 if (need_ident) {
8436                         error(state, 0, "Identifier expected");
8437                 }
8438                 break;
8439         }
8440         do {
8441                 op = 1;
8442                 arrays_complete(state, type);
8443                 switch(peek(state)) {
8444                 case TOK_LPAREN:
8445                         eat(state, TOK_LPAREN);
8446                         type = param_type_list(state, type);
8447                         eat(state, TOK_RPAREN);
8448                         break;
8449                 case TOK_LBRACKET:
8450                 {
8451                         unsigned int qualifiers;
8452                         struct triple *value;
8453                         value = 0;
8454                         eat(state, TOK_LBRACKET);
8455                         if (peek(state) != TOK_RBRACKET) {
8456                                 value = constant_expr(state);
8457                                 integral(state, value);
8458                         }
8459                         eat(state, TOK_RBRACKET);
8460
8461                         qualifiers = type->type & (QUAL_MASK | STOR_MASK);
8462                         type = new_type(TYPE_ARRAY | qualifiers, type, 0);
8463                         if (value) {
8464                                 type->elements = value->u.cval;
8465                                 free_triple(state, value);
8466                         } else {
8467                                 type->elements = ELEMENT_COUNT_UNSPECIFIED;
8468                                 op = 0;
8469                         }
8470                 }
8471                         break;
8472                 default:
8473                         op = 0;
8474                         break;
8475                 }
8476         } while(op);
8477         if (outer) {
8478                 struct type *inner;
8479                 arrays_complete(state, type);
8480                 FINISHME();
8481                 for(inner = outer; inner->left; inner = inner->left)
8482                         ;
8483                 inner->left = type;
8484                 type = outer;
8485         }
8486         return type;
8487 }
8488
8489 static struct type *declarator(
8490         struct compile_state *state, struct type *type, 
8491         struct hash_entry **ident, int need_ident)
8492 {
8493         while(peek(state) == TOK_STAR) {
8494                 eat(state, TOK_STAR);
8495                 type = new_type(TYPE_POINTER | (type->type & STOR_MASK), type, 0);
8496         }
8497         type = direct_declarator(state, type, ident, need_ident);
8498         return type;
8499 }
8500
8501
8502 static struct type *typedef_name(
8503         struct compile_state *state, unsigned int specifiers)
8504 {
8505         struct hash_entry *ident;
8506         struct type *type;
8507         eat(state, TOK_TYPE_NAME);
8508         ident = state->token[0].ident;
8509         type = ident->sym_ident->type;
8510         specifiers |= type->type & QUAL_MASK;
8511         if ((specifiers & (STOR_MASK | QUAL_MASK)) != 
8512                 (type->type & (STOR_MASK | QUAL_MASK))) {
8513                 type = clone_type(specifiers, type);
8514         }
8515         return type;
8516 }
8517
8518 static struct type *enum_specifier(
8519         struct compile_state *state, unsigned int specifiers)
8520 {
8521         int tok;
8522         struct type *type;
8523         type = 0;
8524         FINISHME();
8525         eat(state, TOK_ENUM);
8526         tok = peek(state);
8527         if (tok == TOK_IDENT) {
8528                 eat(state, TOK_IDENT);
8529         }
8530         if ((tok != TOK_IDENT) || (peek(state) == TOK_LBRACE)) {
8531                 eat(state, TOK_LBRACE);
8532                 do {
8533                         eat(state, TOK_IDENT);
8534                         if (peek(state) == TOK_EQ) {
8535                                 eat(state, TOK_EQ);
8536                                 constant_expr(state);
8537                         }
8538                         if (peek(state) == TOK_COMMA) {
8539                                 eat(state, TOK_COMMA);
8540                         }
8541                 } while(peek(state) != TOK_RBRACE);
8542                 eat(state, TOK_RBRACE);
8543         }
8544         FINISHME();
8545         return type;
8546 }
8547
8548 static struct type *struct_declarator(
8549         struct compile_state *state, struct type *type, struct hash_entry **ident)
8550 {
8551         int tok;
8552         tok = peek(state);
8553         if (tok != TOK_COLON) {
8554                 type = declarator(state, type, ident, 1);
8555         }
8556         if ((tok == TOK_COLON) || (peek(state) == TOK_COLON)) {
8557                 struct triple *value;
8558                 eat(state, TOK_COLON);
8559                 value = constant_expr(state);
8560 #warning "FIXME implement bitfields to reduce register usage"
8561                 error(state, 0, "bitfields not yet implemented");
8562         }
8563         return type;
8564 }
8565
8566 static struct type *struct_or_union_specifier(
8567         struct compile_state *state, unsigned int spec)
8568 {
8569         struct type *struct_type;
8570         struct hash_entry *ident;
8571         unsigned int type_join;
8572         int tok;
8573         struct_type = 0;
8574         ident = 0;
8575         switch(peek(state)) {
8576         case TOK_STRUCT:
8577                 eat(state, TOK_STRUCT);
8578                 type_join = TYPE_PRODUCT;
8579                 break;
8580         case TOK_UNION:
8581                 eat(state, TOK_UNION);
8582                 type_join = TYPE_OVERLAP;
8583                 error(state, 0, "unions not yet supported\n");
8584                 break;
8585         default:
8586                 eat(state, TOK_STRUCT);
8587                 type_join = TYPE_PRODUCT;
8588                 break;
8589         }
8590         tok = peek(state);
8591         if ((tok == TOK_IDENT) || (tok == TOK_TYPE_NAME)) {
8592                 eat(state, tok);
8593                 ident = state->token[0].ident;
8594         }
8595         if (!ident || (peek(state) == TOK_LBRACE)) {
8596                 ulong_t elements;
8597                 struct type **next;
8598                 elements = 0;
8599                 eat(state, TOK_LBRACE);
8600                 next = &struct_type;
8601                 do {
8602                         struct type *base_type;
8603                         int done;
8604                         base_type = specifier_qualifier_list(state);
8605                         do {
8606                                 struct type *type;
8607                                 struct hash_entry *fident;
8608                                 done = 1;
8609                                 type = struct_declarator(state, base_type, &fident);
8610                                 elements++;
8611                                 if (peek(state) == TOK_COMMA) {
8612                                         done = 0;
8613                                         eat(state, TOK_COMMA);
8614                                 }
8615                                 type = clone_type(0, type);
8616                                 type->field_ident = fident;
8617                                 if (*next) {
8618                                         *next = new_type(type_join, *next, type);
8619                                         next = &((*next)->right);
8620                                 } else {
8621                                         *next = type;
8622                                 }
8623                         } while(!done);
8624                         eat(state, TOK_SEMI);
8625                 } while(peek(state) != TOK_RBRACE);
8626                 eat(state, TOK_RBRACE);
8627                 struct_type = new_type(TYPE_STRUCT | spec, struct_type, 0);
8628                 struct_type->type_ident = ident;
8629                 struct_type->elements = elements;
8630                 symbol(state, ident, &ident->sym_struct, 0, struct_type);
8631         }
8632         if (ident && ident->sym_struct) {
8633                 struct_type = clone_type(spec,  ident->sym_struct->type);
8634         }
8635         else if (ident && !ident->sym_struct) {
8636                 error(state, 0, "struct %s undeclared", ident->name);
8637         }
8638         return struct_type;
8639 }
8640
8641 static unsigned int storage_class_specifier_opt(struct compile_state *state)
8642 {
8643         unsigned int specifiers;
8644         switch(peek(state)) {
8645         case TOK_AUTO:
8646                 eat(state, TOK_AUTO);
8647                 specifiers = STOR_AUTO;
8648                 break;
8649         case TOK_REGISTER:
8650                 eat(state, TOK_REGISTER);
8651                 specifiers = STOR_REGISTER;
8652                 break;
8653         case TOK_STATIC:
8654                 eat(state, TOK_STATIC);
8655                 specifiers = STOR_STATIC;
8656                 break;
8657         case TOK_EXTERN:
8658                 eat(state, TOK_EXTERN);
8659                 specifiers = STOR_EXTERN;
8660                 break;
8661         case TOK_TYPEDEF:
8662                 eat(state, TOK_TYPEDEF);
8663                 specifiers = STOR_TYPEDEF;
8664                 break;
8665         default:
8666                 if (state->scope_depth <= GLOBAL_SCOPE_DEPTH) {
8667                         specifiers = STOR_STATIC;
8668                 }
8669                 else {
8670                         specifiers = STOR_AUTO;
8671                 }
8672         }
8673         return specifiers;
8674 }
8675
8676 static unsigned int function_specifier_opt(struct compile_state *state)
8677 {
8678         /* Ignore the inline keyword */
8679         unsigned int specifiers;
8680         specifiers = 0;
8681         switch(peek(state)) {
8682         case TOK_INLINE:
8683                 eat(state, TOK_INLINE);
8684                 specifiers = STOR_INLINE;
8685         }
8686         return specifiers;
8687 }
8688
8689 static unsigned int type_qualifiers(struct compile_state *state)
8690 {
8691         unsigned int specifiers;
8692         int done;
8693         done = 0;
8694         specifiers = QUAL_NONE;
8695         do {
8696                 switch(peek(state)) {
8697                 case TOK_CONST:
8698                         eat(state, TOK_CONST);
8699                         specifiers = QUAL_CONST;
8700                         break;
8701                 case TOK_VOLATILE:
8702                         eat(state, TOK_VOLATILE);
8703                         specifiers = QUAL_VOLATILE;
8704                         break;
8705                 case TOK_RESTRICT:
8706                         eat(state, TOK_RESTRICT);
8707                         specifiers = QUAL_RESTRICT;
8708                         break;
8709                 default:
8710                         done = 1;
8711                         break;
8712                 }
8713         } while(!done);
8714         return specifiers;
8715 }
8716
8717 static struct type *type_specifier(
8718         struct compile_state *state, unsigned int spec)
8719 {
8720         struct type *type;
8721         type = 0;
8722         switch(peek(state)) {
8723         case TOK_VOID:
8724                 eat(state, TOK_VOID);
8725                 type = new_type(TYPE_VOID | spec, 0, 0);
8726                 break;
8727         case TOK_CHAR:
8728                 eat(state, TOK_CHAR);
8729                 type = new_type(TYPE_CHAR | spec, 0, 0);
8730                 break;
8731         case TOK_SHORT:
8732                 eat(state, TOK_SHORT);
8733                 if (peek(state) == TOK_INT) {
8734                         eat(state, TOK_INT);
8735                 }
8736                 type = new_type(TYPE_SHORT | spec, 0, 0);
8737                 break;
8738         case TOK_INT:
8739                 eat(state, TOK_INT);
8740                 type = new_type(TYPE_INT | spec, 0, 0);
8741                 break;
8742         case TOK_LONG:
8743                 eat(state, TOK_LONG);
8744                 switch(peek(state)) {
8745                 case TOK_LONG:
8746                         eat(state, TOK_LONG);
8747                         error(state, 0, "long long not supported");
8748                         break;
8749                 case TOK_DOUBLE:
8750                         eat(state, TOK_DOUBLE);
8751                         error(state, 0, "long double not supported");
8752                         break;
8753                 case TOK_INT:
8754                         eat(state, TOK_INT);
8755                         type = new_type(TYPE_LONG | spec, 0, 0);
8756                         break;
8757                 default:
8758                         type = new_type(TYPE_LONG | spec, 0, 0);
8759                         break;
8760                 }
8761                 break;
8762         case TOK_FLOAT:
8763                 eat(state, TOK_FLOAT);
8764                 error(state, 0, "type float not supported");
8765                 break;
8766         case TOK_DOUBLE:
8767                 eat(state, TOK_DOUBLE);
8768                 error(state, 0, "type double not supported");
8769                 break;
8770         case TOK_SIGNED:
8771                 eat(state, TOK_SIGNED);
8772                 switch(peek(state)) {
8773                 case TOK_LONG:
8774                         eat(state, TOK_LONG);
8775                         switch(peek(state)) {
8776                         case TOK_LONG:
8777                                 eat(state, TOK_LONG);
8778                                 error(state, 0, "type long long not supported");
8779                                 break;
8780                         case TOK_INT:
8781                                 eat(state, TOK_INT);
8782                                 type = new_type(TYPE_LONG | spec, 0, 0);
8783                                 break;
8784                         default:
8785                                 type = new_type(TYPE_LONG | spec, 0, 0);
8786                                 break;
8787                         }
8788                         break;
8789                 case TOK_INT:
8790                         eat(state, TOK_INT);
8791                         type = new_type(TYPE_INT | spec, 0, 0);
8792                         break;
8793                 case TOK_SHORT:
8794                         eat(state, TOK_SHORT);
8795                         type = new_type(TYPE_SHORT | spec, 0, 0);
8796                         break;
8797                 case TOK_CHAR:
8798                         eat(state, TOK_CHAR);
8799                         type = new_type(TYPE_CHAR | spec, 0, 0);
8800                         break;
8801                 default:
8802                         type = new_type(TYPE_INT | spec, 0, 0);
8803                         break;
8804                 }
8805                 break;
8806         case TOK_UNSIGNED:
8807                 eat(state, TOK_UNSIGNED);
8808                 switch(peek(state)) {
8809                 case TOK_LONG:
8810                         eat(state, TOK_LONG);
8811                         switch(peek(state)) {
8812                         case TOK_LONG:
8813                                 eat(state, TOK_LONG);
8814                                 error(state, 0, "unsigned long long not supported");
8815                                 break;
8816                         case TOK_INT:
8817                                 eat(state, TOK_INT);
8818                                 type = new_type(TYPE_ULONG | spec, 0, 0);
8819                                 break;
8820                         default:
8821                                 type = new_type(TYPE_ULONG | spec, 0, 0);
8822                                 break;
8823                         }
8824                         break;
8825                 case TOK_INT:
8826                         eat(state, TOK_INT);
8827                         type = new_type(TYPE_UINT | spec, 0, 0);
8828                         break;
8829                 case TOK_SHORT:
8830                         eat(state, TOK_SHORT);
8831                         type = new_type(TYPE_USHORT | spec, 0, 0);
8832                         break;
8833                 case TOK_CHAR:
8834                         eat(state, TOK_CHAR);
8835                         type = new_type(TYPE_UCHAR | spec, 0, 0);
8836                         break;
8837                 default:
8838                         type = new_type(TYPE_UINT | spec, 0, 0);
8839                         break;
8840                 }
8841                 break;
8842                 /* struct or union specifier */
8843         case TOK_STRUCT:
8844         case TOK_UNION:
8845                 type = struct_or_union_specifier(state, spec);
8846                 break;
8847                 /* enum-spefifier */
8848         case TOK_ENUM:
8849                 type = enum_specifier(state, spec);
8850                 break;
8851                 /* typedef name */
8852         case TOK_TYPE_NAME:
8853                 type = typedef_name(state, spec);
8854                 break;
8855         default:
8856                 error(state, 0, "bad type specifier %s", 
8857                         tokens[peek(state)]);
8858                 break;
8859         }
8860         return type;
8861 }
8862
8863 static int istype(int tok)
8864 {
8865         switch(tok) {
8866         case TOK_CONST:
8867         case TOK_RESTRICT:
8868         case TOK_VOLATILE:
8869         case TOK_VOID:
8870         case TOK_CHAR:
8871         case TOK_SHORT:
8872         case TOK_INT:
8873         case TOK_LONG:
8874         case TOK_FLOAT:
8875         case TOK_DOUBLE:
8876         case TOK_SIGNED:
8877         case TOK_UNSIGNED:
8878         case TOK_STRUCT:
8879         case TOK_UNION:
8880         case TOK_ENUM:
8881         case TOK_TYPE_NAME:
8882                 return 1;
8883         default:
8884                 return 0;
8885         }
8886 }
8887
8888
8889 static struct type *specifier_qualifier_list(struct compile_state *state)
8890 {
8891         struct type *type;
8892         unsigned int specifiers = 0;
8893
8894         /* type qualifiers */
8895         specifiers |= type_qualifiers(state);
8896
8897         /* type specifier */
8898         type = type_specifier(state, specifiers);
8899
8900         return type;
8901 }
8902
8903 static int isdecl_specifier(int tok)
8904 {
8905         switch(tok) {
8906                 /* storage class specifier */
8907         case TOK_AUTO:
8908         case TOK_REGISTER:
8909         case TOK_STATIC:
8910         case TOK_EXTERN:
8911         case TOK_TYPEDEF:
8912                 /* type qualifier */
8913         case TOK_CONST:
8914         case TOK_RESTRICT:
8915         case TOK_VOLATILE:
8916                 /* type specifiers */
8917         case TOK_VOID:
8918         case TOK_CHAR:
8919         case TOK_SHORT:
8920         case TOK_INT:
8921         case TOK_LONG:
8922         case TOK_FLOAT:
8923         case TOK_DOUBLE:
8924         case TOK_SIGNED:
8925         case TOK_UNSIGNED:
8926                 /* struct or union specifier */
8927         case TOK_STRUCT:
8928         case TOK_UNION:
8929                 /* enum-spefifier */
8930         case TOK_ENUM:
8931                 /* typedef name */
8932         case TOK_TYPE_NAME:
8933                 /* function specifiers */
8934         case TOK_INLINE:
8935                 return 1;
8936         default:
8937                 return 0;
8938         }
8939 }
8940
8941 static struct type *decl_specifiers(struct compile_state *state)
8942 {
8943         struct type *type;
8944         unsigned int specifiers;
8945         /* I am overly restrictive in the arragement of specifiers supported.
8946          * C is overly flexible in this department it makes interpreting
8947          * the parse tree difficult.
8948          */
8949         specifiers = 0;
8950
8951         /* storage class specifier */
8952         specifiers |= storage_class_specifier_opt(state);
8953
8954         /* function-specifier */
8955         specifiers |= function_specifier_opt(state);
8956
8957         /* type qualifier */
8958         specifiers |= type_qualifiers(state);
8959
8960         /* type specifier */
8961         type = type_specifier(state, specifiers);
8962         return type;
8963 }
8964
8965 struct field_info {
8966         struct type *type;
8967         size_t offset;
8968 };
8969
8970 static struct field_info designator(struct compile_state *state, struct type *type)
8971 {
8972         int tok;
8973         struct field_info info;
8974         info.offset = ~0U;
8975         info.type = 0;
8976         do {
8977                 switch(peek(state)) {
8978                 case TOK_LBRACKET:
8979                 {
8980                         struct triple *value;
8981                         if ((type->type & TYPE_MASK) != TYPE_ARRAY) {
8982                                 error(state, 0, "Array designator not in array initializer");
8983                         }
8984                         eat(state, TOK_LBRACKET);
8985                         value = constant_expr(state);
8986                         eat(state, TOK_RBRACKET);
8987
8988                         info.type = type->left;
8989                         info.offset = value->u.cval * size_of(state, info.type);
8990                         break;
8991                 }
8992                 case TOK_DOT:
8993                 {
8994                         struct hash_entry *field;
8995                         if ((type->type & TYPE_MASK) != TYPE_STRUCT) {
8996                                 error(state, 0, "Struct designator not in struct initializer");
8997                         }
8998                         eat(state, TOK_DOT);
8999                         eat(state, TOK_IDENT);
9000                         field = state->token[0].ident;
9001                         info.offset = field_offset(state, type, field);
9002                         info.type   = field_type(state, type, field);
9003                         break;
9004                 }
9005                 default:
9006                         error(state, 0, "Invalid designator");
9007                 }
9008                 tok = peek(state);
9009         } while((tok == TOK_LBRACKET) || (tok == TOK_DOT));
9010         eat(state, TOK_EQ);
9011         return info;
9012 }
9013
9014 static struct triple *initializer(
9015         struct compile_state *state, struct type *type)
9016 {
9017         struct triple *result;
9018         if (peek(state) != TOK_LBRACE) {
9019                 result = assignment_expr(state);
9020         }
9021         else {
9022                 int comma;
9023                 size_t max_offset;
9024                 struct field_info info;
9025                 void *buf;
9026                 if (((type->type & TYPE_MASK) != TYPE_ARRAY) &&
9027                         ((type->type & TYPE_MASK) != TYPE_STRUCT)) {
9028                         internal_error(state, 0, "unknown initializer type");
9029                 }
9030                 info.offset = 0;
9031                 info.type = type->left;
9032                 if ((type->type & TYPE_MASK) == TYPE_STRUCT) {
9033                         info.type = next_field(state, type, 0);
9034                 }
9035                 if (type->elements == ELEMENT_COUNT_UNSPECIFIED) {
9036                         max_offset = 0;
9037                 } else {
9038                         max_offset = size_of(state, type);
9039                 }
9040                 buf = xcmalloc(max_offset, "initializer");
9041                 eat(state, TOK_LBRACE);
9042                 do {
9043                         struct triple *value;
9044                         struct type *value_type;
9045                         size_t value_size;
9046                         void *dest;
9047                         int tok;
9048                         comma = 0;
9049                         tok = peek(state);
9050                         if ((tok == TOK_LBRACKET) || (tok == TOK_DOT)) {
9051                                 info = designator(state, type);
9052                         }
9053                         if ((type->elements != ELEMENT_COUNT_UNSPECIFIED) &&
9054                                 (info.offset >= max_offset)) {
9055                                 error(state, 0, "element beyond bounds");
9056                         }
9057                         value_type = info.type;
9058                         value = eval_const_expr(state, initializer(state, value_type));
9059                         value_size = size_of(state, value_type);
9060                         if (((type->type & TYPE_MASK) == TYPE_ARRAY) &&
9061                                 (type->elements == ELEMENT_COUNT_UNSPECIFIED) &&
9062                                 (max_offset <= info.offset)) {
9063                                 void *old_buf;
9064                                 size_t old_size;
9065                                 old_buf = buf;
9066                                 old_size = max_offset;
9067                                 max_offset = info.offset + value_size;
9068                                 buf = xmalloc(max_offset, "initializer");
9069                                 memcpy(buf, old_buf, old_size);
9070                                 xfree(old_buf);
9071                         }
9072                         dest = ((char *)buf) + info.offset;
9073                         if (value->op == OP_BLOBCONST) {
9074                                 memcpy(dest, value->u.blob, value_size);
9075                         }
9076                         else if ((value->op == OP_INTCONST) && (value_size == 1)) {
9077                                 *((uint8_t *)dest) = value->u.cval & 0xff;
9078                         }
9079                         else if ((value->op == OP_INTCONST) && (value_size == 2)) {
9080                                 *((uint16_t *)dest) = value->u.cval & 0xffff;
9081                         }
9082                         else if ((value->op == OP_INTCONST) && (value_size == 4)) {
9083                                 *((uint32_t *)dest) = value->u.cval & 0xffffffff;
9084                         }
9085                         else {
9086                                 internal_error(state, 0, "unhandled constant initializer");
9087                         }
9088                         free_triple(state, value);
9089                         if (peek(state) == TOK_COMMA) {
9090                                 eat(state, TOK_COMMA);
9091                                 comma = 1;
9092                         }
9093                         info.offset += value_size;
9094                         if ((type->type & TYPE_MASK) == TYPE_STRUCT) {
9095                                 info.type = next_field(state, type, info.type);
9096                                 info.offset = field_offset(state, type, 
9097                                         info.type->field_ident);
9098                         }
9099                 } while(comma && (peek(state) != TOK_RBRACE));
9100                 if ((type->elements == ELEMENT_COUNT_UNSPECIFIED) &&
9101                         ((type->type & TYPE_MASK) == TYPE_ARRAY)) {
9102                         type->elements = max_offset / size_of(state, type->left);
9103                 }
9104                 eat(state, TOK_RBRACE);
9105                 result = triple(state, OP_BLOBCONST, type, 0, 0);
9106                 result->u.blob = buf;
9107         }
9108         return result;
9109 }
9110
9111 static void resolve_branches(struct compile_state *state)
9112 {
9113         /* Make a second pass and finish anything outstanding
9114          * with respect to branches.  The only outstanding item
9115          * is to see if there are goto to labels that have not
9116          * been defined and to error about them.
9117          */
9118         int i;
9119         for(i = 0; i < HASH_TABLE_SIZE; i++) {
9120                 struct hash_entry *entry;
9121                 for(entry = state->hash_table[i]; entry; entry = entry->next) {
9122                         struct triple *ins;
9123                         if (!entry->sym_label) {
9124                                 continue;
9125                         }
9126                         ins = entry->sym_label->def;
9127                         if (!(ins->id & TRIPLE_FLAG_FLATTENED)) {
9128                                 error(state, ins, "label `%s' used but not defined",
9129                                         entry->name);
9130                         }
9131                 }
9132         }
9133 }
9134
9135 static struct triple *function_definition(
9136         struct compile_state *state, struct type *type)
9137 {
9138         struct triple *def, *tmp, *first, *end;
9139         struct hash_entry *ident;
9140         struct type *param;
9141         int i;
9142         if ((type->type &TYPE_MASK) != TYPE_FUNCTION) {
9143                 error(state, 0, "Invalid function header");
9144         }
9145
9146         /* Verify the function type */
9147         if (((type->right->type & TYPE_MASK) != TYPE_VOID)  &&
9148                 ((type->right->type & TYPE_MASK) != TYPE_PRODUCT) &&
9149                 (type->right->field_ident == 0)) {
9150                 error(state, 0, "Invalid function parameters");
9151         }
9152         param = type->right;
9153         i = 0;
9154         while((param->type & TYPE_MASK) == TYPE_PRODUCT) {
9155                 i++;
9156                 if (!param->left->field_ident) {
9157                         error(state, 0, "No identifier for parameter %d\n", i);
9158                 }
9159                 param = param->right;
9160         }
9161         i++;
9162         if (((param->type & TYPE_MASK) != TYPE_VOID) && !param->field_ident) {
9163                 error(state, 0, "No identifier for paramter %d\n", i);
9164         }
9165         
9166         /* Get a list of statements for this function. */
9167         def = triple(state, OP_LIST, type, 0, 0);
9168
9169         /* Start a new scope for the passed parameters */
9170         start_scope(state);
9171
9172         /* Put a label at the very start of a function */
9173         first = label(state);
9174         RHS(def, 0) = first;
9175
9176         /* Put a label at the very end of a function */
9177         end = label(state);
9178         flatten(state, first, end);
9179
9180         /* Walk through the parameters and create symbol table entries
9181          * for them.
9182          */
9183         param = type->right;
9184         while((param->type & TYPE_MASK) == TYPE_PRODUCT) {
9185                 ident = param->left->field_ident;
9186                 tmp = variable(state, param->left);
9187                 symbol(state, ident, &ident->sym_ident, tmp, tmp->type);
9188                 flatten(state, end, tmp);
9189                 param = param->right;
9190         }
9191         if ((param->type & TYPE_MASK) != TYPE_VOID) {
9192                 /* And don't forget the last parameter */
9193                 ident = param->field_ident;
9194                 tmp = variable(state, param);
9195                 symbol(state, ident, &ident->sym_ident, tmp, tmp->type);
9196                 flatten(state, end, tmp);
9197         }
9198         /* Add a variable for the return value */
9199         MISC(def, 0) = 0;
9200         if ((type->left->type & TYPE_MASK) != TYPE_VOID) {
9201                 /* Remove all type qualifiers from the return type */
9202                 tmp = variable(state, clone_type(0, type->left));
9203                 flatten(state, end, tmp);
9204                 /* Remember where the return value is */
9205                 MISC(def, 0) = tmp;
9206         }
9207
9208         /* Remember which function I am compiling.
9209          * Also assume the last defined function is the main function.
9210          */
9211         state->main_function = def;
9212
9213         /* Now get the actual function definition */
9214         compound_statement(state, end);
9215
9216         /* Finish anything unfinished with branches */
9217         resolve_branches(state);
9218
9219         /* Remove the parameter scope */
9220         end_scope(state);
9221
9222 #if 0
9223         fprintf(stdout, "\n");
9224         loc(stdout, state, 0);
9225         fprintf(stdout, "\n__________ function_definition _________\n");
9226         print_triple(state, def);
9227         fprintf(stdout, "__________ function_definition _________ done\n\n");
9228 #endif
9229
9230         return def;
9231 }
9232
9233 static struct triple *do_decl(struct compile_state *state, 
9234         struct type *type, struct hash_entry *ident)
9235 {
9236         struct triple *def;
9237         def = 0;
9238         /* Clean up the storage types used */
9239         switch (type->type & STOR_MASK) {
9240         case STOR_AUTO:
9241         case STOR_STATIC:
9242                 /* These are the good types I am aiming for */
9243                 break;
9244         case STOR_REGISTER:
9245                 type->type &= ~STOR_MASK;
9246                 type->type |= STOR_AUTO;
9247                 break;
9248         case STOR_EXTERN:
9249                 type->type &= ~STOR_MASK;
9250                 type->type |= STOR_STATIC;
9251                 break;
9252         case STOR_TYPEDEF:
9253                 if (!ident) {
9254                         error(state, 0, "typedef without name");
9255                 }
9256                 symbol(state, ident, &ident->sym_ident, 0, type);
9257                 ident->tok = TOK_TYPE_NAME;
9258                 return 0;
9259                 break;
9260         default:
9261                 internal_error(state, 0, "Undefined storage class");
9262         }
9263         if ((type->type & TYPE_MASK) == TYPE_FUNCTION) {
9264                 error(state, 0, "Function prototypes not supported");
9265         }
9266         if (ident && 
9267                 ((type->type & STOR_MASK) == STOR_STATIC) &&
9268                 ((type->type & QUAL_CONST) == 0)) {
9269                 error(state, 0, "non const static variables not supported");
9270         }
9271         if (ident) {
9272                 def = variable(state, type);
9273                 symbol(state, ident, &ident->sym_ident, def, type);
9274         }
9275         return def;
9276 }
9277
9278 static void decl(struct compile_state *state, struct triple *first)
9279 {
9280         struct type *base_type, *type;
9281         struct hash_entry *ident;
9282         struct triple *def;
9283         int global;
9284         global = (state->scope_depth <= GLOBAL_SCOPE_DEPTH);
9285         base_type = decl_specifiers(state);
9286         ident = 0;
9287         type = declarator(state, base_type, &ident, 0);
9288         if (global && ident && (peek(state) == TOK_LBRACE)) {
9289                 /* function */
9290                 state->function = ident->name;
9291                 def = function_definition(state, type);
9292                 symbol(state, ident, &ident->sym_ident, def, type);
9293                 state->function = 0;
9294         }
9295         else {
9296                 int done;
9297                 flatten(state, first, do_decl(state, type, ident));
9298                 /* type or variable definition */
9299                 do {
9300                         done = 1;
9301                         if (peek(state) == TOK_EQ) {
9302                                 if (!ident) {
9303                                         error(state, 0, "cannot assign to a type");
9304                                 }
9305                                 eat(state, TOK_EQ);
9306                                 flatten(state, first,
9307                                         init_expr(state, 
9308                                                 ident->sym_ident->def, 
9309                                                 initializer(state, type)));
9310                         }
9311                         arrays_complete(state, type);
9312                         if (peek(state) == TOK_COMMA) {
9313                                 eat(state, TOK_COMMA);
9314                                 ident = 0;
9315                                 type = declarator(state, base_type, &ident, 0);
9316                                 flatten(state, first, do_decl(state, type, ident));
9317                                 done = 0;
9318                         }
9319                 } while(!done);
9320                 eat(state, TOK_SEMI);
9321         }
9322 }
9323
9324 static void decls(struct compile_state *state)
9325 {
9326         struct triple *list;
9327         int tok;
9328         list = label(state);
9329         while(1) {
9330                 tok = peek(state);
9331                 if (tok == TOK_EOF) {
9332                         return;
9333                 }
9334                 if (tok == TOK_SPACE) {
9335                         eat(state, TOK_SPACE);
9336                 }
9337                 decl(state, list);
9338                 if (list->next != list) {
9339                         error(state, 0, "global variables not supported");
9340                 }
9341         }
9342 }
9343
9344 /*
9345  * Data structurs for optimation.
9346  */
9347
9348 static void do_use_block(
9349         struct block *used, struct block_set **head, struct block *user, 
9350         int front)
9351 {
9352         struct block_set **ptr, *new;
9353         if (!used)
9354                 return;
9355         if (!user)
9356                 return;
9357         ptr = head;
9358         while(*ptr) {
9359                 if ((*ptr)->member == user) {
9360                         return;
9361                 }
9362                 ptr = &(*ptr)->next;
9363         }
9364         new = xcmalloc(sizeof(*new), "block_set");
9365         new->member = user;
9366         if (front) {
9367                 new->next = *head;
9368                 *head = new;
9369         }
9370         else {
9371                 new->next = 0;
9372                 *ptr = new;
9373         }
9374 }
9375 static void do_unuse_block(
9376         struct block *used, struct block_set **head, struct block *unuser)
9377 {
9378         struct block_set *use, **ptr;
9379         ptr = head;
9380         while(*ptr) {
9381                 use = *ptr;
9382                 if (use->member == unuser) {
9383                         *ptr = use->next;
9384                         memset(use, -1, sizeof(*use));
9385                         xfree(use);
9386                 }
9387                 else {
9388                         ptr = &use->next;
9389                 }
9390         }
9391 }
9392
9393 static void use_block(struct block *used, struct block *user)
9394 {
9395         /* Append new to the head of the list, print_block
9396          * depends on this.
9397          */
9398         do_use_block(used, &used->use, user, 1); 
9399         used->users++;
9400 }
9401 static void unuse_block(struct block *used, struct block *unuser)
9402 {
9403         do_unuse_block(used, &used->use, unuser); 
9404         used->users--;
9405 }
9406
9407 static void idom_block(struct block *idom, struct block *user)
9408 {
9409         do_use_block(idom, &idom->idominates, user, 0);
9410 }
9411
9412 static void unidom_block(struct block *idom, struct block *unuser)
9413 {
9414         do_unuse_block(idom, &idom->idominates, unuser);
9415 }
9416
9417 static void domf_block(struct block *block, struct block *domf)
9418 {
9419         do_use_block(block, &block->domfrontier, domf, 0);
9420 }
9421
9422 static void undomf_block(struct block *block, struct block *undomf)
9423 {
9424         do_unuse_block(block, &block->domfrontier, undomf);
9425 }
9426
9427 static void ipdom_block(struct block *ipdom, struct block *user)
9428 {
9429         do_use_block(ipdom, &ipdom->ipdominates, user, 0);
9430 }
9431
9432 static void unipdom_block(struct block *ipdom, struct block *unuser)
9433 {
9434         do_unuse_block(ipdom, &ipdom->ipdominates, unuser);
9435 }
9436
9437 static void ipdomf_block(struct block *block, struct block *ipdomf)
9438 {
9439         do_use_block(block, &block->ipdomfrontier, ipdomf, 0);
9440 }
9441
9442 static void unipdomf_block(struct block *block, struct block *unipdomf)
9443 {
9444         do_unuse_block(block, &block->ipdomfrontier, unipdomf);
9445 }
9446
9447
9448
9449 static int do_walk_triple(struct compile_state *state,
9450         struct triple *ptr, int depth,
9451         int (*cb)(struct compile_state *state, struct triple *ptr, int depth)) 
9452 {
9453         int result;
9454         result = cb(state, ptr, depth);
9455         if ((result == 0) && (ptr->op == OP_LIST)) {
9456                 struct triple *list;
9457                 list = ptr;
9458                 ptr = RHS(list, 0);
9459                 do {
9460                         result = do_walk_triple(state, ptr, depth + 1, cb);
9461                         if (ptr->next->prev != ptr) {
9462                                 internal_error(state, ptr->next, "bad prev");
9463                         }
9464                         ptr = ptr->next;
9465                         
9466                 } while((result == 0) && (ptr != RHS(list, 0)));
9467         }
9468         return result;
9469 }
9470
9471 static int walk_triple(
9472         struct compile_state *state, 
9473         struct triple *ptr, 
9474         int (*cb)(struct compile_state *state, struct triple *ptr, int depth))
9475 {
9476         return do_walk_triple(state, ptr, 0, cb);
9477 }
9478
9479 static void do_print_prefix(int depth)
9480 {
9481         int i;
9482         for(i = 0; i < depth; i++) {
9483                 printf("  ");
9484         }
9485 }
9486
9487 #define PRINT_LIST 1
9488 static int do_print_triple(struct compile_state *state, struct triple *ins, int depth)
9489 {
9490         int op;
9491         op = ins->op;
9492         if (op == OP_LIST) {
9493 #if !PRINT_LIST
9494                 return 0;
9495 #endif
9496         }
9497         if ((op == OP_LABEL) && (ins->use)) {
9498                 printf("\n%p:\n", ins);
9499         }
9500         do_print_prefix(depth);
9501         display_triple(stdout, ins);
9502
9503         if ((ins->op == OP_BRANCH) && ins->use) {
9504                 internal_error(state, ins, "branch used?");
9505         }
9506         if (triple_is_branch(state, ins)) {
9507                 printf("\n");
9508         }
9509         return 0;
9510 }
9511
9512 static void print_triple(struct compile_state *state, struct triple *ins)
9513 {
9514         walk_triple(state, ins, do_print_triple);
9515 }
9516
9517 static void print_triples(struct compile_state *state)
9518 {
9519         print_triple(state, state->main_function);
9520 }
9521
9522 struct cf_block {
9523         struct block *block;
9524 };
9525 static void find_cf_blocks(struct cf_block *cf, struct block *block)
9526 {
9527         if (!block || (cf[block->vertex].block == block)) {
9528                 return;
9529         }
9530         cf[block->vertex].block = block;
9531         find_cf_blocks(cf, block->left);
9532         find_cf_blocks(cf, block->right);
9533 }
9534
9535 static void print_control_flow(struct compile_state *state)
9536 {
9537         struct cf_block *cf;
9538         int i;
9539         printf("\ncontrol flow\n");
9540         cf = xcmalloc(sizeof(*cf) * (state->last_vertex + 1), "cf_block");
9541         find_cf_blocks(cf, state->first_block);
9542
9543         for(i = 1; i <= state->last_vertex; i++) {
9544                 struct block *block;
9545                 block = cf[i].block;
9546                 if (!block)
9547                         continue;
9548                 printf("(%p) %d:", block, block->vertex);
9549                 if (block->left) {
9550                         printf(" %d", block->left->vertex);
9551                 }
9552                 if (block->right && (block->right != block->left)) {
9553                         printf(" %d", block->right->vertex);
9554                 }
9555                 printf("\n");
9556         }
9557
9558         xfree(cf);
9559 }
9560
9561
9562 static struct block *basic_block(struct compile_state *state,
9563         struct triple *first)
9564 {
9565         struct block *block;
9566         struct triple *ptr, *final;
9567         int op;
9568         if (first->op != OP_LABEL) {
9569                 internal_error(state, 0, "block does not start with a label");
9570         }
9571         /* See if this basic block has already been setup */
9572         if (first->u.block != 0) {
9573                 return first->u.block;
9574         }
9575         /* Lookup the final instruction.
9576          * It is important that the final instruction has it's own
9577          * basic block.
9578          */
9579         final = RHS(state->main_function, 0)->prev;
9580         /* Allocate another basic block structure */
9581         state->last_vertex += 1;
9582         block = xcmalloc(sizeof(*block), "block");
9583         block->first = block->last = first;
9584         block->vertex = state->last_vertex;
9585         ptr = first;
9586         do {
9587                 if ((ptr != first) && (ptr->op == OP_LABEL) && 
9588                         ((ptr->use) || ptr == final)) {
9589                         break;
9590                 }
9591                 block->last = ptr;
9592                 /* If ptr->u is not used remember where the baic block is */
9593                 if (triple_stores_block(state, ptr)) {
9594                         ptr->u.block = block;
9595                 }
9596                 if (ptr->op == OP_BRANCH) {
9597                         break;
9598                 }
9599                 ptr = ptr->next;
9600         } while (ptr != RHS(state->main_function, 0));
9601         if (ptr == RHS(state->main_function, 0))
9602                 return block;
9603         op = ptr->op;
9604         if (op == OP_LABEL) {
9605                 block->left = basic_block(state, ptr);
9606                 block->right = 0;
9607                 use_block(block->left, block);
9608         }
9609         else if (op == OP_BRANCH) {
9610                 block->left = 0;
9611                 /* Trace the branch target */
9612                 block->right = basic_block(state, TARG(ptr, 0));
9613                 use_block(block->right, block);
9614                 /* If there is a test trace the branch as well */
9615                 if (TRIPLE_RHS(ptr->sizes)) {
9616                         block->left = basic_block(state, ptr->next);
9617                         use_block(block->left, block);
9618                 }
9619         }
9620         else {
9621                 internal_error(state, 0, "Bad basic block split");
9622         }
9623         return block;
9624 }
9625
9626
9627 static void walk_blocks(struct compile_state *state,
9628         void (*cb)(struct compile_state *state, struct block *block, void *arg),
9629         void *arg)
9630 {
9631         struct triple *ptr, *first;
9632         struct block *last_block;
9633         last_block = 0;
9634         first = RHS(state->main_function, 0);
9635         ptr = first;
9636         do {
9637                 struct block *block;
9638                 if (triple_stores_block(state, ptr)) {
9639                         block = ptr->u.block;
9640                         if (block && (block != last_block)) {
9641                                 cb(state, block, arg);
9642                         }
9643                         last_block = block;
9644                 }
9645                 if (block && (block->last == ptr)) {
9646                         block = 0;
9647                 }
9648                 ptr = ptr->next;
9649         } while(ptr != first);
9650 }
9651
9652 static void print_block(
9653         struct compile_state *state, struct block *block, void *arg)
9654 {
9655         struct block_set *user;
9656         struct triple *ptr;
9657         FILE *fp = arg;
9658
9659         fprintf(fp, "\nblock: %p (%d)  %p<-%p %p<-%p\n", 
9660                 block, 
9661                 block->vertex,
9662                 block->left, 
9663                 block->left && block->left->use?block->left->use->member : 0,
9664                 block->right, 
9665                 block->right && block->right->use?block->right->use->member : 0);
9666         if (block->first->op == OP_LABEL) {
9667                 fprintf(fp, "%p:\n", block->first);
9668         }
9669         for(ptr = block->first; ; ptr = ptr->next) {
9670                 display_triple(fp, ptr);
9671                 if (ptr == block->last)
9672                         break;
9673         }
9674         fprintf(fp, "users %d: ", block->users);
9675         for(user = block->use; user; user = user->next) {
9676                 fprintf(fp, "%p (%d) ", 
9677                         user->member,
9678                         user->member->vertex);
9679         }
9680         fprintf(fp,"\n\n");
9681 }
9682
9683
9684 static void print_blocks(struct compile_state *state, FILE *fp)
9685 {
9686         fprintf(fp, "--------------- blocks ---------------\n");
9687         walk_blocks(state, print_block, fp);
9688 }
9689
9690 static void prune_nonblock_triples(struct compile_state *state)
9691 {
9692         struct block *block;
9693         struct triple *first, *ins, *next;
9694         /* Delete the triples not in a basic block */
9695         first = RHS(state->main_function, 0);
9696         block = 0;
9697         ins = first;
9698         do {
9699                 next = ins->next;
9700                 if (ins->op == OP_LABEL) {
9701                         block = ins->u.block;
9702                 }
9703                 if (!block) {
9704                         release_triple(state, ins);
9705                 }
9706                 if (block && block->last == ins) {
9707                         block = 0;
9708                 }
9709                 ins = next;
9710         } while(ins != first);
9711 }
9712
9713 static void setup_basic_blocks(struct compile_state *state)
9714 {
9715         if (!triple_stores_block(state, RHS(state->main_function, 0)) ||
9716                 !triple_stores_block(state, RHS(state->main_function,0)->prev)) {
9717                 internal_error(state, 0, "ins will not store block?");
9718         }
9719         /* Find the basic blocks */
9720         state->last_vertex = 0;
9721         state->first_block = basic_block(state, RHS(state->main_function,0));
9722         /* Delete the triples not in a basic block */
9723         prune_nonblock_triples(state);
9724         /* Find the last basic block */
9725         state->last_block = RHS(state->main_function, 0)->prev->u.block;
9726         if (!state->last_block) {
9727                 internal_error(state, 0, "end not used?");
9728         }
9729         /* If we are debugging print what I have just done */
9730         if (state->debug & DEBUG_BASIC_BLOCKS) {
9731                 print_blocks(state, stdout);
9732                 print_control_flow(state);
9733         }
9734 }
9735
9736 static void free_basic_block(struct compile_state *state, struct block *block)
9737 {
9738         struct block_set *entry, *next;
9739         struct block *child;
9740         if (!block) {
9741                 return;
9742         }
9743         if (block->vertex == -1) {
9744                 return;
9745         }
9746         block->vertex = -1;
9747         if (block->left) {
9748                 unuse_block(block->left, block);
9749         }
9750         if (block->right) {
9751                 unuse_block(block->right, block);
9752         }
9753         if (block->idom) {
9754                 unidom_block(block->idom, block);
9755         }
9756         block->idom = 0;
9757         if (block->ipdom) {
9758                 unipdom_block(block->ipdom, block);
9759         }
9760         block->ipdom = 0;
9761         for(entry = block->use; entry; entry = next) {
9762                 next = entry->next;
9763                 child = entry->member;
9764                 unuse_block(block, child);
9765                 if (child->left == block) {
9766                         child->left = 0;
9767                 }
9768                 if (child->right == block) {
9769                         child->right = 0;
9770                 }
9771         }
9772         for(entry = block->idominates; entry; entry = next) {
9773                 next = entry->next;
9774                 child = entry->member;
9775                 unidom_block(block, child);
9776                 child->idom = 0;
9777         }
9778         for(entry = block->domfrontier; entry; entry = next) {
9779                 next = entry->next;
9780                 child = entry->member;
9781                 undomf_block(block, child);
9782         }
9783         for(entry = block->ipdominates; entry; entry = next) {
9784                 next = entry->next;
9785                 child = entry->member;
9786                 unipdom_block(block, child);
9787                 child->ipdom = 0;
9788         }
9789         for(entry = block->ipdomfrontier; entry; entry = next) {
9790                 next = entry->next;
9791                 child = entry->member;
9792                 unipdomf_block(block, child);
9793         }
9794         if (block->users != 0) {
9795                 internal_error(state, 0, "block still has users");
9796         }
9797         free_basic_block(state, block->left);
9798         block->left = 0;
9799         free_basic_block(state, block->right);
9800         block->right = 0;
9801         memset(block, -1, sizeof(*block));
9802         xfree(block);
9803 }
9804
9805 static void free_basic_blocks(struct compile_state *state)
9806 {
9807         struct triple *first, *ins;
9808         free_basic_block(state, state->first_block);
9809         state->last_vertex = 0;
9810         state->first_block = state->last_block = 0;
9811         first = RHS(state->main_function, 0);
9812         ins = first;
9813         do {
9814                 if (triple_stores_block(state, ins)) {
9815                         ins->u.block = 0;
9816                 }
9817                 ins = ins->next;
9818         } while(ins != first);
9819         
9820 }
9821
9822 struct sdom_block {
9823         struct block *block;
9824         struct sdom_block *sdominates;
9825         struct sdom_block *sdom_next;
9826         struct sdom_block *sdom;
9827         struct sdom_block *label;
9828         struct sdom_block *parent;
9829         struct sdom_block *ancestor;
9830         int vertex;
9831 };
9832
9833
9834 static void unsdom_block(struct sdom_block *block)
9835 {
9836         struct sdom_block **ptr;
9837         if (!block->sdom_next) {
9838                 return;
9839         }
9840         ptr = &block->sdom->sdominates;
9841         while(*ptr) {
9842                 if ((*ptr) == block) {
9843                         *ptr = block->sdom_next;
9844                         return;
9845                 }
9846                 ptr = &(*ptr)->sdom_next;
9847         }
9848 }
9849
9850 static void sdom_block(struct sdom_block *sdom, struct sdom_block *block)
9851 {
9852         unsdom_block(block);
9853         block->sdom = sdom;
9854         block->sdom_next = sdom->sdominates;
9855         sdom->sdominates = block;
9856 }
9857
9858
9859
9860 static int initialize_sdblock(struct sdom_block *sd,
9861         struct block *parent, struct block *block, int vertex)
9862 {
9863         if (!block || (sd[block->vertex].block == block)) {
9864                 return vertex;
9865         }
9866         vertex += 1;
9867         /* Renumber the blocks in a convinient fashion */
9868         block->vertex = vertex;
9869         sd[vertex].block    = block;
9870         sd[vertex].sdom     = &sd[vertex];
9871         sd[vertex].label    = &sd[vertex];
9872         sd[vertex].parent   = parent? &sd[parent->vertex] : 0;
9873         sd[vertex].ancestor = 0;
9874         sd[vertex].vertex   = vertex;
9875         vertex = initialize_sdblock(sd, block, block->left, vertex);
9876         vertex = initialize_sdblock(sd, block, block->right, vertex);
9877         return vertex;
9878 }
9879
9880 static int initialize_sdpblock(
9881         struct compile_state *state, struct sdom_block *sd,
9882         struct block *parent, struct block *block, int vertex)
9883 {
9884         struct block_set *user;
9885         if (!block || (sd[block->vertex].block == block)) {
9886                 return vertex;
9887         }
9888         vertex += 1;
9889         /* Renumber the blocks in a convinient fashion */
9890         block->vertex = vertex;
9891         sd[vertex].block    = block;
9892         sd[vertex].sdom     = &sd[vertex];
9893         sd[vertex].label    = &sd[vertex];
9894         sd[vertex].parent   = parent? &sd[parent->vertex] : 0;
9895         sd[vertex].ancestor = 0;
9896         sd[vertex].vertex   = vertex;
9897         for(user = block->use; user; user = user->next) {
9898                 vertex = initialize_sdpblock(state, sd, block, user->member, vertex);
9899         }
9900         return vertex;
9901 }
9902
9903 static int setup_sdpblocks(struct compile_state *state, struct sdom_block *sd)
9904 {
9905         struct block *block;
9906         int vertex;
9907         /* Setup as many sdpblocks as possible without using fake edges */
9908         vertex = initialize_sdpblock(state, sd, 0, state->last_block, 0);
9909
9910         /* Walk through the graph and find unconnected blocks.  If 
9911          * we can, add a fake edge from the unconnected blocks to the
9912          * end of the graph.
9913          */
9914         block = state->first_block->last->next->u.block;
9915         for(; block && block != state->first_block; block =  block->last->next->u.block) {
9916                 if (sd[block->vertex].block == block) {
9917                         continue;
9918                 }
9919                 if (block->left != 0) {
9920                         continue;
9921                 }
9922
9923 #if DEBUG_SDP_BLOCKS
9924                 fprintf(stderr, "Adding %d\n", vertex +1);
9925 #endif
9926
9927                 block->left = state->last_block;
9928                 use_block(block->left, block);
9929                 vertex = initialize_sdpblock(state, sd, state->last_block, block, vertex);
9930         }
9931         return vertex;
9932 }
9933
9934 static void compress_ancestors(struct sdom_block *v)
9935 {
9936         /* This procedure assumes ancestor(v) != 0 */
9937         /* if (ancestor(ancestor(v)) != 0) {
9938          *      compress(ancestor(ancestor(v)));
9939          *      if (semi(label(ancestor(v))) < semi(label(v))) {
9940          *              label(v) = label(ancestor(v));
9941          *      }
9942          *      ancestor(v) = ancestor(ancestor(v));
9943          * }
9944          */
9945         if (!v->ancestor) {
9946                 return;
9947         }
9948         if (v->ancestor->ancestor) {
9949                 compress_ancestors(v->ancestor->ancestor);
9950                 if (v->ancestor->label->sdom->vertex < v->label->sdom->vertex) {
9951                         v->label = v->ancestor->label;
9952                 }
9953                 v->ancestor = v->ancestor->ancestor;
9954         }
9955 }
9956
9957 static void compute_sdom(struct compile_state *state, struct sdom_block *sd)
9958 {
9959         int i;
9960         /* // step 2 
9961          *  for each v <= pred(w) {
9962          *      u = EVAL(v);
9963          *      if (semi[u] < semi[w] { 
9964          *              semi[w] = semi[u]; 
9965          *      } 
9966          * }
9967          * add w to bucket(vertex(semi[w]));
9968          * LINK(parent(w), w);
9969          *
9970          * // step 3
9971          * for each v <= bucket(parent(w)) {
9972          *      delete v from bucket(parent(w));
9973          *      u = EVAL(v);
9974          *      dom(v) = (semi[u] < semi[v]) ? u : parent(w);
9975          * }
9976          */
9977         for(i = state->last_vertex; i >= 2; i--) {
9978                 struct sdom_block *v, *parent, *next;
9979                 struct block_set *user;
9980                 struct block *block;
9981                 block = sd[i].block;
9982                 parent = sd[i].parent;
9983                 /* Step 2 */
9984                 for(user = block->use; user; user = user->next) {
9985                         struct sdom_block *v, *u;
9986                         v = &sd[user->member->vertex];
9987                         u = !(v->ancestor)? v : (compress_ancestors(v), v->label);
9988                         if (u->sdom->vertex < sd[i].sdom->vertex) {
9989                                 sd[i].sdom = u->sdom;
9990                         }
9991                 }
9992                 sdom_block(sd[i].sdom, &sd[i]);
9993                 sd[i].ancestor = parent;
9994                 /* Step 3 */
9995                 for(v = parent->sdominates; v; v = next) {
9996                         struct sdom_block *u;
9997                         next = v->sdom_next;
9998                         unsdom_block(v);
9999                         u = (!v->ancestor) ? v : (compress_ancestors(v), v->label);
10000                         v->block->idom = (u->sdom->vertex < v->sdom->vertex)? 
10001                                 u->block : parent->block;
10002                 }
10003         }
10004 }
10005
10006 static void compute_spdom(struct compile_state *state, struct sdom_block *sd)
10007 {
10008         int i;
10009         /* // step 2 
10010          *  for each v <= pred(w) {
10011          *      u = EVAL(v);
10012          *      if (semi[u] < semi[w] { 
10013          *              semi[w] = semi[u]; 
10014          *      } 
10015          * }
10016          * add w to bucket(vertex(semi[w]));
10017          * LINK(parent(w), w);
10018          *
10019          * // step 3
10020          * for each v <= bucket(parent(w)) {
10021          *      delete v from bucket(parent(w));
10022          *      u = EVAL(v);
10023          *      dom(v) = (semi[u] < semi[v]) ? u : parent(w);
10024          * }
10025          */
10026         for(i = state->last_vertex; i >= 2; i--) {
10027                 struct sdom_block *u, *v, *parent, *next;
10028                 struct block *block;
10029                 block = sd[i].block;
10030                 parent = sd[i].parent;
10031                 /* Step 2 */
10032                 if (block->left) {
10033                         v = &sd[block->left->vertex];
10034                         u = !(v->ancestor)? v : (compress_ancestors(v), v->label);
10035                         if (u->sdom->vertex < sd[i].sdom->vertex) {
10036                                 sd[i].sdom = u->sdom;
10037                         }
10038                 }
10039                 if (block->right && (block->right != block->left)) {
10040                         v = &sd[block->right->vertex];
10041                         u = !(v->ancestor)? v : (compress_ancestors(v), v->label);
10042                         if (u->sdom->vertex < sd[i].sdom->vertex) {
10043                                 sd[i].sdom = u->sdom;
10044                         }
10045                 }
10046                 sdom_block(sd[i].sdom, &sd[i]);
10047                 sd[i].ancestor = parent;
10048                 /* Step 3 */
10049                 for(v = parent->sdominates; v; v = next) {
10050                         struct sdom_block *u;
10051                         next = v->sdom_next;
10052                         unsdom_block(v);
10053                         u = (!v->ancestor) ? v : (compress_ancestors(v), v->label);
10054                         v->block->ipdom = (u->sdom->vertex < v->sdom->vertex)? 
10055                                 u->block : parent->block;
10056                 }
10057         }
10058 }
10059
10060 static void compute_idom(struct compile_state *state, struct sdom_block *sd)
10061 {
10062         int i;
10063         for(i = 2; i <= state->last_vertex; i++) {
10064                 struct block *block;
10065                 block = sd[i].block;
10066                 if (block->idom->vertex != sd[i].sdom->vertex) {
10067                         block->idom = block->idom->idom;
10068                 }
10069                 idom_block(block->idom, block);
10070         }
10071         sd[1].block->idom = 0;
10072 }
10073
10074 static void compute_ipdom(struct compile_state *state, struct sdom_block *sd)
10075 {
10076         int i;
10077         for(i = 2; i <= state->last_vertex; i++) {
10078                 struct block *block;
10079                 block = sd[i].block;
10080                 if (block->ipdom->vertex != sd[i].sdom->vertex) {
10081                         block->ipdom = block->ipdom->ipdom;
10082                 }
10083                 ipdom_block(block->ipdom, block);
10084         }
10085         sd[1].block->ipdom = 0;
10086 }
10087
10088         /* Theorem 1:
10089          *   Every vertex of a flowgraph G = (V, E, r) except r has
10090          *   a unique immediate dominator.  
10091          *   The edges {(idom(w), w) |w <= V - {r}} form a directed tree
10092          *   rooted at r, called the dominator tree of G, such that 
10093          *   v dominates w if and only if v is a proper ancestor of w in
10094          *   the dominator tree.
10095          */
10096         /* Lemma 1:  
10097          *   If v and w are vertices of G such that v <= w,
10098          *   than any path from v to w must contain a common ancestor
10099          *   of v and w in T.
10100          */
10101         /* Lemma 2:  For any vertex w != r, idom(w) -> w */
10102         /* Lemma 3:  For any vertex w != r, sdom(w) -> w */
10103         /* Lemma 4:  For any vertex w != r, idom(w) -> sdom(w) */
10104         /* Theorem 2:
10105          *   Let w != r.  Suppose every u for which sdom(w) -> u -> w satisfies
10106          *   sdom(u) >= sdom(w).  Then idom(w) = sdom(w).
10107          */
10108         /* Theorem 3:
10109          *   Let w != r and let u be a vertex for which sdom(u) is 
10110          *   minimum amoung vertices u satisfying sdom(w) -> u -> w.
10111          *   Then sdom(u) <= sdom(w) and idom(u) = idom(w).
10112          */
10113         /* Lemma 5:  Let vertices v,w satisfy v -> w.
10114          *           Then v -> idom(w) or idom(w) -> idom(v)
10115          */
10116
10117 static void find_immediate_dominators(struct compile_state *state)
10118 {
10119         struct sdom_block *sd;
10120         /* w->sdom = min{v| there is a path v = v0,v1,...,vk = w such that:
10121          *           vi > w for (1 <= i <= k - 1}
10122          */
10123         /* Theorem 4:
10124          *   For any vertex w != r.
10125          *   sdom(w) = min(
10126          *                 {v|(v,w) <= E  and v < w } U 
10127          *                 {sdom(u) | u > w and there is an edge (v, w) such that u -> v})
10128          */
10129         /* Corollary 1:
10130          *   Let w != r and let u be a vertex for which sdom(u) is 
10131          *   minimum amoung vertices u satisfying sdom(w) -> u -> w.
10132          *   Then:
10133          *                   { sdom(w) if sdom(w) = sdom(u),
10134          *        idom(w) = {
10135          *                   { idom(u) otherwise
10136          */
10137         /* The algorithm consists of the following 4 steps.
10138          * Step 1.  Carry out a depth-first search of the problem graph.  
10139          *    Number the vertices from 1 to N as they are reached during
10140          *    the search.  Initialize the variables used in succeeding steps.
10141          * Step 2.  Compute the semidominators of all vertices by applying
10142          *    theorem 4.   Carry out the computation vertex by vertex in
10143          *    decreasing order by number.
10144          * Step 3.  Implicitly define the immediate dominator of each vertex
10145          *    by applying Corollary 1.
10146          * Step 4.  Explicitly define the immediate dominator of each vertex,
10147          *    carrying out the computation vertex by vertex in increasing order
10148          *    by number.
10149          */
10150         /* Step 1 initialize the basic block information */
10151         sd = xcmalloc(sizeof(*sd) * (state->last_vertex + 1), "sdom_state");
10152         initialize_sdblock(sd, 0, state->first_block, 0);
10153 #if 0
10154         sd[1].size  = 0;
10155         sd[1].label = 0;
10156         sd[1].sdom  = 0;
10157 #endif
10158         /* Step 2 compute the semidominators */
10159         /* Step 3 implicitly define the immediate dominator of each vertex */
10160         compute_sdom(state, sd);
10161         /* Step 4 explicitly define the immediate dominator of each vertex */
10162         compute_idom(state, sd);
10163         xfree(sd);
10164 }
10165
10166 static void find_post_dominators(struct compile_state *state)
10167 {
10168         struct sdom_block *sd;
10169         int vertex;
10170         /* Step 1 initialize the basic block information */
10171         sd = xcmalloc(sizeof(*sd) * (state->last_vertex + 1), "sdom_state");
10172
10173         vertex = setup_sdpblocks(state, sd);
10174         if (vertex != state->last_vertex) {
10175                 internal_error(state, 0, "missing %d blocks\n",
10176                         state->last_vertex - vertex);
10177         }
10178
10179         /* Step 2 compute the semidominators */
10180         /* Step 3 implicitly define the immediate dominator of each vertex */
10181         compute_spdom(state, sd);
10182         /* Step 4 explicitly define the immediate dominator of each vertex */
10183         compute_ipdom(state, sd);
10184         xfree(sd);
10185 }
10186
10187
10188
10189 static void find_block_domf(struct compile_state *state, struct block *block)
10190 {
10191         struct block *child;
10192         struct block_set *user;
10193         if (block->domfrontier != 0) {
10194                 internal_error(state, block->first, "domfrontier present?");
10195         }
10196         for(user = block->idominates; user; user = user->next) {
10197                 child = user->member;
10198                 if (child->idom != block) {
10199                         internal_error(state, block->first, "bad idom");
10200                 }
10201                 find_block_domf(state, child);
10202         }
10203         if (block->left && block->left->idom != block) {
10204                 domf_block(block, block->left);
10205         }
10206         if (block->right && block->right->idom != block) {
10207                 domf_block(block, block->right);
10208         }
10209         for(user = block->idominates; user; user = user->next) {
10210                 struct block_set *frontier;
10211                 child = user->member;
10212                 for(frontier = child->domfrontier; frontier; frontier = frontier->next) {
10213                         if (frontier->member->idom != block) {
10214                                 domf_block(block, frontier->member);
10215                         }
10216                 }
10217         }
10218 }
10219
10220 static void find_block_ipdomf(struct compile_state *state, struct block *block)
10221 {
10222         struct block *child;
10223         struct block_set *user;
10224         if (block->ipdomfrontier != 0) {
10225                 internal_error(state, block->first, "ipdomfrontier present?");
10226         }
10227         for(user = block->ipdominates; user; user = user->next) {
10228                 child = user->member;
10229                 if (child->ipdom != block) {
10230                         internal_error(state, block->first, "bad ipdom");
10231                 }
10232                 find_block_ipdomf(state, child);
10233         }
10234         if (block->left && block->left->ipdom != block) {
10235                 ipdomf_block(block, block->left);
10236         }
10237         if (block->right && block->right->ipdom != block) {
10238                 ipdomf_block(block, block->right);
10239         }
10240         for(user = block->idominates; user; user = user->next) {
10241                 struct block_set *frontier;
10242                 child = user->member;
10243                 for(frontier = child->ipdomfrontier; frontier; frontier = frontier->next) {
10244                         if (frontier->member->ipdom != block) {
10245                                 ipdomf_block(block, frontier->member);
10246                         }
10247                 }
10248         }
10249 }
10250
10251 static void print_dominated(
10252         struct compile_state *state, struct block *block, void *arg)
10253 {
10254         struct block_set *user;
10255         FILE *fp = arg;
10256
10257         fprintf(fp, "%d:", block->vertex);
10258         for(user = block->idominates; user; user = user->next) {
10259                 fprintf(fp, " %d", user->member->vertex);
10260                 if (user->member->idom != block) {
10261                         internal_error(state, user->member->first, "bad idom");
10262                 }
10263         }
10264         fprintf(fp,"\n");
10265 }
10266
10267 static void print_dominators(struct compile_state *state, FILE *fp)
10268 {
10269         fprintf(fp, "\ndominates\n");
10270         walk_blocks(state, print_dominated, fp);
10271 }
10272
10273
10274 static int print_frontiers(
10275         struct compile_state *state, struct block *block, int vertex)
10276 {
10277         struct block_set *user;
10278
10279         if (!block || (block->vertex != vertex + 1)) {
10280                 return vertex;
10281         }
10282         vertex += 1;
10283
10284         printf("%d:", block->vertex);
10285         for(user = block->domfrontier; user; user = user->next) {
10286                 printf(" %d", user->member->vertex);
10287         }
10288         printf("\n");
10289
10290         vertex = print_frontiers(state, block->left, vertex);
10291         vertex = print_frontiers(state, block->right, vertex);
10292         return vertex;
10293 }
10294 static void print_dominance_frontiers(struct compile_state *state)
10295 {
10296         printf("\ndominance frontiers\n");
10297         print_frontiers(state, state->first_block, 0);
10298         
10299 }
10300
10301 static void analyze_idominators(struct compile_state *state)
10302 {
10303         /* Find the immediate dominators */
10304         find_immediate_dominators(state);
10305         /* Find the dominance frontiers */
10306         find_block_domf(state, state->first_block);
10307         /* If debuging print the print what I have just found */
10308         if (state->debug & DEBUG_FDOMINATORS) {
10309                 print_dominators(state, stdout);
10310                 print_dominance_frontiers(state);
10311                 print_control_flow(state);
10312         }
10313 }
10314
10315
10316
10317 static void print_ipdominated(
10318         struct compile_state *state, struct block *block, void *arg)
10319 {
10320         struct block_set *user;
10321         FILE *fp = arg;
10322
10323         fprintf(fp, "%d:", block->vertex);
10324         for(user = block->ipdominates; user; user = user->next) {
10325                 fprintf(fp, " %d", user->member->vertex);
10326                 if (user->member->ipdom != block) {
10327                         internal_error(state, user->member->first, "bad ipdom");
10328                 }
10329         }
10330         fprintf(fp, "\n");
10331 }
10332
10333 static void print_ipdominators(struct compile_state *state, FILE *fp)
10334 {
10335         fprintf(fp, "\nipdominates\n");
10336         walk_blocks(state, print_ipdominated, fp);
10337 }
10338
10339 static int print_pfrontiers(
10340         struct compile_state *state, struct block *block, int vertex)
10341 {
10342         struct block_set *user;
10343
10344         if (!block || (block->vertex != vertex + 1)) {
10345                 return vertex;
10346         }
10347         vertex += 1;
10348
10349         printf("%d:", block->vertex);
10350         for(user = block->ipdomfrontier; user; user = user->next) {
10351                 printf(" %d", user->member->vertex);
10352         }
10353         printf("\n");
10354         for(user = block->use; user; user = user->next) {
10355                 vertex = print_pfrontiers(state, user->member, vertex);
10356         }
10357         return vertex;
10358 }
10359 static void print_ipdominance_frontiers(struct compile_state *state)
10360 {
10361         printf("\nipdominance frontiers\n");
10362         print_pfrontiers(state, state->last_block, 0);
10363         
10364 }
10365
10366 static void analyze_ipdominators(struct compile_state *state)
10367 {
10368         /* Find the post dominators */
10369         find_post_dominators(state);
10370         /* Find the control dependencies (post dominance frontiers) */
10371         find_block_ipdomf(state, state->last_block);
10372         /* If debuging print the print what I have just found */
10373         if (state->debug & DEBUG_RDOMINATORS) {
10374                 print_ipdominators(state, stdout);
10375                 print_ipdominance_frontiers(state);
10376                 print_control_flow(state);
10377         }
10378 }
10379
10380 static int bdominates(struct compile_state *state,
10381         struct block *dom, struct block *sub)
10382 {
10383         while(sub && (sub != dom)) {
10384                 sub = sub->idom;
10385         }
10386         return sub == dom;
10387 }
10388
10389 static int tdominates(struct compile_state *state,
10390         struct triple *dom, struct triple *sub)
10391 {
10392         struct block *bdom, *bsub;
10393         int result;
10394         bdom = block_of_triple(state, dom);
10395         bsub = block_of_triple(state, sub);
10396         if (bdom != bsub) {
10397                 result = bdominates(state, bdom, bsub);
10398         } 
10399         else {
10400                 struct triple *ins;
10401                 ins = sub;
10402                 while((ins != bsub->first) && (ins != dom)) {
10403                         ins = ins->prev;
10404                 }
10405                 result = (ins == dom);
10406         }
10407         return result;
10408 }
10409
10410 static void insert_phi_operations(struct compile_state *state)
10411 {
10412         size_t size;
10413         struct triple *first;
10414         int *has_already, *work;
10415         struct block *work_list, **work_list_tail;
10416         int iter;
10417         struct triple *var, *vnext;
10418
10419         size = sizeof(int) * (state->last_vertex + 1);
10420         has_already = xcmalloc(size, "has_already");
10421         work =        xcmalloc(size, "work");
10422         iter = 0;
10423
10424         first = RHS(state->main_function, 0);
10425         for(var = first->next; var != first ; var = vnext) {
10426                 struct block *block;
10427                 struct triple_set *user, *unext;
10428                 vnext = var->next;
10429                 if ((var->op != OP_ADECL) || !var->use) {
10430                         continue;
10431                 }
10432                 iter += 1;
10433                 work_list = 0;
10434                 work_list_tail = &work_list;
10435                 for(user = var->use; user; user = unext) {
10436                         unext = user->next;
10437                         if (user->member->op == OP_READ) {
10438                                 continue;
10439                         }
10440                         if (user->member->op != OP_WRITE) {
10441                                 internal_error(state, user->member, 
10442                                         "bad variable access");
10443                         }
10444                         block = user->member->u.block;
10445                         if (!block) {
10446                                 warning(state, user->member, "dead code");
10447                                 release_triple(state, user->member);
10448                                 continue;
10449                         }
10450                         if (work[block->vertex] >= iter) {
10451                                 continue;
10452                         }
10453                         work[block->vertex] = iter;
10454                         *work_list_tail = block;
10455                         block->work_next = 0;
10456                         work_list_tail = &block->work_next;
10457                 }
10458                 for(block = work_list; block; block = block->work_next) {
10459                         struct block_set *df;
10460                         for(df = block->domfrontier; df; df = df->next) {
10461                                 struct triple *phi;
10462                                 struct block *front;
10463                                 int in_edges;
10464                                 front = df->member;
10465
10466                                 if (has_already[front->vertex] >= iter) {
10467                                         continue;
10468                                 }
10469                                 /* Count how many edges flow into this block */
10470                                 in_edges = front->users;
10471                                 /* Insert a phi function for this variable */
10472                                 get_occurance(var->occurance);
10473                                 phi = alloc_triple(
10474                                         state, OP_PHI, var->type, -1, in_edges, 
10475                                         var->occurance);
10476                                 phi->u.block = front;
10477                                 MISC(phi, 0) = var;
10478                                 use_triple(var, phi);
10479                                 /* Insert the phi functions immediately after the label */
10480                                 insert_triple(state, front->first->next, phi);
10481                                 if (front->first == front->last) {
10482                                         front->last = front->first->next;
10483                                 }
10484                                 has_already[front->vertex] = iter;
10485
10486                                 /* If necessary plan to visit the basic block */
10487                                 if (work[front->vertex] >= iter) {
10488                                         continue;
10489                                 }
10490                                 work[front->vertex] = iter;
10491                                 *work_list_tail = front;
10492                                 front->work_next = 0;
10493                                 work_list_tail = &front->work_next;
10494                         }
10495                 }
10496         }
10497         xfree(has_already);
10498         xfree(work);
10499 }
10500
10501
10502 static int count_and_number_adecls(struct compile_state *state)
10503 {
10504         struct triple *first, *ins;
10505         int adecls = 0;
10506         first = RHS(state->main_function, 0);
10507         ins = first;
10508         do {
10509                 if (ins->op == OP_ADECL) {
10510                         adecls += 1;
10511                         ins->id = adecls;
10512                 }
10513                 ins = ins->next;
10514         } while(ins != first);
10515         return adecls;
10516 }
10517
10518 static struct triple *peek_triple(struct triple_set **stacks, struct triple *var)
10519 {
10520         struct triple_set *head;
10521         struct triple *top_val;
10522         top_val = 0;
10523         head = stacks[var->id];
10524         if (head) {
10525                 top_val = head->member;
10526         }
10527         return top_val;
10528 }
10529
10530 static void push_triple(struct triple_set **stacks, struct triple *var, struct triple *val)
10531 {
10532         struct triple_set *new;
10533         /* Append new to the head of the list,
10534          * it's the only sensible behavoir for a stack.
10535          */
10536         new = xcmalloc(sizeof(*new), "triple_set");
10537         new->member = val;
10538         new->next   = stacks[var->id];
10539         stacks[var->id] = new;
10540 }
10541
10542 static void pop_triple(struct triple_set **stacks, struct triple *var, struct triple *oldval)
10543 {
10544         struct triple_set *set, **ptr;
10545         ptr = &stacks[var->id];
10546         while(*ptr) {
10547                 set = *ptr;
10548                 if (set->member == oldval) {
10549                         *ptr = set->next;
10550                         xfree(set);
10551                         /* Only free one occurance from the stack */
10552                         return;
10553                 }
10554                 else {
10555                         ptr = &set->next;
10556                 }
10557         }
10558 }
10559
10560 /*
10561  * C(V)
10562  * S(V)
10563  */
10564 static void fixup_block_phi_variables(
10565         struct compile_state *state, struct triple_set **stacks, struct block *parent, struct block *block)
10566 {
10567         struct block_set *set;
10568         struct triple *ptr;
10569         int edge;
10570         if (!parent || !block)
10571                 return;
10572         /* Find the edge I am coming in on */
10573         edge = 0;
10574         for(set = block->use; set; set = set->next, edge++) {
10575                 if (set->member == parent) {
10576                         break;
10577                 }
10578         }
10579         if (!set) {
10580                 internal_error(state, 0, "phi input is not on a control predecessor");
10581         }
10582         for(ptr = block->first; ; ptr = ptr->next) {
10583                 if (ptr->op == OP_PHI) {
10584                         struct triple *var, *val, **slot;
10585                         var = MISC(ptr, 0);
10586                         if (!var) {
10587                                 internal_error(state, ptr, "no var???");
10588                         }
10589                         /* Find the current value of the variable */
10590                         val = peek_triple(stacks, var);
10591                         if (val && ((val->op == OP_WRITE) || (val->op == OP_READ))) {
10592                                 internal_error(state, val, "bad value in phi");
10593                         }
10594                         if (edge >= TRIPLE_RHS(ptr->sizes)) {
10595                                 internal_error(state, ptr, "edges > phi rhs");
10596                         }
10597                         slot = &RHS(ptr, edge);
10598                         if ((*slot != 0) && (*slot != val)) {
10599                                 internal_error(state, ptr, "phi already bound on this edge");
10600                         }
10601                         *slot = val;
10602                         use_triple(val, ptr);
10603                 }
10604                 if (ptr == block->last) {
10605                         break;
10606                 }
10607         }
10608 }
10609
10610
10611 static void rename_block_variables(
10612         struct compile_state *state, struct triple_set **stacks, struct block *block)
10613 {
10614         struct block_set *user;
10615         struct triple *ptr, *next, *last;
10616         int done;
10617         if (!block)
10618                 return;
10619         last = block->first;
10620         done = 0;
10621         for(ptr = block->first; !done; ptr = next) {
10622                 next = ptr->next;
10623                 if (ptr == block->last) {
10624                         done = 1;
10625                 }
10626                 /* RHS(A) */
10627                 if (ptr->op == OP_READ) {
10628                         struct triple *var, *val;
10629                         var = RHS(ptr, 0);
10630                         unuse_triple(var, ptr);
10631                         /* Find the current value of the variable */
10632                         val = peek_triple(stacks, var);
10633                         if (!val) {
10634                                 error(state, ptr, "variable used without being set");
10635                         }
10636                         if ((val->op == OP_WRITE) || (val->op == OP_READ)) {
10637                                 internal_error(state, val, "bad value in read");
10638                         }
10639                         propogate_use(state, ptr, val);
10640                         release_triple(state, ptr);
10641                         continue;
10642                 }
10643                 /* LHS(A) */
10644                 if (ptr->op == OP_WRITE) {
10645                         struct triple *var, *val, *tval;
10646                         var = RHS(ptr, 0);
10647                         tval = val = RHS(ptr, 1);
10648                         if ((val->op == OP_WRITE) || (val->op == OP_READ)) {
10649                                 internal_error(state, ptr, "bad value in write");
10650                         }
10651                         /* Insert a copy if the types differ */
10652                         if (!equiv_types(ptr->type, val->type)) {
10653                                 if (val->op == OP_INTCONST) {
10654                                         tval = pre_triple(state, ptr, OP_INTCONST, ptr->type, 0, 0);
10655                                         tval->u.cval = val->u.cval;
10656                                 }
10657                                 else {
10658                                         tval = pre_triple(state, ptr, OP_COPY, ptr->type, val, 0);
10659                                         use_triple(val, tval);
10660                                 }
10661                                 unuse_triple(val, ptr);
10662                                 RHS(ptr, 1) = tval;
10663                                 use_triple(tval, ptr);
10664                         }
10665                         propogate_use(state, ptr, tval);
10666                         unuse_triple(var, ptr);
10667                         /* Push OP_WRITE ptr->right onto a stack of variable uses */
10668                         push_triple(stacks, var, tval);
10669                 }
10670                 if (ptr->op == OP_PHI) {
10671                         struct triple *var;
10672                         var = MISC(ptr, 0);
10673                         /* Push OP_PHI onto a stack of variable uses */
10674                         push_triple(stacks, var, ptr);
10675                 }
10676                 last = ptr;
10677         }
10678         block->last = last;
10679
10680         /* Fixup PHI functions in the cf successors */
10681         fixup_block_phi_variables(state, stacks, block, block->left);
10682         fixup_block_phi_variables(state, stacks, block, block->right);
10683         /* rename variables in the dominated nodes */
10684         for(user = block->idominates; user; user = user->next) {
10685                 rename_block_variables(state, stacks, user->member);
10686         }
10687         /* pop the renamed variable stack */
10688         last = block->first;
10689         done = 0;
10690         for(ptr = block->first; !done ; ptr = next) {
10691                 next = ptr->next;
10692                 if (ptr == block->last) {
10693                         done = 1;
10694                 }
10695                 if (ptr->op == OP_WRITE) {
10696                         struct triple *var;
10697                         var = RHS(ptr, 0);
10698                         /* Pop OP_WRITE ptr->right from the stack of variable uses */
10699                         pop_triple(stacks, var, RHS(ptr, 1));
10700                         release_triple(state, ptr);
10701                         continue;
10702                 }
10703                 if (ptr->op == OP_PHI) {
10704                         struct triple *var;
10705                         var = MISC(ptr, 0);
10706                         /* Pop OP_WRITE ptr->right from the stack of variable uses */
10707                         pop_triple(stacks, var, ptr);
10708                 }
10709                 last = ptr;
10710         }
10711         block->last = last;
10712 }
10713
10714 static void prune_block_variables(struct compile_state *state,
10715         struct block *block)
10716 {
10717         struct block_set *user;
10718         struct triple *next, *last, *ptr;
10719         int done;
10720         last = block->first;
10721         done = 0;
10722         for(ptr = block->first; !done; ptr = next) {
10723                 next = ptr->next;
10724                 if (ptr == block->last) {
10725                         done = 1;
10726                 }
10727                 if (ptr->op == OP_ADECL) {
10728                         struct triple_set *user, *next;
10729                         for(user = ptr->use; user; user = next) {
10730                                 struct triple *use;
10731                                 next = user->next;
10732                                 use = user->member;
10733                                 if (use->op != OP_PHI) {
10734                                         internal_error(state, use, "decl still used");
10735                                 }
10736                                 if (MISC(use, 0) != ptr) {
10737                                         internal_error(state, use, "bad phi use of decl");
10738                                 }
10739                                 unuse_triple(ptr, use);
10740                                 MISC(use, 0) = 0;
10741                         }
10742                         release_triple(state, ptr);
10743                         continue;
10744                 }
10745                 last = ptr;
10746         }
10747         block->last = last;
10748         for(user = block->idominates; user; user = user->next) {
10749                 prune_block_variables(state, user->member);
10750         }
10751 }
10752
10753 struct phi_triple {
10754         struct triple *phi;
10755         unsigned orig_id;
10756         int alive;
10757 };
10758
10759 static void keep_phi(struct compile_state *state, struct phi_triple *live, struct triple *phi)
10760 {
10761         struct triple **slot;
10762         int zrhs, i;
10763         if (live[phi->id].alive) {
10764                 return;
10765         }
10766         live[phi->id].alive = 1;
10767         zrhs = TRIPLE_RHS(phi->sizes);
10768         slot = &RHS(phi, 0);
10769         for(i = 0; i < zrhs; i++) {
10770                 struct triple *used;
10771                 used = slot[i];
10772                 if (used && (used->op == OP_PHI)) {
10773                         keep_phi(state, live, used);
10774                 }
10775         }
10776 }
10777
10778 static void prune_unused_phis(struct compile_state *state)
10779 {
10780         struct triple *first, *phi;
10781         struct phi_triple *live;
10782         int phis, i;
10783         
10784
10785         /* Find the first instruction */
10786         first = RHS(state->main_function, 0);
10787
10788         /* Count how many phi functions I need to process */
10789         phis = 0;
10790         for(phi = first->next; phi != first; phi = phi->next) {
10791                 if (phi->op == OP_PHI) {
10792                         phis += 1;
10793                 }
10794         }
10795         
10796         /* Mark them all dead */
10797         live = xcmalloc(sizeof(*live) * (phis + 1), "phi_triple");
10798         phis = 0;
10799         for(phi = first->next; phi != first; phi = phi->next) {
10800                 if (phi->op != OP_PHI) {
10801                         continue;
10802                 }
10803                 live[phis].alive   = 0;
10804                 live[phis].orig_id = phi->id;
10805                 live[phis].phi     = phi;
10806                 phi->id = phis;
10807                 phis += 1;
10808         }
10809         
10810         /* Mark phis alive that are used by non phis */
10811         for(i = 0; i < phis; i++) {
10812                 struct triple_set *set;
10813                 for(set = live[i].phi->use; !live[i].alive && set; set = set->next) {
10814                         if (set->member->op != OP_PHI) {
10815                                 keep_phi(state, live, live[i].phi);
10816                                 break;
10817                         }
10818                 }
10819         }
10820
10821         /* Delete the extraneous phis */
10822         for(i = 0; i < phis; i++) {
10823                 struct triple **slot;
10824                 int zrhs, j;
10825                 if (!live[i].alive) {
10826                         release_triple(state, live[i].phi);
10827                         continue;
10828                 }
10829                 phi = live[i].phi;
10830                 slot = &RHS(phi, 0);
10831                 zrhs = TRIPLE_RHS(phi->sizes);
10832                 for(j = 0; j < zrhs; j++) {
10833                         if(!slot[j]) {
10834                                 error(state, phi, "variable not set on all paths to use");
10835                         }
10836                 }
10837         }
10838         xfree(live);
10839 }
10840
10841
10842 static void transform_to_ssa_form(struct compile_state *state)
10843 {
10844         struct triple_set **stacks;
10845         int adecls;
10846         insert_phi_operations(state);
10847 #if 0
10848         printf("@%s:%d\n", __FILE__, __LINE__);
10849         print_blocks(state, stdout);
10850 #endif
10851
10852         /* Allocate stacks for the Variables */
10853         adecls = count_and_number_adecls(state);
10854         stacks = xcmalloc(sizeof(stacks[0])*(adecls + 1), "adecl stacks");
10855         rename_block_variables(state, stacks, state->first_block);
10856         xfree(stacks);
10857
10858         prune_block_variables(state, state->first_block);
10859
10860 #if 1
10861         prune_unused_phis(state);
10862 #endif
10863
10864 }
10865
10866
10867 static void clear_vertex(
10868         struct compile_state *state, struct block *block, void *arg)
10869 {
10870         block->vertex = 0;
10871 }
10872
10873 static void mark_live_block(
10874         struct compile_state *state, struct block *block, int *next_vertex)
10875 {
10876         /* See if this is a block that has not been marked */
10877         if (block->vertex != 0) {
10878                 return;
10879         }
10880         block->vertex = *next_vertex;
10881         *next_vertex += 1;
10882         if (triple_is_branch(state, block->last)) {
10883                 struct triple **targ;
10884                 targ = triple_targ(state, block->last, 0);
10885                 for(; targ; targ = triple_targ(state, block->last, targ)) {
10886                         if (!*targ) {
10887                                 continue;
10888                         }
10889                         if (!triple_stores_block(state, *targ)) {
10890                                 internal_error(state, 0, "bad targ");
10891                         }
10892                         mark_live_block(state, (*targ)->u.block, next_vertex);
10893                 }
10894         }
10895         else if (block->last->next != RHS(state->main_function, 0)) {
10896                 struct triple *ins;
10897                 ins = block->last->next;
10898                 if (!triple_stores_block(state, ins)) {
10899                         internal_error(state, 0, "bad block start");
10900                 }
10901                 mark_live_block(state, ins->u.block, next_vertex);
10902         }
10903 }
10904
10905 static void transform_from_ssa_form(struct compile_state *state)
10906 {
10907         /* To get out of ssa form we insert moves on the incoming
10908          * edges to blocks containting phi functions.
10909          */
10910         struct triple *first;
10911         struct triple *phi, *next;
10912         int next_vertex;
10913
10914         /* Walk the control flow to see which blocks remain alive */
10915         walk_blocks(state, clear_vertex, 0);
10916         next_vertex = 1;
10917         mark_live_block(state, state->first_block, &next_vertex);
10918
10919         /* Walk all of the operations to find the phi functions */
10920         first = RHS(state->main_function, 0);
10921         for(phi = first->next; phi != first ; phi = next) {
10922                 struct block_set *set;
10923                 struct block *block;
10924                 struct triple **slot;
10925                 struct triple *var, *read;
10926                 struct triple_set *use, *use_next;
10927                 int edge, used;
10928                 next = phi->next;
10929                 if (phi->op != OP_PHI) {
10930                         continue;
10931                 }
10932                 block = phi->u.block;
10933                 slot  = &RHS(phi, 0);
10934
10935                 /* Forget uses from code in dead blocks */
10936                 for(use = phi->use; use; use = use_next) {
10937                         struct block *ublock;
10938                         struct triple **expr;
10939                         use_next = use->next;
10940                         ublock = block_of_triple(state, use->member);
10941                         if ((use->member == phi) || (ublock->vertex != 0)) {
10942                                 continue;
10943                         }
10944                         expr = triple_rhs(state, use->member, 0);
10945                         for(; expr; expr = triple_rhs(state, use->member, expr)) {
10946                                 if (*expr == phi) {
10947                                         *expr = 0;
10948                                 }
10949                         }
10950                         unuse_triple(phi, use->member);
10951                 }
10952
10953 #warning "CHECK_ME does the OP_ADECL need to be placed somewhere that dominates all of the incoming phi edges?"
10954                 /* A variable to replace the phi function */
10955                 var = post_triple(state, phi, OP_ADECL, phi->type, 0,0);
10956                 /* A read of the single value that is set into the variable */
10957                 read = post_triple(state, var, OP_READ, phi->type, var, 0);
10958                 use_triple(var, read);
10959
10960                 /* Replaces uses of the phi with variable reads */
10961                 propogate_use(state, phi, read);
10962
10963                 /* Walk all of the incoming edges/blocks and insert moves.
10964                  */
10965                 for(edge = 0, set = block->use; set; set = set->next, edge++) {
10966                         struct block *eblock;
10967                         struct triple *move;
10968                         struct triple *val, *base;
10969                         eblock = set->member;
10970                         val = slot[edge];
10971                         slot[edge] = 0;
10972                         unuse_triple(val, phi);
10973
10974                         if (!val || (val == &zero_triple) ||
10975                                 (block->vertex == 0) || (eblock->vertex == 0) ||
10976                                 (val == phi) || (val == read)) {
10977                                 continue;
10978                         }
10979                         
10980                         /* Make certain the write is placed in the edge block... */
10981                         base = eblock->first;
10982                         if (block_of_triple(state, val) == eblock) {
10983                                 base = val;
10984                         }
10985                         move = post_triple(state, base, OP_WRITE, phi->type, var, val);
10986                         use_triple(val, move);
10987                         use_triple(var, move);
10988                 }               
10989                 /* See if there are any writers of var */
10990                 used = 0;
10991                 for(use = var->use; use; use = use->next) {
10992                         if ((use->member->op == OP_WRITE) &&
10993                                 (RHS(use->member, 0) == var)) {
10994                                 used = 1;
10995                         }
10996                 }
10997                 /* If var is not used free it */
10998                 if (!used) {
10999                         unuse_triple(var, read);
11000                         free_triple(state, read);
11001                         free_triple(state, var);
11002                 }
11003
11004                 /* Release the phi function */
11005                 release_triple(state, phi);
11006         }
11007         
11008 }
11009
11010
11011 /* 
11012  * Register conflict resolution
11013  * =========================================================
11014  */
11015
11016 static struct reg_info find_def_color(
11017         struct compile_state *state, struct triple *def)
11018 {
11019         struct triple_set *set;
11020         struct reg_info info;
11021         info.reg = REG_UNSET;
11022         info.regcm = 0;
11023         if (!triple_is_def(state, def)) {
11024                 return info;
11025         }
11026         info = arch_reg_lhs(state, def, 0);
11027         if (info.reg >= MAX_REGISTERS) {
11028                 info.reg = REG_UNSET;
11029         }
11030         for(set = def->use; set; set = set->next) {
11031                 struct reg_info tinfo;
11032                 int i;
11033                 i = find_rhs_use(state, set->member, def);
11034                 if (i < 0) {
11035                         continue;
11036                 }
11037                 tinfo = arch_reg_rhs(state, set->member, i);
11038                 if (tinfo.reg >= MAX_REGISTERS) {
11039                         tinfo.reg = REG_UNSET;
11040                 }
11041                 if ((tinfo.reg != REG_UNSET) && 
11042                         (info.reg != REG_UNSET) &&
11043                         (tinfo.reg != info.reg)) {
11044                         internal_error(state, def, "register conflict");
11045                 }
11046                 if ((info.regcm & tinfo.regcm) == 0) {
11047                         internal_error(state, def, "regcm conflict %x & %x == 0",
11048                                 info.regcm, tinfo.regcm);
11049                 }
11050                 if (info.reg == REG_UNSET) {
11051                         info.reg = tinfo.reg;
11052                 }
11053                 info.regcm &= tinfo.regcm;
11054         }
11055         if (info.reg >= MAX_REGISTERS) {
11056                 internal_error(state, def, "register out of range");
11057         }
11058         return info;
11059 }
11060
11061 static struct reg_info find_lhs_pre_color(
11062         struct compile_state *state, struct triple *ins, int index)
11063 {
11064         struct reg_info info;
11065         int zlhs, zrhs, i;
11066         zrhs = TRIPLE_RHS(ins->sizes);
11067         zlhs = TRIPLE_LHS(ins->sizes);
11068         if (!zlhs && triple_is_def(state, ins)) {
11069                 zlhs = 1;
11070         }
11071         if (index >= zlhs) {
11072                 internal_error(state, ins, "Bad lhs %d", index);
11073         }
11074         info = arch_reg_lhs(state, ins, index);
11075         for(i = 0; i < zrhs; i++) {
11076                 struct reg_info rinfo;
11077                 rinfo = arch_reg_rhs(state, ins, i);
11078                 if ((info.reg == rinfo.reg) &&
11079                         (rinfo.reg >= MAX_REGISTERS)) {
11080                         struct reg_info tinfo;
11081                         tinfo = find_lhs_pre_color(state, RHS(ins, index), 0);
11082                         info.reg = tinfo.reg;
11083                         info.regcm &= tinfo.regcm;
11084                         break;
11085                 }
11086         }
11087         if (info.reg >= MAX_REGISTERS) {
11088                 info.reg = REG_UNSET;
11089         }
11090         return info;
11091 }
11092
11093 static struct reg_info find_rhs_post_color(
11094         struct compile_state *state, struct triple *ins, int index);
11095
11096 static struct reg_info find_lhs_post_color(
11097         struct compile_state *state, struct triple *ins, int index)
11098 {
11099         struct triple_set *set;
11100         struct reg_info info;
11101         struct triple *lhs;
11102 #if DEBUG_TRIPLE_COLOR
11103         fprintf(stderr, "find_lhs_post_color(%p, %d)\n",
11104                 ins, index);
11105 #endif
11106         if ((index == 0) && triple_is_def(state, ins)) {
11107                 lhs = ins;
11108         }
11109         else if (index < TRIPLE_LHS(ins->sizes)) {
11110                 lhs = LHS(ins, index);
11111         }
11112         else {
11113                 internal_error(state, ins, "Bad lhs %d", index);
11114                 lhs = 0;
11115         }
11116         info = arch_reg_lhs(state, ins, index);
11117         if (info.reg >= MAX_REGISTERS) {
11118                 info.reg = REG_UNSET;
11119         }
11120         for(set = lhs->use; set; set = set->next) {
11121                 struct reg_info rinfo;
11122                 struct triple *user;
11123                 int zrhs, i;
11124                 user = set->member;
11125                 zrhs = TRIPLE_RHS(user->sizes);
11126                 for(i = 0; i < zrhs; i++) {
11127                         if (RHS(user, i) != lhs) {
11128                                 continue;
11129                         }
11130                         rinfo = find_rhs_post_color(state, user, i);
11131                         if ((info.reg != REG_UNSET) &&
11132                                 (rinfo.reg != REG_UNSET) &&
11133                                 (info.reg != rinfo.reg)) {
11134                                 internal_error(state, ins, "register conflict");
11135                         }
11136                         if ((info.regcm & rinfo.regcm) == 0) {
11137                                 internal_error(state, ins, "regcm conflict %x & %x == 0",
11138                                         info.regcm, rinfo.regcm);
11139                         }
11140                         if (info.reg == REG_UNSET) {
11141                                 info.reg = rinfo.reg;
11142                         }
11143                         info.regcm &= rinfo.regcm;
11144                 }
11145         }
11146 #if DEBUG_TRIPLE_COLOR
11147         fprintf(stderr, "find_lhs_post_color(%p, %d) -> ( %d, %x)\n",
11148                 ins, index, info.reg, info.regcm);
11149 #endif
11150         return info;
11151 }
11152
11153 static struct reg_info find_rhs_post_color(
11154         struct compile_state *state, struct triple *ins, int index)
11155 {
11156         struct reg_info info, rinfo;
11157         int zlhs, i;
11158 #if DEBUG_TRIPLE_COLOR
11159         fprintf(stderr, "find_rhs_post_color(%p, %d)\n",
11160                 ins, index);
11161 #endif
11162         rinfo = arch_reg_rhs(state, ins, index);
11163         zlhs = TRIPLE_LHS(ins->sizes);
11164         if (!zlhs && triple_is_def(state, ins)) {
11165                 zlhs = 1;
11166         }
11167         info = rinfo;
11168         if (info.reg >= MAX_REGISTERS) {
11169                 info.reg = REG_UNSET;
11170         }
11171         for(i = 0; i < zlhs; i++) {
11172                 struct reg_info linfo;
11173                 linfo = arch_reg_lhs(state, ins, i);
11174                 if ((linfo.reg == rinfo.reg) &&
11175                         (linfo.reg >= MAX_REGISTERS)) {
11176                         struct reg_info tinfo;
11177                         tinfo = find_lhs_post_color(state, ins, i);
11178                         if (tinfo.reg >= MAX_REGISTERS) {
11179                                 tinfo.reg = REG_UNSET;
11180                         }
11181                         info.regcm &= linfo.regcm;
11182                         info.regcm &= tinfo.regcm;
11183                         if (info.reg != REG_UNSET) {
11184                                 internal_error(state, ins, "register conflict");
11185                         }
11186                         if (info.regcm == 0) {
11187                                 internal_error(state, ins, "regcm conflict");
11188                         }
11189                         info.reg = tinfo.reg;
11190                 }
11191         }
11192 #if DEBUG_TRIPLE_COLOR
11193         fprintf(stderr, "find_rhs_post_color(%p, %d) -> ( %d, %x)\n",
11194                 ins, index, info.reg, info.regcm);
11195 #endif
11196         return info;
11197 }
11198
11199 static struct reg_info find_lhs_color(
11200         struct compile_state *state, struct triple *ins, int index)
11201 {
11202         struct reg_info pre, post, info;
11203 #if DEBUG_TRIPLE_COLOR
11204         fprintf(stderr, "find_lhs_color(%p, %d)\n",
11205                 ins, index);
11206 #endif
11207         pre = find_lhs_pre_color(state, ins, index);
11208         post = find_lhs_post_color(state, ins, index);
11209         if ((pre.reg != post.reg) &&
11210                 (pre.reg != REG_UNSET) &&
11211                 (post.reg != REG_UNSET)) {
11212                 internal_error(state, ins, "register conflict");
11213         }
11214         info.regcm = pre.regcm & post.regcm;
11215         info.reg = pre.reg;
11216         if (info.reg == REG_UNSET) {
11217                 info.reg = post.reg;
11218         }
11219 #if DEBUG_TRIPLE_COLOR
11220         fprintf(stderr, "find_lhs_color(%p, %d) -> ( %d, %x) ... (%d, %x) (%d, %x)\n",
11221                 ins, index, info.reg, info.regcm,
11222                 pre.reg, pre.regcm, post.reg, post.regcm);
11223 #endif
11224         return info;
11225 }
11226
11227 static struct triple *post_copy(struct compile_state *state, struct triple *ins)
11228 {
11229         struct triple_set *entry, *next;
11230         struct triple *out;
11231         struct reg_info info, rinfo;
11232
11233         info = arch_reg_lhs(state, ins, 0);
11234         out = post_triple(state, ins, OP_COPY, ins->type, ins, 0);
11235         use_triple(RHS(out, 0), out);
11236         /* Get the users of ins to use out instead */
11237         for(entry = ins->use; entry; entry = next) {
11238                 int i;
11239                 next = entry->next;
11240                 if (entry->member == out) {
11241                         continue;
11242                 }
11243                 i = find_rhs_use(state, entry->member, ins);
11244                 if (i < 0) {
11245                         continue;
11246                 }
11247                 rinfo = arch_reg_rhs(state, entry->member, i);
11248                 if ((info.reg == REG_UNNEEDED) && (rinfo.reg == REG_UNNEEDED)) {
11249                         continue;
11250                 }
11251                 replace_rhs_use(state, ins, out, entry->member);
11252         }
11253         transform_to_arch_instruction(state, out);
11254         return out;
11255 }
11256
11257 static struct triple *typed_pre_copy(
11258         struct compile_state *state, struct type *type, struct triple *ins, int index)
11259 {
11260         /* Carefully insert enough operations so that I can
11261          * enter any operation with a GPR32.
11262          */
11263         struct triple *in;
11264         struct triple **expr;
11265         unsigned classes;
11266         struct reg_info info;
11267         if (ins->op == OP_PHI) {
11268                 internal_error(state, ins, "pre_copy on a phi?");
11269         }
11270         classes = arch_type_to_regcm(state, type);
11271         info = arch_reg_rhs(state, ins, index);
11272         expr = &RHS(ins, index);
11273         if ((info.regcm & classes) == 0) {
11274                 internal_error(state, ins, "pre_copy with no register classes");
11275         }
11276         in = pre_triple(state, ins, OP_COPY, type, *expr, 0);
11277         unuse_triple(*expr, ins);
11278         *expr = in;
11279         use_triple(RHS(in, 0), in);
11280         use_triple(in, ins);
11281         transform_to_arch_instruction(state, in);
11282         return in;
11283         
11284 }
11285 static struct triple *pre_copy(
11286         struct compile_state *state, struct triple *ins, int index)
11287 {
11288         return typed_pre_copy(state, RHS(ins, index)->type, ins, index);
11289 }
11290
11291
11292 static void insert_copies_to_phi(struct compile_state *state)
11293 {
11294         /* To get out of ssa form we insert moves on the incoming
11295          * edges to blocks containting phi functions.
11296          */
11297         struct triple *first;
11298         struct triple *phi;
11299
11300         /* Walk all of the operations to find the phi functions */
11301         first = RHS(state->main_function, 0);
11302         for(phi = first->next; phi != first ; phi = phi->next) {
11303                 struct block_set *set;
11304                 struct block *block;
11305                 struct triple **slot, *copy;
11306                 int edge;
11307                 if (phi->op != OP_PHI) {
11308                         continue;
11309                 }
11310                 phi->id |= TRIPLE_FLAG_POST_SPLIT;
11311                 block = phi->u.block;
11312                 slot  = &RHS(phi, 0);
11313                 /* Phi's that feed into mandatory live range joins
11314                  * cause nasty complications.  Insert a copy of
11315                  * the phi value so I never have to deal with
11316                  * that in the rest of the code.
11317                  */
11318                 copy = post_copy(state, phi);
11319                 copy->id |= TRIPLE_FLAG_PRE_SPLIT;
11320                 /* Walk all of the incoming edges/blocks and insert moves.
11321                  */
11322                 for(edge = 0, set = block->use; set; set = set->next, edge++) {
11323                         struct block *eblock;
11324                         struct triple *move;
11325                         struct triple *val;
11326                         struct triple *ptr;
11327                         eblock = set->member;
11328                         val = slot[edge];
11329
11330                         if (val == phi) {
11331                                 continue;
11332                         }
11333
11334                         get_occurance(val->occurance);
11335                         move = build_triple(state, OP_COPY, phi->type, val, 0,
11336                                 val->occurance);
11337                         move->u.block = eblock;
11338                         move->id |= TRIPLE_FLAG_PRE_SPLIT;
11339                         use_triple(val, move);
11340                         
11341                         slot[edge] = move;
11342                         unuse_triple(val, phi);
11343                         use_triple(move, phi);
11344
11345                         /* Walk up the dominator tree until I have found the appropriate block */
11346                         while(eblock && !tdominates(state, val, eblock->last)) {
11347                                 eblock = eblock->idom;
11348                         }
11349                         if (!eblock) {
11350                                 internal_error(state, phi, "Cannot find block dominated by %p",
11351                                         val);
11352                         }
11353
11354                         /* Walk through the block backwards to find
11355                          * an appropriate location for the OP_COPY.
11356                          */
11357                         for(ptr = eblock->last; ptr != eblock->first; ptr = ptr->prev) {
11358                                 struct triple **expr;
11359                                 if ((ptr == phi) || (ptr == val)) {
11360                                         goto out;
11361                                 }
11362                                 expr = triple_rhs(state, ptr, 0);
11363                                 for(;expr; expr = triple_rhs(state, ptr, expr)) {
11364                                         if ((*expr) == phi) {
11365                                                 goto out;
11366                                         }
11367                                 }
11368                         }
11369                 out:
11370                         if (triple_is_branch(state, ptr)) {
11371                                 internal_error(state, ptr,
11372                                         "Could not insert write to phi");
11373                         }
11374                         insert_triple(state, ptr->next, move);
11375                         if (eblock->last == ptr) {
11376                                 eblock->last = move;
11377                         }
11378                         transform_to_arch_instruction(state, move);
11379                 }
11380         }
11381 }
11382
11383 struct triple_reg_set {
11384         struct triple_reg_set *next;
11385         struct triple *member;
11386         struct triple *new;
11387 };
11388
11389 struct reg_block {
11390         struct block *block;
11391         struct triple_reg_set *in;
11392         struct triple_reg_set *out;
11393         int vertex;
11394 };
11395
11396 static int do_triple_set(struct triple_reg_set **head, 
11397         struct triple *member, struct triple *new_member)
11398 {
11399         struct triple_reg_set **ptr, *new;
11400         if (!member)
11401                 return 0;
11402         ptr = head;
11403         while(*ptr) {
11404                 if ((*ptr)->member == member) {
11405                         return 0;
11406                 }
11407                 ptr = &(*ptr)->next;
11408         }
11409         new = xcmalloc(sizeof(*new), "triple_set");
11410         new->member = member;
11411         new->new    = new_member;
11412         new->next   = *head;
11413         *head       = new;
11414         return 1;
11415 }
11416
11417 static void do_triple_unset(struct triple_reg_set **head, struct triple *member)
11418 {
11419         struct triple_reg_set *entry, **ptr;
11420         ptr = head;
11421         while(*ptr) {
11422                 entry = *ptr;
11423                 if (entry->member == member) {
11424                         *ptr = entry->next;
11425                         xfree(entry);
11426                         return;
11427                 }
11428                 else {
11429                         ptr = &entry->next;
11430                 }
11431         }
11432 }
11433
11434 static int in_triple(struct reg_block *rb, struct triple *in)
11435 {
11436         return do_triple_set(&rb->in, in, 0);
11437 }
11438 static void unin_triple(struct reg_block *rb, struct triple *unin)
11439 {
11440         do_triple_unset(&rb->in, unin);
11441 }
11442
11443 static int out_triple(struct reg_block *rb, struct triple *out)
11444 {
11445         return do_triple_set(&rb->out, out, 0);
11446 }
11447 static void unout_triple(struct reg_block *rb, struct triple *unout)
11448 {
11449         do_triple_unset(&rb->out, unout);
11450 }
11451
11452 static int initialize_regblock(struct reg_block *blocks,
11453         struct block *block, int vertex)
11454 {
11455         struct block_set *user;
11456         if (!block || (blocks[block->vertex].block == block)) {
11457                 return vertex;
11458         }
11459         vertex += 1;
11460         /* Renumber the blocks in a convinient fashion */
11461         block->vertex = vertex;
11462         blocks[vertex].block    = block;
11463         blocks[vertex].vertex   = vertex;
11464         for(user = block->use; user; user = user->next) {
11465                 vertex = initialize_regblock(blocks, user->member, vertex);
11466         }
11467         return vertex;
11468 }
11469
11470 static int phi_in(struct compile_state *state, struct reg_block *blocks,
11471         struct reg_block *rb, struct block *suc)
11472 {
11473         /* Read the conditional input set of a successor block
11474          * (i.e. the input to the phi nodes) and place it in the
11475          * current blocks output set.
11476          */
11477         struct block_set *set;
11478         struct triple *ptr;
11479         int edge;
11480         int done, change;
11481         change = 0;
11482         /* Find the edge I am coming in on */
11483         for(edge = 0, set = suc->use; set; set = set->next, edge++) {
11484                 if (set->member == rb->block) {
11485                         break;
11486                 }
11487         }
11488         if (!set) {
11489                 internal_error(state, 0, "Not coming on a control edge?");
11490         }
11491         for(done = 0, ptr = suc->first; !done; ptr = ptr->next) {
11492                 struct triple **slot, *expr, *ptr2;
11493                 int out_change, done2;
11494                 done = (ptr == suc->last);
11495                 if (ptr->op != OP_PHI) {
11496                         continue;
11497                 }
11498                 slot = &RHS(ptr, 0);
11499                 expr = slot[edge];
11500                 out_change = out_triple(rb, expr);
11501                 if (!out_change) {
11502                         continue;
11503                 }
11504                 /* If we don't define the variable also plast it
11505                  * in the current blocks input set.
11506                  */
11507                 ptr2 = rb->block->first;
11508                 for(done2 = 0; !done2; ptr2 = ptr2->next) {
11509                         if (ptr2 == expr) {
11510                                 break;
11511                         }
11512                         done2 = (ptr2 == rb->block->last);
11513                 }
11514                 if (!done2) {
11515                         continue;
11516                 }
11517                 change |= in_triple(rb, expr);
11518         }
11519         return change;
11520 }
11521
11522 static int reg_in(struct compile_state *state, struct reg_block *blocks,
11523         struct reg_block *rb, struct block *suc)
11524 {
11525         struct triple_reg_set *in_set;
11526         int change;
11527         change = 0;
11528         /* Read the input set of a successor block
11529          * and place it in the current blocks output set.
11530          */
11531         in_set = blocks[suc->vertex].in;
11532         for(; in_set; in_set = in_set->next) {
11533                 int out_change, done;
11534                 struct triple *first, *last, *ptr;
11535                 out_change = out_triple(rb, in_set->member);
11536                 if (!out_change) {
11537                         continue;
11538                 }
11539                 /* If we don't define the variable also place it
11540                  * in the current blocks input set.
11541                  */
11542                 first = rb->block->first;
11543                 last = rb->block->last;
11544                 done = 0;
11545                 for(ptr = first; !done; ptr = ptr->next) {
11546                         if (ptr == in_set->member) {
11547                                 break;
11548                         }
11549                         done = (ptr == last);
11550                 }
11551                 if (!done) {
11552                         continue;
11553                 }
11554                 change |= in_triple(rb, in_set->member);
11555         }
11556         change |= phi_in(state, blocks, rb, suc);
11557         return change;
11558 }
11559
11560
11561 static int use_in(struct compile_state *state, struct reg_block *rb)
11562 {
11563         /* Find the variables we use but don't define and add
11564          * it to the current blocks input set.
11565          */
11566 #warning "FIXME is this O(N^2) algorithm bad?"
11567         struct block *block;
11568         struct triple *ptr;
11569         int done;
11570         int change;
11571         block = rb->block;
11572         change = 0;
11573         for(done = 0, ptr = block->last; !done; ptr = ptr->prev) {
11574                 struct triple **expr;
11575                 done = (ptr == block->first);
11576                 /* The variable a phi function uses depends on the
11577                  * control flow, and is handled in phi_in, not
11578                  * here.
11579                  */
11580                 if (ptr->op == OP_PHI) {
11581                         continue;
11582                 }
11583                 expr = triple_rhs(state, ptr, 0);
11584                 for(;expr; expr = triple_rhs(state, ptr, expr)) {
11585                         struct triple *rhs, *test;
11586                         int tdone;
11587                         rhs = *expr;
11588                         if (!rhs) {
11589                                 continue;
11590                         }
11591                         /* See if rhs is defined in this block */
11592                         for(tdone = 0, test = ptr; !tdone; test = test->prev) {
11593                                 tdone = (test == block->first);
11594                                 if (test == rhs) {
11595                                         rhs = 0;
11596                                         break;
11597                                 }
11598                         }
11599                         /* If I still have a valid rhs add it to in */
11600                         change |= in_triple(rb, rhs);
11601                 }
11602         }
11603         return change;
11604 }
11605
11606 static struct reg_block *compute_variable_lifetimes(
11607         struct compile_state *state)
11608 {
11609         struct reg_block *blocks;
11610         int change;
11611         blocks = xcmalloc(
11612                 sizeof(*blocks)*(state->last_vertex + 1), "reg_block");
11613         initialize_regblock(blocks, state->last_block, 0);
11614         do {
11615                 int i;
11616                 change = 0;
11617                 for(i = 1; i <= state->last_vertex; i++) {
11618                         struct reg_block *rb;
11619                         rb = &blocks[i];
11620                         /* Add the left successor's input set to in */
11621                         if (rb->block->left) {
11622                                 change |= reg_in(state, blocks, rb, rb->block->left);
11623                         }
11624                         /* Add the right successor's input set to in */
11625                         if ((rb->block->right) && 
11626                                 (rb->block->right != rb->block->left)) {
11627                                 change |= reg_in(state, blocks, rb, rb->block->right);
11628                         }
11629                         /* Add use to in... */
11630                         change |= use_in(state, rb);
11631                 }
11632         } while(change);
11633         return blocks;
11634 }
11635
11636 static void free_variable_lifetimes(
11637         struct compile_state *state, struct reg_block *blocks)
11638 {
11639         int i;
11640         /* free in_set && out_set on each block */
11641         for(i = 1; i <= state->last_vertex; i++) {
11642                 struct triple_reg_set *entry, *next;
11643                 struct reg_block *rb;
11644                 rb = &blocks[i];
11645                 for(entry = rb->in; entry ; entry = next) {
11646                         next = entry->next;
11647                         do_triple_unset(&rb->in, entry->member);
11648                 }
11649                 for(entry = rb->out; entry; entry = next) {
11650                         next = entry->next;
11651                         do_triple_unset(&rb->out, entry->member);
11652                 }
11653         }
11654         xfree(blocks);
11655
11656 }
11657
11658 typedef void (*wvl_cb_t)(
11659         struct compile_state *state, 
11660         struct reg_block *blocks, struct triple_reg_set *live, 
11661         struct reg_block *rb, struct triple *ins, void *arg);
11662
11663 static void walk_variable_lifetimes(struct compile_state *state,
11664         struct reg_block *blocks, wvl_cb_t cb, void *arg)
11665 {
11666         int i;
11667         
11668         for(i = 1; i <= state->last_vertex; i++) {
11669                 struct triple_reg_set *live;
11670                 struct triple_reg_set *entry, *next;
11671                 struct triple *ptr, *prev;
11672                 struct reg_block *rb;
11673                 struct block *block;
11674                 int done;
11675
11676                 /* Get the blocks */
11677                 rb = &blocks[i];
11678                 block = rb->block;
11679
11680                 /* Copy out into live */
11681                 live = 0;
11682                 for(entry = rb->out; entry; entry = next) {
11683                         next = entry->next;
11684                         do_triple_set(&live, entry->member, entry->new);
11685                 }
11686                 /* Walk through the basic block calculating live */
11687                 for(done = 0, ptr = block->last; !done; ptr = prev) {
11688                         struct triple **expr;
11689
11690                         prev = ptr->prev;
11691                         done = (ptr == block->first);
11692
11693                         /* Ensure the current definition is in live */
11694                         if (triple_is_def(state, ptr)) {
11695                                 do_triple_set(&live, ptr, 0);
11696                         }
11697
11698                         /* Inform the callback function of what is
11699                          * going on.
11700                          */
11701                          cb(state, blocks, live, rb, ptr, arg);
11702                         
11703                         /* Remove the current definition from live */
11704                         do_triple_unset(&live, ptr);
11705
11706                         /* Add the current uses to live.
11707                          *
11708                          * It is safe to skip phi functions because they do
11709                          * not have any block local uses, and the block
11710                          * output sets already properly account for what
11711                          * control flow depedent uses phi functions do have.
11712                          */
11713                         if (ptr->op == OP_PHI) {
11714                                 continue;
11715                         }
11716                         expr = triple_rhs(state, ptr, 0);
11717                         for(;expr; expr = triple_rhs(state, ptr, expr)) {
11718                                 /* If the triple is not a definition skip it. */
11719                                 if (!*expr || !triple_is_def(state, *expr)) {
11720                                         continue;
11721                                 }
11722                                 do_triple_set(&live, *expr, 0);
11723                         }
11724                 }
11725                 /* Free live */
11726                 for(entry = live; entry; entry = next) {
11727                         next = entry->next;
11728                         do_triple_unset(&live, entry->member);
11729                 }
11730         }
11731 }
11732
11733 static int count_triples(struct compile_state *state)
11734 {
11735         struct triple *first, *ins;
11736         int triples = 0;
11737         first = RHS(state->main_function, 0);
11738         ins = first;
11739         do {
11740                 triples++;
11741                 ins = ins->next;
11742         } while (ins != first);
11743         return triples;
11744 }
11745
11746
11747 struct dead_triple {
11748         struct triple *triple;
11749         struct dead_triple *work_next;
11750         struct block *block;
11751         int color;
11752         int flags;
11753 #define TRIPLE_FLAG_ALIVE 1
11754 };
11755
11756
11757 static void awaken(
11758         struct compile_state *state,
11759         struct dead_triple *dtriple, struct triple **expr,
11760         struct dead_triple ***work_list_tail)
11761 {
11762         struct triple *triple;
11763         struct dead_triple *dt;
11764         if (!expr) {
11765                 return;
11766         }
11767         triple = *expr;
11768         if (!triple) {
11769                 return;
11770         }
11771         if (triple->id <= 0)  {
11772                 internal_error(state, triple, "bad triple id: %d",
11773                         triple->id);
11774         }
11775         if (triple->op == OP_NOOP) {
11776                 internal_warning(state, triple, "awakening noop?");
11777                 return;
11778         }
11779         dt = &dtriple[triple->id];
11780         if (!(dt->flags & TRIPLE_FLAG_ALIVE)) {
11781                 dt->flags |= TRIPLE_FLAG_ALIVE;
11782                 if (!dt->work_next) {
11783                         **work_list_tail = dt;
11784                         *work_list_tail = &dt->work_next;
11785                 }
11786         }
11787 }
11788
11789 static void eliminate_inefectual_code(struct compile_state *state)
11790 {
11791         struct block *block;
11792         struct dead_triple *dtriple, *work_list, **work_list_tail, *dt;
11793         int triples, i;
11794         struct triple *first, *ins;
11795
11796         /* Setup the work list */
11797         work_list = 0;
11798         work_list_tail = &work_list;
11799
11800         first = RHS(state->main_function, 0);
11801
11802         /* Count how many triples I have */
11803         triples = count_triples(state);
11804
11805         /* Now put then in an array and mark all of the triples dead */
11806         dtriple = xcmalloc(sizeof(*dtriple) * (triples + 1), "dtriples");
11807         
11808         ins = first;
11809         i = 1;
11810         block = 0;
11811         do {
11812                 if (ins->op == OP_LABEL) {
11813                         block = ins->u.block;
11814                 }
11815                 dtriple[i].triple = ins;
11816                 dtriple[i].block  = block;
11817                 dtriple[i].flags  = 0;
11818                 dtriple[i].color  = ins->id;
11819                 ins->id = i;
11820                 /* See if it is an operation we always keep */
11821 #warning "FIXME handle the case of killing a branch instruction"
11822                 if (!triple_is_pure(state, ins) || triple_is_branch(state, ins)) {
11823                         awaken(state, dtriple, &ins, &work_list_tail);
11824                 }
11825 #if 1
11826                 /* Unconditionally keep the very last instruction */
11827                 else if (ins->next == first) {
11828                         awaken(state, dtriple, &ins, &work_list_tail);
11829                 }
11830 #endif
11831                 i++;
11832                 ins = ins->next;
11833         } while(ins != first);
11834         while(work_list) {
11835                 struct dead_triple *dt;
11836                 struct block_set *user;
11837                 struct triple **expr;
11838                 dt = work_list;
11839                 work_list = dt->work_next;
11840                 if (!work_list) {
11841                         work_list_tail = &work_list;
11842                 }
11843                 /* Wake up the data depencencies of this triple */
11844                 expr = 0;
11845                 do {
11846                         expr = triple_rhs(state, dt->triple, expr);
11847                         awaken(state, dtriple, expr, &work_list_tail);
11848                 } while(expr);
11849                 do {
11850                         expr = triple_lhs(state, dt->triple, expr);
11851                         awaken(state, dtriple, expr, &work_list_tail);
11852                 } while(expr);
11853                 do {
11854                         expr = triple_misc(state, dt->triple, expr);
11855                         awaken(state, dtriple, expr, &work_list_tail);
11856                 } while(expr);
11857                 /* Wake up the forward control dependencies */
11858                 do {
11859                         expr = triple_targ(state, dt->triple, expr);
11860                         awaken(state, dtriple, expr, &work_list_tail);
11861                 } while(expr);
11862                 /* Wake up the reverse control dependencies of this triple */
11863                 for(user = dt->block->ipdomfrontier; user; user = user->next) {
11864                         awaken(state, dtriple, &user->member->last, &work_list_tail);
11865                 }
11866         }
11867         for(dt = &dtriple[1]; dt <= &dtriple[triples]; dt++) {
11868                 if ((dt->triple->op == OP_NOOP) && 
11869                         (dt->flags & TRIPLE_FLAG_ALIVE)) {
11870                         internal_error(state, dt->triple, "noop effective?");
11871                 }
11872                 dt->triple->id = dt->color;     /* Restore the color */
11873                 if (!(dt->flags & TRIPLE_FLAG_ALIVE)) {
11874 #warning "FIXME handle the case of killing a basic block"
11875                         if (dt->block->first == dt->triple) {
11876                                 continue;
11877                         }
11878                         if (dt->block->last == dt->triple) {
11879                                 dt->block->last = dt->triple->prev;
11880                         }
11881                         release_triple(state, dt->triple);
11882                 }
11883         }
11884         xfree(dtriple);
11885 }
11886
11887
11888 static void insert_mandatory_copies(struct compile_state *state)
11889 {
11890         struct triple *ins, *first;
11891
11892         /* The object is with a minimum of inserted copies,
11893          * to resolve in fundamental register conflicts between
11894          * register value producers and consumers.
11895          * Theoretically we may be greater than minimal when we
11896          * are inserting copies before instructions but that
11897          * case should be rare.
11898          */
11899         first = RHS(state->main_function, 0);
11900         ins = first;
11901         do {
11902                 struct triple_set *entry, *next;
11903                 struct triple *tmp;
11904                 struct reg_info info;
11905                 unsigned reg, regcm;
11906                 int do_post_copy, do_pre_copy;
11907                 tmp = 0;
11908                 if (!triple_is_def(state, ins)) {
11909                         goto next;
11910                 }
11911                 /* Find the architecture specific color information */
11912                 info = arch_reg_lhs(state, ins, 0);
11913                 if (info.reg >= MAX_REGISTERS) {
11914                         info.reg = REG_UNSET;
11915                 }
11916                 
11917                 reg = REG_UNSET;
11918                 regcm = arch_type_to_regcm(state, ins->type);
11919                 do_post_copy = do_pre_copy = 0;
11920
11921                 /* Walk through the uses of ins and check for conflicts */
11922                 for(entry = ins->use; entry; entry = next) {
11923                         struct reg_info rinfo;
11924                         int i;
11925                         next = entry->next;
11926                         i = find_rhs_use(state, entry->member, ins);
11927                         if (i < 0) {
11928                                 continue;
11929                         }
11930                         
11931                         /* Find the users color requirements */
11932                         rinfo = arch_reg_rhs(state, entry->member, i);
11933                         if (rinfo.reg >= MAX_REGISTERS) {
11934                                 rinfo.reg = REG_UNSET;
11935                         }
11936                         
11937                         /* See if I need a pre_copy */
11938                         if (rinfo.reg != REG_UNSET) {
11939                                 if ((reg != REG_UNSET) && (reg != rinfo.reg)) {
11940                                         do_pre_copy = 1;
11941                                 }
11942                                 reg = rinfo.reg;
11943                         }
11944                         regcm &= rinfo.regcm;
11945                         regcm = arch_regcm_normalize(state, regcm);
11946                         if (regcm == 0) {
11947                                 do_pre_copy = 1;
11948                         }
11949                         /* Always use pre_copies for constants.
11950                          * They do not take up any registers until a
11951                          * copy places them in one.
11952                          */
11953                         if ((info.reg == REG_UNNEEDED) && 
11954                                 (rinfo.reg != REG_UNNEEDED)) {
11955                                 do_pre_copy = 1;
11956                         }
11957                 }
11958                 do_post_copy =
11959                         !do_pre_copy &&
11960                         (((info.reg != REG_UNSET) && 
11961                                 (reg != REG_UNSET) &&
11962                                 (info.reg != reg)) ||
11963                         ((info.regcm & regcm) == 0));
11964
11965                 reg = info.reg;
11966                 regcm = info.regcm;
11967                 /* Walk through the uses of ins and do a pre_copy or see if a post_copy is warranted */
11968                 for(entry = ins->use; entry; entry = next) {
11969                         struct reg_info rinfo;
11970                         int i;
11971                         next = entry->next;
11972                         i = find_rhs_use(state, entry->member, ins);
11973                         if (i < 0) {
11974                                 continue;
11975                         }
11976                         
11977                         /* Find the users color requirements */
11978                         rinfo = arch_reg_rhs(state, entry->member, i);
11979                         if (rinfo.reg >= MAX_REGISTERS) {
11980                                 rinfo.reg = REG_UNSET;
11981                         }
11982
11983                         /* Now see if it is time to do the pre_copy */
11984                         if (rinfo.reg != REG_UNSET) {
11985                                 if (((reg != REG_UNSET) && (reg != rinfo.reg)) ||
11986                                         ((regcm & rinfo.regcm) == 0) ||
11987                                         /* Don't let a mandatory coalesce sneak
11988                                          * into a operation that is marked to prevent
11989                                          * coalescing.
11990                                          */
11991                                         ((reg != REG_UNNEEDED) &&
11992                                         ((ins->id & TRIPLE_FLAG_POST_SPLIT) ||
11993                                         (entry->member->id & TRIPLE_FLAG_PRE_SPLIT)))
11994                                         ) {
11995                                         if (do_pre_copy) {
11996                                                 struct triple *user;
11997                                                 user = entry->member;
11998                                                 if (RHS(user, i) != ins) {
11999                                                         internal_error(state, user, "bad rhs");
12000                                                 }
12001                                                 tmp = pre_copy(state, user, i);
12002                                                 tmp->id |= TRIPLE_FLAG_PRE_SPLIT;
12003                                                 continue;
12004                                         } else {
12005                                                 do_post_copy = 1;
12006                                         }
12007                                 }
12008                                 reg = rinfo.reg;
12009                         }
12010                         if ((regcm & rinfo.regcm) == 0) {
12011                                 if (do_pre_copy) {
12012                                         struct triple *user;
12013                                         user = entry->member;
12014                                         if (RHS(user, i) != ins) {
12015                                                 internal_error(state, user, "bad rhs");
12016                                         }
12017                                         tmp = pre_copy(state, user, i);
12018                                         tmp->id |= TRIPLE_FLAG_PRE_SPLIT;
12019                                         continue;
12020                                 } else {
12021                                         do_post_copy = 1;
12022                                 }
12023                         }
12024                         regcm &= rinfo.regcm;
12025                         
12026                 }
12027                 if (do_post_copy) {
12028                         struct reg_info pre, post;
12029                         tmp = post_copy(state, ins);
12030                         tmp->id |= TRIPLE_FLAG_PRE_SPLIT;
12031                         pre = arch_reg_lhs(state, ins, 0);
12032                         post = arch_reg_lhs(state, tmp, 0);
12033                         if ((pre.reg == post.reg) && (pre.regcm == post.regcm)) {
12034                                 internal_error(state, tmp, "useless copy");
12035                         }
12036                 }
12037         next:
12038                 ins = ins->next;
12039         } while(ins != first);
12040 }
12041
12042
12043 struct live_range_edge;
12044 struct live_range_def;
12045 struct live_range {
12046         struct live_range_edge *edges;
12047         struct live_range_def *defs;
12048 /* Note. The list pointed to by defs is kept in order.
12049  * That is baring splits in the flow control
12050  * defs dominates defs->next wich dominates defs->next->next
12051  * etc.
12052  */
12053         unsigned color;
12054         unsigned classes;
12055         unsigned degree;
12056         unsigned length;
12057         struct live_range *group_next, **group_prev;
12058 };
12059
12060 struct live_range_edge {
12061         struct live_range_edge *next;
12062         struct live_range *node;
12063 };
12064
12065 struct live_range_def {
12066         struct live_range_def *next;
12067         struct live_range_def *prev;
12068         struct live_range *lr;
12069         struct triple *def;
12070         unsigned orig_id;
12071 };
12072
12073 #define LRE_HASH_SIZE 2048
12074 struct lre_hash {
12075         struct lre_hash *next;
12076         struct live_range *left;
12077         struct live_range *right;
12078 };
12079
12080
12081 struct reg_state {
12082         struct lre_hash *hash[LRE_HASH_SIZE];
12083         struct reg_block *blocks;
12084         struct live_range_def *lrd;
12085         struct live_range *lr;
12086         struct live_range *low, **low_tail;
12087         struct live_range *high, **high_tail;
12088         unsigned defs;
12089         unsigned ranges;
12090         int passes, max_passes;
12091 #define MAX_ALLOCATION_PASSES 100
12092 };
12093
12094
12095
12096 struct print_interference_block_info {
12097         struct reg_state *rstate;
12098         FILE *fp;
12099         int need_edges;
12100 };
12101 static void print_interference_block(
12102         struct compile_state *state, struct block *block, void *arg)
12103
12104 {
12105         struct print_interference_block_info *info = arg;
12106         struct reg_state *rstate = info->rstate;
12107         FILE *fp = info->fp;
12108         struct reg_block *rb;
12109         struct triple *ptr;
12110         int phi_present;
12111         int done;
12112         rb = &rstate->blocks[block->vertex];
12113
12114         fprintf(fp, "\nblock: %p (%d), %p<-%p %p<-%p\n", 
12115                 block, 
12116                 block->vertex,
12117                 block->left, 
12118                 block->left && block->left->use?block->left->use->member : 0,
12119                 block->right, 
12120                 block->right && block->right->use?block->right->use->member : 0);
12121         if (rb->in) {
12122                 struct triple_reg_set *in_set;
12123                 fprintf(fp, "        in:");
12124                 for(in_set = rb->in; in_set; in_set = in_set->next) {
12125                         fprintf(fp, " %-10p", in_set->member);
12126                 }
12127                 fprintf(fp, "\n");
12128         }
12129         phi_present = 0;
12130         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
12131                 done = (ptr == block->last);
12132                 if (ptr->op == OP_PHI) {
12133                         phi_present = 1;
12134                         break;
12135                 }
12136         }
12137         if (phi_present) {
12138                 int edge;
12139                 for(edge = 0; edge < block->users; edge++) {
12140                         fprintf(fp, "     in(%d):", edge);
12141                         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
12142                                 struct triple **slot;
12143                                 done = (ptr == block->last);
12144                                 if (ptr->op != OP_PHI) {
12145                                         continue;
12146                                 }
12147                                 slot = &RHS(ptr, 0);
12148                                 fprintf(fp, " %-10p", slot[edge]);
12149                         }
12150                         fprintf(fp, "\n");
12151                 }
12152         }
12153         if (block->first->op == OP_LABEL) {
12154                 fprintf(fp, "%p:\n", block->first);
12155         }
12156         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
12157                 struct live_range *lr;
12158                 unsigned id;
12159                 int op;
12160                 op = ptr->op;
12161                 done = (ptr == block->last);
12162                 lr = rstate->lrd[ptr->id].lr;
12163                 
12164                 id = ptr->id;
12165                 ptr->id = rstate->lrd[id].orig_id;
12166                 SET_REG(ptr->id, lr->color);
12167                 display_triple(fp, ptr);
12168                 ptr->id = id;
12169
12170                 if (triple_is_def(state, ptr) && (lr->defs == 0)) {
12171                         internal_error(state, ptr, "lr has no defs!");
12172                 }
12173                 if (info->need_edges) {
12174                         if (lr->defs) {
12175                                 struct live_range_def *lrd;
12176                                 fprintf(fp, "       range:");
12177                                 lrd = lr->defs;
12178                                 do {
12179                                         fprintf(fp, " %-10p", lrd->def);
12180                                         lrd = lrd->next;
12181                                 } while(lrd != lr->defs);
12182                                 fprintf(fp, "\n");
12183                         }
12184                         if (lr->edges > 0) {
12185                                 struct live_range_edge *edge;
12186                                 fprintf(fp, "       edges:");
12187                                 for(edge = lr->edges; edge; edge = edge->next) {
12188                                         struct live_range_def *lrd;
12189                                         lrd = edge->node->defs;
12190                                         do {
12191                                                 fprintf(fp, " %-10p", lrd->def);
12192                                                 lrd = lrd->next;
12193                                         } while(lrd != edge->node->defs);
12194                                         fprintf(fp, "|");
12195                                 }
12196                                 fprintf(fp, "\n");
12197                         }
12198                 }
12199                 /* Do a bunch of sanity checks */
12200                 valid_ins(state, ptr);
12201                 if ((ptr->id < 0) || (ptr->id > rstate->defs)) {
12202                         internal_error(state, ptr, "Invalid triple id: %d",
12203                                 ptr->id);
12204                 }
12205         }
12206         if (rb->out) {
12207                 struct triple_reg_set *out_set;
12208                 fprintf(fp, "       out:");
12209                 for(out_set = rb->out; out_set; out_set = out_set->next) {
12210                         fprintf(fp, " %-10p", out_set->member);
12211                 }
12212                 fprintf(fp, "\n");
12213         }
12214         fprintf(fp, "\n");
12215 }
12216
12217 static void print_interference_blocks(
12218         struct compile_state *state, struct reg_state *rstate, FILE *fp, int need_edges)
12219 {
12220         struct print_interference_block_info info;
12221         info.rstate = rstate;
12222         info.fp = fp;
12223         info.need_edges = need_edges;
12224         fprintf(fp, "\nlive variables by block\n");
12225         walk_blocks(state, print_interference_block, &info);
12226
12227 }
12228
12229 static unsigned regc_max_size(struct compile_state *state, int classes)
12230 {
12231         unsigned max_size;
12232         int i;
12233         max_size = 0;
12234         for(i = 0; i < MAX_REGC; i++) {
12235                 if (classes & (1 << i)) {
12236                         unsigned size;
12237                         size = arch_regc_size(state, i);
12238                         if (size > max_size) {
12239                                 max_size = size;
12240                         }
12241                 }
12242         }
12243         return max_size;
12244 }
12245
12246 static int reg_is_reg(struct compile_state *state, int reg1, int reg2)
12247 {
12248         unsigned equivs[MAX_REG_EQUIVS];
12249         int i;
12250         if ((reg1 < 0) || (reg1 >= MAX_REGISTERS)) {
12251                 internal_error(state, 0, "invalid register");
12252         }
12253         if ((reg2 < 0) || (reg2 >= MAX_REGISTERS)) {
12254                 internal_error(state, 0, "invalid register");
12255         }
12256         arch_reg_equivs(state, equivs, reg1);
12257         for(i = 0; (i < MAX_REG_EQUIVS) && equivs[i] != REG_UNSET; i++) {
12258                 if (equivs[i] == reg2) {
12259                         return 1;
12260                 }
12261         }
12262         return 0;
12263 }
12264
12265 static void reg_fill_used(struct compile_state *state, char *used, int reg)
12266 {
12267         unsigned equivs[MAX_REG_EQUIVS];
12268         int i;
12269         if (reg == REG_UNNEEDED) {
12270                 return;
12271         }
12272         arch_reg_equivs(state, equivs, reg);
12273         for(i = 0; (i < MAX_REG_EQUIVS) && equivs[i] != REG_UNSET; i++) {
12274                 used[equivs[i]] = 1;
12275         }
12276         return;
12277 }
12278
12279 static void reg_inc_used(struct compile_state *state, char *used, int reg)
12280 {
12281         unsigned equivs[MAX_REG_EQUIVS];
12282         int i;
12283         if (reg == REG_UNNEEDED) {
12284                 return;
12285         }
12286         arch_reg_equivs(state, equivs, reg);
12287         for(i = 0; (i < MAX_REG_EQUIVS) && equivs[i] != REG_UNSET; i++) {
12288                 used[equivs[i]] += 1;
12289         }
12290         return;
12291 }
12292
12293 static unsigned int hash_live_edge(
12294         struct live_range *left, struct live_range *right)
12295 {
12296         unsigned int hash, val;
12297         unsigned long lval, rval;
12298         lval = ((unsigned long)left)/sizeof(struct live_range);
12299         rval = ((unsigned long)right)/sizeof(struct live_range);
12300         hash = 0;
12301         while(lval) {
12302                 val = lval & 0xff;
12303                 lval >>= 8;
12304                 hash = (hash *263) + val;
12305         }
12306         while(rval) {
12307                 val = rval & 0xff;
12308                 rval >>= 8;
12309                 hash = (hash *263) + val;
12310         }
12311         hash = hash & (LRE_HASH_SIZE - 1);
12312         return hash;
12313 }
12314
12315 static struct lre_hash **lre_probe(struct reg_state *rstate,
12316         struct live_range *left, struct live_range *right)
12317 {
12318         struct lre_hash **ptr;
12319         unsigned int index;
12320         /* Ensure left <= right */
12321         if (left > right) {
12322                 struct live_range *tmp;
12323                 tmp = left;
12324                 left = right;
12325                 right = tmp;
12326         }
12327         index = hash_live_edge(left, right);
12328         
12329         ptr = &rstate->hash[index];
12330         while(*ptr) {
12331                 if (((*ptr)->left == left) && ((*ptr)->right == right)) {
12332                         break;
12333                 }
12334                 ptr = &(*ptr)->next;
12335         }
12336         return ptr;
12337 }
12338
12339 static int interfere(struct reg_state *rstate,
12340         struct live_range *left, struct live_range *right)
12341 {
12342         struct lre_hash **ptr;
12343         ptr = lre_probe(rstate, left, right);
12344         return ptr && *ptr;
12345 }
12346
12347 static void add_live_edge(struct reg_state *rstate, 
12348         struct live_range *left, struct live_range *right)
12349 {
12350         /* FIXME the memory allocation overhead is noticeable here... */
12351         struct lre_hash **ptr, *new_hash;
12352         struct live_range_edge *edge;
12353
12354         if (left == right) {
12355                 return;
12356         }
12357         if ((left == &rstate->lr[0]) || (right == &rstate->lr[0])) {
12358                 return;
12359         }
12360         /* Ensure left <= right */
12361         if (left > right) {
12362                 struct live_range *tmp;
12363                 tmp = left;
12364                 left = right;
12365                 right = tmp;
12366         }
12367         ptr = lre_probe(rstate, left, right);
12368         if (*ptr) {
12369                 return;
12370         }
12371 #if 0
12372         fprintf(stderr, "new_live_edge(%p, %p)\n",
12373                 left, right);
12374 #endif
12375         new_hash = xmalloc(sizeof(*new_hash), "lre_hash");
12376         new_hash->next  = *ptr;
12377         new_hash->left  = left;
12378         new_hash->right = right;
12379         *ptr = new_hash;
12380
12381         edge = xmalloc(sizeof(*edge), "live_range_edge");
12382         edge->next   = left->edges;
12383         edge->node   = right;
12384         left->edges  = edge;
12385         left->degree += 1;
12386         
12387         edge = xmalloc(sizeof(*edge), "live_range_edge");
12388         edge->next    = right->edges;
12389         edge->node    = left;
12390         right->edges  = edge;
12391         right->degree += 1;
12392 }
12393
12394 static void remove_live_edge(struct reg_state *rstate,
12395         struct live_range *left, struct live_range *right)
12396 {
12397         struct live_range_edge *edge, **ptr;
12398         struct lre_hash **hptr, *entry;
12399         hptr = lre_probe(rstate, left, right);
12400         if (!hptr || !*hptr) {
12401                 return;
12402         }
12403         entry = *hptr;
12404         *hptr = entry->next;
12405         xfree(entry);
12406
12407         for(ptr = &left->edges; *ptr; ptr = &(*ptr)->next) {
12408                 edge = *ptr;
12409                 if (edge->node == right) {
12410                         *ptr = edge->next;
12411                         memset(edge, 0, sizeof(*edge));
12412                         xfree(edge);
12413                         right->degree--;
12414                         break;
12415                 }
12416         }
12417         for(ptr = &right->edges; *ptr; ptr = &(*ptr)->next) {
12418                 edge = *ptr;
12419                 if (edge->node == left) {
12420                         *ptr = edge->next;
12421                         memset(edge, 0, sizeof(*edge));
12422                         xfree(edge);
12423                         left->degree--;
12424                         break;
12425                 }
12426         }
12427 }
12428
12429 static void remove_live_edges(struct reg_state *rstate, struct live_range *range)
12430 {
12431         struct live_range_edge *edge, *next;
12432         for(edge = range->edges; edge; edge = next) {
12433                 next = edge->next;
12434                 remove_live_edge(rstate, range, edge->node);
12435         }
12436 }
12437
12438 static void transfer_live_edges(struct reg_state *rstate, 
12439         struct live_range *dest, struct live_range *src)
12440 {
12441         struct live_range_edge *edge, *next;
12442         for(edge = src->edges; edge; edge = next) {
12443                 struct live_range *other;
12444                 next = edge->next;
12445                 other = edge->node;
12446                 remove_live_edge(rstate, src, other);
12447                 add_live_edge(rstate, dest, other);
12448         }
12449 }
12450
12451
12452 /* Interference graph...
12453  * 
12454  * new(n) --- Return a graph with n nodes but no edges.
12455  * add(g,x,y) --- Return a graph including g with an between x and y
12456  * interfere(g, x, y) --- Return true if there exists an edge between the nodes
12457  *                x and y in the graph g
12458  * degree(g, x) --- Return the degree of the node x in the graph g
12459  * neighbors(g, x, f) --- Apply function f to each neighbor of node x in the graph g
12460  *
12461  * Implement with a hash table && a set of adjcency vectors.
12462  * The hash table supports constant time implementations of add and interfere.
12463  * The adjacency vectors support an efficient implementation of neighbors.
12464  */
12465
12466 /* 
12467  *     +---------------------------------------------------+
12468  *     |         +--------------+                          |
12469  *     v         v              |                          |
12470  * renumber -> build graph -> colalesce -> spill_costs -> simplify -> select 
12471  *
12472  * -- In simplify implment optimistic coloring... (No backtracking)
12473  * -- Implement Rematerialization it is the only form of spilling we can perform
12474  *    Essentially this means dropping a constant from a register because
12475  *    we can regenerate it later.
12476  *
12477  * --- Very conservative colalescing (don't colalesce just mark the opportunities)
12478  *     coalesce at phi points...
12479  * --- Bias coloring if at all possible do the coalesing a compile time.
12480  *
12481  *
12482  */
12483
12484 static void different_colored(
12485         struct compile_state *state, struct reg_state *rstate, 
12486         struct triple *parent, struct triple *ins)
12487 {
12488         struct live_range *lr;
12489         struct triple **expr;
12490         lr = rstate->lrd[ins->id].lr;
12491         expr = triple_rhs(state, ins, 0);
12492         for(;expr; expr = triple_rhs(state, ins, expr)) {
12493                 struct live_range *lr2;
12494                 if (!*expr || (*expr == parent) || (*expr == ins)) {
12495                         continue;
12496                 }
12497                 lr2 = rstate->lrd[(*expr)->id].lr;
12498                 if (lr->color == lr2->color) {
12499                         internal_error(state, ins, "live range too big");
12500                 }
12501         }
12502 }
12503
12504
12505 static struct live_range *coalesce_ranges(
12506         struct compile_state *state, struct reg_state *rstate,
12507         struct live_range *lr1, struct live_range *lr2)
12508 {
12509         struct live_range_def *head, *mid1, *mid2, *end, *lrd;
12510         unsigned color;
12511         unsigned classes;
12512         if (lr1 == lr2) {
12513                 return lr1;
12514         }
12515         if (!lr1->defs || !lr2->defs) {
12516                 internal_error(state, 0,
12517                         "cannot coalese dead live ranges");
12518         }
12519         if ((lr1->color == REG_UNNEEDED) ||
12520                 (lr2->color == REG_UNNEEDED)) {
12521                 internal_error(state, 0, 
12522                         "cannot coalesce live ranges without a possible color");
12523         }
12524         if ((lr1->color != lr2->color) &&
12525                 (lr1->color != REG_UNSET) &&
12526                 (lr2->color != REG_UNSET)) {
12527                 internal_error(state, lr1->defs->def, 
12528                         "cannot coalesce live ranges of different colors");
12529         }
12530         color = lr1->color;
12531         if (color == REG_UNSET) {
12532                 color = lr2->color;
12533         }
12534         classes = lr1->classes & lr2->classes;
12535         if (!classes) {
12536                 internal_error(state, lr1->defs->def,
12537                         "cannot coalesce live ranges with dissimilar register classes");
12538         }
12539 #if DEBUG_COALESCING
12540         fprintf(stderr, "coalescing:");
12541         lrd = lr1->defs;
12542         do {
12543                 fprintf(stderr, " %p", lrd->def);
12544                 lrd = lrd->next;
12545         } while(lrd != lr1->defs);
12546         fprintf(stderr, " |");
12547         lrd = lr2->defs;
12548         do {
12549                 fprintf(stderr, " %p", lrd->def);
12550                 lrd = lrd->next;
12551         } while(lrd != lr2->defs);
12552         fprintf(stderr, "\n");
12553 #endif
12554         /* If there is a clear dominate live range put it in lr1,
12555          * For purposes of this test phi functions are
12556          * considered dominated by the definitions that feed into
12557          * them. 
12558          */
12559         if ((lr1->defs->prev->def->op == OP_PHI) ||
12560                 ((lr2->defs->prev->def->op != OP_PHI) &&
12561                 tdominates(state, lr2->defs->def, lr1->defs->def))) {
12562                 struct live_range *tmp;
12563                 tmp = lr1;
12564                 lr1 = lr2;
12565                 lr2 = tmp;
12566         }
12567 #if 0
12568         if (lr1->defs->orig_id  & TRIPLE_FLAG_POST_SPLIT) {
12569                 fprintf(stderr, "lr1 post\n");
12570         }
12571         if (lr1->defs->orig_id & TRIPLE_FLAG_PRE_SPLIT) {
12572                 fprintf(stderr, "lr1 pre\n");
12573         }
12574         if (lr2->defs->orig_id  & TRIPLE_FLAG_POST_SPLIT) {
12575                 fprintf(stderr, "lr2 post\n");
12576         }
12577         if (lr2->defs->orig_id & TRIPLE_FLAG_PRE_SPLIT) {
12578                 fprintf(stderr, "lr2 pre\n");
12579         }
12580 #endif
12581 #if 0
12582         fprintf(stderr, "coalesce color1(%p): %3d color2(%p) %3d\n",
12583                 lr1->defs->def,
12584                 lr1->color,
12585                 lr2->defs->def,
12586                 lr2->color);
12587 #endif
12588         
12589         /* Append lr2 onto lr1 */
12590 #warning "FIXME should this be a merge instead of a splice?"
12591         /* This FIXME item applies to the correctness of live_range_end 
12592          * and to the necessity of making multiple passes of coalesce_live_ranges.
12593          * A failure to find some coalesce opportunities in coaleace_live_ranges
12594          * does not impact the correct of the compiler just the efficiency with
12595          * which registers are allocated.
12596          */
12597         head = lr1->defs;
12598         mid1 = lr1->defs->prev;
12599         mid2 = lr2->defs;
12600         end  = lr2->defs->prev;
12601         
12602         head->prev = end;
12603         end->next  = head;
12604
12605         mid1->next = mid2;
12606         mid2->prev = mid1;
12607
12608         /* Fixup the live range in the added live range defs */
12609         lrd = head;
12610         do {
12611                 lrd->lr = lr1;
12612                 lrd = lrd->next;
12613         } while(lrd != head);
12614
12615         /* Mark lr2 as free. */
12616         lr2->defs = 0;
12617         lr2->color = REG_UNNEEDED;
12618         lr2->classes = 0;
12619
12620         if (!lr1->defs) {
12621                 internal_error(state, 0, "lr1->defs == 0 ?");
12622         }
12623
12624         lr1->color   = color;
12625         lr1->classes = classes;
12626
12627         /* Keep the graph in sync by transfering the edges from lr2 to lr1 */
12628         transfer_live_edges(rstate, lr1, lr2);
12629
12630         return lr1;
12631 }
12632
12633 static struct live_range_def *live_range_head(
12634         struct compile_state *state, struct live_range *lr,
12635         struct live_range_def *last)
12636 {
12637         struct live_range_def *result;
12638         result = 0;
12639         if (last == 0) {
12640                 result = lr->defs;
12641         }
12642         else if (!tdominates(state, lr->defs->def, last->next->def)) {
12643                 result = last->next;
12644         }
12645         return result;
12646 }
12647
12648 static struct live_range_def *live_range_end(
12649         struct compile_state *state, struct live_range *lr,
12650         struct live_range_def *last)
12651 {
12652         struct live_range_def *result;
12653         result = 0;
12654         if (last == 0) {
12655                 result = lr->defs->prev;
12656         }
12657         else if (!tdominates(state, last->prev->def, lr->defs->prev->def)) {
12658                 result = last->prev;
12659         }
12660         return result;
12661 }
12662
12663
12664 static void initialize_live_ranges(
12665         struct compile_state *state, struct reg_state *rstate)
12666 {
12667         struct triple *ins, *first;
12668         size_t count, size;
12669         int i, j;
12670
12671         first = RHS(state->main_function, 0);
12672         /* First count how many instructions I have.
12673          */
12674         count = count_triples(state);
12675         /* Potentially I need one live range definitions for each
12676          * instruction.
12677          */
12678         rstate->defs = count;
12679         /* Potentially I need one live range for each instruction
12680          * plus an extra for the dummy live range.
12681          */
12682         rstate->ranges = count + 1;
12683         size = sizeof(rstate->lrd[0]) * rstate->defs;
12684         rstate->lrd = xcmalloc(size, "live_range_def");
12685         size = sizeof(rstate->lr[0]) * rstate->ranges;
12686         rstate->lr  = xcmalloc(size, "live_range");
12687
12688         /* Setup the dummy live range */
12689         rstate->lr[0].classes = 0;
12690         rstate->lr[0].color = REG_UNSET;
12691         rstate->lr[0].defs = 0;
12692         i = j = 0;
12693         ins = first;
12694         do {
12695                 /* If the triple is a variable give it a live range */
12696                 if (triple_is_def(state, ins)) {
12697                         struct reg_info info;
12698                         /* Find the architecture specific color information */
12699                         info = find_def_color(state, ins);
12700                         i++;
12701                         rstate->lr[i].defs    = &rstate->lrd[j];
12702                         rstate->lr[i].color   = info.reg;
12703                         rstate->lr[i].classes = info.regcm;
12704                         rstate->lr[i].degree  = 0;
12705                         rstate->lrd[j].lr = &rstate->lr[i];
12706                 } 
12707                 /* Otherwise give the triple the dummy live range. */
12708                 else {
12709                         rstate->lrd[j].lr = &rstate->lr[0];
12710                 }
12711
12712                 /* Initalize the live_range_def */
12713                 rstate->lrd[j].next    = &rstate->lrd[j];
12714                 rstate->lrd[j].prev    = &rstate->lrd[j];
12715                 rstate->lrd[j].def     = ins;
12716                 rstate->lrd[j].orig_id = ins->id;
12717                 ins->id = j;
12718
12719                 j++;
12720                 ins = ins->next;
12721         } while(ins != first);
12722         rstate->ranges = i;
12723
12724         /* Make a second pass to handle achitecture specific register
12725          * constraints.
12726          */
12727         ins = first;
12728         do {
12729                 int zlhs, zrhs, i, j;
12730                 if (ins->id > rstate->defs) {
12731                         internal_error(state, ins, "bad id");
12732                 }
12733                 
12734                 /* Walk through the template of ins and coalesce live ranges */
12735                 zlhs = TRIPLE_LHS(ins->sizes);
12736                 if ((zlhs == 0) && triple_is_def(state, ins)) {
12737                         zlhs = 1;
12738                 }
12739                 zrhs = TRIPLE_RHS(ins->sizes);
12740
12741 #if DEBUG_COALESCING > 1
12742                 fprintf(stderr, "mandatory coalesce: %p %d %d\n",
12743                         ins, zlhs, zrhs);
12744 #endif          
12745                 for(i = 0; i < zlhs; i++) {
12746                         struct reg_info linfo;
12747                         struct live_range_def *lhs;
12748                         linfo = arch_reg_lhs(state, ins, i);
12749                         if (linfo.reg < MAX_REGISTERS) {
12750                                 continue;
12751                         }
12752                         if (triple_is_def(state, ins)) {
12753                                 lhs = &rstate->lrd[ins->id];
12754                         } else {
12755                                 lhs = &rstate->lrd[LHS(ins, i)->id];
12756                         }
12757 #if DEBUG_COALESCING > 1
12758                         fprintf(stderr, "coalesce lhs(%d): %p %d\n",
12759                                 i, lhs, linfo.reg);
12760                 
12761 #endif          
12762                         for(j = 0; j < zrhs; j++) {
12763                                 struct reg_info rinfo;
12764                                 struct live_range_def *rhs;
12765                                 rinfo = arch_reg_rhs(state, ins, j);
12766                                 if (rinfo.reg < MAX_REGISTERS) {
12767                                         continue;
12768                                 }
12769                                 rhs = &rstate->lrd[RHS(ins, j)->id];
12770 #if DEBUG_COALESCING > 1
12771                                 fprintf(stderr, "coalesce rhs(%d): %p %d\n",
12772                                         j, rhs, rinfo.reg);
12773                 
12774 #endif          
12775                                 if (rinfo.reg == linfo.reg) {
12776                                         coalesce_ranges(state, rstate, 
12777                                                 lhs->lr, rhs->lr);
12778                                 }
12779                         }
12780                 }
12781                 ins = ins->next;
12782         } while(ins != first);
12783 }
12784
12785 static void graph_ins(
12786         struct compile_state *state, 
12787         struct reg_block *blocks, struct triple_reg_set *live, 
12788         struct reg_block *rb, struct triple *ins, void *arg)
12789 {
12790         struct reg_state *rstate = arg;
12791         struct live_range *def;
12792         struct triple_reg_set *entry;
12793
12794         /* If the triple is not a definition
12795          * we do not have a definition to add to
12796          * the interference graph.
12797          */
12798         if (!triple_is_def(state, ins)) {
12799                 return;
12800         }
12801         def = rstate->lrd[ins->id].lr;
12802         
12803         /* Create an edge between ins and everything that is
12804          * alive, unless the live_range cannot share
12805          * a physical register with ins.
12806          */
12807         for(entry = live; entry; entry = entry->next) {
12808                 struct live_range *lr;
12809                 if ((entry->member->id < 0) || (entry->member->id > rstate->defs)) {
12810                         internal_error(state, 0, "bad entry?");
12811                 }
12812                 lr = rstate->lrd[entry->member->id].lr;
12813                 if (def == lr) {
12814                         continue;
12815                 }
12816                 if (!arch_regcm_intersect(def->classes, lr->classes)) {
12817                         continue;
12818                 }
12819                 add_live_edge(rstate, def, lr);
12820         }
12821         return;
12822 }
12823
12824 static struct live_range *get_verify_live_range(
12825         struct compile_state *state, struct reg_state *rstate, struct triple *ins)
12826 {
12827         struct live_range *lr;
12828         struct live_range_def *lrd;
12829         int ins_found;
12830         if ((ins->id < 0) || (ins->id > rstate->defs)) {
12831                 internal_error(state, ins, "bad ins?");
12832         }
12833         lr = rstate->lrd[ins->id].lr;
12834         ins_found = 0;
12835         lrd = lr->defs;
12836         do {
12837                 if (lrd->def == ins) {
12838                         ins_found = 1;
12839                 }
12840                 lrd = lrd->next;
12841         } while(lrd != lr->defs);
12842         if (!ins_found) {
12843                 internal_error(state, ins, "ins not in live range");
12844         }
12845         return lr;
12846 }
12847
12848 static void verify_graph_ins(
12849         struct compile_state *state, 
12850         struct reg_block *blocks, struct triple_reg_set *live, 
12851         struct reg_block *rb, struct triple *ins, void *arg)
12852 {
12853         struct reg_state *rstate = arg;
12854         struct triple_reg_set *entry1, *entry2;
12855
12856
12857         /* Compare live against edges and make certain the code is working */
12858         for(entry1 = live; entry1; entry1 = entry1->next) {
12859                 struct live_range *lr1;
12860                 lr1 = get_verify_live_range(state, rstate, entry1->member);
12861                 for(entry2 = live; entry2; entry2 = entry2->next) {
12862                         struct live_range *lr2;
12863                         struct live_range_edge *edge2;
12864                         int lr1_found;
12865                         int lr2_degree;
12866                         if (entry2 == entry1) {
12867                                 continue;
12868                         }
12869                         lr2 = get_verify_live_range(state, rstate, entry2->member);
12870                         if (lr1 == lr2) {
12871                                 internal_error(state, entry2->member, 
12872                                         "live range with 2 values simultaneously alive");
12873                         }
12874                         if (!arch_regcm_intersect(lr1->classes, lr2->classes)) {
12875                                 continue;
12876                         }
12877                         if (!interfere(rstate, lr1, lr2)) {
12878                                 internal_error(state, entry2->member, 
12879                                         "edges don't interfere?");
12880                         }
12881                                 
12882                         lr1_found = 0;
12883                         lr2_degree = 0;
12884                         for(edge2 = lr2->edges; edge2; edge2 = edge2->next) {
12885                                 lr2_degree++;
12886                                 if (edge2->node == lr1) {
12887                                         lr1_found = 1;
12888                                 }
12889                         }
12890                         if (lr2_degree != lr2->degree) {
12891                                 internal_error(state, entry2->member,
12892                                         "computed degree: %d does not match reported degree: %d\n",
12893                                         lr2_degree, lr2->degree);
12894                         }
12895                         if (!lr1_found) {
12896                                 internal_error(state, entry2->member, "missing edge");
12897                         }
12898                 }
12899         }
12900         return;
12901 }
12902
12903
12904 static void print_interference_ins(
12905         struct compile_state *state, 
12906         struct reg_block *blocks, struct triple_reg_set *live, 
12907         struct reg_block *rb, struct triple *ins, void *arg)
12908 {
12909         struct reg_state *rstate = arg;
12910         struct live_range *lr;
12911         unsigned id;
12912
12913         lr = rstate->lrd[ins->id].lr;
12914         id = ins->id;
12915         ins->id = rstate->lrd[id].orig_id;
12916         SET_REG(ins->id, lr->color);
12917         display_triple(stdout, ins);
12918         ins->id = id;
12919
12920         if (lr->defs) {
12921                 struct live_range_def *lrd;
12922                 printf("       range:");
12923                 lrd = lr->defs;
12924                 do {
12925                         printf(" %-10p", lrd->def);
12926                         lrd = lrd->next;
12927                 } while(lrd != lr->defs);
12928                 printf("\n");
12929         }
12930         if (live) {
12931                 struct triple_reg_set *entry;
12932                 printf("        live:");
12933                 for(entry = live; entry; entry = entry->next) {
12934                         printf(" %-10p", entry->member);
12935                 }
12936                 printf("\n");
12937         }
12938         if (lr->edges) {
12939                 struct live_range_edge *entry;
12940                 printf("       edges:");
12941                 for(entry = lr->edges; entry; entry = entry->next) {
12942                         struct live_range_def *lrd;
12943                         lrd = entry->node->defs;
12944                         do {
12945                                 printf(" %-10p", lrd->def);
12946                                 lrd = lrd->next;
12947                         } while(lrd != entry->node->defs);
12948                         printf("|");
12949                 }
12950                 printf("\n");
12951         }
12952         if (triple_is_branch(state, ins)) {
12953                 printf("\n");
12954         }
12955         return;
12956 }
12957
12958 static int coalesce_live_ranges(
12959         struct compile_state *state, struct reg_state *rstate)
12960 {
12961         /* At the point where a value is moved from one
12962          * register to another that value requires two
12963          * registers, thus increasing register pressure.
12964          * Live range coaleescing reduces the register
12965          * pressure by keeping a value in one register
12966          * longer.
12967          *
12968          * In the case of a phi function all paths leading
12969          * into it must be allocated to the same register
12970          * otherwise the phi function may not be removed.
12971          *
12972          * Forcing a value to stay in a single register
12973          * for an extended period of time does have
12974          * limitations when applied to non homogenous
12975          * register pool.  
12976          *
12977          * The two cases I have identified are:
12978          * 1) Two forced register assignments may
12979          *    collide.
12980          * 2) Registers may go unused because they
12981          *    are only good for storing the value
12982          *    and not manipulating it.
12983          *
12984          * Because of this I need to split live ranges,
12985          * even outside of the context of coalesced live
12986          * ranges.  The need to split live ranges does
12987          * impose some constraints on live range coalescing.
12988          *
12989          * - Live ranges may not be coalesced across phi
12990          *   functions.  This creates a 2 headed live
12991          *   range that cannot be sanely split.
12992          *
12993          * - phi functions (coalesced in initialize_live_ranges) 
12994          *   are handled as pre split live ranges so we will
12995          *   never attempt to split them.
12996          */
12997         int coalesced;
12998         int i;
12999
13000         coalesced = 0;
13001         for(i = 0; i <= rstate->ranges; i++) {
13002                 struct live_range *lr1;
13003                 struct live_range_def *lrd1;
13004                 lr1 = &rstate->lr[i];
13005                 if (!lr1->defs) {
13006                         continue;
13007                 }
13008                 lrd1 = live_range_end(state, lr1, 0);
13009                 for(; lrd1; lrd1 = live_range_end(state, lr1, lrd1)) {
13010                         struct triple_set *set;
13011                         if (lrd1->def->op != OP_COPY) {
13012                                 continue;
13013                         }
13014                         /* Skip copies that are the result of a live range split. */
13015                         if (lrd1->orig_id & TRIPLE_FLAG_POST_SPLIT) {
13016                                 continue;
13017                         }
13018                         for(set = lrd1->def->use; set; set = set->next) {
13019                                 struct live_range_def *lrd2;
13020                                 struct live_range *lr2, *res;
13021
13022                                 lrd2 = &rstate->lrd[set->member->id];
13023
13024                                 /* Don't coalesce with instructions
13025                                  * that are the result of a live range
13026                                  * split.
13027                                  */
13028                                 if (lrd2->orig_id & TRIPLE_FLAG_PRE_SPLIT) {
13029                                         continue;
13030                                 }
13031                                 lr2 = rstate->lrd[set->member->id].lr;
13032                                 if (lr1 == lr2) {
13033                                         continue;
13034                                 }
13035                                 if ((lr1->color != lr2->color) &&
13036                                         (lr1->color != REG_UNSET) &&
13037                                         (lr2->color != REG_UNSET)) {
13038                                         continue;
13039                                 }
13040                                 if ((lr1->classes & lr2->classes) == 0) {
13041                                         continue;
13042                                 }
13043                                 
13044                                 if (interfere(rstate, lr1, lr2)) {
13045                                         continue;
13046                                 }
13047
13048                                 res = coalesce_ranges(state, rstate, lr1, lr2);
13049                                 coalesced += 1;
13050                                 if (res != lr1) {
13051                                         goto next;
13052                                 }
13053                         }
13054                 }
13055         next:
13056                 ;
13057         }
13058         return coalesced;
13059 }
13060
13061
13062 static void fix_coalesce_conflicts(struct compile_state *state,
13063         struct reg_block *blocks, struct triple_reg_set *live,
13064         struct reg_block *rb, struct triple *ins, void *arg)
13065 {
13066         int *conflicts = arg;
13067         int zlhs, zrhs, i, j;
13068
13069         /* See if we have a mandatory coalesce operation between
13070          * a lhs and a rhs value.  If so and the rhs value is also
13071          * alive then this triple needs to be pre copied.  Otherwise
13072          * we would have two definitions in the same live range simultaneously
13073          * alive.
13074          */
13075         zlhs = TRIPLE_LHS(ins->sizes);
13076         if ((zlhs == 0) && triple_is_def(state, ins)) {
13077                 zlhs = 1;
13078         }
13079         zrhs = TRIPLE_RHS(ins->sizes);
13080         for(i = 0; i < zlhs; i++) {
13081                 struct reg_info linfo;
13082                 linfo = arch_reg_lhs(state, ins, i);
13083                 if (linfo.reg < MAX_REGISTERS) {
13084                         continue;
13085                 }
13086                 for(j = 0; j < zrhs; j++) {
13087                         struct reg_info rinfo;
13088                         struct triple *rhs;
13089                         struct triple_reg_set *set;
13090                         int found;
13091                         found = 0;
13092                         rinfo = arch_reg_rhs(state, ins, j);
13093                         if (rinfo.reg != linfo.reg) {
13094                                 continue;
13095                         }
13096                         rhs = RHS(ins, j);
13097                         for(set = live; set && !found; set = set->next) {
13098                                 if (set->member == rhs) {
13099                                         found = 1;
13100                                 }
13101                         }
13102                         if (found) {
13103                                 struct triple *copy;
13104                                 copy = pre_copy(state, ins, j);
13105                                 copy->id |= TRIPLE_FLAG_PRE_SPLIT;
13106                                 (*conflicts)++;
13107                         }
13108                 }
13109         }
13110         return;
13111 }
13112
13113 static int correct_coalesce_conflicts(
13114         struct compile_state *state, struct reg_block *blocks)
13115 {
13116         int conflicts;
13117         conflicts = 0;
13118         walk_variable_lifetimes(state, blocks, fix_coalesce_conflicts, &conflicts);
13119         return conflicts;
13120 }
13121
13122 static void replace_set_use(struct compile_state *state,
13123         struct triple_reg_set *head, struct triple *orig, struct triple *new)
13124 {
13125         struct triple_reg_set *set;
13126         for(set = head; set; set = set->next) {
13127                 if (set->member == orig) {
13128                         set->member = new;
13129                 }
13130         }
13131 }
13132
13133 static void replace_block_use(struct compile_state *state, 
13134         struct reg_block *blocks, struct triple *orig, struct triple *new)
13135 {
13136         int i;
13137 #warning "WISHLIST visit just those blocks that need it *"
13138         for(i = 1; i <= state->last_vertex; i++) {
13139                 struct reg_block *rb;
13140                 rb = &blocks[i];
13141                 replace_set_use(state, rb->in, orig, new);
13142                 replace_set_use(state, rb->out, orig, new);
13143         }
13144 }
13145
13146 static void color_instructions(struct compile_state *state)
13147 {
13148         struct triple *ins, *first;
13149         first = RHS(state->main_function, 0);
13150         ins = first;
13151         do {
13152                 if (triple_is_def(state, ins)) {
13153                         struct reg_info info;
13154                         info = find_lhs_color(state, ins, 0);
13155                         if (info.reg >= MAX_REGISTERS) {
13156                                 info.reg = REG_UNSET;
13157                         }
13158                         SET_INFO(ins->id, info);
13159                 }
13160                 ins = ins->next;
13161         } while(ins != first);
13162 }
13163
13164 static struct reg_info read_lhs_color(
13165         struct compile_state *state, struct triple *ins, int index)
13166 {
13167         struct reg_info info;
13168         if ((index == 0) && triple_is_def(state, ins)) {
13169                 info.reg   = ID_REG(ins->id);
13170                 info.regcm = ID_REGCM(ins->id);
13171         }
13172         else if (index < TRIPLE_LHS(ins->sizes)) {
13173                 info = read_lhs_color(state, LHS(ins, index), 0);
13174         }
13175         else {
13176                 internal_error(state, ins, "Bad lhs %d", index);
13177                 info.reg = REG_UNSET;
13178                 info.regcm = 0;
13179         }
13180         return info;
13181 }
13182
13183 static struct triple *resolve_tangle(
13184         struct compile_state *state, struct triple *tangle)
13185 {
13186         struct reg_info info, uinfo;
13187         struct triple_set *set, *next;
13188         struct triple *copy;
13189
13190 #warning "WISHLIST recalculate all affected instructions colors"
13191         info = find_lhs_color(state, tangle, 0);
13192         for(set = tangle->use; set; set = next) {
13193                 struct triple *user;
13194                 int i, zrhs;
13195                 next = set->next;
13196                 user = set->member;
13197                 zrhs = TRIPLE_RHS(user->sizes);
13198                 for(i = 0; i < zrhs; i++) {
13199                         if (RHS(user, i) != tangle) {
13200                                 continue;
13201                         }
13202                         uinfo = find_rhs_post_color(state, user, i);
13203                         if (uinfo.reg == info.reg) {
13204                                 copy = pre_copy(state, user, i);
13205                                 copy->id |= TRIPLE_FLAG_PRE_SPLIT;
13206                                 SET_INFO(copy->id, uinfo);
13207                         }
13208                 }
13209         }
13210         copy = 0;
13211         uinfo = find_lhs_pre_color(state, tangle, 0);
13212         if (uinfo.reg == info.reg) {
13213                 struct reg_info linfo;
13214                 copy = post_copy(state, tangle);
13215                 copy->id |= TRIPLE_FLAG_PRE_SPLIT;
13216                 linfo = find_lhs_color(state, copy, 0);
13217                 SET_INFO(copy->id, linfo);
13218         }
13219         info = find_lhs_color(state, tangle, 0);
13220         SET_INFO(tangle->id, info);
13221         
13222         return copy;
13223 }
13224
13225
13226 static void fix_tangles(struct compile_state *state,
13227         struct reg_block *blocks, struct triple_reg_set *live,
13228         struct reg_block *rb, struct triple *ins, void *arg)
13229 {
13230         int *tangles = arg;
13231         struct triple *tangle;
13232         do {
13233                 char used[MAX_REGISTERS];
13234                 struct triple_reg_set *set;
13235                 tangle = 0;
13236
13237                 /* Find out which registers have multiple uses at this point */
13238                 memset(used, 0, sizeof(used));
13239                 for(set = live; set; set = set->next) {
13240                         struct reg_info info;
13241                         info = read_lhs_color(state, set->member, 0);
13242                         if (info.reg == REG_UNSET) {
13243                                 continue;
13244                         }
13245                         reg_inc_used(state, used, info.reg);
13246                 }
13247                 
13248                 /* Now find the least dominated definition of a register in
13249                  * conflict I have seen so far.
13250                  */
13251                 for(set = live; set; set = set->next) {
13252                         struct reg_info info;
13253                         info = read_lhs_color(state, set->member, 0);
13254                         if (used[info.reg] < 2) {
13255                                 continue;
13256                         }
13257                         /* Changing copies that feed into phi functions
13258                          * is incorrect.
13259                          */
13260                         if (set->member->use && 
13261                                 (set->member->use->member->op == OP_PHI)) {
13262                                 continue;
13263                         }
13264                         if (!tangle || tdominates(state, set->member, tangle)) {
13265                                 tangle = set->member;
13266                         }
13267                 }
13268                 /* If I have found a tangle resolve it */
13269                 if (tangle) {
13270                         struct triple *post_copy;
13271                         (*tangles)++;
13272                         post_copy = resolve_tangle(state, tangle);
13273                         if (post_copy) {
13274                                 replace_block_use(state, blocks, tangle, post_copy);
13275                         }
13276                         if (post_copy && (tangle != ins)) {
13277                                 replace_set_use(state, live, tangle, post_copy);
13278                         }
13279                 }
13280         } while(tangle);
13281         return;
13282 }
13283
13284 static int correct_tangles(
13285         struct compile_state *state, struct reg_block *blocks)
13286 {
13287         int tangles;
13288         tangles = 0;
13289         color_instructions(state);
13290         walk_variable_lifetimes(state, blocks, fix_tangles, &tangles);
13291         return tangles;
13292 }
13293
13294
13295 static void ids_from_rstate(struct compile_state *state, struct reg_state *rstate);
13296 static void cleanup_rstate(struct compile_state *state, struct reg_state *rstate);
13297
13298 struct triple *find_constrained_def(
13299         struct compile_state *state, struct live_range *range, struct triple *constrained)
13300 {
13301         struct live_range_def *lrd;
13302         lrd = range->defs;
13303         do {
13304                 struct reg_info info;
13305                 unsigned regcm;
13306                 int is_constrained;
13307                 regcm = arch_type_to_regcm(state, lrd->def->type);
13308                 info = find_lhs_color(state, lrd->def, 0);
13309                 regcm      = arch_regcm_reg_normalize(state, regcm);
13310                 info.regcm = arch_regcm_reg_normalize(state, info.regcm);
13311                 /* If the 2 register class masks are not equal the
13312                  * the current register class is constrained.
13313                  */
13314                 is_constrained = regcm != info.regcm;
13315                 
13316                 /* Of the constrained live ranges deal with the
13317                  * least dominated one first.
13318                  */
13319                 if (is_constrained) {
13320 #if DEBUG_RANGE_CONFLICTS
13321                         fprintf(stderr, "canidate: %p %-8s regcm: %x %x\n",
13322                                 lrd->def, tops(lrd->def->op), regcm, info.regcm);
13323 #endif
13324                         if (!constrained || 
13325                                 tdominates(state, lrd->def, constrained))
13326                         {
13327                                 constrained = lrd->def;
13328                         }
13329                 }
13330                 lrd = lrd->next;
13331         } while(lrd != range->defs);
13332         return constrained;
13333 }
13334
13335 static int split_constrained_ranges(
13336         struct compile_state *state, struct reg_state *rstate, 
13337         struct live_range *range)
13338 {
13339         /* Walk through the edges in conflict and our current live
13340          * range, and find definitions that are more severly constrained
13341          * than they type of data they contain require.
13342          * 
13343          * Then pick one of those ranges and relax the constraints.
13344          */
13345         struct live_range_edge *edge;
13346         struct triple *constrained;
13347
13348         constrained = 0;
13349         for(edge = range->edges; edge; edge = edge->next) {
13350                 constrained = find_constrained_def(state, edge->node, constrained);
13351         }
13352         if (!constrained) {
13353                 constrained = find_constrained_def(state, range, constrained);
13354         }
13355 #if DEBUG_RANGE_CONFLICTS
13356         fprintf(stderr, "constrained: %p %-8s\n",
13357                 constrained, tops(constrained->op));
13358 #endif
13359         if (constrained) {
13360                 ids_from_rstate(state, rstate);
13361                 cleanup_rstate(state, rstate);
13362                 resolve_tangle(state, constrained);
13363         }
13364         return !!constrained;
13365 }
13366         
13367 static int split_ranges(
13368         struct compile_state *state, struct reg_state *rstate,
13369         char *used, struct live_range *range)
13370 {
13371         int split;
13372 #if DEBUG_RANGE_CONFLICTS
13373         fprintf(stderr, "split_ranges %d %s %p\n", 
13374                 rstate->passes, tops(range->defs->def->op), range->defs->def);
13375 #endif
13376         if ((range->color == REG_UNNEEDED) ||
13377                 (rstate->passes >= rstate->max_passes)) {
13378                 return 0;
13379         }
13380         split = split_constrained_ranges(state, rstate, range);
13381
13382         /* Ideally I would split the live range that will not be used
13383          * for the longest period of time in hopes that this will 
13384          * (a) allow me to spill a register or
13385          * (b) allow me to place a value in another register.
13386          *
13387          * So far I don't have a test case for this, the resolving
13388          * of mandatory constraints has solved all of my
13389          * know issues.  So I have choosen not to write any
13390          * code until I cat get a better feel for cases where
13391          * it would be useful to have.
13392          *
13393          */
13394 #warning "WISHLIST implement live range splitting..."
13395         if ((DEBUG_RANGE_CONFLICTS > 1) && 
13396                 (!split || (DEBUG_RANGE_CONFLICTS > 2))) {
13397                 print_interference_blocks(state, rstate, stderr, 0);
13398                 print_dominators(state, stderr);
13399         }
13400         return split;
13401 }
13402
13403 #if DEBUG_COLOR_GRAPH > 1
13404 #define cgdebug_printf(...) fprintf(stdout, __VA_ARGS__)
13405 #define cgdebug_flush() fflush(stdout)
13406 #define cgdebug_loc(STATE, TRIPLE) loc(stdout, STATE, TRIPLE)
13407 #elif DEBUG_COLOR_GRAPH == 1
13408 #define cgdebug_printf(...) fprintf(stderr, __VA_ARGS__)
13409 #define cgdebug_flush() fflush(stderr)
13410 #define cgdebug_loc(STATE, TRIPLE) loc(stderr, STATE, TRIPLE)
13411 #else
13412 #define cgdebug_printf(...)
13413 #define cgdebug_flush()
13414 #define cgdebug_loc(STATE, TRIPLE)
13415 #endif
13416
13417         
13418 static int select_free_color(struct compile_state *state, 
13419         struct reg_state *rstate, struct live_range *range)
13420 {
13421         struct triple_set *entry;
13422         struct live_range_def *lrd;
13423         struct live_range_def *phi;
13424         struct live_range_edge *edge;
13425         char used[MAX_REGISTERS];
13426         struct triple **expr;
13427
13428         /* Instead of doing just the trivial color select here I try
13429          * a few extra things because a good color selection will help reduce
13430          * copies.
13431          */
13432
13433         /* Find the registers currently in use */
13434         memset(used, 0, sizeof(used));
13435         for(edge = range->edges; edge; edge = edge->next) {
13436                 if (edge->node->color == REG_UNSET) {
13437                         continue;
13438                 }
13439                 reg_fill_used(state, used, edge->node->color);
13440         }
13441 #if DEBUG_COLOR_GRAPH > 1
13442         {
13443                 int i;
13444                 i = 0;
13445                 for(edge = range->edges; edge; edge = edge->next) {
13446                         i++;
13447                 }
13448                 cgdebug_printf("\n%s edges: %d @%s:%d.%d\n", 
13449                         tops(range->def->op), i, 
13450                         range->def->filename, range->def->line, range->def->col);
13451                 for(i = 0; i < MAX_REGISTERS; i++) {
13452                         if (used[i]) {
13453                                 cgdebug_printf("used: %s\n",
13454                                         arch_reg_str(i));
13455                         }
13456                 }
13457         }       
13458 #endif
13459
13460         /* If a color is already assigned see if it will work */
13461         if (range->color != REG_UNSET) {
13462                 struct live_range_def *lrd;
13463                 if (!used[range->color]) {
13464                         return 1;
13465                 }
13466                 for(edge = range->edges; edge; edge = edge->next) {
13467                         if (edge->node->color != range->color) {
13468                                 continue;
13469                         }
13470                         warning(state, edge->node->defs->def, "edge: ");
13471                         lrd = edge->node->defs;
13472                         do {
13473                                 warning(state, lrd->def, " %p %s",
13474                                         lrd->def, tops(lrd->def->op));
13475                                 lrd = lrd->next;
13476                         } while(lrd != edge->node->defs);
13477                 }
13478                 lrd = range->defs;
13479                 warning(state, range->defs->def, "def: ");
13480                 do {
13481                         warning(state, lrd->def, " %p %s",
13482                                 lrd->def, tops(lrd->def->op));
13483                         lrd = lrd->next;
13484                 } while(lrd != range->defs);
13485                 internal_error(state, range->defs->def,
13486                         "live range with already used color %s",
13487                         arch_reg_str(range->color));
13488         }
13489
13490         /* If I feed into an expression reuse it's color.
13491          * This should help remove copies in the case of 2 register instructions
13492          * and phi functions.
13493          */
13494         phi = 0;
13495         lrd = live_range_end(state, range, 0);
13496         for(; (range->color == REG_UNSET) && lrd ; lrd = live_range_end(state, range, lrd)) {
13497                 entry = lrd->def->use;
13498                 for(;(range->color == REG_UNSET) && entry; entry = entry->next) {
13499                         struct live_range_def *insd;
13500                         unsigned regcm;
13501                         insd = &rstate->lrd[entry->member->id];
13502                         if (insd->lr->defs == 0) {
13503                                 continue;
13504                         }
13505                         if (!phi && (insd->def->op == OP_PHI) &&
13506                                 !interfere(rstate, range, insd->lr)) {
13507                                 phi = insd;
13508                         }
13509                         if (insd->lr->color == REG_UNSET) {
13510                                 continue;
13511                         }
13512                         regcm = insd->lr->classes;
13513                         if (((regcm & range->classes) == 0) ||
13514                                 (used[insd->lr->color])) {
13515                                 continue;
13516                         }
13517                         if (interfere(rstate, range, insd->lr)) {
13518                                 continue;
13519                         }
13520                         range->color = insd->lr->color;
13521                 }
13522         }
13523         /* If I feed into a phi function reuse it's color or the color
13524          * of something else that feeds into the phi function.
13525          */
13526         if (phi) {
13527                 if (phi->lr->color != REG_UNSET) {
13528                         if (used[phi->lr->color]) {
13529                                 range->color = phi->lr->color;
13530                         }
13531                 }
13532                 else {
13533                         expr = triple_rhs(state, phi->def, 0);
13534                         for(; expr; expr = triple_rhs(state, phi->def, expr)) {
13535                                 struct live_range *lr;
13536                                 unsigned regcm;
13537                                 if (!*expr) {
13538                                         continue;
13539                                 }
13540                                 lr = rstate->lrd[(*expr)->id].lr;
13541                                 if (lr->color == REG_UNSET) {
13542                                         continue;
13543                                 }
13544                                 regcm = lr->classes;
13545                                 if (((regcm & range->classes) == 0) ||
13546                                         (used[lr->color])) {
13547                                         continue;
13548                                 }
13549                                 if (interfere(rstate, range, lr)) {
13550                                         continue;
13551                                 }
13552                                 range->color = lr->color;
13553                         }
13554                 }
13555         }
13556         /* If I don't interfere with a rhs node reuse it's color */
13557         lrd = live_range_head(state, range, 0);
13558         for(; (range->color == REG_UNSET) && lrd ; lrd = live_range_head(state, range, lrd)) {
13559                 expr = triple_rhs(state, lrd->def, 0);
13560                 for(; expr; expr = triple_rhs(state, lrd->def, expr)) {
13561                         struct live_range *lr;
13562                         unsigned regcm;
13563                         if (!*expr) {
13564                                 continue;
13565                         }
13566                         lr = rstate->lrd[(*expr)->id].lr;
13567                         if (lr->color == REG_UNSET) {
13568                                 continue;
13569                         }
13570                         regcm = lr->classes;
13571                         if (((regcm & range->classes) == 0) ||
13572                                 (used[lr->color])) {
13573                                 continue;
13574                         }
13575                         if (interfere(rstate, range, lr)) {
13576                                 continue;
13577                         }
13578                         range->color = lr->color;
13579                         break;
13580                 }
13581         }
13582         /* If I have not opportunitically picked a useful color
13583          * pick the first color that is free.
13584          */
13585         if (range->color == REG_UNSET) {
13586                 range->color = 
13587                         arch_select_free_register(state, used, range->classes);
13588         }
13589         if (range->color == REG_UNSET) {
13590                 struct live_range_def *lrd;
13591                 int i;
13592                 if (split_ranges(state, rstate, used, range)) {
13593                         return 0;
13594                 }
13595                 for(edge = range->edges; edge; edge = edge->next) {
13596                         warning(state, edge->node->defs->def, "edge reg %s",
13597                                 arch_reg_str(edge->node->color));
13598                         lrd = edge->node->defs;
13599                         do {
13600                                 warning(state, lrd->def, " %s %p",
13601                                         tops(lrd->def->op), lrd->def);
13602                                 lrd = lrd->next;
13603                         } while(lrd != edge->node->defs);
13604                 }
13605                 warning(state, range->defs->def, "range: ");
13606                 lrd = range->defs;
13607                 do {
13608                         warning(state, lrd->def, " %s %p",
13609                                 tops(lrd->def->op), lrd->def);
13610                         lrd = lrd->next;
13611                 } while(lrd != range->defs);
13612                         
13613                 warning(state, range->defs->def, "classes: %x",
13614                         range->classes);
13615                 for(i = 0; i < MAX_REGISTERS; i++) {
13616                         if (used[i]) {
13617                                 warning(state, range->defs->def, "used: %s",
13618                                         arch_reg_str(i));
13619                         }
13620                 }
13621 #if DEBUG_COLOR_GRAPH < 2
13622                 error(state, range->defs->def, "too few registers");
13623 #else
13624                 internal_error(state, range->defs->def, "too few registers");
13625 #endif
13626         }
13627         range->classes &= arch_reg_regcm(state, range->color);
13628         if ((range->color == REG_UNSET) || (range->classes == 0)) {
13629                 internal_error(state, range->defs->def, "select_free_color did not?");
13630         }
13631         return 1;
13632 }
13633
13634 static int color_graph(struct compile_state *state, struct reg_state *rstate)
13635 {
13636         int colored;
13637         struct live_range_edge *edge;
13638         struct live_range *range;
13639         if (rstate->low) {
13640                 cgdebug_printf("Lo: ");
13641                 range = rstate->low;
13642                 if (*range->group_prev != range) {
13643                         internal_error(state, 0, "lo: *prev != range?");
13644                 }
13645                 *range->group_prev = range->group_next;
13646                 if (range->group_next) {
13647                         range->group_next->group_prev = range->group_prev;
13648                 }
13649                 if (&range->group_next == rstate->low_tail) {
13650                         rstate->low_tail = range->group_prev;
13651                 }
13652                 if (rstate->low == range) {
13653                         internal_error(state, 0, "low: next != prev?");
13654                 }
13655         }
13656         else if (rstate->high) {
13657                 cgdebug_printf("Hi: ");
13658                 range = rstate->high;
13659                 if (*range->group_prev != range) {
13660                         internal_error(state, 0, "hi: *prev != range?");
13661                 }
13662                 *range->group_prev = range->group_next;
13663                 if (range->group_next) {
13664                         range->group_next->group_prev = range->group_prev;
13665                 }
13666                 if (&range->group_next == rstate->high_tail) {
13667                         rstate->high_tail = range->group_prev;
13668                 }
13669                 if (rstate->high == range) {
13670                         internal_error(state, 0, "high: next != prev?");
13671                 }
13672         }
13673         else {
13674                 return 1;
13675         }
13676         cgdebug_printf(" %d\n", range - rstate->lr);
13677         range->group_prev = 0;
13678         for(edge = range->edges; edge; edge = edge->next) {
13679                 struct live_range *node;
13680                 node = edge->node;
13681                 /* Move nodes from the high to the low list */
13682                 if (node->group_prev && (node->color == REG_UNSET) &&
13683                         (node->degree == regc_max_size(state, node->classes))) {
13684                         if (*node->group_prev != node) {
13685                                 internal_error(state, 0, "move: *prev != node?");
13686                         }
13687                         *node->group_prev = node->group_next;
13688                         if (node->group_next) {
13689                                 node->group_next->group_prev = node->group_prev;
13690                         }
13691                         if (&node->group_next == rstate->high_tail) {
13692                                 rstate->high_tail = node->group_prev;
13693                         }
13694                         cgdebug_printf("Moving...%d to low\n", node - rstate->lr);
13695                         node->group_prev  = rstate->low_tail;
13696                         node->group_next  = 0;
13697                         *rstate->low_tail = node;
13698                         rstate->low_tail  = &node->group_next;
13699                         if (*node->group_prev != node) {
13700                                 internal_error(state, 0, "move2: *prev != node?");
13701                         }
13702                 }
13703                 node->degree -= 1;
13704         }
13705         colored = color_graph(state, rstate);
13706         if (colored) {
13707                 cgdebug_printf("Coloring %d @", range - rstate->lr);
13708                 cgdebug_loc(state, range->defs->def);
13709                 cgdebug_flush();
13710                 colored = select_free_color(state, rstate, range);
13711                 cgdebug_printf(" %s\n", arch_reg_str(range->color));
13712         }
13713         return colored;
13714 }
13715
13716 static void verify_colors(struct compile_state *state, struct reg_state *rstate)
13717 {
13718         struct live_range *lr;
13719         struct live_range_edge *edge;
13720         struct triple *ins, *first;
13721         char used[MAX_REGISTERS];
13722         first = RHS(state->main_function, 0);
13723         ins = first;
13724         do {
13725                 if (triple_is_def(state, ins)) {
13726                         if ((ins->id < 0) || (ins->id > rstate->defs)) {
13727                                 internal_error(state, ins, 
13728                                         "triple without a live range def");
13729                         }
13730                         lr = rstate->lrd[ins->id].lr;
13731                         if (lr->color == REG_UNSET) {
13732                                 internal_error(state, ins,
13733                                         "triple without a color");
13734                         }
13735                         /* Find the registers used by the edges */
13736                         memset(used, 0, sizeof(used));
13737                         for(edge = lr->edges; edge; edge = edge->next) {
13738                                 if (edge->node->color == REG_UNSET) {
13739                                         internal_error(state, 0,
13740                                                 "live range without a color");
13741                         }
13742                                 reg_fill_used(state, used, edge->node->color);
13743                         }
13744                         if (used[lr->color]) {
13745                                 internal_error(state, ins,
13746                                         "triple with already used color");
13747                         }
13748                 }
13749                 ins = ins->next;
13750         } while(ins != first);
13751 }
13752
13753 static void color_triples(struct compile_state *state, struct reg_state *rstate)
13754 {
13755         struct live_range *lr;
13756         struct triple *first, *ins;
13757         first = RHS(state->main_function, 0);
13758         ins = first;
13759         do {
13760                 if ((ins->id < 0) || (ins->id > rstate->defs)) {
13761                         internal_error(state, ins, 
13762                                 "triple without a live range");
13763                 }
13764                 lr = rstate->lrd[ins->id].lr;
13765                 SET_REG(ins->id, lr->color);
13766                 ins = ins->next;
13767         } while (ins != first);
13768 }
13769
13770 static struct live_range *merge_sort_lr(
13771         struct live_range *first, struct live_range *last)
13772 {
13773         struct live_range *mid, *join, **join_tail, *pick;
13774         size_t size;
13775         size = (last - first) + 1;
13776         if (size >= 2) {
13777                 mid = first + size/2;
13778                 first = merge_sort_lr(first, mid -1);
13779                 mid   = merge_sort_lr(mid, last);
13780                 
13781                 join = 0;
13782                 join_tail = &join;
13783                 /* merge the two lists */
13784                 while(first && mid) {
13785                         if ((first->degree < mid->degree) ||
13786                                 ((first->degree == mid->degree) &&
13787                                         (first->length < mid->length))) {
13788                                 pick = first;
13789                                 first = first->group_next;
13790                                 if (first) {
13791                                         first->group_prev = 0;
13792                                 }
13793                         }
13794                         else {
13795                                 pick = mid;
13796                                 mid = mid->group_next;
13797                                 if (mid) {
13798                                         mid->group_prev = 0;
13799                                 }
13800                         }
13801                         pick->group_next = 0;
13802                         pick->group_prev = join_tail;
13803                         *join_tail = pick;
13804                         join_tail = &pick->group_next;
13805                 }
13806                 /* Splice the remaining list */
13807                 pick = (first)? first : mid;
13808                 *join_tail = pick;
13809                 if (pick) { 
13810                         pick->group_prev = join_tail;
13811                 }
13812         }
13813         else {
13814                 if (!first->defs) {
13815                         first = 0;
13816                 }
13817                 join = first;
13818         }
13819         return join;
13820 }
13821
13822 static void ids_from_rstate(struct compile_state *state, 
13823         struct reg_state *rstate)
13824 {
13825         struct triple *ins, *first;
13826         if (!rstate->defs) {
13827                 return;
13828         }
13829         /* Display the graph if desired */
13830         if (state->debug & DEBUG_INTERFERENCE) {
13831                 print_blocks(state, stdout);
13832                 print_control_flow(state);
13833         }
13834         first = RHS(state->main_function, 0);
13835         ins = first;
13836         do {
13837                 if (ins->id) {
13838                         struct live_range_def *lrd;
13839                         lrd = &rstate->lrd[ins->id];
13840                         ins->id = lrd->orig_id;
13841                 }
13842                 ins = ins->next;
13843         } while(ins != first);
13844 }
13845
13846 static void cleanup_live_edges(struct reg_state *rstate)
13847 {
13848         int i;
13849         /* Free the edges on each node */
13850         for(i = 1; i <= rstate->ranges; i++) {
13851                 remove_live_edges(rstate, &rstate->lr[i]);
13852         }
13853 }
13854
13855 static void cleanup_rstate(struct compile_state *state, struct reg_state *rstate)
13856 {
13857         cleanup_live_edges(rstate);
13858         xfree(rstate->lrd);
13859         xfree(rstate->lr);
13860
13861         /* Free the variable lifetime information */
13862         if (rstate->blocks) {
13863                 free_variable_lifetimes(state, rstate->blocks);
13864         }
13865         rstate->defs = 0;
13866         rstate->ranges = 0;
13867         rstate->lrd = 0;
13868         rstate->lr = 0;
13869         rstate->blocks = 0;
13870 }
13871
13872 static void verify_consistency(struct compile_state *state);
13873 static void allocate_registers(struct compile_state *state)
13874 {
13875         struct reg_state rstate;
13876         int colored;
13877
13878         /* Clear out the reg_state */
13879         memset(&rstate, 0, sizeof(rstate));
13880         rstate.max_passes = MAX_ALLOCATION_PASSES;
13881
13882         do {
13883                 struct live_range **point, **next;
13884                 int conflicts;
13885                 int tangles;
13886                 int coalesced;
13887
13888 #if DEBUG_RANGE_CONFLICTS
13889                 fprintf(stderr, "pass: %d\n", rstate.passes);
13890 #endif
13891
13892                 /* Restore ids */
13893                 ids_from_rstate(state, &rstate);
13894
13895                 /* Cleanup the temporary data structures */
13896                 cleanup_rstate(state, &rstate);
13897
13898                 /* Compute the variable lifetimes */
13899                 rstate.blocks = compute_variable_lifetimes(state);
13900
13901                 /* Fix invalid mandatory live range coalesce conflicts */
13902                 conflicts = correct_coalesce_conflicts(state, rstate.blocks);
13903
13904                 /* Fix two simultaneous uses of the same register.
13905                  * In a few pathlogical cases a partial untangle moves
13906                  * the tangle to a part of the graph we won't revisit.
13907                  * So we keep looping until we have no more tangle fixes
13908                  * to apply.
13909                  */
13910                 do {
13911                         tangles = correct_tangles(state, rstate.blocks);
13912                 } while(tangles);
13913
13914                 if (state->debug & DEBUG_INSERTED_COPIES) {
13915                         printf("After resolve_tangles\n");
13916                         print_blocks(state, stdout);
13917                         print_control_flow(state);
13918                 }
13919                 verify_consistency(state);
13920                 
13921                 /* Allocate and initialize the live ranges */
13922                 initialize_live_ranges(state, &rstate);
13923
13924                 /* Note current doing coalescing in a loop appears to 
13925                  * buys me nothing.  The code is left this way in case
13926                  * there is some value in it.  Or if a future bugfix
13927                  *  yields some benefit.
13928                  */
13929                 do {
13930 #if DEBUG_COALESCING
13931                         fprintf(stderr, "coalescing\n");
13932 #endif                  
13933                         /* Remove any previous live edge calculations */
13934                         cleanup_live_edges(&rstate);
13935
13936                         /* Compute the interference graph */
13937                         walk_variable_lifetimes(
13938                                 state, rstate.blocks, graph_ins, &rstate);
13939                         
13940                         /* Display the interference graph if desired */
13941                         if (state->debug & DEBUG_INTERFERENCE) {
13942                                 print_interference_blocks(state, &rstate, stdout, 1);
13943                                 printf("\nlive variables by instruction\n");
13944                                 walk_variable_lifetimes(
13945                                         state, rstate.blocks, 
13946                                         print_interference_ins, &rstate);
13947                         }
13948                         
13949                         coalesced = coalesce_live_ranges(state, &rstate);
13950
13951 #if DEBUG_COALESCING
13952                         fprintf(stderr, "coalesced: %d\n", coalesced);
13953 #endif
13954                 } while(coalesced);
13955
13956 #if DEBUG_CONSISTENCY > 1
13957 # if 0
13958                 fprintf(stderr, "verify_graph_ins...\n");
13959 # endif
13960                 /* Verify the interference graph */
13961                 walk_variable_lifetimes(
13962                         state, rstate.blocks, verify_graph_ins, &rstate);
13963 # if 0
13964                 fprintf(stderr, "verify_graph_ins done\n");
13965 #endif
13966 #endif
13967                         
13968                 /* Build the groups low and high.  But with the nodes
13969                  * first sorted by degree order.
13970                  */
13971                 rstate.low_tail  = &rstate.low;
13972                 rstate.high_tail = &rstate.high;
13973                 rstate.high = merge_sort_lr(&rstate.lr[1], &rstate.lr[rstate.ranges]);
13974                 if (rstate.high) {
13975                         rstate.high->group_prev = &rstate.high;
13976                 }
13977                 for(point = &rstate.high; *point; point = &(*point)->group_next)
13978                         ;
13979                 rstate.high_tail = point;
13980                 /* Walk through the high list and move everything that needs
13981                  * to be onto low.
13982                  */
13983                 for(point = &rstate.high; *point; point = next) {
13984                         struct live_range *range;
13985                         next = &(*point)->group_next;
13986                         range = *point;
13987                         
13988                         /* If it has a low degree or it already has a color
13989                          * place the node in low.
13990                          */
13991                         if ((range->degree < regc_max_size(state, range->classes)) ||
13992                                 (range->color != REG_UNSET)) {
13993                                 cgdebug_printf("Lo: %5d degree %5d%s\n", 
13994                                         range - rstate.lr, range->degree,
13995                                         (range->color != REG_UNSET) ? " (colored)": "");
13996                                 *range->group_prev = range->group_next;
13997                                 if (range->group_next) {
13998                                         range->group_next->group_prev = range->group_prev;
13999                                 }
14000                                 if (&range->group_next == rstate.high_tail) {
14001                                         rstate.high_tail = range->group_prev;
14002                                 }
14003                                 range->group_prev  = rstate.low_tail;
14004                                 range->group_next  = 0;
14005                                 *rstate.low_tail   = range;
14006                                 rstate.low_tail    = &range->group_next;
14007                                 next = point;
14008                         }
14009                         else {
14010                                 cgdebug_printf("hi: %5d degree %5d%s\n", 
14011                                         range - rstate.lr, range->degree,
14012                                         (range->color != REG_UNSET) ? " (colored)": "");
14013                         }
14014                 }
14015                 /* Color the live_ranges */
14016                 colored = color_graph(state, &rstate);
14017                 rstate.passes++;
14018         } while (!colored);
14019
14020         /* Verify the graph was properly colored */
14021         verify_colors(state, &rstate);
14022
14023         /* Move the colors from the graph to the triples */
14024         color_triples(state, &rstate);
14025
14026         /* Cleanup the temporary data structures */
14027         cleanup_rstate(state, &rstate);
14028 }
14029
14030 /* Sparce Conditional Constant Propogation
14031  * =========================================
14032  */
14033 struct ssa_edge;
14034 struct flow_block;
14035 struct lattice_node {
14036         unsigned old_id;
14037         struct triple *def;
14038         struct ssa_edge *out;
14039         struct flow_block *fblock;
14040         struct triple *val;
14041         /* lattice high   val && !is_const(val) 
14042          * lattice const  is_const(val)
14043          * lattice low    val == 0
14044          */
14045 };
14046 struct ssa_edge {
14047         struct lattice_node *src;
14048         struct lattice_node *dst;
14049         struct ssa_edge *work_next;
14050         struct ssa_edge *work_prev;
14051         struct ssa_edge *out_next;
14052 };
14053 struct flow_edge {
14054         struct flow_block *src;
14055         struct flow_block *dst;
14056         struct flow_edge *work_next;
14057         struct flow_edge *work_prev;
14058         struct flow_edge *in_next;
14059         struct flow_edge *out_next;
14060         int executable;
14061 };
14062 struct flow_block {
14063         struct block *block;
14064         struct flow_edge *in;
14065         struct flow_edge *out;
14066         struct flow_edge left, right;
14067 };
14068
14069 struct scc_state {
14070         int ins_count;
14071         struct lattice_node *lattice;
14072         struct ssa_edge     *ssa_edges;
14073         struct flow_block   *flow_blocks;
14074         struct flow_edge    *flow_work_list;
14075         struct ssa_edge     *ssa_work_list;
14076 };
14077
14078
14079 static void scc_add_fedge(struct compile_state *state, struct scc_state *scc, 
14080         struct flow_edge *fedge)
14081 {
14082         if (!scc->flow_work_list) {
14083                 scc->flow_work_list = fedge;
14084                 fedge->work_next = fedge->work_prev = fedge;
14085         }
14086         else {
14087                 struct flow_edge *ftail;
14088                 ftail = scc->flow_work_list->work_prev;
14089                 fedge->work_next = ftail->work_next;
14090                 fedge->work_prev = ftail;
14091                 fedge->work_next->work_prev = fedge;
14092                 fedge->work_prev->work_next = fedge;
14093         }
14094 }
14095
14096 static struct flow_edge *scc_next_fedge(
14097         struct compile_state *state, struct scc_state *scc)
14098 {
14099         struct flow_edge *fedge;
14100         fedge = scc->flow_work_list;
14101         if (fedge) {
14102                 fedge->work_next->work_prev = fedge->work_prev;
14103                 fedge->work_prev->work_next = fedge->work_next;
14104                 if (fedge->work_next != fedge) {
14105                         scc->flow_work_list = fedge->work_next;
14106                 } else {
14107                         scc->flow_work_list = 0;
14108                 }
14109         }
14110         return fedge;
14111 }
14112
14113 static void scc_add_sedge(struct compile_state *state, struct scc_state *scc,
14114         struct ssa_edge *sedge)
14115 {
14116         if (!scc->ssa_work_list) {
14117                 scc->ssa_work_list = sedge;
14118                 sedge->work_next = sedge->work_prev = sedge;
14119         }
14120         else {
14121                 struct ssa_edge *stail;
14122                 stail = scc->ssa_work_list->work_prev;
14123                 sedge->work_next = stail->work_next;
14124                 sedge->work_prev = stail;
14125                 sedge->work_next->work_prev = sedge;
14126                 sedge->work_prev->work_next = sedge;
14127         }
14128 }
14129
14130 static struct ssa_edge *scc_next_sedge(
14131         struct compile_state *state, struct scc_state *scc)
14132 {
14133         struct ssa_edge *sedge;
14134         sedge = scc->ssa_work_list;
14135         if (sedge) {
14136                 sedge->work_next->work_prev = sedge->work_prev;
14137                 sedge->work_prev->work_next = sedge->work_next;
14138                 if (sedge->work_next != sedge) {
14139                         scc->ssa_work_list = sedge->work_next;
14140                 } else {
14141                         scc->ssa_work_list = 0;
14142                 }
14143         }
14144         return sedge;
14145 }
14146
14147 static void initialize_scc_state(
14148         struct compile_state *state, struct scc_state *scc)
14149 {
14150         int ins_count, ssa_edge_count;
14151         int ins_index, ssa_edge_index, fblock_index;
14152         struct triple *first, *ins;
14153         struct block *block;
14154         struct flow_block *fblock;
14155
14156         memset(scc, 0, sizeof(*scc));
14157
14158         /* Inialize pass zero find out how much memory we need */
14159         first = RHS(state->main_function, 0);
14160         ins = first;
14161         ins_count = ssa_edge_count = 0;
14162         do {
14163                 struct triple_set *edge;
14164                 ins_count += 1;
14165                 for(edge = ins->use; edge; edge = edge->next) {
14166                         ssa_edge_count++;
14167                 }
14168                 ins = ins->next;
14169         } while(ins != first);
14170 #if DEBUG_SCC
14171         fprintf(stderr, "ins_count: %d ssa_edge_count: %d vertex_count: %d\n",
14172                 ins_count, ssa_edge_count, state->last_vertex);
14173 #endif
14174         scc->ins_count   = ins_count;
14175         scc->lattice     = 
14176                 xcmalloc(sizeof(*scc->lattice)*(ins_count + 1), "lattice");
14177         scc->ssa_edges   = 
14178                 xcmalloc(sizeof(*scc->ssa_edges)*(ssa_edge_count + 1), "ssa_edges");
14179         scc->flow_blocks = 
14180                 xcmalloc(sizeof(*scc->flow_blocks)*(state->last_vertex + 1), 
14181                         "flow_blocks");
14182
14183         /* Initialize pass one collect up the nodes */
14184         fblock = 0;
14185         block = 0;
14186         ins_index = ssa_edge_index = fblock_index = 0;
14187         ins = first;
14188         do {
14189                 if ((ins->op == OP_LABEL) && (block != ins->u.block)) {
14190                         block = ins->u.block;
14191                         if (!block) {
14192                                 internal_error(state, ins, "label without block");
14193                         }
14194                         fblock_index += 1;
14195                         block->vertex = fblock_index;
14196                         fblock = &scc->flow_blocks[fblock_index];
14197                         fblock->block = block;
14198                 }
14199                 {
14200                         struct lattice_node *lnode;
14201                         ins_index += 1;
14202                         lnode = &scc->lattice[ins_index];
14203                         lnode->def = ins;
14204                         lnode->out = 0;
14205                         lnode->fblock = fblock;
14206                         lnode->val = ins; /* LATTICE HIGH */
14207                         lnode->old_id = ins->id;
14208                         ins->id = ins_index;
14209                 }
14210                 ins = ins->next;
14211         } while(ins != first);
14212         /* Initialize pass two collect up the edges */
14213         block = 0;
14214         fblock = 0;
14215         ins = first;
14216         do {
14217                 if ((ins->op == OP_LABEL) && (block != ins->u.block)) {
14218                         struct flow_edge *fedge, **ftail;
14219                         struct block_set *bedge;
14220                         block = ins->u.block;
14221                         fblock = &scc->flow_blocks[block->vertex];
14222                         fblock->in = 0;
14223                         fblock->out = 0;
14224                         ftail = &fblock->out;
14225                         if (block->left) {
14226                                 fblock->left.dst = &scc->flow_blocks[block->left->vertex];
14227                                 if (fblock->left.dst->block != block->left) {
14228                                         internal_error(state, 0, "block mismatch");
14229                                 }
14230                                 fblock->left.out_next = 0;
14231                                 *ftail = &fblock->left;
14232                                 ftail = &fblock->left.out_next;
14233                         }
14234                         if (block->right) {
14235                                 fblock->right.dst = &scc->flow_blocks[block->right->vertex];
14236                                 if (fblock->right.dst->block != block->right) {
14237                                         internal_error(state, 0, "block mismatch");
14238                                 }
14239                                 fblock->right.out_next = 0;
14240                                 *ftail = &fblock->right;
14241                                 ftail = &fblock->right.out_next;
14242                         }
14243                         for(fedge = fblock->out; fedge; fedge = fedge->out_next) {
14244                                 fedge->src = fblock;
14245                                 fedge->work_next = fedge->work_prev = fedge;
14246                                 fedge->executable = 0;
14247                         }
14248                         ftail = &fblock->in;
14249                         for(bedge = block->use; bedge; bedge = bedge->next) {
14250                                 struct block *src_block;
14251                                 struct flow_block *sfblock;
14252                                 struct flow_edge *sfedge;
14253                                 src_block = bedge->member;
14254                                 sfblock = &scc->flow_blocks[src_block->vertex];
14255                                 sfedge = 0;
14256                                 if (src_block->left == block) {
14257                                         sfedge = &sfblock->left;
14258                                 } else {
14259                                         sfedge = &sfblock->right;
14260                                 }
14261                                 *ftail = sfedge;
14262                                 ftail = &sfedge->in_next;
14263                                 sfedge->in_next = 0;
14264                         }
14265                 }
14266                 {
14267                         struct triple_set *edge;
14268                         struct ssa_edge **stail;
14269                         struct lattice_node *lnode;
14270                         lnode = &scc->lattice[ins->id];
14271                         lnode->out = 0;
14272                         stail = &lnode->out;
14273                         for(edge = ins->use; edge; edge = edge->next) {
14274                                 struct ssa_edge *sedge;
14275                                 ssa_edge_index += 1;
14276                                 sedge = &scc->ssa_edges[ssa_edge_index];
14277                                 *stail = sedge;
14278                                 stail = &sedge->out_next;
14279                                 sedge->src = lnode;
14280                                 sedge->dst = &scc->lattice[edge->member->id];
14281                                 sedge->work_next = sedge->work_prev = sedge;
14282                                 sedge->out_next = 0;
14283                         }
14284                 }
14285                 ins = ins->next;
14286         } while(ins != first);
14287         /* Setup a dummy block 0 as a node above the start node */
14288         {
14289                 struct flow_block *fblock, *dst;
14290                 struct flow_edge *fedge;
14291                 fblock = &scc->flow_blocks[0];
14292                 fblock->block = 0;
14293                 fblock->in = 0;
14294                 fblock->out = &fblock->left;
14295                 dst = &scc->flow_blocks[state->first_block->vertex];
14296                 fedge = &fblock->left;
14297                 fedge->src        = fblock;
14298                 fedge->dst        = dst;
14299                 fedge->work_next  = fedge;
14300                 fedge->work_prev  = fedge;
14301                 fedge->in_next    = fedge->dst->in;
14302                 fedge->out_next   = 0;
14303                 fedge->executable = 0;
14304                 fedge->dst->in = fedge;
14305                 
14306                 /* Initialize the work lists */
14307                 scc->flow_work_list = 0;
14308                 scc->ssa_work_list  = 0;
14309                 scc_add_fedge(state, scc, fedge);
14310         }
14311 #if DEBUG_SCC
14312         fprintf(stderr, "ins_index: %d ssa_edge_index: %d fblock_index: %d\n",
14313                 ins_index, ssa_edge_index, fblock_index);
14314 #endif
14315 }
14316
14317         
14318 static void free_scc_state(
14319         struct compile_state *state, struct scc_state *scc)
14320 {
14321         xfree(scc->flow_blocks);
14322         xfree(scc->ssa_edges);
14323         xfree(scc->lattice);
14324         
14325 }
14326
14327 static struct lattice_node *triple_to_lattice(
14328         struct compile_state *state, struct scc_state *scc, struct triple *ins)
14329 {
14330         if (ins->id <= 0) {
14331                 internal_error(state, ins, "bad id");
14332         }
14333         return &scc->lattice[ins->id];
14334 }
14335
14336 static struct triple *preserve_lval(
14337         struct compile_state *state, struct lattice_node *lnode)
14338 {
14339         struct triple *old;
14340         /* Preserve the original value */
14341         if (lnode->val) {
14342                 old = dup_triple(state, lnode->val);
14343                 if (lnode->val != lnode->def) {
14344                         xfree(lnode->val);
14345                 }
14346                 lnode->val = 0;
14347         } else {
14348                 old = 0;
14349         }
14350         return old;
14351 }
14352
14353 static int lval_changed(struct compile_state *state, 
14354         struct triple *old, struct lattice_node *lnode)
14355 {
14356         int changed;
14357         /* See if the lattice value has changed */
14358         changed = 1;
14359         if (!old && !lnode->val) {
14360                 changed = 0;
14361         }
14362         if (changed && lnode->val && !is_const(lnode->val)) {
14363                 changed = 0;
14364         }
14365         if (changed &&
14366                 lnode->val && old &&
14367                 (memcmp(lnode->val->param, old->param,
14368                         TRIPLE_SIZE(lnode->val->sizes) * sizeof(lnode->val->param[0])) == 0) &&
14369                 (memcmp(&lnode->val->u, &old->u, sizeof(old->u)) == 0)) {
14370                 changed = 0;
14371         }
14372         if (old) {
14373                 xfree(old);
14374         }
14375         return changed;
14376
14377 }
14378
14379 static void scc_visit_phi(struct compile_state *state, struct scc_state *scc, 
14380         struct lattice_node *lnode)
14381 {
14382         struct lattice_node *tmp;
14383         struct triple **slot, *old;
14384         struct flow_edge *fedge;
14385         int index;
14386         if (lnode->def->op != OP_PHI) {
14387                 internal_error(state, lnode->def, "not phi");
14388         }
14389         /* Store the original value */
14390         old = preserve_lval(state, lnode);
14391
14392         /* default to lattice high */
14393         lnode->val = lnode->def;
14394         slot = &RHS(lnode->def, 0);
14395         index = 0;
14396         for(fedge = lnode->fblock->in; fedge; index++, fedge = fedge->in_next) {
14397                 if (!fedge->executable) {
14398                         continue;
14399                 }
14400                 if (!slot[index]) {
14401                         internal_error(state, lnode->def, "no phi value");
14402                 }
14403                 tmp = triple_to_lattice(state, scc, slot[index]);
14404                 /* meet(X, lattice low) = lattice low */
14405                 if (!tmp->val) {
14406                         lnode->val = 0;
14407                 }
14408                 /* meet(X, lattice high) = X */
14409                 else if (!tmp->val) {
14410                         lnode->val = lnode->val;
14411                 }
14412                 /* meet(lattice high, X) = X */
14413                 else if (!is_const(lnode->val)) {
14414                         lnode->val = dup_triple(state, tmp->val);
14415                         lnode->val->type = lnode->def->type;
14416                 }
14417                 /* meet(const, const) = const or lattice low */
14418                 else if (!constants_equal(state, lnode->val, tmp->val)) {
14419                         lnode->val = 0;
14420                 }
14421                 if (!lnode->val) {
14422                         break;
14423                 }
14424         }
14425 #if DEBUG_SCC
14426         fprintf(stderr, "phi: %d -> %s\n",
14427                 lnode->def->id,
14428                 (!lnode->val)? "lo": is_const(lnode->val)? "const": "hi");
14429 #endif
14430         /* If the lattice value has changed update the work lists. */
14431         if (lval_changed(state, old, lnode)) {
14432                 struct ssa_edge *sedge;
14433                 for(sedge = lnode->out; sedge; sedge = sedge->out_next) {
14434                         scc_add_sedge(state, scc, sedge);
14435                 }
14436         }
14437 }
14438
14439 static int compute_lnode_val(struct compile_state *state, struct scc_state *scc,
14440         struct lattice_node *lnode)
14441 {
14442         int changed;
14443         struct triple *old, *scratch;
14444         struct triple **dexpr, **vexpr;
14445         int count, i;
14446         
14447         /* Store the original value */
14448         old = preserve_lval(state, lnode);
14449
14450         /* Reinitialize the value */
14451         lnode->val = scratch = dup_triple(state, lnode->def);
14452         scratch->id = lnode->old_id;
14453         scratch->next     = scratch;
14454         scratch->prev     = scratch;
14455         scratch->use      = 0;
14456
14457         count = TRIPLE_SIZE(scratch->sizes);
14458         for(i = 0; i < count; i++) {
14459                 dexpr = &lnode->def->param[i];
14460                 vexpr = &scratch->param[i];
14461                 *vexpr = *dexpr;
14462                 if (((i < TRIPLE_MISC_OFF(scratch->sizes)) ||
14463                         (i >= TRIPLE_TARG_OFF(scratch->sizes))) &&
14464                         *dexpr) {
14465                         struct lattice_node *tmp;
14466                         tmp = triple_to_lattice(state, scc, *dexpr);
14467                         *vexpr = (tmp->val)? tmp->val : tmp->def;
14468                 }
14469         }
14470         if (scratch->op == OP_BRANCH) {
14471                 scratch->next = lnode->def->next;
14472         }
14473         /* Recompute the value */
14474 #warning "FIXME see if simplify does anything bad"
14475         /* So far it looks like only the strength reduction
14476          * optimization are things I need to worry about.
14477          */
14478         simplify(state, scratch);
14479         /* Cleanup my value */
14480         if (scratch->use) {
14481                 internal_error(state, lnode->def, "scratch used?");
14482         }
14483         if ((scratch->prev != scratch) ||
14484                 ((scratch->next != scratch) &&
14485                         ((lnode->def->op != OP_BRANCH) ||
14486                                 (scratch->next != lnode->def->next)))) {
14487                 internal_error(state, lnode->def, "scratch in list?");
14488         }
14489         /* undo any uses... */
14490         count = TRIPLE_SIZE(scratch->sizes);
14491         for(i = 0; i < count; i++) {
14492                 vexpr = &scratch->param[i];
14493                 if (*vexpr) {
14494                         unuse_triple(*vexpr, scratch);
14495                 }
14496         }
14497         if (!is_const(scratch)) {
14498                 for(i = 0; i < count; i++) {
14499                         dexpr = &lnode->def->param[i];
14500                         if (((i < TRIPLE_MISC_OFF(scratch->sizes)) ||
14501                                 (i >= TRIPLE_TARG_OFF(scratch->sizes))) &&
14502                                 *dexpr) {
14503                                 struct lattice_node *tmp;
14504                                 tmp = triple_to_lattice(state, scc, *dexpr);
14505                                 if (!tmp->val) {
14506                                         lnode->val = 0;
14507                                 }
14508                         }
14509                 }
14510         }
14511         if (lnode->val && 
14512                 (lnode->val->op == lnode->def->op) &&
14513                 (memcmp(lnode->val->param, lnode->def->param, 
14514                         count * sizeof(lnode->val->param[0])) == 0) &&
14515                 (memcmp(&lnode->val->u, &lnode->def->u, sizeof(lnode->def->u)) == 0)) {
14516                 lnode->val = lnode->def;
14517         }
14518         /* Find the cases that are always lattice lo */
14519         if (lnode->val && 
14520                 triple_is_def(state, lnode->val) &&
14521                 !triple_is_pure(state, lnode->val)) {
14522                 lnode->val = 0;
14523         }
14524         if (lnode->val && 
14525                 (lnode->val->op == OP_SDECL) && 
14526                 (lnode->val != lnode->def)) {
14527                 internal_error(state, lnode->def, "bad sdecl");
14528         }
14529         /* See if the lattice value has changed */
14530         changed = lval_changed(state, old, lnode);
14531         if (lnode->val != scratch) {
14532                 xfree(scratch);
14533         }
14534         return changed;
14535 }
14536
14537 static void scc_visit_branch(struct compile_state *state, struct scc_state *scc,
14538         struct lattice_node *lnode)
14539 {
14540         struct lattice_node *cond;
14541 #if DEBUG_SCC
14542         {
14543                 struct flow_edge *fedge;
14544                 fprintf(stderr, "branch: %d (",
14545                         lnode->def->id);
14546                 
14547                 for(fedge = lnode->fblock->out; fedge; fedge = fedge->out_next) {
14548                         fprintf(stderr, " %d", fedge->dst->block->vertex);
14549                 }
14550                 fprintf(stderr, " )");
14551                 if (TRIPLE_RHS(lnode->def->sizes) > 0) {
14552                         fprintf(stderr, " <- %d",
14553                                 RHS(lnode->def, 0)->id);
14554                 }
14555                 fprintf(stderr, "\n");
14556         }
14557 #endif
14558         if (lnode->def->op != OP_BRANCH) {
14559                 internal_error(state, lnode->def, "not branch");
14560         }
14561         /* This only applies to conditional branches */
14562         if (TRIPLE_RHS(lnode->def->sizes) == 0) {
14563                 return;
14564         }
14565         cond = triple_to_lattice(state, scc, RHS(lnode->def,0));
14566         if (cond->val && !is_const(cond->val)) {
14567 #warning "FIXME do I need to do something here?"
14568                 warning(state, cond->def, "condition not constant?");
14569                 return;
14570         }
14571         if (cond->val == 0) {
14572                 scc_add_fedge(state, scc, cond->fblock->out);
14573                 scc_add_fedge(state, scc, cond->fblock->out->out_next);
14574         }
14575         else if (cond->val->u.cval) {
14576                 scc_add_fedge(state, scc, cond->fblock->out->out_next);
14577                 
14578         } else {
14579                 scc_add_fedge(state, scc, cond->fblock->out);
14580         }
14581
14582 }
14583
14584 static void scc_visit_expr(struct compile_state *state, struct scc_state *scc,
14585         struct lattice_node *lnode)
14586 {
14587         int changed;
14588
14589         changed = compute_lnode_val(state, scc, lnode);
14590 #if DEBUG_SCC
14591         {
14592                 struct triple **expr;
14593                 fprintf(stderr, "expr: %3d %10s (",
14594                         lnode->def->id, tops(lnode->def->op));
14595                 expr = triple_rhs(state, lnode->def, 0);
14596                 for(;expr;expr = triple_rhs(state, lnode->def, expr)) {
14597                         if (*expr) {
14598                                 fprintf(stderr, " %d", (*expr)->id);
14599                         }
14600                 }
14601                 fprintf(stderr, " ) -> %s\n",
14602                         (!lnode->val)? "lo": is_const(lnode->val)? "const": "hi");
14603         }
14604 #endif
14605         if (lnode->def->op == OP_BRANCH) {
14606                 scc_visit_branch(state, scc, lnode);
14607
14608         }
14609         else if (changed) {
14610                 struct ssa_edge *sedge;
14611                 for(sedge = lnode->out; sedge; sedge = sedge->out_next) {
14612                         scc_add_sedge(state, scc, sedge);
14613                 }
14614         }
14615 }
14616
14617 static void scc_writeback_values(
14618         struct compile_state *state, struct scc_state *scc)
14619 {
14620         struct triple *first, *ins;
14621         first = RHS(state->main_function, 0);
14622         ins = first;
14623         do {
14624                 struct lattice_node *lnode;
14625                 lnode = triple_to_lattice(state, scc, ins);
14626                 /* Restore id */
14627                 ins->id = lnode->old_id;
14628 #if DEBUG_SCC
14629                 if (lnode->val && !is_const(lnode->val)) {
14630                         warning(state, lnode->def, 
14631                                 "lattice node still high?");
14632                 }
14633 #endif
14634                 if (lnode->val && (lnode->val != ins)) {
14635                         /* See if it something I know how to write back */
14636                         switch(lnode->val->op) {
14637                         case OP_INTCONST:
14638                                 mkconst(state, ins, lnode->val->u.cval);
14639                                 break;
14640                         case OP_ADDRCONST:
14641                                 mkaddr_const(state, ins, 
14642                                         MISC(lnode->val, 0), lnode->val->u.cval);
14643                                 break;
14644                         default:
14645                                 /* By default don't copy the changes,
14646                                  * recompute them in place instead.
14647                                  */
14648                                 simplify(state, ins);
14649                                 break;
14650                         }
14651                         if (is_const(lnode->val) &&
14652                                 !constants_equal(state, lnode->val, ins)) {
14653                                 internal_error(state, 0, "constants not equal");
14654                         }
14655                         /* Free the lattice nodes */
14656                         xfree(lnode->val);
14657                         lnode->val = 0;
14658                 }
14659                 ins = ins->next;
14660         } while(ins != first);
14661 }
14662
14663 static void scc_transform(struct compile_state *state)
14664 {
14665         struct scc_state scc;
14666
14667         initialize_scc_state(state, &scc);
14668
14669         while(scc.flow_work_list || scc.ssa_work_list) {
14670                 struct flow_edge *fedge;
14671                 struct ssa_edge *sedge;
14672                 struct flow_edge *fptr;
14673                 while((fedge = scc_next_fedge(state, &scc))) {
14674                         struct block *block;
14675                         struct triple *ptr;
14676                         struct flow_block *fblock;
14677                         int time;
14678                         int done;
14679                         if (fedge->executable) {
14680                                 continue;
14681                         }
14682                         if (!fedge->dst) {
14683                                 internal_error(state, 0, "fedge without dst");
14684                         }
14685                         if (!fedge->src) {
14686                                 internal_error(state, 0, "fedge without src");
14687                         }
14688                         fedge->executable = 1;
14689                         fblock = fedge->dst;
14690                         block = fblock->block;
14691                         time = 0;
14692                         for(fptr = fblock->in; fptr; fptr = fptr->in_next) {
14693                                 if (fptr->executable) {
14694                                         time++;
14695                                 }
14696                         }
14697 #if DEBUG_SCC
14698                         fprintf(stderr, "vertex: %d time: %d\n", 
14699                                 block->vertex, time);
14700                         
14701 #endif
14702                         done = 0;
14703                         for(ptr = block->first; !done; ptr = ptr->next) {
14704                                 struct lattice_node *lnode;
14705                                 done = (ptr == block->last);
14706                                 lnode = &scc.lattice[ptr->id];
14707                                 if (ptr->op == OP_PHI) {
14708                                         scc_visit_phi(state, &scc, lnode);
14709                                 }
14710                                 else if (time == 1) {
14711                                         scc_visit_expr(state, &scc, lnode);
14712                                 }
14713                         }
14714                         if (fblock->out && !fblock->out->out_next) {
14715                                 scc_add_fedge(state, &scc, fblock->out);
14716                         }
14717                 }
14718                 while((sedge = scc_next_sedge(state, &scc))) {
14719                         struct lattice_node *lnode;
14720                         struct flow_block *fblock;
14721                         lnode = sedge->dst;
14722                         fblock = lnode->fblock;
14723 #if DEBUG_SCC
14724                         fprintf(stderr, "sedge: %5d (%5d -> %5d)\n",
14725                                 sedge - scc.ssa_edges,
14726                                 sedge->src->def->id,
14727                                 sedge->dst->def->id);
14728 #endif
14729                         if (lnode->def->op == OP_PHI) {
14730                                 scc_visit_phi(state, &scc, lnode);
14731                         }
14732                         else {
14733                                 for(fptr = fblock->in; fptr; fptr = fptr->in_next) {
14734                                         if (fptr->executable) {
14735                                                 break;
14736                                         }
14737                                 }
14738                                 if (fptr) {
14739                                         scc_visit_expr(state, &scc, lnode);
14740                                 }
14741                         }
14742                 }
14743         }
14744         
14745         scc_writeback_values(state, &scc);
14746         free_scc_state(state, &scc);
14747 }
14748
14749
14750 static void transform_to_arch_instructions(struct compile_state *state)
14751 {
14752         struct triple *ins, *first;
14753         first = RHS(state->main_function, 0);
14754         ins = first;
14755         do {
14756                 ins = transform_to_arch_instruction(state, ins);
14757         } while(ins != first);
14758 }
14759
14760 #if DEBUG_CONSISTENCY
14761 static void verify_uses(struct compile_state *state)
14762 {
14763         struct triple *first, *ins;
14764         struct triple_set *set;
14765         first = RHS(state->main_function, 0);
14766         ins = first;
14767         do {
14768                 struct triple **expr;
14769                 expr = triple_rhs(state, ins, 0);
14770                 for(; expr; expr = triple_rhs(state, ins, expr)) {
14771                         struct triple *rhs;
14772                         rhs = *expr;
14773                         for(set = rhs?rhs->use:0; set; set = set->next) {
14774                                 if (set->member == ins) {
14775                                         break;
14776                                 }
14777                         }
14778                         if (!set) {
14779                                 internal_error(state, ins, "rhs not used");
14780                         }
14781                 }
14782                 expr = triple_lhs(state, ins, 0);
14783                 for(; expr; expr = triple_lhs(state, ins, expr)) {
14784                         struct triple *lhs;
14785                         lhs = *expr;
14786                         for(set =  lhs?lhs->use:0; set; set = set->next) {
14787                                 if (set->member == ins) {
14788                                         break;
14789                                 }
14790                         }
14791                         if (!set) {
14792                                 internal_error(state, ins, "lhs not used");
14793                         }
14794                 }
14795                 ins = ins->next;
14796         } while(ins != first);
14797         
14798 }
14799 static void verify_blocks_present(struct compile_state *state)
14800 {
14801         struct triple *first, *ins;
14802         if (!state->first_block) {
14803                 return;
14804         }
14805         first = RHS(state->main_function, 0);
14806         ins = first;
14807         do {
14808                 valid_ins(state, ins);
14809                 if (triple_stores_block(state, ins)) {
14810                         if (!ins->u.block) {
14811                                 internal_error(state, ins, 
14812                                         "%p not in a block?\n", ins);
14813                         }
14814                 }
14815                 ins = ins->next;
14816         } while(ins != first);
14817         
14818         
14819 }
14820 static void verify_blocks(struct compile_state *state)
14821 {
14822         struct triple *ins;
14823         struct block *block;
14824         int blocks;
14825         block = state->first_block;
14826         if (!block) {
14827                 return;
14828         }
14829         blocks = 0;
14830         do {
14831                 int users;
14832                 struct block_set *user;
14833                 blocks++;
14834                 for(ins = block->first; ins != block->last->next; ins = ins->next) {
14835                         if (triple_stores_block(state, ins) && (ins->u.block != block)) {
14836                                 internal_error(state, ins, "inconsitent block specified");
14837                         }
14838                         valid_ins(state, ins);
14839                 }
14840                 users = 0;
14841                 for(user = block->use; user; user = user->next) {
14842                         users++;
14843                         if ((block == state->last_block) &&
14844                                 (user->member == state->first_block)) {
14845                                 continue;
14846                         }
14847                         if ((user->member->left != block) &&
14848                                 (user->member->right != block)) {
14849                                 internal_error(state, user->member->first,
14850                                         "user does not use block");
14851                         }
14852                 }
14853                 if (triple_is_branch(state, block->last) &&
14854                         (block->right != block_of_triple(state, TARG(block->last, 0))))
14855                 {
14856                         internal_error(state, block->last, "block->right != TARG(0)");
14857                 }
14858                 if (!triple_is_uncond_branch(state, block->last) &&
14859                         (block != state->last_block) &&
14860                         (block->left != block_of_triple(state, block->last->next)))
14861                 {
14862                         internal_error(state, block->last, "block->left != block->last->next");
14863                 }
14864                 if (block->left) {
14865                         for(user = block->left->use; user; user = user->next) {
14866                                 if (user->member == block) {
14867                                         break;
14868                                 }
14869                         }
14870                         if (!user || user->member != block) {
14871                                 internal_error(state, block->first,
14872                                         "block does not use left");
14873                         }
14874                 }
14875                 if (block->right) {
14876                         for(user = block->right->use; user; user = user->next) {
14877                                 if (user->member == block) {
14878                                         break;
14879                                 }
14880                         }
14881                         if (!user || user->member != block) {
14882                                 internal_error(state, block->first,
14883                                         "block does not use right");
14884                         }
14885                 }
14886                 if (block->users != users) {
14887                         internal_error(state, block->first, 
14888                                 "computed users %d != stored users %d\n",
14889                                 users, block->users);
14890                 }
14891                 if (!triple_stores_block(state, block->last->next)) {
14892                         internal_error(state, block->last->next, 
14893                                 "cannot find next block");
14894                 }
14895                 block = block->last->next->u.block;
14896                 if (!block) {
14897                         internal_error(state, block->last->next,
14898                                 "bad next block");
14899                 }
14900         } while(block != state->first_block);
14901         if (blocks != state->last_vertex) {
14902                 internal_error(state, 0, "computed blocks != stored blocks %d\n",
14903                         blocks, state->last_vertex);
14904         }
14905 }
14906
14907 static void verify_domination(struct compile_state *state)
14908 {
14909         struct triple *first, *ins;
14910         struct triple_set *set;
14911         if (!state->first_block) {
14912                 return;
14913         }
14914         
14915         first = RHS(state->main_function, 0);
14916         ins = first;
14917         do {
14918                 for(set = ins->use; set; set = set->next) {
14919                         struct triple **slot;
14920                         struct triple *use_point;
14921                         int i, zrhs;
14922                         use_point = 0;
14923                         zrhs = TRIPLE_RHS(ins->sizes);
14924                         slot = &RHS(set->member, 0);
14925                         /* See if the use is on the right hand side */
14926                         for(i = 0; i < zrhs; i++) {
14927                                 if (slot[i] == ins) {
14928                                         break;
14929                                 }
14930                         }
14931                         if (i < zrhs) {
14932                                 use_point = set->member;
14933                                 if (set->member->op == OP_PHI) {
14934                                         struct block_set *bset;
14935                                         int edge;
14936                                         bset = set->member->u.block->use;
14937                                         for(edge = 0; bset && (edge < i); edge++) {
14938                                                 bset = bset->next;
14939                                         }
14940                                         if (!bset) {
14941                                                 internal_error(state, set->member, 
14942                                                         "no edge for phi rhs %d\n", i);
14943                                         }
14944                                         use_point = bset->member->last;
14945                                 }
14946                         }
14947                         if (use_point &&
14948                                 !tdominates(state, ins, use_point)) {
14949                                 internal_warning(state, ins, 
14950                                         "ins does not dominate rhs use");
14951                                 internal_error(state, use_point, 
14952                                         "non dominated rhs use point?");
14953                         }
14954                 }
14955                 ins = ins->next;
14956         } while(ins != first);
14957 }
14958
14959 static void verify_piece(struct compile_state *state)
14960 {
14961         struct triple *first, *ins;
14962         first = RHS(state->main_function, 0);
14963         ins = first;
14964         do {
14965                 struct triple *ptr;
14966                 int lhs, i;
14967                 lhs = TRIPLE_LHS(ins->sizes);
14968                 for(ptr = ins->next, i = 0; i < lhs; i++, ptr = ptr->next) {
14969                         if (ptr != LHS(ins, i)) {
14970                                 internal_error(state, ins, "malformed lhs on %s",
14971                                         tops(ins->op));
14972                         }
14973                         if (ptr->op != OP_PIECE) {
14974                                 internal_error(state, ins, "bad lhs op %s at %d on %s",
14975                                         tops(ptr->op), i, tops(ins->op));
14976                         }
14977                         if (ptr->u.cval != i) {
14978                                 internal_error(state, ins, "bad u.cval of %d %d expected",
14979                                         ptr->u.cval, i);
14980                         }
14981                 }
14982                 ins = ins->next;
14983         } while(ins != first);
14984 }
14985 static void verify_ins_colors(struct compile_state *state)
14986 {
14987         struct triple *first, *ins;
14988         
14989         first = RHS(state->main_function, 0);
14990         ins = first;
14991         do {
14992                 ins = ins->next;
14993         } while(ins != first);
14994 }
14995 static void verify_consistency(struct compile_state *state)
14996 {
14997         verify_uses(state);
14998         verify_blocks_present(state);
14999         verify_blocks(state);
15000         verify_domination(state);
15001         verify_piece(state);
15002         verify_ins_colors(state);
15003 }
15004 #else 
15005 static void verify_consistency(struct compile_state *state) {}
15006 #endif /* DEBUG_USES */
15007
15008 static void optimize(struct compile_state *state)
15009 {
15010         if (state->debug & DEBUG_TRIPLES) {
15011                 print_triples(state);
15012         }
15013         /* Replace structures with simpler data types */
15014         flatten_structures(state);
15015         if (state->debug & DEBUG_TRIPLES) {
15016                 print_triples(state);
15017         }
15018         verify_consistency(state);
15019         /* Analize the intermediate code */
15020         setup_basic_blocks(state);
15021         analyze_idominators(state);
15022         analyze_ipdominators(state);
15023
15024         /* Transform the code to ssa form. */
15025         /*
15026          * The transformation to ssa form puts a phi function
15027          * on each of edge of a dominance frontier where that
15028          * phi function might be needed.  At -O2 if we don't
15029          * eleminate the excess phi functions we can get an
15030          * exponential code size growth.  So I kill the extra
15031          * phi functions early and I kill them often.
15032          */
15033         transform_to_ssa_form(state);
15034         eliminate_inefectual_code(state);
15035
15036         verify_consistency(state);
15037         if (state->debug & DEBUG_CODE_ELIMINATION) {
15038                 fprintf(stdout, "After transform_to_ssa_form\n");
15039                 print_blocks(state, stdout);
15040         }
15041         /* Do strength reduction and simple constant optimizations */
15042         if (state->optimize >= 1) {
15043                 simplify_all(state);
15044                 transform_from_ssa_form(state);
15045                 free_basic_blocks(state);
15046                 setup_basic_blocks(state);
15047                 analyze_idominators(state);
15048                 analyze_ipdominators(state);
15049                 transform_to_ssa_form(state);
15050                 eliminate_inefectual_code(state);
15051         }
15052         if (state->debug & DEBUG_CODE_ELIMINATION) {
15053                 fprintf(stdout, "After simplify_all\n");
15054                 print_blocks(state, stdout);
15055         }
15056         verify_consistency(state);
15057         /* Propogate constants throughout the code */
15058         if (state->optimize >= 2) {
15059                 scc_transform(state);
15060                 transform_from_ssa_form(state);
15061                 free_basic_blocks(state);
15062                 setup_basic_blocks(state);
15063                 analyze_idominators(state);
15064                 analyze_ipdominators(state);
15065                 transform_to_ssa_form(state);
15066                 eliminate_inefectual_code(state);
15067         }
15068         verify_consistency(state);
15069 #warning "WISHLIST implement single use constants (least possible register pressure)"
15070 #warning "WISHLIST implement induction variable elimination"
15071         /* Select architecture instructions and an initial partial
15072          * coloring based on architecture constraints.
15073          */
15074         transform_to_arch_instructions(state);
15075         verify_consistency(state);
15076         if (state->debug & DEBUG_ARCH_CODE) {
15077                 printf("After transform_to_arch_instructions\n");
15078                 print_blocks(state, stdout);
15079                 print_control_flow(state);
15080         }
15081         eliminate_inefectual_code(state);
15082         verify_consistency(state);
15083         if (state->debug & DEBUG_CODE_ELIMINATION) {
15084                 printf("After eliminate_inefectual_code\n");
15085                 print_blocks(state, stdout);
15086                 print_control_flow(state);
15087         }
15088         verify_consistency(state);
15089         /* Color all of the variables to see if they will fit in registers */
15090         insert_copies_to_phi(state);
15091         if (state->debug & DEBUG_INSERTED_COPIES) {
15092                 printf("After insert_copies_to_phi\n");
15093                 print_blocks(state, stdout);
15094                 print_control_flow(state);
15095         }
15096         verify_consistency(state);
15097         insert_mandatory_copies(state);
15098         if (state->debug & DEBUG_INSERTED_COPIES) {
15099                 printf("After insert_mandatory_copies\n");
15100                 print_blocks(state, stdout);
15101                 print_control_flow(state);
15102         }
15103         verify_consistency(state);
15104         allocate_registers(state);
15105         verify_consistency(state);
15106         if (state->debug & DEBUG_INTERMEDIATE_CODE) {
15107                 print_blocks(state, stdout);
15108         }
15109         if (state->debug & DEBUG_CONTROL_FLOW) {
15110                 print_control_flow(state);
15111         }
15112         /* Remove the optimization information.
15113          * This is more to check for memory consistency than to free memory.
15114          */
15115         free_basic_blocks(state);
15116 }
15117
15118 static void print_op_asm(struct compile_state *state,
15119         struct triple *ins, FILE *fp)
15120 {
15121         struct asm_info *info;
15122         const char *ptr;
15123         unsigned lhs, rhs, i;
15124         info = ins->u.ainfo;
15125         lhs = TRIPLE_LHS(ins->sizes);
15126         rhs = TRIPLE_RHS(ins->sizes);
15127         /* Don't count the clobbers in lhs */
15128         for(i = 0; i < lhs; i++) {
15129                 if (LHS(ins, i)->type == &void_type) {
15130                         break;
15131                 }
15132         }
15133         lhs = i;
15134         fprintf(fp, "#ASM\n");
15135         fputc('\t', fp);
15136         for(ptr = info->str; *ptr; ptr++) {
15137                 char *next;
15138                 unsigned long param;
15139                 struct triple *piece;
15140                 if (*ptr != '%') {
15141                         fputc(*ptr, fp);
15142                         continue;
15143                 }
15144                 ptr++;
15145                 if (*ptr == '%') {
15146                         fputc('%', fp);
15147                         continue;
15148                 }
15149                 param = strtoul(ptr, &next, 10);
15150                 if (ptr == next) {
15151                         error(state, ins, "Invalid asm template");
15152                 }
15153                 if (param >= (lhs + rhs)) {
15154                         error(state, ins, "Invalid param %%%u in asm template",
15155                                 param);
15156                 }
15157                 piece = (param < lhs)? LHS(ins, param) : RHS(ins, param - lhs);
15158                 fprintf(fp, "%s", 
15159                         arch_reg_str(ID_REG(piece->id)));
15160                 ptr = next -1;
15161         }
15162         fprintf(fp, "\n#NOT ASM\n");
15163 }
15164
15165
15166 /* Only use the low x86 byte registers.  This allows me
15167  * allocate the entire register when a byte register is used.
15168  */
15169 #define X86_4_8BIT_GPRS 1
15170
15171 /* Recognized x86 cpu variants */
15172 #define BAD_CPU      0
15173 #define CPU_I386     1
15174 #define CPU_P3       2
15175 #define CPU_P4       3
15176 #define CPU_K7       4
15177 #define CPU_K8       5
15178
15179 #define CPU_DEFAULT  CPU_I386
15180
15181 /* The x86 register classes */
15182 #define REGC_FLAGS       0
15183 #define REGC_GPR8        1
15184 #define REGC_GPR16       2
15185 #define REGC_GPR32       3
15186 #define REGC_DIVIDEND64  4
15187 #define REGC_DIVIDEND32  5
15188 #define REGC_MMX         6
15189 #define REGC_XMM         7
15190 #define REGC_GPR32_8     8
15191 #define REGC_GPR16_8     9
15192 #define REGC_GPR8_LO    10
15193 #define REGC_IMM32      11
15194 #define REGC_IMM16      12
15195 #define REGC_IMM8       13
15196 #define LAST_REGC  REGC_IMM8
15197 #if LAST_REGC >= MAX_REGC
15198 #error "MAX_REGC is to low"
15199 #endif
15200
15201 /* Register class masks */
15202 #define REGCM_FLAGS      (1 << REGC_FLAGS)
15203 #define REGCM_GPR8       (1 << REGC_GPR8)
15204 #define REGCM_GPR16      (1 << REGC_GPR16)
15205 #define REGCM_GPR32      (1 << REGC_GPR32)
15206 #define REGCM_DIVIDEND64 (1 << REGC_DIVIDEND64)
15207 #define REGCM_DIVIDEND32 (1 << REGC_DIVIDEND32)
15208 #define REGCM_MMX        (1 << REGC_MMX)
15209 #define REGCM_XMM        (1 << REGC_XMM)
15210 #define REGCM_GPR32_8    (1 << REGC_GPR32_8)
15211 #define REGCM_GPR16_8    (1 << REGC_GPR16_8)
15212 #define REGCM_GPR8_LO    (1 << REGC_GPR8_LO)
15213 #define REGCM_IMM32      (1 << REGC_IMM32)
15214 #define REGCM_IMM16      (1 << REGC_IMM16)
15215 #define REGCM_IMM8       (1 << REGC_IMM8)
15216 #define REGCM_ALL        ((1 << (LAST_REGC + 1)) - 1)
15217
15218 /* The x86 registers */
15219 #define REG_EFLAGS  2
15220 #define REGC_FLAGS_FIRST REG_EFLAGS
15221 #define REGC_FLAGS_LAST  REG_EFLAGS
15222 #define REG_AL      3
15223 #define REG_BL      4
15224 #define REG_CL      5
15225 #define REG_DL      6
15226 #define REG_AH      7
15227 #define REG_BH      8
15228 #define REG_CH      9
15229 #define REG_DH      10
15230 #define REGC_GPR8_LO_FIRST REG_AL
15231 #define REGC_GPR8_LO_LAST  REG_DL
15232 #define REGC_GPR8_FIRST  REG_AL
15233 #define REGC_GPR8_LAST   REG_DH
15234 #define REG_AX     11
15235 #define REG_BX     12
15236 #define REG_CX     13
15237 #define REG_DX     14
15238 #define REG_SI     15
15239 #define REG_DI     16
15240 #define REG_BP     17
15241 #define REG_SP     18
15242 #define REGC_GPR16_FIRST REG_AX
15243 #define REGC_GPR16_LAST  REG_SP
15244 #define REG_EAX    19
15245 #define REG_EBX    20
15246 #define REG_ECX    21
15247 #define REG_EDX    22
15248 #define REG_ESI    23
15249 #define REG_EDI    24
15250 #define REG_EBP    25
15251 #define REG_ESP    26
15252 #define REGC_GPR32_FIRST REG_EAX
15253 #define REGC_GPR32_LAST  REG_ESP
15254 #define REG_EDXEAX 27
15255 #define REGC_DIVIDEND64_FIRST REG_EDXEAX
15256 #define REGC_DIVIDEND64_LAST  REG_EDXEAX
15257 #define REG_DXAX   28
15258 #define REGC_DIVIDEND32_FIRST REG_DXAX
15259 #define REGC_DIVIDEND32_LAST  REG_DXAX
15260 #define REG_MMX0   29
15261 #define REG_MMX1   30
15262 #define REG_MMX2   31
15263 #define REG_MMX3   32
15264 #define REG_MMX4   33
15265 #define REG_MMX5   34
15266 #define REG_MMX6   35
15267 #define REG_MMX7   36
15268 #define REGC_MMX_FIRST REG_MMX0
15269 #define REGC_MMX_LAST  REG_MMX7
15270 #define REG_XMM0   37
15271 #define REG_XMM1   38
15272 #define REG_XMM2   39
15273 #define REG_XMM3   40
15274 #define REG_XMM4   41
15275 #define REG_XMM5   42
15276 #define REG_XMM6   43
15277 #define REG_XMM7   44
15278 #define REGC_XMM_FIRST REG_XMM0
15279 #define REGC_XMM_LAST  REG_XMM7
15280 #warning "WISHLIST figure out how to use pinsrw and pextrw to better use extended regs"
15281 #define LAST_REG   REG_XMM7
15282
15283 #define REGC_GPR32_8_FIRST REG_EAX
15284 #define REGC_GPR32_8_LAST  REG_EDX
15285 #define REGC_GPR16_8_FIRST REG_AX
15286 #define REGC_GPR16_8_LAST  REG_DX
15287
15288 #define REGC_IMM8_FIRST    -1
15289 #define REGC_IMM8_LAST     -1
15290 #define REGC_IMM16_FIRST   -2
15291 #define REGC_IMM16_LAST    -1
15292 #define REGC_IMM32_FIRST   -4
15293 #define REGC_IMM32_LAST    -1
15294
15295 #if LAST_REG >= MAX_REGISTERS
15296 #error "MAX_REGISTERS to low"
15297 #endif
15298
15299
15300 static unsigned regc_size[LAST_REGC +1] = {
15301         [REGC_FLAGS]      = REGC_FLAGS_LAST      - REGC_FLAGS_FIRST + 1,
15302         [REGC_GPR8]       = REGC_GPR8_LAST       - REGC_GPR8_FIRST + 1,
15303         [REGC_GPR16]      = REGC_GPR16_LAST      - REGC_GPR16_FIRST + 1,
15304         [REGC_GPR32]      = REGC_GPR32_LAST      - REGC_GPR32_FIRST + 1,
15305         [REGC_DIVIDEND64] = REGC_DIVIDEND64_LAST - REGC_DIVIDEND64_FIRST + 1,
15306         [REGC_DIVIDEND32] = REGC_DIVIDEND32_LAST - REGC_DIVIDEND32_FIRST + 1,
15307         [REGC_MMX]        = REGC_MMX_LAST        - REGC_MMX_FIRST + 1,
15308         [REGC_XMM]        = REGC_XMM_LAST        - REGC_XMM_FIRST + 1,
15309         [REGC_GPR32_8]    = REGC_GPR32_8_LAST    - REGC_GPR32_8_FIRST + 1,
15310         [REGC_GPR16_8]    = REGC_GPR16_8_LAST    - REGC_GPR16_8_FIRST + 1,
15311         [REGC_GPR8_LO]    = REGC_GPR8_LO_LAST    - REGC_GPR8_LO_FIRST + 1,
15312         [REGC_IMM32]      = 0,
15313         [REGC_IMM16]      = 0,
15314         [REGC_IMM8]       = 0,
15315 };
15316
15317 static const struct {
15318         int first, last;
15319 } regcm_bound[LAST_REGC + 1] = {
15320         [REGC_FLAGS]      = { REGC_FLAGS_FIRST,      REGC_FLAGS_LAST },
15321         [REGC_GPR8]       = { REGC_GPR8_FIRST,       REGC_GPR8_LAST },
15322         [REGC_GPR16]      = { REGC_GPR16_FIRST,      REGC_GPR16_LAST },
15323         [REGC_GPR32]      = { REGC_GPR32_FIRST,      REGC_GPR32_LAST },
15324         [REGC_DIVIDEND64] = { REGC_DIVIDEND64_FIRST, REGC_DIVIDEND64_LAST },
15325         [REGC_DIVIDEND32] = { REGC_DIVIDEND32_FIRST, REGC_DIVIDEND32_LAST },
15326         [REGC_MMX]        = { REGC_MMX_FIRST,        REGC_MMX_LAST },
15327         [REGC_XMM]        = { REGC_XMM_FIRST,        REGC_XMM_LAST },
15328         [REGC_GPR32_8]    = { REGC_GPR32_8_FIRST,    REGC_GPR32_8_LAST },
15329         [REGC_GPR16_8]    = { REGC_GPR16_8_FIRST,    REGC_GPR16_8_LAST },
15330         [REGC_GPR8_LO]    = { REGC_GPR8_LO_FIRST,    REGC_GPR8_LO_LAST },
15331         [REGC_IMM32]      = { REGC_IMM32_FIRST,      REGC_IMM32_LAST },
15332         [REGC_IMM16]      = { REGC_IMM16_FIRST,      REGC_IMM16_LAST },
15333         [REGC_IMM8]       = { REGC_IMM8_FIRST,       REGC_IMM8_LAST },
15334 };
15335
15336 static int arch_encode_cpu(const char *cpu)
15337 {
15338         struct cpu {
15339                 const char *name;
15340                 int cpu;
15341         } cpus[] = {
15342                 { "i386", CPU_I386 },
15343                 { "p3",   CPU_P3 },
15344                 { "p4",   CPU_P4 },
15345                 { "k7",   CPU_K7 },
15346                 { "k8",   CPU_K8 },
15347                 {  0,     BAD_CPU }
15348         };
15349         struct cpu *ptr;
15350         for(ptr = cpus; ptr->name; ptr++) {
15351                 if (strcmp(ptr->name, cpu) == 0) {
15352                         break;
15353                 }
15354         }
15355         return ptr->cpu;
15356 }
15357
15358 static unsigned arch_regc_size(struct compile_state *state, int class)
15359 {
15360         if ((class < 0) || (class > LAST_REGC)) {
15361                 return 0;
15362         }
15363         return regc_size[class];
15364 }
15365
15366 static int arch_regcm_intersect(unsigned regcm1, unsigned regcm2)
15367 {
15368         /* See if two register classes may have overlapping registers */
15369         unsigned gpr_mask = REGCM_GPR8 | REGCM_GPR8_LO | REGCM_GPR16_8 | REGCM_GPR16 |
15370                 REGCM_GPR32_8 | REGCM_GPR32 | 
15371                 REGCM_DIVIDEND32 | REGCM_DIVIDEND64;
15372
15373         /* Special case for the immediates */
15374         if ((regcm1 & (REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8)) &&
15375                 ((regcm1 & ~(REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8)) == 0) &&
15376                 (regcm2 & (REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8)) &&
15377                 ((regcm2 & ~(REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8)) == 0)) { 
15378                 return 0;
15379         }
15380         return (regcm1 & regcm2) ||
15381                 ((regcm1 & gpr_mask) && (regcm2 & gpr_mask));
15382 }
15383
15384 static void arch_reg_equivs(
15385         struct compile_state *state, unsigned *equiv, int reg)
15386 {
15387         if ((reg < 0) || (reg > LAST_REG)) {
15388                 internal_error(state, 0, "invalid register");
15389         }
15390         *equiv++ = reg;
15391         switch(reg) {
15392         case REG_AL:
15393 #if X86_4_8BIT_GPRS
15394                 *equiv++ = REG_AH;
15395 #endif
15396                 *equiv++ = REG_AX;
15397                 *equiv++ = REG_EAX;
15398                 *equiv++ = REG_DXAX;
15399                 *equiv++ = REG_EDXEAX;
15400                 break;
15401         case REG_AH:
15402 #if X86_4_8BIT_GPRS
15403                 *equiv++ = REG_AL;
15404 #endif
15405                 *equiv++ = REG_AX;
15406                 *equiv++ = REG_EAX;
15407                 *equiv++ = REG_DXAX;
15408                 *equiv++ = REG_EDXEAX;
15409                 break;
15410         case REG_BL:  
15411 #if X86_4_8BIT_GPRS
15412                 *equiv++ = REG_BH;
15413 #endif
15414                 *equiv++ = REG_BX;
15415                 *equiv++ = REG_EBX;
15416                 break;
15417
15418         case REG_BH:
15419 #if X86_4_8BIT_GPRS
15420                 *equiv++ = REG_BL;
15421 #endif
15422                 *equiv++ = REG_BX;
15423                 *equiv++ = REG_EBX;
15424                 break;
15425         case REG_CL:
15426 #if X86_4_8BIT_GPRS
15427                 *equiv++ = REG_CH;
15428 #endif
15429                 *equiv++ = REG_CX;
15430                 *equiv++ = REG_ECX;
15431                 break;
15432
15433         case REG_CH:
15434 #if X86_4_8BIT_GPRS
15435                 *equiv++ = REG_CL;
15436 #endif
15437                 *equiv++ = REG_CX;
15438                 *equiv++ = REG_ECX;
15439                 break;
15440         case REG_DL:
15441 #if X86_4_8BIT_GPRS
15442                 *equiv++ = REG_DH;
15443 #endif
15444                 *equiv++ = REG_DX;
15445                 *equiv++ = REG_EDX;
15446                 *equiv++ = REG_DXAX;
15447                 *equiv++ = REG_EDXEAX;
15448                 break;
15449         case REG_DH:
15450 #if X86_4_8BIT_GPRS
15451                 *equiv++ = REG_DL;
15452 #endif
15453                 *equiv++ = REG_DX;
15454                 *equiv++ = REG_EDX;
15455                 *equiv++ = REG_DXAX;
15456                 *equiv++ = REG_EDXEAX;
15457                 break;
15458         case REG_AX:
15459                 *equiv++ = REG_AL;
15460                 *equiv++ = REG_AH;
15461                 *equiv++ = REG_EAX;
15462                 *equiv++ = REG_DXAX;
15463                 *equiv++ = REG_EDXEAX;
15464                 break;
15465         case REG_BX:
15466                 *equiv++ = REG_BL;
15467                 *equiv++ = REG_BH;
15468                 *equiv++ = REG_EBX;
15469                 break;
15470         case REG_CX:  
15471                 *equiv++ = REG_CL;
15472                 *equiv++ = REG_CH;
15473                 *equiv++ = REG_ECX;
15474                 break;
15475         case REG_DX:  
15476                 *equiv++ = REG_DL;
15477                 *equiv++ = REG_DH;
15478                 *equiv++ = REG_EDX;
15479                 *equiv++ = REG_DXAX;
15480                 *equiv++ = REG_EDXEAX;
15481                 break;
15482         case REG_SI:  
15483                 *equiv++ = REG_ESI;
15484                 break;
15485         case REG_DI:
15486                 *equiv++ = REG_EDI;
15487                 break;
15488         case REG_BP:
15489                 *equiv++ = REG_EBP;
15490                 break;
15491         case REG_SP:
15492                 *equiv++ = REG_ESP;
15493                 break;
15494         case REG_EAX:
15495                 *equiv++ = REG_AL;
15496                 *equiv++ = REG_AH;
15497                 *equiv++ = REG_AX;
15498                 *equiv++ = REG_DXAX;
15499                 *equiv++ = REG_EDXEAX;
15500                 break;
15501         case REG_EBX:
15502                 *equiv++ = REG_BL;
15503                 *equiv++ = REG_BH;
15504                 *equiv++ = REG_BX;
15505                 break;
15506         case REG_ECX:
15507                 *equiv++ = REG_CL;
15508                 *equiv++ = REG_CH;
15509                 *equiv++ = REG_CX;
15510                 break;
15511         case REG_EDX:
15512                 *equiv++ = REG_DL;
15513                 *equiv++ = REG_DH;
15514                 *equiv++ = REG_DX;
15515                 *equiv++ = REG_DXAX;
15516                 *equiv++ = REG_EDXEAX;
15517                 break;
15518         case REG_ESI: 
15519                 *equiv++ = REG_SI;
15520                 break;
15521         case REG_EDI: 
15522                 *equiv++ = REG_DI;
15523                 break;
15524         case REG_EBP: 
15525                 *equiv++ = REG_BP;
15526                 break;
15527         case REG_ESP: 
15528                 *equiv++ = REG_SP;
15529                 break;
15530         case REG_DXAX: 
15531                 *equiv++ = REG_AL;
15532                 *equiv++ = REG_AH;
15533                 *equiv++ = REG_DL;
15534                 *equiv++ = REG_DH;
15535                 *equiv++ = REG_AX;
15536                 *equiv++ = REG_DX;
15537                 *equiv++ = REG_EAX;
15538                 *equiv++ = REG_EDX;
15539                 *equiv++ = REG_EDXEAX;
15540                 break;
15541         case REG_EDXEAX: 
15542                 *equiv++ = REG_AL;
15543                 *equiv++ = REG_AH;
15544                 *equiv++ = REG_DL;
15545                 *equiv++ = REG_DH;
15546                 *equiv++ = REG_AX;
15547                 *equiv++ = REG_DX;
15548                 *equiv++ = REG_EAX;
15549                 *equiv++ = REG_EDX;
15550                 *equiv++ = REG_DXAX;
15551                 break;
15552         }
15553         *equiv++ = REG_UNSET; 
15554 }
15555
15556 static unsigned arch_avail_mask(struct compile_state *state)
15557 {
15558         unsigned avail_mask;
15559         /* REGCM_GPR8 is not available */
15560         avail_mask = REGCM_GPR8_LO | REGCM_GPR16_8 | REGCM_GPR16 | 
15561                 REGCM_GPR32 | REGCM_GPR32_8 | 
15562                 REGCM_DIVIDEND32 | REGCM_DIVIDEND64 |
15563                 REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8 | REGCM_FLAGS;
15564         switch(state->cpu) {
15565         case CPU_P3:
15566         case CPU_K7:
15567                 avail_mask |= REGCM_MMX;
15568                 break;
15569         case CPU_P4:
15570         case CPU_K8:
15571                 avail_mask |= REGCM_MMX | REGCM_XMM;
15572                 break;
15573         }
15574         return avail_mask;
15575 }
15576
15577 static unsigned arch_regcm_normalize(struct compile_state *state, unsigned regcm)
15578 {
15579         unsigned mask, result;
15580         int class, class2;
15581         result = regcm;
15582
15583         for(class = 0, mask = 1; mask; mask <<= 1, class++) {
15584                 if ((result & mask) == 0) {
15585                         continue;
15586                 }
15587                 if (class > LAST_REGC) {
15588                         result &= ~mask;
15589                 }
15590                 for(class2 = 0; class2 <= LAST_REGC; class2++) {
15591                         if ((regcm_bound[class2].first >= regcm_bound[class].first) &&
15592                                 (regcm_bound[class2].last <= regcm_bound[class].last)) {
15593                                 result |= (1 << class2);
15594                         }
15595                 }
15596         }
15597         result &= arch_avail_mask(state);
15598         return result;
15599 }
15600
15601 static unsigned arch_regcm_reg_normalize(struct compile_state *state, unsigned regcm)
15602 {
15603         /* Like arch_regcm_normalize except immediate register classes are excluded */
15604         regcm = arch_regcm_normalize(state, regcm);
15605         /* Remove the immediate register classes */
15606         regcm &= ~(REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8);
15607         return regcm;
15608         
15609 }
15610
15611 static unsigned arch_reg_regcm(struct compile_state *state, int reg)
15612 {
15613         unsigned mask;
15614         int class;
15615         mask = 0;
15616         for(class = 0; class <= LAST_REGC; class++) {
15617                 if ((reg >= regcm_bound[class].first) &&
15618                         (reg <= regcm_bound[class].last)) {
15619                         mask |= (1 << class);
15620                 }
15621         }
15622         if (!mask) {
15623                 internal_error(state, 0, "reg %d not in any class", reg);
15624         }
15625         return mask;
15626 }
15627
15628 static struct reg_info arch_reg_constraint(
15629         struct compile_state *state, struct type *type, const char *constraint)
15630 {
15631         static const struct {
15632                 char class;
15633                 unsigned int mask;
15634                 unsigned int reg;
15635         } constraints[] = {
15636                 { 'r', REGCM_GPR32,   REG_UNSET },
15637                 { 'g', REGCM_GPR32,   REG_UNSET },
15638                 { 'p', REGCM_GPR32,   REG_UNSET },
15639                 { 'q', REGCM_GPR8_LO, REG_UNSET },
15640                 { 'Q', REGCM_GPR32_8, REG_UNSET },
15641                 { 'x', REGCM_XMM,     REG_UNSET },
15642                 { 'y', REGCM_MMX,     REG_UNSET },
15643                 { 'a', REGCM_GPR32,   REG_EAX },
15644                 { 'b', REGCM_GPR32,   REG_EBX },
15645                 { 'c', REGCM_GPR32,   REG_ECX },
15646                 { 'd', REGCM_GPR32,   REG_EDX },
15647                 { 'D', REGCM_GPR32,   REG_EDI },
15648                 { 'S', REGCM_GPR32,   REG_ESI },
15649                 { '\0', 0, REG_UNSET },
15650         };
15651         unsigned int regcm;
15652         unsigned int mask, reg;
15653         struct reg_info result;
15654         const char *ptr;
15655         regcm = arch_type_to_regcm(state, type);
15656         reg = REG_UNSET;
15657         mask = 0;
15658         for(ptr = constraint; *ptr; ptr++) {
15659                 int i;
15660                 if (*ptr ==  ' ') {
15661                         continue;
15662                 }
15663                 for(i = 0; constraints[i].class != '\0'; i++) {
15664                         if (constraints[i].class == *ptr) {
15665                                 break;
15666                         }
15667                 }
15668                 if (constraints[i].class == '\0') {
15669                         error(state, 0, "invalid register constraint ``%c''", *ptr);
15670                         break;
15671                 }
15672                 if ((constraints[i].mask & regcm) == 0) {
15673                         error(state, 0, "invalid register class %c specified",
15674                                 *ptr);
15675                 }
15676                 mask |= constraints[i].mask;
15677                 if (constraints[i].reg != REG_UNSET) {
15678                         if ((reg != REG_UNSET) && (reg != constraints[i].reg)) {
15679                                 error(state, 0, "Only one register may be specified");
15680                         }
15681                         reg = constraints[i].reg;
15682                 }
15683         }
15684         result.reg = reg;
15685         result.regcm = mask;
15686         return result;
15687 }
15688
15689 static struct reg_info arch_reg_clobber(
15690         struct compile_state *state, const char *clobber)
15691 {
15692         struct reg_info result;
15693         if (strcmp(clobber, "memory") == 0) {
15694                 result.reg = REG_UNSET;
15695                 result.regcm = 0;
15696         }
15697         else if (strcmp(clobber, "%eax") == 0) {
15698                 result.reg = REG_EAX;
15699                 result.regcm = REGCM_GPR32;
15700         }
15701         else if (strcmp(clobber, "%ebx") == 0) {
15702                 result.reg = REG_EBX;
15703                 result.regcm = REGCM_GPR32;
15704         }
15705         else if (strcmp(clobber, "%ecx") == 0) {
15706                 result.reg = REG_ECX;
15707                 result.regcm = REGCM_GPR32;
15708         }
15709         else if (strcmp(clobber, "%edx") == 0) {
15710                 result.reg = REG_EDX;
15711                 result.regcm = REGCM_GPR32;
15712         }
15713         else if (strcmp(clobber, "%esi") == 0) {
15714                 result.reg = REG_ESI;
15715                 result.regcm = REGCM_GPR32;
15716         }
15717         else if (strcmp(clobber, "%edi") == 0) {
15718                 result.reg = REG_EDI;
15719                 result.regcm = REGCM_GPR32;
15720         }
15721         else if (strcmp(clobber, "%ebp") == 0) {
15722                 result.reg = REG_EBP;
15723                 result.regcm = REGCM_GPR32;
15724         }
15725         else if (strcmp(clobber, "%esp") == 0) {
15726                 result.reg = REG_ESP;
15727                 result.regcm = REGCM_GPR32;
15728         }
15729         else if (strcmp(clobber, "cc") == 0) {
15730                 result.reg = REG_EFLAGS;
15731                 result.regcm = REGCM_FLAGS;
15732         }
15733         else if ((strncmp(clobber, "xmm", 3) == 0)  &&
15734                 octdigitp(clobber[3]) && (clobber[4] == '\0')) {
15735                 result.reg = REG_XMM0 + octdigval(clobber[3]);
15736                 result.regcm = REGCM_XMM;
15737         }
15738         else if ((strncmp(clobber, "mmx", 3) == 0) &&
15739                 octdigitp(clobber[3]) && (clobber[4] == '\0')) {
15740                 result.reg = REG_MMX0 + octdigval(clobber[3]);
15741                 result.regcm = REGCM_MMX;
15742         }
15743         else {
15744                 error(state, 0, "Invalid register clobber");
15745                 result.reg = REG_UNSET;
15746                 result.regcm = 0;
15747         }
15748         return result;
15749 }
15750
15751 static int do_select_reg(struct compile_state *state, 
15752         char *used, int reg, unsigned classes)
15753 {
15754         unsigned mask;
15755         if (used[reg]) {
15756                 return REG_UNSET;
15757         }
15758         mask = arch_reg_regcm(state, reg);
15759         return (classes & mask) ? reg : REG_UNSET;
15760 }
15761
15762 static int arch_select_free_register(
15763         struct compile_state *state, char *used, int classes)
15764 {
15765         /* Live ranges with the most neighbors are colored first.
15766          *
15767          * Generally it does not matter which colors are given
15768          * as the register allocator attempts to color live ranges
15769          * in an order where you are guaranteed not to run out of colors.
15770          *
15771          * Occasionally the register allocator cannot find an order
15772          * of register selection that will find a free color.  To
15773          * increase the odds the register allocator will work when
15774          * it guesses first give out registers from register classes
15775          * least likely to run out of registers.
15776          * 
15777          */
15778         int i, reg;
15779         reg = REG_UNSET;
15780         for(i = REGC_XMM_FIRST; (reg == REG_UNSET) && (i <= REGC_XMM_LAST); i++) {
15781                 reg = do_select_reg(state, used, i, classes);
15782         }
15783         for(i = REGC_MMX_FIRST; (reg == REG_UNSET) && (i <= REGC_MMX_LAST); i++) {
15784                 reg = do_select_reg(state, used, i, classes);
15785         }
15786         for(i = REGC_GPR32_LAST; (reg == REG_UNSET) && (i >= REGC_GPR32_FIRST); i--) {
15787                 reg = do_select_reg(state, used, i, classes);
15788         }
15789         for(i = REGC_GPR16_FIRST; (reg == REG_UNSET) && (i <= REGC_GPR16_LAST); i++) {
15790                 reg = do_select_reg(state, used, i, classes);
15791         }
15792         for(i = REGC_GPR8_FIRST; (reg == REG_UNSET) && (i <= REGC_GPR8_LAST); i++) {
15793                 reg = do_select_reg(state, used, i, classes);
15794         }
15795         for(i = REGC_GPR8_LO_FIRST; (reg == REG_UNSET) && (i <= REGC_GPR8_LO_LAST); i++) {
15796                 reg = do_select_reg(state, used, i, classes);
15797         }
15798         for(i = REGC_DIVIDEND32_FIRST; (reg == REG_UNSET) && (i <= REGC_DIVIDEND32_LAST); i++) {
15799                 reg = do_select_reg(state, used, i, classes);
15800         }
15801         for(i = REGC_DIVIDEND64_FIRST; (reg == REG_UNSET) && (i <= REGC_DIVIDEND64_LAST); i++) {
15802                 reg = do_select_reg(state, used, i, classes);
15803         }
15804         for(i = REGC_FLAGS_FIRST; (reg == REG_UNSET) && (i <= REGC_FLAGS_LAST); i++) {
15805                 reg = do_select_reg(state, used, i, classes);
15806         }
15807         return reg;
15808 }
15809
15810
15811 static unsigned arch_type_to_regcm(struct compile_state *state, struct type *type) 
15812 {
15813 #warning "FIXME force types smaller (if legal) before I get here"
15814         unsigned mask;
15815         mask = 0;
15816         switch(type->type & TYPE_MASK) {
15817         case TYPE_ARRAY:
15818         case TYPE_VOID: 
15819                 mask = 0; 
15820                 break;
15821         case TYPE_CHAR:
15822         case TYPE_UCHAR:
15823                 mask = REGCM_GPR8 | REGCM_GPR8_LO |
15824                         REGCM_GPR16 | REGCM_GPR16_8 | 
15825                         REGCM_GPR32 | REGCM_GPR32_8 |
15826                         REGCM_DIVIDEND32 | REGCM_DIVIDEND64 |
15827                         REGCM_MMX | REGCM_XMM |
15828                         REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8;
15829                 break;
15830         case TYPE_SHORT:
15831         case TYPE_USHORT:
15832                 mask =  REGCM_GPR16 | REGCM_GPR16_8 |
15833                         REGCM_GPR32 | REGCM_GPR32_8 |
15834                         REGCM_DIVIDEND32 | REGCM_DIVIDEND64 |
15835                         REGCM_MMX | REGCM_XMM |
15836                         REGCM_IMM32 | REGCM_IMM16;
15837                 break;
15838         case TYPE_INT:
15839         case TYPE_UINT:
15840         case TYPE_LONG:
15841         case TYPE_ULONG:
15842         case TYPE_POINTER:
15843                 mask =  REGCM_GPR32 | REGCM_GPR32_8 |
15844                         REGCM_DIVIDEND32 | REGCM_DIVIDEND64 |
15845                         REGCM_MMX | REGCM_XMM |
15846                         REGCM_IMM32;
15847                 break;
15848         default:
15849                 internal_error(state, 0, "no register class for type");
15850                 break;
15851         }
15852         mask = arch_regcm_normalize(state, mask);
15853         return mask;
15854 }
15855
15856 static int is_imm32(struct triple *imm)
15857 {
15858         return ((imm->op == OP_INTCONST) && (imm->u.cval <= 0xffffffffUL)) ||
15859                 (imm->op == OP_ADDRCONST);
15860         
15861 }
15862 static int is_imm16(struct triple *imm)
15863 {
15864         return ((imm->op == OP_INTCONST) && (imm->u.cval <= 0xffff));
15865 }
15866 static int is_imm8(struct triple *imm)
15867 {
15868         return ((imm->op == OP_INTCONST) && (imm->u.cval <= 0xff));
15869 }
15870
15871 static int get_imm32(struct triple *ins, struct triple **expr)
15872 {
15873         struct triple *imm;
15874         imm = *expr;
15875         while(imm->op == OP_COPY) {
15876                 imm = RHS(imm, 0);
15877         }
15878         if (!is_imm32(imm)) {
15879                 return 0;
15880         }
15881         unuse_triple(*expr, ins);
15882         use_triple(imm, ins);
15883         *expr = imm;
15884         return 1;
15885 }
15886
15887 static int get_imm8(struct triple *ins, struct triple **expr)
15888 {
15889         struct triple *imm;
15890         imm = *expr;
15891         while(imm->op == OP_COPY) {
15892                 imm = RHS(imm, 0);
15893         }
15894         if (!is_imm8(imm)) {
15895                 return 0;
15896         }
15897         unuse_triple(*expr, ins);
15898         use_triple(imm, ins);
15899         *expr = imm;
15900         return 1;
15901 }
15902
15903 #define TEMPLATE_NOP           0
15904 #define TEMPLATE_INTCONST8     1
15905 #define TEMPLATE_INTCONST32    2
15906 #define TEMPLATE_COPY8_REG     3
15907 #define TEMPLATE_COPY16_REG    4
15908 #define TEMPLATE_COPY32_REG    5
15909 #define TEMPLATE_COPY_IMM8     6
15910 #define TEMPLATE_COPY_IMM16    7
15911 #define TEMPLATE_COPY_IMM32    8
15912 #define TEMPLATE_PHI8          9
15913 #define TEMPLATE_PHI16        10
15914 #define TEMPLATE_PHI32        11
15915 #define TEMPLATE_STORE8       12
15916 #define TEMPLATE_STORE16      13
15917 #define TEMPLATE_STORE32      14
15918 #define TEMPLATE_LOAD8        15
15919 #define TEMPLATE_LOAD16       16
15920 #define TEMPLATE_LOAD32       17
15921 #define TEMPLATE_BINARY8_REG  18
15922 #define TEMPLATE_BINARY16_REG 19
15923 #define TEMPLATE_BINARY32_REG 20
15924 #define TEMPLATE_BINARY8_IMM  21
15925 #define TEMPLATE_BINARY16_IMM 22
15926 #define TEMPLATE_BINARY32_IMM 23
15927 #define TEMPLATE_SL8_CL       24
15928 #define TEMPLATE_SL16_CL      25
15929 #define TEMPLATE_SL32_CL      26
15930 #define TEMPLATE_SL8_IMM      27
15931 #define TEMPLATE_SL16_IMM     28
15932 #define TEMPLATE_SL32_IMM     29
15933 #define TEMPLATE_UNARY8       30
15934 #define TEMPLATE_UNARY16      31
15935 #define TEMPLATE_UNARY32      32
15936 #define TEMPLATE_CMP8_REG     33
15937 #define TEMPLATE_CMP16_REG    34
15938 #define TEMPLATE_CMP32_REG    35
15939 #define TEMPLATE_CMP8_IMM     36
15940 #define TEMPLATE_CMP16_IMM    37
15941 #define TEMPLATE_CMP32_IMM    38
15942 #define TEMPLATE_TEST8        39
15943 #define TEMPLATE_TEST16       40
15944 #define TEMPLATE_TEST32       41
15945 #define TEMPLATE_SET          42
15946 #define TEMPLATE_JMP          43
15947 #define TEMPLATE_INB_DX       44
15948 #define TEMPLATE_INB_IMM      45
15949 #define TEMPLATE_INW_DX       46
15950 #define TEMPLATE_INW_IMM      47
15951 #define TEMPLATE_INL_DX       48
15952 #define TEMPLATE_INL_IMM      49
15953 #define TEMPLATE_OUTB_DX      50
15954 #define TEMPLATE_OUTB_IMM     51
15955 #define TEMPLATE_OUTW_DX      52
15956 #define TEMPLATE_OUTW_IMM     53
15957 #define TEMPLATE_OUTL_DX      54
15958 #define TEMPLATE_OUTL_IMM     55
15959 #define TEMPLATE_BSF          56
15960 #define TEMPLATE_RDMSR        57
15961 #define TEMPLATE_WRMSR        58
15962 #define TEMPLATE_UMUL8        59
15963 #define TEMPLATE_UMUL16       60
15964 #define TEMPLATE_UMUL32       61
15965 #define TEMPLATE_DIV8         62
15966 #define TEMPLATE_DIV16        63
15967 #define TEMPLATE_DIV32        64
15968 #define LAST_TEMPLATE       TEMPLATE_DIV32
15969 #if LAST_TEMPLATE >= MAX_TEMPLATES
15970 #error "MAX_TEMPLATES to low"
15971 #endif
15972
15973 #define COPY8_REGCM     (REGCM_DIVIDEND64 | REGCM_DIVIDEND32 | REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO | REGCM_MMX | REGCM_XMM)
15974 #define COPY16_REGCM    (REGCM_DIVIDEND64 | REGCM_DIVIDEND32 | REGCM_GPR32 | REGCM_GPR16 | REGCM_MMX | REGCM_XMM)  
15975 #define COPY32_REGCM    (REGCM_DIVIDEND64 | REGCM_DIVIDEND32 | REGCM_GPR32 | REGCM_MMX | REGCM_XMM)
15976
15977
15978 static struct ins_template templates[] = {
15979         [TEMPLATE_NOP]      = {},
15980         [TEMPLATE_INTCONST8] = { 
15981                 .lhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
15982         },
15983         [TEMPLATE_INTCONST32] = { 
15984                 .lhs = { [0] = { REG_UNNEEDED, REGCM_IMM32 } },
15985         },
15986         [TEMPLATE_COPY8_REG] = {
15987                 .lhs = { [0] = { REG_UNSET, COPY8_REGCM } },
15988                 .rhs = { [0] = { REG_UNSET, COPY8_REGCM }  },
15989         },
15990         [TEMPLATE_COPY16_REG] = {
15991                 .lhs = { [0] = { REG_UNSET, COPY16_REGCM } },
15992                 .rhs = { [0] = { REG_UNSET, COPY16_REGCM }  },
15993         },
15994         [TEMPLATE_COPY32_REG] = {
15995                 .lhs = { [0] = { REG_UNSET, COPY32_REGCM } },
15996                 .rhs = { [0] = { REG_UNSET, COPY32_REGCM }  },
15997         },
15998         [TEMPLATE_COPY_IMM8] = {
15999                 .lhs = { [0] = { REG_UNSET, COPY8_REGCM } },
16000                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
16001         },
16002         [TEMPLATE_COPY_IMM16] = {
16003                 .lhs = { [0] = { REG_UNSET, COPY16_REGCM } },
16004                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM16 | REGCM_IMM8 } },
16005         },
16006         [TEMPLATE_COPY_IMM32] = {
16007                 .lhs = { [0] = { REG_UNSET, COPY32_REGCM } },
16008                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8 } },
16009         },
16010         [TEMPLATE_PHI8] = { 
16011                 .lhs = { [0] = { REG_VIRT0, COPY8_REGCM } },
16012                 .rhs = { 
16013                         [ 0] = { REG_VIRT0, COPY8_REGCM },
16014                         [ 1] = { REG_VIRT0, COPY8_REGCM },
16015                         [ 2] = { REG_VIRT0, COPY8_REGCM },
16016                         [ 3] = { REG_VIRT0, COPY8_REGCM },
16017                         [ 4] = { REG_VIRT0, COPY8_REGCM },
16018                         [ 5] = { REG_VIRT0, COPY8_REGCM },
16019                         [ 6] = { REG_VIRT0, COPY8_REGCM },
16020                         [ 7] = { REG_VIRT0, COPY8_REGCM },
16021                         [ 8] = { REG_VIRT0, COPY8_REGCM },
16022                         [ 9] = { REG_VIRT0, COPY8_REGCM },
16023                         [10] = { REG_VIRT0, COPY8_REGCM },
16024                         [11] = { REG_VIRT0, COPY8_REGCM },
16025                         [12] = { REG_VIRT0, COPY8_REGCM },
16026                         [13] = { REG_VIRT0, COPY8_REGCM },
16027                         [14] = { REG_VIRT0, COPY8_REGCM },
16028                         [15] = { REG_VIRT0, COPY8_REGCM },
16029                 }, },
16030         [TEMPLATE_PHI16] = { 
16031                 .lhs = { [0] = { REG_VIRT0, COPY16_REGCM } },
16032                 .rhs = { 
16033                         [ 0] = { REG_VIRT0, COPY16_REGCM },
16034                         [ 1] = { REG_VIRT0, COPY16_REGCM },
16035                         [ 2] = { REG_VIRT0, COPY16_REGCM },
16036                         [ 3] = { REG_VIRT0, COPY16_REGCM },
16037                         [ 4] = { REG_VIRT0, COPY16_REGCM },
16038                         [ 5] = { REG_VIRT0, COPY16_REGCM },
16039                         [ 6] = { REG_VIRT0, COPY16_REGCM },
16040                         [ 7] = { REG_VIRT0, COPY16_REGCM },
16041                         [ 8] = { REG_VIRT0, COPY16_REGCM },
16042                         [ 9] = { REG_VIRT0, COPY16_REGCM },
16043                         [10] = { REG_VIRT0, COPY16_REGCM },
16044                         [11] = { REG_VIRT0, COPY16_REGCM },
16045                         [12] = { REG_VIRT0, COPY16_REGCM },
16046                         [13] = { REG_VIRT0, COPY16_REGCM },
16047                         [14] = { REG_VIRT0, COPY16_REGCM },
16048                         [15] = { REG_VIRT0, COPY16_REGCM },
16049                 }, },
16050         [TEMPLATE_PHI32] = { 
16051                 .lhs = { [0] = { REG_VIRT0, COPY32_REGCM } },
16052                 .rhs = { 
16053                         [ 0] = { REG_VIRT0, COPY32_REGCM },
16054                         [ 1] = { REG_VIRT0, COPY32_REGCM },
16055                         [ 2] = { REG_VIRT0, COPY32_REGCM },
16056                         [ 3] = { REG_VIRT0, COPY32_REGCM },
16057                         [ 4] = { REG_VIRT0, COPY32_REGCM },
16058                         [ 5] = { REG_VIRT0, COPY32_REGCM },
16059                         [ 6] = { REG_VIRT0, COPY32_REGCM },
16060                         [ 7] = { REG_VIRT0, COPY32_REGCM },
16061                         [ 8] = { REG_VIRT0, COPY32_REGCM },
16062                         [ 9] = { REG_VIRT0, COPY32_REGCM },
16063                         [10] = { REG_VIRT0, COPY32_REGCM },
16064                         [11] = { REG_VIRT0, COPY32_REGCM },
16065                         [12] = { REG_VIRT0, COPY32_REGCM },
16066                         [13] = { REG_VIRT0, COPY32_REGCM },
16067                         [14] = { REG_VIRT0, COPY32_REGCM },
16068                         [15] = { REG_VIRT0, COPY32_REGCM },
16069                 }, },
16070         [TEMPLATE_STORE8] = {
16071                 .rhs = { 
16072                         [0] = { REG_UNSET, REGCM_GPR32 },
16073                         [1] = { REG_UNSET, REGCM_GPR8_LO },
16074                 },
16075         },
16076         [TEMPLATE_STORE16] = {
16077                 .rhs = { 
16078                         [0] = { REG_UNSET, REGCM_GPR32 },
16079                         [1] = { REG_UNSET, REGCM_GPR16 },
16080                 },
16081         },
16082         [TEMPLATE_STORE32] = {
16083                 .rhs = { 
16084                         [0] = { REG_UNSET, REGCM_GPR32 },
16085                         [1] = { REG_UNSET, REGCM_GPR32 },
16086                 },
16087         },
16088         [TEMPLATE_LOAD8] = {
16089                 .lhs = { [0] = { REG_UNSET, REGCM_GPR8_LO } },
16090                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
16091         },
16092         [TEMPLATE_LOAD16] = {
16093                 .lhs = { [0] = { REG_UNSET, REGCM_GPR16 } },
16094                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
16095         },
16096         [TEMPLATE_LOAD32] = {
16097                 .lhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
16098                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
16099         },
16100         [TEMPLATE_BINARY8_REG] = {
16101                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
16102                 .rhs = { 
16103                         [0] = { REG_VIRT0, REGCM_GPR8_LO },
16104                         [1] = { REG_UNSET, REGCM_GPR8_LO },
16105                 },
16106         },
16107         [TEMPLATE_BINARY16_REG] = {
16108                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
16109                 .rhs = { 
16110                         [0] = { REG_VIRT0, REGCM_GPR16 },
16111                         [1] = { REG_UNSET, REGCM_GPR16 },
16112                 },
16113         },
16114         [TEMPLATE_BINARY32_REG] = {
16115                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
16116                 .rhs = { 
16117                         [0] = { REG_VIRT0, REGCM_GPR32 },
16118                         [1] = { REG_UNSET, REGCM_GPR32 },
16119                 },
16120         },
16121         [TEMPLATE_BINARY8_IMM] = {
16122                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
16123                 .rhs = { 
16124                         [0] = { REG_VIRT0,    REGCM_GPR8_LO },
16125                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
16126                 },
16127         },
16128         [TEMPLATE_BINARY16_IMM] = {
16129                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
16130                 .rhs = { 
16131                         [0] = { REG_VIRT0,    REGCM_GPR16 },
16132                         [1] = { REG_UNNEEDED, REGCM_IMM16 },
16133                 },
16134         },
16135         [TEMPLATE_BINARY32_IMM] = {
16136                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
16137                 .rhs = { 
16138                         [0] = { REG_VIRT0,    REGCM_GPR32 },
16139                         [1] = { REG_UNNEEDED, REGCM_IMM32 },
16140                 },
16141         },
16142         [TEMPLATE_SL8_CL] = {
16143                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
16144                 .rhs = { 
16145                         [0] = { REG_VIRT0, REGCM_GPR8_LO },
16146                         [1] = { REG_CL, REGCM_GPR8_LO },
16147                 },
16148         },
16149         [TEMPLATE_SL16_CL] = {
16150                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
16151                 .rhs = { 
16152                         [0] = { REG_VIRT0, REGCM_GPR16 },
16153                         [1] = { REG_CL, REGCM_GPR8_LO },
16154                 },
16155         },
16156         [TEMPLATE_SL32_CL] = {
16157                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
16158                 .rhs = { 
16159                         [0] = { REG_VIRT0, REGCM_GPR32 },
16160                         [1] = { REG_CL, REGCM_GPR8_LO },
16161                 },
16162         },
16163         [TEMPLATE_SL8_IMM] = {
16164                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
16165                 .rhs = { 
16166                         [0] = { REG_VIRT0,    REGCM_GPR8_LO },
16167                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
16168                 },
16169         },
16170         [TEMPLATE_SL16_IMM] = {
16171                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
16172                 .rhs = { 
16173                         [0] = { REG_VIRT0,    REGCM_GPR16 },
16174                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
16175                 },
16176         },
16177         [TEMPLATE_SL32_IMM] = {
16178                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
16179                 .rhs = { 
16180                         [0] = { REG_VIRT0,    REGCM_GPR32 },
16181                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
16182                 },
16183         },
16184         [TEMPLATE_UNARY8] = {
16185                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
16186                 .rhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
16187         },
16188         [TEMPLATE_UNARY16] = {
16189                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
16190                 .rhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
16191         },
16192         [TEMPLATE_UNARY32] = {
16193                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
16194                 .rhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
16195         },
16196         [TEMPLATE_CMP8_REG] = {
16197                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
16198                 .rhs = {
16199                         [0] = { REG_UNSET, REGCM_GPR8_LO },
16200                         [1] = { REG_UNSET, REGCM_GPR8_LO },
16201                 },
16202         },
16203         [TEMPLATE_CMP16_REG] = {
16204                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
16205                 .rhs = {
16206                         [0] = { REG_UNSET, REGCM_GPR16 },
16207                         [1] = { REG_UNSET, REGCM_GPR16 },
16208                 },
16209         },
16210         [TEMPLATE_CMP32_REG] = {
16211                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
16212                 .rhs = {
16213                         [0] = { REG_UNSET, REGCM_GPR32 },
16214                         [1] = { REG_UNSET, REGCM_GPR32 },
16215                 },
16216         },
16217         [TEMPLATE_CMP8_IMM] = {
16218                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
16219                 .rhs = {
16220                         [0] = { REG_UNSET, REGCM_GPR8_LO },
16221                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
16222                 },
16223         },
16224         [TEMPLATE_CMP16_IMM] = {
16225                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
16226                 .rhs = {
16227                         [0] = { REG_UNSET, REGCM_GPR16 },
16228                         [1] = { REG_UNNEEDED, REGCM_IMM16 },
16229                 },
16230         },
16231         [TEMPLATE_CMP32_IMM] = {
16232                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
16233                 .rhs = {
16234                         [0] = { REG_UNSET, REGCM_GPR32 },
16235                         [1] = { REG_UNNEEDED, REGCM_IMM32 },
16236                 },
16237         },
16238         [TEMPLATE_TEST8] = {
16239                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
16240                 .rhs = { [0] = { REG_UNSET, REGCM_GPR8_LO } },
16241         },
16242         [TEMPLATE_TEST16] = {
16243                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
16244                 .rhs = { [0] = { REG_UNSET, REGCM_GPR16 } },
16245         },
16246         [TEMPLATE_TEST32] = {
16247                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
16248                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
16249         },
16250         [TEMPLATE_SET] = {
16251                 .lhs = { [0] = { REG_UNSET, REGCM_GPR8_LO } },
16252                 .rhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
16253         },
16254         [TEMPLATE_JMP] = {
16255                 .rhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
16256         },
16257         [TEMPLATE_INB_DX] = {
16258                 .lhs = { [0] = { REG_AL,  REGCM_GPR8_LO } },  
16259                 .rhs = { [0] = { REG_DX, REGCM_GPR16 } },
16260         },
16261         [TEMPLATE_INB_IMM] = {
16262                 .lhs = { [0] = { REG_AL,  REGCM_GPR8_LO } },  
16263                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
16264         },
16265         [TEMPLATE_INW_DX]  = { 
16266                 .lhs = { [0] = { REG_AX,  REGCM_GPR16 } }, 
16267                 .rhs = { [0] = { REG_DX, REGCM_GPR16 } },
16268         },
16269         [TEMPLATE_INW_IMM] = { 
16270                 .lhs = { [0] = { REG_AX,  REGCM_GPR16 } }, 
16271                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
16272         },
16273         [TEMPLATE_INL_DX]  = {
16274                 .lhs = { [0] = { REG_EAX, REGCM_GPR32 } },
16275                 .rhs = { [0] = { REG_DX, REGCM_GPR16 } },
16276         },
16277         [TEMPLATE_INL_IMM] = {
16278                 .lhs = { [0] = { REG_EAX, REGCM_GPR32 } },
16279                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
16280         },
16281         [TEMPLATE_OUTB_DX] = { 
16282                 .rhs = {
16283                         [0] = { REG_AL,  REGCM_GPR8_LO },
16284                         [1] = { REG_DX, REGCM_GPR16 },
16285                 },
16286         },
16287         [TEMPLATE_OUTB_IMM] = { 
16288                 .rhs = {
16289                         [0] = { REG_AL,  REGCM_GPR8_LO },  
16290                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
16291                 },
16292         },
16293         [TEMPLATE_OUTW_DX] = { 
16294                 .rhs = {
16295                         [0] = { REG_AX,  REGCM_GPR16 },
16296                         [1] = { REG_DX, REGCM_GPR16 },
16297                 },
16298         },
16299         [TEMPLATE_OUTW_IMM] = {
16300                 .rhs = {
16301                         [0] = { REG_AX,  REGCM_GPR16 }, 
16302                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
16303                 },
16304         },
16305         [TEMPLATE_OUTL_DX] = { 
16306                 .rhs = {
16307                         [0] = { REG_EAX, REGCM_GPR32 },
16308                         [1] = { REG_DX, REGCM_GPR16 },
16309                 },
16310         },
16311         [TEMPLATE_OUTL_IMM] = { 
16312                 .rhs = {
16313                         [0] = { REG_EAX, REGCM_GPR32 }, 
16314                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
16315                 },
16316         },
16317         [TEMPLATE_BSF] = {
16318                 .lhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
16319                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
16320         },
16321         [TEMPLATE_RDMSR] = {
16322                 .lhs = { 
16323                         [0] = { REG_EAX, REGCM_GPR32 },
16324                         [1] = { REG_EDX, REGCM_GPR32 },
16325                 },
16326                 .rhs = { [0] = { REG_ECX, REGCM_GPR32 } },
16327         },
16328         [TEMPLATE_WRMSR] = {
16329                 .rhs = {
16330                         [0] = { REG_ECX, REGCM_GPR32 },
16331                         [1] = { REG_EAX, REGCM_GPR32 },
16332                         [2] = { REG_EDX, REGCM_GPR32 },
16333                 },
16334         },
16335         [TEMPLATE_UMUL8] = {
16336                 .lhs = { [0] = { REG_AX, REGCM_GPR16 } },
16337                 .rhs = { 
16338                         [0] = { REG_AL, REGCM_GPR8_LO },
16339                         [1] = { REG_UNSET, REGCM_GPR8_LO },
16340                 },
16341         },
16342         [TEMPLATE_UMUL16] = {
16343                 .lhs = { [0] = { REG_DXAX, REGCM_DIVIDEND32 } },
16344                 .rhs = { 
16345                         [0] = { REG_AX, REGCM_GPR16 },
16346                         [1] = { REG_UNSET, REGCM_GPR16 },
16347                 },
16348         },
16349         [TEMPLATE_UMUL32] = {
16350                 .lhs = { [0] = { REG_EDXEAX, REGCM_DIVIDEND64 } },
16351                 .rhs = { 
16352                         [0] = { REG_EAX, REGCM_GPR32 },
16353                         [1] = { REG_UNSET, REGCM_GPR32 },
16354                 },
16355         },
16356         [TEMPLATE_DIV8] = {
16357                 .lhs = { 
16358                         [0] = { REG_AL, REGCM_GPR8_LO },
16359                         [1] = { REG_AH, REGCM_GPR8 },
16360                 },
16361                 .rhs = {
16362                         [0] = { REG_AX, REGCM_GPR16 },
16363                         [1] = { REG_UNSET, REGCM_GPR8_LO },
16364                 },
16365         },
16366         [TEMPLATE_DIV16] = {
16367                 .lhs = { 
16368                         [0] = { REG_AX, REGCM_GPR16 },
16369                         [1] = { REG_DX, REGCM_GPR16 },
16370                 },
16371                 .rhs = {
16372                         [0] = { REG_DXAX, REGCM_DIVIDEND32 },
16373                         [1] = { REG_UNSET, REGCM_GPR16 },
16374                 },
16375         },
16376         [TEMPLATE_DIV32] = {
16377                 .lhs = { 
16378                         [0] = { REG_EAX, REGCM_GPR32 },
16379                         [1] = { REG_EDX, REGCM_GPR32 },
16380                 },
16381                 .rhs = {
16382                         [0] = { REG_EDXEAX, REGCM_DIVIDEND64 },
16383                         [1] = { REG_UNSET, REGCM_GPR32 },
16384                 },
16385         },
16386 };
16387
16388 static void fixup_branches(struct compile_state *state,
16389         struct triple *cmp, struct triple *use, int jmp_op)
16390 {
16391         struct triple_set *entry, *next;
16392         for(entry = use->use; entry; entry = next) {
16393                 next = entry->next;
16394                 if (entry->member->op == OP_COPY) {
16395                         fixup_branches(state, cmp, entry->member, jmp_op);
16396                 }
16397                 else if (entry->member->op == OP_BRANCH) {
16398                         struct triple *branch, *test;
16399                         struct triple *left, *right;
16400                         left = right = 0;
16401                         left = RHS(cmp, 0);
16402                         if (TRIPLE_RHS(cmp->sizes) > 1) {
16403                                 right = RHS(cmp, 1);
16404                         }
16405                         branch = entry->member;
16406                         test = pre_triple(state, branch,
16407                                 cmp->op, cmp->type, left, right);
16408                         test->template_id = TEMPLATE_TEST32; 
16409                         if (cmp->op == OP_CMP) {
16410                                 test->template_id = TEMPLATE_CMP32_REG;
16411                                 if (get_imm32(test, &RHS(test, 1))) {
16412                                         test->template_id = TEMPLATE_CMP32_IMM;
16413                                 }
16414                         }
16415                         use_triple(RHS(test, 0), test);
16416                         use_triple(RHS(test, 1), test);
16417                         unuse_triple(RHS(branch, 0), branch);
16418                         RHS(branch, 0) = test;
16419                         branch->op = jmp_op;
16420                         branch->template_id = TEMPLATE_JMP;
16421                         use_triple(RHS(branch, 0), branch);
16422                 }
16423         }
16424 }
16425
16426 static void bool_cmp(struct compile_state *state, 
16427         struct triple *ins, int cmp_op, int jmp_op, int set_op)
16428 {
16429         struct triple_set *entry, *next;
16430         struct triple *set;
16431
16432         /* Put a barrier up before the cmp which preceeds the
16433          * copy instruction.  If a set actually occurs this gives
16434          * us a chance to move variables in registers out of the way.
16435          */
16436
16437         /* Modify the comparison operator */
16438         ins->op = cmp_op;
16439         ins->template_id = TEMPLATE_TEST32;
16440         if (cmp_op == OP_CMP) {
16441                 ins->template_id = TEMPLATE_CMP32_REG;
16442                 if (get_imm32(ins, &RHS(ins, 1))) {
16443                         ins->template_id =  TEMPLATE_CMP32_IMM;
16444                 }
16445         }
16446         /* Generate the instruction sequence that will transform the
16447          * result of the comparison into a logical value.
16448          */
16449         set = post_triple(state, ins, set_op, &char_type, ins, 0);
16450         use_triple(ins, set);
16451         set->template_id = TEMPLATE_SET;
16452
16453         for(entry = ins->use; entry; entry = next) {
16454                 next = entry->next;
16455                 if (entry->member == set) {
16456                         continue;
16457                 }
16458                 replace_rhs_use(state, ins, set, entry->member);
16459         }
16460         fixup_branches(state, ins, set, jmp_op);
16461 }
16462
16463 static struct triple *after_lhs(struct compile_state *state, struct triple *ins)
16464 {
16465         struct triple *next;
16466         int lhs, i;
16467         lhs = TRIPLE_LHS(ins->sizes);
16468         for(next = ins->next, i = 0; i < lhs; i++, next = next->next) {
16469                 if (next != LHS(ins, i)) {
16470                         internal_error(state, ins, "malformed lhs on %s",
16471                                 tops(ins->op));
16472                 }
16473                 if (next->op != OP_PIECE) {
16474                         internal_error(state, ins, "bad lhs op %s at %d on %s",
16475                                 tops(next->op), i, tops(ins->op));
16476                 }
16477                 if (next->u.cval != i) {
16478                         internal_error(state, ins, "bad u.cval of %d %d expected",
16479                                 next->u.cval, i);
16480                 }
16481         }
16482         return next;
16483 }
16484
16485 struct reg_info arch_reg_lhs(struct compile_state *state, struct triple *ins, int index)
16486 {
16487         struct ins_template *template;
16488         struct reg_info result;
16489         int zlhs;
16490         if (ins->op == OP_PIECE) {
16491                 index = ins->u.cval;
16492                 ins = MISC(ins, 0);
16493         }
16494         zlhs = TRIPLE_LHS(ins->sizes);
16495         if (triple_is_def(state, ins)) {
16496                 zlhs = 1;
16497         }
16498         if (index >= zlhs) {
16499                 internal_error(state, ins, "index %d out of range for %s\n",
16500                         index, tops(ins->op));
16501         }
16502         switch(ins->op) {
16503         case OP_ASM:
16504                 template = &ins->u.ainfo->tmpl;
16505                 break;
16506         default:
16507                 if (ins->template_id > LAST_TEMPLATE) {
16508                         internal_error(state, ins, "bad template number %d", 
16509                                 ins->template_id);
16510                 }
16511                 template = &templates[ins->template_id];
16512                 break;
16513         }
16514         result = template->lhs[index];
16515         result.regcm = arch_regcm_normalize(state, result.regcm);
16516         if (result.reg != REG_UNNEEDED) {
16517                 result.regcm &= ~(REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8);
16518         }
16519         if (result.regcm == 0) {
16520                 internal_error(state, ins, "lhs %d regcm == 0", index);
16521         }
16522         return result;
16523 }
16524
16525 struct reg_info arch_reg_rhs(struct compile_state *state, struct triple *ins, int index)
16526 {
16527         struct reg_info result;
16528         struct ins_template *template;
16529         if ((index > TRIPLE_RHS(ins->sizes)) ||
16530                 (ins->op == OP_PIECE)) {
16531                 internal_error(state, ins, "index %d out of range for %s\n",
16532                         index, tops(ins->op));
16533         }
16534         switch(ins->op) {
16535         case OP_ASM:
16536                 template = &ins->u.ainfo->tmpl;
16537                 break;
16538         default:
16539                 if (ins->template_id > LAST_TEMPLATE) {
16540                         internal_error(state, ins, "bad template number %d", 
16541                                 ins->template_id);
16542                 }
16543                 template = &templates[ins->template_id];
16544                 break;
16545         }
16546         result = template->rhs[index];
16547         result.regcm = arch_regcm_normalize(state, result.regcm);
16548         if (result.regcm == 0) {
16549                 internal_error(state, ins, "rhs %d regcm == 0", index);
16550         }
16551         return result;
16552 }
16553
16554 static struct triple *mod_div(struct compile_state *state,
16555         struct triple *ins, int div_op, int index)
16556 {
16557         struct triple *div, *piece0, *piece1;
16558         
16559         /* Generate a piece to hold the remainder */
16560         piece1 = post_triple(state, ins, OP_PIECE, ins->type, 0, 0);
16561         piece1->u.cval = 1;
16562
16563         /* Generate a piece to hold the quotient */
16564         piece0 = post_triple(state, ins, OP_PIECE, ins->type, 0, 0);
16565         piece0->u.cval = 0;
16566
16567         /* Generate the appropriate division instruction */
16568         div = post_triple(state, ins, div_op, ins->type, 0, 0);
16569         RHS(div, 0) = RHS(ins, 0);
16570         RHS(div, 1) = RHS(ins, 1);
16571         LHS(div, 0) = piece0;
16572         LHS(div, 1) = piece1;
16573         div->template_id  = TEMPLATE_DIV32;
16574         use_triple(RHS(div, 0), div);
16575         use_triple(RHS(div, 1), div);
16576         use_triple(LHS(div, 0), div);
16577         use_triple(LHS(div, 1), div);
16578
16579         /* Hook on piece0 */
16580         MISC(piece0, 0) = div;
16581         use_triple(div, piece0);
16582
16583         /* Hook on piece1 */
16584         MISC(piece1, 0) = div;
16585         use_triple(div, piece1);
16586         
16587         /* Replate uses of ins with the appropriate piece of the div */
16588         propogate_use(state, ins, LHS(div, index));
16589         release_triple(state, ins);
16590
16591         /* Return the address of the next instruction */
16592         return piece1->next;
16593 }
16594
16595 static struct triple *transform_to_arch_instruction(
16596         struct compile_state *state, struct triple *ins)
16597 {
16598         /* Transform from generic 3 address instructions
16599          * to archtecture specific instructions.
16600          * And apply architecture specific constraints to instructions.
16601          * Copies are inserted to preserve the register flexibility
16602          * of 3 address instructions.
16603          */
16604         struct triple *next;
16605         size_t size;
16606         next = ins->next;
16607         switch(ins->op) {
16608         case OP_INTCONST:
16609                 ins->template_id = TEMPLATE_INTCONST32;
16610                 if (ins->u.cval < 256) {
16611                         ins->template_id = TEMPLATE_INTCONST8;
16612                 }
16613                 break;
16614         case OP_ADDRCONST:
16615                 ins->template_id = TEMPLATE_INTCONST32;
16616                 break;
16617         case OP_NOOP:
16618         case OP_SDECL:
16619         case OP_BLOBCONST:
16620         case OP_LABEL:
16621                 ins->template_id = TEMPLATE_NOP;
16622                 break;
16623         case OP_COPY:
16624                 size = size_of(state, ins->type);
16625                 if (is_imm8(RHS(ins, 0)) && (size <= 1)) {
16626                         ins->template_id = TEMPLATE_COPY_IMM8;
16627                 }
16628                 else if (is_imm16(RHS(ins, 0)) && (size <= 2)) {
16629                         ins->template_id = TEMPLATE_COPY_IMM16;
16630                 }
16631                 else if (is_imm32(RHS(ins, 0)) && (size <= 4)) {
16632                         ins->template_id = TEMPLATE_COPY_IMM32;
16633                 }
16634                 else if (is_const(RHS(ins, 0))) {
16635                         internal_error(state, ins, "bad constant passed to copy");
16636                 }
16637                 else if (size <= 1) {
16638                         ins->template_id = TEMPLATE_COPY8_REG;
16639                 }
16640                 else if (size <= 2) {
16641                         ins->template_id = TEMPLATE_COPY16_REG;
16642                 }
16643                 else if (size <= 4) {
16644                         ins->template_id = TEMPLATE_COPY32_REG;
16645                 }
16646                 else {
16647                         internal_error(state, ins, "bad type passed to copy");
16648                 }
16649                 break;
16650         case OP_PHI:
16651                 size = size_of(state, ins->type);
16652                 if (size <= 1) {
16653                         ins->template_id = TEMPLATE_PHI8;
16654                 }
16655                 else if (size <= 2) {
16656                         ins->template_id = TEMPLATE_PHI16;
16657                 }
16658                 else if (size <= 4) {
16659                         ins->template_id = TEMPLATE_PHI32;
16660                 }
16661                 else {
16662                         internal_error(state, ins, "bad type passed to phi");
16663                 }
16664                 break;
16665         case OP_STORE:
16666                 switch(ins->type->type & TYPE_MASK) {
16667                 case TYPE_CHAR:    case TYPE_UCHAR:
16668                         ins->template_id = TEMPLATE_STORE8;
16669                         break;
16670                 case TYPE_SHORT:   case TYPE_USHORT:
16671                         ins->template_id = TEMPLATE_STORE16;
16672                         break;
16673                 case TYPE_INT:     case TYPE_UINT:
16674                 case TYPE_LONG:    case TYPE_ULONG:
16675                 case TYPE_POINTER:
16676                         ins->template_id = TEMPLATE_STORE32;
16677                         break;
16678                 default:
16679                         internal_error(state, ins, "unknown type in store");
16680                         break;
16681                 }
16682                 break;
16683         case OP_LOAD:
16684                 switch(ins->type->type & TYPE_MASK) {
16685                 case TYPE_CHAR:   case TYPE_UCHAR:
16686                         ins->template_id = TEMPLATE_LOAD8;
16687                         break;
16688                 case TYPE_SHORT:
16689                 case TYPE_USHORT:
16690                         ins->template_id = TEMPLATE_LOAD16;
16691                         break;
16692                 case TYPE_INT:
16693                 case TYPE_UINT:
16694                 case TYPE_LONG:
16695                 case TYPE_ULONG:
16696                 case TYPE_POINTER:
16697                         ins->template_id = TEMPLATE_LOAD32;
16698                         break;
16699                 default:
16700                         internal_error(state, ins, "unknown type in load");
16701                         break;
16702                 }
16703                 break;
16704         case OP_ADD:
16705         case OP_SUB:
16706         case OP_AND:
16707         case OP_XOR:
16708         case OP_OR:
16709         case OP_SMUL:
16710                 ins->template_id = TEMPLATE_BINARY32_REG;
16711                 if (get_imm32(ins, &RHS(ins, 1))) {
16712                         ins->template_id = TEMPLATE_BINARY32_IMM;
16713                 }
16714                 break;
16715         case OP_SDIVT:
16716         case OP_UDIVT:
16717                 ins->template_id = TEMPLATE_DIV32;
16718                 next = after_lhs(state, ins);
16719                 break;
16720                 /* FIXME UMUL does not work yet.. */
16721         case OP_UMUL:
16722                 ins->template_id = TEMPLATE_UMUL32;
16723                 break;
16724         case OP_UDIV:
16725                 next = mod_div(state, ins, OP_UDIVT, 0);
16726                 break;
16727         case OP_SDIV:
16728                 next = mod_div(state, ins, OP_SDIVT, 0);
16729                 break;
16730         case OP_UMOD:
16731                 next = mod_div(state, ins, OP_UDIVT, 1);
16732                 break;
16733         case OP_SMOD:
16734                 next = mod_div(state, ins, OP_SDIVT, 1);
16735                 break;
16736         case OP_SL:
16737         case OP_SSR:
16738         case OP_USR:
16739                 ins->template_id = TEMPLATE_SL32_CL;
16740                 if (get_imm8(ins, &RHS(ins, 1))) {
16741                         ins->template_id = TEMPLATE_SL32_IMM;
16742                 } else if (size_of(state, RHS(ins, 1)->type) > 1) {
16743                         typed_pre_copy(state, &char_type, ins, 1);
16744                 }
16745                 break;
16746         case OP_INVERT:
16747         case OP_NEG:
16748                 ins->template_id = TEMPLATE_UNARY32;
16749                 break;
16750         case OP_EQ: 
16751                 bool_cmp(state, ins, OP_CMP, OP_JMP_EQ, OP_SET_EQ); 
16752                 break;
16753         case OP_NOTEQ:
16754                 bool_cmp(state, ins, OP_CMP, OP_JMP_NOTEQ, OP_SET_NOTEQ);
16755                 break;
16756         case OP_SLESS:
16757                 bool_cmp(state, ins, OP_CMP, OP_JMP_SLESS, OP_SET_SLESS);
16758                 break;
16759         case OP_ULESS:
16760                 bool_cmp(state, ins, OP_CMP, OP_JMP_ULESS, OP_SET_ULESS);
16761                 break;
16762         case OP_SMORE:
16763                 bool_cmp(state, ins, OP_CMP, OP_JMP_SMORE, OP_SET_SMORE);
16764                 break;
16765         case OP_UMORE:
16766                 bool_cmp(state, ins, OP_CMP, OP_JMP_UMORE, OP_SET_UMORE);
16767                 break;
16768         case OP_SLESSEQ:
16769                 bool_cmp(state, ins, OP_CMP, OP_JMP_SLESSEQ, OP_SET_SLESSEQ);
16770                 break;
16771         case OP_ULESSEQ:
16772                 bool_cmp(state, ins, OP_CMP, OP_JMP_ULESSEQ, OP_SET_ULESSEQ);
16773                 break;
16774         case OP_SMOREEQ:
16775                 bool_cmp(state, ins, OP_CMP, OP_JMP_SMOREEQ, OP_SET_SMOREEQ);
16776                 break;
16777         case OP_UMOREEQ:
16778                 bool_cmp(state, ins, OP_CMP, OP_JMP_UMOREEQ, OP_SET_UMOREEQ);
16779                 break;
16780         case OP_LTRUE:
16781                 bool_cmp(state, ins, OP_TEST, OP_JMP_NOTEQ, OP_SET_NOTEQ);
16782                 break;
16783         case OP_LFALSE:
16784                 bool_cmp(state, ins, OP_TEST, OP_JMP_EQ, OP_SET_EQ);
16785                 break;
16786         case OP_BRANCH:
16787                 if (TRIPLE_RHS(ins->sizes) > 0) {
16788                         internal_error(state, ins, "bad branch test");
16789                 }
16790                 ins->op = OP_JMP;
16791                 ins->template_id = TEMPLATE_NOP;
16792                 break;
16793         case OP_INB:
16794         case OP_INW:
16795         case OP_INL:
16796                 switch(ins->op) {
16797                 case OP_INB: ins->template_id = TEMPLATE_INB_DX; break;
16798                 case OP_INW: ins->template_id = TEMPLATE_INW_DX; break;
16799                 case OP_INL: ins->template_id = TEMPLATE_INL_DX; break;
16800                 }
16801                 if (get_imm8(ins, &RHS(ins, 0))) {
16802                         ins->template_id += 1;
16803                 }
16804                 break;
16805         case OP_OUTB:
16806         case OP_OUTW:
16807         case OP_OUTL:
16808                 switch(ins->op) {
16809                 case OP_OUTB: ins->template_id = TEMPLATE_OUTB_DX; break;
16810                 case OP_OUTW: ins->template_id = TEMPLATE_OUTW_DX; break;
16811                 case OP_OUTL: ins->template_id = TEMPLATE_OUTL_DX; break;
16812                 }
16813                 if (get_imm8(ins, &RHS(ins, 1))) {
16814                         ins->template_id += 1;
16815                 }
16816                 break;
16817         case OP_BSF:
16818         case OP_BSR:
16819                 ins->template_id = TEMPLATE_BSF;
16820                 break;
16821         case OP_RDMSR:
16822                 ins->template_id = TEMPLATE_RDMSR;
16823                 next = after_lhs(state, ins);
16824                 break;
16825         case OP_WRMSR:
16826                 ins->template_id = TEMPLATE_WRMSR;
16827                 break;
16828         case OP_HLT:
16829                 ins->template_id = TEMPLATE_NOP;
16830                 break;
16831         case OP_ASM:
16832                 ins->template_id = TEMPLATE_NOP;
16833                 next = after_lhs(state, ins);
16834                 break;
16835                 /* Already transformed instructions */
16836         case OP_TEST:
16837                 ins->template_id = TEMPLATE_TEST32;
16838                 break;
16839         case OP_CMP:
16840                 ins->template_id = TEMPLATE_CMP32_REG;
16841                 if (get_imm32(ins, &RHS(ins, 1))) {
16842                         ins->template_id = TEMPLATE_CMP32_IMM;
16843                 }
16844                 break;
16845         case OP_JMP_EQ:      case OP_JMP_NOTEQ:
16846         case OP_JMP_SLESS:   case OP_JMP_ULESS:
16847         case OP_JMP_SMORE:   case OP_JMP_UMORE:
16848         case OP_JMP_SLESSEQ: case OP_JMP_ULESSEQ:
16849         case OP_JMP_SMOREEQ: case OP_JMP_UMOREEQ:
16850                 ins->template_id = TEMPLATE_JMP;
16851                 break;
16852         case OP_SET_EQ:      case OP_SET_NOTEQ:
16853         case OP_SET_SLESS:   case OP_SET_ULESS:
16854         case OP_SET_SMORE:   case OP_SET_UMORE:
16855         case OP_SET_SLESSEQ: case OP_SET_ULESSEQ:
16856         case OP_SET_SMOREEQ: case OP_SET_UMOREEQ:
16857                 ins->template_id = TEMPLATE_SET;
16858                 break;
16859                 /* Unhandled instructions */
16860         case OP_PIECE:
16861         default:
16862                 internal_error(state, ins, "unhandled ins: %d %s\n",
16863                         ins->op, tops(ins->op));
16864                 break;
16865         }
16866         return next;
16867 }
16868
16869 static long next_label(struct compile_state *state)
16870 {
16871         static long label_counter = 0;
16872         return ++label_counter;
16873 }
16874 static void generate_local_labels(struct compile_state *state)
16875 {
16876         struct triple *first, *label;
16877         first = RHS(state->main_function, 0);
16878         label = first;
16879         do {
16880                 if ((label->op == OP_LABEL) || 
16881                         (label->op == OP_SDECL)) {
16882                         if (label->use) {
16883                                 label->u.cval = next_label(state);
16884                         } else {
16885                                 label->u.cval = 0;
16886                         }
16887                         
16888                 }
16889                 label = label->next;
16890         } while(label != first);
16891 }
16892
16893 static int check_reg(struct compile_state *state, 
16894         struct triple *triple, int classes)
16895 {
16896         unsigned mask;
16897         int reg;
16898         reg = ID_REG(triple->id);
16899         if (reg == REG_UNSET) {
16900                 internal_error(state, triple, "register not set");
16901         }
16902         mask = arch_reg_regcm(state, reg);
16903         if (!(classes & mask)) {
16904                 internal_error(state, triple, "reg %d in wrong class",
16905                         reg);
16906         }
16907         return reg;
16908 }
16909
16910 static const char *arch_reg_str(int reg)
16911 {
16912 #if REG_XMM7 != 44
16913 #error "Registers have renumberd fix arch_reg_str"
16914 #endif
16915         static const char *regs[] = {
16916                 "%unset",
16917                 "%unneeded",
16918                 "%eflags",
16919                 "%al", "%bl", "%cl", "%dl", "%ah", "%bh", "%ch", "%dh",
16920                 "%ax", "%bx", "%cx", "%dx", "%si", "%di", "%bp", "%sp",
16921                 "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi", "%ebp", "%esp",
16922                 "%edx:%eax",
16923                 "%dx:%ax",
16924                 "%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7",
16925                 "%xmm0", "%xmm1", "%xmm2", "%xmm3", 
16926                 "%xmm4", "%xmm5", "%xmm6", "%xmm7",
16927         };
16928         if (!((reg >= REG_EFLAGS) && (reg <= REG_XMM7))) {
16929                 reg = 0;
16930         }
16931         return regs[reg];
16932 }
16933
16934
16935 static const char *reg(struct compile_state *state, struct triple *triple,
16936         int classes)
16937 {
16938         int reg;
16939         reg = check_reg(state, triple, classes);
16940         return arch_reg_str(reg);
16941 }
16942
16943 const char *type_suffix(struct compile_state *state, struct type *type)
16944 {
16945         const char *suffix;
16946         switch(size_of(state, type)) {
16947         case 1: suffix = "b"; break;
16948         case 2: suffix = "w"; break;
16949         case 4: suffix = "l"; break;
16950         default:
16951                 internal_error(state, 0, "unknown suffix");
16952                 suffix = 0;
16953                 break;
16954         }
16955         return suffix;
16956 }
16957
16958 static void print_const_val(
16959         struct compile_state *state, struct triple *ins, FILE *fp)
16960 {
16961         switch(ins->op) {
16962         case OP_INTCONST:
16963                 fprintf(fp, " $%ld ", 
16964                         (long_t)(ins->u.cval));
16965                 break;
16966         case OP_ADDRCONST:
16967                 if (MISC(ins, 0)->op != OP_SDECL) {
16968                         internal_error(state, ins, "bad base for addrconst");
16969                 }
16970                 if (MISC(ins, 0)->u.cval <= 0) {
16971                         internal_error(state, ins, "unlabeled constant");
16972                 }
16973                 fprintf(fp, " $L%s%lu+%lu ",
16974                         state->label_prefix, 
16975                         MISC(ins, 0)->u.cval,
16976                         ins->u.cval);
16977                 break;
16978         default:
16979                 internal_error(state, ins, "unknown constant type");
16980                 break;
16981         }
16982 }
16983
16984 static void print_const(struct compile_state *state,
16985         struct triple *ins, FILE *fp)
16986 {
16987         switch(ins->op) {
16988         case OP_INTCONST:
16989                 switch(ins->type->type & TYPE_MASK) {
16990                 case TYPE_CHAR:
16991                 case TYPE_UCHAR:
16992                         fprintf(fp, ".byte 0x%02lx\n", ins->u.cval);
16993                         break;
16994                 case TYPE_SHORT:
16995                 case TYPE_USHORT:
16996                         fprintf(fp, ".short 0x%04lx\n", ins->u.cval);
16997                         break;
16998                 case TYPE_INT:
16999                 case TYPE_UINT:
17000                 case TYPE_LONG:
17001                 case TYPE_ULONG:
17002                         fprintf(fp, ".int %lu\n", ins->u.cval);
17003                         break;
17004                 default:
17005                         internal_error(state, ins, "Unknown constant type");
17006                 }
17007                 break;
17008         case OP_ADDRCONST:
17009                 if (MISC(ins, 0)->op != OP_SDECL) {
17010                         internal_error(state, ins, "bad base for addrconst");
17011                 }
17012                 if (MISC(ins, 0)->u.cval <= 0) {
17013                         internal_error(state, ins, "unlabeled constant");
17014                 }
17015                 fprintf(fp, ".int L%s%lu+%lu\n",
17016                         state->label_prefix,
17017                         MISC(ins, 0)->u.cval,
17018                         ins->u.cval);
17019                 break;
17020         case OP_BLOBCONST:
17021         {
17022                 unsigned char *blob;
17023                 size_t size, i;
17024                 size = size_of(state, ins->type);
17025                 blob = ins->u.blob;
17026                 for(i = 0; i < size; i++) {
17027                         fprintf(fp, ".byte 0x%02x\n",
17028                                 blob[i]);
17029                 }
17030                 break;
17031         }
17032         default:
17033                 internal_error(state, ins, "Unknown constant type");
17034                 break;
17035         }
17036 }
17037
17038 #define TEXT_SECTION ".rom.text"
17039 #define DATA_SECTION ".rom.data"
17040
17041 static long get_const_pool_ref(
17042         struct compile_state *state, struct triple *ins, FILE *fp)
17043 {
17044         long ref;
17045         ref = next_label(state);
17046         fprintf(fp, ".section \"" DATA_SECTION "\"\n");
17047         fprintf(fp, ".balign %d\n", align_of(state, ins->type));
17048         fprintf(fp, "L%s%lu:\n", state->label_prefix, ref);
17049         print_const(state, ins, fp);
17050         fprintf(fp, ".section \"" TEXT_SECTION "\"\n");
17051         return ref;
17052 }
17053
17054 static void print_binary_op(struct compile_state *state,
17055         const char *op, struct triple *ins, FILE *fp) 
17056 {
17057         unsigned mask;
17058         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO;
17059         if (RHS(ins, 0)->id != ins->id) {
17060                 internal_error(state, ins, "invalid register assignment");
17061         }
17062         if (is_const(RHS(ins, 1))) {
17063                 fprintf(fp, "\t%s ", op);
17064                 print_const_val(state, RHS(ins, 1), fp);
17065                 fprintf(fp, ", %s\n",
17066                         reg(state, RHS(ins, 0), mask));
17067         }
17068         else {
17069                 unsigned lmask, rmask;
17070                 int lreg, rreg;
17071                 lreg = check_reg(state, RHS(ins, 0), mask);
17072                 rreg = check_reg(state, RHS(ins, 1), mask);
17073                 lmask = arch_reg_regcm(state, lreg);
17074                 rmask = arch_reg_regcm(state, rreg);
17075                 mask = lmask & rmask;
17076                 fprintf(fp, "\t%s %s, %s\n",
17077                         op,
17078                         reg(state, RHS(ins, 1), mask),
17079                         reg(state, RHS(ins, 0), mask));
17080         }
17081 }
17082 static void print_unary_op(struct compile_state *state, 
17083         const char *op, struct triple *ins, FILE *fp)
17084 {
17085         unsigned mask;
17086         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO;
17087         fprintf(fp, "\t%s %s\n",
17088                 op,
17089                 reg(state, RHS(ins, 0), mask));
17090 }
17091
17092 static void print_op_shift(struct compile_state *state,
17093         const char *op, struct triple *ins, FILE *fp)
17094 {
17095         unsigned mask;
17096         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO;
17097         if (RHS(ins, 0)->id != ins->id) {
17098                 internal_error(state, ins, "invalid register assignment");
17099         }
17100         if (is_const(RHS(ins, 1))) {
17101                 fprintf(fp, "\t%s ", op);
17102                 print_const_val(state, RHS(ins, 1), fp);
17103                 fprintf(fp, ", %s\n",
17104                         reg(state, RHS(ins, 0), mask));
17105         }
17106         else {
17107                 fprintf(fp, "\t%s %s, %s\n",
17108                         op,
17109                         reg(state, RHS(ins, 1), REGCM_GPR8_LO),
17110                         reg(state, RHS(ins, 0), mask));
17111         }
17112 }
17113
17114 static void print_op_in(struct compile_state *state, struct triple *ins, FILE *fp)
17115 {
17116         const char *op;
17117         int mask;
17118         int dreg;
17119         mask = 0;
17120         switch(ins->op) {
17121         case OP_INB: op = "inb", mask = REGCM_GPR8_LO; break;
17122         case OP_INW: op = "inw", mask = REGCM_GPR16; break;
17123         case OP_INL: op = "inl", mask = REGCM_GPR32; break;
17124         default:
17125                 internal_error(state, ins, "not an in operation");
17126                 op = 0;
17127                 break;
17128         }
17129         dreg = check_reg(state, ins, mask);
17130         if (!reg_is_reg(state, dreg, REG_EAX)) {
17131                 internal_error(state, ins, "dst != %%eax");
17132         }
17133         if (is_const(RHS(ins, 0))) {
17134                 fprintf(fp, "\t%s ", op);
17135                 print_const_val(state, RHS(ins, 0), fp);
17136                 fprintf(fp, ", %s\n",
17137                         reg(state, ins, mask));
17138         }
17139         else {
17140                 int addr_reg;
17141                 addr_reg = check_reg(state, RHS(ins, 0), REGCM_GPR16);
17142                 if (!reg_is_reg(state, addr_reg, REG_DX)) {
17143                         internal_error(state, ins, "src != %%dx");
17144                 }
17145                 fprintf(fp, "\t%s %s, %s\n",
17146                         op, 
17147                         reg(state, RHS(ins, 0), REGCM_GPR16),
17148                         reg(state, ins, mask));
17149         }
17150 }
17151
17152 static void print_op_out(struct compile_state *state, struct triple *ins, FILE *fp)
17153 {
17154         const char *op;
17155         int mask;
17156         int lreg;
17157         mask = 0;
17158         switch(ins->op) {
17159         case OP_OUTB: op = "outb", mask = REGCM_GPR8_LO; break;
17160         case OP_OUTW: op = "outw", mask = REGCM_GPR16; break;
17161         case OP_OUTL: op = "outl", mask = REGCM_GPR32; break;
17162         default:
17163                 internal_error(state, ins, "not an out operation");
17164                 op = 0;
17165                 break;
17166         }
17167         lreg = check_reg(state, RHS(ins, 0), mask);
17168         if (!reg_is_reg(state, lreg, REG_EAX)) {
17169                 internal_error(state, ins, "src != %%eax");
17170         }
17171         if (is_const(RHS(ins, 1))) {
17172                 fprintf(fp, "\t%s %s,", 
17173                         op, reg(state, RHS(ins, 0), mask));
17174                 print_const_val(state, RHS(ins, 1), fp);
17175                 fprintf(fp, "\n");
17176         }
17177         else {
17178                 int addr_reg;
17179                 addr_reg = check_reg(state, RHS(ins, 1), REGCM_GPR16);
17180                 if (!reg_is_reg(state, addr_reg, REG_DX)) {
17181                         internal_error(state, ins, "dst != %%dx");
17182                 }
17183                 fprintf(fp, "\t%s %s, %s\n",
17184                         op, 
17185                         reg(state, RHS(ins, 0), mask),
17186                         reg(state, RHS(ins, 1), REGCM_GPR16));
17187         }
17188 }
17189
17190 static void print_op_move(struct compile_state *state,
17191         struct triple *ins, FILE *fp)
17192 {
17193         /* op_move is complex because there are many types
17194          * of registers we can move between.
17195          * Because OP_COPY will be introduced in arbitrary locations
17196          * OP_COPY must not affect flags.
17197          */
17198         int omit_copy = 1; /* Is it o.k. to omit a noop copy? */
17199         struct triple *dst, *src;
17200         if (ins->op == OP_COPY) {
17201                 src = RHS(ins, 0);
17202                 dst = ins;
17203         }
17204         else {
17205                 internal_error(state, ins, "unknown move operation");
17206                 src = dst = 0;
17207         }
17208         if (!is_const(src)) {
17209                 int src_reg, dst_reg;
17210                 int src_regcm, dst_regcm;
17211                 src_reg   = ID_REG(src->id);
17212                 dst_reg   = ID_REG(dst->id);
17213                 src_regcm = arch_reg_regcm(state, src_reg);
17214                 dst_regcm = arch_reg_regcm(state, dst_reg);
17215                 /* If the class is the same just move the register */
17216                 if (src_regcm & dst_regcm & 
17217                         (REGCM_GPR8_LO | REGCM_GPR16 | REGCM_GPR32)) {
17218                         if ((src_reg != dst_reg) || !omit_copy) {
17219                                 fprintf(fp, "\tmov %s, %s\n",
17220                                         reg(state, src, src_regcm),
17221                                         reg(state, dst, dst_regcm));
17222                         }
17223                 }
17224                 /* Move 32bit to 16bit */
17225                 else if ((src_regcm & REGCM_GPR32) &&
17226                         (dst_regcm & REGCM_GPR16)) {
17227                         src_reg = (src_reg - REGC_GPR32_FIRST) + REGC_GPR16_FIRST;
17228                         if ((src_reg != dst_reg) || !omit_copy) {
17229                                 fprintf(fp, "\tmovw %s, %s\n",
17230                                         arch_reg_str(src_reg), 
17231                                         arch_reg_str(dst_reg));
17232                         }
17233                 }
17234                 /* Move from 32bit gprs to 16bit gprs */
17235                 else if ((src_regcm & REGCM_GPR32) &&
17236                         (dst_regcm & REGCM_GPR16)) {
17237                         dst_reg = (dst_reg - REGC_GPR16_FIRST) + REGC_GPR32_FIRST;
17238                         if ((src_reg != dst_reg) || !omit_copy) {
17239                                 fprintf(fp, "\tmov %s, %s\n",
17240                                         arch_reg_str(src_reg),
17241                                         arch_reg_str(dst_reg));
17242                         }
17243                 }
17244                 /* Move 32bit to 8bit */
17245                 else if ((src_regcm & REGCM_GPR32_8) &&
17246                         (dst_regcm & REGCM_GPR8_LO))
17247                 {
17248                         src_reg = (src_reg - REGC_GPR32_8_FIRST) + REGC_GPR8_FIRST;
17249                         if ((src_reg != dst_reg) || !omit_copy) {
17250                                 fprintf(fp, "\tmovb %s, %s\n",
17251                                         arch_reg_str(src_reg),
17252                                         arch_reg_str(dst_reg));
17253                         }
17254                 }
17255                 /* Move 16bit to 8bit */
17256                 else if ((src_regcm & REGCM_GPR16_8) &&
17257                         (dst_regcm & REGCM_GPR8_LO))
17258                 {
17259                         src_reg = (src_reg - REGC_GPR16_8_FIRST) + REGC_GPR8_FIRST;
17260                         if ((src_reg != dst_reg) || !omit_copy) {
17261                                 fprintf(fp, "\tmovb %s, %s\n",
17262                                         arch_reg_str(src_reg),
17263                                         arch_reg_str(dst_reg));
17264                         }
17265                 }
17266                 /* Move 8/16bit to 16/32bit */
17267                 else if ((src_regcm & (REGCM_GPR8_LO | REGCM_GPR16)) && 
17268                         (dst_regcm & (REGCM_GPR16 | REGCM_GPR32))) {
17269                         const char *op;
17270                         op = is_signed(src->type)? "movsx": "movzx";
17271                         fprintf(fp, "\t%s %s, %s\n",
17272                                 op,
17273                                 reg(state, src, src_regcm),
17274                                 reg(state, dst, dst_regcm));
17275                 }
17276                 /* Move between sse registers */
17277                 else if ((src_regcm & dst_regcm & REGCM_XMM)) {
17278                         if ((src_reg != dst_reg) || !omit_copy) {
17279                                 fprintf(fp, "\tmovdqa %s, %s\n",
17280                                         reg(state, src, src_regcm),
17281                                         reg(state, dst, dst_regcm));
17282                         }
17283                 }
17284                 /* Move between mmx registers */
17285                 else if ((src_regcm & dst_regcm & REGCM_MMX)) {
17286                         if ((src_reg != dst_reg) || !omit_copy) {
17287                                 fprintf(fp, "\tmovq %s, %s\n",
17288                                         reg(state, src, src_regcm),
17289                                         reg(state, dst, dst_regcm));
17290                         }
17291                 }
17292                 /* Move from sse to mmx registers */
17293                 else if ((src_regcm & REGCM_XMM) && (dst_regcm & REGCM_MMX)) {
17294                         fprintf(fp, "\tmovdq2q %s, %s\n",
17295                                 reg(state, src, src_regcm),
17296                                 reg(state, dst, dst_regcm));
17297                 }
17298                 /* Move from mmx to sse registers */
17299                 else if ((src_regcm & REGCM_MMX) && (dst_regcm & REGCM_XMM)) {
17300                         fprintf(fp, "\tmovq2dq %s, %s\n",
17301                                 reg(state, src, src_regcm),
17302                                 reg(state, dst, dst_regcm));
17303                 }
17304                 /* Move between 32bit gprs & mmx/sse registers */
17305                 else if ((src_regcm & (REGCM_GPR32 | REGCM_MMX | REGCM_XMM)) &&
17306                         (dst_regcm & (REGCM_GPR32 | REGCM_MMX | REGCM_XMM))) {
17307                         fprintf(fp, "\tmovd %s, %s\n",
17308                                 reg(state, src, src_regcm),
17309                                 reg(state, dst, dst_regcm));
17310                 }
17311                 /* Move from 16bit gprs &  mmx/sse registers */
17312                 else if ((src_regcm & REGCM_GPR16) &&
17313                         (dst_regcm & (REGCM_MMX | REGCM_XMM))) {
17314                         const char *op;
17315                         int mid_reg;
17316                         op = is_signed(src->type)? "movsx":"movzx";
17317                         mid_reg = (src_reg - REGC_GPR16_FIRST) + REGC_GPR32_FIRST;
17318                         fprintf(fp, "\t%s %s, %s\n\tmovd %s, %s\n",
17319                                 op,
17320                                 arch_reg_str(src_reg),
17321                                 arch_reg_str(mid_reg),
17322                                 arch_reg_str(mid_reg),
17323                                 arch_reg_str(dst_reg));
17324                 }
17325                 /* Move from mmx/sse registers to 16bit gprs */
17326                 else if ((src_regcm & (REGCM_MMX | REGCM_XMM)) &&
17327                         (dst_regcm & REGCM_GPR16)) {
17328                         dst_reg = (dst_reg - REGC_GPR16_FIRST) + REGC_GPR32_FIRST;
17329                         fprintf(fp, "\tmovd %s, %s\n",
17330                                 arch_reg_str(src_reg),
17331                                 arch_reg_str(dst_reg));
17332                 }
17333                 /* Move from gpr to 64bit dividend */
17334                 else if ((src_regcm & (REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO))  &&
17335                         (dst_regcm & REGCM_DIVIDEND64)) {
17336                         const char *extend;
17337                         extend = is_signed(src->type)? "cltd":"movl $0, %edx";
17338                         fprintf(fp, "\tmov %s, %%eax\n\t%s\n",
17339                                 arch_reg_str(src_reg), 
17340                                 extend);
17341                 }
17342                 /* Move from 64bit gpr to gpr */
17343                 else if ((src_regcm & REGCM_DIVIDEND64) &&
17344                         (dst_regcm & (REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO))) {
17345                         if (dst_regcm & REGCM_GPR32) {
17346                                 src_reg = REG_EAX;
17347                         } 
17348                         else if (dst_regcm & REGCM_GPR16) {
17349                                 src_reg = REG_AX;
17350                         }
17351                         else if (dst_regcm & REGCM_GPR8_LO) {
17352                                 src_reg = REG_AL;
17353                         }
17354                         fprintf(fp, "\tmov %s, %s\n",
17355                                 arch_reg_str(src_reg),
17356                                 arch_reg_str(dst_reg));
17357                 }
17358                 /* Move from mmx/sse registers to 64bit gpr */
17359                 else if ((src_regcm & (REGCM_MMX | REGCM_XMM)) &&
17360                         (dst_regcm & REGCM_DIVIDEND64)) {
17361                         const char *extend;
17362                         extend = is_signed(src->type)? "cltd": "movl $0, %edx";
17363                         fprintf(fp, "\tmovd %s, %%eax\n\t%s\n",
17364                                 arch_reg_str(src_reg),
17365                                 extend);
17366                 }
17367                 /* Move from 64bit gpr to mmx/sse register */
17368                 else if ((src_regcm & REGCM_DIVIDEND64) &&
17369                         (dst_regcm & (REGCM_XMM | REGCM_MMX))) {
17370                         fprintf(fp, "\tmovd %%eax, %s\n",
17371                                 arch_reg_str(dst_reg));
17372                 }
17373 #if X86_4_8BIT_GPRS
17374                 /* Move from 8bit gprs to  mmx/sse registers */
17375                 else if ((src_regcm & REGCM_GPR8_LO) && (src_reg <= REG_DL) &&
17376                         (dst_regcm & (REGCM_MMX | REGCM_XMM))) {
17377                         const char *op;
17378                         int mid_reg;
17379                         op = is_signed(src->type)? "movsx":"movzx";
17380                         mid_reg = (src_reg - REGC_GPR8_FIRST) + REGC_GPR32_FIRST;
17381                         fprintf(fp, "\t%s %s, %s\n\tmovd %s, %s\n",
17382                                 op,
17383                                 reg(state, src, src_regcm),
17384                                 arch_reg_str(mid_reg),
17385                                 arch_reg_str(mid_reg),
17386                                 reg(state, dst, dst_regcm));
17387                 }
17388                 /* Move from mmx/sse registers and 8bit gprs */
17389                 else if ((src_regcm & (REGCM_MMX | REGCM_XMM)) &&
17390                         (dst_regcm & REGCM_GPR8_LO) && (dst_reg <= REG_DL)) {
17391                         int mid_reg;
17392                         mid_reg = (dst_reg - REGC_GPR8_FIRST) + REGC_GPR32_FIRST;
17393                         fprintf(fp, "\tmovd %s, %s\n",
17394                                 reg(state, src, src_regcm),
17395                                 arch_reg_str(mid_reg));
17396                 }
17397                 /* Move from 32bit gprs to 8bit gprs */
17398                 else if ((src_regcm & REGCM_GPR32) &&
17399                         (dst_regcm & REGCM_GPR8_LO)) {
17400                         dst_reg = (dst_reg - REGC_GPR8_FIRST) + REGC_GPR32_FIRST;
17401                         if ((src_reg != dst_reg) || !omit_copy) {
17402                                 fprintf(fp, "\tmov %s, %s\n",
17403                                         arch_reg_str(src_reg),
17404                                         arch_reg_str(dst_reg));
17405                         }
17406                 }
17407                 /* Move from 16bit gprs to 8bit gprs */
17408                 else if ((src_regcm & REGCM_GPR16) &&
17409                         (dst_regcm & REGCM_GPR8_LO)) {
17410                         dst_reg = (dst_reg - REGC_GPR8_FIRST) + REGC_GPR16_FIRST;
17411                         if ((src_reg != dst_reg) || !omit_copy) {
17412                                 fprintf(fp, "\tmov %s, %s\n",
17413                                         arch_reg_str(src_reg),
17414                                         arch_reg_str(dst_reg));
17415                         }
17416                 }
17417 #endif /* X86_4_8BIT_GPRS */
17418                 else {
17419                         internal_error(state, ins, "unknown copy type");
17420                 }
17421         }
17422         else {
17423                 int dst_reg;
17424                 int dst_regcm;
17425                 dst_reg = ID_REG(dst->id);
17426                 dst_regcm = arch_reg_regcm(state, dst_reg);
17427                 if (dst_regcm & (REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO)) {
17428                         fprintf(fp, "\tmov ");
17429                         print_const_val(state, src, fp);
17430                         fprintf(fp, ", %s\n",
17431                                 reg(state, dst, REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO));
17432                 }
17433                 else if (dst_regcm & REGCM_DIVIDEND64) {
17434                         if (size_of(state, dst->type) > 4) {
17435                                 internal_error(state, ins, "64bit constant...");
17436                         }
17437                         fprintf(fp, "\tmov $0, %%edx\n");
17438                         fprintf(fp, "\tmov ");
17439                         print_const_val(state, src, fp);
17440                         fprintf(fp, ", %%eax\n");
17441                 }
17442                 else if (dst_regcm & REGCM_DIVIDEND32) {
17443                         if (size_of(state, dst->type) > 2) {
17444                                 internal_error(state, ins, "32bit constant...");
17445                         }
17446                         fprintf(fp, "\tmov $0, %%dx\n");
17447                         fprintf(fp, "\tmov ");
17448                         print_const_val(state, src, fp);
17449                         fprintf(fp, ", %%ax");
17450                 }
17451                 else if (dst_regcm & (REGCM_XMM | REGCM_MMX)) {
17452                         long ref;
17453                         ref = get_const_pool_ref(state, src, fp);
17454                         fprintf(fp, "\tmovq L%s%lu, %s\n",
17455                                 state->label_prefix, ref,
17456                                 reg(state, dst, (REGCM_XMM | REGCM_MMX)));
17457                 }
17458                 else {
17459                         internal_error(state, ins, "unknown copy immediate type");
17460                 }
17461         }
17462 }
17463
17464 static void print_op_load(struct compile_state *state,
17465         struct triple *ins, FILE *fp)
17466 {
17467         struct triple *dst, *src;
17468         dst = ins;
17469         src = RHS(ins, 0);
17470         if (is_const(src) || is_const(dst)) {
17471                 internal_error(state, ins, "unknown load operation");
17472         }
17473         fprintf(fp, "\tmov (%s), %s\n",
17474                 reg(state, src, REGCM_GPR32),
17475                 reg(state, dst, REGCM_GPR8_LO | REGCM_GPR16 | REGCM_GPR32));
17476 }
17477
17478
17479 static void print_op_store(struct compile_state *state,
17480         struct triple *ins, FILE *fp)
17481 {
17482         struct triple *dst, *src;
17483         dst = RHS(ins, 0);
17484         src = RHS(ins, 1);
17485         if (is_const(src) && (src->op == OP_INTCONST)) {
17486                 long_t value;
17487                 value = (long_t)(src->u.cval);
17488                 fprintf(fp, "\tmov%s $%ld, (%s)\n",
17489                         type_suffix(state, src->type),
17490                         value,
17491                         reg(state, dst, REGCM_GPR32));
17492         }
17493         else if (is_const(dst) && (dst->op == OP_INTCONST)) {
17494                 fprintf(fp, "\tmov%s %s, 0x%08lx\n",
17495                         type_suffix(state, src->type),
17496                         reg(state, src, REGCM_GPR8_LO | REGCM_GPR16 | REGCM_GPR32),
17497                         dst->u.cval);
17498         }
17499         else {
17500                 if (is_const(src) || is_const(dst)) {
17501                         internal_error(state, ins, "unknown store operation");
17502                 }
17503                 fprintf(fp, "\tmov%s %s, (%s)\n",
17504                         type_suffix(state, src->type),
17505                         reg(state, src, REGCM_GPR8_LO | REGCM_GPR16 | REGCM_GPR32),
17506                         reg(state, dst, REGCM_GPR32));
17507         }
17508         
17509         
17510 }
17511
17512 static void print_op_smul(struct compile_state *state,
17513         struct triple *ins, FILE *fp)
17514 {
17515         if (!is_const(RHS(ins, 1))) {
17516                 fprintf(fp, "\timul %s, %s\n",
17517                         reg(state, RHS(ins, 1), REGCM_GPR32),
17518                         reg(state, RHS(ins, 0), REGCM_GPR32));
17519         }
17520         else {
17521                 fprintf(fp, "\timul ");
17522                 print_const_val(state, RHS(ins, 1), fp);
17523                 fprintf(fp, ", %s\n", reg(state, RHS(ins, 0), REGCM_GPR32));
17524         }
17525 }
17526
17527 static void print_op_cmp(struct compile_state *state,
17528         struct triple *ins, FILE *fp)
17529 {
17530         unsigned mask;
17531         int dreg;
17532         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO;
17533         dreg = check_reg(state, ins, REGCM_FLAGS);
17534         if (!reg_is_reg(state, dreg, REG_EFLAGS)) {
17535                 internal_error(state, ins, "bad dest register for cmp");
17536         }
17537         if (is_const(RHS(ins, 1))) {
17538                 fprintf(fp, "\tcmp ");
17539                 print_const_val(state, RHS(ins, 1), fp);
17540                 fprintf(fp, ", %s\n", reg(state, RHS(ins, 0), mask));
17541         }
17542         else {
17543                 unsigned lmask, rmask;
17544                 int lreg, rreg;
17545                 lreg = check_reg(state, RHS(ins, 0), mask);
17546                 rreg = check_reg(state, RHS(ins, 1), mask);
17547                 lmask = arch_reg_regcm(state, lreg);
17548                 rmask = arch_reg_regcm(state, rreg);
17549                 mask = lmask & rmask;
17550                 fprintf(fp, "\tcmp %s, %s\n",
17551                         reg(state, RHS(ins, 1), mask),
17552                         reg(state, RHS(ins, 0), mask));
17553         }
17554 }
17555
17556 static void print_op_test(struct compile_state *state,
17557         struct triple *ins, FILE *fp)
17558 {
17559         unsigned mask;
17560         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO;
17561         fprintf(fp, "\ttest %s, %s\n",
17562                 reg(state, RHS(ins, 0), mask),
17563                 reg(state, RHS(ins, 0), mask));
17564 }
17565
17566 static void print_op_branch(struct compile_state *state,
17567         struct triple *branch, FILE *fp)
17568 {
17569         const char *bop = "j";
17570         if (branch->op == OP_JMP) {
17571                 if (TRIPLE_RHS(branch->sizes) != 0) {
17572                         internal_error(state, branch, "jmp with condition?");
17573                 }
17574                 bop = "jmp";
17575         }
17576         else {
17577                 struct triple *ptr;
17578                 if (TRIPLE_RHS(branch->sizes) != 1) {
17579                         internal_error(state, branch, "jmpcc without condition?");
17580                 }
17581                 check_reg(state, RHS(branch, 0), REGCM_FLAGS);
17582                 if ((RHS(branch, 0)->op != OP_CMP) &&
17583                         (RHS(branch, 0)->op != OP_TEST)) {
17584                         internal_error(state, branch, "bad branch test");
17585                 }
17586 #warning "FIXME I have observed instructions between the test and branch instructions"
17587                 ptr = RHS(branch, 0);
17588                 for(ptr = RHS(branch, 0)->next; ptr != branch; ptr = ptr->next) {
17589                         if (ptr->op != OP_COPY) {
17590                                 internal_error(state, branch, "branch does not follow test");
17591                         }
17592                 }
17593                 switch(branch->op) {
17594                 case OP_JMP_EQ:       bop = "jz";  break;
17595                 case OP_JMP_NOTEQ:    bop = "jnz"; break;
17596                 case OP_JMP_SLESS:    bop = "jl";  break;
17597                 case OP_JMP_ULESS:    bop = "jb";  break;
17598                 case OP_JMP_SMORE:    bop = "jg";  break;
17599                 case OP_JMP_UMORE:    bop = "ja";  break;
17600                 case OP_JMP_SLESSEQ:  bop = "jle"; break;
17601                 case OP_JMP_ULESSEQ:  bop = "jbe"; break;
17602                 case OP_JMP_SMOREEQ:  bop = "jge"; break;
17603                 case OP_JMP_UMOREEQ:  bop = "jae"; break;
17604                 default:
17605                         internal_error(state, branch, "Invalid branch op");
17606                         break;
17607                 }
17608                 
17609         }
17610         fprintf(fp, "\t%s L%s%lu\n",
17611                 bop, 
17612                 state->label_prefix,
17613                 TARG(branch, 0)->u.cval);
17614 }
17615
17616 static void print_op_set(struct compile_state *state,
17617         struct triple *set, FILE *fp)
17618 {
17619         const char *sop = "set";
17620         if (TRIPLE_RHS(set->sizes) != 1) {
17621                 internal_error(state, set, "setcc without condition?");
17622         }
17623         check_reg(state, RHS(set, 0), REGCM_FLAGS);
17624         if ((RHS(set, 0)->op != OP_CMP) &&
17625                 (RHS(set, 0)->op != OP_TEST)) {
17626                 internal_error(state, set, "bad set test");
17627         }
17628         if (RHS(set, 0)->next != set) {
17629                 internal_error(state, set, "set does not follow test");
17630         }
17631         switch(set->op) {
17632         case OP_SET_EQ:       sop = "setz";  break;
17633         case OP_SET_NOTEQ:    sop = "setnz"; break;
17634         case OP_SET_SLESS:    sop = "setl";  break;
17635         case OP_SET_ULESS:    sop = "setb";  break;
17636         case OP_SET_SMORE:    sop = "setg";  break;
17637         case OP_SET_UMORE:    sop = "seta";  break;
17638         case OP_SET_SLESSEQ:  sop = "setle"; break;
17639         case OP_SET_ULESSEQ:  sop = "setbe"; break;
17640         case OP_SET_SMOREEQ:  sop = "setge"; break;
17641         case OP_SET_UMOREEQ:  sop = "setae"; break;
17642         default:
17643                 internal_error(state, set, "Invalid set op");
17644                 break;
17645         }
17646         fprintf(fp, "\t%s %s\n",
17647                 sop, reg(state, set, REGCM_GPR8_LO));
17648 }
17649
17650 static void print_op_bit_scan(struct compile_state *state, 
17651         struct triple *ins, FILE *fp) 
17652 {
17653         const char *op;
17654         switch(ins->op) {
17655         case OP_BSF: op = "bsf"; break;
17656         case OP_BSR: op = "bsr"; break;
17657         default: 
17658                 internal_error(state, ins, "unknown bit scan");
17659                 op = 0;
17660                 break;
17661         }
17662         fprintf(fp, 
17663                 "\t%s %s, %s\n"
17664                 "\tjnz 1f\n"
17665                 "\tmovl $-1, %s\n"
17666                 "1:\n",
17667                 op,
17668                 reg(state, RHS(ins, 0), REGCM_GPR32),
17669                 reg(state, ins, REGCM_GPR32),
17670                 reg(state, ins, REGCM_GPR32));
17671 }
17672
17673
17674 static void print_sdecl(struct compile_state *state,
17675         struct triple *ins, FILE *fp)
17676 {
17677         fprintf(fp, ".section \"" DATA_SECTION "\"\n");
17678         fprintf(fp, ".balign %d\n", align_of(state, ins->type));
17679         fprintf(fp, "L%s%lu:\n", state->label_prefix, ins->u.cval);
17680         print_const(state, MISC(ins, 0), fp);
17681         fprintf(fp, ".section \"" TEXT_SECTION "\"\n");
17682                 
17683 }
17684
17685 static void print_instruction(struct compile_state *state,
17686         struct triple *ins, FILE *fp)
17687 {
17688         /* Assumption: after I have exted the register allocator
17689          * everything is in a valid register. 
17690          */
17691         switch(ins->op) {
17692         case OP_ASM:
17693                 print_op_asm(state, ins, fp);
17694                 break;
17695         case OP_ADD:    print_binary_op(state, "add", ins, fp); break;
17696         case OP_SUB:    print_binary_op(state, "sub", ins, fp); break;
17697         case OP_AND:    print_binary_op(state, "and", ins, fp); break;
17698         case OP_XOR:    print_binary_op(state, "xor", ins, fp); break;
17699         case OP_OR:     print_binary_op(state, "or",  ins, fp); break;
17700         case OP_SL:     print_op_shift(state, "shl", ins, fp); break;
17701         case OP_USR:    print_op_shift(state, "shr", ins, fp); break;
17702         case OP_SSR:    print_op_shift(state, "sar", ins, fp); break;
17703         case OP_POS:    break;
17704         case OP_NEG:    print_unary_op(state, "neg", ins, fp); break;
17705         case OP_INVERT: print_unary_op(state, "not", ins, fp); break;
17706         case OP_INTCONST:
17707         case OP_ADDRCONST:
17708         case OP_BLOBCONST:
17709                 /* Don't generate anything here for constants */
17710         case OP_PHI:
17711                 /* Don't generate anything for variable declarations. */
17712                 break;
17713         case OP_SDECL:
17714                 print_sdecl(state, ins, fp);
17715                 break;
17716         case OP_COPY:   
17717                 print_op_move(state, ins, fp);
17718                 break;
17719         case OP_LOAD:
17720                 print_op_load(state, ins, fp);
17721                 break;
17722         case OP_STORE:
17723                 print_op_store(state, ins, fp);
17724                 break;
17725         case OP_SMUL:
17726                 print_op_smul(state, ins, fp);
17727                 break;
17728         case OP_CMP:    print_op_cmp(state, ins, fp); break;
17729         case OP_TEST:   print_op_test(state, ins, fp); break;
17730         case OP_JMP:
17731         case OP_JMP_EQ:      case OP_JMP_NOTEQ:
17732         case OP_JMP_SLESS:   case OP_JMP_ULESS:
17733         case OP_JMP_SMORE:   case OP_JMP_UMORE:
17734         case OP_JMP_SLESSEQ: case OP_JMP_ULESSEQ:
17735         case OP_JMP_SMOREEQ: case OP_JMP_UMOREEQ:
17736                 print_op_branch(state, ins, fp);
17737                 break;
17738         case OP_SET_EQ:      case OP_SET_NOTEQ:
17739         case OP_SET_SLESS:   case OP_SET_ULESS:
17740         case OP_SET_SMORE:   case OP_SET_UMORE:
17741         case OP_SET_SLESSEQ: case OP_SET_ULESSEQ:
17742         case OP_SET_SMOREEQ: case OP_SET_UMOREEQ:
17743                 print_op_set(state, ins, fp);
17744                 break;
17745         case OP_INB:  case OP_INW:  case OP_INL:
17746                 print_op_in(state, ins, fp); 
17747                 break;
17748         case OP_OUTB: case OP_OUTW: case OP_OUTL:
17749                 print_op_out(state, ins, fp); 
17750                 break;
17751         case OP_BSF:
17752         case OP_BSR:
17753                 print_op_bit_scan(state, ins, fp);
17754                 break;
17755         case OP_RDMSR:
17756                 after_lhs(state, ins);
17757                 fprintf(fp, "\trdmsr\n");
17758                 break;
17759         case OP_WRMSR:
17760                 fprintf(fp, "\twrmsr\n");
17761                 break;
17762         case OP_HLT:
17763                 fprintf(fp, "\thlt\n");
17764                 break;
17765         case OP_SDIVT:
17766                 fprintf(fp, "\tidiv %s\n", reg(state, RHS(ins, 1), REGCM_GPR32));
17767                 break;
17768         case OP_UDIVT:
17769                 fprintf(fp, "\tdiv %s\n", reg(state, RHS(ins, 1), REGCM_GPR32));
17770                 break;
17771         case OP_UMUL:
17772                 fprintf(fp, "\tmul %s\n", reg(state, RHS(ins, 1), REGCM_GPR32));
17773                 break;
17774         case OP_LABEL:
17775                 if (!ins->use) {
17776                         return;
17777                 }
17778                 fprintf(fp, "L%s%lu:\n", state->label_prefix, ins->u.cval);
17779                 break;
17780                 /* Ignore OP_PIECE */
17781         case OP_PIECE:
17782                 break;
17783                 /* Operations that should never get here */
17784         case OP_SDIV: case OP_UDIV:
17785         case OP_SMOD: case OP_UMOD:
17786         case OP_LTRUE:   case OP_LFALSE:  case OP_EQ:      case OP_NOTEQ:
17787         case OP_SLESS:   case OP_ULESS:   case OP_SMORE:   case OP_UMORE:
17788         case OP_SLESSEQ: case OP_ULESSEQ: case OP_SMOREEQ: case OP_UMOREEQ:
17789         default:
17790                 internal_error(state, ins, "unknown op: %d %s",
17791                         ins->op, tops(ins->op));
17792                 break;
17793         }
17794 }
17795
17796 static void print_instructions(struct compile_state *state)
17797 {
17798         struct triple *first, *ins;
17799         int print_location;
17800         struct occurance *last_occurance;
17801         FILE *fp;
17802         int max_inline_depth;
17803         max_inline_depth = 0;
17804         print_location = 1;
17805         last_occurance = 0;
17806         fp = state->output;
17807         fprintf(fp, ".section \"" TEXT_SECTION "\"\n");
17808         first = RHS(state->main_function, 0);
17809         ins = first;
17810         do {
17811                 if (print_location && 
17812                         last_occurance != ins->occurance) {
17813                         if (!ins->occurance->parent) {
17814                                 fprintf(fp, "\t/* %s,%s:%d.%d */\n",
17815                                         ins->occurance->function,
17816                                         ins->occurance->filename,
17817                                         ins->occurance->line,
17818                                         ins->occurance->col);
17819                         }
17820                         else {
17821                                 struct occurance *ptr;
17822                                 int inline_depth;
17823                                 fprintf(fp, "\t/*\n");
17824                                 inline_depth = 0;
17825                                 for(ptr = ins->occurance; ptr; ptr = ptr->parent) {
17826                                         inline_depth++;
17827                                         fprintf(fp, "\t * %s,%s:%d.%d\n",
17828                                                 ptr->function,
17829                                                 ptr->filename,
17830                                                 ptr->line,
17831                                                 ptr->col);
17832                                 }
17833                                 fprintf(fp, "\t */\n");
17834                                 if (inline_depth > max_inline_depth) {
17835                                         max_inline_depth = inline_depth;
17836                                 }
17837                         }
17838                         if (last_occurance) {
17839                                 put_occurance(last_occurance);
17840                         }
17841                         get_occurance(ins->occurance);
17842                         last_occurance = ins->occurance;
17843                 }
17844
17845                 print_instruction(state, ins, fp);
17846                 ins = ins->next;
17847         } while(ins != first);
17848         if (print_location) {
17849                 fprintf(fp, "/* max inline depth %d */\n",
17850                         max_inline_depth);
17851         }
17852 }
17853
17854 static void generate_code(struct compile_state *state)
17855 {
17856         generate_local_labels(state);
17857         print_instructions(state);
17858         
17859 }
17860
17861 static void print_tokens(struct compile_state *state)
17862 {
17863         struct token *tk;
17864         tk = &state->token[0];
17865         do {
17866 #if 1
17867                 token(state, 0);
17868 #else
17869                 next_token(state, 0);
17870 #endif
17871                 loc(stdout, state, 0);
17872                 printf("%s <- `%s'\n",
17873                         tokens[tk->tok],
17874                         tk->ident ? tk->ident->name :
17875                         tk->str_len ? tk->val.str : "");
17876                 
17877         } while(tk->tok != TOK_EOF);
17878 }
17879
17880 static void compile(const char *filename, const char *ofilename, 
17881         int cpu, int debug, int opt, const char *label_prefix)
17882 {
17883         int i;
17884         struct compile_state state;
17885         memset(&state, 0, sizeof(state));
17886         state.file = 0;
17887         for(i = 0; i < sizeof(state.token)/sizeof(state.token[0]); i++) {
17888                 memset(&state.token[i], 0, sizeof(state.token[i]));
17889                 state.token[i].tok = -1;
17890         }
17891         /* Remember the debug settings */
17892         state.cpu      = cpu;
17893         state.debug    = debug;
17894         state.optimize = opt;
17895         /* Remember the output filename */
17896         state.ofilename = ofilename;
17897         state.output    = fopen(state.ofilename, "w");
17898         if (!state.output) {
17899                 error(&state, 0, "Cannot open output file %s\n",
17900                         ofilename);
17901         }
17902         /* Remember the label prefix */
17903         state.label_prefix = label_prefix;
17904         /* Prep the preprocessor */
17905         state.if_depth = 0;
17906         state.if_value = 0;
17907         /* register the C keywords */
17908         register_keywords(&state);
17909         /* register the keywords the macro preprocessor knows */
17910         register_macro_keywords(&state);
17911         /* Memorize where some special keywords are. */
17912         state.i_continue = lookup(&state, "continue", 8);
17913         state.i_break    = lookup(&state, "break", 5);
17914         /* Enter the globl definition scope */
17915         start_scope(&state);
17916         register_builtins(&state);
17917         compile_file(&state, filename, 1);
17918 #if 0
17919         print_tokens(&state);
17920 #endif  
17921         decls(&state);
17922         /* Exit the global definition scope */
17923         end_scope(&state);
17924
17925         /* Now that basic compilation has happened 
17926          * optimize the intermediate code 
17927          */
17928         optimize(&state);
17929
17930         generate_code(&state);
17931         if (state.debug) {
17932                 fprintf(stderr, "done\n");
17933         }
17934 }
17935
17936 static void version(void)
17937 {
17938         printf("romcc " VERSION " released " RELEASE_DATE "\n");
17939 }
17940
17941 static void usage(void)
17942 {
17943         version();
17944         printf(
17945                 "Usage: romcc <source>.c\n"
17946                 "Compile a C source file without using ram\n"
17947         );
17948 }
17949
17950 static void arg_error(char *fmt, ...)
17951 {
17952         va_list args;
17953         va_start(args, fmt);
17954         vfprintf(stderr, fmt, args);
17955         va_end(args);
17956         usage();
17957         exit(1);
17958 }
17959
17960 int main(int argc, char **argv)
17961 {
17962         const char *filename;
17963         const char *ofilename;
17964         const char *label_prefix;
17965         int cpu;
17966         int last_argc;
17967         int debug;
17968         int optimize;
17969         cpu = CPU_DEFAULT;
17970         label_prefix = "";
17971         ofilename = "auto.inc";
17972         optimize = 0;
17973         debug = 0;
17974         last_argc = -1;
17975         while((argc > 1) && (argc != last_argc)) {
17976                 last_argc = argc;
17977                 if (strncmp(argv[1], "--debug=", 8) == 0) {
17978                         debug = atoi(argv[1] + 8);
17979                         argv++;
17980                         argc--;
17981                 }
17982                 else if (strncmp(argv[1], "--label-prefix=", 15) == 0) {
17983                         label_prefix= argv[1] + 15;
17984                         argv++;
17985                         argc--;
17986                 }
17987                 else if ((strcmp(argv[1],"-O") == 0) ||
17988                         (strcmp(argv[1], "-O1") == 0)) {
17989                         optimize = 1;
17990                         argv++;
17991                         argc--;
17992                 }
17993                 else if (strcmp(argv[1],"-O2") == 0) {
17994                         optimize = 2;
17995                         argv++;
17996                         argc--;
17997                 }
17998                 else if ((strcmp(argv[1], "-o") == 0) && (argc > 2)) {
17999                         ofilename = argv[2];
18000                         argv += 2;
18001                         argc -= 2;
18002                 }
18003                 else if (strncmp(argv[1], "-mcpu=", 6) == 0) {
18004                         cpu = arch_encode_cpu(argv[1] + 6);
18005                         if (cpu == BAD_CPU) {
18006                                 arg_error("Invalid cpu specified: %s\n",
18007                                         argv[1] + 6);
18008                         }
18009                         argv++;
18010                         argc--;
18011                 }
18012         }
18013         if (argc != 2) {
18014                 arg_error("Wrong argument count %d\n", argc);
18015         }
18016         filename = argv[1];
18017         compile(filename, ofilename, cpu, debug, optimize, label_prefix);
18018
18019         return 0;
18020 }