- Structure handling fixes.
[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 + size_of(state, 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         {
4025                 size_t align, pad;
4026                 size = size_of(state, type->left);
4027                 /* Pad structures so their size is a multiples of their alignment */
4028                 align = align_of(state, type);
4029                 pad = needed_padding(size, align);
4030                 size = size + pad;
4031                 break;
4032         }
4033         default:
4034                 internal_error(state, 0, "sizeof not yet defined for type\n");
4035                 break;
4036         }
4037         return size;
4038 }
4039
4040 static size_t field_offset(struct compile_state *state, 
4041         struct type *type, struct hash_entry *field)
4042 {
4043         struct type *member;
4044         size_t size, align;
4045         if ((type->type & TYPE_MASK) != TYPE_STRUCT) {
4046                 internal_error(state, 0, "field_offset only works on structures");
4047         }
4048         size = 0;
4049         member = type->left;
4050         while((member->type & TYPE_MASK) == TYPE_PRODUCT) {
4051                 align = align_of(state, member->left);
4052                 size += needed_padding(size, align);
4053                 if (member->left->field_ident == field) {
4054                         member = member->left;
4055                         break;
4056                 }
4057                 size += size_of(state, member->left);
4058                 member = member->right;
4059         }
4060         align = align_of(state, member);
4061         size += needed_padding(size, align);
4062         if (member->field_ident != field) {
4063                 error(state, 0, "member %s not present", field->name);
4064         }
4065         return size;
4066 }
4067
4068 static struct type *field_type(struct compile_state *state, 
4069         struct type *type, struct hash_entry *field)
4070 {
4071         struct type *member;
4072         if ((type->type & TYPE_MASK) != TYPE_STRUCT) {
4073                 internal_error(state, 0, "field_type only works on structures");
4074         }
4075         member = type->left;
4076         while((member->type & TYPE_MASK) == TYPE_PRODUCT) {
4077                 if (member->left->field_ident == field) {
4078                         member = member->left;
4079                         break;
4080                 }
4081                 member = member->right;
4082         }
4083         if (member->field_ident != field) {
4084                 error(state, 0, "member %s not present", field->name);
4085         }
4086         return member;
4087 }
4088
4089 static struct type *next_field(struct compile_state *state,
4090         struct type *type, struct type *prev_member) 
4091 {
4092         struct type *member;
4093         if ((type->type & TYPE_MASK) != TYPE_STRUCT) {
4094                 internal_error(state, 0, "next_field only works on structures");
4095         }
4096         member = type->left;
4097         while((member->type & TYPE_MASK) == TYPE_PRODUCT) {
4098                 if (!prev_member) {
4099                         member = member->left;
4100                         break;
4101                 }
4102                 if (member->left == prev_member) {
4103                         prev_member = 0;
4104                 }
4105                 member = member->right;
4106         }
4107         if (member == prev_member) {
4108                 prev_member = 0;
4109         }
4110         if (prev_member) {
4111                 internal_error(state, 0, "prev_member %s not present", 
4112                         prev_member->field_ident->name);
4113         }
4114         return member;
4115 }
4116
4117 static struct triple *struct_field(struct compile_state *state,
4118         struct triple *decl, struct hash_entry *field)
4119 {
4120         struct triple **vector;
4121         struct type *type;
4122         ulong_t index;
4123         type = decl->type;
4124         if ((type->type & TYPE_MASK) != TYPE_STRUCT) {
4125                 return decl;
4126         }
4127         if (decl->op != OP_VAL_VEC) {
4128                 internal_error(state, 0, "Invalid struct variable");
4129         }
4130         if (!field) {
4131                 internal_error(state, 0, "Missing structure field");
4132         }
4133         type = type->left;
4134         vector = &RHS(decl, 0);
4135         index = 0;
4136         while((type->type & TYPE_MASK) == TYPE_PRODUCT) {
4137                 if (type->left->field_ident == field) {
4138                         type = type->left;
4139                         break;
4140                 }
4141                 index += 1;
4142                 type = type->right;
4143         }
4144         if (type->field_ident != field) {
4145                 internal_error(state, 0, "field %s not found?", field->name);
4146         }
4147         return vector[index];
4148 }
4149
4150 static void arrays_complete(struct compile_state *state, struct type *type)
4151 {
4152         if ((type->type & TYPE_MASK) == TYPE_ARRAY) {
4153                 if (type->elements == ELEMENT_COUNT_UNSPECIFIED) {
4154                         error(state, 0, "array size not specified");
4155                 }
4156                 arrays_complete(state, type->left);
4157         }
4158 }
4159
4160 static unsigned int do_integral_promotion(unsigned int type)
4161 {
4162         type &= TYPE_MASK;
4163         if (TYPE_INTEGER(type) && 
4164                 TYPE_RANK(type) < TYPE_RANK(TYPE_INT)) {
4165                 type = TYPE_INT;
4166         }
4167         return type;
4168 }
4169
4170 static unsigned int do_arithmetic_conversion(
4171         unsigned int left, unsigned int right)
4172 {
4173         left &= TYPE_MASK;
4174         right &= TYPE_MASK;
4175         if ((left == TYPE_LDOUBLE) || (right == TYPE_LDOUBLE)) {
4176                 return TYPE_LDOUBLE;
4177         }
4178         else if ((left == TYPE_DOUBLE) || (right == TYPE_DOUBLE)) {
4179                 return TYPE_DOUBLE;
4180         }
4181         else if ((left == TYPE_FLOAT) || (right == TYPE_FLOAT)) {
4182                 return TYPE_FLOAT;
4183         }
4184         left = do_integral_promotion(left);
4185         right = do_integral_promotion(right);
4186         /* If both operands have the same size done */
4187         if (left == right) {
4188                 return left;
4189         }
4190         /* If both operands have the same signedness pick the larger */
4191         else if (!!TYPE_UNSIGNED(left) == !!TYPE_UNSIGNED(right)) {
4192                 return (TYPE_RANK(left) >= TYPE_RANK(right)) ? left : right;
4193         }
4194         /* If the signed type can hold everything use it */
4195         else if (TYPE_SIGNED(left) && (TYPE_RANK(left) > TYPE_RANK(right))) {
4196                 return left;
4197         }
4198         else if (TYPE_SIGNED(right) && (TYPE_RANK(right) > TYPE_RANK(left))) {
4199                 return right;
4200         }
4201         /* Convert to the unsigned type with the same rank as the signed type */
4202         else if (TYPE_SIGNED(left)) {
4203                 return TYPE_MKUNSIGNED(left);
4204         }
4205         else {
4206                 return TYPE_MKUNSIGNED(right);
4207         }
4208 }
4209
4210 /* see if two types are the same except for qualifiers */
4211 static int equiv_types(struct type *left, struct type *right)
4212 {
4213         unsigned int type;
4214         /* Error if the basic types do not match */
4215         if ((left->type & TYPE_MASK) != (right->type & TYPE_MASK)) {
4216                 return 0;
4217         }
4218         type = left->type & TYPE_MASK;
4219         /* If the basic types match and it is a void type we are done */
4220         if (type == TYPE_VOID) {
4221                 return 1;
4222         }
4223         /* if the basic types match and it is an arithmetic type we are done */
4224         if (TYPE_ARITHMETIC(type)) {
4225                 return 1;
4226         }
4227         /* If it is a pointer type recurse and keep testing */
4228         if (type == TYPE_POINTER) {
4229                 return equiv_types(left->left, right->left);
4230         }
4231         else if (type == TYPE_ARRAY) {
4232                 return (left->elements == right->elements) &&
4233                         equiv_types(left->left, right->left);
4234         }
4235         /* test for struct/union equality */
4236         else if (type == TYPE_STRUCT) {
4237                 return left->type_ident == right->type_ident;
4238         }
4239         /* Test for equivalent functions */
4240         else if (type == TYPE_FUNCTION) {
4241                 return equiv_types(left->left, right->left) &&
4242                         equiv_types(left->right, right->right);
4243         }
4244         /* We only see TYPE_PRODUCT as part of function equivalence matching */
4245         else if (type == TYPE_PRODUCT) {
4246                 return equiv_types(left->left, right->left) &&
4247                         equiv_types(left->right, right->right);
4248         }
4249         /* We should see TYPE_OVERLAP */
4250         else {
4251                 return 0;
4252         }
4253 }
4254
4255 static int equiv_ptrs(struct type *left, struct type *right)
4256 {
4257         if (((left->type & TYPE_MASK) != TYPE_POINTER) ||
4258                 ((right->type & TYPE_MASK) != TYPE_POINTER)) {
4259                 return 0;
4260         }
4261         return equiv_types(left->left, right->left);
4262 }
4263
4264 static struct type *compatible_types(struct type *left, struct type *right)
4265 {
4266         struct type *result;
4267         unsigned int type, qual_type;
4268         /* Error if the basic types do not match */
4269         if ((left->type & TYPE_MASK) != (right->type & TYPE_MASK)) {
4270                 return 0;
4271         }
4272         type = left->type & TYPE_MASK;
4273         qual_type = (left->type & ~STOR_MASK) | (right->type & ~STOR_MASK);
4274         result = 0;
4275         /* if the basic types match and it is an arithmetic type we are done */
4276         if (TYPE_ARITHMETIC(type)) {
4277                 result = new_type(qual_type, 0, 0);
4278         }
4279         /* If it is a pointer type recurse and keep testing */
4280         else if (type == TYPE_POINTER) {
4281                 result = compatible_types(left->left, right->left);
4282                 if (result) {
4283                         result = new_type(qual_type, result, 0);
4284                 }
4285         }
4286         /* test for struct/union equality */
4287         else if (type == TYPE_STRUCT) {
4288                 if (left->type_ident == right->type_ident) {
4289                         result = left;
4290                 }
4291         }
4292         /* Test for equivalent functions */
4293         else if (type == TYPE_FUNCTION) {
4294                 struct type *lf, *rf;
4295                 lf = compatible_types(left->left, right->left);
4296                 rf = compatible_types(left->right, right->right);
4297                 if (lf && rf) {
4298                         result = new_type(qual_type, lf, rf);
4299                 }
4300         }
4301         /* We only see TYPE_PRODUCT as part of function equivalence matching */
4302         else if (type == TYPE_PRODUCT) {
4303                 struct type *lf, *rf;
4304                 lf = compatible_types(left->left, right->left);
4305                 rf = compatible_types(left->right, right->right);
4306                 if (lf && rf) {
4307                         result = new_type(qual_type, lf, rf);
4308                 }
4309         }
4310         else {
4311                 /* Nothing else is compatible */
4312         }
4313         return result;
4314 }
4315
4316 static struct type *compatible_ptrs(struct type *left, struct type *right)
4317 {
4318         struct type *result;
4319         if (((left->type & TYPE_MASK) != TYPE_POINTER) ||
4320                 ((right->type & TYPE_MASK) != TYPE_POINTER)) {
4321                 return 0;
4322         }
4323         result = compatible_types(left->left, right->left);
4324         if (result) {
4325                 unsigned int qual_type;
4326                 qual_type = (left->type & ~STOR_MASK) | (right->type & ~STOR_MASK);
4327                 result = new_type(qual_type, result, 0);
4328         }
4329         return result;
4330         
4331 }
4332 static struct triple *integral_promotion(
4333         struct compile_state *state, struct triple *def)
4334 {
4335         struct type *type;
4336         type = def->type;
4337         /* As all operations are carried out in registers
4338          * the values are converted on load I just convert
4339          * logical type of the operand.
4340          */
4341         if (TYPE_INTEGER(type->type)) {
4342                 unsigned int int_type;
4343                 int_type = type->type & ~TYPE_MASK;
4344                 int_type |= do_integral_promotion(type->type);
4345                 if (int_type != type->type) {
4346                         def->type = new_type(int_type, 0, 0);
4347                 }
4348         }
4349         return def;
4350 }
4351
4352
4353 static void arithmetic(struct compile_state *state, struct triple *def)
4354 {
4355         if (!TYPE_ARITHMETIC(def->type->type)) {
4356                 error(state, 0, "arithmetic type expexted");
4357         }
4358 }
4359
4360 static void ptr_arithmetic(struct compile_state *state, struct triple *def)
4361 {
4362         if (!TYPE_PTR(def->type->type) && !TYPE_ARITHMETIC(def->type->type)) {
4363                 error(state, def, "pointer or arithmetic type expected");
4364         }
4365 }
4366
4367 static int is_integral(struct triple *ins)
4368 {
4369         return TYPE_INTEGER(ins->type->type);
4370 }
4371
4372 static void integral(struct compile_state *state, struct triple *def)
4373 {
4374         if (!is_integral(def)) {
4375                 error(state, 0, "integral type expected");
4376         }
4377 }
4378
4379
4380 static void bool(struct compile_state *state, struct triple *def)
4381 {
4382         if (!TYPE_ARITHMETIC(def->type->type) &&
4383                 ((def->type->type & TYPE_MASK) != TYPE_POINTER)) {
4384                 error(state, 0, "arithmetic or pointer type expected");
4385         }
4386 }
4387
4388 static int is_signed(struct type *type)
4389 {
4390         return !!TYPE_SIGNED(type->type);
4391 }
4392
4393 /* Is this value located in a register otherwise it must be in memory */
4394 static int is_in_reg(struct compile_state *state, struct triple *def)
4395 {
4396         int in_reg;
4397         if (def->op == OP_ADECL) {
4398                 in_reg = 1;
4399         }
4400         else if ((def->op == OP_SDECL) || (def->op == OP_DEREF)) {
4401                 in_reg = 0;
4402         }
4403         else if (def->op == OP_VAL_VEC) {
4404                 in_reg = is_in_reg(state, RHS(def, 0));
4405         }
4406         else if (def->op == OP_DOT) {
4407                 in_reg = is_in_reg(state, RHS(def, 0));
4408         }
4409         else {
4410                 internal_error(state, 0, "unknown expr storage location");
4411                 in_reg = -1;
4412         }
4413         return in_reg;
4414 }
4415
4416 /* Is this a stable variable location otherwise it must be a temporary */
4417 static int is_stable(struct compile_state *state, struct triple *def)
4418 {
4419         int ret;
4420         ret = 0;
4421         if (!def) {
4422                 return 0;
4423         }
4424         if ((def->op == OP_ADECL) || 
4425                 (def->op == OP_SDECL) || 
4426                 (def->op == OP_DEREF) ||
4427                 (def->op == OP_BLOBCONST)) {
4428                 ret = 1;
4429         }
4430         else if (def->op == OP_DOT) {
4431                 ret = is_stable(state, RHS(def, 0));
4432         }
4433         else if (def->op == OP_VAL_VEC) {
4434                 struct triple **vector;
4435                 ulong_t i;
4436                 ret = 1;
4437                 vector = &RHS(def, 0);
4438                 for(i = 0; i < def->type->elements; i++) {
4439                         if (!is_stable(state, vector[i])) {
4440                                 ret = 0;
4441                                 break;
4442                         }
4443                 }
4444         }
4445         return ret;
4446 }
4447
4448 static int is_lvalue(struct compile_state *state, struct triple *def)
4449 {
4450         int ret;
4451         ret = 1;
4452         if (!def) {
4453                 return 0;
4454         }
4455         if (!is_stable(state, def)) {
4456                 return 0;
4457         }
4458         if (def->op == OP_DOT) {
4459                 ret = is_lvalue(state, RHS(def, 0));
4460         }
4461         return ret;
4462 }
4463
4464 static void clvalue(struct compile_state *state, struct triple *def)
4465 {
4466         if (!def) {
4467                 internal_error(state, def, "nothing where lvalue expected?");
4468         }
4469         if (!is_lvalue(state, def)) { 
4470                 error(state, def, "lvalue expected");
4471         }
4472 }
4473 static void lvalue(struct compile_state *state, struct triple *def)
4474 {
4475         clvalue(state, def);
4476         if (def->type->type & QUAL_CONST) {
4477                 error(state, def, "modifable lvalue expected");
4478         }
4479 }
4480
4481 static int is_pointer(struct triple *def)
4482 {
4483         return (def->type->type & TYPE_MASK) == TYPE_POINTER;
4484 }
4485
4486 static void pointer(struct compile_state *state, struct triple *def)
4487 {
4488         if (!is_pointer(def)) {
4489                 error(state, def, "pointer expected");
4490         }
4491 }
4492
4493 static struct triple *int_const(
4494         struct compile_state *state, struct type *type, ulong_t value)
4495 {
4496         struct triple *result;
4497         switch(type->type & TYPE_MASK) {
4498         case TYPE_CHAR:
4499         case TYPE_INT:   case TYPE_UINT:
4500         case TYPE_LONG:  case TYPE_ULONG:
4501                 break;
4502         default:
4503                 internal_error(state, 0, "constant for unkown type");
4504         }
4505         result = triple(state, OP_INTCONST, type, 0, 0);
4506         result->u.cval = value;
4507         return result;
4508 }
4509
4510
4511 static struct triple *do_mk_addr_expr(struct compile_state *state, 
4512         struct triple *expr, struct type *type, ulong_t offset)
4513 {
4514         struct triple *result;
4515         clvalue(state, expr);
4516
4517         type = new_type(TYPE_POINTER | (type->type & QUAL_MASK), type, 0);
4518
4519         result = 0;
4520         if (expr->op == OP_ADECL) {
4521                 error(state, expr, "address of auto variables not supported");
4522         }
4523         else if (expr->op == OP_SDECL) {
4524                 result = triple(state, OP_ADDRCONST, type, 0, 0);
4525                 MISC(result, 0) = expr;
4526                 result->u.cval = offset;
4527         }
4528         else if (expr->op == OP_DEREF) {
4529                 result = triple(state, OP_ADD, type,
4530                         RHS(expr, 0),
4531                         int_const(state, &ulong_type, offset));
4532         }
4533         return result;
4534 }
4535
4536 static struct triple *mk_addr_expr(
4537         struct compile_state *state, struct triple *expr, ulong_t offset)
4538 {
4539         return do_mk_addr_expr(state, expr, expr->type, offset);
4540 }
4541
4542 static struct triple *mk_deref_expr(
4543         struct compile_state *state, struct triple *expr)
4544 {
4545         struct type *base_type;
4546         pointer(state, expr);
4547         base_type = expr->type->left;
4548         return triple(state, OP_DEREF, base_type, expr, 0);
4549 }
4550
4551 static struct triple *array_to_pointer(struct compile_state *state, struct triple *def)
4552 {
4553         if ((def->type->type & TYPE_MASK) == TYPE_ARRAY) {
4554                 struct type *type;
4555                 type = new_type(
4556                         TYPE_POINTER | (def->type->type & QUAL_MASK),
4557                         def->type->left, 0);
4558                 if ((def->op == OP_SDECL) || IS_CONST_OP(def->op)) {
4559                         struct triple *addrconst;
4560                         if ((def->op != OP_SDECL) && (def->op != OP_BLOBCONST)) {
4561                                 internal_error(state, def, "bad array constant");
4562                         }
4563                         addrconst = triple(state, OP_ADDRCONST, type, 0, 0);
4564                         MISC(addrconst, 0) = def;
4565                         def = addrconst;
4566                 }
4567                 else {
4568                         def = triple(state, OP_COPY, type, def, 0);
4569                 }
4570         }
4571         return def;
4572 }
4573
4574 static struct triple *deref_field(
4575         struct compile_state *state, struct triple *expr, struct hash_entry *field)
4576 {
4577         struct triple *result;
4578         struct type *type, *member;
4579         if (!field) {
4580                 internal_error(state, 0, "No field passed to deref_field");
4581         }
4582         result = 0;
4583         type = expr->type;
4584         if ((type->type & TYPE_MASK) != TYPE_STRUCT) {
4585                 error(state, 0, "request for member %s in something not a struct or union",
4586                         field->name);
4587         }
4588         member = field_type(state, type, field);
4589         if ((type->type & STOR_MASK) == STOR_PERM) {
4590                 /* Do the pointer arithmetic to get a deref the field */
4591                 ulong_t offset;
4592                 offset = field_offset(state, type, field);
4593                 result = do_mk_addr_expr(state, expr, member, offset);
4594                 result = mk_deref_expr(state, result);
4595         }
4596         else {
4597                 /* Find the variable for the field I want. */
4598                 result = triple(state, OP_DOT, member, expr, 0);
4599                 result->u.field = field;
4600         }
4601         return result;
4602 }
4603
4604 static struct triple *read_expr(struct compile_state *state, struct triple *def)
4605 {
4606         int op;
4607         if  (!def) {
4608                 return 0;
4609         }
4610         if (!is_stable(state, def)) {
4611                 return def;
4612         }
4613         /* Tranform an array to a pointer to the first element */
4614         
4615 #warning "CHECK_ME is this the right place to transform arrays to pointers?"
4616         if ((def->type->type & TYPE_MASK) == TYPE_ARRAY) {
4617                 return array_to_pointer(state, def);
4618         }
4619         if (is_in_reg(state, def)) {
4620                 op = OP_READ;
4621         } else {
4622                 op = OP_LOAD;
4623         }
4624         return triple(state, op, def->type, def, 0);
4625 }
4626
4627 int is_write_compatible(struct compile_state *state, 
4628         struct type *dest, struct type *rval)
4629 {
4630         int compatible = 0;
4631         /* Both operands have arithmetic type */
4632         if (TYPE_ARITHMETIC(dest->type) && TYPE_ARITHMETIC(rval->type)) {
4633                 compatible = 1;
4634         }
4635         /* One operand is a pointer and the other is a pointer to void */
4636         else if (((dest->type & TYPE_MASK) == TYPE_POINTER) &&
4637                 ((rval->type & TYPE_MASK) == TYPE_POINTER) &&
4638                 (((dest->left->type & TYPE_MASK) == TYPE_VOID) ||
4639                         ((rval->left->type & TYPE_MASK) == TYPE_VOID))) {
4640                 compatible = 1;
4641         }
4642         /* If both types are the same without qualifiers we are good */
4643         else if (equiv_ptrs(dest, rval)) {
4644                 compatible = 1;
4645         }
4646         /* test for struct/union equality  */
4647         else if (((dest->type & TYPE_MASK) == TYPE_STRUCT) &&
4648                 ((rval->type & TYPE_MASK) == TYPE_STRUCT) &&
4649                 (dest->type_ident == rval->type_ident)) {
4650                 compatible = 1;
4651         }
4652         return compatible;
4653 }
4654
4655
4656 static void write_compatible(struct compile_state *state,
4657         struct type *dest, struct type *rval)
4658 {
4659         if (!is_write_compatible(state, dest, rval)) {
4660                 error(state, 0, "Incompatible types in assignment");
4661         }
4662 }
4663
4664 static int is_init_compatible(struct compile_state *state,
4665         struct type *dest, struct type *rval)
4666 {
4667         int compatible = 0;
4668         if (is_write_compatible(state, dest, rval)) {
4669                 compatible = 1;
4670         }
4671         else if (equiv_types(dest, rval)) {
4672                 compatible = 1;
4673         }
4674         return compatible;
4675 }
4676
4677 static struct triple *write_expr(
4678         struct compile_state *state, struct triple *dest, struct triple *rval)
4679 {
4680         struct triple *def;
4681         int op;
4682
4683         def = 0;
4684         if (!rval) {
4685                 internal_error(state, 0, "missing rval");
4686         }
4687
4688         if (rval->op == OP_LIST) {
4689                 internal_error(state, 0, "expression of type OP_LIST?");
4690         }
4691         if (!is_lvalue(state, dest)) {
4692                 internal_error(state, 0, "writing to a non lvalue?");
4693         }
4694         if (dest->type->type & QUAL_CONST) {
4695                 internal_error(state, 0, "modifable lvalue expexted");
4696         }
4697
4698         write_compatible(state, dest->type, rval->type);
4699
4700         /* Now figure out which assignment operator to use */
4701         op = -1;
4702         if (is_in_reg(state, dest)) {
4703                 op = OP_WRITE;
4704         } else {
4705                 op = OP_STORE;
4706         }
4707         def = triple(state, op, dest->type, dest, rval);
4708         return def;
4709 }
4710
4711 static struct triple *init_expr(
4712         struct compile_state *state, struct triple *dest, struct triple *rval)
4713 {
4714         struct triple *def;
4715
4716         def = 0;
4717         if (!rval) {
4718                 internal_error(state, 0, "missing rval");
4719         }
4720         if ((dest->type->type & STOR_MASK) != STOR_PERM) {
4721                 rval = read_expr(state, rval);
4722                 def = write_expr(state, dest, rval);
4723         }
4724         else {
4725                 /* Fill in the array size if necessary */
4726                 if (((dest->type->type & TYPE_MASK) == TYPE_ARRAY) &&
4727                         ((rval->type->type & TYPE_MASK) == TYPE_ARRAY)) {
4728                         if (dest->type->elements == ELEMENT_COUNT_UNSPECIFIED) {
4729                                 dest->type->elements = rval->type->elements;
4730                         }
4731                 }
4732                 if (!equiv_types(dest->type, rval->type)) {
4733                         error(state, 0, "Incompatible types in inializer");
4734                 }
4735                 MISC(dest, 0) = rval;
4736                 insert_triple(state, dest, rval);
4737                 rval->id |= TRIPLE_FLAG_FLATTENED;
4738                 use_triple(MISC(dest, 0), dest);
4739         }
4740         return def;
4741 }
4742
4743 struct type *arithmetic_result(
4744         struct compile_state *state, struct triple *left, struct triple *right)
4745 {
4746         struct type *type;
4747         /* Sanity checks to ensure I am working with arithmetic types */
4748         arithmetic(state, left);
4749         arithmetic(state, right);
4750         type = new_type(
4751                 do_arithmetic_conversion(
4752                         left->type->type, 
4753                         right->type->type), 0, 0);
4754         return type;
4755 }
4756
4757 struct type *ptr_arithmetic_result(
4758         struct compile_state *state, struct triple *left, struct triple *right)
4759 {
4760         struct type *type;
4761         /* Sanity checks to ensure I am working with the proper types */
4762         ptr_arithmetic(state, left);
4763         arithmetic(state, right);
4764         if (TYPE_ARITHMETIC(left->type->type) && 
4765                 TYPE_ARITHMETIC(right->type->type)) {
4766                 type = arithmetic_result(state, left, right);
4767         }
4768         else if (TYPE_PTR(left->type->type)) {
4769                 type = left->type;
4770         }
4771         else {
4772                 internal_error(state, 0, "huh?");
4773                 type = 0;
4774         }
4775         return type;
4776 }
4777
4778
4779 /* boolean helper function */
4780
4781 static struct triple *ltrue_expr(struct compile_state *state, 
4782         struct triple *expr)
4783 {
4784         switch(expr->op) {
4785         case OP_LTRUE:   case OP_LFALSE:  case OP_EQ:      case OP_NOTEQ:
4786         case OP_SLESS:   case OP_ULESS:   case OP_SMORE:   case OP_UMORE:
4787         case OP_SLESSEQ: case OP_ULESSEQ: case OP_SMOREEQ: case OP_UMOREEQ:
4788                 /* If the expression is already boolean do nothing */
4789                 break;
4790         default:
4791                 expr = triple(state, OP_LTRUE, &int_type, expr, 0);
4792                 break;
4793         }
4794         return expr;
4795 }
4796
4797 static struct triple *lfalse_expr(struct compile_state *state, 
4798         struct triple *expr)
4799 {
4800         return triple(state, OP_LFALSE, &int_type, expr, 0);
4801 }
4802
4803 static struct triple *cond_expr(
4804         struct compile_state *state, 
4805         struct triple *test, struct triple *left, struct triple *right)
4806 {
4807         struct triple *def;
4808         struct type *result_type;
4809         unsigned int left_type, right_type;
4810         bool(state, test);
4811         left_type = left->type->type;
4812         right_type = right->type->type;
4813         result_type = 0;
4814         /* Both operands have arithmetic type */
4815         if (TYPE_ARITHMETIC(left_type) && TYPE_ARITHMETIC(right_type)) {
4816                 result_type = arithmetic_result(state, left, right);
4817         }
4818         /* Both operands have void type */
4819         else if (((left_type & TYPE_MASK) == TYPE_VOID) &&
4820                 ((right_type & TYPE_MASK) == TYPE_VOID)) {
4821                 result_type = &void_type;
4822         }
4823         /* pointers to the same type... */
4824         else if ((result_type = compatible_ptrs(left->type, right->type))) {
4825                 ;
4826         }
4827         /* Both operands are pointers and left is a pointer to void */
4828         else if (((left_type & TYPE_MASK) == TYPE_POINTER) &&
4829                 ((right_type & TYPE_MASK) == TYPE_POINTER) &&
4830                 ((left->type->left->type & TYPE_MASK) == TYPE_VOID)) {
4831                 result_type = right->type;
4832         }
4833         /* Both operands are pointers and right is a pointer to void */
4834         else if (((left_type & TYPE_MASK) == TYPE_POINTER) &&
4835                 ((right_type & TYPE_MASK) == TYPE_POINTER) &&
4836                 ((right->type->left->type & TYPE_MASK) == TYPE_VOID)) {
4837                 result_type = left->type;
4838         }
4839         if (!result_type) {
4840                 error(state, 0, "Incompatible types in conditional expression");
4841         }
4842         /* Cleanup and invert the test */
4843         test = lfalse_expr(state, read_expr(state, test));
4844         def = new_triple(state, OP_COND, result_type, 0, 3);
4845         def->param[0] = test;
4846         def->param[1] = left;
4847         def->param[2] = right;
4848         return def;
4849 }
4850
4851
4852 static int expr_depth(struct compile_state *state, struct triple *ins)
4853 {
4854         int count;
4855         count = 0;
4856         if (!ins || (ins->id & TRIPLE_FLAG_FLATTENED)) {
4857                 count = 0;
4858         }
4859         else if (ins->op == OP_DEREF) {
4860                 count = expr_depth(state, RHS(ins, 0)) - 1;
4861         }
4862         else if (ins->op == OP_VAL) {
4863                 count = expr_depth(state, RHS(ins, 0)) - 1;
4864         }
4865         else if (ins->op == OP_COMMA) {
4866                 int ldepth, rdepth;
4867                 ldepth = expr_depth(state, RHS(ins, 0));
4868                 rdepth = expr_depth(state, RHS(ins, 1));
4869                 count = (ldepth >= rdepth)? ldepth : rdepth;
4870         }
4871         else if (ins->op == OP_CALL) {
4872                 /* Don't figure the depth of a call just guess it is huge */
4873                 count = 1000;
4874         }
4875         else {
4876                 struct triple **expr;
4877                 expr = triple_rhs(state, ins, 0);
4878                 for(;expr; expr = triple_rhs(state, ins, expr)) {
4879                         if (*expr) {
4880                                 int depth;
4881                                 depth = expr_depth(state, *expr);
4882                                 if (depth > count) {
4883                                         count = depth;
4884                                 }
4885                         }
4886                 }
4887         }
4888         return count + 1;
4889 }
4890
4891 static struct triple *flatten(
4892         struct compile_state *state, struct triple *first, struct triple *ptr);
4893
4894 static struct triple *flatten_generic(
4895         struct compile_state *state, struct triple *first, struct triple *ptr)
4896 {
4897         struct rhs_vector {
4898                 int depth;
4899                 struct triple **ins;
4900         } vector[MAX_RHS];
4901         int i, rhs, lhs;
4902         /* Only operations with just a rhs should come here */
4903         rhs = TRIPLE_RHS(ptr->sizes);
4904         lhs = TRIPLE_LHS(ptr->sizes);
4905         if (TRIPLE_SIZE(ptr->sizes) != lhs + rhs) {
4906                 internal_error(state, ptr, "unexpected args for: %d %s",
4907                         ptr->op, tops(ptr->op));
4908         }
4909         /* Find the depth of the rhs elements */
4910         for(i = 0; i < rhs; i++) {
4911                 vector[i].ins = &RHS(ptr, i);
4912                 vector[i].depth = expr_depth(state, *vector[i].ins);
4913         }
4914         /* Selection sort the rhs */
4915         for(i = 0; i < rhs; i++) {
4916                 int j, max = i;
4917                 for(j = i + 1; j < rhs; j++ ) {
4918                         if (vector[j].depth > vector[max].depth) {
4919                                 max = j;
4920                         }
4921                 }
4922                 if (max != i) {
4923                         struct rhs_vector tmp;
4924                         tmp = vector[i];
4925                         vector[i] = vector[max];
4926                         vector[max] = tmp;
4927                 }
4928         }
4929         /* Now flatten the rhs elements */
4930         for(i = 0; i < rhs; i++) {
4931                 *vector[i].ins = flatten(state, first, *vector[i].ins);
4932                 use_triple(*vector[i].ins, ptr);
4933         }
4934         
4935         /* Now flatten the lhs elements */
4936         for(i = 0; i < lhs; i++) {
4937                 struct triple **ins = &LHS(ptr, i);
4938                 *ins = flatten(state, first, *ins);
4939                 use_triple(*ins, ptr);
4940         }
4941         return ptr;
4942 }
4943
4944 static struct triple *flatten_land(
4945         struct compile_state *state, struct triple *first, struct triple *ptr)
4946 {
4947         struct triple *left, *right;
4948         struct triple *val, *test, *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         test         = flatten(state, first, 
4961                 lfalse_expr(state, read_expr(state, val)));
4962         jmp          = flatten(state, first, branch(state, end, test));
4963         label1       = flatten(state, first, label(state));
4964         right        = flatten(state, first, write_expr(state, val, right));
4965         TARG(jmp, 0) = flatten(state, first, end); 
4966         
4967         /* Now give the caller something to chew on */
4968         return read_expr(state, val);
4969 }
4970
4971 static struct triple *flatten_lor(
4972         struct compile_state *state, struct triple *first, struct triple *ptr)
4973 {
4974         struct triple *left, *right;
4975         struct triple *val, *jmp, *label1, *end;
4976
4977         /* Find the triples */
4978         left = RHS(ptr, 0);
4979         right = RHS(ptr, 1);
4980
4981         /* Generate the needed triples */
4982         end = label(state);
4983
4984         /* Thread the triples together */
4985         val          = flatten(state, first, variable(state, ptr->type));
4986         left         = flatten(state, first, write_expr(state, val, left));
4987         jmp          = flatten(state, first, branch(state, end, left));
4988         label1       = flatten(state, first, label(state));
4989         right        = flatten(state, first, write_expr(state, val, right));
4990         TARG(jmp, 0) = flatten(state, first, end);
4991        
4992         
4993         /* Now give the caller something to chew on */
4994         return read_expr(state, val);
4995 }
4996
4997 static struct triple *flatten_cond(
4998         struct compile_state *state, struct triple *first, struct triple *ptr)
4999 {
5000         struct triple *test, *left, *right;
5001         struct triple *val, *mv1, *jmp1, *label1, *mv2, *middle, *jmp2, *end;
5002
5003         /* Find the triples */
5004         test = RHS(ptr, 0);
5005         left = RHS(ptr, 1);
5006         right = RHS(ptr, 2);
5007
5008         /* Generate the needed triples */
5009         end = label(state);
5010         middle = label(state);
5011
5012         /* Thread the triples together */
5013         val           = flatten(state, first, variable(state, ptr->type));
5014         test          = flatten(state, first, test);
5015         jmp1          = flatten(state, first, branch(state, middle, test));
5016         label1        = flatten(state, first, label(state));
5017         left          = flatten(state, first, left);
5018         mv1           = flatten(state, first, write_expr(state, val, left));
5019         jmp2          = flatten(state, first, branch(state, end, 0));
5020         TARG(jmp1, 0) = flatten(state, first, middle);
5021         right         = flatten(state, first, right);
5022         mv2           = flatten(state, first, write_expr(state, val, right));
5023         TARG(jmp2, 0) = flatten(state, first, end);
5024         
5025         /* Now give the caller something to chew on */
5026         return read_expr(state, val);
5027 }
5028
5029 struct triple *copy_func(struct compile_state *state, struct triple *ofunc, 
5030         struct occurance *base_occurance)
5031 {
5032         struct triple *nfunc;
5033         struct triple *nfirst, *ofirst;
5034         struct triple *new, *old;
5035
5036 #if 0
5037         fprintf(stdout, "\n");
5038         loc(stdout, state, 0);
5039         fprintf(stdout, "\n__________ copy_func _________\n");
5040         print_triple(state, ofunc);
5041         fprintf(stdout, "__________ copy_func _________ done\n\n");
5042 #endif
5043
5044         /* Make a new copy of the old function */
5045         nfunc = triple(state, OP_LIST, ofunc->type, 0, 0);
5046         nfirst = 0;
5047         ofirst = old = RHS(ofunc, 0);
5048         do {
5049                 struct triple *new;
5050                 struct occurance *occurance;
5051                 int old_lhs, old_rhs;
5052                 old_lhs = TRIPLE_LHS(old->sizes);
5053                 old_rhs = TRIPLE_RHS(old->sizes);
5054                 occurance = inline_occurance(state, base_occurance, old->occurance);
5055                 new = alloc_triple(state, old->op, old->type, old_lhs, old_rhs,
5056                         occurance);
5057                 if (!triple_stores_block(state, new)) {
5058                         memcpy(&new->u, &old->u, sizeof(new->u));
5059                 }
5060                 if (!nfirst) {
5061                         RHS(nfunc, 0) = nfirst = new;
5062                 }
5063                 else {
5064                         insert_triple(state, nfirst, new);
5065                 }
5066                 new->id |= TRIPLE_FLAG_FLATTENED;
5067                 
5068                 /* During the copy remember new as user of old */
5069                 use_triple(old, new);
5070
5071                 /* Populate the return type if present */
5072                 if (old == MISC(ofunc, 0)) {
5073                         MISC(nfunc, 0) = new;
5074                 }
5075                 old = old->next;
5076         } while(old != ofirst);
5077
5078         /* Make a second pass to fix up any unresolved references */
5079         old = ofirst;
5080         new = nfirst;
5081         do {
5082                 struct triple **oexpr, **nexpr;
5083                 int count, i;
5084                 /* Lookup where the copy is, to join pointers */
5085                 count = TRIPLE_SIZE(old->sizes);
5086                 for(i = 0; i < count; i++) {
5087                         oexpr = &old->param[i];
5088                         nexpr = &new->param[i];
5089                         if (!*nexpr && *oexpr && (*oexpr)->use) {
5090                                 *nexpr = (*oexpr)->use->member;
5091                                 if (*nexpr == old) {
5092                                         internal_error(state, 0, "new == old?");
5093                                 }
5094                                 use_triple(*nexpr, new);
5095                         }
5096                         if (!*nexpr && *oexpr) {
5097                                 internal_error(state, 0, "Could not copy %d\n", i);
5098                         }
5099                 }
5100                 old = old->next;
5101                 new = new->next;
5102         } while((old != ofirst) && (new != nfirst));
5103         
5104         /* Make a third pass to cleanup the extra useses */
5105         old = ofirst;
5106         new = nfirst;
5107         do {
5108                 unuse_triple(old, new);
5109                 old = old->next;
5110                 new = new->next;
5111         } while ((old != ofirst) && (new != nfirst));
5112         return nfunc;
5113 }
5114
5115 static struct triple *flatten_call(
5116         struct compile_state *state, struct triple *first, struct triple *ptr)
5117 {
5118         /* Inline the function call */
5119         struct type *ptype;
5120         struct triple *ofunc, *nfunc, *nfirst, *param, *result;
5121         struct triple *end, *nend;
5122         int pvals, i;
5123
5124         /* Find the triples */
5125         ofunc = MISC(ptr, 0);
5126         if (ofunc->op != OP_LIST) {
5127                 internal_error(state, 0, "improper function");
5128         }
5129         nfunc = copy_func(state, ofunc, ptr->occurance);
5130         nfirst = RHS(nfunc, 0)->next;
5131         /* Prepend the parameter reading into the new function list */
5132         ptype = nfunc->type->right;
5133         param = RHS(nfunc, 0)->next;
5134         pvals = TRIPLE_RHS(ptr->sizes);
5135         for(i = 0; i < pvals; i++) {
5136                 struct type *atype;
5137                 struct triple *arg;
5138                 atype = ptype;
5139                 if ((ptype->type & TYPE_MASK) == TYPE_PRODUCT) {
5140                         atype = ptype->left;
5141                 }
5142                 while((param->type->type & TYPE_MASK) != (atype->type & TYPE_MASK)) {
5143                         param = param->next;
5144                 }
5145                 arg = RHS(ptr, i);
5146                 flatten(state, nfirst, write_expr(state, param, arg));
5147                 ptype = ptype->right;
5148                 param = param->next;
5149         }
5150         result = 0;
5151         if ((nfunc->type->left->type & TYPE_MASK) != TYPE_VOID) {
5152                 result = read_expr(state, MISC(nfunc,0));
5153         }
5154 #if 0
5155         fprintf(stdout, "\n");
5156         loc(stdout, state, 0);
5157         fprintf(stdout, "\n__________ flatten_call _________\n");
5158         print_triple(state, nfunc);
5159         fprintf(stdout, "__________ flatten_call _________ done\n\n");
5160 #endif
5161
5162         /* Get rid of the extra triples */
5163         nfirst = RHS(nfunc, 0)->next;
5164         free_triple(state, RHS(nfunc, 0));
5165         RHS(nfunc, 0) = 0;
5166         free_triple(state, nfunc);
5167
5168         /* Append the new function list onto the return list */
5169         end = first->prev;
5170         nend = nfirst->prev;
5171         end->next    = nfirst;
5172         nfirst->prev = end;
5173         nend->next   = first;
5174         first->prev  = nend;
5175
5176         return result;
5177 }
5178
5179 static struct triple *flatten(
5180         struct compile_state *state, struct triple *first, struct triple *ptr)
5181 {
5182         struct triple *orig_ptr;
5183         if (!ptr)
5184                 return 0;
5185         do {
5186                 orig_ptr = ptr;
5187                 /* Only flatten triples once */
5188                 if (ptr->id & TRIPLE_FLAG_FLATTENED) {
5189                         return ptr;
5190                 }
5191                 switch(ptr->op) {
5192                 case OP_COMMA:
5193                         RHS(ptr, 0) = flatten(state, first, RHS(ptr, 0));
5194                         ptr = RHS(ptr, 1);
5195                         break;
5196                 case OP_VAL:
5197                         RHS(ptr, 0) = flatten(state, first, RHS(ptr, 0));
5198                         return MISC(ptr, 0);
5199                         break;
5200                 case OP_LAND:
5201                         ptr = flatten_land(state, first, ptr);
5202                         break;
5203                 case OP_LOR:
5204                         ptr = flatten_lor(state, first, ptr);
5205                         break;
5206                 case OP_COND:
5207                         ptr = flatten_cond(state, first, ptr);
5208                         break;
5209                 case OP_CALL:
5210                         ptr = flatten_call(state, first, ptr);
5211                         break;
5212                 case OP_READ:
5213                 case OP_LOAD:
5214                         RHS(ptr, 0) = flatten(state, first, RHS(ptr, 0));
5215                         use_triple(RHS(ptr, 0), ptr);
5216                         break;
5217                 case OP_BRANCH:
5218                         use_triple(TARG(ptr, 0), ptr);
5219                         if (TRIPLE_RHS(ptr->sizes)) {
5220                                 use_triple(RHS(ptr, 0), ptr);
5221                                 if (ptr->next != ptr) {
5222                                         use_triple(ptr->next, ptr);
5223                                 }
5224                         }
5225                         break;
5226                 case OP_BLOBCONST:
5227                         insert_triple(state, first, ptr);
5228                         ptr->id |= TRIPLE_FLAG_FLATTENED;
5229                         ptr = triple(state, OP_SDECL, ptr->type, ptr, 0);
5230                         use_triple(MISC(ptr, 0), ptr);
5231                         break;
5232                 case OP_DEREF:
5233                         /* Since OP_DEREF is just a marker delete it when I flatten it */
5234                         ptr = RHS(ptr, 0);
5235                         RHS(orig_ptr, 0) = 0;
5236                         free_triple(state, orig_ptr);
5237                         break;
5238                 case OP_DOT:
5239                 {
5240                         struct triple *base;
5241                         base = RHS(ptr, 0);
5242                         if (base->op == OP_DEREF) {
5243                                 struct triple *left;
5244                                 ulong_t offset;
5245                                 offset = field_offset(state, base->type, ptr->u.field);
5246                                 left = RHS(base, 0);
5247                                 ptr = triple(state, OP_ADD, left->type, 
5248                                         read_expr(state, left),
5249                                         int_const(state, &ulong_type, offset));
5250                                 free_triple(state, base);
5251                         }
5252                         else if (base->op == OP_VAL_VEC) {
5253                                 base = flatten(state, first, base);
5254                                 ptr = struct_field(state, base, ptr->u.field);
5255                         }
5256                         break;
5257                 }
5258                 case OP_PIECE:
5259                         MISC(ptr, 0) = flatten(state, first, MISC(ptr, 0));
5260                         use_triple(MISC(ptr, 0), ptr);
5261                         use_triple(ptr, MISC(ptr, 0));
5262                         break;
5263                 case OP_ADDRCONST:
5264                 case OP_SDECL:
5265                         MISC(ptr, 0) = flatten(state, first, MISC(ptr, 0));
5266                         use_triple(MISC(ptr, 0), ptr);
5267                         break;
5268                 case OP_ADECL:
5269                         break;
5270                 default:
5271                         /* Flatten the easy cases we don't override */
5272                         ptr = flatten_generic(state, first, ptr);
5273                         break;
5274                 }
5275         } while(ptr && (ptr != orig_ptr));
5276         if (ptr) {
5277                 insert_triple(state, first, ptr);
5278                 ptr->id |= TRIPLE_FLAG_FLATTENED;
5279         }
5280         return ptr;
5281 }
5282
5283 static void release_expr(struct compile_state *state, struct triple *expr)
5284 {
5285         struct triple *head;
5286         head = label(state);
5287         flatten(state, head, expr);
5288         while(head->next != head) {
5289                 release_triple(state, head->next);
5290         }
5291         free_triple(state, head);
5292 }
5293
5294 static int replace_rhs_use(struct compile_state *state,
5295         struct triple *orig, struct triple *new, struct triple *use)
5296 {
5297         struct triple **expr;
5298         int found;
5299         found = 0;
5300         expr = triple_rhs(state, use, 0);
5301         for(;expr; expr = triple_rhs(state, use, expr)) {
5302                 if (*expr == orig) {
5303                         *expr = new;
5304                         found = 1;
5305                 }
5306         }
5307         if (found) {
5308                 unuse_triple(orig, use);
5309                 use_triple(new, use);
5310         }
5311         return found;
5312 }
5313
5314 static int replace_lhs_use(struct compile_state *state,
5315         struct triple *orig, struct triple *new, struct triple *use)
5316 {
5317         struct triple **expr;
5318         int found;
5319         found = 0;
5320         expr = triple_lhs(state, use, 0);
5321         for(;expr; expr = triple_lhs(state, use, expr)) {
5322                 if (*expr == orig) {
5323                         *expr = new;
5324                         found = 1;
5325                 }
5326         }
5327         if (found) {
5328                 unuse_triple(orig, use);
5329                 use_triple(new, use);
5330         }
5331         return found;
5332 }
5333
5334 static void propogate_use(struct compile_state *state,
5335         struct triple *orig, struct triple *new)
5336 {
5337         struct triple_set *user, *next;
5338         for(user = orig->use; user; user = next) {
5339                 struct triple *use;
5340                 int found;
5341                 next = user->next;
5342                 use = user->member;
5343                 found = 0;
5344                 found |= replace_rhs_use(state, orig, new, use);
5345                 found |= replace_lhs_use(state, orig, new, use);
5346                 if (!found) {
5347                         internal_error(state, use, "use without use");
5348                 }
5349         }
5350         if (orig->use) {
5351                 internal_error(state, orig, "used after propogate_use");
5352         }
5353 }
5354
5355 /*
5356  * Code generators
5357  * ===========================
5358  */
5359
5360 static struct triple *mk_add_expr(
5361         struct compile_state *state, struct triple *left, struct triple *right)
5362 {
5363         struct type *result_type;
5364         /* Put pointer operands on the left */
5365         if (is_pointer(right)) {
5366                 struct triple *tmp;
5367                 tmp = left;
5368                 left = right;
5369                 right = tmp;
5370         }
5371         left  = read_expr(state, left);
5372         right = read_expr(state, right);
5373         result_type = ptr_arithmetic_result(state, left, right);
5374         if (is_pointer(left)) {
5375                 right = triple(state, 
5376                         is_signed(right->type)? OP_SMUL : OP_UMUL, 
5377                         &ulong_type, 
5378                         right, 
5379                         int_const(state, &ulong_type, 
5380                                 size_of(state, left->type->left)));
5381         }
5382         return triple(state, OP_ADD, result_type, left, right);
5383 }
5384
5385 static struct triple *mk_sub_expr(
5386         struct compile_state *state, struct triple *left, struct triple *right)
5387 {
5388         struct type *result_type;
5389         result_type = ptr_arithmetic_result(state, left, right);
5390         left  = read_expr(state, left);
5391         right = read_expr(state, right);
5392         if (is_pointer(left)) {
5393                 right = triple(state, 
5394                         is_signed(right->type)? OP_SMUL : OP_UMUL, 
5395                         &ulong_type, 
5396                         right, 
5397                         int_const(state, &ulong_type, 
5398                                 size_of(state, left->type->left)));
5399         }
5400         return triple(state, OP_SUB, result_type, left, right);
5401 }
5402
5403 static struct triple *mk_pre_inc_expr(
5404         struct compile_state *state, struct triple *def)
5405 {
5406         struct triple *val;
5407         lvalue(state, def);
5408         val = mk_add_expr(state, def, int_const(state, &int_type, 1));
5409         return triple(state, OP_VAL, def->type,
5410                 write_expr(state, def, val),
5411                 val);
5412 }
5413
5414 static struct triple *mk_pre_dec_expr(
5415         struct compile_state *state, struct triple *def)
5416 {
5417         struct triple *val;
5418         lvalue(state, def);
5419         val = mk_sub_expr(state, def, int_const(state, &int_type, 1));
5420         return triple(state, OP_VAL, def->type,
5421                 write_expr(state, def, val),
5422                 val);
5423 }
5424
5425 static struct triple *mk_post_inc_expr(
5426         struct compile_state *state, struct triple *def)
5427 {
5428         struct triple *val;
5429         lvalue(state, def);
5430         val = read_expr(state, def);
5431         return triple(state, OP_VAL, def->type,
5432                 write_expr(state, def,
5433                         mk_add_expr(state, val, int_const(state, &int_type, 1)))
5434                 , val);
5435 }
5436
5437 static struct triple *mk_post_dec_expr(
5438         struct compile_state *state, struct triple *def)
5439 {
5440         struct triple *val;
5441         lvalue(state, def);
5442         val = read_expr(state, def);
5443         return triple(state, OP_VAL, def->type, 
5444                 write_expr(state, def,
5445                         mk_sub_expr(state, val, int_const(state, &int_type, 1)))
5446                 , val);
5447 }
5448
5449 static struct triple *mk_subscript_expr(
5450         struct compile_state *state, struct triple *left, struct triple *right)
5451 {
5452         left  = read_expr(state, left);
5453         right = read_expr(state, right);
5454         if (!is_pointer(left) && !is_pointer(right)) {
5455                 error(state, left, "subscripted value is not a pointer");
5456         }
5457         return mk_deref_expr(state, mk_add_expr(state, left, right));
5458 }
5459
5460 static struct triple *mk_cast_expr(
5461         struct compile_state *state, struct type *type, struct triple *expr)
5462 {
5463         struct triple *def;
5464         def = read_expr(state, expr);
5465         def = triple(state, OP_COPY, type, def, 0);
5466         return def;
5467 }
5468
5469 /*
5470  * Compile time evaluation
5471  * ===========================
5472  */
5473 static int is_const(struct triple *ins)
5474 {
5475         return IS_CONST_OP(ins->op);
5476 }
5477
5478 static int constants_equal(struct compile_state *state, 
5479         struct triple *left, struct triple *right)
5480 {
5481         int equal;
5482         if (!is_const(left) || !is_const(right)) {
5483                 equal = 0;
5484         }
5485         else if (left->op != right->op) {
5486                 equal = 0;
5487         }
5488         else if (!equiv_types(left->type, right->type)) {
5489                 equal = 0;
5490         }
5491         else {
5492                 equal = 0;
5493                 switch(left->op) {
5494                 case OP_INTCONST:
5495                         if (left->u.cval == right->u.cval) {
5496                                 equal = 1;
5497                         }
5498                         break;
5499                 case OP_BLOBCONST:
5500                 {
5501                         size_t lsize, rsize;
5502                         lsize = size_of(state, left->type);
5503                         rsize = size_of(state, right->type);
5504                         if (lsize != rsize) {
5505                                 break;
5506                         }
5507                         if (memcmp(left->u.blob, right->u.blob, lsize) == 0) {
5508                                 equal = 1;
5509                         }
5510                         break;
5511                 }
5512                 case OP_ADDRCONST:
5513                         if ((MISC(left, 0) == MISC(right, 0)) &&
5514                                 (left->u.cval == right->u.cval)) {
5515                                 equal = 1;
5516                         }
5517                         break;
5518                 default:
5519                         internal_error(state, left, "uknown constant type");
5520                         break;
5521                 }
5522         }
5523         return equal;
5524 }
5525
5526 static int is_zero(struct triple *ins)
5527 {
5528         return is_const(ins) && (ins->u.cval == 0);
5529 }
5530
5531 static int is_one(struct triple *ins)
5532 {
5533         return is_const(ins) && (ins->u.cval == 1);
5534 }
5535
5536 static long_t bit_count(ulong_t value)
5537 {
5538         int count;
5539         int i;
5540         count = 0;
5541         for(i = (sizeof(ulong_t)*8) -1; i >= 0; i--) {
5542                 ulong_t mask;
5543                 mask = 1;
5544                 mask <<= i;
5545                 if (value & mask) {
5546                         count++;
5547                 }
5548         }
5549         return count;
5550         
5551 }
5552 static long_t bsr(ulong_t value)
5553 {
5554         int i;
5555         for(i = (sizeof(ulong_t)*8) -1; i >= 0; i--) {
5556                 ulong_t mask;
5557                 mask = 1;
5558                 mask <<= i;
5559                 if (value & mask) {
5560                         return i;
5561                 }
5562         }
5563         return -1;
5564 }
5565
5566 static long_t bsf(ulong_t value)
5567 {
5568         int i;
5569         for(i = 0; i < (sizeof(ulong_t)*8); i++) {
5570                 ulong_t mask;
5571                 mask = 1;
5572                 mask <<= 1;
5573                 if (value & mask) {
5574                         return i;
5575                 }
5576         }
5577         return -1;
5578 }
5579
5580 static long_t log2(ulong_t value)
5581 {
5582         return bsr(value);
5583 }
5584
5585 static long_t tlog2(struct triple *ins)
5586 {
5587         return log2(ins->u.cval);
5588 }
5589
5590 static int is_pow2(struct triple *ins)
5591 {
5592         ulong_t value, mask;
5593         long_t log;
5594         if (!is_const(ins)) {
5595                 return 0;
5596         }
5597         value = ins->u.cval;
5598         log = log2(value);
5599         if (log == -1) {
5600                 return 0;
5601         }
5602         mask = 1;
5603         mask <<= log;
5604         return  ((value & mask) == value);
5605 }
5606
5607 static ulong_t read_const(struct compile_state *state,
5608         struct triple *ins, struct triple **expr)
5609 {
5610         struct triple *rhs;
5611         rhs = *expr;
5612         switch(rhs->type->type &TYPE_MASK) {
5613         case TYPE_CHAR:   
5614         case TYPE_SHORT:
5615         case TYPE_INT:
5616         case TYPE_LONG:
5617         case TYPE_UCHAR:   
5618         case TYPE_USHORT:  
5619         case TYPE_UINT:
5620         case TYPE_ULONG:
5621         case TYPE_POINTER:
5622                 break;
5623         default:
5624                 internal_error(state, rhs, "bad type to read_const\n");
5625                 break;
5626         }
5627         return rhs->u.cval;
5628 }
5629
5630 static long_t read_sconst(struct triple *ins, struct triple **expr)
5631 {
5632         struct triple *rhs;
5633         rhs = *expr;
5634         return (long_t)(rhs->u.cval);
5635 }
5636
5637 static void unuse_rhs(struct compile_state *state, struct triple *ins)
5638 {
5639         struct triple **expr;
5640         expr = triple_rhs(state, ins, 0);
5641         for(;expr;expr = triple_rhs(state, ins, expr)) {
5642                 if (*expr) {
5643                         unuse_triple(*expr, ins);
5644                         *expr = 0;
5645                 }
5646         }
5647 }
5648
5649 static void unuse_lhs(struct compile_state *state, struct triple *ins)
5650 {
5651         struct triple **expr;
5652         expr = triple_lhs(state, ins, 0);
5653         for(;expr;expr = triple_lhs(state, ins, expr)) {
5654                 unuse_triple(*expr, ins);
5655                 *expr = 0;
5656         }
5657 }
5658
5659 static void check_lhs(struct compile_state *state, struct triple *ins)
5660 {
5661         struct triple **expr;
5662         expr = triple_lhs(state, ins, 0);
5663         for(;expr;expr = triple_lhs(state, ins, expr)) {
5664                 internal_error(state, ins, "unexpected lhs");
5665         }
5666         
5667 }
5668 static void check_targ(struct compile_state *state, struct triple *ins)
5669 {
5670         struct triple **expr;
5671         expr = triple_targ(state, ins, 0);
5672         for(;expr;expr = triple_targ(state, ins, expr)) {
5673                 internal_error(state, ins, "unexpected targ");
5674         }
5675 }
5676
5677 static void wipe_ins(struct compile_state *state, struct triple *ins)
5678 {
5679         /* Becareful which instructions you replace the wiped
5680          * instruction with, as there are not enough slots
5681          * in all instructions to hold all others.
5682          */
5683         check_targ(state, ins);
5684         unuse_rhs(state, ins);
5685         unuse_lhs(state, ins);
5686 }
5687
5688 static void mkcopy(struct compile_state *state, 
5689         struct triple *ins, struct triple *rhs)
5690 {
5691         wipe_ins(state, ins);
5692         ins->op = OP_COPY;
5693         ins->sizes = TRIPLE_SIZES(0, 1, 0, 0);
5694         RHS(ins, 0) = rhs;
5695         use_triple(RHS(ins, 0), ins);
5696 }
5697
5698 static void mkconst(struct compile_state *state, 
5699         struct triple *ins, ulong_t value)
5700 {
5701         if (!is_integral(ins) && !is_pointer(ins)) {
5702                 internal_error(state, ins, "unknown type to make constant\n");
5703         }
5704         wipe_ins(state, ins);
5705         ins->op = OP_INTCONST;
5706         ins->sizes = TRIPLE_SIZES(0, 0, 0, 0);
5707         ins->u.cval = value;
5708 }
5709
5710 static void mkaddr_const(struct compile_state *state,
5711         struct triple *ins, struct triple *sdecl, ulong_t value)
5712 {
5713         if (sdecl->op != OP_SDECL) {
5714                 internal_error(state, ins, "bad base for addrconst");
5715         }
5716         wipe_ins(state, ins);
5717         ins->op = OP_ADDRCONST;
5718         ins->sizes = TRIPLE_SIZES(0, 0, 1, 0);
5719         MISC(ins, 0) = sdecl;
5720         ins->u.cval = value;
5721         use_triple(sdecl, ins);
5722 }
5723
5724 /* Transform multicomponent variables into simple register variables */
5725 static void flatten_structures(struct compile_state *state)
5726 {
5727         struct triple *ins, *first;
5728         first = RHS(state->main_function, 0);
5729         ins = first;
5730         /* Pass one expand structure values into valvecs.
5731          */
5732         ins = first;
5733         do {
5734                 struct triple *next;
5735                 next = ins->next;
5736                 if ((ins->type->type & TYPE_MASK) == TYPE_STRUCT) {
5737                         if (ins->op == OP_VAL_VEC) {
5738                                 /* Do nothing */
5739                         }
5740                         else if ((ins->op == OP_LOAD) || (ins->op == OP_READ)) {
5741                                 struct triple *def, **vector;
5742                                 struct type *tptr;
5743                                 int op;
5744                                 ulong_t i;
5745
5746                                 op = ins->op;
5747                                 def = RHS(ins, 0);
5748                                 get_occurance(ins->occurance);
5749                                 next = alloc_triple(state, OP_VAL_VEC, ins->type, -1, -1,
5750                                         ins->occurance);
5751
5752                                 vector = &RHS(next, 0);
5753                                 tptr = next->type->left;
5754                                 for(i = 0; i < next->type->elements; i++) {
5755                                         struct triple *sfield;
5756                                         struct type *mtype;
5757                                         mtype = tptr;
5758                                         if ((mtype->type & TYPE_MASK) == TYPE_PRODUCT) {
5759                                                 mtype = mtype->left;
5760                                         }
5761                                         sfield = deref_field(state, def, mtype->field_ident);
5762                                         
5763                                         vector[i] = triple(
5764                                                 state, op, mtype, sfield, 0);
5765                                         put_occurance(vector[i]->occurance);
5766                                         get_occurance(next->occurance);
5767                                         vector[i]->occurance = next->occurance;
5768                                         tptr = tptr->right;
5769                                 }
5770                                 propogate_use(state, ins, next);
5771                                 flatten(state, ins, next);
5772                                 free_triple(state, ins);
5773                         }
5774                         else if ((ins->op == OP_STORE) || (ins->op == OP_WRITE)) {
5775                                 struct triple *src, *dst, **vector;
5776                                 struct type *tptr;
5777                                 int op;
5778                                 ulong_t i;
5779
5780                                 op = ins->op;
5781                                 src = RHS(ins, 1);
5782                                 dst = RHS(ins, 0);
5783                                 get_occurance(ins->occurance);
5784                                 next = alloc_triple(state, OP_VAL_VEC, ins->type, -1, -1,
5785                                         ins->occurance);
5786                                 
5787                                 vector = &RHS(next, 0);
5788                                 tptr = next->type->left;
5789                                 for(i = 0; i < ins->type->elements; i++) {
5790                                         struct triple *dfield, *sfield;
5791                                         struct type *mtype;
5792                                         mtype = tptr;
5793                                         if ((mtype->type & TYPE_MASK) == TYPE_PRODUCT) {
5794                                                 mtype = mtype->left;
5795                                         }
5796                                         sfield = deref_field(state, src, mtype->field_ident);
5797                                         dfield = deref_field(state, dst, mtype->field_ident);
5798                                         vector[i] = triple(
5799                                                 state, op, mtype, dfield, sfield);
5800                                         put_occurance(vector[i]->occurance);
5801                                         get_occurance(next->occurance);
5802                                         vector[i]->occurance = next->occurance;
5803                                         tptr = tptr->right;
5804                                 }
5805                                 propogate_use(state, ins, next);
5806                                 flatten(state, ins, next);
5807                                 free_triple(state, ins);
5808                         }
5809                 }
5810                 ins = next;
5811         } while(ins != first);
5812         /* Pass two flatten the valvecs.
5813          */
5814         ins = first;
5815         do {
5816                 struct triple *next;
5817                 next = ins->next;
5818                 if (ins->op == OP_VAL_VEC) {
5819                         release_triple(state, ins);
5820                 } 
5821                 ins = next;
5822         } while(ins != first);
5823         /* Pass three verify the state and set ->id to 0.
5824          */
5825         ins = first;
5826         do {
5827                 ins->id &= ~TRIPLE_FLAG_FLATTENED;
5828                 if ((ins->op != OP_BLOBCONST) && (ins->op != OP_SDECL) &&
5829                         ((ins->type->type & TYPE_MASK) == TYPE_STRUCT)) {
5830                         internal_error(state, ins, "STRUCT_TYPE remains?");
5831                 }
5832                 if (ins->op == OP_DOT) {
5833                         internal_error(state, ins, "OP_DOT remains?");
5834                 }
5835                 if (ins->op == OP_VAL_VEC) {
5836                         internal_error(state, ins, "OP_VAL_VEC remains?");
5837                 }
5838                 ins = ins->next;
5839         } while(ins != first);
5840 }
5841
5842 /* For those operations that cannot be simplified */
5843 static void simplify_noop(struct compile_state *state, struct triple *ins)
5844 {
5845         return;
5846 }
5847
5848 static void simplify_smul(struct compile_state *state, struct triple *ins)
5849 {
5850         if (is_const(RHS(ins, 0)) && !is_const(RHS(ins, 1))) {
5851                 struct triple *tmp;
5852                 tmp = RHS(ins, 0);
5853                 RHS(ins, 0) = RHS(ins, 1);
5854                 RHS(ins, 1) = tmp;
5855         }
5856         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
5857                 long_t left, right;
5858                 left  = read_sconst(ins, &RHS(ins, 0));
5859                 right = read_sconst(ins, &RHS(ins, 1));
5860                 mkconst(state, ins, left * right);
5861         }
5862         else if (is_zero(RHS(ins, 1))) {
5863                 mkconst(state, ins, 0);
5864         }
5865         else if (is_one(RHS(ins, 1))) {
5866                 mkcopy(state, ins, RHS(ins, 0));
5867         }
5868         else if (is_pow2(RHS(ins, 1))) {
5869                 struct triple *val;
5870                 val = int_const(state, ins->type, tlog2(RHS(ins, 1)));
5871                 ins->op = OP_SL;
5872                 insert_triple(state, ins, val);
5873                 unuse_triple(RHS(ins, 1), ins);
5874                 use_triple(val, ins);
5875                 RHS(ins, 1) = val;
5876         }
5877 }
5878
5879 static void simplify_umul(struct compile_state *state, struct triple *ins)
5880 {
5881         if (is_const(RHS(ins, 0)) && !is_const(RHS(ins, 1))) {
5882                 struct triple *tmp;
5883                 tmp = RHS(ins, 0);
5884                 RHS(ins, 0) = RHS(ins, 1);
5885                 RHS(ins, 1) = tmp;
5886         }
5887         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
5888                 ulong_t left, right;
5889                 left  = read_const(state, ins, &RHS(ins, 0));
5890                 right = read_const(state, ins, &RHS(ins, 1));
5891                 mkconst(state, ins, left * right);
5892         }
5893         else if (is_zero(RHS(ins, 1))) {
5894                 mkconst(state, ins, 0);
5895         }
5896         else if (is_one(RHS(ins, 1))) {
5897                 mkcopy(state, ins, RHS(ins, 0));
5898         }
5899         else if (is_pow2(RHS(ins, 1))) {
5900                 struct triple *val;
5901                 val = int_const(state, ins->type, tlog2(RHS(ins, 1)));
5902                 ins->op = OP_SL;
5903                 insert_triple(state, ins, val);
5904                 unuse_triple(RHS(ins, 1), ins);
5905                 use_triple(val, ins);
5906                 RHS(ins, 1) = val;
5907         }
5908 }
5909
5910 static void simplify_sdiv(struct compile_state *state, struct triple *ins)
5911 {
5912         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
5913                 long_t left, right;
5914                 left  = read_sconst(ins, &RHS(ins, 0));
5915                 right = read_sconst(ins, &RHS(ins, 1));
5916                 mkconst(state, ins, left / right);
5917         }
5918         else if (is_zero(RHS(ins, 0))) {
5919                 mkconst(state, ins, 0);
5920         }
5921         else if (is_zero(RHS(ins, 1))) {
5922                 error(state, ins, "division by zero");
5923         }
5924         else if (is_one(RHS(ins, 1))) {
5925                 mkcopy(state, ins, RHS(ins, 0));
5926         }
5927         else if (is_pow2(RHS(ins, 1))) {
5928                 struct triple *val;
5929                 val = int_const(state, ins->type, tlog2(RHS(ins, 1)));
5930                 ins->op = OP_SSR;
5931                 insert_triple(state, ins, val);
5932                 unuse_triple(RHS(ins, 1), ins);
5933                 use_triple(val, ins);
5934                 RHS(ins, 1) = val;
5935         }
5936 }
5937
5938 static void simplify_udiv(struct compile_state *state, struct triple *ins)
5939 {
5940         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
5941                 ulong_t left, right;
5942                 left  = read_const(state, ins, &RHS(ins, 0));
5943                 right = read_const(state, ins, &RHS(ins, 1));
5944                 mkconst(state, ins, left / right);
5945         }
5946         else if (is_zero(RHS(ins, 0))) {
5947                 mkconst(state, ins, 0);
5948         }
5949         else if (is_zero(RHS(ins, 1))) {
5950                 error(state, ins, "division by zero");
5951         }
5952         else if (is_one(RHS(ins, 1))) {
5953                 mkcopy(state, ins, RHS(ins, 0));
5954         }
5955         else if (is_pow2(RHS(ins, 1))) {
5956                 struct triple *val;
5957                 val = int_const(state, ins->type, tlog2(RHS(ins, 1)));
5958                 ins->op = OP_USR;
5959                 insert_triple(state, ins, val);
5960                 unuse_triple(RHS(ins, 1), ins);
5961                 use_triple(val, ins);
5962                 RHS(ins, 1) = val;
5963         }
5964 }
5965
5966 static void simplify_smod(struct compile_state *state, struct triple *ins)
5967 {
5968         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
5969                 long_t left, right;
5970                 left  = read_const(state, ins, &RHS(ins, 0));
5971                 right = read_const(state, ins, &RHS(ins, 1));
5972                 mkconst(state, ins, left % right);
5973         }
5974         else if (is_zero(RHS(ins, 0))) {
5975                 mkconst(state, ins, 0);
5976         }
5977         else if (is_zero(RHS(ins, 1))) {
5978                 error(state, ins, "division by zero");
5979         }
5980         else if (is_one(RHS(ins, 1))) {
5981                 mkconst(state, ins, 0);
5982         }
5983         else if (is_pow2(RHS(ins, 1))) {
5984                 struct triple *val;
5985                 val = int_const(state, ins->type, RHS(ins, 1)->u.cval - 1);
5986                 ins->op = OP_AND;
5987                 insert_triple(state, ins, val);
5988                 unuse_triple(RHS(ins, 1), ins);
5989                 use_triple(val, ins);
5990                 RHS(ins, 1) = val;
5991         }
5992 }
5993 static void simplify_umod(struct compile_state *state, struct triple *ins)
5994 {
5995         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
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 (is_zero(RHS(ins, 0))) {
6002                 mkconst(state, ins, 0);
6003         }
6004         else if (is_zero(RHS(ins, 1))) {
6005                 error(state, ins, "division by zero");
6006         }
6007         else if (is_one(RHS(ins, 1))) {
6008                 mkconst(state, ins, 0);
6009         }
6010         else if (is_pow2(RHS(ins, 1))) {
6011                 struct triple *val;
6012                 val = int_const(state, ins->type, RHS(ins, 1)->u.cval - 1);
6013                 ins->op = OP_AND;
6014                 insert_triple(state, ins, val);
6015                 unuse_triple(RHS(ins, 1), ins);
6016                 use_triple(val, ins);
6017                 RHS(ins, 1) = val;
6018         }
6019 }
6020
6021 static void simplify_add(struct compile_state *state, struct triple *ins)
6022 {
6023         /* start with the pointer on the left */
6024         if (is_pointer(RHS(ins, 1))) {
6025                 struct triple *tmp;
6026                 tmp = RHS(ins, 0);
6027                 RHS(ins, 0) = RHS(ins, 1);
6028                 RHS(ins, 1) = tmp;
6029         }
6030         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6031                 if (RHS(ins, 0)->op == OP_INTCONST) {
6032                         ulong_t left, right;
6033                         left  = read_const(state, ins, &RHS(ins, 0));
6034                         right = read_const(state, ins, &RHS(ins, 1));
6035                         mkconst(state, ins, left + right);
6036                 }
6037                 else if (RHS(ins, 0)->op == OP_ADDRCONST) {
6038                         struct triple *sdecl;
6039                         ulong_t left, right;
6040                         sdecl = MISC(RHS(ins, 0), 0);
6041                         left  = RHS(ins, 0)->u.cval;
6042                         right = RHS(ins, 1)->u.cval;
6043                         mkaddr_const(state, ins, sdecl, left + right);
6044                 }
6045                 else {
6046                         internal_warning(state, ins, "Optimize me!");
6047                 }
6048         }
6049         else if (is_const(RHS(ins, 0)) && !is_const(RHS(ins, 1))) {
6050                 struct triple *tmp;
6051                 tmp = RHS(ins, 1);
6052                 RHS(ins, 1) = RHS(ins, 0);
6053                 RHS(ins, 0) = tmp;
6054         }
6055 }
6056
6057 static void simplify_sub(struct compile_state *state, struct triple *ins)
6058 {
6059         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6060                 if (RHS(ins, 0)->op == OP_INTCONST) {
6061                         ulong_t left, right;
6062                         left  = read_const(state, ins, &RHS(ins, 0));
6063                         right = read_const(state, ins, &RHS(ins, 1));
6064                         mkconst(state, ins, left - right);
6065                 }
6066                 else if (RHS(ins, 0)->op == OP_ADDRCONST) {
6067                         struct triple *sdecl;
6068                         ulong_t left, right;
6069                         sdecl = MISC(RHS(ins, 0), 0);
6070                         left  = RHS(ins, 0)->u.cval;
6071                         right = RHS(ins, 1)->u.cval;
6072                         mkaddr_const(state, ins, sdecl, left - right);
6073                 }
6074                 else {
6075                         internal_warning(state, ins, "Optimize me!");
6076                 }
6077         }
6078 }
6079
6080 static void simplify_sl(struct compile_state *state, struct triple *ins)
6081 {
6082         if (is_const(RHS(ins, 1))) {
6083                 ulong_t right;
6084                 right = read_const(state, ins, &RHS(ins, 1));
6085                 if (right >= (size_of(state, ins->type)*8)) {
6086                         warning(state, ins, "left shift count >= width of type");
6087                 }
6088         }
6089         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6090                 ulong_t left, right;
6091                 left  = read_const(state, ins, &RHS(ins, 0));
6092                 right = read_const(state, ins, &RHS(ins, 1));
6093                 mkconst(state, ins,  left << right);
6094         }
6095 }
6096
6097 static void simplify_usr(struct compile_state *state, struct triple *ins)
6098 {
6099         if (is_const(RHS(ins, 1))) {
6100                 ulong_t right;
6101                 right = read_const(state, ins, &RHS(ins, 1));
6102                 if (right >= (size_of(state, ins->type)*8)) {
6103                         warning(state, ins, "right shift count >= width of type");
6104                 }
6105         }
6106         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6107                 ulong_t left, right;
6108                 left  = read_const(state, ins, &RHS(ins, 0));
6109                 right = read_const(state, ins, &RHS(ins, 1));
6110                 mkconst(state, ins, left >> right);
6111         }
6112 }
6113
6114 static void simplify_ssr(struct compile_state *state, struct triple *ins)
6115 {
6116         if (is_const(RHS(ins, 1))) {
6117                 ulong_t right;
6118                 right = read_const(state, ins, &RHS(ins, 1));
6119                 if (right >= (size_of(state, ins->type)*8)) {
6120                         warning(state, ins, "right shift count >= width of type");
6121                 }
6122         }
6123         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6124                 long_t left, right;
6125                 left  = read_sconst(ins, &RHS(ins, 0));
6126                 right = read_sconst(ins, &RHS(ins, 1));
6127                 mkconst(state, ins, left >> right);
6128         }
6129 }
6130
6131 static void simplify_and(struct compile_state *state, struct triple *ins)
6132 {
6133         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6134                 ulong_t left, right;
6135                 left  = read_const(state, ins, &RHS(ins, 0));
6136                 right = read_const(state, ins, &RHS(ins, 1));
6137                 mkconst(state, ins, left & right);
6138         }
6139 }
6140
6141 static void simplify_or(struct compile_state *state, struct triple *ins)
6142 {
6143         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6144                 ulong_t left, right;
6145                 left  = read_const(state, ins, &RHS(ins, 0));
6146                 right = read_const(state, ins, &RHS(ins, 1));
6147                 mkconst(state, ins, left | right);
6148         }
6149 }
6150
6151 static void simplify_xor(struct compile_state *state, struct triple *ins)
6152 {
6153         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6154                 ulong_t left, right;
6155                 left  = read_const(state, ins, &RHS(ins, 0));
6156                 right = read_const(state, ins, &RHS(ins, 1));
6157                 mkconst(state, ins, left ^ right);
6158         }
6159 }
6160
6161 static void simplify_pos(struct compile_state *state, struct triple *ins)
6162 {
6163         if (is_const(RHS(ins, 0))) {
6164                 mkconst(state, ins, RHS(ins, 0)->u.cval);
6165         }
6166         else {
6167                 mkcopy(state, ins, RHS(ins, 0));
6168         }
6169 }
6170
6171 static void simplify_neg(struct compile_state *state, struct triple *ins)
6172 {
6173         if (is_const(RHS(ins, 0))) {
6174                 ulong_t left;
6175                 left = read_const(state, ins, &RHS(ins, 0));
6176                 mkconst(state, ins, -left);
6177         }
6178         else if (RHS(ins, 0)->op == OP_NEG) {
6179                 mkcopy(state, ins, RHS(RHS(ins, 0), 0));
6180         }
6181 }
6182
6183 static void simplify_invert(struct compile_state *state, struct triple *ins)
6184 {
6185         if (is_const(RHS(ins, 0))) {
6186                 ulong_t left;
6187                 left = read_const(state, ins, &RHS(ins, 0));
6188                 mkconst(state, ins, ~left);
6189         }
6190 }
6191
6192 static void simplify_eq(struct compile_state *state, struct triple *ins)
6193 {
6194         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6195                 ulong_t left, right;
6196                 left  = read_const(state, ins, &RHS(ins, 0));
6197                 right = read_const(state, ins, &RHS(ins, 1));
6198                 mkconst(state, ins, left == right);
6199         }
6200         else if (RHS(ins, 0) == RHS(ins, 1)) {
6201                 mkconst(state, ins, 1);
6202         }
6203 }
6204
6205 static void simplify_noteq(struct compile_state *state, struct triple *ins)
6206 {
6207         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6208                 ulong_t left, right;
6209                 left  = read_const(state, ins, &RHS(ins, 0));
6210                 right = read_const(state, ins, &RHS(ins, 1));
6211                 mkconst(state, ins, left != right);
6212         }
6213         else if (RHS(ins, 0) == RHS(ins, 1)) {
6214                 mkconst(state, ins, 0);
6215         }
6216 }
6217
6218 static void simplify_sless(struct compile_state *state, struct triple *ins)
6219 {
6220         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6221                 long_t left, right;
6222                 left  = read_sconst(ins, &RHS(ins, 0));
6223                 right = read_sconst(ins, &RHS(ins, 1));
6224                 mkconst(state, ins, left < right);
6225         }
6226         else if (RHS(ins, 0) == RHS(ins, 1)) {
6227                 mkconst(state, ins, 0);
6228         }
6229 }
6230
6231 static void simplify_uless(struct compile_state *state, struct triple *ins)
6232 {
6233         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6234                 ulong_t left, right;
6235                 left  = read_const(state, ins, &RHS(ins, 0));
6236                 right = read_const(state, ins, &RHS(ins, 1));
6237                 mkconst(state, ins, left < right);
6238         }
6239         else if (is_zero(RHS(ins, 0))) {
6240                 mkconst(state, ins, 1);
6241         }
6242         else if (RHS(ins, 0) == RHS(ins, 1)) {
6243                 mkconst(state, ins, 0);
6244         }
6245 }
6246
6247 static void simplify_smore(struct compile_state *state, struct triple *ins)
6248 {
6249         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6250                 long_t left, right;
6251                 left  = read_sconst(ins, &RHS(ins, 0));
6252                 right = read_sconst(ins, &RHS(ins, 1));
6253                 mkconst(state, ins, left > right);
6254         }
6255         else if (RHS(ins, 0) == RHS(ins, 1)) {
6256                 mkconst(state, ins, 0);
6257         }
6258 }
6259
6260 static void simplify_umore(struct compile_state *state, struct triple *ins)
6261 {
6262         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6263                 ulong_t left, right;
6264                 left  = read_const(state, ins, &RHS(ins, 0));
6265                 right = read_const(state, ins, &RHS(ins, 1));
6266                 mkconst(state, ins, left > right);
6267         }
6268         else if (is_zero(RHS(ins, 1))) {
6269                 mkconst(state, ins, 1);
6270         }
6271         else if (RHS(ins, 0) == RHS(ins, 1)) {
6272                 mkconst(state, ins, 0);
6273         }
6274 }
6275
6276
6277 static void simplify_slesseq(struct compile_state *state, struct triple *ins)
6278 {
6279         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6280                 long_t left, right;
6281                 left  = read_sconst(ins, &RHS(ins, 0));
6282                 right = read_sconst(ins, &RHS(ins, 1));
6283                 mkconst(state, ins, left <= right);
6284         }
6285         else if (RHS(ins, 0) == RHS(ins, 1)) {
6286                 mkconst(state, ins, 1);
6287         }
6288 }
6289
6290 static void simplify_ulesseq(struct compile_state *state, struct triple *ins)
6291 {
6292         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6293                 ulong_t left, right;
6294                 left  = read_const(state, ins, &RHS(ins, 0));
6295                 right = read_const(state, ins, &RHS(ins, 1));
6296                 mkconst(state, ins, left <= right);
6297         }
6298         else if (is_zero(RHS(ins, 0))) {
6299                 mkconst(state, ins, 1);
6300         }
6301         else if (RHS(ins, 0) == RHS(ins, 1)) {
6302                 mkconst(state, ins, 1);
6303         }
6304 }
6305
6306 static void simplify_smoreeq(struct compile_state *state, struct triple *ins)
6307 {
6308         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 0))) {
6309                 long_t left, right;
6310                 left  = read_sconst(ins, &RHS(ins, 0));
6311                 right = read_sconst(ins, &RHS(ins, 1));
6312                 mkconst(state, ins, left >= right);
6313         }
6314         else if (RHS(ins, 0) == RHS(ins, 1)) {
6315                 mkconst(state, ins, 1);
6316         }
6317 }
6318
6319 static void simplify_umoreeq(struct compile_state *state, struct triple *ins)
6320 {
6321         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
6322                 ulong_t left, right;
6323                 left  = read_const(state, ins, &RHS(ins, 0));
6324                 right = read_const(state, ins, &RHS(ins, 1));
6325                 mkconst(state, ins, left >= right);
6326         }
6327         else if (is_zero(RHS(ins, 1))) {
6328                 mkconst(state, ins, 1);
6329         }
6330         else if (RHS(ins, 0) == RHS(ins, 1)) {
6331                 mkconst(state, ins, 1);
6332         }
6333 }
6334
6335 static void simplify_lfalse(struct compile_state *state, struct triple *ins)
6336 {
6337         if (is_const(RHS(ins, 0))) {
6338                 ulong_t left;
6339                 left = read_const(state, ins, &RHS(ins, 0));
6340                 mkconst(state, ins, left == 0);
6341         }
6342         /* Otherwise if I am the only user... */
6343         else if ((RHS(ins, 0)->use->member == ins) && (RHS(ins, 0)->use->next == 0)) {
6344                 int need_copy = 1;
6345                 /* Invert a boolean operation */
6346                 switch(RHS(ins, 0)->op) {
6347                 case OP_LTRUE:   RHS(ins, 0)->op = OP_LFALSE;  break;
6348                 case OP_LFALSE:  RHS(ins, 0)->op = OP_LTRUE;   break;
6349                 case OP_EQ:      RHS(ins, 0)->op = OP_NOTEQ;   break;
6350                 case OP_NOTEQ:   RHS(ins, 0)->op = OP_EQ;      break;
6351                 case OP_SLESS:   RHS(ins, 0)->op = OP_SMOREEQ; break;
6352                 case OP_ULESS:   RHS(ins, 0)->op = OP_UMOREEQ; break;
6353                 case OP_SMORE:   RHS(ins, 0)->op = OP_SLESSEQ; break;
6354                 case OP_UMORE:   RHS(ins, 0)->op = OP_ULESSEQ; break;
6355                 case OP_SLESSEQ: RHS(ins, 0)->op = OP_SMORE;   break;
6356                 case OP_ULESSEQ: RHS(ins, 0)->op = OP_UMORE;   break;
6357                 case OP_SMOREEQ: RHS(ins, 0)->op = OP_SLESS;   break;
6358                 case OP_UMOREEQ: RHS(ins, 0)->op = OP_ULESS;   break;
6359                 default:
6360                         need_copy = 0;
6361                         break;
6362                 }
6363                 if (need_copy) {
6364                         mkcopy(state, ins, RHS(ins, 0));
6365                 }
6366         }
6367 }
6368
6369 static void simplify_ltrue (struct compile_state *state, struct triple *ins)
6370 {
6371         if (is_const(RHS(ins, 0))) {
6372                 ulong_t left;
6373                 left = read_const(state, ins, &RHS(ins, 0));
6374                 mkconst(state, ins, left != 0);
6375         }
6376         else switch(RHS(ins, 0)->op) {
6377         case OP_LTRUE:   case OP_LFALSE:  case OP_EQ:      case OP_NOTEQ:
6378         case OP_SLESS:   case OP_ULESS:   case OP_SMORE:   case OP_UMORE:
6379         case OP_SLESSEQ: case OP_ULESSEQ: case OP_SMOREEQ: case OP_UMOREEQ:
6380                 mkcopy(state, ins, RHS(ins, 0));
6381         }
6382
6383 }
6384
6385 static void simplify_copy(struct compile_state *state, struct triple *ins)
6386 {
6387         if (is_const(RHS(ins, 0))) {
6388                 switch(RHS(ins, 0)->op) {
6389                 case OP_INTCONST:
6390                 {
6391                         ulong_t left;
6392                         left = read_const(state, ins, &RHS(ins, 0));
6393                         mkconst(state, ins, left);
6394                         break;
6395                 }
6396                 case OP_ADDRCONST:
6397                 {
6398                         struct triple *sdecl;
6399                         ulong_t offset;
6400                         sdecl  = MISC(RHS(ins, 0), 0);
6401                         offset = RHS(ins, 0)->u.cval;
6402                         mkaddr_const(state, ins, sdecl, offset);
6403                         break;
6404                 }
6405                 default:
6406                         internal_error(state, ins, "uknown constant");
6407                         break;
6408                 }
6409         }
6410 }
6411
6412 static void simplify_branch(struct compile_state *state, struct triple *ins)
6413 {
6414         struct block *block;
6415         if (ins->op != OP_BRANCH) {
6416                 internal_error(state, ins, "not branch");
6417         }
6418         if (ins->use != 0) {
6419                 internal_error(state, ins, "branch use");
6420         }
6421 #warning "FIXME implement simplify branch."
6422         /* The challenge here with simplify branch is that I need to 
6423          * make modifications to the control flow graph as well
6424          * as to the branch instruction itself.
6425          */
6426         block = ins->u.block;
6427         
6428         if (TRIPLE_RHS(ins->sizes) && is_const(RHS(ins, 0))) {
6429                 struct triple *targ;
6430                 ulong_t value;
6431                 value = read_const(state, ins, &RHS(ins, 0));
6432                 unuse_triple(RHS(ins, 0), ins);
6433                 targ = TARG(ins, 0);
6434                 ins->sizes = TRIPLE_SIZES(0, 0, 0, 1);
6435                 if (value) {
6436                         unuse_triple(ins->next, ins);
6437                         TARG(ins, 0) = targ;
6438                 }
6439                 else {
6440                         unuse_triple(targ, ins);
6441                         TARG(ins, 0) = ins->next;
6442                 }
6443 #warning "FIXME handle the case of making a branch unconditional"
6444         }
6445         if (TARG(ins, 0) == ins->next) {
6446                 unuse_triple(ins->next, ins);
6447                 if (TRIPLE_RHS(ins->sizes)) {
6448                         unuse_triple(RHS(ins, 0), ins);
6449                         unuse_triple(ins->next, ins);
6450                 }
6451                 ins->sizes = TRIPLE_SIZES(0, 0, 0, 0);
6452                 ins->op = OP_NOOP;
6453                 if (ins->use) {
6454                         internal_error(state, ins, "noop use != 0");
6455                 }
6456 #warning "FIXME handle the case of killing a branch"
6457         }
6458 }
6459
6460 int phi_present(struct block *block)
6461 {
6462         struct triple *ptr;
6463         if (!block) {
6464                 return 0;
6465         }
6466         ptr = block->first;
6467         do {
6468                 if (ptr->op == OP_PHI) {
6469                         return 1;
6470                 }
6471                 ptr = ptr->next;
6472         } while(ptr != block->last);
6473         return 0;
6474 }
6475
6476 static void simplify_label(struct compile_state *state, struct triple *ins)
6477 {
6478 #warning "FIXME enable simplify_label"
6479         struct triple *first, *last;
6480         first = RHS(state->main_function, 0);
6481         last = first->prev;
6482         /* Ignore the first and last instructions */
6483         if ((ins == first) || (ins == last)) {
6484                 return;
6485         }
6486         if (ins->use == 0) {
6487                 ins->op = OP_NOOP;
6488         }
6489         else if (ins->prev->op == OP_LABEL) {
6490                 struct block *block;
6491                 block = ins->prev->u.block;
6492                 /* In general it is not safe to merge one label that
6493                  * imediately follows another.  The problem is that the empty
6494                  * looking block may have phi functions that depend on it.
6495                  */
6496                 if (!block || 
6497                         (!phi_present(block->left) && 
6498                         !phi_present(block->right))) 
6499                 {
6500                         struct triple_set *user, *next;
6501                         ins->op = OP_NOOP;
6502                         for(user = ins->use; user; user = next) {
6503                                 struct triple *use;
6504                                 next = user->next;
6505                                 use = user->member;
6506                                 if (TARG(use, 0) == ins) {
6507                                         TARG(use, 0) = ins->prev;
6508                                         unuse_triple(ins, use);
6509                                         use_triple(ins->prev, use);
6510                                 }
6511                         }
6512                         if (ins->use) {
6513                                 internal_error(state, ins, "noop use != 0");
6514                         }
6515                 }
6516         }
6517 }
6518
6519 static void simplify_phi(struct compile_state *state, struct triple *ins)
6520 {
6521         struct triple **expr;
6522         ulong_t value;
6523         expr = triple_rhs(state, ins, 0);
6524         if (!*expr || !is_const(*expr)) {
6525                 return;
6526         }
6527         value = read_const(state, ins, expr);
6528         for(;expr;expr = triple_rhs(state, ins, expr)) {
6529                 if (!*expr || !is_const(*expr)) {
6530                         return;
6531                 }
6532                 if (value != read_const(state, ins, expr)) {
6533                         return;
6534                 }
6535         }
6536         mkconst(state, ins, value);
6537 }
6538
6539
6540 static void simplify_bsf(struct compile_state *state, struct triple *ins)
6541 {
6542         if (is_const(RHS(ins, 0))) {
6543                 ulong_t left;
6544                 left = read_const(state, ins, &RHS(ins, 0));
6545                 mkconst(state, ins, bsf(left));
6546         }
6547 }
6548
6549 static void simplify_bsr(struct compile_state *state, struct triple *ins)
6550 {
6551         if (is_const(RHS(ins, 0))) {
6552                 ulong_t left;
6553                 left = read_const(state, ins, &RHS(ins, 0));
6554                 mkconst(state, ins, bsr(left));
6555         }
6556 }
6557
6558
6559 typedef void (*simplify_t)(struct compile_state *state, struct triple *ins);
6560 static const simplify_t table_simplify[] = {
6561 #if 1
6562 #define simplify_sdivt    simplify_noop
6563 #define simplify_udivt    simplify_noop
6564 #endif
6565 #if 0
6566 #define simplify_smul     simplify_noop
6567 #define simplify_umul     simplify_noop
6568 #define simplify_sdiv     simplify_noop
6569 #define simplify_udiv     simplify_noop
6570 #define simplify_smod     simplify_noop
6571 #define simplify_umod     simplify_noop
6572 #endif
6573 #if 0
6574 #define simplify_add      simplify_noop
6575 #define simplify_sub      simplify_noop
6576 #endif
6577 #if 0
6578 #define simplify_sl       simplify_noop
6579 #define simplify_usr      simplify_noop
6580 #define simplify_ssr      simplify_noop
6581 #endif
6582 #if 0
6583 #define simplify_and      simplify_noop
6584 #define simplify_xor      simplify_noop
6585 #define simplify_or       simplify_noop
6586 #endif
6587 #if 0
6588 #define simplify_pos      simplify_noop
6589 #define simplify_neg      simplify_noop
6590 #define simplify_invert   simplify_noop
6591 #endif
6592
6593 #if 0
6594 #define simplify_eq       simplify_noop
6595 #define simplify_noteq    simplify_noop
6596 #endif
6597 #if 0
6598 #define simplify_sless    simplify_noop
6599 #define simplify_uless    simplify_noop
6600 #define simplify_smore    simplify_noop
6601 #define simplify_umore    simplify_noop
6602 #endif
6603 #if 0
6604 #define simplify_slesseq  simplify_noop
6605 #define simplify_ulesseq  simplify_noop
6606 #define simplify_smoreeq  simplify_noop
6607 #define simplify_umoreeq  simplify_noop
6608 #endif
6609 #if 0
6610 #define simplify_lfalse   simplify_noop
6611 #endif
6612 #if 0
6613 #define simplify_ltrue    simplify_noop
6614 #endif
6615
6616 #if 0
6617 #define simplify_copy     simplify_noop
6618 #endif
6619
6620 #if 0
6621 #define simplify_branch   simplify_noop
6622 #endif
6623 #if 1
6624 #define simplify_label    simplify_noop
6625 #endif
6626
6627 #if 0
6628 #define simplify_phi      simplify_noop
6629 #endif
6630
6631 #if 0
6632 #define simplify_bsf      simplify_noop
6633 #define simplify_bsr      simplify_noop
6634 #endif
6635
6636 [OP_SDIVT      ] = simplify_sdivt,
6637 [OP_UDIVT      ] = simplify_udivt,
6638 [OP_SMUL       ] = simplify_smul,
6639 [OP_UMUL       ] = simplify_umul,
6640 [OP_SDIV       ] = simplify_sdiv,
6641 [OP_UDIV       ] = simplify_udiv,
6642 [OP_SMOD       ] = simplify_smod,
6643 [OP_UMOD       ] = simplify_umod,
6644 [OP_ADD        ] = simplify_add,
6645 [OP_SUB        ] = simplify_sub,
6646 [OP_SL         ] = simplify_sl,
6647 [OP_USR        ] = simplify_usr,
6648 [OP_SSR        ] = simplify_ssr,
6649 [OP_AND        ] = simplify_and,
6650 [OP_XOR        ] = simplify_xor,
6651 [OP_OR         ] = simplify_or,
6652 [OP_POS        ] = simplify_pos,
6653 [OP_NEG        ] = simplify_neg,
6654 [OP_INVERT     ] = simplify_invert,
6655
6656 [OP_EQ         ] = simplify_eq,
6657 [OP_NOTEQ      ] = simplify_noteq,
6658 [OP_SLESS      ] = simplify_sless,
6659 [OP_ULESS      ] = simplify_uless,
6660 [OP_SMORE      ] = simplify_smore,
6661 [OP_UMORE      ] = simplify_umore,
6662 [OP_SLESSEQ    ] = simplify_slesseq,
6663 [OP_ULESSEQ    ] = simplify_ulesseq,
6664 [OP_SMOREEQ    ] = simplify_smoreeq,
6665 [OP_UMOREEQ    ] = simplify_umoreeq,
6666 [OP_LFALSE     ] = simplify_lfalse,
6667 [OP_LTRUE      ] = simplify_ltrue,
6668
6669 [OP_LOAD       ] = simplify_noop,
6670 [OP_STORE      ] = simplify_noop,
6671
6672 [OP_NOOP       ] = simplify_noop,
6673
6674 [OP_INTCONST   ] = simplify_noop,
6675 [OP_BLOBCONST  ] = simplify_noop,
6676 [OP_ADDRCONST  ] = simplify_noop,
6677
6678 [OP_WRITE      ] = simplify_noop,
6679 [OP_READ       ] = simplify_noop,
6680 [OP_COPY       ] = simplify_copy,
6681 [OP_PIECE      ] = simplify_noop,
6682 [OP_ASM        ] = simplify_noop,
6683
6684 [OP_DOT        ] = simplify_noop,
6685 [OP_VAL_VEC    ] = simplify_noop,
6686
6687 [OP_LIST       ] = simplify_noop,
6688 [OP_BRANCH     ] = simplify_branch,
6689 [OP_LABEL      ] = simplify_label,
6690 [OP_ADECL      ] = simplify_noop,
6691 [OP_SDECL      ] = simplify_noop,
6692 [OP_PHI        ] = simplify_phi,
6693
6694 [OP_INB        ] = simplify_noop,
6695 [OP_INW        ] = simplify_noop,
6696 [OP_INL        ] = simplify_noop,
6697 [OP_OUTB       ] = simplify_noop,
6698 [OP_OUTW       ] = simplify_noop,
6699 [OP_OUTL       ] = simplify_noop,
6700 [OP_BSF        ] = simplify_bsf,
6701 [OP_BSR        ] = simplify_bsr,
6702 [OP_RDMSR      ] = simplify_noop,
6703 [OP_WRMSR      ] = simplify_noop,                    
6704 [OP_HLT        ] = simplify_noop,
6705 };
6706
6707 static void simplify(struct compile_state *state, struct triple *ins)
6708 {
6709         int op;
6710         simplify_t do_simplify;
6711         do {
6712                 op = ins->op;
6713                 do_simplify = 0;
6714                 if ((op < 0) || (op > sizeof(table_simplify)/sizeof(table_simplify[0]))) {
6715                         do_simplify = 0;
6716                 }
6717                 else {
6718                         do_simplify = table_simplify[op];
6719                 }
6720                 if (!do_simplify) {
6721                         internal_error(state, ins, "cannot simplify op: %d %s\n",
6722                                 op, tops(op));
6723                         return;
6724                 }
6725                 do_simplify(state, ins);
6726         } while(ins->op != op);
6727 }
6728
6729 static void simplify_all(struct compile_state *state)
6730 {
6731         struct triple *ins, *first;
6732         first = RHS(state->main_function, 0);
6733         ins = first;
6734         do {
6735                 simplify(state, ins);
6736                 ins = ins->next;
6737         }while(ins != first);
6738 }
6739
6740 /*
6741  * Builtins....
6742  * ============================
6743  */
6744
6745 static void register_builtin_function(struct compile_state *state,
6746         const char *name, int op, struct type *rtype, ...)
6747 {
6748         struct type *ftype, *atype, *param, **next;
6749         struct triple *def, *arg, *result, *work, *last, *first;
6750         struct hash_entry *ident;
6751         struct file_state file;
6752         int parameters;
6753         int name_len;
6754         va_list args;
6755         int i;
6756
6757         /* Dummy file state to get debug handling right */
6758         memset(&file, 0, sizeof(file));
6759         file.basename = "<built-in>";
6760         file.line = 1;
6761         file.report_line = 1;
6762         file.report_name = file.basename;
6763         file.prev = state->file;
6764         state->file = &file;
6765         state->function = name;
6766
6767         /* Find the Parameter count */
6768         valid_op(state, op);
6769         parameters = table_ops[op].rhs;
6770         if (parameters < 0 ) {
6771                 internal_error(state, 0, "Invalid builtin parameter count");
6772         }
6773
6774         /* Find the function type */
6775         ftype = new_type(TYPE_FUNCTION, rtype, 0);
6776         next = &ftype->right;
6777         va_start(args, rtype);
6778         for(i = 0; i < parameters; i++) {
6779                 atype = va_arg(args, struct type *);
6780                 if (!*next) {
6781                         *next = atype;
6782                 } else {
6783                         *next = new_type(TYPE_PRODUCT, *next, atype);
6784                         next = &((*next)->right);
6785                 }
6786         }
6787         if (!*next) {
6788                 *next = &void_type;
6789         }
6790         va_end(args);
6791
6792         /* Generate the needed triples */
6793         def = triple(state, OP_LIST, ftype, 0, 0);
6794         first = label(state);
6795         RHS(def, 0) = first;
6796
6797         /* Now string them together */
6798         param = ftype->right;
6799         for(i = 0; i < parameters; i++) {
6800                 if ((param->type & TYPE_MASK) == TYPE_PRODUCT) {
6801                         atype = param->left;
6802                 } else {
6803                         atype = param;
6804                 }
6805                 arg = flatten(state, first, variable(state, atype));
6806                 param = param->right;
6807         }
6808         result = 0;
6809         if ((rtype->type & TYPE_MASK) != TYPE_VOID) {
6810                 result = flatten(state, first, variable(state, rtype));
6811         }
6812         MISC(def, 0) = result;
6813         work = new_triple(state, op, rtype, -1, parameters);
6814         for(i = 0, arg = first->next; i < parameters; i++, arg = arg->next) {
6815                 RHS(work, i) = read_expr(state, arg);
6816         }
6817         if (result && ((rtype->type & TYPE_MASK) == TYPE_STRUCT)) {
6818                 struct triple *val;
6819                 /* Populate the LHS with the target registers */
6820                 work = flatten(state, first, work);
6821                 work->type = &void_type;
6822                 param = rtype->left;
6823                 if (rtype->elements != TRIPLE_LHS(work->sizes)) {
6824                         internal_error(state, 0, "Invalid result type");
6825                 }
6826                 val = new_triple(state, OP_VAL_VEC, rtype, -1, -1);
6827                 for(i = 0; i < rtype->elements; i++) {
6828                         struct triple *piece;
6829                         atype = param;
6830                         if ((param->type & TYPE_MASK) == TYPE_PRODUCT) {
6831                                 atype = param->left;
6832                         }
6833                         if (!TYPE_ARITHMETIC(atype->type) &&
6834                                 !TYPE_PTR(atype->type)) {
6835                                 internal_error(state, 0, "Invalid lhs type");
6836                         }
6837                         piece = triple(state, OP_PIECE, atype, work, 0);
6838                         piece->u.cval = i;
6839                         LHS(work, i) = piece;
6840                         RHS(val, i) = piece;
6841                 }
6842                 work = val;
6843         }
6844         if (result) {
6845                 work = write_expr(state, result, work);
6846         }
6847         work = flatten(state, first, work);
6848         last = flatten(state, first, label(state));
6849         name_len = strlen(name);
6850         ident = lookup(state, name, name_len);
6851         symbol(state, ident, &ident->sym_ident, def, ftype);
6852         
6853         state->file = file.prev;
6854         state->function = 0;
6855 #if 0
6856         fprintf(stdout, "\n");
6857         loc(stdout, state, 0);
6858         fprintf(stdout, "\n__________ builtin_function _________\n");
6859         print_triple(state, def);
6860         fprintf(stdout, "__________ builtin_function _________ done\n\n");
6861 #endif
6862 }
6863
6864 static struct type *partial_struct(struct compile_state *state,
6865         const char *field_name, struct type *type, struct type *rest)
6866 {
6867         struct hash_entry *field_ident;
6868         struct type *result;
6869         int field_name_len;
6870
6871         field_name_len = strlen(field_name);
6872         field_ident = lookup(state, field_name, field_name_len);
6873
6874         result = clone_type(0, type);
6875         result->field_ident = field_ident;
6876
6877         if (rest) {
6878                 result = new_type(TYPE_PRODUCT, result, rest);
6879         }
6880         return result;
6881 }
6882
6883 static struct type *register_builtin_type(struct compile_state *state,
6884         const char *name, struct type *type)
6885 {
6886         struct hash_entry *ident;
6887         int name_len;
6888
6889         name_len = strlen(name);
6890         ident = lookup(state, name, name_len);
6891         
6892         if ((type->type & TYPE_MASK) == TYPE_PRODUCT) {
6893                 ulong_t elements = 0;
6894                 struct type *field;
6895                 type = new_type(TYPE_STRUCT, type, 0);
6896                 field = type->left;
6897                 while((field->type & TYPE_MASK) == TYPE_PRODUCT) {
6898                         elements++;
6899                         field = field->right;
6900                 }
6901                 elements++;
6902                 symbol(state, ident, &ident->sym_struct, 0, type);
6903                 type->type_ident = ident;
6904                 type->elements = elements;
6905         }
6906         symbol(state, ident, &ident->sym_ident, 0, type);
6907         ident->tok = TOK_TYPE_NAME;
6908         return type;
6909 }
6910
6911
6912 static void register_builtins(struct compile_state *state)
6913 {
6914         struct type *div_type, *ldiv_type;
6915         struct type *udiv_type, *uldiv_type;
6916         struct type *msr_type;
6917
6918         div_type = register_builtin_type(state, "__builtin_div_t",
6919                 partial_struct(state, "quot", &int_type,
6920                 partial_struct(state, "rem",  &int_type, 0)));
6921         ldiv_type = register_builtin_type(state, "__builtin_ldiv_t",
6922                 partial_struct(state, "quot", &long_type,
6923                 partial_struct(state, "rem",  &long_type, 0)));
6924         udiv_type = register_builtin_type(state, "__builtin_udiv_t",
6925                 partial_struct(state, "quot", &uint_type,
6926                 partial_struct(state, "rem",  &uint_type, 0)));
6927         uldiv_type = register_builtin_type(state, "__builtin_uldiv_t",
6928                 partial_struct(state, "quot", &ulong_type,
6929                 partial_struct(state, "rem",  &ulong_type, 0)));
6930
6931         register_builtin_function(state, "__builtin_div",   OP_SDIVT, div_type,
6932                 &int_type, &int_type);
6933         register_builtin_function(state, "__builtin_ldiv",  OP_SDIVT, ldiv_type,
6934                 &long_type, &long_type);
6935         register_builtin_function(state, "__builtin_udiv",  OP_UDIVT, udiv_type,
6936                 &uint_type, &uint_type);
6937         register_builtin_function(state, "__builtin_uldiv", OP_UDIVT, uldiv_type,
6938                 &ulong_type, &ulong_type);
6939
6940         register_builtin_function(state, "__builtin_inb", OP_INB, &uchar_type, 
6941                 &ushort_type);
6942         register_builtin_function(state, "__builtin_inw", OP_INW, &ushort_type,
6943                 &ushort_type);
6944         register_builtin_function(state, "__builtin_inl", OP_INL, &uint_type,   
6945                 &ushort_type);
6946
6947         register_builtin_function(state, "__builtin_outb", OP_OUTB, &void_type, 
6948                 &uchar_type, &ushort_type);
6949         register_builtin_function(state, "__builtin_outw", OP_OUTW, &void_type, 
6950                 &ushort_type, &ushort_type);
6951         register_builtin_function(state, "__builtin_outl", OP_OUTL, &void_type, 
6952                 &uint_type, &ushort_type);
6953         
6954         register_builtin_function(state, "__builtin_bsf", OP_BSF, &int_type, 
6955                 &int_type);
6956         register_builtin_function(state, "__builtin_bsr", OP_BSR, &int_type, 
6957                 &int_type);
6958
6959         msr_type = register_builtin_type(state, "__builtin_msr_t",
6960                 partial_struct(state, "lo", &ulong_type,
6961                 partial_struct(state, "hi", &ulong_type, 0)));
6962
6963         register_builtin_function(state, "__builtin_rdmsr", OP_RDMSR, msr_type,
6964                 &ulong_type);
6965         register_builtin_function(state, "__builtin_wrmsr", OP_WRMSR, &void_type,
6966                 &ulong_type, &ulong_type, &ulong_type);
6967         
6968         register_builtin_function(state, "__builtin_hlt", OP_HLT, &void_type, 
6969                 &void_type);
6970 }
6971
6972 static struct type *declarator(
6973         struct compile_state *state, struct type *type, 
6974         struct hash_entry **ident, int need_ident);
6975 static void decl(struct compile_state *state, struct triple *first);
6976 static struct type *specifier_qualifier_list(struct compile_state *state);
6977 static int isdecl_specifier(int tok);
6978 static struct type *decl_specifiers(struct compile_state *state);
6979 static int istype(int tok);
6980 static struct triple *expr(struct compile_state *state);
6981 static struct triple *assignment_expr(struct compile_state *state);
6982 static struct type *type_name(struct compile_state *state);
6983 static void statement(struct compile_state *state, struct triple *fist);
6984
6985 static struct triple *call_expr(
6986         struct compile_state *state, struct triple *func)
6987 {
6988         struct triple *def;
6989         struct type *param, *type;
6990         ulong_t pvals, index;
6991
6992         if ((func->type->type & TYPE_MASK) != TYPE_FUNCTION) {
6993                 error(state, 0, "Called object is not a function");
6994         }
6995         if (func->op != OP_LIST) {
6996                 internal_error(state, 0, "improper function");
6997         }
6998         eat(state, TOK_LPAREN);
6999         /* Find the return type without any specifiers */
7000         type = clone_type(0, func->type->left);
7001         def = new_triple(state, OP_CALL, func->type, -1, -1);
7002         def->type = type;
7003
7004         pvals = TRIPLE_RHS(def->sizes);
7005         MISC(def, 0) = func;
7006
7007         param = func->type->right;
7008         for(index = 0; index < pvals; index++) {
7009                 struct triple *val;
7010                 struct type *arg_type;
7011                 val = read_expr(state, assignment_expr(state));
7012                 arg_type = param;
7013                 if ((param->type & TYPE_MASK) == TYPE_PRODUCT) {
7014                         arg_type = param->left;
7015                 }
7016                 write_compatible(state, arg_type, val->type);
7017                 RHS(def, index) = val;
7018                 if (index != (pvals - 1)) {
7019                         eat(state, TOK_COMMA);
7020                         param = param->right;
7021                 }
7022         }
7023         eat(state, TOK_RPAREN);
7024         return def;
7025 }
7026
7027
7028 static struct triple *character_constant(struct compile_state *state)
7029 {
7030         struct triple *def;
7031         struct token *tk;
7032         const signed char *str, *end;
7033         int c;
7034         int str_len;
7035         eat(state, TOK_LIT_CHAR);
7036         tk = &state->token[0];
7037         str = tk->val.str + 1;
7038         str_len = tk->str_len - 2;
7039         if (str_len <= 0) {
7040                 error(state, 0, "empty character constant");
7041         }
7042         end = str + str_len;
7043         c = char_value(state, &str, end);
7044         if (str != end) {
7045                 error(state, 0, "multibyte character constant not supported");
7046         }
7047         def = int_const(state, &char_type, (ulong_t)((long_t)c));
7048         return def;
7049 }
7050
7051 static struct triple *string_constant(struct compile_state *state)
7052 {
7053         struct triple *def;
7054         struct token *tk;
7055         struct type *type;
7056         const signed char *str, *end;
7057         signed char *buf, *ptr;
7058         int str_len;
7059
7060         buf = 0;
7061         type = new_type(TYPE_ARRAY, &char_type, 0);
7062         type->elements = 0;
7063         /* The while loop handles string concatenation */
7064         do {
7065                 eat(state, TOK_LIT_STRING);
7066                 tk = &state->token[0];
7067                 str = tk->val.str + 1;
7068                 str_len = tk->str_len - 2;
7069                 if (str_len < 0) {
7070                         error(state, 0, "negative string constant length");
7071                 }
7072                 end = str + str_len;
7073                 ptr = buf;
7074                 buf = xmalloc(type->elements + str_len + 1, "string_constant");
7075                 memcpy(buf, ptr, type->elements);
7076                 ptr = buf + type->elements;
7077                 do {
7078                         *ptr++ = char_value(state, &str, end);
7079                 } while(str < end);
7080                 type->elements = ptr - buf;
7081         } while(peek(state) == TOK_LIT_STRING);
7082         *ptr = '\0';
7083         type->elements += 1;
7084         def = triple(state, OP_BLOBCONST, type, 0, 0);
7085         def->u.blob = buf;
7086         return def;
7087 }
7088
7089
7090 static struct triple *integer_constant(struct compile_state *state)
7091 {
7092         struct triple *def;
7093         unsigned long val;
7094         struct token *tk;
7095         char *end;
7096         int u, l, decimal;
7097         struct type *type;
7098
7099         eat(state, TOK_LIT_INT);
7100         tk = &state->token[0];
7101         errno = 0;
7102         decimal = (tk->val.str[0] != '0');
7103         val = strtoul(tk->val.str, &end, 0);
7104         if ((val == ULONG_MAX) && (errno == ERANGE)) {
7105                 error(state, 0, "Integer constant to large");
7106         }
7107         u = l = 0;
7108         if ((*end == 'u') || (*end == 'U')) {
7109                 u = 1;
7110                         end++;
7111         }
7112         if ((*end == 'l') || (*end == 'L')) {
7113                 l = 1;
7114                 end++;
7115         }
7116         if ((*end == 'u') || (*end == 'U')) {
7117                 u = 1;
7118                 end++;
7119         }
7120         if (*end) {
7121                 error(state, 0, "Junk at end of integer constant");
7122         }
7123         if (u && l)  {
7124                 type = &ulong_type;
7125         }
7126         else if (l) {
7127                 type = &long_type;
7128                 if (!decimal && (val > LONG_MAX)) {
7129                         type = &ulong_type;
7130                 }
7131         }
7132         else if (u) {
7133                 type = &uint_type;
7134                 if (val > UINT_MAX) {
7135                         type = &ulong_type;
7136                 }
7137         }
7138         else {
7139                 type = &int_type;
7140                 if (!decimal && (val > INT_MAX) && (val <= UINT_MAX)) {
7141                         type = &uint_type;
7142                 }
7143                 else if (!decimal && (val > LONG_MAX)) {
7144                         type = &ulong_type;
7145                 }
7146                 else if (val > INT_MAX) {
7147                         type = &long_type;
7148                 }
7149         }
7150         def = int_const(state, type, val);
7151         return def;
7152 }
7153
7154 static struct triple *primary_expr(struct compile_state *state)
7155 {
7156         struct triple *def;
7157         int tok;
7158         tok = peek(state);
7159         switch(tok) {
7160         case TOK_IDENT:
7161         {
7162                 struct hash_entry *ident;
7163                 /* Here ident is either:
7164                  * a varable name
7165                  * a function name
7166                  * an enumeration constant.
7167                  */
7168                 eat(state, TOK_IDENT);
7169                 ident = state->token[0].ident;
7170                 if (!ident->sym_ident) {
7171                         error(state, 0, "%s undeclared", ident->name);
7172                 }
7173                 def = ident->sym_ident->def;
7174                 break;
7175         }
7176         case TOK_ENUM_CONST:
7177                 /* Here ident is an enumeration constant */
7178                 eat(state, TOK_ENUM_CONST);
7179                 def = 0;
7180                 FINISHME();
7181                 break;
7182         case TOK_LPAREN:
7183                 eat(state, TOK_LPAREN);
7184                 def = expr(state);
7185                 eat(state, TOK_RPAREN);
7186                 break;
7187         case TOK_LIT_INT:
7188                 def = integer_constant(state);
7189                 break;
7190         case TOK_LIT_FLOAT:
7191                 eat(state, TOK_LIT_FLOAT);
7192                 error(state, 0, "Floating point constants not supported");
7193                 def = 0;
7194                 FINISHME();
7195                 break;
7196         case TOK_LIT_CHAR:
7197                 def = character_constant(state);
7198                 break;
7199         case TOK_LIT_STRING:
7200                 def = string_constant(state);
7201                 break;
7202         default:
7203                 def = 0;
7204                 error(state, 0, "Unexpected token: %s\n", tokens[tok]);
7205         }
7206         return def;
7207 }
7208
7209 static struct triple *postfix_expr(struct compile_state *state)
7210 {
7211         struct triple *def;
7212         int postfix;
7213         def = primary_expr(state);
7214         do {
7215                 struct triple *left;
7216                 int tok;
7217                 postfix = 1;
7218                 left = def;
7219                 switch((tok = peek(state))) {
7220                 case TOK_LBRACKET:
7221                         eat(state, TOK_LBRACKET);
7222                         def = mk_subscript_expr(state, left, expr(state));
7223                         eat(state, TOK_RBRACKET);
7224                         break;
7225                 case TOK_LPAREN:
7226                         def = call_expr(state, def);
7227                         break;
7228                 case TOK_DOT:
7229                 {
7230                         struct hash_entry *field;
7231                         eat(state, TOK_DOT);
7232                         eat(state, TOK_IDENT);
7233                         field = state->token[0].ident;
7234                         def = deref_field(state, def, field);
7235                         break;
7236                 }
7237                 case TOK_ARROW:
7238                 {
7239                         struct hash_entry *field;
7240                         eat(state, TOK_ARROW);
7241                         eat(state, TOK_IDENT);
7242                         field = state->token[0].ident;
7243                         def = mk_deref_expr(state, read_expr(state, def));
7244                         def = deref_field(state, def, field);
7245                         break;
7246                 }
7247                 case TOK_PLUSPLUS:
7248                         eat(state, TOK_PLUSPLUS);
7249                         def = mk_post_inc_expr(state, left);
7250                         break;
7251                 case TOK_MINUSMINUS:
7252                         eat(state, TOK_MINUSMINUS);
7253                         def = mk_post_dec_expr(state, left);
7254                         break;
7255                 default:
7256                         postfix = 0;
7257                         break;
7258                 }
7259         } while(postfix);
7260         return def;
7261 }
7262
7263 static struct triple *cast_expr(struct compile_state *state);
7264
7265 static struct triple *unary_expr(struct compile_state *state)
7266 {
7267         struct triple *def, *right;
7268         int tok;
7269         switch((tok = peek(state))) {
7270         case TOK_PLUSPLUS:
7271                 eat(state, TOK_PLUSPLUS);
7272                 def = mk_pre_inc_expr(state, unary_expr(state));
7273                 break;
7274         case TOK_MINUSMINUS:
7275                 eat(state, TOK_MINUSMINUS);
7276                 def = mk_pre_dec_expr(state, unary_expr(state));
7277                 break;
7278         case TOK_AND:
7279                 eat(state, TOK_AND);
7280                 def = mk_addr_expr(state, cast_expr(state), 0);
7281                 break;
7282         case TOK_STAR:
7283                 eat(state, TOK_STAR);
7284                 def = mk_deref_expr(state, read_expr(state, cast_expr(state)));
7285                 break;
7286         case TOK_PLUS:
7287                 eat(state, TOK_PLUS);
7288                 right = read_expr(state, cast_expr(state));
7289                 arithmetic(state, right);
7290                 def = integral_promotion(state, right);
7291                 break;
7292         case TOK_MINUS:
7293                 eat(state, TOK_MINUS);
7294                 right = read_expr(state, cast_expr(state));
7295                 arithmetic(state, right);
7296                 def = integral_promotion(state, right);
7297                 def = triple(state, OP_NEG, def->type, def, 0);
7298                 break;
7299         case TOK_TILDE:
7300                 eat(state, TOK_TILDE);
7301                 right = read_expr(state, cast_expr(state));
7302                 integral(state, right);
7303                 def = integral_promotion(state, right);
7304                 def = triple(state, OP_INVERT, def->type, def, 0);
7305                 break;
7306         case TOK_BANG:
7307                 eat(state, TOK_BANG);
7308                 right = read_expr(state, cast_expr(state));
7309                 bool(state, right);
7310                 def = lfalse_expr(state, right);
7311                 break;
7312         case TOK_SIZEOF:
7313         {
7314                 struct type *type;
7315                 int tok1, tok2;
7316                 eat(state, TOK_SIZEOF);
7317                 tok1 = peek(state);
7318                 tok2 = peek2(state);
7319                 if ((tok1 == TOK_LPAREN) && istype(tok2)) {
7320                         eat(state, TOK_LPAREN);
7321                         type = type_name(state);
7322                         eat(state, TOK_RPAREN);
7323                 }
7324                 else {
7325                         struct triple *expr;
7326                         expr = unary_expr(state);
7327                         type = expr->type;
7328                         release_expr(state, expr);
7329                 }
7330                 def = int_const(state, &ulong_type, size_of(state, type));
7331                 break;
7332         }
7333         case TOK_ALIGNOF:
7334         {
7335                 struct type *type;
7336                 int tok1, tok2;
7337                 eat(state, TOK_ALIGNOF);
7338                 tok1 = peek(state);
7339                 tok2 = peek2(state);
7340                 if ((tok1 == TOK_LPAREN) && istype(tok2)) {
7341                         eat(state, TOK_LPAREN);
7342                         type = type_name(state);
7343                         eat(state, TOK_RPAREN);
7344                 }
7345                 else {
7346                         struct triple *expr;
7347                         expr = unary_expr(state);
7348                         type = expr->type;
7349                         release_expr(state, expr);
7350                 }
7351                 def = int_const(state, &ulong_type, align_of(state, type));
7352                 break;
7353         }
7354         default:
7355                 def = postfix_expr(state);
7356                 break;
7357         }
7358         return def;
7359 }
7360
7361 static struct triple *cast_expr(struct compile_state *state)
7362 {
7363         struct triple *def;
7364         int tok1, tok2;
7365         tok1 = peek(state);
7366         tok2 = peek2(state);
7367         if ((tok1 == TOK_LPAREN) && istype(tok2)) {
7368                 struct type *type;
7369                 eat(state, TOK_LPAREN);
7370                 type = type_name(state);
7371                 eat(state, TOK_RPAREN);
7372                 def = mk_cast_expr(state, type, cast_expr(state));
7373         }
7374         else {
7375                 def = unary_expr(state);
7376         }
7377         return def;
7378 }
7379
7380 static struct triple *mult_expr(struct compile_state *state)
7381 {
7382         struct triple *def;
7383         int done;
7384         def = cast_expr(state);
7385         do {
7386                 struct triple *left, *right;
7387                 struct type *result_type;
7388                 int tok, op, sign;
7389                 done = 0;
7390                 switch(tok = (peek(state))) {
7391                 case TOK_STAR:
7392                 case TOK_DIV:
7393                 case TOK_MOD:
7394                         left = read_expr(state, def);
7395                         arithmetic(state, left);
7396
7397                         eat(state, tok);
7398
7399                         right = read_expr(state, cast_expr(state));
7400                         arithmetic(state, right);
7401
7402                         result_type = arithmetic_result(state, left, right);
7403                         sign = is_signed(result_type);
7404                         op = -1;
7405                         switch(tok) {
7406                         case TOK_STAR: op = sign? OP_SMUL : OP_UMUL; break;
7407                         case TOK_DIV:  op = sign? OP_SDIV : OP_UDIV; break;
7408                         case TOK_MOD:  op = sign? OP_SMOD : OP_UMOD; break;
7409                         }
7410                         def = triple(state, op, result_type, left, right);
7411                         break;
7412                 default:
7413                         done = 1;
7414                         break;
7415                 }
7416         } while(!done);
7417         return def;
7418 }
7419
7420 static struct triple *add_expr(struct compile_state *state)
7421 {
7422         struct triple *def;
7423         int done;
7424         def = mult_expr(state);
7425         do {
7426                 done = 0;
7427                 switch( peek(state)) {
7428                 case TOK_PLUS:
7429                         eat(state, TOK_PLUS);
7430                         def = mk_add_expr(state, def, mult_expr(state));
7431                         break;
7432                 case TOK_MINUS:
7433                         eat(state, TOK_MINUS);
7434                         def = mk_sub_expr(state, def, mult_expr(state));
7435                         break;
7436                 default:
7437                         done = 1;
7438                         break;
7439                 }
7440         } while(!done);
7441         return def;
7442 }
7443
7444 static struct triple *shift_expr(struct compile_state *state)
7445 {
7446         struct triple *def;
7447         int done;
7448         def = add_expr(state);
7449         do {
7450                 struct triple *left, *right;
7451                 int tok, op;
7452                 done = 0;
7453                 switch((tok = peek(state))) {
7454                 case TOK_SL:
7455                 case TOK_SR:
7456                         left = read_expr(state, def);
7457                         integral(state, left);
7458                         left = integral_promotion(state, left);
7459
7460                         eat(state, tok);
7461
7462                         right = read_expr(state, add_expr(state));
7463                         integral(state, right);
7464                         right = integral_promotion(state, right);
7465                         
7466                         op = (tok == TOK_SL)? OP_SL : 
7467                                 is_signed(left->type)? OP_SSR: OP_USR;
7468
7469                         def = triple(state, op, left->type, left, right);
7470                         break;
7471                 default:
7472                         done = 1;
7473                         break;
7474                 }
7475         } while(!done);
7476         return def;
7477 }
7478
7479 static struct triple *relational_expr(struct compile_state *state)
7480 {
7481 #warning "Extend relational exprs to work on more than arithmetic types"
7482         struct triple *def;
7483         int done;
7484         def = shift_expr(state);
7485         do {
7486                 struct triple *left, *right;
7487                 struct type *arg_type;
7488                 int tok, op, sign;
7489                 done = 0;
7490                 switch((tok = peek(state))) {
7491                 case TOK_LESS:
7492                 case TOK_MORE:
7493                 case TOK_LESSEQ:
7494                 case TOK_MOREEQ:
7495                         left = read_expr(state, def);
7496                         arithmetic(state, left);
7497
7498                         eat(state, tok);
7499
7500                         right = read_expr(state, shift_expr(state));
7501                         arithmetic(state, right);
7502
7503                         arg_type = arithmetic_result(state, left, right);
7504                         sign = is_signed(arg_type);
7505                         op = -1;
7506                         switch(tok) {
7507                         case TOK_LESS:   op = sign? OP_SLESS : OP_ULESS; break;
7508                         case TOK_MORE:   op = sign? OP_SMORE : OP_UMORE; break;
7509                         case TOK_LESSEQ: op = sign? OP_SLESSEQ : OP_ULESSEQ; break;
7510                         case TOK_MOREEQ: op = sign? OP_SMOREEQ : OP_UMOREEQ; break;
7511                         }
7512                         def = triple(state, op, &int_type, left, right);
7513                         break;
7514                 default:
7515                         done = 1;
7516                         break;
7517                 }
7518         } while(!done);
7519         return def;
7520 }
7521
7522 static struct triple *equality_expr(struct compile_state *state)
7523 {
7524 #warning "Extend equality exprs to work on more than arithmetic types"
7525         struct triple *def;
7526         int done;
7527         def = relational_expr(state);
7528         do {
7529                 struct triple *left, *right;
7530                 int tok, op;
7531                 done = 0;
7532                 switch((tok = peek(state))) {
7533                 case TOK_EQEQ:
7534                 case TOK_NOTEQ:
7535                         left = read_expr(state, def);
7536                         arithmetic(state, left);
7537                         eat(state, tok);
7538                         right = read_expr(state, relational_expr(state));
7539                         arithmetic(state, right);
7540                         op = (tok == TOK_EQEQ) ? OP_EQ: OP_NOTEQ;
7541                         def = triple(state, op, &int_type, left, right);
7542                         break;
7543                 default:
7544                         done = 1;
7545                         break;
7546                 }
7547         } while(!done);
7548         return def;
7549 }
7550
7551 static struct triple *and_expr(struct compile_state *state)
7552 {
7553         struct triple *def;
7554         def = equality_expr(state);
7555         while(peek(state) == TOK_AND) {
7556                 struct triple *left, *right;
7557                 struct type *result_type;
7558                 left = read_expr(state, def);
7559                 integral(state, left);
7560                 eat(state, TOK_AND);
7561                 right = read_expr(state, equality_expr(state));
7562                 integral(state, right);
7563                 result_type = arithmetic_result(state, left, right);
7564                 def = triple(state, OP_AND, result_type, left, right);
7565         }
7566         return def;
7567 }
7568
7569 static struct triple *xor_expr(struct compile_state *state)
7570 {
7571         struct triple *def;
7572         def = and_expr(state);
7573         while(peek(state) == TOK_XOR) {
7574                 struct triple *left, *right;
7575                 struct type *result_type;
7576                 left = read_expr(state, def);
7577                 integral(state, left);
7578                 eat(state, TOK_XOR);
7579                 right = read_expr(state, and_expr(state));
7580                 integral(state, right);
7581                 result_type = arithmetic_result(state, left, right);
7582                 def = triple(state, OP_XOR, result_type, left, right);
7583         }
7584         return def;
7585 }
7586
7587 static struct triple *or_expr(struct compile_state *state)
7588 {
7589         struct triple *def;
7590         def = xor_expr(state);
7591         while(peek(state) == TOK_OR) {
7592                 struct triple *left, *right;
7593                 struct type *result_type;
7594                 left = read_expr(state, def);
7595                 integral(state, left);
7596                 eat(state, TOK_OR);
7597                 right = read_expr(state, xor_expr(state));
7598                 integral(state, right);
7599                 result_type = arithmetic_result(state, left, right);
7600                 def = triple(state, OP_OR, result_type, left, right);
7601         }
7602         return def;
7603 }
7604
7605 static struct triple *land_expr(struct compile_state *state)
7606 {
7607         struct triple *def;
7608         def = or_expr(state);
7609         while(peek(state) == TOK_LOGAND) {
7610                 struct triple *left, *right;
7611                 left = read_expr(state, def);
7612                 bool(state, left);
7613                 eat(state, TOK_LOGAND);
7614                 right = read_expr(state, or_expr(state));
7615                 bool(state, right);
7616
7617                 def = triple(state, OP_LAND, &int_type,
7618                         ltrue_expr(state, left),
7619                         ltrue_expr(state, right));
7620         }
7621         return def;
7622 }
7623
7624 static struct triple *lor_expr(struct compile_state *state)
7625 {
7626         struct triple *def;
7627         def = land_expr(state);
7628         while(peek(state) == TOK_LOGOR) {
7629                 struct triple *left, *right;
7630                 left = read_expr(state, def);
7631                 bool(state, left);
7632                 eat(state, TOK_LOGOR);
7633                 right = read_expr(state, land_expr(state));
7634                 bool(state, right);
7635                 
7636                 def = triple(state, OP_LOR, &int_type,
7637                         ltrue_expr(state, left),
7638                         ltrue_expr(state, right));
7639         }
7640         return def;
7641 }
7642
7643 static struct triple *conditional_expr(struct compile_state *state)
7644 {
7645         struct triple *def;
7646         def = lor_expr(state);
7647         if (peek(state) == TOK_QUEST) {
7648                 struct triple *test, *left, *right;
7649                 bool(state, def);
7650                 test = ltrue_expr(state, read_expr(state, def));
7651                 eat(state, TOK_QUEST);
7652                 left = read_expr(state, expr(state));
7653                 eat(state, TOK_COLON);
7654                 right = read_expr(state, conditional_expr(state));
7655
7656                 def = cond_expr(state, test, left, right);
7657         }
7658         return def;
7659 }
7660
7661 static struct triple *eval_const_expr(
7662         struct compile_state *state, struct triple *expr)
7663 {
7664         struct triple *def;
7665         if (is_const(expr)) {
7666                 def = expr;
7667         } 
7668         else {
7669                 /* If we don't start out as a constant simplify into one */
7670                 struct triple *head, *ptr;
7671                 head = label(state); /* dummy initial triple */
7672                 flatten(state, head, expr);
7673                 for(ptr = head->next; ptr != head; ptr = ptr->next) {
7674                         simplify(state, ptr);
7675                 }
7676                 /* Remove the constant value the tail of the list */
7677                 def = head->prev;
7678                 def->prev->next = def->next;
7679                 def->next->prev = def->prev;
7680                 def->next = def->prev = def;
7681                 if (!is_const(def)) {
7682                         error(state, 0, "Not a constant expression");
7683                 }
7684                 /* Free the intermediate expressions */
7685                 while(head->next != head) {
7686                         release_triple(state, head->next);
7687                 }
7688                 free_triple(state, head);
7689         }
7690         return def;
7691 }
7692
7693 static struct triple *constant_expr(struct compile_state *state)
7694 {
7695         return eval_const_expr(state, conditional_expr(state));
7696 }
7697
7698 static struct triple *assignment_expr(struct compile_state *state)
7699 {
7700         struct triple *def, *left, *right;
7701         int tok, op, sign;
7702         /* The C grammer in K&R shows assignment expressions
7703          * only taking unary expressions as input on their
7704          * left hand side.  But specifies the precedence of
7705          * assignemnt as the lowest operator except for comma.
7706          *
7707          * Allowing conditional expressions on the left hand side
7708          * of an assignement results in a grammar that accepts
7709          * a larger set of statements than standard C.   As long
7710          * as the subset of the grammar that is standard C behaves
7711          * correctly this should cause no problems.
7712          * 
7713          * For the extra token strings accepted by the grammar
7714          * none of them should produce a valid lvalue, so they
7715          * should not produce functioning programs.
7716          *
7717          * GCC has this bug as well, so surprises should be minimal.
7718          */
7719         def = conditional_expr(state);
7720         left = def;
7721         switch((tok = peek(state))) {
7722         case TOK_EQ:
7723                 lvalue(state, left);
7724                 eat(state, TOK_EQ);
7725                 def = write_expr(state, left, 
7726                         read_expr(state, assignment_expr(state)));
7727                 break;
7728         case TOK_TIMESEQ:
7729         case TOK_DIVEQ:
7730         case TOK_MODEQ:
7731                 lvalue(state, left);
7732                 arithmetic(state, left);
7733                 eat(state, tok);
7734                 right = read_expr(state, assignment_expr(state));
7735                 arithmetic(state, right);
7736
7737                 sign = is_signed(left->type);
7738                 op = -1;
7739                 switch(tok) {
7740                 case TOK_TIMESEQ: op = sign? OP_SMUL : OP_UMUL; break;
7741                 case TOK_DIVEQ:   op = sign? OP_SDIV : OP_UDIV; break;
7742                 case TOK_MODEQ:   op = sign? OP_SMOD : OP_UMOD; break;
7743                 }
7744                 def = write_expr(state, left,
7745                         triple(state, op, left->type, 
7746                                 read_expr(state, left), right));
7747                 break;
7748         case TOK_PLUSEQ:
7749                 lvalue(state, left);
7750                 eat(state, TOK_PLUSEQ);
7751                 def = write_expr(state, left,
7752                         mk_add_expr(state, left, assignment_expr(state)));
7753                 break;
7754         case TOK_MINUSEQ:
7755                 lvalue(state, left);
7756                 eat(state, TOK_MINUSEQ);
7757                 def = write_expr(state, left,
7758                         mk_sub_expr(state, left, assignment_expr(state)));
7759                 break;
7760         case TOK_SLEQ:
7761         case TOK_SREQ:
7762         case TOK_ANDEQ:
7763         case TOK_XOREQ:
7764         case TOK_OREQ:
7765                 lvalue(state, left);
7766                 integral(state, left);
7767                 eat(state, tok);
7768                 right = read_expr(state, assignment_expr(state));
7769                 integral(state, right);
7770                 right = integral_promotion(state, right);
7771                 sign = is_signed(left->type);
7772                 op = -1;
7773                 switch(tok) {
7774                 case TOK_SLEQ:  op = OP_SL; break;
7775                 case TOK_SREQ:  op = sign? OP_SSR: OP_USR; break;
7776                 case TOK_ANDEQ: op = OP_AND; break;
7777                 case TOK_XOREQ: op = OP_XOR; break;
7778                 case TOK_OREQ:  op = OP_OR; break;
7779                 }
7780                 def = write_expr(state, left,
7781                         triple(state, op, left->type, 
7782                                 read_expr(state, left), right));
7783                 break;
7784         }
7785         return def;
7786 }
7787
7788 static struct triple *expr(struct compile_state *state)
7789 {
7790         struct triple *def;
7791         def = assignment_expr(state);
7792         while(peek(state) == TOK_COMMA) {
7793                 struct triple *left, *right;
7794                 left = def;
7795                 eat(state, TOK_COMMA);
7796                 right = assignment_expr(state);
7797                 def = triple(state, OP_COMMA, right->type, left, right);
7798         }
7799         return def;
7800 }
7801
7802 static void expr_statement(struct compile_state *state, struct triple *first)
7803 {
7804         if (peek(state) != TOK_SEMI) {
7805                 flatten(state, first, expr(state));
7806         }
7807         eat(state, TOK_SEMI);
7808 }
7809
7810 static void if_statement(struct compile_state *state, struct triple *first)
7811 {
7812         struct triple *test, *jmp1, *jmp2, *middle, *end;
7813
7814         jmp1 = jmp2 = middle = 0;
7815         eat(state, TOK_IF);
7816         eat(state, TOK_LPAREN);
7817         test = expr(state);
7818         bool(state, test);
7819         /* Cleanup and invert the test */
7820         test = lfalse_expr(state, read_expr(state, test));
7821         eat(state, TOK_RPAREN);
7822         /* Generate the needed pieces */
7823         middle = label(state);
7824         jmp1 = branch(state, middle, test);
7825         /* Thread the pieces together */
7826         flatten(state, first, test);
7827         flatten(state, first, jmp1);
7828         flatten(state, first, label(state));
7829         statement(state, first);
7830         if (peek(state) == TOK_ELSE) {
7831                 eat(state, TOK_ELSE);
7832                 /* Generate the rest of the pieces */
7833                 end = label(state);
7834                 jmp2 = branch(state, end, 0);
7835                 /* Thread them together */
7836                 flatten(state, first, jmp2);
7837                 flatten(state, first, middle);
7838                 statement(state, first);
7839                 flatten(state, first, end);
7840         }
7841         else {
7842                 flatten(state, first, middle);
7843         }
7844 }
7845
7846 static void for_statement(struct compile_state *state, struct triple *first)
7847 {
7848         struct triple *head, *test, *tail, *jmp1, *jmp2, *end;
7849         struct triple *label1, *label2, *label3;
7850         struct hash_entry *ident;
7851
7852         eat(state, TOK_FOR);
7853         eat(state, TOK_LPAREN);
7854         head = test = tail = jmp1 = jmp2 = 0;
7855         if (peek(state) != TOK_SEMI) {
7856                 head = expr(state);
7857         } 
7858         eat(state, TOK_SEMI);
7859         if (peek(state) != TOK_SEMI) {
7860                 test = expr(state);
7861                 bool(state, test);
7862                 test = ltrue_expr(state, read_expr(state, test));
7863         }
7864         eat(state, TOK_SEMI);
7865         if (peek(state) != TOK_RPAREN) {
7866                 tail = expr(state);
7867         }
7868         eat(state, TOK_RPAREN);
7869         /* Generate the needed pieces */
7870         label1 = label(state);
7871         label2 = label(state);
7872         label3 = label(state);
7873         if (test) {
7874                 jmp1 = branch(state, label3, 0);
7875                 jmp2 = branch(state, label1, test);
7876         }
7877         else {
7878                 jmp2 = branch(state, label1, 0);
7879         }
7880         end = label(state);
7881         /* Remember where break and continue go */
7882         start_scope(state);
7883         ident = state->i_break;
7884         symbol(state, ident, &ident->sym_ident, end, end->type);
7885         ident = state->i_continue;
7886         symbol(state, ident, &ident->sym_ident, label2, label2->type);
7887         /* Now include the body */
7888         flatten(state, first, head);
7889         flatten(state, first, jmp1);
7890         flatten(state, first, label1);
7891         statement(state, first);
7892         flatten(state, first, label2);
7893         flatten(state, first, tail);
7894         flatten(state, first, label3);
7895         flatten(state, first, test);
7896         flatten(state, first, jmp2);
7897         flatten(state, first, end);
7898         /* Cleanup the break/continue scope */
7899         end_scope(state);
7900 }
7901
7902 static void while_statement(struct compile_state *state, struct triple *first)
7903 {
7904         struct triple *label1, *test, *label2, *jmp1, *jmp2, *end;
7905         struct hash_entry *ident;
7906         eat(state, TOK_WHILE);
7907         eat(state, TOK_LPAREN);
7908         test = expr(state);
7909         bool(state, test);
7910         test = ltrue_expr(state, read_expr(state, test));
7911         eat(state, TOK_RPAREN);
7912         /* Generate the needed pieces */
7913         label1 = label(state);
7914         label2 = label(state);
7915         jmp1 = branch(state, label2, 0);
7916         jmp2 = branch(state, label1, test);
7917         end = label(state);
7918         /* Remember where break and continue go */
7919         start_scope(state);
7920         ident = state->i_break;
7921         symbol(state, ident, &ident->sym_ident, end, end->type);
7922         ident = state->i_continue;
7923         symbol(state, ident, &ident->sym_ident, label2, label2->type);
7924         /* Thread them together */
7925         flatten(state, first, jmp1);
7926         flatten(state, first, label1);
7927         statement(state, first);
7928         flatten(state, first, label2);
7929         flatten(state, first, test);
7930         flatten(state, first, jmp2);
7931         flatten(state, first, end);
7932         /* Cleanup the break/continue scope */
7933         end_scope(state);
7934 }
7935
7936 static void do_statement(struct compile_state *state, struct triple *first)
7937 {
7938         struct triple *label1, *label2, *test, *end;
7939         struct hash_entry *ident;
7940         eat(state, TOK_DO);
7941         /* Generate the needed pieces */
7942         label1 = label(state);
7943         label2 = label(state);
7944         end = label(state);
7945         /* Remember where break and continue go */
7946         start_scope(state);
7947         ident = state->i_break;
7948         symbol(state, ident, &ident->sym_ident, end, end->type);
7949         ident = state->i_continue;
7950         symbol(state, ident, &ident->sym_ident, label2, label2->type);
7951         /* Now include the body */
7952         flatten(state, first, label1);
7953         statement(state, first);
7954         /* Cleanup the break/continue scope */
7955         end_scope(state);
7956         /* Eat the rest of the loop */
7957         eat(state, TOK_WHILE);
7958         eat(state, TOK_LPAREN);
7959         test = read_expr(state, expr(state));
7960         bool(state, test);
7961         eat(state, TOK_RPAREN);
7962         eat(state, TOK_SEMI);
7963         /* Thread the pieces together */
7964         test = ltrue_expr(state, test);
7965         flatten(state, first, label2);
7966         flatten(state, first, test);
7967         flatten(state, first, branch(state, label1, test));
7968         flatten(state, first, end);
7969 }
7970
7971
7972 static void return_statement(struct compile_state *state, struct triple *first)
7973 {
7974         struct triple *jmp, *mv, *dest, *var, *val;
7975         int last;
7976         eat(state, TOK_RETURN);
7977
7978 #warning "FIXME implement a more general excess branch elimination"
7979         val = 0;
7980         /* If we have a return value do some more work */
7981         if (peek(state) != TOK_SEMI) {
7982                 val = read_expr(state, expr(state));
7983         }
7984         eat(state, TOK_SEMI);
7985
7986         /* See if this last statement in a function */
7987         last = ((peek(state) == TOK_RBRACE) && 
7988                 (state->scope_depth == GLOBAL_SCOPE_DEPTH +2));
7989
7990         /* Find the return variable */
7991         var = MISC(state->main_function, 0);
7992         /* Find the return destination */
7993         dest = RHS(state->main_function, 0)->prev;
7994         mv = jmp = 0;
7995         /* If needed generate a jump instruction */
7996         if (!last) {
7997                 jmp = branch(state, dest, 0);
7998         }
7999         /* If needed generate an assignment instruction */
8000         if (val) {
8001                 mv = write_expr(state, var, val);
8002         }
8003         /* Now put the code together */
8004         if (mv) {
8005                 flatten(state, first, mv);
8006                 flatten(state, first, jmp);
8007         }
8008         else if (jmp) {
8009                 flatten(state, first, jmp);
8010         }
8011 }
8012
8013 static void break_statement(struct compile_state *state, struct triple *first)
8014 {
8015         struct triple *dest;
8016         eat(state, TOK_BREAK);
8017         eat(state, TOK_SEMI);
8018         if (!state->i_break->sym_ident) {
8019                 error(state, 0, "break statement not within loop or switch");
8020         }
8021         dest = state->i_break->sym_ident->def;
8022         flatten(state, first, branch(state, dest, 0));
8023 }
8024
8025 static void continue_statement(struct compile_state *state, struct triple *first)
8026 {
8027         struct triple *dest;
8028         eat(state, TOK_CONTINUE);
8029         eat(state, TOK_SEMI);
8030         if (!state->i_continue->sym_ident) {
8031                 error(state, 0, "continue statement outside of a loop");
8032         }
8033         dest = state->i_continue->sym_ident->def;
8034         flatten(state, first, branch(state, dest, 0));
8035 }
8036
8037 static void goto_statement(struct compile_state *state, struct triple *first)
8038 {
8039         struct hash_entry *ident;
8040         eat(state, TOK_GOTO);
8041         eat(state, TOK_IDENT);
8042         ident = state->token[0].ident;
8043         if (!ident->sym_label) {
8044                 /* If this is a forward branch allocate the label now,
8045                  * it will be flattend in the appropriate location later.
8046                  */
8047                 struct triple *ins;
8048                 ins = label(state);
8049                 label_symbol(state, ident, ins);
8050         }
8051         eat(state, TOK_SEMI);
8052
8053         flatten(state, first, branch(state, ident->sym_label->def, 0));
8054 }
8055
8056 static void labeled_statement(struct compile_state *state, struct triple *first)
8057 {
8058         struct triple *ins;
8059         struct hash_entry *ident;
8060         eat(state, TOK_IDENT);
8061
8062         ident = state->token[0].ident;
8063         if (ident->sym_label && ident->sym_label->def) {
8064                 ins = ident->sym_label->def;
8065                 put_occurance(ins->occurance);
8066                 ins->occurance = new_occurance(state);
8067         }
8068         else {
8069                 ins = label(state);
8070                 label_symbol(state, ident, ins);
8071         }
8072         if (ins->id & TRIPLE_FLAG_FLATTENED) {
8073                 error(state, 0, "label %s already defined", ident->name);
8074         }
8075         flatten(state, first, ins);
8076
8077         eat(state, TOK_COLON);
8078         statement(state, first);
8079 }
8080
8081 static void switch_statement(struct compile_state *state, struct triple *first)
8082 {
8083         FINISHME();
8084         eat(state, TOK_SWITCH);
8085         eat(state, TOK_LPAREN);
8086         expr(state);
8087         eat(state, TOK_RPAREN);
8088         statement(state, first);
8089         error(state, 0, "switch statements are not implemented");
8090         FINISHME();
8091 }
8092
8093 static void case_statement(struct compile_state *state, struct triple *first)
8094 {
8095         FINISHME();
8096         eat(state, TOK_CASE);
8097         constant_expr(state);
8098         eat(state, TOK_COLON);
8099         statement(state, first);
8100         error(state, 0, "case statements are not implemented");
8101         FINISHME();
8102 }
8103
8104 static void default_statement(struct compile_state *state, struct triple *first)
8105 {
8106         FINISHME();
8107         eat(state, TOK_DEFAULT);
8108         eat(state, TOK_COLON);
8109         statement(state, first);
8110         error(state, 0, "default statements are not implemented");
8111         FINISHME();
8112 }
8113
8114 static void asm_statement(struct compile_state *state, struct triple *first)
8115 {
8116         struct asm_info *info;
8117         struct {
8118                 struct triple *constraint;
8119                 struct triple *expr;
8120         } out_param[MAX_LHS], in_param[MAX_RHS], clob_param[MAX_LHS];
8121         struct triple *def, *asm_str;
8122         int out, in, clobbers, more, colons, i;
8123
8124         eat(state, TOK_ASM);
8125         /* For now ignore the qualifiers */
8126         switch(peek(state)) {
8127         case TOK_CONST:
8128                 eat(state, TOK_CONST);
8129                 break;
8130         case TOK_VOLATILE:
8131                 eat(state, TOK_VOLATILE);
8132                 break;
8133         }
8134         eat(state, TOK_LPAREN);
8135         asm_str = string_constant(state);
8136
8137         colons = 0;
8138         out = in = clobbers = 0;
8139         /* Outputs */
8140         if ((colons == 0) && (peek(state) == TOK_COLON)) {
8141                 eat(state, TOK_COLON);
8142                 colons++;
8143                 more = (peek(state) == TOK_LIT_STRING);
8144                 while(more) {
8145                         struct triple *var;
8146                         struct triple *constraint;
8147                         char *str;
8148                         more = 0;
8149                         if (out > MAX_LHS) {
8150                                 error(state, 0, "Maximum output count exceeded.");
8151                         }
8152                         constraint = string_constant(state);
8153                         str = constraint->u.blob;
8154                         if (str[0] != '=') {
8155                                 error(state, 0, "Output constraint does not start with =");
8156                         }
8157                         constraint->u.blob = str + 1;
8158                         eat(state, TOK_LPAREN);
8159                         var = conditional_expr(state);
8160                         eat(state, TOK_RPAREN);
8161
8162                         lvalue(state, var);
8163                         out_param[out].constraint = constraint;
8164                         out_param[out].expr       = var;
8165                         if (peek(state) == TOK_COMMA) {
8166                                 eat(state, TOK_COMMA);
8167                                 more = 1;
8168                         }
8169                         out++;
8170                 }
8171         }
8172         /* Inputs */
8173         if ((colons == 1) && (peek(state) == TOK_COLON)) {
8174                 eat(state, TOK_COLON);
8175                 colons++;
8176                 more = (peek(state) == TOK_LIT_STRING);
8177                 while(more) {
8178                         struct triple *val;
8179                         struct triple *constraint;
8180                         char *str;
8181                         more = 0;
8182                         if (in > MAX_RHS) {
8183                                 error(state, 0, "Maximum input count exceeded.");
8184                         }
8185                         constraint = string_constant(state);
8186                         str = constraint->u.blob;
8187                         if (digitp(str[0] && str[1] == '\0')) {
8188                                 int val;
8189                                 val = digval(str[0]);
8190                                 if ((val < 0) || (val >= out)) {
8191                                         error(state, 0, "Invalid input constraint %d", val);
8192                                 }
8193                         }
8194                         eat(state, TOK_LPAREN);
8195                         val = conditional_expr(state);
8196                         eat(state, TOK_RPAREN);
8197
8198                         in_param[in].constraint = constraint;
8199                         in_param[in].expr       = val;
8200                         if (peek(state) == TOK_COMMA) {
8201                                 eat(state, TOK_COMMA);
8202                                 more = 1;
8203                         }
8204                         in++;
8205                 }
8206         }
8207
8208         /* Clobber */
8209         if ((colons == 2) && (peek(state) == TOK_COLON)) {
8210                 eat(state, TOK_COLON);
8211                 colons++;
8212                 more = (peek(state) == TOK_LIT_STRING);
8213                 while(more) {
8214                         struct triple *clobber;
8215                         more = 0;
8216                         if ((clobbers + out) > MAX_LHS) {
8217                                 error(state, 0, "Maximum clobber limit exceeded.");
8218                         }
8219                         clobber = string_constant(state);
8220
8221                         clob_param[clobbers].constraint = clobber;
8222                         if (peek(state) == TOK_COMMA) {
8223                                 eat(state, TOK_COMMA);
8224                                 more = 1;
8225                         }
8226                         clobbers++;
8227                 }
8228         }
8229         eat(state, TOK_RPAREN);
8230         eat(state, TOK_SEMI);
8231
8232
8233         info = xcmalloc(sizeof(*info), "asm_info");
8234         info->str = asm_str->u.blob;
8235         free_triple(state, asm_str);
8236
8237         def = new_triple(state, OP_ASM, &void_type, clobbers + out, in);
8238         def->u.ainfo = info;
8239
8240         /* Find the register constraints */
8241         for(i = 0; i < out; i++) {
8242                 struct triple *constraint;
8243                 constraint = out_param[i].constraint;
8244                 info->tmpl.lhs[i] = arch_reg_constraint(state, 
8245                         out_param[i].expr->type, constraint->u.blob);
8246                 free_triple(state, constraint);
8247         }
8248         for(; i - out < clobbers; i++) {
8249                 struct triple *constraint;
8250                 constraint = clob_param[i - out].constraint;
8251                 info->tmpl.lhs[i] = arch_reg_clobber(state, constraint->u.blob);
8252                 free_triple(state, constraint);
8253         }
8254         for(i = 0; i < in; i++) {
8255                 struct triple *constraint;
8256                 const char *str;
8257                 constraint = in_param[i].constraint;
8258                 str = constraint->u.blob;
8259                 if (digitp(str[0]) && str[1] == '\0') {
8260                         struct reg_info cinfo;
8261                         int val;
8262                         val = digval(str[0]);
8263                         cinfo.reg = info->tmpl.lhs[val].reg;
8264                         cinfo.regcm = arch_type_to_regcm(state, in_param[i].expr->type);
8265                         cinfo.regcm &= info->tmpl.lhs[val].regcm;
8266                         if (cinfo.reg == REG_UNSET) {
8267                                 cinfo.reg = REG_VIRT0 + val;
8268                         }
8269                         if (cinfo.regcm == 0) {
8270                                 error(state, 0, "No registers for %d", val);
8271                         }
8272                         info->tmpl.lhs[val] = cinfo;
8273                         info->tmpl.rhs[i]   = cinfo;
8274                                 
8275                 } else {
8276                         info->tmpl.rhs[i] = arch_reg_constraint(state, 
8277                                 in_param[i].expr->type, str);
8278                 }
8279                 free_triple(state, constraint);
8280         }
8281
8282         /* Now build the helper expressions */
8283         for(i = 0; i < in; i++) {
8284                 RHS(def, i) = read_expr(state,in_param[i].expr);
8285         }
8286         flatten(state, first, def);
8287         for(i = 0; i < (out + clobbers); i++) {
8288                 struct type *type;
8289                 struct triple *piece;
8290                 type = (i < out)? out_param[i].expr->type : &void_type;
8291                 piece = triple(state, OP_PIECE, type, def, 0);
8292                 piece->u.cval = i;
8293                 LHS(def, i) = piece;
8294                 flatten(state, first, piece);
8295         }
8296         /* And write the helpers to their destinations */
8297         for(i = 0; i < out; i++) {
8298                 struct triple *piece;
8299                 piece = LHS(def, i);
8300                 flatten(state, first,
8301                         write_expr(state, out_param[i].expr, piece));
8302         }
8303 }
8304
8305
8306 static int isdecl(int tok)
8307 {
8308         switch(tok) {
8309         case TOK_AUTO:
8310         case TOK_REGISTER:
8311         case TOK_STATIC:
8312         case TOK_EXTERN:
8313         case TOK_TYPEDEF:
8314         case TOK_CONST:
8315         case TOK_RESTRICT:
8316         case TOK_VOLATILE:
8317         case TOK_VOID:
8318         case TOK_CHAR:
8319         case TOK_SHORT:
8320         case TOK_INT:
8321         case TOK_LONG:
8322         case TOK_FLOAT:
8323         case TOK_DOUBLE:
8324         case TOK_SIGNED:
8325         case TOK_UNSIGNED:
8326         case TOK_STRUCT:
8327         case TOK_UNION:
8328         case TOK_ENUM:
8329         case TOK_TYPE_NAME: /* typedef name */
8330                 return 1;
8331         default:
8332                 return 0;
8333         }
8334 }
8335
8336 static void compound_statement(struct compile_state *state, struct triple *first)
8337 {
8338         eat(state, TOK_LBRACE);
8339         start_scope(state);
8340
8341         /* statement-list opt */
8342         while (peek(state) != TOK_RBRACE) {
8343                 statement(state, first);
8344         }
8345         end_scope(state);
8346         eat(state, TOK_RBRACE);
8347 }
8348
8349 static void statement(struct compile_state *state, struct triple *first)
8350 {
8351         int tok;
8352         tok = peek(state);
8353         if (tok == TOK_LBRACE) {
8354                 compound_statement(state, first);
8355         }
8356         else if (tok == TOK_IF) {
8357                 if_statement(state, first); 
8358         }
8359         else if (tok == TOK_FOR) {
8360                 for_statement(state, first);
8361         }
8362         else if (tok == TOK_WHILE) {
8363                 while_statement(state, first);
8364         }
8365         else if (tok == TOK_DO) {
8366                 do_statement(state, first);
8367         }
8368         else if (tok == TOK_RETURN) {
8369                 return_statement(state, first);
8370         }
8371         else if (tok == TOK_BREAK) {
8372                 break_statement(state, first);
8373         }
8374         else if (tok == TOK_CONTINUE) {
8375                 continue_statement(state, first);
8376         }
8377         else if (tok == TOK_GOTO) {
8378                 goto_statement(state, first);
8379         }
8380         else if (tok == TOK_SWITCH) {
8381                 switch_statement(state, first);
8382         }
8383         else if (tok == TOK_ASM) {
8384                 asm_statement(state, first);
8385         }
8386         else if ((tok == TOK_IDENT) && (peek2(state) == TOK_COLON)) {
8387                 labeled_statement(state, first); 
8388         }
8389         else if (tok == TOK_CASE) {
8390                 case_statement(state, first);
8391         }
8392         else if (tok == TOK_DEFAULT) {
8393                 default_statement(state, first);
8394         }
8395         else if (isdecl(tok)) {
8396                 /* This handles C99 intermixing of statements and decls */
8397                 decl(state, first);
8398         }
8399         else {
8400                 expr_statement(state, first);
8401         }
8402 }
8403
8404 static struct type *param_decl(struct compile_state *state)
8405 {
8406         struct type *type;
8407         struct hash_entry *ident;
8408         /* Cheat so the declarator will know we are not global */
8409         start_scope(state); 
8410         ident = 0;
8411         type = decl_specifiers(state);
8412         type = declarator(state, type, &ident, 0);
8413         type->field_ident = ident;
8414         end_scope(state);
8415         return type;
8416 }
8417
8418 static struct type *param_type_list(struct compile_state *state, struct type *type)
8419 {
8420         struct type *ftype, **next;
8421         ftype = new_type(TYPE_FUNCTION, type, param_decl(state));
8422         next = &ftype->right;
8423         while(peek(state) == TOK_COMMA) {
8424                 eat(state, TOK_COMMA);
8425                 if (peek(state) == TOK_DOTS) {
8426                         eat(state, TOK_DOTS);
8427                         error(state, 0, "variadic functions not supported");
8428                 }
8429                 else {
8430                         *next = new_type(TYPE_PRODUCT, *next, param_decl(state));
8431                         next = &((*next)->right);
8432                 }
8433         }
8434         return ftype;
8435 }
8436
8437
8438 static struct type *type_name(struct compile_state *state)
8439 {
8440         struct type *type;
8441         type = specifier_qualifier_list(state);
8442         /* abstract-declarator (may consume no tokens) */
8443         type = declarator(state, type, 0, 0);
8444         return type;
8445 }
8446
8447 static struct type *direct_declarator(
8448         struct compile_state *state, struct type *type, 
8449         struct hash_entry **ident, int need_ident)
8450 {
8451         struct type *outer;
8452         int op;
8453         outer = 0;
8454         arrays_complete(state, type);
8455         switch(peek(state)) {
8456         case TOK_IDENT:
8457                 eat(state, TOK_IDENT);
8458                 if (!ident) {
8459                         error(state, 0, "Unexpected identifier found");
8460                 }
8461                 /* The name of what we are declaring */
8462                 *ident = state->token[0].ident;
8463                 break;
8464         case TOK_LPAREN:
8465                 eat(state, TOK_LPAREN);
8466                 outer = declarator(state, type, ident, need_ident);
8467                 eat(state, TOK_RPAREN);
8468                 break;
8469         default:
8470                 if (need_ident) {
8471                         error(state, 0, "Identifier expected");
8472                 }
8473                 break;
8474         }
8475         do {
8476                 op = 1;
8477                 arrays_complete(state, type);
8478                 switch(peek(state)) {
8479                 case TOK_LPAREN:
8480                         eat(state, TOK_LPAREN);
8481                         type = param_type_list(state, type);
8482                         eat(state, TOK_RPAREN);
8483                         break;
8484                 case TOK_LBRACKET:
8485                 {
8486                         unsigned int qualifiers;
8487                         struct triple *value;
8488                         value = 0;
8489                         eat(state, TOK_LBRACKET);
8490                         if (peek(state) != TOK_RBRACKET) {
8491                                 value = constant_expr(state);
8492                                 integral(state, value);
8493                         }
8494                         eat(state, TOK_RBRACKET);
8495
8496                         qualifiers = type->type & (QUAL_MASK | STOR_MASK);
8497                         type = new_type(TYPE_ARRAY | qualifiers, type, 0);
8498                         if (value) {
8499                                 type->elements = value->u.cval;
8500                                 free_triple(state, value);
8501                         } else {
8502                                 type->elements = ELEMENT_COUNT_UNSPECIFIED;
8503                                 op = 0;
8504                         }
8505                 }
8506                         break;
8507                 default:
8508                         op = 0;
8509                         break;
8510                 }
8511         } while(op);
8512         if (outer) {
8513                 struct type *inner;
8514                 arrays_complete(state, type);
8515                 FINISHME();
8516                 for(inner = outer; inner->left; inner = inner->left)
8517                         ;
8518                 inner->left = type;
8519                 type = outer;
8520         }
8521         return type;
8522 }
8523
8524 static struct type *declarator(
8525         struct compile_state *state, struct type *type, 
8526         struct hash_entry **ident, int need_ident)
8527 {
8528         while(peek(state) == TOK_STAR) {
8529                 eat(state, TOK_STAR);
8530                 type = new_type(TYPE_POINTER | (type->type & STOR_MASK), type, 0);
8531         }
8532         type = direct_declarator(state, type, ident, need_ident);
8533         return type;
8534 }
8535
8536
8537 static struct type *typedef_name(
8538         struct compile_state *state, unsigned int specifiers)
8539 {
8540         struct hash_entry *ident;
8541         struct type *type;
8542         eat(state, TOK_TYPE_NAME);
8543         ident = state->token[0].ident;
8544         type = ident->sym_ident->type;
8545         specifiers |= type->type & QUAL_MASK;
8546         if ((specifiers & (STOR_MASK | QUAL_MASK)) != 
8547                 (type->type & (STOR_MASK | QUAL_MASK))) {
8548                 type = clone_type(specifiers, type);
8549         }
8550         return type;
8551 }
8552
8553 static struct type *enum_specifier(
8554         struct compile_state *state, unsigned int specifiers)
8555 {
8556         int tok;
8557         struct type *type;
8558         type = 0;
8559         FINISHME();
8560         eat(state, TOK_ENUM);
8561         tok = peek(state);
8562         if (tok == TOK_IDENT) {
8563                 eat(state, TOK_IDENT);
8564         }
8565         if ((tok != TOK_IDENT) || (peek(state) == TOK_LBRACE)) {
8566                 eat(state, TOK_LBRACE);
8567                 do {
8568                         eat(state, TOK_IDENT);
8569                         if (peek(state) == TOK_EQ) {
8570                                 eat(state, TOK_EQ);
8571                                 constant_expr(state);
8572                         }
8573                         if (peek(state) == TOK_COMMA) {
8574                                 eat(state, TOK_COMMA);
8575                         }
8576                 } while(peek(state) != TOK_RBRACE);
8577                 eat(state, TOK_RBRACE);
8578         }
8579         FINISHME();
8580         return type;
8581 }
8582
8583 static struct type *struct_declarator(
8584         struct compile_state *state, struct type *type, struct hash_entry **ident)
8585 {
8586         int tok;
8587         tok = peek(state);
8588         if (tok != TOK_COLON) {
8589                 type = declarator(state, type, ident, 1);
8590         }
8591         if ((tok == TOK_COLON) || (peek(state) == TOK_COLON)) {
8592                 struct triple *value;
8593                 eat(state, TOK_COLON);
8594                 value = constant_expr(state);
8595 #warning "FIXME implement bitfields to reduce register usage"
8596                 error(state, 0, "bitfields not yet implemented");
8597         }
8598         return type;
8599 }
8600
8601 static struct type *struct_or_union_specifier(
8602         struct compile_state *state, unsigned int spec)
8603 {
8604         struct type *struct_type;
8605         struct hash_entry *ident;
8606         unsigned int type_join;
8607         int tok;
8608         struct_type = 0;
8609         ident = 0;
8610         switch(peek(state)) {
8611         case TOK_STRUCT:
8612                 eat(state, TOK_STRUCT);
8613                 type_join = TYPE_PRODUCT;
8614                 break;
8615         case TOK_UNION:
8616                 eat(state, TOK_UNION);
8617                 type_join = TYPE_OVERLAP;
8618                 error(state, 0, "unions not yet supported\n");
8619                 break;
8620         default:
8621                 eat(state, TOK_STRUCT);
8622                 type_join = TYPE_PRODUCT;
8623                 break;
8624         }
8625         tok = peek(state);
8626         if ((tok == TOK_IDENT) || (tok == TOK_TYPE_NAME)) {
8627                 eat(state, tok);
8628                 ident = state->token[0].ident;
8629         }
8630         if (!ident || (peek(state) == TOK_LBRACE)) {
8631                 ulong_t elements;
8632                 struct type **next;
8633                 elements = 0;
8634                 eat(state, TOK_LBRACE);
8635                 next = &struct_type;
8636                 do {
8637                         struct type *base_type;
8638                         int done;
8639                         base_type = specifier_qualifier_list(state);
8640                         do {
8641                                 struct type *type;
8642                                 struct hash_entry *fident;
8643                                 done = 1;
8644                                 type = struct_declarator(state, base_type, &fident);
8645                                 elements++;
8646                                 if (peek(state) == TOK_COMMA) {
8647                                         done = 0;
8648                                         eat(state, TOK_COMMA);
8649                                 }
8650                                 type = clone_type(0, type);
8651                                 type->field_ident = fident;
8652                                 if (*next) {
8653                                         *next = new_type(type_join, *next, type);
8654                                         next = &((*next)->right);
8655                                 } else {
8656                                         *next = type;
8657                                 }
8658                         } while(!done);
8659                         eat(state, TOK_SEMI);
8660                 } while(peek(state) != TOK_RBRACE);
8661                 eat(state, TOK_RBRACE);
8662                 struct_type = new_type(TYPE_STRUCT | spec, struct_type, 0);
8663                 struct_type->type_ident = ident;
8664                 struct_type->elements = elements;
8665                 if (ident) {
8666                         symbol(state, ident, &ident->sym_struct, 0, struct_type);
8667                 }
8668         }
8669         if (ident && ident->sym_struct) {
8670                 struct_type = clone_type(spec,  ident->sym_struct->type);
8671         }
8672         else if (ident && !ident->sym_struct) {
8673                 error(state, 0, "struct %s undeclared", ident->name);
8674         }
8675         return struct_type;
8676 }
8677
8678 static unsigned int storage_class_specifier_opt(struct compile_state *state)
8679 {
8680         unsigned int specifiers;
8681         switch(peek(state)) {
8682         case TOK_AUTO:
8683                 eat(state, TOK_AUTO);
8684                 specifiers = STOR_AUTO;
8685                 break;
8686         case TOK_REGISTER:
8687                 eat(state, TOK_REGISTER);
8688                 specifiers = STOR_REGISTER;
8689                 break;
8690         case TOK_STATIC:
8691                 eat(state, TOK_STATIC);
8692                 specifiers = STOR_STATIC;
8693                 break;
8694         case TOK_EXTERN:
8695                 eat(state, TOK_EXTERN);
8696                 specifiers = STOR_EXTERN;
8697                 break;
8698         case TOK_TYPEDEF:
8699                 eat(state, TOK_TYPEDEF);
8700                 specifiers = STOR_TYPEDEF;
8701                 break;
8702         default:
8703                 if (state->scope_depth <= GLOBAL_SCOPE_DEPTH) {
8704                         specifiers = STOR_STATIC;
8705                 }
8706                 else {
8707                         specifiers = STOR_AUTO;
8708                 }
8709         }
8710         return specifiers;
8711 }
8712
8713 static unsigned int function_specifier_opt(struct compile_state *state)
8714 {
8715         /* Ignore the inline keyword */
8716         unsigned int specifiers;
8717         specifiers = 0;
8718         switch(peek(state)) {
8719         case TOK_INLINE:
8720                 eat(state, TOK_INLINE);
8721                 specifiers = STOR_INLINE;
8722         }
8723         return specifiers;
8724 }
8725
8726 static unsigned int type_qualifiers(struct compile_state *state)
8727 {
8728         unsigned int specifiers;
8729         int done;
8730         done = 0;
8731         specifiers = QUAL_NONE;
8732         do {
8733                 switch(peek(state)) {
8734                 case TOK_CONST:
8735                         eat(state, TOK_CONST);
8736                         specifiers = QUAL_CONST;
8737                         break;
8738                 case TOK_VOLATILE:
8739                         eat(state, TOK_VOLATILE);
8740                         specifiers = QUAL_VOLATILE;
8741                         break;
8742                 case TOK_RESTRICT:
8743                         eat(state, TOK_RESTRICT);
8744                         specifiers = QUAL_RESTRICT;
8745                         break;
8746                 default:
8747                         done = 1;
8748                         break;
8749                 }
8750         } while(!done);
8751         return specifiers;
8752 }
8753
8754 static struct type *type_specifier(
8755         struct compile_state *state, unsigned int spec)
8756 {
8757         struct type *type;
8758         type = 0;
8759         switch(peek(state)) {
8760         case TOK_VOID:
8761                 eat(state, TOK_VOID);
8762                 type = new_type(TYPE_VOID | spec, 0, 0);
8763                 break;
8764         case TOK_CHAR:
8765                 eat(state, TOK_CHAR);
8766                 type = new_type(TYPE_CHAR | spec, 0, 0);
8767                 break;
8768         case TOK_SHORT:
8769                 eat(state, TOK_SHORT);
8770                 if (peek(state) == TOK_INT) {
8771                         eat(state, TOK_INT);
8772                 }
8773                 type = new_type(TYPE_SHORT | spec, 0, 0);
8774                 break;
8775         case TOK_INT:
8776                 eat(state, TOK_INT);
8777                 type = new_type(TYPE_INT | spec, 0, 0);
8778                 break;
8779         case TOK_LONG:
8780                 eat(state, TOK_LONG);
8781                 switch(peek(state)) {
8782                 case TOK_LONG:
8783                         eat(state, TOK_LONG);
8784                         error(state, 0, "long long not supported");
8785                         break;
8786                 case TOK_DOUBLE:
8787                         eat(state, TOK_DOUBLE);
8788                         error(state, 0, "long double not supported");
8789                         break;
8790                 case TOK_INT:
8791                         eat(state, TOK_INT);
8792                         type = new_type(TYPE_LONG | spec, 0, 0);
8793                         break;
8794                 default:
8795                         type = new_type(TYPE_LONG | spec, 0, 0);
8796                         break;
8797                 }
8798                 break;
8799         case TOK_FLOAT:
8800                 eat(state, TOK_FLOAT);
8801                 error(state, 0, "type float not supported");
8802                 break;
8803         case TOK_DOUBLE:
8804                 eat(state, TOK_DOUBLE);
8805                 error(state, 0, "type double not supported");
8806                 break;
8807         case TOK_SIGNED:
8808                 eat(state, TOK_SIGNED);
8809                 switch(peek(state)) {
8810                 case TOK_LONG:
8811                         eat(state, TOK_LONG);
8812                         switch(peek(state)) {
8813                         case TOK_LONG:
8814                                 eat(state, TOK_LONG);
8815                                 error(state, 0, "type long long not supported");
8816                                 break;
8817                         case TOK_INT:
8818                                 eat(state, TOK_INT);
8819                                 type = new_type(TYPE_LONG | spec, 0, 0);
8820                                 break;
8821                         default:
8822                                 type = new_type(TYPE_LONG | spec, 0, 0);
8823                                 break;
8824                         }
8825                         break;
8826                 case TOK_INT:
8827                         eat(state, TOK_INT);
8828                         type = new_type(TYPE_INT | spec, 0, 0);
8829                         break;
8830                 case TOK_SHORT:
8831                         eat(state, TOK_SHORT);
8832                         type = new_type(TYPE_SHORT | spec, 0, 0);
8833                         break;
8834                 case TOK_CHAR:
8835                         eat(state, TOK_CHAR);
8836                         type = new_type(TYPE_CHAR | spec, 0, 0);
8837                         break;
8838                 default:
8839                         type = new_type(TYPE_INT | spec, 0, 0);
8840                         break;
8841                 }
8842                 break;
8843         case TOK_UNSIGNED:
8844                 eat(state, TOK_UNSIGNED);
8845                 switch(peek(state)) {
8846                 case TOK_LONG:
8847                         eat(state, TOK_LONG);
8848                         switch(peek(state)) {
8849                         case TOK_LONG:
8850                                 eat(state, TOK_LONG);
8851                                 error(state, 0, "unsigned long long not supported");
8852                                 break;
8853                         case TOK_INT:
8854                                 eat(state, TOK_INT);
8855                                 type = new_type(TYPE_ULONG | spec, 0, 0);
8856                                 break;
8857                         default:
8858                                 type = new_type(TYPE_ULONG | spec, 0, 0);
8859                                 break;
8860                         }
8861                         break;
8862                 case TOK_INT:
8863                         eat(state, TOK_INT);
8864                         type = new_type(TYPE_UINT | spec, 0, 0);
8865                         break;
8866                 case TOK_SHORT:
8867                         eat(state, TOK_SHORT);
8868                         type = new_type(TYPE_USHORT | spec, 0, 0);
8869                         break;
8870                 case TOK_CHAR:
8871                         eat(state, TOK_CHAR);
8872                         type = new_type(TYPE_UCHAR | spec, 0, 0);
8873                         break;
8874                 default:
8875                         type = new_type(TYPE_UINT | spec, 0, 0);
8876                         break;
8877                 }
8878                 break;
8879                 /* struct or union specifier */
8880         case TOK_STRUCT:
8881         case TOK_UNION:
8882                 type = struct_or_union_specifier(state, spec);
8883                 break;
8884                 /* enum-spefifier */
8885         case TOK_ENUM:
8886                 type = enum_specifier(state, spec);
8887                 break;
8888                 /* typedef name */
8889         case TOK_TYPE_NAME:
8890                 type = typedef_name(state, spec);
8891                 break;
8892         default:
8893                 error(state, 0, "bad type specifier %s", 
8894                         tokens[peek(state)]);
8895                 break;
8896         }
8897         return type;
8898 }
8899
8900 static int istype(int tok)
8901 {
8902         switch(tok) {
8903         case TOK_CONST:
8904         case TOK_RESTRICT:
8905         case TOK_VOLATILE:
8906         case TOK_VOID:
8907         case TOK_CHAR:
8908         case TOK_SHORT:
8909         case TOK_INT:
8910         case TOK_LONG:
8911         case TOK_FLOAT:
8912         case TOK_DOUBLE:
8913         case TOK_SIGNED:
8914         case TOK_UNSIGNED:
8915         case TOK_STRUCT:
8916         case TOK_UNION:
8917         case TOK_ENUM:
8918         case TOK_TYPE_NAME:
8919                 return 1;
8920         default:
8921                 return 0;
8922         }
8923 }
8924
8925
8926 static struct type *specifier_qualifier_list(struct compile_state *state)
8927 {
8928         struct type *type;
8929         unsigned int specifiers = 0;
8930
8931         /* type qualifiers */
8932         specifiers |= type_qualifiers(state);
8933
8934         /* type specifier */
8935         type = type_specifier(state, specifiers);
8936
8937         return type;
8938 }
8939
8940 static int isdecl_specifier(int tok)
8941 {
8942         switch(tok) {
8943                 /* storage class specifier */
8944         case TOK_AUTO:
8945         case TOK_REGISTER:
8946         case TOK_STATIC:
8947         case TOK_EXTERN:
8948         case TOK_TYPEDEF:
8949                 /* type qualifier */
8950         case TOK_CONST:
8951         case TOK_RESTRICT:
8952         case TOK_VOLATILE:
8953                 /* type specifiers */
8954         case TOK_VOID:
8955         case TOK_CHAR:
8956         case TOK_SHORT:
8957         case TOK_INT:
8958         case TOK_LONG:
8959         case TOK_FLOAT:
8960         case TOK_DOUBLE:
8961         case TOK_SIGNED:
8962         case TOK_UNSIGNED:
8963                 /* struct or union specifier */
8964         case TOK_STRUCT:
8965         case TOK_UNION:
8966                 /* enum-spefifier */
8967         case TOK_ENUM:
8968                 /* typedef name */
8969         case TOK_TYPE_NAME:
8970                 /* function specifiers */
8971         case TOK_INLINE:
8972                 return 1;
8973         default:
8974                 return 0;
8975         }
8976 }
8977
8978 static struct type *decl_specifiers(struct compile_state *state)
8979 {
8980         struct type *type;
8981         unsigned int specifiers;
8982         /* I am overly restrictive in the arragement of specifiers supported.
8983          * C is overly flexible in this department it makes interpreting
8984          * the parse tree difficult.
8985          */
8986         specifiers = 0;
8987
8988         /* storage class specifier */
8989         specifiers |= storage_class_specifier_opt(state);
8990
8991         /* function-specifier */
8992         specifiers |= function_specifier_opt(state);
8993
8994         /* type qualifier */
8995         specifiers |= type_qualifiers(state);
8996
8997         /* type specifier */
8998         type = type_specifier(state, specifiers);
8999         return type;
9000 }
9001
9002 struct field_info {
9003         struct type *type;
9004         size_t offset;
9005 };
9006
9007 static struct field_info designator(struct compile_state *state, struct type *type)
9008 {
9009         int tok;
9010         struct field_info info;
9011         info.offset = ~0U;
9012         info.type = 0;
9013         do {
9014                 switch(peek(state)) {
9015                 case TOK_LBRACKET:
9016                 {
9017                         struct triple *value;
9018                         if ((type->type & TYPE_MASK) != TYPE_ARRAY) {
9019                                 error(state, 0, "Array designator not in array initializer");
9020                         }
9021                         eat(state, TOK_LBRACKET);
9022                         value = constant_expr(state);
9023                         eat(state, TOK_RBRACKET);
9024
9025                         info.type = type->left;
9026                         info.offset = value->u.cval * size_of(state, info.type);
9027                         break;
9028                 }
9029                 case TOK_DOT:
9030                 {
9031                         struct hash_entry *field;
9032                         if ((type->type & TYPE_MASK) != TYPE_STRUCT) {
9033                                 error(state, 0, "Struct designator not in struct initializer");
9034                         }
9035                         eat(state, TOK_DOT);
9036                         eat(state, TOK_IDENT);
9037                         field = state->token[0].ident;
9038                         info.offset = field_offset(state, type, field);
9039                         info.type   = field_type(state, type, field);
9040                         break;
9041                 }
9042                 default:
9043                         error(state, 0, "Invalid designator");
9044                 }
9045                 tok = peek(state);
9046         } while((tok == TOK_LBRACKET) || (tok == TOK_DOT));
9047         eat(state, TOK_EQ);
9048         return info;
9049 }
9050
9051 static struct triple *initializer(
9052         struct compile_state *state, struct type *type)
9053 {
9054         struct triple *result;
9055 #warning "FIXME handle string pointer initializers "
9056 #warning "FIXME more consistent initializer handling (where should eval_const_expr go?"
9057         if (peek(state) != TOK_LBRACE) {
9058                 result = assignment_expr(state);
9059                 if (((type->type & TYPE_MASK) == TYPE_ARRAY) &&
9060                         (type->elements == ELEMENT_COUNT_UNSPECIFIED) &&
9061                         ((result->type->type & TYPE_MASK) == TYPE_ARRAY) &&
9062                         (result->type->elements != ELEMENT_COUNT_UNSPECIFIED) &&
9063                         (equiv_types(type->left, result->type->left))) {
9064                         type->elements = result->type->elements;
9065                 }
9066                 if (!is_init_compatible(state, type, result->type)) {
9067                         error(state, 0, "Incompatible types in initializer");
9068                 }
9069                 if (!equiv_types(type, result->type)) {
9070                         result = mk_cast_expr(state, type, result);
9071                 }
9072         }
9073         else {
9074                 int comma;
9075                 size_t max_offset;
9076                 struct field_info info;
9077                 void *buf;
9078                 if (((type->type & TYPE_MASK) != TYPE_ARRAY) &&
9079                         ((type->type & TYPE_MASK) != TYPE_STRUCT)) {
9080                         internal_error(state, 0, "unknown initializer type");
9081                 }
9082                 info.offset = 0;
9083                 info.type = type->left;
9084                 if ((type->type & TYPE_MASK) == TYPE_STRUCT) {
9085                         info.type = next_field(state, type, 0);
9086                 }
9087                 if (type->elements == ELEMENT_COUNT_UNSPECIFIED) {
9088                         max_offset = 0;
9089                 } else {
9090                         max_offset = size_of(state, type);
9091                 }
9092                 buf = xcmalloc(max_offset, "initializer");
9093                 eat(state, TOK_LBRACE);
9094                 do {
9095                         struct triple *value;
9096                         struct type *value_type;
9097                         size_t value_size;
9098                         void *dest;
9099                         int tok;
9100                         comma = 0;
9101                         tok = peek(state);
9102                         if ((tok == TOK_LBRACKET) || (tok == TOK_DOT)) {
9103                                 info = designator(state, type);
9104                         }
9105                         if ((type->elements != ELEMENT_COUNT_UNSPECIFIED) &&
9106                                 (info.offset >= max_offset)) {
9107                                 error(state, 0, "element beyond bounds");
9108                         }
9109                         value_type = info.type;
9110                         value = eval_const_expr(state, initializer(state, value_type));
9111                         value_size = size_of(state, value_type);
9112                         if (((type->type & TYPE_MASK) == TYPE_ARRAY) &&
9113                                 (type->elements == ELEMENT_COUNT_UNSPECIFIED) &&
9114                                 (max_offset <= info.offset)) {
9115                                 void *old_buf;
9116                                 size_t old_size;
9117                                 old_buf = buf;
9118                                 old_size = max_offset;
9119                                 max_offset = info.offset + value_size;
9120                                 buf = xmalloc(max_offset, "initializer");
9121                                 memcpy(buf, old_buf, old_size);
9122                                 xfree(old_buf);
9123                         }
9124                         dest = ((char *)buf) + info.offset;
9125                         if (value->op == OP_BLOBCONST) {
9126                                 memcpy(dest, value->u.blob, value_size);
9127                         }
9128                         else if ((value->op == OP_INTCONST) && (value_size == 1)) {
9129                                 *((uint8_t *)dest) = value->u.cval & 0xff;
9130                         }
9131                         else if ((value->op == OP_INTCONST) && (value_size == 2)) {
9132                                 *((uint16_t *)dest) = value->u.cval & 0xffff;
9133                         }
9134                         else if ((value->op == OP_INTCONST) && (value_size == 4)) {
9135                                 *((uint32_t *)dest) = value->u.cval & 0xffffffff;
9136                         }
9137                         else {
9138                                 internal_error(state, 0, "unhandled constant initializer");
9139                         }
9140                         free_triple(state, value);
9141                         if (peek(state) == TOK_COMMA) {
9142                                 eat(state, TOK_COMMA);
9143                                 comma = 1;
9144                         }
9145                         info.offset += value_size;
9146                         if ((type->type & TYPE_MASK) == TYPE_STRUCT) {
9147                                 info.type = next_field(state, type, info.type);
9148                                 info.offset = field_offset(state, type, 
9149                                         info.type->field_ident);
9150                         }
9151                 } while(comma && (peek(state) != TOK_RBRACE));
9152                 if ((type->elements == ELEMENT_COUNT_UNSPECIFIED) &&
9153                         ((type->type & TYPE_MASK) == TYPE_ARRAY)) {
9154                         type->elements = max_offset / size_of(state, type->left);
9155                 }
9156                 eat(state, TOK_RBRACE);
9157                 result = triple(state, OP_BLOBCONST, type, 0, 0);
9158                 result->u.blob = buf;
9159         }
9160         return result;
9161 }
9162
9163 static void resolve_branches(struct compile_state *state)
9164 {
9165         /* Make a second pass and finish anything outstanding
9166          * with respect to branches.  The only outstanding item
9167          * is to see if there are goto to labels that have not
9168          * been defined and to error about them.
9169          */
9170         int i;
9171         for(i = 0; i < HASH_TABLE_SIZE; i++) {
9172                 struct hash_entry *entry;
9173                 for(entry = state->hash_table[i]; entry; entry = entry->next) {
9174                         struct triple *ins;
9175                         if (!entry->sym_label) {
9176                                 continue;
9177                         }
9178                         ins = entry->sym_label->def;
9179                         if (!(ins->id & TRIPLE_FLAG_FLATTENED)) {
9180                                 error(state, ins, "label `%s' used but not defined",
9181                                         entry->name);
9182                         }
9183                 }
9184         }
9185 }
9186
9187 static struct triple *function_definition(
9188         struct compile_state *state, struct type *type)
9189 {
9190         struct triple *def, *tmp, *first, *end;
9191         struct hash_entry *ident;
9192         struct type *param;
9193         int i;
9194         if ((type->type &TYPE_MASK) != TYPE_FUNCTION) {
9195                 error(state, 0, "Invalid function header");
9196         }
9197
9198         /* Verify the function type */
9199         if (((type->right->type & TYPE_MASK) != TYPE_VOID)  &&
9200                 ((type->right->type & TYPE_MASK) != TYPE_PRODUCT) &&
9201                 (type->right->field_ident == 0)) {
9202                 error(state, 0, "Invalid function parameters");
9203         }
9204         param = type->right;
9205         i = 0;
9206         while((param->type & TYPE_MASK) == TYPE_PRODUCT) {
9207                 i++;
9208                 if (!param->left->field_ident) {
9209                         error(state, 0, "No identifier for parameter %d\n", i);
9210                 }
9211                 param = param->right;
9212         }
9213         i++;
9214         if (((param->type & TYPE_MASK) != TYPE_VOID) && !param->field_ident) {
9215                 error(state, 0, "No identifier for paramter %d\n", i);
9216         }
9217         
9218         /* Get a list of statements for this function. */
9219         def = triple(state, OP_LIST, type, 0, 0);
9220
9221         /* Start a new scope for the passed parameters */
9222         start_scope(state);
9223
9224         /* Put a label at the very start of a function */
9225         first = label(state);
9226         RHS(def, 0) = first;
9227
9228         /* Put a label at the very end of a function */
9229         end = label(state);
9230         flatten(state, first, end);
9231
9232         /* Walk through the parameters and create symbol table entries
9233          * for them.
9234          */
9235         param = type->right;
9236         while((param->type & TYPE_MASK) == TYPE_PRODUCT) {
9237                 ident = param->left->field_ident;
9238                 tmp = variable(state, param->left);
9239                 symbol(state, ident, &ident->sym_ident, tmp, tmp->type);
9240                 flatten(state, end, tmp);
9241                 param = param->right;
9242         }
9243         if ((param->type & TYPE_MASK) != TYPE_VOID) {
9244                 /* And don't forget the last parameter */
9245                 ident = param->field_ident;
9246                 tmp = variable(state, param);
9247                 symbol(state, ident, &ident->sym_ident, tmp, tmp->type);
9248                 flatten(state, end, tmp);
9249         }
9250         /* Add a variable for the return value */
9251         MISC(def, 0) = 0;
9252         if ((type->left->type & TYPE_MASK) != TYPE_VOID) {
9253                 /* Remove all type qualifiers from the return type */
9254                 tmp = variable(state, clone_type(0, type->left));
9255                 flatten(state, end, tmp);
9256                 /* Remember where the return value is */
9257                 MISC(def, 0) = tmp;
9258         }
9259
9260         /* Remember which function I am compiling.
9261          * Also assume the last defined function is the main function.
9262          */
9263         state->main_function = def;
9264
9265         /* Now get the actual function definition */
9266         compound_statement(state, end);
9267
9268         /* Finish anything unfinished with branches */
9269         resolve_branches(state);
9270
9271         /* Remove the parameter scope */
9272         end_scope(state);
9273
9274 #if 0
9275         fprintf(stdout, "\n");
9276         loc(stdout, state, 0);
9277         fprintf(stdout, "\n__________ function_definition _________\n");
9278         print_triple(state, def);
9279         fprintf(stdout, "__________ function_definition _________ done\n\n");
9280 #endif
9281
9282         return def;
9283 }
9284
9285 static struct triple *do_decl(struct compile_state *state, 
9286         struct type *type, struct hash_entry *ident)
9287 {
9288         struct triple *def;
9289         def = 0;
9290         /* Clean up the storage types used */
9291         switch (type->type & STOR_MASK) {
9292         case STOR_AUTO:
9293         case STOR_STATIC:
9294                 /* These are the good types I am aiming for */
9295                 break;
9296         case STOR_REGISTER:
9297                 type->type &= ~STOR_MASK;
9298                 type->type |= STOR_AUTO;
9299                 break;
9300         case STOR_EXTERN:
9301                 type->type &= ~STOR_MASK;
9302                 type->type |= STOR_STATIC;
9303                 break;
9304         case STOR_TYPEDEF:
9305                 if (!ident) {
9306                         error(state, 0, "typedef without name");
9307                 }
9308                 symbol(state, ident, &ident->sym_ident, 0, type);
9309                 ident->tok = TOK_TYPE_NAME;
9310                 return 0;
9311                 break;
9312         default:
9313                 internal_error(state, 0, "Undefined storage class");
9314         }
9315         if ((type->type & TYPE_MASK) == TYPE_FUNCTION) {
9316                 error(state, 0, "Function prototypes not supported");
9317         }
9318         if (ident && 
9319                 ((type->type & STOR_MASK) == STOR_STATIC) &&
9320                 ((type->type & QUAL_CONST) == 0)) {
9321                 error(state, 0, "non const static variables not supported");
9322         }
9323         if (ident) {
9324                 def = variable(state, type);
9325                 symbol(state, ident, &ident->sym_ident, def, type);
9326         }
9327         return def;
9328 }
9329
9330 static void decl(struct compile_state *state, struct triple *first)
9331 {
9332         struct type *base_type, *type;
9333         struct hash_entry *ident;
9334         struct triple *def;
9335         int global;
9336         global = (state->scope_depth <= GLOBAL_SCOPE_DEPTH);
9337         base_type = decl_specifiers(state);
9338         ident = 0;
9339         type = declarator(state, base_type, &ident, 0);
9340         if (global && ident && (peek(state) == TOK_LBRACE)) {
9341                 /* function */
9342                 state->function = ident->name;
9343                 def = function_definition(state, type);
9344                 symbol(state, ident, &ident->sym_ident, def, type);
9345                 state->function = 0;
9346         }
9347         else {
9348                 int done;
9349                 flatten(state, first, do_decl(state, type, ident));
9350                 /* type or variable definition */
9351                 do {
9352                         done = 1;
9353                         if (peek(state) == TOK_EQ) {
9354                                 if (!ident) {
9355                                         error(state, 0, "cannot assign to a type");
9356                                 }
9357                                 eat(state, TOK_EQ);
9358                                 flatten(state, first,
9359                                         init_expr(state, 
9360                                                 ident->sym_ident->def, 
9361                                                 initializer(state, type)));
9362                         }
9363                         arrays_complete(state, type);
9364                         if (peek(state) == TOK_COMMA) {
9365                                 eat(state, TOK_COMMA);
9366                                 ident = 0;
9367                                 type = declarator(state, base_type, &ident, 0);
9368                                 flatten(state, first, do_decl(state, type, ident));
9369                                 done = 0;
9370                         }
9371                 } while(!done);
9372                 eat(state, TOK_SEMI);
9373         }
9374 }
9375
9376 static void decls(struct compile_state *state)
9377 {
9378         struct triple *list;
9379         int tok;
9380         list = label(state);
9381         while(1) {
9382                 tok = peek(state);
9383                 if (tok == TOK_EOF) {
9384                         return;
9385                 }
9386                 if (tok == TOK_SPACE) {
9387                         eat(state, TOK_SPACE);
9388                 }
9389                 decl(state, list);
9390                 if (list->next != list) {
9391                         error(state, 0, "global variables not supported");
9392                 }
9393         }
9394 }
9395
9396 /*
9397  * Data structurs for optimation.
9398  */
9399
9400 static void do_use_block(
9401         struct block *used, struct block_set **head, struct block *user, 
9402         int front)
9403 {
9404         struct block_set **ptr, *new;
9405         if (!used)
9406                 return;
9407         if (!user)
9408                 return;
9409         ptr = head;
9410         while(*ptr) {
9411                 if ((*ptr)->member == user) {
9412                         return;
9413                 }
9414                 ptr = &(*ptr)->next;
9415         }
9416         new = xcmalloc(sizeof(*new), "block_set");
9417         new->member = user;
9418         if (front) {
9419                 new->next = *head;
9420                 *head = new;
9421         }
9422         else {
9423                 new->next = 0;
9424                 *ptr = new;
9425         }
9426 }
9427 static void do_unuse_block(
9428         struct block *used, struct block_set **head, struct block *unuser)
9429 {
9430         struct block_set *use, **ptr;
9431         ptr = head;
9432         while(*ptr) {
9433                 use = *ptr;
9434                 if (use->member == unuser) {
9435                         *ptr = use->next;
9436                         memset(use, -1, sizeof(*use));
9437                         xfree(use);
9438                 }
9439                 else {
9440                         ptr = &use->next;
9441                 }
9442         }
9443 }
9444
9445 static void use_block(struct block *used, struct block *user)
9446 {
9447         /* Append new to the head of the list, print_block
9448          * depends on this.
9449          */
9450         do_use_block(used, &used->use, user, 1); 
9451         used->users++;
9452 }
9453 static void unuse_block(struct block *used, struct block *unuser)
9454 {
9455         do_unuse_block(used, &used->use, unuser); 
9456         used->users--;
9457 }
9458
9459 static void idom_block(struct block *idom, struct block *user)
9460 {
9461         do_use_block(idom, &idom->idominates, user, 0);
9462 }
9463
9464 static void unidom_block(struct block *idom, struct block *unuser)
9465 {
9466         do_unuse_block(idom, &idom->idominates, unuser);
9467 }
9468
9469 static void domf_block(struct block *block, struct block *domf)
9470 {
9471         do_use_block(block, &block->domfrontier, domf, 0);
9472 }
9473
9474 static void undomf_block(struct block *block, struct block *undomf)
9475 {
9476         do_unuse_block(block, &block->domfrontier, undomf);
9477 }
9478
9479 static void ipdom_block(struct block *ipdom, struct block *user)
9480 {
9481         do_use_block(ipdom, &ipdom->ipdominates, user, 0);
9482 }
9483
9484 static void unipdom_block(struct block *ipdom, struct block *unuser)
9485 {
9486         do_unuse_block(ipdom, &ipdom->ipdominates, unuser);
9487 }
9488
9489 static void ipdomf_block(struct block *block, struct block *ipdomf)
9490 {
9491         do_use_block(block, &block->ipdomfrontier, ipdomf, 0);
9492 }
9493
9494 static void unipdomf_block(struct block *block, struct block *unipdomf)
9495 {
9496         do_unuse_block(block, &block->ipdomfrontier, unipdomf);
9497 }
9498
9499
9500
9501 static int do_walk_triple(struct compile_state *state,
9502         struct triple *ptr, int depth,
9503         int (*cb)(struct compile_state *state, struct triple *ptr, int depth)) 
9504 {
9505         int result;
9506         result = cb(state, ptr, depth);
9507         if ((result == 0) && (ptr->op == OP_LIST)) {
9508                 struct triple *list;
9509                 list = ptr;
9510                 ptr = RHS(list, 0);
9511                 do {
9512                         result = do_walk_triple(state, ptr, depth + 1, cb);
9513                         if (ptr->next->prev != ptr) {
9514                                 internal_error(state, ptr->next, "bad prev");
9515                         }
9516                         ptr = ptr->next;
9517                         
9518                 } while((result == 0) && (ptr != RHS(list, 0)));
9519         }
9520         return result;
9521 }
9522
9523 static int walk_triple(
9524         struct compile_state *state, 
9525         struct triple *ptr, 
9526         int (*cb)(struct compile_state *state, struct triple *ptr, int depth))
9527 {
9528         return do_walk_triple(state, ptr, 0, cb);
9529 }
9530
9531 static void do_print_prefix(int depth)
9532 {
9533         int i;
9534         for(i = 0; i < depth; i++) {
9535                 printf("  ");
9536         }
9537 }
9538
9539 #define PRINT_LIST 1
9540 static int do_print_triple(struct compile_state *state, struct triple *ins, int depth)
9541 {
9542         int op;
9543         op = ins->op;
9544         if (op == OP_LIST) {
9545 #if !PRINT_LIST
9546                 return 0;
9547 #endif
9548         }
9549         if ((op == OP_LABEL) && (ins->use)) {
9550                 printf("\n%p:\n", ins);
9551         }
9552         do_print_prefix(depth);
9553         display_triple(stdout, ins);
9554
9555         if ((ins->op == OP_BRANCH) && ins->use) {
9556                 internal_error(state, ins, "branch used?");
9557         }
9558         if (triple_is_branch(state, ins)) {
9559                 printf("\n");
9560         }
9561         return 0;
9562 }
9563
9564 static void print_triple(struct compile_state *state, struct triple *ins)
9565 {
9566         walk_triple(state, ins, do_print_triple);
9567 }
9568
9569 static void print_triples(struct compile_state *state)
9570 {
9571         print_triple(state, state->main_function);
9572 }
9573
9574 struct cf_block {
9575         struct block *block;
9576 };
9577 static void find_cf_blocks(struct cf_block *cf, struct block *block)
9578 {
9579         if (!block || (cf[block->vertex].block == block)) {
9580                 return;
9581         }
9582         cf[block->vertex].block = block;
9583         find_cf_blocks(cf, block->left);
9584         find_cf_blocks(cf, block->right);
9585 }
9586
9587 static void print_control_flow(struct compile_state *state)
9588 {
9589         struct cf_block *cf;
9590         int i;
9591         printf("\ncontrol flow\n");
9592         cf = xcmalloc(sizeof(*cf) * (state->last_vertex + 1), "cf_block");
9593         find_cf_blocks(cf, state->first_block);
9594
9595         for(i = 1; i <= state->last_vertex; i++) {
9596                 struct block *block;
9597                 block = cf[i].block;
9598                 if (!block)
9599                         continue;
9600                 printf("(%p) %d:", block, block->vertex);
9601                 if (block->left) {
9602                         printf(" %d", block->left->vertex);
9603                 }
9604                 if (block->right && (block->right != block->left)) {
9605                         printf(" %d", block->right->vertex);
9606                 }
9607                 printf("\n");
9608         }
9609
9610         xfree(cf);
9611 }
9612
9613
9614 static struct block *basic_block(struct compile_state *state,
9615         struct triple *first)
9616 {
9617         struct block *block;
9618         struct triple *ptr, *final;
9619         int op;
9620         if (first->op != OP_LABEL) {
9621                 internal_error(state, 0, "block does not start with a label");
9622         }
9623         /* See if this basic block has already been setup */
9624         if (first->u.block != 0) {
9625                 return first->u.block;
9626         }
9627         /* Lookup the final instruction.
9628          * It is important that the final instruction has it's own
9629          * basic block.
9630          */
9631         final = RHS(state->main_function, 0)->prev;
9632         /* Allocate another basic block structure */
9633         state->last_vertex += 1;
9634         block = xcmalloc(sizeof(*block), "block");
9635         block->first = block->last = first;
9636         block->vertex = state->last_vertex;
9637         ptr = first;
9638         do {
9639                 if ((ptr != first) && (ptr->op == OP_LABEL) && 
9640                         ((ptr->use) || ptr == final)) {
9641                         break;
9642                 }
9643                 block->last = ptr;
9644                 /* If ptr->u is not used remember where the baic block is */
9645                 if (triple_stores_block(state, ptr)) {
9646                         ptr->u.block = block;
9647                 }
9648                 if (ptr->op == OP_BRANCH) {
9649                         break;
9650                 }
9651                 ptr = ptr->next;
9652         } while (ptr != RHS(state->main_function, 0));
9653         if (ptr == RHS(state->main_function, 0))
9654                 return block;
9655         op = ptr->op;
9656         if (op == OP_LABEL) {
9657                 block->left = basic_block(state, ptr);
9658                 block->right = 0;
9659                 use_block(block->left, block);
9660         }
9661         else if (op == OP_BRANCH) {
9662                 block->left = 0;
9663                 /* Trace the branch target */
9664                 block->right = basic_block(state, TARG(ptr, 0));
9665                 use_block(block->right, block);
9666                 /* If there is a test trace the branch as well */
9667                 if (TRIPLE_RHS(ptr->sizes)) {
9668                         block->left = basic_block(state, ptr->next);
9669                         use_block(block->left, block);
9670                 }
9671         }
9672         else {
9673                 internal_error(state, 0, "Bad basic block split");
9674         }
9675         return block;
9676 }
9677
9678
9679 static void walk_blocks(struct compile_state *state,
9680         void (*cb)(struct compile_state *state, struct block *block, void *arg),
9681         void *arg)
9682 {
9683         struct triple *ptr, *first;
9684         struct block *last_block;
9685         last_block = 0;
9686         first = RHS(state->main_function, 0);
9687         ptr = first;
9688         do {
9689                 struct block *block;
9690                 if (triple_stores_block(state, ptr)) {
9691                         block = ptr->u.block;
9692                         if (block && (block != last_block)) {
9693                                 cb(state, block, arg);
9694                         }
9695                         last_block = block;
9696                 }
9697                 if (block && (block->last == ptr)) {
9698                         block = 0;
9699                 }
9700                 ptr = ptr->next;
9701         } while(ptr != first);
9702 }
9703
9704 static void print_block(
9705         struct compile_state *state, struct block *block, void *arg)
9706 {
9707         struct block_set *user;
9708         struct triple *ptr;
9709         FILE *fp = arg;
9710
9711         fprintf(fp, "\nblock: %p (%d)  %p<-%p %p<-%p\n", 
9712                 block, 
9713                 block->vertex,
9714                 block->left, 
9715                 block->left && block->left->use?block->left->use->member : 0,
9716                 block->right, 
9717                 block->right && block->right->use?block->right->use->member : 0);
9718         if (block->first->op == OP_LABEL) {
9719                 fprintf(fp, "%p:\n", block->first);
9720         }
9721         for(ptr = block->first; ; ptr = ptr->next) {
9722                 display_triple(fp, ptr);
9723                 if (ptr == block->last)
9724                         break;
9725         }
9726         fprintf(fp, "users %d: ", block->users);
9727         for(user = block->use; user; user = user->next) {
9728                 fprintf(fp, "%p (%d) ", 
9729                         user->member,
9730                         user->member->vertex);
9731         }
9732         fprintf(fp,"\n\n");
9733 }
9734
9735
9736 static void print_blocks(struct compile_state *state, FILE *fp)
9737 {
9738         fprintf(fp, "--------------- blocks ---------------\n");
9739         walk_blocks(state, print_block, fp);
9740 }
9741
9742 static void prune_nonblock_triples(struct compile_state *state)
9743 {
9744         struct block *block;
9745         struct triple *first, *ins, *next;
9746         /* Delete the triples not in a basic block */
9747         first = RHS(state->main_function, 0);
9748         block = 0;
9749         ins = first;
9750         do {
9751                 next = ins->next;
9752                 if (ins->op == OP_LABEL) {
9753                         block = ins->u.block;
9754                 }
9755                 if (!block) {
9756                         release_triple(state, ins);
9757                 }
9758                 if (block && block->last == ins) {
9759                         block = 0;
9760                 }
9761                 ins = next;
9762         } while(ins != first);
9763 }
9764
9765 static void setup_basic_blocks(struct compile_state *state)
9766 {
9767         if (!triple_stores_block(state, RHS(state->main_function, 0)) ||
9768                 !triple_stores_block(state, RHS(state->main_function,0)->prev)) {
9769                 internal_error(state, 0, "ins will not store block?");
9770         }
9771         /* Find the basic blocks */
9772         state->last_vertex = 0;
9773         state->first_block = basic_block(state, RHS(state->main_function,0));
9774         /* Delete the triples not in a basic block */
9775         prune_nonblock_triples(state);
9776         /* Find the last basic block */
9777         state->last_block = RHS(state->main_function, 0)->prev->u.block;
9778         if (!state->last_block) {
9779                 internal_error(state, 0, "end not used?");
9780         }
9781         /* If we are debugging print what I have just done */
9782         if (state->debug & DEBUG_BASIC_BLOCKS) {
9783                 print_blocks(state, stdout);
9784                 print_control_flow(state);
9785         }
9786 }
9787
9788 static void free_basic_block(struct compile_state *state, struct block *block)
9789 {
9790         struct block_set *entry, *next;
9791         struct block *child;
9792         if (!block) {
9793                 return;
9794         }
9795         if (block->vertex == -1) {
9796                 return;
9797         }
9798         block->vertex = -1;
9799         if (block->left) {
9800                 unuse_block(block->left, block);
9801         }
9802         if (block->right) {
9803                 unuse_block(block->right, block);
9804         }
9805         if (block->idom) {
9806                 unidom_block(block->idom, block);
9807         }
9808         block->idom = 0;
9809         if (block->ipdom) {
9810                 unipdom_block(block->ipdom, block);
9811         }
9812         block->ipdom = 0;
9813         for(entry = block->use; entry; entry = next) {
9814                 next = entry->next;
9815                 child = entry->member;
9816                 unuse_block(block, child);
9817                 if (child->left == block) {
9818                         child->left = 0;
9819                 }
9820                 if (child->right == block) {
9821                         child->right = 0;
9822                 }
9823         }
9824         for(entry = block->idominates; entry; entry = next) {
9825                 next = entry->next;
9826                 child = entry->member;
9827                 unidom_block(block, child);
9828                 child->idom = 0;
9829         }
9830         for(entry = block->domfrontier; entry; entry = next) {
9831                 next = entry->next;
9832                 child = entry->member;
9833                 undomf_block(block, child);
9834         }
9835         for(entry = block->ipdominates; entry; entry = next) {
9836                 next = entry->next;
9837                 child = entry->member;
9838                 unipdom_block(block, child);
9839                 child->ipdom = 0;
9840         }
9841         for(entry = block->ipdomfrontier; entry; entry = next) {
9842                 next = entry->next;
9843                 child = entry->member;
9844                 unipdomf_block(block, child);
9845         }
9846         if (block->users != 0) {
9847                 internal_error(state, 0, "block still has users");
9848         }
9849         free_basic_block(state, block->left);
9850         block->left = 0;
9851         free_basic_block(state, block->right);
9852         block->right = 0;
9853         memset(block, -1, sizeof(*block));
9854         xfree(block);
9855 }
9856
9857 static void free_basic_blocks(struct compile_state *state)
9858 {
9859         struct triple *first, *ins;
9860         free_basic_block(state, state->first_block);
9861         state->last_vertex = 0;
9862         state->first_block = state->last_block = 0;
9863         first = RHS(state->main_function, 0);
9864         ins = first;
9865         do {
9866                 if (triple_stores_block(state, ins)) {
9867                         ins->u.block = 0;
9868                 }
9869                 ins = ins->next;
9870         } while(ins != first);
9871         
9872 }
9873
9874 struct sdom_block {
9875         struct block *block;
9876         struct sdom_block *sdominates;
9877         struct sdom_block *sdom_next;
9878         struct sdom_block *sdom;
9879         struct sdom_block *label;
9880         struct sdom_block *parent;
9881         struct sdom_block *ancestor;
9882         int vertex;
9883 };
9884
9885
9886 static void unsdom_block(struct sdom_block *block)
9887 {
9888         struct sdom_block **ptr;
9889         if (!block->sdom_next) {
9890                 return;
9891         }
9892         ptr = &block->sdom->sdominates;
9893         while(*ptr) {
9894                 if ((*ptr) == block) {
9895                         *ptr = block->sdom_next;
9896                         return;
9897                 }
9898                 ptr = &(*ptr)->sdom_next;
9899         }
9900 }
9901
9902 static void sdom_block(struct sdom_block *sdom, struct sdom_block *block)
9903 {
9904         unsdom_block(block);
9905         block->sdom = sdom;
9906         block->sdom_next = sdom->sdominates;
9907         sdom->sdominates = block;
9908 }
9909
9910
9911
9912 static int initialize_sdblock(struct sdom_block *sd,
9913         struct block *parent, struct block *block, int vertex)
9914 {
9915         if (!block || (sd[block->vertex].block == block)) {
9916                 return vertex;
9917         }
9918         vertex += 1;
9919         /* Renumber the blocks in a convinient fashion */
9920         block->vertex = vertex;
9921         sd[vertex].block    = block;
9922         sd[vertex].sdom     = &sd[vertex];
9923         sd[vertex].label    = &sd[vertex];
9924         sd[vertex].parent   = parent? &sd[parent->vertex] : 0;
9925         sd[vertex].ancestor = 0;
9926         sd[vertex].vertex   = vertex;
9927         vertex = initialize_sdblock(sd, block, block->left, vertex);
9928         vertex = initialize_sdblock(sd, block, block->right, vertex);
9929         return vertex;
9930 }
9931
9932 static int initialize_sdpblock(
9933         struct compile_state *state, struct sdom_block *sd,
9934         struct block *parent, struct block *block, int vertex)
9935 {
9936         struct block_set *user;
9937         if (!block || (sd[block->vertex].block == block)) {
9938                 return vertex;
9939         }
9940         vertex += 1;
9941         /* Renumber the blocks in a convinient fashion */
9942         block->vertex = vertex;
9943         sd[vertex].block    = block;
9944         sd[vertex].sdom     = &sd[vertex];
9945         sd[vertex].label    = &sd[vertex];
9946         sd[vertex].parent   = parent? &sd[parent->vertex] : 0;
9947         sd[vertex].ancestor = 0;
9948         sd[vertex].vertex   = vertex;
9949         for(user = block->use; user; user = user->next) {
9950                 vertex = initialize_sdpblock(state, sd, block, user->member, vertex);
9951         }
9952         return vertex;
9953 }
9954
9955 static int setup_sdpblocks(struct compile_state *state, struct sdom_block *sd)
9956 {
9957         struct block *block;
9958         int vertex;
9959         /* Setup as many sdpblocks as possible without using fake edges */
9960         vertex = initialize_sdpblock(state, sd, 0, state->last_block, 0);
9961
9962         /* Walk through the graph and find unconnected blocks.  If 
9963          * we can, add a fake edge from the unconnected blocks to the
9964          * end of the graph.
9965          */
9966         block = state->first_block->last->next->u.block;
9967         for(; block && block != state->first_block; block =  block->last->next->u.block) {
9968                 if (sd[block->vertex].block == block) {
9969                         continue;
9970                 }
9971                 if (block->left != 0) {
9972                         continue;
9973                 }
9974
9975 #if DEBUG_SDP_BLOCKS
9976                 fprintf(stderr, "Adding %d\n", vertex +1);
9977 #endif
9978
9979                 block->left = state->last_block;
9980                 use_block(block->left, block);
9981                 vertex = initialize_sdpblock(state, sd, state->last_block, block, vertex);
9982         }
9983         return vertex;
9984 }
9985
9986 static void compress_ancestors(struct sdom_block *v)
9987 {
9988         /* This procedure assumes ancestor(v) != 0 */
9989         /* if (ancestor(ancestor(v)) != 0) {
9990          *      compress(ancestor(ancestor(v)));
9991          *      if (semi(label(ancestor(v))) < semi(label(v))) {
9992          *              label(v) = label(ancestor(v));
9993          *      }
9994          *      ancestor(v) = ancestor(ancestor(v));
9995          * }
9996          */
9997         if (!v->ancestor) {
9998                 return;
9999         }
10000         if (v->ancestor->ancestor) {
10001                 compress_ancestors(v->ancestor->ancestor);
10002                 if (v->ancestor->label->sdom->vertex < v->label->sdom->vertex) {
10003                         v->label = v->ancestor->label;
10004                 }
10005                 v->ancestor = v->ancestor->ancestor;
10006         }
10007 }
10008
10009 static void compute_sdom(struct compile_state *state, struct sdom_block *sd)
10010 {
10011         int i;
10012         /* // step 2 
10013          *  for each v <= pred(w) {
10014          *      u = EVAL(v);
10015          *      if (semi[u] < semi[w] { 
10016          *              semi[w] = semi[u]; 
10017          *      } 
10018          * }
10019          * add w to bucket(vertex(semi[w]));
10020          * LINK(parent(w), w);
10021          *
10022          * // step 3
10023          * for each v <= bucket(parent(w)) {
10024          *      delete v from bucket(parent(w));
10025          *      u = EVAL(v);
10026          *      dom(v) = (semi[u] < semi[v]) ? u : parent(w);
10027          * }
10028          */
10029         for(i = state->last_vertex; i >= 2; i--) {
10030                 struct sdom_block *v, *parent, *next;
10031                 struct block_set *user;
10032                 struct block *block;
10033                 block = sd[i].block;
10034                 parent = sd[i].parent;
10035                 /* Step 2 */
10036                 for(user = block->use; user; user = user->next) {
10037                         struct sdom_block *v, *u;
10038                         v = &sd[user->member->vertex];
10039                         u = !(v->ancestor)? v : (compress_ancestors(v), v->label);
10040                         if (u->sdom->vertex < sd[i].sdom->vertex) {
10041                                 sd[i].sdom = u->sdom;
10042                         }
10043                 }
10044                 sdom_block(sd[i].sdom, &sd[i]);
10045                 sd[i].ancestor = parent;
10046                 /* Step 3 */
10047                 for(v = parent->sdominates; v; v = next) {
10048                         struct sdom_block *u;
10049                         next = v->sdom_next;
10050                         unsdom_block(v);
10051                         u = (!v->ancestor) ? v : (compress_ancestors(v), v->label);
10052                         v->block->idom = (u->sdom->vertex < v->sdom->vertex)? 
10053                                 u->block : parent->block;
10054                 }
10055         }
10056 }
10057
10058 static void compute_spdom(struct compile_state *state, struct sdom_block *sd)
10059 {
10060         int i;
10061         /* // step 2 
10062          *  for each v <= pred(w) {
10063          *      u = EVAL(v);
10064          *      if (semi[u] < semi[w] { 
10065          *              semi[w] = semi[u]; 
10066          *      } 
10067          * }
10068          * add w to bucket(vertex(semi[w]));
10069          * LINK(parent(w), w);
10070          *
10071          * // step 3
10072          * for each v <= bucket(parent(w)) {
10073          *      delete v from bucket(parent(w));
10074          *      u = EVAL(v);
10075          *      dom(v) = (semi[u] < semi[v]) ? u : parent(w);
10076          * }
10077          */
10078         for(i = state->last_vertex; i >= 2; i--) {
10079                 struct sdom_block *u, *v, *parent, *next;
10080                 struct block *block;
10081                 block = sd[i].block;
10082                 parent = sd[i].parent;
10083                 /* Step 2 */
10084                 if (block->left) {
10085                         v = &sd[block->left->vertex];
10086                         u = !(v->ancestor)? v : (compress_ancestors(v), v->label);
10087                         if (u->sdom->vertex < sd[i].sdom->vertex) {
10088                                 sd[i].sdom = u->sdom;
10089                         }
10090                 }
10091                 if (block->right && (block->right != block->left)) {
10092                         v = &sd[block->right->vertex];
10093                         u = !(v->ancestor)? v : (compress_ancestors(v), v->label);
10094                         if (u->sdom->vertex < sd[i].sdom->vertex) {
10095                                 sd[i].sdom = u->sdom;
10096                         }
10097                 }
10098                 sdom_block(sd[i].sdom, &sd[i]);
10099                 sd[i].ancestor = parent;
10100                 /* Step 3 */
10101                 for(v = parent->sdominates; v; v = next) {
10102                         struct sdom_block *u;
10103                         next = v->sdom_next;
10104                         unsdom_block(v);
10105                         u = (!v->ancestor) ? v : (compress_ancestors(v), v->label);
10106                         v->block->ipdom = (u->sdom->vertex < v->sdom->vertex)? 
10107                                 u->block : parent->block;
10108                 }
10109         }
10110 }
10111
10112 static void compute_idom(struct compile_state *state, struct sdom_block *sd)
10113 {
10114         int i;
10115         for(i = 2; i <= state->last_vertex; i++) {
10116                 struct block *block;
10117                 block = sd[i].block;
10118                 if (block->idom->vertex != sd[i].sdom->vertex) {
10119                         block->idom = block->idom->idom;
10120                 }
10121                 idom_block(block->idom, block);
10122         }
10123         sd[1].block->idom = 0;
10124 }
10125
10126 static void compute_ipdom(struct compile_state *state, struct sdom_block *sd)
10127 {
10128         int i;
10129         for(i = 2; i <= state->last_vertex; i++) {
10130                 struct block *block;
10131                 block = sd[i].block;
10132                 if (block->ipdom->vertex != sd[i].sdom->vertex) {
10133                         block->ipdom = block->ipdom->ipdom;
10134                 }
10135                 ipdom_block(block->ipdom, block);
10136         }
10137         sd[1].block->ipdom = 0;
10138 }
10139
10140         /* Theorem 1:
10141          *   Every vertex of a flowgraph G = (V, E, r) except r has
10142          *   a unique immediate dominator.  
10143          *   The edges {(idom(w), w) |w <= V - {r}} form a directed tree
10144          *   rooted at r, called the dominator tree of G, such that 
10145          *   v dominates w if and only if v is a proper ancestor of w in
10146          *   the dominator tree.
10147          */
10148         /* Lemma 1:  
10149          *   If v and w are vertices of G such that v <= w,
10150          *   than any path from v to w must contain a common ancestor
10151          *   of v and w in T.
10152          */
10153         /* Lemma 2:  For any vertex w != r, idom(w) -> w */
10154         /* Lemma 3:  For any vertex w != r, sdom(w) -> w */
10155         /* Lemma 4:  For any vertex w != r, idom(w) -> sdom(w) */
10156         /* Theorem 2:
10157          *   Let w != r.  Suppose every u for which sdom(w) -> u -> w satisfies
10158          *   sdom(u) >= sdom(w).  Then idom(w) = sdom(w).
10159          */
10160         /* Theorem 3:
10161          *   Let w != r and let u be a vertex for which sdom(u) is 
10162          *   minimum amoung vertices u satisfying sdom(w) -> u -> w.
10163          *   Then sdom(u) <= sdom(w) and idom(u) = idom(w).
10164          */
10165         /* Lemma 5:  Let vertices v,w satisfy v -> w.
10166          *           Then v -> idom(w) or idom(w) -> idom(v)
10167          */
10168
10169 static void find_immediate_dominators(struct compile_state *state)
10170 {
10171         struct sdom_block *sd;
10172         /* w->sdom = min{v| there is a path v = v0,v1,...,vk = w such that:
10173          *           vi > w for (1 <= i <= k - 1}
10174          */
10175         /* Theorem 4:
10176          *   For any vertex w != r.
10177          *   sdom(w) = min(
10178          *                 {v|(v,w) <= E  and v < w } U 
10179          *                 {sdom(u) | u > w and there is an edge (v, w) such that u -> v})
10180          */
10181         /* Corollary 1:
10182          *   Let w != r and let u be a vertex for which sdom(u) is 
10183          *   minimum amoung vertices u satisfying sdom(w) -> u -> w.
10184          *   Then:
10185          *                   { sdom(w) if sdom(w) = sdom(u),
10186          *        idom(w) = {
10187          *                   { idom(u) otherwise
10188          */
10189         /* The algorithm consists of the following 4 steps.
10190          * Step 1.  Carry out a depth-first search of the problem graph.  
10191          *    Number the vertices from 1 to N as they are reached during
10192          *    the search.  Initialize the variables used in succeeding steps.
10193          * Step 2.  Compute the semidominators of all vertices by applying
10194          *    theorem 4.   Carry out the computation vertex by vertex in
10195          *    decreasing order by number.
10196          * Step 3.  Implicitly define the immediate dominator of each vertex
10197          *    by applying Corollary 1.
10198          * Step 4.  Explicitly define the immediate dominator of each vertex,
10199          *    carrying out the computation vertex by vertex in increasing order
10200          *    by number.
10201          */
10202         /* Step 1 initialize the basic block information */
10203         sd = xcmalloc(sizeof(*sd) * (state->last_vertex + 1), "sdom_state");
10204         initialize_sdblock(sd, 0, state->first_block, 0);
10205 #if 0
10206         sd[1].size  = 0;
10207         sd[1].label = 0;
10208         sd[1].sdom  = 0;
10209 #endif
10210         /* Step 2 compute the semidominators */
10211         /* Step 3 implicitly define the immediate dominator of each vertex */
10212         compute_sdom(state, sd);
10213         /* Step 4 explicitly define the immediate dominator of each vertex */
10214         compute_idom(state, sd);
10215         xfree(sd);
10216 }
10217
10218 static void find_post_dominators(struct compile_state *state)
10219 {
10220         struct sdom_block *sd;
10221         int vertex;
10222         /* Step 1 initialize the basic block information */
10223         sd = xcmalloc(sizeof(*sd) * (state->last_vertex + 1), "sdom_state");
10224
10225         vertex = setup_sdpblocks(state, sd);
10226         if (vertex != state->last_vertex) {
10227                 internal_error(state, 0, "missing %d blocks\n",
10228                         state->last_vertex - vertex);
10229         }
10230
10231         /* Step 2 compute the semidominators */
10232         /* Step 3 implicitly define the immediate dominator of each vertex */
10233         compute_spdom(state, sd);
10234         /* Step 4 explicitly define the immediate dominator of each vertex */
10235         compute_ipdom(state, sd);
10236         xfree(sd);
10237 }
10238
10239
10240
10241 static void find_block_domf(struct compile_state *state, struct block *block)
10242 {
10243         struct block *child;
10244         struct block_set *user;
10245         if (block->domfrontier != 0) {
10246                 internal_error(state, block->first, "domfrontier present?");
10247         }
10248         for(user = block->idominates; user; user = user->next) {
10249                 child = user->member;
10250                 if (child->idom != block) {
10251                         internal_error(state, block->first, "bad idom");
10252                 }
10253                 find_block_domf(state, child);
10254         }
10255         if (block->left && block->left->idom != block) {
10256                 domf_block(block, block->left);
10257         }
10258         if (block->right && block->right->idom != block) {
10259                 domf_block(block, block->right);
10260         }
10261         for(user = block->idominates; user; user = user->next) {
10262                 struct block_set *frontier;
10263                 child = user->member;
10264                 for(frontier = child->domfrontier; frontier; frontier = frontier->next) {
10265                         if (frontier->member->idom != block) {
10266                                 domf_block(block, frontier->member);
10267                         }
10268                 }
10269         }
10270 }
10271
10272 static void find_block_ipdomf(struct compile_state *state, struct block *block)
10273 {
10274         struct block *child;
10275         struct block_set *user;
10276         if (block->ipdomfrontier != 0) {
10277                 internal_error(state, block->first, "ipdomfrontier present?");
10278         }
10279         for(user = block->ipdominates; user; user = user->next) {
10280                 child = user->member;
10281                 if (child->ipdom != block) {
10282                         internal_error(state, block->first, "bad ipdom");
10283                 }
10284                 find_block_ipdomf(state, child);
10285         }
10286         if (block->left && block->left->ipdom != block) {
10287                 ipdomf_block(block, block->left);
10288         }
10289         if (block->right && block->right->ipdom != block) {
10290                 ipdomf_block(block, block->right);
10291         }
10292         for(user = block->idominates; user; user = user->next) {
10293                 struct block_set *frontier;
10294                 child = user->member;
10295                 for(frontier = child->ipdomfrontier; frontier; frontier = frontier->next) {
10296                         if (frontier->member->ipdom != block) {
10297                                 ipdomf_block(block, frontier->member);
10298                         }
10299                 }
10300         }
10301 }
10302
10303 static void print_dominated(
10304         struct compile_state *state, struct block *block, void *arg)
10305 {
10306         struct block_set *user;
10307         FILE *fp = arg;
10308
10309         fprintf(fp, "%d:", block->vertex);
10310         for(user = block->idominates; user; user = user->next) {
10311                 fprintf(fp, " %d", user->member->vertex);
10312                 if (user->member->idom != block) {
10313                         internal_error(state, user->member->first, "bad idom");
10314                 }
10315         }
10316         fprintf(fp,"\n");
10317 }
10318
10319 static void print_dominators(struct compile_state *state, FILE *fp)
10320 {
10321         fprintf(fp, "\ndominates\n");
10322         walk_blocks(state, print_dominated, fp);
10323 }
10324
10325
10326 static int print_frontiers(
10327         struct compile_state *state, struct block *block, int vertex)
10328 {
10329         struct block_set *user;
10330
10331         if (!block || (block->vertex != vertex + 1)) {
10332                 return vertex;
10333         }
10334         vertex += 1;
10335
10336         printf("%d:", block->vertex);
10337         for(user = block->domfrontier; user; user = user->next) {
10338                 printf(" %d", user->member->vertex);
10339         }
10340         printf("\n");
10341
10342         vertex = print_frontiers(state, block->left, vertex);
10343         vertex = print_frontiers(state, block->right, vertex);
10344         return vertex;
10345 }
10346 static void print_dominance_frontiers(struct compile_state *state)
10347 {
10348         printf("\ndominance frontiers\n");
10349         print_frontiers(state, state->first_block, 0);
10350         
10351 }
10352
10353 static void analyze_idominators(struct compile_state *state)
10354 {
10355         /* Find the immediate dominators */
10356         find_immediate_dominators(state);
10357         /* Find the dominance frontiers */
10358         find_block_domf(state, state->first_block);
10359         /* If debuging print the print what I have just found */
10360         if (state->debug & DEBUG_FDOMINATORS) {
10361                 print_dominators(state, stdout);
10362                 print_dominance_frontiers(state);
10363                 print_control_flow(state);
10364         }
10365 }
10366
10367
10368
10369 static void print_ipdominated(
10370         struct compile_state *state, struct block *block, void *arg)
10371 {
10372         struct block_set *user;
10373         FILE *fp = arg;
10374
10375         fprintf(fp, "%d:", block->vertex);
10376         for(user = block->ipdominates; user; user = user->next) {
10377                 fprintf(fp, " %d", user->member->vertex);
10378                 if (user->member->ipdom != block) {
10379                         internal_error(state, user->member->first, "bad ipdom");
10380                 }
10381         }
10382         fprintf(fp, "\n");
10383 }
10384
10385 static void print_ipdominators(struct compile_state *state, FILE *fp)
10386 {
10387         fprintf(fp, "\nipdominates\n");
10388         walk_blocks(state, print_ipdominated, fp);
10389 }
10390
10391 static int print_pfrontiers(
10392         struct compile_state *state, struct block *block, int vertex)
10393 {
10394         struct block_set *user;
10395
10396         if (!block || (block->vertex != vertex + 1)) {
10397                 return vertex;
10398         }
10399         vertex += 1;
10400
10401         printf("%d:", block->vertex);
10402         for(user = block->ipdomfrontier; user; user = user->next) {
10403                 printf(" %d", user->member->vertex);
10404         }
10405         printf("\n");
10406         for(user = block->use; user; user = user->next) {
10407                 vertex = print_pfrontiers(state, user->member, vertex);
10408         }
10409         return vertex;
10410 }
10411 static void print_ipdominance_frontiers(struct compile_state *state)
10412 {
10413         printf("\nipdominance frontiers\n");
10414         print_pfrontiers(state, state->last_block, 0);
10415         
10416 }
10417
10418 static void analyze_ipdominators(struct compile_state *state)
10419 {
10420         /* Find the post dominators */
10421         find_post_dominators(state);
10422         /* Find the control dependencies (post dominance frontiers) */
10423         find_block_ipdomf(state, state->last_block);
10424         /* If debuging print the print what I have just found */
10425         if (state->debug & DEBUG_RDOMINATORS) {
10426                 print_ipdominators(state, stdout);
10427                 print_ipdominance_frontiers(state);
10428                 print_control_flow(state);
10429         }
10430 }
10431
10432 static int bdominates(struct compile_state *state,
10433         struct block *dom, struct block *sub)
10434 {
10435         while(sub && (sub != dom)) {
10436                 sub = sub->idom;
10437         }
10438         return sub == dom;
10439 }
10440
10441 static int tdominates(struct compile_state *state,
10442         struct triple *dom, struct triple *sub)
10443 {
10444         struct block *bdom, *bsub;
10445         int result;
10446         bdom = block_of_triple(state, dom);
10447         bsub = block_of_triple(state, sub);
10448         if (bdom != bsub) {
10449                 result = bdominates(state, bdom, bsub);
10450         } 
10451         else {
10452                 struct triple *ins;
10453                 ins = sub;
10454                 while((ins != bsub->first) && (ins != dom)) {
10455                         ins = ins->prev;
10456                 }
10457                 result = (ins == dom);
10458         }
10459         return result;
10460 }
10461
10462 static void insert_phi_operations(struct compile_state *state)
10463 {
10464         size_t size;
10465         struct triple *first;
10466         int *has_already, *work;
10467         struct block *work_list, **work_list_tail;
10468         int iter;
10469         struct triple *var, *vnext;
10470
10471         size = sizeof(int) * (state->last_vertex + 1);
10472         has_already = xcmalloc(size, "has_already");
10473         work =        xcmalloc(size, "work");
10474         iter = 0;
10475
10476         first = RHS(state->main_function, 0);
10477         for(var = first->next; var != first ; var = vnext) {
10478                 struct block *block;
10479                 struct triple_set *user, *unext;
10480                 vnext = var->next;
10481                 if ((var->op != OP_ADECL) || !var->use) {
10482                         continue;
10483                 }
10484                 iter += 1;
10485                 work_list = 0;
10486                 work_list_tail = &work_list;
10487                 for(user = var->use; user; user = unext) {
10488                         unext = user->next;
10489                         if (user->member->op == OP_READ) {
10490                                 continue;
10491                         }
10492                         if (user->member->op != OP_WRITE) {
10493                                 internal_error(state, user->member, 
10494                                         "bad variable access");
10495                         }
10496                         block = user->member->u.block;
10497                         if (!block) {
10498                                 warning(state, user->member, "dead code");
10499                                 release_triple(state, user->member);
10500                                 continue;
10501                         }
10502                         if (work[block->vertex] >= iter) {
10503                                 continue;
10504                         }
10505                         work[block->vertex] = iter;
10506                         *work_list_tail = block;
10507                         block->work_next = 0;
10508                         work_list_tail = &block->work_next;
10509                 }
10510                 for(block = work_list; block; block = block->work_next) {
10511                         struct block_set *df;
10512                         for(df = block->domfrontier; df; df = df->next) {
10513                                 struct triple *phi;
10514                                 struct block *front;
10515                                 int in_edges;
10516                                 front = df->member;
10517
10518                                 if (has_already[front->vertex] >= iter) {
10519                                         continue;
10520                                 }
10521                                 /* Count how many edges flow into this block */
10522                                 in_edges = front->users;
10523                                 /* Insert a phi function for this variable */
10524                                 get_occurance(var->occurance);
10525                                 phi = alloc_triple(
10526                                         state, OP_PHI, var->type, -1, in_edges, 
10527                                         var->occurance);
10528                                 phi->u.block = front;
10529                                 MISC(phi, 0) = var;
10530                                 use_triple(var, phi);
10531                                 /* Insert the phi functions immediately after the label */
10532                                 insert_triple(state, front->first->next, phi);
10533                                 if (front->first == front->last) {
10534                                         front->last = front->first->next;
10535                                 }
10536                                 has_already[front->vertex] = iter;
10537
10538                                 /* If necessary plan to visit the basic block */
10539                                 if (work[front->vertex] >= iter) {
10540                                         continue;
10541                                 }
10542                                 work[front->vertex] = iter;
10543                                 *work_list_tail = front;
10544                                 front->work_next = 0;
10545                                 work_list_tail = &front->work_next;
10546                         }
10547                 }
10548         }
10549         xfree(has_already);
10550         xfree(work);
10551 }
10552
10553
10554 static int count_and_number_adecls(struct compile_state *state)
10555 {
10556         struct triple *first, *ins;
10557         int adecls = 0;
10558         first = RHS(state->main_function, 0);
10559         ins = first;
10560         do {
10561                 if (ins->op == OP_ADECL) {
10562                         adecls += 1;
10563                         ins->id = adecls;
10564                 }
10565                 ins = ins->next;
10566         } while(ins != first);
10567         return adecls;
10568 }
10569
10570 static struct triple *peek_triple(struct triple_set **stacks, struct triple *var)
10571 {
10572         struct triple_set *head;
10573         struct triple *top_val;
10574         top_val = 0;
10575         head = stacks[var->id];
10576         if (head) {
10577                 top_val = head->member;
10578         }
10579         return top_val;
10580 }
10581
10582 static void push_triple(struct triple_set **stacks, struct triple *var, struct triple *val)
10583 {
10584         struct triple_set *new;
10585         /* Append new to the head of the list,
10586          * it's the only sensible behavoir for a stack.
10587          */
10588         new = xcmalloc(sizeof(*new), "triple_set");
10589         new->member = val;
10590         new->next   = stacks[var->id];
10591         stacks[var->id] = new;
10592 }
10593
10594 static void pop_triple(struct triple_set **stacks, struct triple *var, struct triple *oldval)
10595 {
10596         struct triple_set *set, **ptr;
10597         ptr = &stacks[var->id];
10598         while(*ptr) {
10599                 set = *ptr;
10600                 if (set->member == oldval) {
10601                         *ptr = set->next;
10602                         xfree(set);
10603                         /* Only free one occurance from the stack */
10604                         return;
10605                 }
10606                 else {
10607                         ptr = &set->next;
10608                 }
10609         }
10610 }
10611
10612 /*
10613  * C(V)
10614  * S(V)
10615  */
10616 static void fixup_block_phi_variables(
10617         struct compile_state *state, struct triple_set **stacks, struct block *parent, struct block *block)
10618 {
10619         struct block_set *set;
10620         struct triple *ptr;
10621         int edge;
10622         if (!parent || !block)
10623                 return;
10624         /* Find the edge I am coming in on */
10625         edge = 0;
10626         for(set = block->use; set; set = set->next, edge++) {
10627                 if (set->member == parent) {
10628                         break;
10629                 }
10630         }
10631         if (!set) {
10632                 internal_error(state, 0, "phi input is not on a control predecessor");
10633         }
10634         for(ptr = block->first; ; ptr = ptr->next) {
10635                 if (ptr->op == OP_PHI) {
10636                         struct triple *var, *val, **slot;
10637                         var = MISC(ptr, 0);
10638                         if (!var) {
10639                                 internal_error(state, ptr, "no var???");
10640                         }
10641                         /* Find the current value of the variable */
10642                         val = peek_triple(stacks, var);
10643                         if (val && ((val->op == OP_WRITE) || (val->op == OP_READ))) {
10644                                 internal_error(state, val, "bad value in phi");
10645                         }
10646                         if (edge >= TRIPLE_RHS(ptr->sizes)) {
10647                                 internal_error(state, ptr, "edges > phi rhs");
10648                         }
10649                         slot = &RHS(ptr, edge);
10650                         if ((*slot != 0) && (*slot != val)) {
10651                                 internal_error(state, ptr, "phi already bound on this edge");
10652                         }
10653                         *slot = val;
10654                         use_triple(val, ptr);
10655                 }
10656                 if (ptr == block->last) {
10657                         break;
10658                 }
10659         }
10660 }
10661
10662
10663 static void rename_block_variables(
10664         struct compile_state *state, struct triple_set **stacks, struct block *block)
10665 {
10666         struct block_set *user;
10667         struct triple *ptr, *next, *last;
10668         int done;
10669         if (!block)
10670                 return;
10671         last = block->first;
10672         done = 0;
10673         for(ptr = block->first; !done; ptr = next) {
10674                 next = ptr->next;
10675                 if (ptr == block->last) {
10676                         done = 1;
10677                 }
10678                 /* RHS(A) */
10679                 if (ptr->op == OP_READ) {
10680                         struct triple *var, *val;
10681                         var = RHS(ptr, 0);
10682                         unuse_triple(var, ptr);
10683                         /* Find the current value of the variable */
10684                         val = peek_triple(stacks, var);
10685                         if (!val) {
10686                                 error(state, ptr, "variable used without being set");
10687                         }
10688                         if ((val->op == OP_WRITE) || (val->op == OP_READ)) {
10689                                 internal_error(state, val, "bad value in read");
10690                         }
10691                         propogate_use(state, ptr, val);
10692                         release_triple(state, ptr);
10693                         continue;
10694                 }
10695                 /* LHS(A) */
10696                 if (ptr->op == OP_WRITE) {
10697                         struct triple *var, *val, *tval;
10698                         var = RHS(ptr, 0);
10699                         tval = val = RHS(ptr, 1);
10700                         if ((val->op == OP_WRITE) || (val->op == OP_READ)) {
10701                                 internal_error(state, ptr, "bad value in write");
10702                         }
10703                         /* Insert a copy if the types differ */
10704                         if (!equiv_types(ptr->type, val->type)) {
10705                                 if (val->op == OP_INTCONST) {
10706                                         tval = pre_triple(state, ptr, OP_INTCONST, ptr->type, 0, 0);
10707                                         tval->u.cval = val->u.cval;
10708                                 }
10709                                 else {
10710                                         tval = pre_triple(state, ptr, OP_COPY, ptr->type, val, 0);
10711                                         use_triple(val, tval);
10712                                 }
10713                                 unuse_triple(val, ptr);
10714                                 RHS(ptr, 1) = tval;
10715                                 use_triple(tval, ptr);
10716                         }
10717                         propogate_use(state, ptr, tval);
10718                         unuse_triple(var, ptr);
10719                         /* Push OP_WRITE ptr->right onto a stack of variable uses */
10720                         push_triple(stacks, var, tval);
10721                 }
10722                 if (ptr->op == OP_PHI) {
10723                         struct triple *var;
10724                         var = MISC(ptr, 0);
10725                         /* Push OP_PHI onto a stack of variable uses */
10726                         push_triple(stacks, var, ptr);
10727                 }
10728                 last = ptr;
10729         }
10730         block->last = last;
10731
10732         /* Fixup PHI functions in the cf successors */
10733         fixup_block_phi_variables(state, stacks, block, block->left);
10734         fixup_block_phi_variables(state, stacks, block, block->right);
10735         /* rename variables in the dominated nodes */
10736         for(user = block->idominates; user; user = user->next) {
10737                 rename_block_variables(state, stacks, user->member);
10738         }
10739         /* pop the renamed variable stack */
10740         last = block->first;
10741         done = 0;
10742         for(ptr = block->first; !done ; ptr = next) {
10743                 next = ptr->next;
10744                 if (ptr == block->last) {
10745                         done = 1;
10746                 }
10747                 if (ptr->op == OP_WRITE) {
10748                         struct triple *var;
10749                         var = RHS(ptr, 0);
10750                         /* Pop OP_WRITE ptr->right from the stack of variable uses */
10751                         pop_triple(stacks, var, RHS(ptr, 1));
10752                         release_triple(state, ptr);
10753                         continue;
10754                 }
10755                 if (ptr->op == OP_PHI) {
10756                         struct triple *var;
10757                         var = MISC(ptr, 0);
10758                         /* Pop OP_WRITE ptr->right from the stack of variable uses */
10759                         pop_triple(stacks, var, ptr);
10760                 }
10761                 last = ptr;
10762         }
10763         block->last = last;
10764 }
10765
10766 static void prune_block_variables(struct compile_state *state,
10767         struct block *block)
10768 {
10769         struct block_set *user;
10770         struct triple *next, *last, *ptr;
10771         int done;
10772         last = block->first;
10773         done = 0;
10774         for(ptr = block->first; !done; ptr = next) {
10775                 next = ptr->next;
10776                 if (ptr == block->last) {
10777                         done = 1;
10778                 }
10779                 if (ptr->op == OP_ADECL) {
10780                         struct triple_set *user, *next;
10781                         for(user = ptr->use; user; user = next) {
10782                                 struct triple *use;
10783                                 next = user->next;
10784                                 use = user->member;
10785                                 if (use->op != OP_PHI) {
10786                                         internal_error(state, use, "decl still used");
10787                                 }
10788                                 if (MISC(use, 0) != ptr) {
10789                                         internal_error(state, use, "bad phi use of decl");
10790                                 }
10791                                 unuse_triple(ptr, use);
10792                                 MISC(use, 0) = 0;
10793                         }
10794                         release_triple(state, ptr);
10795                         continue;
10796                 }
10797                 last = ptr;
10798         }
10799         block->last = last;
10800         for(user = block->idominates; user; user = user->next) {
10801                 prune_block_variables(state, user->member);
10802         }
10803 }
10804
10805 struct phi_triple {
10806         struct triple *phi;
10807         unsigned orig_id;
10808         int alive;
10809 };
10810
10811 static void keep_phi(struct compile_state *state, struct phi_triple *live, struct triple *phi)
10812 {
10813         struct triple **slot;
10814         int zrhs, i;
10815         if (live[phi->id].alive) {
10816                 return;
10817         }
10818         live[phi->id].alive = 1;
10819         zrhs = TRIPLE_RHS(phi->sizes);
10820         slot = &RHS(phi, 0);
10821         for(i = 0; i < zrhs; i++) {
10822                 struct triple *used;
10823                 used = slot[i];
10824                 if (used && (used->op == OP_PHI)) {
10825                         keep_phi(state, live, used);
10826                 }
10827         }
10828 }
10829
10830 static void prune_unused_phis(struct compile_state *state)
10831 {
10832         struct triple *first, *phi;
10833         struct phi_triple *live;
10834         int phis, i;
10835         
10836
10837         /* Find the first instruction */
10838         first = RHS(state->main_function, 0);
10839
10840         /* Count how many phi functions I need to process */
10841         phis = 0;
10842         for(phi = first->next; phi != first; phi = phi->next) {
10843                 if (phi->op == OP_PHI) {
10844                         phis += 1;
10845                 }
10846         }
10847         
10848         /* Mark them all dead */
10849         live = xcmalloc(sizeof(*live) * (phis + 1), "phi_triple");
10850         phis = 0;
10851         for(phi = first->next; phi != first; phi = phi->next) {
10852                 if (phi->op != OP_PHI) {
10853                         continue;
10854                 }
10855                 live[phis].alive   = 0;
10856                 live[phis].orig_id = phi->id;
10857                 live[phis].phi     = phi;
10858                 phi->id = phis;
10859                 phis += 1;
10860         }
10861         
10862         /* Mark phis alive that are used by non phis */
10863         for(i = 0; i < phis; i++) {
10864                 struct triple_set *set;
10865                 for(set = live[i].phi->use; !live[i].alive && set; set = set->next) {
10866                         if (set->member->op != OP_PHI) {
10867                                 keep_phi(state, live, live[i].phi);
10868                                 break;
10869                         }
10870                 }
10871         }
10872
10873         /* Delete the extraneous phis */
10874         for(i = 0; i < phis; i++) {
10875                 struct triple **slot;
10876                 int zrhs, j;
10877                 if (!live[i].alive) {
10878                         release_triple(state, live[i].phi);
10879                         continue;
10880                 }
10881                 phi = live[i].phi;
10882                 slot = &RHS(phi, 0);
10883                 zrhs = TRIPLE_RHS(phi->sizes);
10884                 for(j = 0; j < zrhs; j++) {
10885                         if(!slot[j]) {
10886                                 error(state, phi, "variable not set on all paths to use");
10887                         }
10888                 }
10889         }
10890         xfree(live);
10891 }
10892
10893
10894 static void transform_to_ssa_form(struct compile_state *state)
10895 {
10896         struct triple_set **stacks;
10897         int adecls;
10898         insert_phi_operations(state);
10899 #if 0
10900         printf("@%s:%d\n", __FILE__, __LINE__);
10901         print_blocks(state, stdout);
10902 #endif
10903
10904         /* Allocate stacks for the Variables */
10905         adecls = count_and_number_adecls(state);
10906         stacks = xcmalloc(sizeof(stacks[0])*(adecls + 1), "adecl stacks");
10907         rename_block_variables(state, stacks, state->first_block);
10908         xfree(stacks);
10909
10910         prune_block_variables(state, state->first_block);
10911
10912 #if 1
10913         prune_unused_phis(state);
10914 #endif
10915
10916 }
10917
10918
10919 static void clear_vertex(
10920         struct compile_state *state, struct block *block, void *arg)
10921 {
10922         block->vertex = 0;
10923 }
10924
10925 static void mark_live_block(
10926         struct compile_state *state, struct block *block, int *next_vertex)
10927 {
10928         /* See if this is a block that has not been marked */
10929         if (block->vertex != 0) {
10930                 return;
10931         }
10932         block->vertex = *next_vertex;
10933         *next_vertex += 1;
10934         if (triple_is_branch(state, block->last)) {
10935                 struct triple **targ;
10936                 targ = triple_targ(state, block->last, 0);
10937                 for(; targ; targ = triple_targ(state, block->last, targ)) {
10938                         if (!*targ) {
10939                                 continue;
10940                         }
10941                         if (!triple_stores_block(state, *targ)) {
10942                                 internal_error(state, 0, "bad targ");
10943                         }
10944                         mark_live_block(state, (*targ)->u.block, next_vertex);
10945                 }
10946         }
10947         else if (block->last->next != RHS(state->main_function, 0)) {
10948                 struct triple *ins;
10949                 ins = block->last->next;
10950                 if (!triple_stores_block(state, ins)) {
10951                         internal_error(state, 0, "bad block start");
10952                 }
10953                 mark_live_block(state, ins->u.block, next_vertex);
10954         }
10955 }
10956
10957 static void transform_from_ssa_form(struct compile_state *state)
10958 {
10959         /* To get out of ssa form we insert moves on the incoming
10960          * edges to blocks containting phi functions.
10961          */
10962         struct triple *first;
10963         struct triple *phi, *next;
10964         int next_vertex;
10965
10966         /* Walk the control flow to see which blocks remain alive */
10967         walk_blocks(state, clear_vertex, 0);
10968         next_vertex = 1;
10969         mark_live_block(state, state->first_block, &next_vertex);
10970
10971         /* Walk all of the operations to find the phi functions */
10972         first = RHS(state->main_function, 0);
10973         for(phi = first->next; phi != first ; phi = next) {
10974                 struct block_set *set;
10975                 struct block *block;
10976                 struct triple **slot;
10977                 struct triple *var, *read;
10978                 struct triple_set *use, *use_next;
10979                 int edge, used;
10980                 next = phi->next;
10981                 if (phi->op != OP_PHI) {
10982                         continue;
10983                 }
10984                 block = phi->u.block;
10985                 slot  = &RHS(phi, 0);
10986
10987                 /* Forget uses from code in dead blocks */
10988                 for(use = phi->use; use; use = use_next) {
10989                         struct block *ublock;
10990                         struct triple **expr;
10991                         use_next = use->next;
10992                         ublock = block_of_triple(state, use->member);
10993                         if ((use->member == phi) || (ublock->vertex != 0)) {
10994                                 continue;
10995                         }
10996                         expr = triple_rhs(state, use->member, 0);
10997                         for(; expr; expr = triple_rhs(state, use->member, expr)) {
10998                                 if (*expr == phi) {
10999                                         *expr = 0;
11000                                 }
11001                         }
11002                         unuse_triple(phi, use->member);
11003                 }
11004
11005 #warning "CHECK_ME does the OP_ADECL need to be placed somewhere that dominates all of the incoming phi edges?"
11006                 /* A variable to replace the phi function */
11007                 var = post_triple(state, phi, OP_ADECL, phi->type, 0,0);
11008                 /* A read of the single value that is set into the variable */
11009                 read = post_triple(state, var, OP_READ, phi->type, var, 0);
11010                 use_triple(var, read);
11011
11012                 /* Replaces uses of the phi with variable reads */
11013                 propogate_use(state, phi, read);
11014
11015                 /* Walk all of the incoming edges/blocks and insert moves.
11016                  */
11017                 for(edge = 0, set = block->use; set; set = set->next, edge++) {
11018                         struct block *eblock;
11019                         struct triple *move;
11020                         struct triple *val, *base;
11021                         eblock = set->member;
11022                         val = slot[edge];
11023                         slot[edge] = 0;
11024                         unuse_triple(val, phi);
11025
11026                         if (!val || (val == &zero_triple) ||
11027                                 (block->vertex == 0) || (eblock->vertex == 0) ||
11028                                 (val == phi) || (val == read)) {
11029                                 continue;
11030                         }
11031                         
11032                         /* Make certain the write is placed in the edge block... */
11033                         base = eblock->first;
11034                         if (block_of_triple(state, val) == eblock) {
11035                                 base = val;
11036                         }
11037                         move = post_triple(state, base, OP_WRITE, phi->type, var, val);
11038                         use_triple(val, move);
11039                         use_triple(var, move);
11040                 }               
11041                 /* See if there are any writers of var */
11042                 used = 0;
11043                 for(use = var->use; use; use = use->next) {
11044                         if ((use->member->op == OP_WRITE) &&
11045                                 (RHS(use->member, 0) == var)) {
11046                                 used = 1;
11047                         }
11048                 }
11049                 /* If var is not used free it */
11050                 if (!used) {
11051                         unuse_triple(var, read);
11052                         free_triple(state, read);
11053                         free_triple(state, var);
11054                 }
11055
11056                 /* Release the phi function */
11057                 release_triple(state, phi);
11058         }
11059         
11060 }
11061
11062
11063 /* 
11064  * Register conflict resolution
11065  * =========================================================
11066  */
11067
11068 static struct reg_info find_def_color(
11069         struct compile_state *state, struct triple *def)
11070 {
11071         struct triple_set *set;
11072         struct reg_info info;
11073         info.reg = REG_UNSET;
11074         info.regcm = 0;
11075         if (!triple_is_def(state, def)) {
11076                 return info;
11077         }
11078         info = arch_reg_lhs(state, def, 0);
11079         if (info.reg >= MAX_REGISTERS) {
11080                 info.reg = REG_UNSET;
11081         }
11082         for(set = def->use; set; set = set->next) {
11083                 struct reg_info tinfo;
11084                 int i;
11085                 i = find_rhs_use(state, set->member, def);
11086                 if (i < 0) {
11087                         continue;
11088                 }
11089                 tinfo = arch_reg_rhs(state, set->member, i);
11090                 if (tinfo.reg >= MAX_REGISTERS) {
11091                         tinfo.reg = REG_UNSET;
11092                 }
11093                 if ((tinfo.reg != REG_UNSET) && 
11094                         (info.reg != REG_UNSET) &&
11095                         (tinfo.reg != info.reg)) {
11096                         internal_error(state, def, "register conflict");
11097                 }
11098                 if ((info.regcm & tinfo.regcm) == 0) {
11099                         internal_error(state, def, "regcm conflict %x & %x == 0",
11100                                 info.regcm, tinfo.regcm);
11101                 }
11102                 if (info.reg == REG_UNSET) {
11103                         info.reg = tinfo.reg;
11104                 }
11105                 info.regcm &= tinfo.regcm;
11106         }
11107         if (info.reg >= MAX_REGISTERS) {
11108                 internal_error(state, def, "register out of range");
11109         }
11110         return info;
11111 }
11112
11113 static struct reg_info find_lhs_pre_color(
11114         struct compile_state *state, struct triple *ins, int index)
11115 {
11116         struct reg_info info;
11117         int zlhs, zrhs, i;
11118         zrhs = TRIPLE_RHS(ins->sizes);
11119         zlhs = TRIPLE_LHS(ins->sizes);
11120         if (!zlhs && triple_is_def(state, ins)) {
11121                 zlhs = 1;
11122         }
11123         if (index >= zlhs) {
11124                 internal_error(state, ins, "Bad lhs %d", index);
11125         }
11126         info = arch_reg_lhs(state, ins, index);
11127         for(i = 0; i < zrhs; i++) {
11128                 struct reg_info rinfo;
11129                 rinfo = arch_reg_rhs(state, ins, i);
11130                 if ((info.reg == rinfo.reg) &&
11131                         (rinfo.reg >= MAX_REGISTERS)) {
11132                         struct reg_info tinfo;
11133                         tinfo = find_lhs_pre_color(state, RHS(ins, index), 0);
11134                         info.reg = tinfo.reg;
11135                         info.regcm &= tinfo.regcm;
11136                         break;
11137                 }
11138         }
11139         if (info.reg >= MAX_REGISTERS) {
11140                 info.reg = REG_UNSET;
11141         }
11142         return info;
11143 }
11144
11145 static struct reg_info find_rhs_post_color(
11146         struct compile_state *state, struct triple *ins, int index);
11147
11148 static struct reg_info find_lhs_post_color(
11149         struct compile_state *state, struct triple *ins, int index)
11150 {
11151         struct triple_set *set;
11152         struct reg_info info;
11153         struct triple *lhs;
11154 #if DEBUG_TRIPLE_COLOR
11155         fprintf(stderr, "find_lhs_post_color(%p, %d)\n",
11156                 ins, index);
11157 #endif
11158         if ((index == 0) && triple_is_def(state, ins)) {
11159                 lhs = ins;
11160         }
11161         else if (index < TRIPLE_LHS(ins->sizes)) {
11162                 lhs = LHS(ins, index);
11163         }
11164         else {
11165                 internal_error(state, ins, "Bad lhs %d", index);
11166                 lhs = 0;
11167         }
11168         info = arch_reg_lhs(state, ins, index);
11169         if (info.reg >= MAX_REGISTERS) {
11170                 info.reg = REG_UNSET;
11171         }
11172         for(set = lhs->use; set; set = set->next) {
11173                 struct reg_info rinfo;
11174                 struct triple *user;
11175                 int zrhs, i;
11176                 user = set->member;
11177                 zrhs = TRIPLE_RHS(user->sizes);
11178                 for(i = 0; i < zrhs; i++) {
11179                         if (RHS(user, i) != lhs) {
11180                                 continue;
11181                         }
11182                         rinfo = find_rhs_post_color(state, user, i);
11183                         if ((info.reg != REG_UNSET) &&
11184                                 (rinfo.reg != REG_UNSET) &&
11185                                 (info.reg != rinfo.reg)) {
11186                                 internal_error(state, ins, "register conflict");
11187                         }
11188                         if ((info.regcm & rinfo.regcm) == 0) {
11189                                 internal_error(state, ins, "regcm conflict %x & %x == 0",
11190                                         info.regcm, rinfo.regcm);
11191                         }
11192                         if (info.reg == REG_UNSET) {
11193                                 info.reg = rinfo.reg;
11194                         }
11195                         info.regcm &= rinfo.regcm;
11196                 }
11197         }
11198 #if DEBUG_TRIPLE_COLOR
11199         fprintf(stderr, "find_lhs_post_color(%p, %d) -> ( %d, %x)\n",
11200                 ins, index, info.reg, info.regcm);
11201 #endif
11202         return info;
11203 }
11204
11205 static struct reg_info find_rhs_post_color(
11206         struct compile_state *state, struct triple *ins, int index)
11207 {
11208         struct reg_info info, rinfo;
11209         int zlhs, i;
11210 #if DEBUG_TRIPLE_COLOR
11211         fprintf(stderr, "find_rhs_post_color(%p, %d)\n",
11212                 ins, index);
11213 #endif
11214         rinfo = arch_reg_rhs(state, ins, index);
11215         zlhs = TRIPLE_LHS(ins->sizes);
11216         if (!zlhs && triple_is_def(state, ins)) {
11217                 zlhs = 1;
11218         }
11219         info = rinfo;
11220         if (info.reg >= MAX_REGISTERS) {
11221                 info.reg = REG_UNSET;
11222         }
11223         for(i = 0; i < zlhs; i++) {
11224                 struct reg_info linfo;
11225                 linfo = arch_reg_lhs(state, ins, i);
11226                 if ((linfo.reg == rinfo.reg) &&
11227                         (linfo.reg >= MAX_REGISTERS)) {
11228                         struct reg_info tinfo;
11229                         tinfo = find_lhs_post_color(state, ins, i);
11230                         if (tinfo.reg >= MAX_REGISTERS) {
11231                                 tinfo.reg = REG_UNSET;
11232                         }
11233                         info.regcm &= linfo.regcm;
11234                         info.regcm &= tinfo.regcm;
11235                         if (info.reg != REG_UNSET) {
11236                                 internal_error(state, ins, "register conflict");
11237                         }
11238                         if (info.regcm == 0) {
11239                                 internal_error(state, ins, "regcm conflict");
11240                         }
11241                         info.reg = tinfo.reg;
11242                 }
11243         }
11244 #if DEBUG_TRIPLE_COLOR
11245         fprintf(stderr, "find_rhs_post_color(%p, %d) -> ( %d, %x)\n",
11246                 ins, index, info.reg, info.regcm);
11247 #endif
11248         return info;
11249 }
11250
11251 static struct reg_info find_lhs_color(
11252         struct compile_state *state, struct triple *ins, int index)
11253 {
11254         struct reg_info pre, post, info;
11255 #if DEBUG_TRIPLE_COLOR
11256         fprintf(stderr, "find_lhs_color(%p, %d)\n",
11257                 ins, index);
11258 #endif
11259         pre = find_lhs_pre_color(state, ins, index);
11260         post = find_lhs_post_color(state, ins, index);
11261         if ((pre.reg != post.reg) &&
11262                 (pre.reg != REG_UNSET) &&
11263                 (post.reg != REG_UNSET)) {
11264                 internal_error(state, ins, "register conflict");
11265         }
11266         info.regcm = pre.regcm & post.regcm;
11267         info.reg = pre.reg;
11268         if (info.reg == REG_UNSET) {
11269                 info.reg = post.reg;
11270         }
11271 #if DEBUG_TRIPLE_COLOR
11272         fprintf(stderr, "find_lhs_color(%p, %d) -> ( %d, %x) ... (%d, %x) (%d, %x)\n",
11273                 ins, index, info.reg, info.regcm,
11274                 pre.reg, pre.regcm, post.reg, post.regcm);
11275 #endif
11276         return info;
11277 }
11278
11279 static struct triple *post_copy(struct compile_state *state, struct triple *ins)
11280 {
11281         struct triple_set *entry, *next;
11282         struct triple *out;
11283         struct reg_info info, rinfo;
11284
11285         info = arch_reg_lhs(state, ins, 0);
11286         out = post_triple(state, ins, OP_COPY, ins->type, ins, 0);
11287         use_triple(RHS(out, 0), out);
11288         /* Get the users of ins to use out instead */
11289         for(entry = ins->use; entry; entry = next) {
11290                 int i;
11291                 next = entry->next;
11292                 if (entry->member == out) {
11293                         continue;
11294                 }
11295                 i = find_rhs_use(state, entry->member, ins);
11296                 if (i < 0) {
11297                         continue;
11298                 }
11299                 rinfo = arch_reg_rhs(state, entry->member, i);
11300                 if ((info.reg == REG_UNNEEDED) && (rinfo.reg == REG_UNNEEDED)) {
11301                         continue;
11302                 }
11303                 replace_rhs_use(state, ins, out, entry->member);
11304         }
11305         transform_to_arch_instruction(state, out);
11306         return out;
11307 }
11308
11309 static struct triple *typed_pre_copy(
11310         struct compile_state *state, struct type *type, struct triple *ins, int index)
11311 {
11312         /* Carefully insert enough operations so that I can
11313          * enter any operation with a GPR32.
11314          */
11315         struct triple *in;
11316         struct triple **expr;
11317         unsigned classes;
11318         struct reg_info info;
11319         if (ins->op == OP_PHI) {
11320                 internal_error(state, ins, "pre_copy on a phi?");
11321         }
11322         classes = arch_type_to_regcm(state, type);
11323         info = arch_reg_rhs(state, ins, index);
11324         expr = &RHS(ins, index);
11325         if ((info.regcm & classes) == 0) {
11326                 internal_error(state, ins, "pre_copy with no register classes");
11327         }
11328         in = pre_triple(state, ins, OP_COPY, type, *expr, 0);
11329         unuse_triple(*expr, ins);
11330         *expr = in;
11331         use_triple(RHS(in, 0), in);
11332         use_triple(in, ins);
11333         transform_to_arch_instruction(state, in);
11334         return in;
11335         
11336 }
11337 static struct triple *pre_copy(
11338         struct compile_state *state, struct triple *ins, int index)
11339 {
11340         return typed_pre_copy(state, RHS(ins, index)->type, ins, index);
11341 }
11342
11343
11344 static void insert_copies_to_phi(struct compile_state *state)
11345 {
11346         /* To get out of ssa form we insert moves on the incoming
11347          * edges to blocks containting phi functions.
11348          */
11349         struct triple *first;
11350         struct triple *phi;
11351
11352         /* Walk all of the operations to find the phi functions */
11353         first = RHS(state->main_function, 0);
11354         for(phi = first->next; phi != first ; phi = phi->next) {
11355                 struct block_set *set;
11356                 struct block *block;
11357                 struct triple **slot, *copy;
11358                 int edge;
11359                 if (phi->op != OP_PHI) {
11360                         continue;
11361                 }
11362                 phi->id |= TRIPLE_FLAG_POST_SPLIT;
11363                 block = phi->u.block;
11364                 slot  = &RHS(phi, 0);
11365                 /* Phi's that feed into mandatory live range joins
11366                  * cause nasty complications.  Insert a copy of
11367                  * the phi value so I never have to deal with
11368                  * that in the rest of the code.
11369                  */
11370                 copy = post_copy(state, phi);
11371                 copy->id |= TRIPLE_FLAG_PRE_SPLIT;
11372                 /* Walk all of the incoming edges/blocks and insert moves.
11373                  */
11374                 for(edge = 0, set = block->use; set; set = set->next, edge++) {
11375                         struct block *eblock;
11376                         struct triple *move;
11377                         struct triple *val;
11378                         struct triple *ptr;
11379                         eblock = set->member;
11380                         val = slot[edge];
11381
11382                         if (val == phi) {
11383                                 continue;
11384                         }
11385
11386                         get_occurance(val->occurance);
11387                         move = build_triple(state, OP_COPY, phi->type, val, 0,
11388                                 val->occurance);
11389                         move->u.block = eblock;
11390                         move->id |= TRIPLE_FLAG_PRE_SPLIT;
11391                         use_triple(val, move);
11392                         
11393                         slot[edge] = move;
11394                         unuse_triple(val, phi);
11395                         use_triple(move, phi);
11396
11397                         /* Walk up the dominator tree until I have found the appropriate block */
11398                         while(eblock && !tdominates(state, val, eblock->last)) {
11399                                 eblock = eblock->idom;
11400                         }
11401                         if (!eblock) {
11402                                 internal_error(state, phi, "Cannot find block dominated by %p",
11403                                         val);
11404                         }
11405
11406                         /* Walk through the block backwards to find
11407                          * an appropriate location for the OP_COPY.
11408                          */
11409                         for(ptr = eblock->last; ptr != eblock->first; ptr = ptr->prev) {
11410                                 struct triple **expr;
11411                                 if ((ptr == phi) || (ptr == val)) {
11412                                         goto out;
11413                                 }
11414                                 expr = triple_rhs(state, ptr, 0);
11415                                 for(;expr; expr = triple_rhs(state, ptr, expr)) {
11416                                         if ((*expr) == phi) {
11417                                                 goto out;
11418                                         }
11419                                 }
11420                         }
11421                 out:
11422                         if (triple_is_branch(state, ptr)) {
11423                                 internal_error(state, ptr,
11424                                         "Could not insert write to phi");
11425                         }
11426                         insert_triple(state, ptr->next, move);
11427                         if (eblock->last == ptr) {
11428                                 eblock->last = move;
11429                         }
11430                         transform_to_arch_instruction(state, move);
11431                 }
11432         }
11433 }
11434
11435 struct triple_reg_set {
11436         struct triple_reg_set *next;
11437         struct triple *member;
11438         struct triple *new;
11439 };
11440
11441 struct reg_block {
11442         struct block *block;
11443         struct triple_reg_set *in;
11444         struct triple_reg_set *out;
11445         int vertex;
11446 };
11447
11448 static int do_triple_set(struct triple_reg_set **head, 
11449         struct triple *member, struct triple *new_member)
11450 {
11451         struct triple_reg_set **ptr, *new;
11452         if (!member)
11453                 return 0;
11454         ptr = head;
11455         while(*ptr) {
11456                 if ((*ptr)->member == member) {
11457                         return 0;
11458                 }
11459                 ptr = &(*ptr)->next;
11460         }
11461         new = xcmalloc(sizeof(*new), "triple_set");
11462         new->member = member;
11463         new->new    = new_member;
11464         new->next   = *head;
11465         *head       = new;
11466         return 1;
11467 }
11468
11469 static void do_triple_unset(struct triple_reg_set **head, struct triple *member)
11470 {
11471         struct triple_reg_set *entry, **ptr;
11472         ptr = head;
11473         while(*ptr) {
11474                 entry = *ptr;
11475                 if (entry->member == member) {
11476                         *ptr = entry->next;
11477                         xfree(entry);
11478                         return;
11479                 }
11480                 else {
11481                         ptr = &entry->next;
11482                 }
11483         }
11484 }
11485
11486 static int in_triple(struct reg_block *rb, struct triple *in)
11487 {
11488         return do_triple_set(&rb->in, in, 0);
11489 }
11490 static void unin_triple(struct reg_block *rb, struct triple *unin)
11491 {
11492         do_triple_unset(&rb->in, unin);
11493 }
11494
11495 static int out_triple(struct reg_block *rb, struct triple *out)
11496 {
11497         return do_triple_set(&rb->out, out, 0);
11498 }
11499 static void unout_triple(struct reg_block *rb, struct triple *unout)
11500 {
11501         do_triple_unset(&rb->out, unout);
11502 }
11503
11504 static int initialize_regblock(struct reg_block *blocks,
11505         struct block *block, int vertex)
11506 {
11507         struct block_set *user;
11508         if (!block || (blocks[block->vertex].block == block)) {
11509                 return vertex;
11510         }
11511         vertex += 1;
11512         /* Renumber the blocks in a convinient fashion */
11513         block->vertex = vertex;
11514         blocks[vertex].block    = block;
11515         blocks[vertex].vertex   = vertex;
11516         for(user = block->use; user; user = user->next) {
11517                 vertex = initialize_regblock(blocks, user->member, vertex);
11518         }
11519         return vertex;
11520 }
11521
11522 static int phi_in(struct compile_state *state, struct reg_block *blocks,
11523         struct reg_block *rb, struct block *suc)
11524 {
11525         /* Read the conditional input set of a successor block
11526          * (i.e. the input to the phi nodes) and place it in the
11527          * current blocks output set.
11528          */
11529         struct block_set *set;
11530         struct triple *ptr;
11531         int edge;
11532         int done, change;
11533         change = 0;
11534         /* Find the edge I am coming in on */
11535         for(edge = 0, set = suc->use; set; set = set->next, edge++) {
11536                 if (set->member == rb->block) {
11537                         break;
11538                 }
11539         }
11540         if (!set) {
11541                 internal_error(state, 0, "Not coming on a control edge?");
11542         }
11543         for(done = 0, ptr = suc->first; !done; ptr = ptr->next) {
11544                 struct triple **slot, *expr, *ptr2;
11545                 int out_change, done2;
11546                 done = (ptr == suc->last);
11547                 if (ptr->op != OP_PHI) {
11548                         continue;
11549                 }
11550                 slot = &RHS(ptr, 0);
11551                 expr = slot[edge];
11552                 out_change = out_triple(rb, expr);
11553                 if (!out_change) {
11554                         continue;
11555                 }
11556                 /* If we don't define the variable also plast it
11557                  * in the current blocks input set.
11558                  */
11559                 ptr2 = rb->block->first;
11560                 for(done2 = 0; !done2; ptr2 = ptr2->next) {
11561                         if (ptr2 == expr) {
11562                                 break;
11563                         }
11564                         done2 = (ptr2 == rb->block->last);
11565                 }
11566                 if (!done2) {
11567                         continue;
11568                 }
11569                 change |= in_triple(rb, expr);
11570         }
11571         return change;
11572 }
11573
11574 static int reg_in(struct compile_state *state, struct reg_block *blocks,
11575         struct reg_block *rb, struct block *suc)
11576 {
11577         struct triple_reg_set *in_set;
11578         int change;
11579         change = 0;
11580         /* Read the input set of a successor block
11581          * and place it in the current blocks output set.
11582          */
11583         in_set = blocks[suc->vertex].in;
11584         for(; in_set; in_set = in_set->next) {
11585                 int out_change, done;
11586                 struct triple *first, *last, *ptr;
11587                 out_change = out_triple(rb, in_set->member);
11588                 if (!out_change) {
11589                         continue;
11590                 }
11591                 /* If we don't define the variable also place it
11592                  * in the current blocks input set.
11593                  */
11594                 first = rb->block->first;
11595                 last = rb->block->last;
11596                 done = 0;
11597                 for(ptr = first; !done; ptr = ptr->next) {
11598                         if (ptr == in_set->member) {
11599                                 break;
11600                         }
11601                         done = (ptr == last);
11602                 }
11603                 if (!done) {
11604                         continue;
11605                 }
11606                 change |= in_triple(rb, in_set->member);
11607         }
11608         change |= phi_in(state, blocks, rb, suc);
11609         return change;
11610 }
11611
11612
11613 static int use_in(struct compile_state *state, struct reg_block *rb)
11614 {
11615         /* Find the variables we use but don't define and add
11616          * it to the current blocks input set.
11617          */
11618 #warning "FIXME is this O(N^2) algorithm bad?"
11619         struct block *block;
11620         struct triple *ptr;
11621         int done;
11622         int change;
11623         block = rb->block;
11624         change = 0;
11625         for(done = 0, ptr = block->last; !done; ptr = ptr->prev) {
11626                 struct triple **expr;
11627                 done = (ptr == block->first);
11628                 /* The variable a phi function uses depends on the
11629                  * control flow, and is handled in phi_in, not
11630                  * here.
11631                  */
11632                 if (ptr->op == OP_PHI) {
11633                         continue;
11634                 }
11635                 expr = triple_rhs(state, ptr, 0);
11636                 for(;expr; expr = triple_rhs(state, ptr, expr)) {
11637                         struct triple *rhs, *test;
11638                         int tdone;
11639                         rhs = *expr;
11640                         if (!rhs) {
11641                                 continue;
11642                         }
11643                         /* See if rhs is defined in this block */
11644                         for(tdone = 0, test = ptr; !tdone; test = test->prev) {
11645                                 tdone = (test == block->first);
11646                                 if (test == rhs) {
11647                                         rhs = 0;
11648                                         break;
11649                                 }
11650                         }
11651                         /* If I still have a valid rhs add it to in */
11652                         change |= in_triple(rb, rhs);
11653                 }
11654         }
11655         return change;
11656 }
11657
11658 static struct reg_block *compute_variable_lifetimes(
11659         struct compile_state *state)
11660 {
11661         struct reg_block *blocks;
11662         int change;
11663         blocks = xcmalloc(
11664                 sizeof(*blocks)*(state->last_vertex + 1), "reg_block");
11665         initialize_regblock(blocks, state->last_block, 0);
11666         do {
11667                 int i;
11668                 change = 0;
11669                 for(i = 1; i <= state->last_vertex; i++) {
11670                         struct reg_block *rb;
11671                         rb = &blocks[i];
11672                         /* Add the left successor's input set to in */
11673                         if (rb->block->left) {
11674                                 change |= reg_in(state, blocks, rb, rb->block->left);
11675                         }
11676                         /* Add the right successor's input set to in */
11677                         if ((rb->block->right) && 
11678                                 (rb->block->right != rb->block->left)) {
11679                                 change |= reg_in(state, blocks, rb, rb->block->right);
11680                         }
11681                         /* Add use to in... */
11682                         change |= use_in(state, rb);
11683                 }
11684         } while(change);
11685         return blocks;
11686 }
11687
11688 static void free_variable_lifetimes(
11689         struct compile_state *state, struct reg_block *blocks)
11690 {
11691         int i;
11692         /* free in_set && out_set on each block */
11693         for(i = 1; i <= state->last_vertex; i++) {
11694                 struct triple_reg_set *entry, *next;
11695                 struct reg_block *rb;
11696                 rb = &blocks[i];
11697                 for(entry = rb->in; entry ; entry = next) {
11698                         next = entry->next;
11699                         do_triple_unset(&rb->in, entry->member);
11700                 }
11701                 for(entry = rb->out; entry; entry = next) {
11702                         next = entry->next;
11703                         do_triple_unset(&rb->out, entry->member);
11704                 }
11705         }
11706         xfree(blocks);
11707
11708 }
11709
11710 typedef void (*wvl_cb_t)(
11711         struct compile_state *state, 
11712         struct reg_block *blocks, struct triple_reg_set *live, 
11713         struct reg_block *rb, struct triple *ins, void *arg);
11714
11715 static void walk_variable_lifetimes(struct compile_state *state,
11716         struct reg_block *blocks, wvl_cb_t cb, void *arg)
11717 {
11718         int i;
11719         
11720         for(i = 1; i <= state->last_vertex; i++) {
11721                 struct triple_reg_set *live;
11722                 struct triple_reg_set *entry, *next;
11723                 struct triple *ptr, *prev;
11724                 struct reg_block *rb;
11725                 struct block *block;
11726                 int done;
11727
11728                 /* Get the blocks */
11729                 rb = &blocks[i];
11730                 block = rb->block;
11731
11732                 /* Copy out into live */
11733                 live = 0;
11734                 for(entry = rb->out; entry; entry = next) {
11735                         next = entry->next;
11736                         do_triple_set(&live, entry->member, entry->new);
11737                 }
11738                 /* Walk through the basic block calculating live */
11739                 for(done = 0, ptr = block->last; !done; ptr = prev) {
11740                         struct triple **expr;
11741
11742                         prev = ptr->prev;
11743                         done = (ptr == block->first);
11744
11745                         /* Ensure the current definition is in live */
11746                         if (triple_is_def(state, ptr)) {
11747                                 do_triple_set(&live, ptr, 0);
11748                         }
11749
11750                         /* Inform the callback function of what is
11751                          * going on.
11752                          */
11753                          cb(state, blocks, live, rb, ptr, arg);
11754                         
11755                         /* Remove the current definition from live */
11756                         do_triple_unset(&live, ptr);
11757
11758                         /* Add the current uses to live.
11759                          *
11760                          * It is safe to skip phi functions because they do
11761                          * not have any block local uses, and the block
11762                          * output sets already properly account for what
11763                          * control flow depedent uses phi functions do have.
11764                          */
11765                         if (ptr->op == OP_PHI) {
11766                                 continue;
11767                         }
11768                         expr = triple_rhs(state, ptr, 0);
11769                         for(;expr; expr = triple_rhs(state, ptr, expr)) {
11770                                 /* If the triple is not a definition skip it. */
11771                                 if (!*expr || !triple_is_def(state, *expr)) {
11772                                         continue;
11773                                 }
11774                                 do_triple_set(&live, *expr, 0);
11775                         }
11776                 }
11777                 /* Free live */
11778                 for(entry = live; entry; entry = next) {
11779                         next = entry->next;
11780                         do_triple_unset(&live, entry->member);
11781                 }
11782         }
11783 }
11784
11785 static int count_triples(struct compile_state *state)
11786 {
11787         struct triple *first, *ins;
11788         int triples = 0;
11789         first = RHS(state->main_function, 0);
11790         ins = first;
11791         do {
11792                 triples++;
11793                 ins = ins->next;
11794         } while (ins != first);
11795         return triples;
11796 }
11797
11798
11799 struct dead_triple {
11800         struct triple *triple;
11801         struct dead_triple *work_next;
11802         struct block *block;
11803         int color;
11804         int flags;
11805 #define TRIPLE_FLAG_ALIVE 1
11806 };
11807
11808
11809 static void awaken(
11810         struct compile_state *state,
11811         struct dead_triple *dtriple, struct triple **expr,
11812         struct dead_triple ***work_list_tail)
11813 {
11814         struct triple *triple;
11815         struct dead_triple *dt;
11816         if (!expr) {
11817                 return;
11818         }
11819         triple = *expr;
11820         if (!triple) {
11821                 return;
11822         }
11823         if (triple->id <= 0)  {
11824                 internal_error(state, triple, "bad triple id: %d",
11825                         triple->id);
11826         }
11827         if (triple->op == OP_NOOP) {
11828                 internal_warning(state, triple, "awakening noop?");
11829                 return;
11830         }
11831         dt = &dtriple[triple->id];
11832         if (!(dt->flags & TRIPLE_FLAG_ALIVE)) {
11833                 dt->flags |= TRIPLE_FLAG_ALIVE;
11834                 if (!dt->work_next) {
11835                         **work_list_tail = dt;
11836                         *work_list_tail = &dt->work_next;
11837                 }
11838         }
11839 }
11840
11841 static void eliminate_inefectual_code(struct compile_state *state)
11842 {
11843         struct block *block;
11844         struct dead_triple *dtriple, *work_list, **work_list_tail, *dt;
11845         int triples, i;
11846         struct triple *first, *ins;
11847
11848         /* Setup the work list */
11849         work_list = 0;
11850         work_list_tail = &work_list;
11851
11852         first = RHS(state->main_function, 0);
11853
11854         /* Count how many triples I have */
11855         triples = count_triples(state);
11856
11857         /* Now put then in an array and mark all of the triples dead */
11858         dtriple = xcmalloc(sizeof(*dtriple) * (triples + 1), "dtriples");
11859         
11860         ins = first;
11861         i = 1;
11862         block = 0;
11863         do {
11864                 if (ins->op == OP_LABEL) {
11865                         block = ins->u.block;
11866                 }
11867                 dtriple[i].triple = ins;
11868                 dtriple[i].block  = block;
11869                 dtriple[i].flags  = 0;
11870                 dtriple[i].color  = ins->id;
11871                 ins->id = i;
11872                 /* See if it is an operation we always keep */
11873 #warning "FIXME handle the case of killing a branch instruction"
11874                 if (!triple_is_pure(state, ins) || triple_is_branch(state, ins)) {
11875                         awaken(state, dtriple, &ins, &work_list_tail);
11876                 }
11877 #if 1
11878                 /* Unconditionally keep the very last instruction */
11879                 else if (ins->next == first) {
11880                         awaken(state, dtriple, &ins, &work_list_tail);
11881                 }
11882 #endif
11883                 i++;
11884                 ins = ins->next;
11885         } while(ins != first);
11886         while(work_list) {
11887                 struct dead_triple *dt;
11888                 struct block_set *user;
11889                 struct triple **expr;
11890                 dt = work_list;
11891                 work_list = dt->work_next;
11892                 if (!work_list) {
11893                         work_list_tail = &work_list;
11894                 }
11895                 /* Wake up the data depencencies of this triple */
11896                 expr = 0;
11897                 do {
11898                         expr = triple_rhs(state, dt->triple, expr);
11899                         awaken(state, dtriple, expr, &work_list_tail);
11900                 } while(expr);
11901                 do {
11902                         expr = triple_lhs(state, dt->triple, expr);
11903                         awaken(state, dtriple, expr, &work_list_tail);
11904                 } while(expr);
11905                 do {
11906                         expr = triple_misc(state, dt->triple, expr);
11907                         awaken(state, dtriple, expr, &work_list_tail);
11908                 } while(expr);
11909                 /* Wake up the forward control dependencies */
11910                 do {
11911                         expr = triple_targ(state, dt->triple, expr);
11912                         awaken(state, dtriple, expr, &work_list_tail);
11913                 } while(expr);
11914                 /* Wake up the reverse control dependencies of this triple */
11915                 for(user = dt->block->ipdomfrontier; user; user = user->next) {
11916                         awaken(state, dtriple, &user->member->last, &work_list_tail);
11917                 }
11918         }
11919         for(dt = &dtriple[1]; dt <= &dtriple[triples]; dt++) {
11920                 if ((dt->triple->op == OP_NOOP) && 
11921                         (dt->flags & TRIPLE_FLAG_ALIVE)) {
11922                         internal_error(state, dt->triple, "noop effective?");
11923                 }
11924                 dt->triple->id = dt->color;     /* Restore the color */
11925                 if (!(dt->flags & TRIPLE_FLAG_ALIVE)) {
11926 #warning "FIXME handle the case of killing a basic block"
11927                         if (dt->block->first == dt->triple) {
11928                                 continue;
11929                         }
11930                         if (dt->block->last == dt->triple) {
11931                                 dt->block->last = dt->triple->prev;
11932                         }
11933                         release_triple(state, dt->triple);
11934                 }
11935         }
11936         xfree(dtriple);
11937 }
11938
11939
11940 static void insert_mandatory_copies(struct compile_state *state)
11941 {
11942         struct triple *ins, *first;
11943
11944         /* The object is with a minimum of inserted copies,
11945          * to resolve in fundamental register conflicts between
11946          * register value producers and consumers.
11947          * Theoretically we may be greater than minimal when we
11948          * are inserting copies before instructions but that
11949          * case should be rare.
11950          */
11951         first = RHS(state->main_function, 0);
11952         ins = first;
11953         do {
11954                 struct triple_set *entry, *next;
11955                 struct triple *tmp;
11956                 struct reg_info info;
11957                 unsigned reg, regcm;
11958                 int do_post_copy, do_pre_copy;
11959                 tmp = 0;
11960                 if (!triple_is_def(state, ins)) {
11961                         goto next;
11962                 }
11963                 /* Find the architecture specific color information */
11964                 info = arch_reg_lhs(state, ins, 0);
11965                 if (info.reg >= MAX_REGISTERS) {
11966                         info.reg = REG_UNSET;
11967                 }
11968                 
11969                 reg = REG_UNSET;
11970                 regcm = arch_type_to_regcm(state, ins->type);
11971                 do_post_copy = do_pre_copy = 0;
11972
11973                 /* Walk through the uses of ins and check for conflicts */
11974                 for(entry = ins->use; entry; entry = next) {
11975                         struct reg_info rinfo;
11976                         int i;
11977                         next = entry->next;
11978                         i = find_rhs_use(state, entry->member, ins);
11979                         if (i < 0) {
11980                                 continue;
11981                         }
11982                         
11983                         /* Find the users color requirements */
11984                         rinfo = arch_reg_rhs(state, entry->member, i);
11985                         if (rinfo.reg >= MAX_REGISTERS) {
11986                                 rinfo.reg = REG_UNSET;
11987                         }
11988                         
11989                         /* See if I need a pre_copy */
11990                         if (rinfo.reg != REG_UNSET) {
11991                                 if ((reg != REG_UNSET) && (reg != rinfo.reg)) {
11992                                         do_pre_copy = 1;
11993                                 }
11994                                 reg = rinfo.reg;
11995                         }
11996                         regcm &= rinfo.regcm;
11997                         regcm = arch_regcm_normalize(state, regcm);
11998                         if (regcm == 0) {
11999                                 do_pre_copy = 1;
12000                         }
12001                         /* Always use pre_copies for constants.
12002                          * They do not take up any registers until a
12003                          * copy places them in one.
12004                          */
12005                         if ((info.reg == REG_UNNEEDED) && 
12006                                 (rinfo.reg != REG_UNNEEDED)) {
12007                                 do_pre_copy = 1;
12008                         }
12009                 }
12010                 do_post_copy =
12011                         !do_pre_copy &&
12012                         (((info.reg != REG_UNSET) && 
12013                                 (reg != REG_UNSET) &&
12014                                 (info.reg != reg)) ||
12015                         ((info.regcm & regcm) == 0));
12016
12017                 reg = info.reg;
12018                 regcm = info.regcm;
12019                 /* Walk through the uses of ins and do a pre_copy or see if a post_copy is warranted */
12020                 for(entry = ins->use; entry; entry = next) {
12021                         struct reg_info rinfo;
12022                         int i;
12023                         next = entry->next;
12024                         i = find_rhs_use(state, entry->member, ins);
12025                         if (i < 0) {
12026                                 continue;
12027                         }
12028                         
12029                         /* Find the users color requirements */
12030                         rinfo = arch_reg_rhs(state, entry->member, i);
12031                         if (rinfo.reg >= MAX_REGISTERS) {
12032                                 rinfo.reg = REG_UNSET;
12033                         }
12034
12035                         /* Now see if it is time to do the pre_copy */
12036                         if (rinfo.reg != REG_UNSET) {
12037                                 if (((reg != REG_UNSET) && (reg != rinfo.reg)) ||
12038                                         ((regcm & rinfo.regcm) == 0) ||
12039                                         /* Don't let a mandatory coalesce sneak
12040                                          * into a operation that is marked to prevent
12041                                          * coalescing.
12042                                          */
12043                                         ((reg != REG_UNNEEDED) &&
12044                                         ((ins->id & TRIPLE_FLAG_POST_SPLIT) ||
12045                                         (entry->member->id & TRIPLE_FLAG_PRE_SPLIT)))
12046                                         ) {
12047                                         if (do_pre_copy) {
12048                                                 struct triple *user;
12049                                                 user = entry->member;
12050                                                 if (RHS(user, i) != ins) {
12051                                                         internal_error(state, user, "bad rhs");
12052                                                 }
12053                                                 tmp = pre_copy(state, user, i);
12054                                                 tmp->id |= TRIPLE_FLAG_PRE_SPLIT;
12055                                                 continue;
12056                                         } else {
12057                                                 do_post_copy = 1;
12058                                         }
12059                                 }
12060                                 reg = rinfo.reg;
12061                         }
12062                         if ((regcm & rinfo.regcm) == 0) {
12063                                 if (do_pre_copy) {
12064                                         struct triple *user;
12065                                         user = entry->member;
12066                                         if (RHS(user, i) != ins) {
12067                                                 internal_error(state, user, "bad rhs");
12068                                         }
12069                                         tmp = pre_copy(state, user, i);
12070                                         tmp->id |= TRIPLE_FLAG_PRE_SPLIT;
12071                                         continue;
12072                                 } else {
12073                                         do_post_copy = 1;
12074                                 }
12075                         }
12076                         regcm &= rinfo.regcm;
12077                         
12078                 }
12079                 if (do_post_copy) {
12080                         struct reg_info pre, post;
12081                         tmp = post_copy(state, ins);
12082                         tmp->id |= TRIPLE_FLAG_PRE_SPLIT;
12083                         pre = arch_reg_lhs(state, ins, 0);
12084                         post = arch_reg_lhs(state, tmp, 0);
12085                         if ((pre.reg == post.reg) && (pre.regcm == post.regcm)) {
12086                                 internal_error(state, tmp, "useless copy");
12087                         }
12088                 }
12089         next:
12090                 ins = ins->next;
12091         } while(ins != first);
12092 }
12093
12094
12095 struct live_range_edge;
12096 struct live_range_def;
12097 struct live_range {
12098         struct live_range_edge *edges;
12099         struct live_range_def *defs;
12100 /* Note. The list pointed to by defs is kept in order.
12101  * That is baring splits in the flow control
12102  * defs dominates defs->next wich dominates defs->next->next
12103  * etc.
12104  */
12105         unsigned color;
12106         unsigned classes;
12107         unsigned degree;
12108         unsigned length;
12109         struct live_range *group_next, **group_prev;
12110 };
12111
12112 struct live_range_edge {
12113         struct live_range_edge *next;
12114         struct live_range *node;
12115 };
12116
12117 struct live_range_def {
12118         struct live_range_def *next;
12119         struct live_range_def *prev;
12120         struct live_range *lr;
12121         struct triple *def;
12122         unsigned orig_id;
12123 };
12124
12125 #define LRE_HASH_SIZE 2048
12126 struct lre_hash {
12127         struct lre_hash *next;
12128         struct live_range *left;
12129         struct live_range *right;
12130 };
12131
12132
12133 struct reg_state {
12134         struct lre_hash *hash[LRE_HASH_SIZE];
12135         struct reg_block *blocks;
12136         struct live_range_def *lrd;
12137         struct live_range *lr;
12138         struct live_range *low, **low_tail;
12139         struct live_range *high, **high_tail;
12140         unsigned defs;
12141         unsigned ranges;
12142         int passes, max_passes;
12143 #define MAX_ALLOCATION_PASSES 100
12144 };
12145
12146
12147
12148 struct print_interference_block_info {
12149         struct reg_state *rstate;
12150         FILE *fp;
12151         int need_edges;
12152 };
12153 static void print_interference_block(
12154         struct compile_state *state, struct block *block, void *arg)
12155
12156 {
12157         struct print_interference_block_info *info = arg;
12158         struct reg_state *rstate = info->rstate;
12159         FILE *fp = info->fp;
12160         struct reg_block *rb;
12161         struct triple *ptr;
12162         int phi_present;
12163         int done;
12164         rb = &rstate->blocks[block->vertex];
12165
12166         fprintf(fp, "\nblock: %p (%d), %p<-%p %p<-%p\n", 
12167                 block, 
12168                 block->vertex,
12169                 block->left, 
12170                 block->left && block->left->use?block->left->use->member : 0,
12171                 block->right, 
12172                 block->right && block->right->use?block->right->use->member : 0);
12173         if (rb->in) {
12174                 struct triple_reg_set *in_set;
12175                 fprintf(fp, "        in:");
12176                 for(in_set = rb->in; in_set; in_set = in_set->next) {
12177                         fprintf(fp, " %-10p", in_set->member);
12178                 }
12179                 fprintf(fp, "\n");
12180         }
12181         phi_present = 0;
12182         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
12183                 done = (ptr == block->last);
12184                 if (ptr->op == OP_PHI) {
12185                         phi_present = 1;
12186                         break;
12187                 }
12188         }
12189         if (phi_present) {
12190                 int edge;
12191                 for(edge = 0; edge < block->users; edge++) {
12192                         fprintf(fp, "     in(%d):", edge);
12193                         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
12194                                 struct triple **slot;
12195                                 done = (ptr == block->last);
12196                                 if (ptr->op != OP_PHI) {
12197                                         continue;
12198                                 }
12199                                 slot = &RHS(ptr, 0);
12200                                 fprintf(fp, " %-10p", slot[edge]);
12201                         }
12202                         fprintf(fp, "\n");
12203                 }
12204         }
12205         if (block->first->op == OP_LABEL) {
12206                 fprintf(fp, "%p:\n", block->first);
12207         }
12208         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
12209                 struct live_range *lr;
12210                 unsigned id;
12211                 int op;
12212                 op = ptr->op;
12213                 done = (ptr == block->last);
12214                 lr = rstate->lrd[ptr->id].lr;
12215                 
12216                 id = ptr->id;
12217                 ptr->id = rstate->lrd[id].orig_id;
12218                 SET_REG(ptr->id, lr->color);
12219                 display_triple(fp, ptr);
12220                 ptr->id = id;
12221
12222                 if (triple_is_def(state, ptr) && (lr->defs == 0)) {
12223                         internal_error(state, ptr, "lr has no defs!");
12224                 }
12225                 if (info->need_edges) {
12226                         if (lr->defs) {
12227                                 struct live_range_def *lrd;
12228                                 fprintf(fp, "       range:");
12229                                 lrd = lr->defs;
12230                                 do {
12231                                         fprintf(fp, " %-10p", lrd->def);
12232                                         lrd = lrd->next;
12233                                 } while(lrd != lr->defs);
12234                                 fprintf(fp, "\n");
12235                         }
12236                         if (lr->edges > 0) {
12237                                 struct live_range_edge *edge;
12238                                 fprintf(fp, "       edges:");
12239                                 for(edge = lr->edges; edge; edge = edge->next) {
12240                                         struct live_range_def *lrd;
12241                                         lrd = edge->node->defs;
12242                                         do {
12243                                                 fprintf(fp, " %-10p", lrd->def);
12244                                                 lrd = lrd->next;
12245                                         } while(lrd != edge->node->defs);
12246                                         fprintf(fp, "|");
12247                                 }
12248                                 fprintf(fp, "\n");
12249                         }
12250                 }
12251                 /* Do a bunch of sanity checks */
12252                 valid_ins(state, ptr);
12253                 if ((ptr->id < 0) || (ptr->id > rstate->defs)) {
12254                         internal_error(state, ptr, "Invalid triple id: %d",
12255                                 ptr->id);
12256                 }
12257         }
12258         if (rb->out) {
12259                 struct triple_reg_set *out_set;
12260                 fprintf(fp, "       out:");
12261                 for(out_set = rb->out; out_set; out_set = out_set->next) {
12262                         fprintf(fp, " %-10p", out_set->member);
12263                 }
12264                 fprintf(fp, "\n");
12265         }
12266         fprintf(fp, "\n");
12267 }
12268
12269 static void print_interference_blocks(
12270         struct compile_state *state, struct reg_state *rstate, FILE *fp, int need_edges)
12271 {
12272         struct print_interference_block_info info;
12273         info.rstate = rstate;
12274         info.fp = fp;
12275         info.need_edges = need_edges;
12276         fprintf(fp, "\nlive variables by block\n");
12277         walk_blocks(state, print_interference_block, &info);
12278
12279 }
12280
12281 static unsigned regc_max_size(struct compile_state *state, int classes)
12282 {
12283         unsigned max_size;
12284         int i;
12285         max_size = 0;
12286         for(i = 0; i < MAX_REGC; i++) {
12287                 if (classes & (1 << i)) {
12288                         unsigned size;
12289                         size = arch_regc_size(state, i);
12290                         if (size > max_size) {
12291                                 max_size = size;
12292                         }
12293                 }
12294         }
12295         return max_size;
12296 }
12297
12298 static int reg_is_reg(struct compile_state *state, int reg1, int reg2)
12299 {
12300         unsigned equivs[MAX_REG_EQUIVS];
12301         int i;
12302         if ((reg1 < 0) || (reg1 >= MAX_REGISTERS)) {
12303                 internal_error(state, 0, "invalid register");
12304         }
12305         if ((reg2 < 0) || (reg2 >= MAX_REGISTERS)) {
12306                 internal_error(state, 0, "invalid register");
12307         }
12308         arch_reg_equivs(state, equivs, reg1);
12309         for(i = 0; (i < MAX_REG_EQUIVS) && equivs[i] != REG_UNSET; i++) {
12310                 if (equivs[i] == reg2) {
12311                         return 1;
12312                 }
12313         }
12314         return 0;
12315 }
12316
12317 static void reg_fill_used(struct compile_state *state, char *used, int reg)
12318 {
12319         unsigned equivs[MAX_REG_EQUIVS];
12320         int i;
12321         if (reg == REG_UNNEEDED) {
12322                 return;
12323         }
12324         arch_reg_equivs(state, equivs, reg);
12325         for(i = 0; (i < MAX_REG_EQUIVS) && equivs[i] != REG_UNSET; i++) {
12326                 used[equivs[i]] = 1;
12327         }
12328         return;
12329 }
12330
12331 static void reg_inc_used(struct compile_state *state, char *used, int reg)
12332 {
12333         unsigned equivs[MAX_REG_EQUIVS];
12334         int i;
12335         if (reg == REG_UNNEEDED) {
12336                 return;
12337         }
12338         arch_reg_equivs(state, equivs, reg);
12339         for(i = 0; (i < MAX_REG_EQUIVS) && equivs[i] != REG_UNSET; i++) {
12340                 used[equivs[i]] += 1;
12341         }
12342         return;
12343 }
12344
12345 static unsigned int hash_live_edge(
12346         struct live_range *left, struct live_range *right)
12347 {
12348         unsigned int hash, val;
12349         unsigned long lval, rval;
12350         lval = ((unsigned long)left)/sizeof(struct live_range);
12351         rval = ((unsigned long)right)/sizeof(struct live_range);
12352         hash = 0;
12353         while(lval) {
12354                 val = lval & 0xff;
12355                 lval >>= 8;
12356                 hash = (hash *263) + val;
12357         }
12358         while(rval) {
12359                 val = rval & 0xff;
12360                 rval >>= 8;
12361                 hash = (hash *263) + val;
12362         }
12363         hash = hash & (LRE_HASH_SIZE - 1);
12364         return hash;
12365 }
12366
12367 static struct lre_hash **lre_probe(struct reg_state *rstate,
12368         struct live_range *left, struct live_range *right)
12369 {
12370         struct lre_hash **ptr;
12371         unsigned int index;
12372         /* Ensure left <= right */
12373         if (left > right) {
12374                 struct live_range *tmp;
12375                 tmp = left;
12376                 left = right;
12377                 right = tmp;
12378         }
12379         index = hash_live_edge(left, right);
12380         
12381         ptr = &rstate->hash[index];
12382         while(*ptr) {
12383                 if (((*ptr)->left == left) && ((*ptr)->right == right)) {
12384                         break;
12385                 }
12386                 ptr = &(*ptr)->next;
12387         }
12388         return ptr;
12389 }
12390
12391 static int interfere(struct reg_state *rstate,
12392         struct live_range *left, struct live_range *right)
12393 {
12394         struct lre_hash **ptr;
12395         ptr = lre_probe(rstate, left, right);
12396         return ptr && *ptr;
12397 }
12398
12399 static void add_live_edge(struct reg_state *rstate, 
12400         struct live_range *left, struct live_range *right)
12401 {
12402         /* FIXME the memory allocation overhead is noticeable here... */
12403         struct lre_hash **ptr, *new_hash;
12404         struct live_range_edge *edge;
12405
12406         if (left == right) {
12407                 return;
12408         }
12409         if ((left == &rstate->lr[0]) || (right == &rstate->lr[0])) {
12410                 return;
12411         }
12412         /* Ensure left <= right */
12413         if (left > right) {
12414                 struct live_range *tmp;
12415                 tmp = left;
12416                 left = right;
12417                 right = tmp;
12418         }
12419         ptr = lre_probe(rstate, left, right);
12420         if (*ptr) {
12421                 return;
12422         }
12423 #if 0
12424         fprintf(stderr, "new_live_edge(%p, %p)\n",
12425                 left, right);
12426 #endif
12427         new_hash = xmalloc(sizeof(*new_hash), "lre_hash");
12428         new_hash->next  = *ptr;
12429         new_hash->left  = left;
12430         new_hash->right = right;
12431         *ptr = new_hash;
12432
12433         edge = xmalloc(sizeof(*edge), "live_range_edge");
12434         edge->next   = left->edges;
12435         edge->node   = right;
12436         left->edges  = edge;
12437         left->degree += 1;
12438         
12439         edge = xmalloc(sizeof(*edge), "live_range_edge");
12440         edge->next    = right->edges;
12441         edge->node    = left;
12442         right->edges  = edge;
12443         right->degree += 1;
12444 }
12445
12446 static void remove_live_edge(struct reg_state *rstate,
12447         struct live_range *left, struct live_range *right)
12448 {
12449         struct live_range_edge *edge, **ptr;
12450         struct lre_hash **hptr, *entry;
12451         hptr = lre_probe(rstate, left, right);
12452         if (!hptr || !*hptr) {
12453                 return;
12454         }
12455         entry = *hptr;
12456         *hptr = entry->next;
12457         xfree(entry);
12458
12459         for(ptr = &left->edges; *ptr; ptr = &(*ptr)->next) {
12460                 edge = *ptr;
12461                 if (edge->node == right) {
12462                         *ptr = edge->next;
12463                         memset(edge, 0, sizeof(*edge));
12464                         xfree(edge);
12465                         right->degree--;
12466                         break;
12467                 }
12468         }
12469         for(ptr = &right->edges; *ptr; ptr = &(*ptr)->next) {
12470                 edge = *ptr;
12471                 if (edge->node == left) {
12472                         *ptr = edge->next;
12473                         memset(edge, 0, sizeof(*edge));
12474                         xfree(edge);
12475                         left->degree--;
12476                         break;
12477                 }
12478         }
12479 }
12480
12481 static void remove_live_edges(struct reg_state *rstate, struct live_range *range)
12482 {
12483         struct live_range_edge *edge, *next;
12484         for(edge = range->edges; edge; edge = next) {
12485                 next = edge->next;
12486                 remove_live_edge(rstate, range, edge->node);
12487         }
12488 }
12489
12490 static void transfer_live_edges(struct reg_state *rstate, 
12491         struct live_range *dest, struct live_range *src)
12492 {
12493         struct live_range_edge *edge, *next;
12494         for(edge = src->edges; edge; edge = next) {
12495                 struct live_range *other;
12496                 next = edge->next;
12497                 other = edge->node;
12498                 remove_live_edge(rstate, src, other);
12499                 add_live_edge(rstate, dest, other);
12500         }
12501 }
12502
12503
12504 /* Interference graph...
12505  * 
12506  * new(n) --- Return a graph with n nodes but no edges.
12507  * add(g,x,y) --- Return a graph including g with an between x and y
12508  * interfere(g, x, y) --- Return true if there exists an edge between the nodes
12509  *                x and y in the graph g
12510  * degree(g, x) --- Return the degree of the node x in the graph g
12511  * neighbors(g, x, f) --- Apply function f to each neighbor of node x in the graph g
12512  *
12513  * Implement with a hash table && a set of adjcency vectors.
12514  * The hash table supports constant time implementations of add and interfere.
12515  * The adjacency vectors support an efficient implementation of neighbors.
12516  */
12517
12518 /* 
12519  *     +---------------------------------------------------+
12520  *     |         +--------------+                          |
12521  *     v         v              |                          |
12522  * renumber -> build graph -> colalesce -> spill_costs -> simplify -> select 
12523  *
12524  * -- In simplify implment optimistic coloring... (No backtracking)
12525  * -- Implement Rematerialization it is the only form of spilling we can perform
12526  *    Essentially this means dropping a constant from a register because
12527  *    we can regenerate it later.
12528  *
12529  * --- Very conservative colalescing (don't colalesce just mark the opportunities)
12530  *     coalesce at phi points...
12531  * --- Bias coloring if at all possible do the coalesing a compile time.
12532  *
12533  *
12534  */
12535
12536 static void different_colored(
12537         struct compile_state *state, struct reg_state *rstate, 
12538         struct triple *parent, struct triple *ins)
12539 {
12540         struct live_range *lr;
12541         struct triple **expr;
12542         lr = rstate->lrd[ins->id].lr;
12543         expr = triple_rhs(state, ins, 0);
12544         for(;expr; expr = triple_rhs(state, ins, expr)) {
12545                 struct live_range *lr2;
12546                 if (!*expr || (*expr == parent) || (*expr == ins)) {
12547                         continue;
12548                 }
12549                 lr2 = rstate->lrd[(*expr)->id].lr;
12550                 if (lr->color == lr2->color) {
12551                         internal_error(state, ins, "live range too big");
12552                 }
12553         }
12554 }
12555
12556
12557 static struct live_range *coalesce_ranges(
12558         struct compile_state *state, struct reg_state *rstate,
12559         struct live_range *lr1, struct live_range *lr2)
12560 {
12561         struct live_range_def *head, *mid1, *mid2, *end, *lrd;
12562         unsigned color;
12563         unsigned classes;
12564         if (lr1 == lr2) {
12565                 return lr1;
12566         }
12567         if (!lr1->defs || !lr2->defs) {
12568                 internal_error(state, 0,
12569                         "cannot coalese dead live ranges");
12570         }
12571         if ((lr1->color == REG_UNNEEDED) ||
12572                 (lr2->color == REG_UNNEEDED)) {
12573                 internal_error(state, 0, 
12574                         "cannot coalesce live ranges without a possible color");
12575         }
12576         if ((lr1->color != lr2->color) &&
12577                 (lr1->color != REG_UNSET) &&
12578                 (lr2->color != REG_UNSET)) {
12579                 internal_error(state, lr1->defs->def, 
12580                         "cannot coalesce live ranges of different colors");
12581         }
12582         color = lr1->color;
12583         if (color == REG_UNSET) {
12584                 color = lr2->color;
12585         }
12586         classes = lr1->classes & lr2->classes;
12587         if (!classes) {
12588                 internal_error(state, lr1->defs->def,
12589                         "cannot coalesce live ranges with dissimilar register classes");
12590         }
12591 #if DEBUG_COALESCING
12592         fprintf(stderr, "coalescing:");
12593         lrd = lr1->defs;
12594         do {
12595                 fprintf(stderr, " %p", lrd->def);
12596                 lrd = lrd->next;
12597         } while(lrd != lr1->defs);
12598         fprintf(stderr, " |");
12599         lrd = lr2->defs;
12600         do {
12601                 fprintf(stderr, " %p", lrd->def);
12602                 lrd = lrd->next;
12603         } while(lrd != lr2->defs);
12604         fprintf(stderr, "\n");
12605 #endif
12606         /* If there is a clear dominate live range put it in lr1,
12607          * For purposes of this test phi functions are
12608          * considered dominated by the definitions that feed into
12609          * them. 
12610          */
12611         if ((lr1->defs->prev->def->op == OP_PHI) ||
12612                 ((lr2->defs->prev->def->op != OP_PHI) &&
12613                 tdominates(state, lr2->defs->def, lr1->defs->def))) {
12614                 struct live_range *tmp;
12615                 tmp = lr1;
12616                 lr1 = lr2;
12617                 lr2 = tmp;
12618         }
12619 #if 0
12620         if (lr1->defs->orig_id  & TRIPLE_FLAG_POST_SPLIT) {
12621                 fprintf(stderr, "lr1 post\n");
12622         }
12623         if (lr1->defs->orig_id & TRIPLE_FLAG_PRE_SPLIT) {
12624                 fprintf(stderr, "lr1 pre\n");
12625         }
12626         if (lr2->defs->orig_id  & TRIPLE_FLAG_POST_SPLIT) {
12627                 fprintf(stderr, "lr2 post\n");
12628         }
12629         if (lr2->defs->orig_id & TRIPLE_FLAG_PRE_SPLIT) {
12630                 fprintf(stderr, "lr2 pre\n");
12631         }
12632 #endif
12633 #if 0
12634         fprintf(stderr, "coalesce color1(%p): %3d color2(%p) %3d\n",
12635                 lr1->defs->def,
12636                 lr1->color,
12637                 lr2->defs->def,
12638                 lr2->color);
12639 #endif
12640         
12641         /* Append lr2 onto lr1 */
12642 #warning "FIXME should this be a merge instead of a splice?"
12643         /* This FIXME item applies to the correctness of live_range_end 
12644          * and to the necessity of making multiple passes of coalesce_live_ranges.
12645          * A failure to find some coalesce opportunities in coaleace_live_ranges
12646          * does not impact the correct of the compiler just the efficiency with
12647          * which registers are allocated.
12648          */
12649         head = lr1->defs;
12650         mid1 = lr1->defs->prev;
12651         mid2 = lr2->defs;
12652         end  = lr2->defs->prev;
12653         
12654         head->prev = end;
12655         end->next  = head;
12656
12657         mid1->next = mid2;
12658         mid2->prev = mid1;
12659
12660         /* Fixup the live range in the added live range defs */
12661         lrd = head;
12662         do {
12663                 lrd->lr = lr1;
12664                 lrd = lrd->next;
12665         } while(lrd != head);
12666
12667         /* Mark lr2 as free. */
12668         lr2->defs = 0;
12669         lr2->color = REG_UNNEEDED;
12670         lr2->classes = 0;
12671
12672         if (!lr1->defs) {
12673                 internal_error(state, 0, "lr1->defs == 0 ?");
12674         }
12675
12676         lr1->color   = color;
12677         lr1->classes = classes;
12678
12679         /* Keep the graph in sync by transfering the edges from lr2 to lr1 */
12680         transfer_live_edges(rstate, lr1, lr2);
12681
12682         return lr1;
12683 }
12684
12685 static struct live_range_def *live_range_head(
12686         struct compile_state *state, struct live_range *lr,
12687         struct live_range_def *last)
12688 {
12689         struct live_range_def *result;
12690         result = 0;
12691         if (last == 0) {
12692                 result = lr->defs;
12693         }
12694         else if (!tdominates(state, lr->defs->def, last->next->def)) {
12695                 result = last->next;
12696         }
12697         return result;
12698 }
12699
12700 static struct live_range_def *live_range_end(
12701         struct compile_state *state, struct live_range *lr,
12702         struct live_range_def *last)
12703 {
12704         struct live_range_def *result;
12705         result = 0;
12706         if (last == 0) {
12707                 result = lr->defs->prev;
12708         }
12709         else if (!tdominates(state, last->prev->def, lr->defs->prev->def)) {
12710                 result = last->prev;
12711         }
12712         return result;
12713 }
12714
12715
12716 static void initialize_live_ranges(
12717         struct compile_state *state, struct reg_state *rstate)
12718 {
12719         struct triple *ins, *first;
12720         size_t count, size;
12721         int i, j;
12722
12723         first = RHS(state->main_function, 0);
12724         /* First count how many instructions I have.
12725          */
12726         count = count_triples(state);
12727         /* Potentially I need one live range definitions for each
12728          * instruction.
12729          */
12730         rstate->defs = count;
12731         /* Potentially I need one live range for each instruction
12732          * plus an extra for the dummy live range.
12733          */
12734         rstate->ranges = count + 1;
12735         size = sizeof(rstate->lrd[0]) * rstate->defs;
12736         rstate->lrd = xcmalloc(size, "live_range_def");
12737         size = sizeof(rstate->lr[0]) * rstate->ranges;
12738         rstate->lr  = xcmalloc(size, "live_range");
12739
12740         /* Setup the dummy live range */
12741         rstate->lr[0].classes = 0;
12742         rstate->lr[0].color = REG_UNSET;
12743         rstate->lr[0].defs = 0;
12744         i = j = 0;
12745         ins = first;
12746         do {
12747                 /* If the triple is a variable give it a live range */
12748                 if (triple_is_def(state, ins)) {
12749                         struct reg_info info;
12750                         /* Find the architecture specific color information */
12751                         info = find_def_color(state, ins);
12752                         i++;
12753                         rstate->lr[i].defs    = &rstate->lrd[j];
12754                         rstate->lr[i].color   = info.reg;
12755                         rstate->lr[i].classes = info.regcm;
12756                         rstate->lr[i].degree  = 0;
12757                         rstate->lrd[j].lr = &rstate->lr[i];
12758                 } 
12759                 /* Otherwise give the triple the dummy live range. */
12760                 else {
12761                         rstate->lrd[j].lr = &rstate->lr[0];
12762                 }
12763
12764                 /* Initalize the live_range_def */
12765                 rstate->lrd[j].next    = &rstate->lrd[j];
12766                 rstate->lrd[j].prev    = &rstate->lrd[j];
12767                 rstate->lrd[j].def     = ins;
12768                 rstate->lrd[j].orig_id = ins->id;
12769                 ins->id = j;
12770
12771                 j++;
12772                 ins = ins->next;
12773         } while(ins != first);
12774         rstate->ranges = i;
12775
12776         /* Make a second pass to handle achitecture specific register
12777          * constraints.
12778          */
12779         ins = first;
12780         do {
12781                 int zlhs, zrhs, i, j;
12782                 if (ins->id > rstate->defs) {
12783                         internal_error(state, ins, "bad id");
12784                 }
12785                 
12786                 /* Walk through the template of ins and coalesce live ranges */
12787                 zlhs = TRIPLE_LHS(ins->sizes);
12788                 if ((zlhs == 0) && triple_is_def(state, ins)) {
12789                         zlhs = 1;
12790                 }
12791                 zrhs = TRIPLE_RHS(ins->sizes);
12792
12793 #if DEBUG_COALESCING > 1
12794                 fprintf(stderr, "mandatory coalesce: %p %d %d\n",
12795                         ins, zlhs, zrhs);
12796 #endif          
12797                 for(i = 0; i < zlhs; i++) {
12798                         struct reg_info linfo;
12799                         struct live_range_def *lhs;
12800                         linfo = arch_reg_lhs(state, ins, i);
12801                         if (linfo.reg < MAX_REGISTERS) {
12802                                 continue;
12803                         }
12804                         if (triple_is_def(state, ins)) {
12805                                 lhs = &rstate->lrd[ins->id];
12806                         } else {
12807                                 lhs = &rstate->lrd[LHS(ins, i)->id];
12808                         }
12809 #if DEBUG_COALESCING > 1
12810                         fprintf(stderr, "coalesce lhs(%d): %p %d\n",
12811                                 i, lhs, linfo.reg);
12812                 
12813 #endif          
12814                         for(j = 0; j < zrhs; j++) {
12815                                 struct reg_info rinfo;
12816                                 struct live_range_def *rhs;
12817                                 rinfo = arch_reg_rhs(state, ins, j);
12818                                 if (rinfo.reg < MAX_REGISTERS) {
12819                                         continue;
12820                                 }
12821                                 rhs = &rstate->lrd[RHS(ins, j)->id];
12822 #if DEBUG_COALESCING > 1
12823                                 fprintf(stderr, "coalesce rhs(%d): %p %d\n",
12824                                         j, rhs, rinfo.reg);
12825                 
12826 #endif          
12827                                 if (rinfo.reg == linfo.reg) {
12828                                         coalesce_ranges(state, rstate, 
12829                                                 lhs->lr, rhs->lr);
12830                                 }
12831                         }
12832                 }
12833                 ins = ins->next;
12834         } while(ins != first);
12835 }
12836
12837 static void graph_ins(
12838         struct compile_state *state, 
12839         struct reg_block *blocks, struct triple_reg_set *live, 
12840         struct reg_block *rb, struct triple *ins, void *arg)
12841 {
12842         struct reg_state *rstate = arg;
12843         struct live_range *def;
12844         struct triple_reg_set *entry;
12845
12846         /* If the triple is not a definition
12847          * we do not have a definition to add to
12848          * the interference graph.
12849          */
12850         if (!triple_is_def(state, ins)) {
12851                 return;
12852         }
12853         def = rstate->lrd[ins->id].lr;
12854         
12855         /* Create an edge between ins and everything that is
12856          * alive, unless the live_range cannot share
12857          * a physical register with ins.
12858          */
12859         for(entry = live; entry; entry = entry->next) {
12860                 struct live_range *lr;
12861                 if ((entry->member->id < 0) || (entry->member->id > rstate->defs)) {
12862                         internal_error(state, 0, "bad entry?");
12863                 }
12864                 lr = rstate->lrd[entry->member->id].lr;
12865                 if (def == lr) {
12866                         continue;
12867                 }
12868                 if (!arch_regcm_intersect(def->classes, lr->classes)) {
12869                         continue;
12870                 }
12871                 add_live_edge(rstate, def, lr);
12872         }
12873         return;
12874 }
12875
12876 static struct live_range *get_verify_live_range(
12877         struct compile_state *state, struct reg_state *rstate, struct triple *ins)
12878 {
12879         struct live_range *lr;
12880         struct live_range_def *lrd;
12881         int ins_found;
12882         if ((ins->id < 0) || (ins->id > rstate->defs)) {
12883                 internal_error(state, ins, "bad ins?");
12884         }
12885         lr = rstate->lrd[ins->id].lr;
12886         ins_found = 0;
12887         lrd = lr->defs;
12888         do {
12889                 if (lrd->def == ins) {
12890                         ins_found = 1;
12891                 }
12892                 lrd = lrd->next;
12893         } while(lrd != lr->defs);
12894         if (!ins_found) {
12895                 internal_error(state, ins, "ins not in live range");
12896         }
12897         return lr;
12898 }
12899
12900 static void verify_graph_ins(
12901         struct compile_state *state, 
12902         struct reg_block *blocks, struct triple_reg_set *live, 
12903         struct reg_block *rb, struct triple *ins, void *arg)
12904 {
12905         struct reg_state *rstate = arg;
12906         struct triple_reg_set *entry1, *entry2;
12907
12908
12909         /* Compare live against edges and make certain the code is working */
12910         for(entry1 = live; entry1; entry1 = entry1->next) {
12911                 struct live_range *lr1;
12912                 lr1 = get_verify_live_range(state, rstate, entry1->member);
12913                 for(entry2 = live; entry2; entry2 = entry2->next) {
12914                         struct live_range *lr2;
12915                         struct live_range_edge *edge2;
12916                         int lr1_found;
12917                         int lr2_degree;
12918                         if (entry2 == entry1) {
12919                                 continue;
12920                         }
12921                         lr2 = get_verify_live_range(state, rstate, entry2->member);
12922                         if (lr1 == lr2) {
12923                                 internal_error(state, entry2->member, 
12924                                         "live range with 2 values simultaneously alive");
12925                         }
12926                         if (!arch_regcm_intersect(lr1->classes, lr2->classes)) {
12927                                 continue;
12928                         }
12929                         if (!interfere(rstate, lr1, lr2)) {
12930                                 internal_error(state, entry2->member, 
12931                                         "edges don't interfere?");
12932                         }
12933                                 
12934                         lr1_found = 0;
12935                         lr2_degree = 0;
12936                         for(edge2 = lr2->edges; edge2; edge2 = edge2->next) {
12937                                 lr2_degree++;
12938                                 if (edge2->node == lr1) {
12939                                         lr1_found = 1;
12940                                 }
12941                         }
12942                         if (lr2_degree != lr2->degree) {
12943                                 internal_error(state, entry2->member,
12944                                         "computed degree: %d does not match reported degree: %d\n",
12945                                         lr2_degree, lr2->degree);
12946                         }
12947                         if (!lr1_found) {
12948                                 internal_error(state, entry2->member, "missing edge");
12949                         }
12950                 }
12951         }
12952         return;
12953 }
12954
12955
12956 static void print_interference_ins(
12957         struct compile_state *state, 
12958         struct reg_block *blocks, struct triple_reg_set *live, 
12959         struct reg_block *rb, struct triple *ins, void *arg)
12960 {
12961         struct reg_state *rstate = arg;
12962         struct live_range *lr;
12963         unsigned id;
12964
12965         lr = rstate->lrd[ins->id].lr;
12966         id = ins->id;
12967         ins->id = rstate->lrd[id].orig_id;
12968         SET_REG(ins->id, lr->color);
12969         display_triple(stdout, ins);
12970         ins->id = id;
12971
12972         if (lr->defs) {
12973                 struct live_range_def *lrd;
12974                 printf("       range:");
12975                 lrd = lr->defs;
12976                 do {
12977                         printf(" %-10p", lrd->def);
12978                         lrd = lrd->next;
12979                 } while(lrd != lr->defs);
12980                 printf("\n");
12981         }
12982         if (live) {
12983                 struct triple_reg_set *entry;
12984                 printf("        live:");
12985                 for(entry = live; entry; entry = entry->next) {
12986                         printf(" %-10p", entry->member);
12987                 }
12988                 printf("\n");
12989         }
12990         if (lr->edges) {
12991                 struct live_range_edge *entry;
12992                 printf("       edges:");
12993                 for(entry = lr->edges; entry; entry = entry->next) {
12994                         struct live_range_def *lrd;
12995                         lrd = entry->node->defs;
12996                         do {
12997                                 printf(" %-10p", lrd->def);
12998                                 lrd = lrd->next;
12999                         } while(lrd != entry->node->defs);
13000                         printf("|");
13001                 }
13002                 printf("\n");
13003         }
13004         if (triple_is_branch(state, ins)) {
13005                 printf("\n");
13006         }
13007         return;
13008 }
13009
13010 static int coalesce_live_ranges(
13011         struct compile_state *state, struct reg_state *rstate)
13012 {
13013         /* At the point where a value is moved from one
13014          * register to another that value requires two
13015          * registers, thus increasing register pressure.
13016          * Live range coaleescing reduces the register
13017          * pressure by keeping a value in one register
13018          * longer.
13019          *
13020          * In the case of a phi function all paths leading
13021          * into it must be allocated to the same register
13022          * otherwise the phi function may not be removed.
13023          *
13024          * Forcing a value to stay in a single register
13025          * for an extended period of time does have
13026          * limitations when applied to non homogenous
13027          * register pool.  
13028          *
13029          * The two cases I have identified are:
13030          * 1) Two forced register assignments may
13031          *    collide.
13032          * 2) Registers may go unused because they
13033          *    are only good for storing the value
13034          *    and not manipulating it.
13035          *
13036          * Because of this I need to split live ranges,
13037          * even outside of the context of coalesced live
13038          * ranges.  The need to split live ranges does
13039          * impose some constraints on live range coalescing.
13040          *
13041          * - Live ranges may not be coalesced across phi
13042          *   functions.  This creates a 2 headed live
13043          *   range that cannot be sanely split.
13044          *
13045          * - phi functions (coalesced in initialize_live_ranges) 
13046          *   are handled as pre split live ranges so we will
13047          *   never attempt to split them.
13048          */
13049         int coalesced;
13050         int i;
13051
13052         coalesced = 0;
13053         for(i = 0; i <= rstate->ranges; i++) {
13054                 struct live_range *lr1;
13055                 struct live_range_def *lrd1;
13056                 lr1 = &rstate->lr[i];
13057                 if (!lr1->defs) {
13058                         continue;
13059                 }
13060                 lrd1 = live_range_end(state, lr1, 0);
13061                 for(; lrd1; lrd1 = live_range_end(state, lr1, lrd1)) {
13062                         struct triple_set *set;
13063                         if (lrd1->def->op != OP_COPY) {
13064                                 continue;
13065                         }
13066                         /* Skip copies that are the result of a live range split. */
13067                         if (lrd1->orig_id & TRIPLE_FLAG_POST_SPLIT) {
13068                                 continue;
13069                         }
13070                         for(set = lrd1->def->use; set; set = set->next) {
13071                                 struct live_range_def *lrd2;
13072                                 struct live_range *lr2, *res;
13073
13074                                 lrd2 = &rstate->lrd[set->member->id];
13075
13076                                 /* Don't coalesce with instructions
13077                                  * that are the result of a live range
13078                                  * split.
13079                                  */
13080                                 if (lrd2->orig_id & TRIPLE_FLAG_PRE_SPLIT) {
13081                                         continue;
13082                                 }
13083                                 lr2 = rstate->lrd[set->member->id].lr;
13084                                 if (lr1 == lr2) {
13085                                         continue;
13086                                 }
13087                                 if ((lr1->color != lr2->color) &&
13088                                         (lr1->color != REG_UNSET) &&
13089                                         (lr2->color != REG_UNSET)) {
13090                                         continue;
13091                                 }
13092                                 if ((lr1->classes & lr2->classes) == 0) {
13093                                         continue;
13094                                 }
13095                                 
13096                                 if (interfere(rstate, lr1, lr2)) {
13097                                         continue;
13098                                 }
13099
13100                                 res = coalesce_ranges(state, rstate, lr1, lr2);
13101                                 coalesced += 1;
13102                                 if (res != lr1) {
13103                                         goto next;
13104                                 }
13105                         }
13106                 }
13107         next:
13108                 ;
13109         }
13110         return coalesced;
13111 }
13112
13113
13114 static void fix_coalesce_conflicts(struct compile_state *state,
13115         struct reg_block *blocks, struct triple_reg_set *live,
13116         struct reg_block *rb, struct triple *ins, void *arg)
13117 {
13118         int *conflicts = arg;
13119         int zlhs, zrhs, i, j;
13120
13121         /* See if we have a mandatory coalesce operation between
13122          * a lhs and a rhs value.  If so and the rhs value is also
13123          * alive then this triple needs to be pre copied.  Otherwise
13124          * we would have two definitions in the same live range simultaneously
13125          * alive.
13126          */
13127         zlhs = TRIPLE_LHS(ins->sizes);
13128         if ((zlhs == 0) && triple_is_def(state, ins)) {
13129                 zlhs = 1;
13130         }
13131         zrhs = TRIPLE_RHS(ins->sizes);
13132         for(i = 0; i < zlhs; i++) {
13133                 struct reg_info linfo;
13134                 linfo = arch_reg_lhs(state, ins, i);
13135                 if (linfo.reg < MAX_REGISTERS) {
13136                         continue;
13137                 }
13138                 for(j = 0; j < zrhs; j++) {
13139                         struct reg_info rinfo;
13140                         struct triple *rhs;
13141                         struct triple_reg_set *set;
13142                         int found;
13143                         found = 0;
13144                         rinfo = arch_reg_rhs(state, ins, j);
13145                         if (rinfo.reg != linfo.reg) {
13146                                 continue;
13147                         }
13148                         rhs = RHS(ins, j);
13149                         for(set = live; set && !found; set = set->next) {
13150                                 if (set->member == rhs) {
13151                                         found = 1;
13152                                 }
13153                         }
13154                         if (found) {
13155                                 struct triple *copy;
13156                                 copy = pre_copy(state, ins, j);
13157                                 copy->id |= TRIPLE_FLAG_PRE_SPLIT;
13158                                 (*conflicts)++;
13159                         }
13160                 }
13161         }
13162         return;
13163 }
13164
13165 static int correct_coalesce_conflicts(
13166         struct compile_state *state, struct reg_block *blocks)
13167 {
13168         int conflicts;
13169         conflicts = 0;
13170         walk_variable_lifetimes(state, blocks, fix_coalesce_conflicts, &conflicts);
13171         return conflicts;
13172 }
13173
13174 static void replace_set_use(struct compile_state *state,
13175         struct triple_reg_set *head, struct triple *orig, struct triple *new)
13176 {
13177         struct triple_reg_set *set;
13178         for(set = head; set; set = set->next) {
13179                 if (set->member == orig) {
13180                         set->member = new;
13181                 }
13182         }
13183 }
13184
13185 static void replace_block_use(struct compile_state *state, 
13186         struct reg_block *blocks, struct triple *orig, struct triple *new)
13187 {
13188         int i;
13189 #warning "WISHLIST visit just those blocks that need it *"
13190         for(i = 1; i <= state->last_vertex; i++) {
13191                 struct reg_block *rb;
13192                 rb = &blocks[i];
13193                 replace_set_use(state, rb->in, orig, new);
13194                 replace_set_use(state, rb->out, orig, new);
13195         }
13196 }
13197
13198 static void color_instructions(struct compile_state *state)
13199 {
13200         struct triple *ins, *first;
13201         first = RHS(state->main_function, 0);
13202         ins = first;
13203         do {
13204                 if (triple_is_def(state, ins)) {
13205                         struct reg_info info;
13206                         info = find_lhs_color(state, ins, 0);
13207                         if (info.reg >= MAX_REGISTERS) {
13208                                 info.reg = REG_UNSET;
13209                         }
13210                         SET_INFO(ins->id, info);
13211                 }
13212                 ins = ins->next;
13213         } while(ins != first);
13214 }
13215
13216 static struct reg_info read_lhs_color(
13217         struct compile_state *state, struct triple *ins, int index)
13218 {
13219         struct reg_info info;
13220         if ((index == 0) && triple_is_def(state, ins)) {
13221                 info.reg   = ID_REG(ins->id);
13222                 info.regcm = ID_REGCM(ins->id);
13223         }
13224         else if (index < TRIPLE_LHS(ins->sizes)) {
13225                 info = read_lhs_color(state, LHS(ins, index), 0);
13226         }
13227         else {
13228                 internal_error(state, ins, "Bad lhs %d", index);
13229                 info.reg = REG_UNSET;
13230                 info.regcm = 0;
13231         }
13232         return info;
13233 }
13234
13235 static struct triple *resolve_tangle(
13236         struct compile_state *state, struct triple *tangle)
13237 {
13238         struct reg_info info, uinfo;
13239         struct triple_set *set, *next;
13240         struct triple *copy;
13241
13242 #warning "WISHLIST recalculate all affected instructions colors"
13243         info = find_lhs_color(state, tangle, 0);
13244         for(set = tangle->use; set; set = next) {
13245                 struct triple *user;
13246                 int i, zrhs;
13247                 next = set->next;
13248                 user = set->member;
13249                 zrhs = TRIPLE_RHS(user->sizes);
13250                 for(i = 0; i < zrhs; i++) {
13251                         if (RHS(user, i) != tangle) {
13252                                 continue;
13253                         }
13254                         uinfo = find_rhs_post_color(state, user, i);
13255                         if (uinfo.reg == info.reg) {
13256                                 copy = pre_copy(state, user, i);
13257                                 copy->id |= TRIPLE_FLAG_PRE_SPLIT;
13258                                 SET_INFO(copy->id, uinfo);
13259                         }
13260                 }
13261         }
13262         copy = 0;
13263         uinfo = find_lhs_pre_color(state, tangle, 0);
13264         if (uinfo.reg == info.reg) {
13265                 struct reg_info linfo;
13266                 copy = post_copy(state, tangle);
13267                 copy->id |= TRIPLE_FLAG_PRE_SPLIT;
13268                 linfo = find_lhs_color(state, copy, 0);
13269                 SET_INFO(copy->id, linfo);
13270         }
13271         info = find_lhs_color(state, tangle, 0);
13272         SET_INFO(tangle->id, info);
13273         
13274         return copy;
13275 }
13276
13277
13278 static void fix_tangles(struct compile_state *state,
13279         struct reg_block *blocks, struct triple_reg_set *live,
13280         struct reg_block *rb, struct triple *ins, void *arg)
13281 {
13282         int *tangles = arg;
13283         struct triple *tangle;
13284         do {
13285                 char used[MAX_REGISTERS];
13286                 struct triple_reg_set *set;
13287                 tangle = 0;
13288
13289                 /* Find out which registers have multiple uses at this point */
13290                 memset(used, 0, sizeof(used));
13291                 for(set = live; set; set = set->next) {
13292                         struct reg_info info;
13293                         info = read_lhs_color(state, set->member, 0);
13294                         if (info.reg == REG_UNSET) {
13295                                 continue;
13296                         }
13297                         reg_inc_used(state, used, info.reg);
13298                 }
13299                 
13300                 /* Now find the least dominated definition of a register in
13301                  * conflict I have seen so far.
13302                  */
13303                 for(set = live; set; set = set->next) {
13304                         struct reg_info info;
13305                         info = read_lhs_color(state, set->member, 0);
13306                         if (used[info.reg] < 2) {
13307                                 continue;
13308                         }
13309                         /* Changing copies that feed into phi functions
13310                          * is incorrect.
13311                          */
13312                         if (set->member->use && 
13313                                 (set->member->use->member->op == OP_PHI)) {
13314                                 continue;
13315                         }
13316                         if (!tangle || tdominates(state, set->member, tangle)) {
13317                                 tangle = set->member;
13318                         }
13319                 }
13320                 /* If I have found a tangle resolve it */
13321                 if (tangle) {
13322                         struct triple *post_copy;
13323                         (*tangles)++;
13324                         post_copy = resolve_tangle(state, tangle);
13325                         if (post_copy) {
13326                                 replace_block_use(state, blocks, tangle, post_copy);
13327                         }
13328                         if (post_copy && (tangle != ins)) {
13329                                 replace_set_use(state, live, tangle, post_copy);
13330                         }
13331                 }
13332         } while(tangle);
13333         return;
13334 }
13335
13336 static int correct_tangles(
13337         struct compile_state *state, struct reg_block *blocks)
13338 {
13339         int tangles;
13340         tangles = 0;
13341         color_instructions(state);
13342         walk_variable_lifetimes(state, blocks, fix_tangles, &tangles);
13343         return tangles;
13344 }
13345
13346
13347 static void ids_from_rstate(struct compile_state *state, struct reg_state *rstate);
13348 static void cleanup_rstate(struct compile_state *state, struct reg_state *rstate);
13349
13350 struct triple *find_constrained_def(
13351         struct compile_state *state, struct live_range *range, struct triple *constrained)
13352 {
13353         struct live_range_def *lrd;
13354         lrd = range->defs;
13355         do {
13356                 struct reg_info info;
13357                 unsigned regcm;
13358                 int is_constrained;
13359                 regcm = arch_type_to_regcm(state, lrd->def->type);
13360                 info = find_lhs_color(state, lrd->def, 0);
13361                 regcm      = arch_regcm_reg_normalize(state, regcm);
13362                 info.regcm = arch_regcm_reg_normalize(state, info.regcm);
13363                 /* If the 2 register class masks are not equal the
13364                  * the current register class is constrained.
13365                  */
13366                 is_constrained = regcm != info.regcm;
13367                 
13368                 /* Of the constrained live ranges deal with the
13369                  * least dominated one first.
13370                  */
13371                 if (is_constrained) {
13372 #if DEBUG_RANGE_CONFLICTS
13373                         fprintf(stderr, "canidate: %p %-8s regcm: %x %x\n",
13374                                 lrd->def, tops(lrd->def->op), regcm, info.regcm);
13375 #endif
13376                         if (!constrained || 
13377                                 tdominates(state, lrd->def, constrained))
13378                         {
13379                                 constrained = lrd->def;
13380                         }
13381                 }
13382                 lrd = lrd->next;
13383         } while(lrd != range->defs);
13384         return constrained;
13385 }
13386
13387 static int split_constrained_ranges(
13388         struct compile_state *state, struct reg_state *rstate, 
13389         struct live_range *range)
13390 {
13391         /* Walk through the edges in conflict and our current live
13392          * range, and find definitions that are more severly constrained
13393          * than they type of data they contain require.
13394          * 
13395          * Then pick one of those ranges and relax the constraints.
13396          */
13397         struct live_range_edge *edge;
13398         struct triple *constrained;
13399
13400         constrained = 0;
13401         for(edge = range->edges; edge; edge = edge->next) {
13402                 constrained = find_constrained_def(state, edge->node, constrained);
13403         }
13404         if (!constrained) {
13405                 constrained = find_constrained_def(state, range, constrained);
13406         }
13407 #if DEBUG_RANGE_CONFLICTS
13408         fprintf(stderr, "constrained: %p %-8s\n",
13409                 constrained, tops(constrained->op));
13410 #endif
13411         if (constrained) {
13412                 ids_from_rstate(state, rstate);
13413                 cleanup_rstate(state, rstate);
13414                 resolve_tangle(state, constrained);
13415         }
13416         return !!constrained;
13417 }
13418         
13419 static int split_ranges(
13420         struct compile_state *state, struct reg_state *rstate,
13421         char *used, struct live_range *range)
13422 {
13423         int split;
13424 #if DEBUG_RANGE_CONFLICTS
13425         fprintf(stderr, "split_ranges %d %s %p\n", 
13426                 rstate->passes, tops(range->defs->def->op), range->defs->def);
13427 #endif
13428         if ((range->color == REG_UNNEEDED) ||
13429                 (rstate->passes >= rstate->max_passes)) {
13430                 return 0;
13431         }
13432         split = split_constrained_ranges(state, rstate, range);
13433
13434         /* Ideally I would split the live range that will not be used
13435          * for the longest period of time in hopes that this will 
13436          * (a) allow me to spill a register or
13437          * (b) allow me to place a value in another register.
13438          *
13439          * So far I don't have a test case for this, the resolving
13440          * of mandatory constraints has solved all of my
13441          * know issues.  So I have choosen not to write any
13442          * code until I cat get a better feel for cases where
13443          * it would be useful to have.
13444          *
13445          */
13446 #warning "WISHLIST implement live range splitting..."
13447         if ((DEBUG_RANGE_CONFLICTS > 1) && 
13448                 (!split || (DEBUG_RANGE_CONFLICTS > 2))) {
13449                 print_interference_blocks(state, rstate, stderr, 0);
13450                 print_dominators(state, stderr);
13451         }
13452         return split;
13453 }
13454
13455 #if DEBUG_COLOR_GRAPH > 1
13456 #define cgdebug_printf(...) fprintf(stdout, __VA_ARGS__)
13457 #define cgdebug_flush() fflush(stdout)
13458 #define cgdebug_loc(STATE, TRIPLE) loc(stdout, STATE, TRIPLE)
13459 #elif DEBUG_COLOR_GRAPH == 1
13460 #define cgdebug_printf(...) fprintf(stderr, __VA_ARGS__)
13461 #define cgdebug_flush() fflush(stderr)
13462 #define cgdebug_loc(STATE, TRIPLE) loc(stderr, STATE, TRIPLE)
13463 #else
13464 #define cgdebug_printf(...)
13465 #define cgdebug_flush()
13466 #define cgdebug_loc(STATE, TRIPLE)
13467 #endif
13468
13469         
13470 static int select_free_color(struct compile_state *state, 
13471         struct reg_state *rstate, struct live_range *range)
13472 {
13473         struct triple_set *entry;
13474         struct live_range_def *lrd;
13475         struct live_range_def *phi;
13476         struct live_range_edge *edge;
13477         char used[MAX_REGISTERS];
13478         struct triple **expr;
13479
13480         /* Instead of doing just the trivial color select here I try
13481          * a few extra things because a good color selection will help reduce
13482          * copies.
13483          */
13484
13485         /* Find the registers currently in use */
13486         memset(used, 0, sizeof(used));
13487         for(edge = range->edges; edge; edge = edge->next) {
13488                 if (edge->node->color == REG_UNSET) {
13489                         continue;
13490                 }
13491                 reg_fill_used(state, used, edge->node->color);
13492         }
13493 #if DEBUG_COLOR_GRAPH > 1
13494         {
13495                 int i;
13496                 i = 0;
13497                 for(edge = range->edges; edge; edge = edge->next) {
13498                         i++;
13499                 }
13500                 cgdebug_printf("\n%s edges: %d @%s:%d.%d\n", 
13501                         tops(range->def->op), i, 
13502                         range->def->filename, range->def->line, range->def->col);
13503                 for(i = 0; i < MAX_REGISTERS; i++) {
13504                         if (used[i]) {
13505                                 cgdebug_printf("used: %s\n",
13506                                         arch_reg_str(i));
13507                         }
13508                 }
13509         }       
13510 #endif
13511
13512         /* If a color is already assigned see if it will work */
13513         if (range->color != REG_UNSET) {
13514                 struct live_range_def *lrd;
13515                 if (!used[range->color]) {
13516                         return 1;
13517                 }
13518                 for(edge = range->edges; edge; edge = edge->next) {
13519                         if (edge->node->color != range->color) {
13520                                 continue;
13521                         }
13522                         warning(state, edge->node->defs->def, "edge: ");
13523                         lrd = edge->node->defs;
13524                         do {
13525                                 warning(state, lrd->def, " %p %s",
13526                                         lrd->def, tops(lrd->def->op));
13527                                 lrd = lrd->next;
13528                         } while(lrd != edge->node->defs);
13529                 }
13530                 lrd = range->defs;
13531                 warning(state, range->defs->def, "def: ");
13532                 do {
13533                         warning(state, lrd->def, " %p %s",
13534                                 lrd->def, tops(lrd->def->op));
13535                         lrd = lrd->next;
13536                 } while(lrd != range->defs);
13537                 internal_error(state, range->defs->def,
13538                         "live range with already used color %s",
13539                         arch_reg_str(range->color));
13540         }
13541
13542         /* If I feed into an expression reuse it's color.
13543          * This should help remove copies in the case of 2 register instructions
13544          * and phi functions.
13545          */
13546         phi = 0;
13547         lrd = live_range_end(state, range, 0);
13548         for(; (range->color == REG_UNSET) && lrd ; lrd = live_range_end(state, range, lrd)) {
13549                 entry = lrd->def->use;
13550                 for(;(range->color == REG_UNSET) && entry; entry = entry->next) {
13551                         struct live_range_def *insd;
13552                         unsigned regcm;
13553                         insd = &rstate->lrd[entry->member->id];
13554                         if (insd->lr->defs == 0) {
13555                                 continue;
13556                         }
13557                         if (!phi && (insd->def->op == OP_PHI) &&
13558                                 !interfere(rstate, range, insd->lr)) {
13559                                 phi = insd;
13560                         }
13561                         if (insd->lr->color == REG_UNSET) {
13562                                 continue;
13563                         }
13564                         regcm = insd->lr->classes;
13565                         if (((regcm & range->classes) == 0) ||
13566                                 (used[insd->lr->color])) {
13567                                 continue;
13568                         }
13569                         if (interfere(rstate, range, insd->lr)) {
13570                                 continue;
13571                         }
13572                         range->color = insd->lr->color;
13573                 }
13574         }
13575         /* If I feed into a phi function reuse it's color or the color
13576          * of something else that feeds into the phi function.
13577          */
13578         if (phi) {
13579                 if (phi->lr->color != REG_UNSET) {
13580                         if (used[phi->lr->color]) {
13581                                 range->color = phi->lr->color;
13582                         }
13583                 }
13584                 else {
13585                         expr = triple_rhs(state, phi->def, 0);
13586                         for(; expr; expr = triple_rhs(state, phi->def, expr)) {
13587                                 struct live_range *lr;
13588                                 unsigned regcm;
13589                                 if (!*expr) {
13590                                         continue;
13591                                 }
13592                                 lr = rstate->lrd[(*expr)->id].lr;
13593                                 if (lr->color == REG_UNSET) {
13594                                         continue;
13595                                 }
13596                                 regcm = lr->classes;
13597                                 if (((regcm & range->classes) == 0) ||
13598                                         (used[lr->color])) {
13599                                         continue;
13600                                 }
13601                                 if (interfere(rstate, range, lr)) {
13602                                         continue;
13603                                 }
13604                                 range->color = lr->color;
13605                         }
13606                 }
13607         }
13608         /* If I don't interfere with a rhs node reuse it's color */
13609         lrd = live_range_head(state, range, 0);
13610         for(; (range->color == REG_UNSET) && lrd ; lrd = live_range_head(state, range, lrd)) {
13611                 expr = triple_rhs(state, lrd->def, 0);
13612                 for(; expr; expr = triple_rhs(state, lrd->def, expr)) {
13613                         struct live_range *lr;
13614                         unsigned regcm;
13615                         if (!*expr) {
13616                                 continue;
13617                         }
13618                         lr = rstate->lrd[(*expr)->id].lr;
13619                         if (lr->color == REG_UNSET) {
13620                                 continue;
13621                         }
13622                         regcm = lr->classes;
13623                         if (((regcm & range->classes) == 0) ||
13624                                 (used[lr->color])) {
13625                                 continue;
13626                         }
13627                         if (interfere(rstate, range, lr)) {
13628                                 continue;
13629                         }
13630                         range->color = lr->color;
13631                         break;
13632                 }
13633         }
13634         /* If I have not opportunitically picked a useful color
13635          * pick the first color that is free.
13636          */
13637         if (range->color == REG_UNSET) {
13638                 range->color = 
13639                         arch_select_free_register(state, used, range->classes);
13640         }
13641         if (range->color == REG_UNSET) {
13642                 struct live_range_def *lrd;
13643                 int i;
13644                 if (split_ranges(state, rstate, used, range)) {
13645                         return 0;
13646                 }
13647                 for(edge = range->edges; edge; edge = edge->next) {
13648                         warning(state, edge->node->defs->def, "edge reg %s",
13649                                 arch_reg_str(edge->node->color));
13650                         lrd = edge->node->defs;
13651                         do {
13652                                 warning(state, lrd->def, " %s %p",
13653                                         tops(lrd->def->op), lrd->def);
13654                                 lrd = lrd->next;
13655                         } while(lrd != edge->node->defs);
13656                 }
13657                 warning(state, range->defs->def, "range: ");
13658                 lrd = range->defs;
13659                 do {
13660                         warning(state, lrd->def, " %s %p",
13661                                 tops(lrd->def->op), lrd->def);
13662                         lrd = lrd->next;
13663                 } while(lrd != range->defs);
13664                         
13665                 warning(state, range->defs->def, "classes: %x",
13666                         range->classes);
13667                 for(i = 0; i < MAX_REGISTERS; i++) {
13668                         if (used[i]) {
13669                                 warning(state, range->defs->def, "used: %s",
13670                                         arch_reg_str(i));
13671                         }
13672                 }
13673 #if DEBUG_COLOR_GRAPH < 2
13674                 error(state, range->defs->def, "too few registers");
13675 #else
13676                 internal_error(state, range->defs->def, "too few registers");
13677 #endif
13678         }
13679         range->classes &= arch_reg_regcm(state, range->color);
13680         if ((range->color == REG_UNSET) || (range->classes == 0)) {
13681                 internal_error(state, range->defs->def, "select_free_color did not?");
13682         }
13683         return 1;
13684 }
13685
13686 static int color_graph(struct compile_state *state, struct reg_state *rstate)
13687 {
13688         int colored;
13689         struct live_range_edge *edge;
13690         struct live_range *range;
13691         if (rstate->low) {
13692                 cgdebug_printf("Lo: ");
13693                 range = rstate->low;
13694                 if (*range->group_prev != range) {
13695                         internal_error(state, 0, "lo: *prev != range?");
13696                 }
13697                 *range->group_prev = range->group_next;
13698                 if (range->group_next) {
13699                         range->group_next->group_prev = range->group_prev;
13700                 }
13701                 if (&range->group_next == rstate->low_tail) {
13702                         rstate->low_tail = range->group_prev;
13703                 }
13704                 if (rstate->low == range) {
13705                         internal_error(state, 0, "low: next != prev?");
13706                 }
13707         }
13708         else if (rstate->high) {
13709                 cgdebug_printf("Hi: ");
13710                 range = rstate->high;
13711                 if (*range->group_prev != range) {
13712                         internal_error(state, 0, "hi: *prev != range?");
13713                 }
13714                 *range->group_prev = range->group_next;
13715                 if (range->group_next) {
13716                         range->group_next->group_prev = range->group_prev;
13717                 }
13718                 if (&range->group_next == rstate->high_tail) {
13719                         rstate->high_tail = range->group_prev;
13720                 }
13721                 if (rstate->high == range) {
13722                         internal_error(state, 0, "high: next != prev?");
13723                 }
13724         }
13725         else {
13726                 return 1;
13727         }
13728         cgdebug_printf(" %d\n", range - rstate->lr);
13729         range->group_prev = 0;
13730         for(edge = range->edges; edge; edge = edge->next) {
13731                 struct live_range *node;
13732                 node = edge->node;
13733                 /* Move nodes from the high to the low list */
13734                 if (node->group_prev && (node->color == REG_UNSET) &&
13735                         (node->degree == regc_max_size(state, node->classes))) {
13736                         if (*node->group_prev != node) {
13737                                 internal_error(state, 0, "move: *prev != node?");
13738                         }
13739                         *node->group_prev = node->group_next;
13740                         if (node->group_next) {
13741                                 node->group_next->group_prev = node->group_prev;
13742                         }
13743                         if (&node->group_next == rstate->high_tail) {
13744                                 rstate->high_tail = node->group_prev;
13745                         }
13746                         cgdebug_printf("Moving...%d to low\n", node - rstate->lr);
13747                         node->group_prev  = rstate->low_tail;
13748                         node->group_next  = 0;
13749                         *rstate->low_tail = node;
13750                         rstate->low_tail  = &node->group_next;
13751                         if (*node->group_prev != node) {
13752                                 internal_error(state, 0, "move2: *prev != node?");
13753                         }
13754                 }
13755                 node->degree -= 1;
13756         }
13757         colored = color_graph(state, rstate);
13758         if (colored) {
13759                 cgdebug_printf("Coloring %d @", range - rstate->lr);
13760                 cgdebug_loc(state, range->defs->def);
13761                 cgdebug_flush();
13762                 colored = select_free_color(state, rstate, range);
13763                 cgdebug_printf(" %s\n", arch_reg_str(range->color));
13764         }
13765         return colored;
13766 }
13767
13768 static void verify_colors(struct compile_state *state, struct reg_state *rstate)
13769 {
13770         struct live_range *lr;
13771         struct live_range_edge *edge;
13772         struct triple *ins, *first;
13773         char used[MAX_REGISTERS];
13774         first = RHS(state->main_function, 0);
13775         ins = first;
13776         do {
13777                 if (triple_is_def(state, ins)) {
13778                         if ((ins->id < 0) || (ins->id > rstate->defs)) {
13779                                 internal_error(state, ins, 
13780                                         "triple without a live range def");
13781                         }
13782                         lr = rstate->lrd[ins->id].lr;
13783                         if (lr->color == REG_UNSET) {
13784                                 internal_error(state, ins,
13785                                         "triple without a color");
13786                         }
13787                         /* Find the registers used by the edges */
13788                         memset(used, 0, sizeof(used));
13789                         for(edge = lr->edges; edge; edge = edge->next) {
13790                                 if (edge->node->color == REG_UNSET) {
13791                                         internal_error(state, 0,
13792                                                 "live range without a color");
13793                         }
13794                                 reg_fill_used(state, used, edge->node->color);
13795                         }
13796                         if (used[lr->color]) {
13797                                 internal_error(state, ins,
13798                                         "triple with already used color");
13799                         }
13800                 }
13801                 ins = ins->next;
13802         } while(ins != first);
13803 }
13804
13805 static void color_triples(struct compile_state *state, struct reg_state *rstate)
13806 {
13807         struct live_range *lr;
13808         struct triple *first, *ins;
13809         first = RHS(state->main_function, 0);
13810         ins = first;
13811         do {
13812                 if ((ins->id < 0) || (ins->id > rstate->defs)) {
13813                         internal_error(state, ins, 
13814                                 "triple without a live range");
13815                 }
13816                 lr = rstate->lrd[ins->id].lr;
13817                 SET_REG(ins->id, lr->color);
13818                 ins = ins->next;
13819         } while (ins != first);
13820 }
13821
13822 static struct live_range *merge_sort_lr(
13823         struct live_range *first, struct live_range *last)
13824 {
13825         struct live_range *mid, *join, **join_tail, *pick;
13826         size_t size;
13827         size = (last - first) + 1;
13828         if (size >= 2) {
13829                 mid = first + size/2;
13830                 first = merge_sort_lr(first, mid -1);
13831                 mid   = merge_sort_lr(mid, last);
13832                 
13833                 join = 0;
13834                 join_tail = &join;
13835                 /* merge the two lists */
13836                 while(first && mid) {
13837                         if ((first->degree < mid->degree) ||
13838                                 ((first->degree == mid->degree) &&
13839                                         (first->length < mid->length))) {
13840                                 pick = first;
13841                                 first = first->group_next;
13842                                 if (first) {
13843                                         first->group_prev = 0;
13844                                 }
13845                         }
13846                         else {
13847                                 pick = mid;
13848                                 mid = mid->group_next;
13849                                 if (mid) {
13850                                         mid->group_prev = 0;
13851                                 }
13852                         }
13853                         pick->group_next = 0;
13854                         pick->group_prev = join_tail;
13855                         *join_tail = pick;
13856                         join_tail = &pick->group_next;
13857                 }
13858                 /* Splice the remaining list */
13859                 pick = (first)? first : mid;
13860                 *join_tail = pick;
13861                 if (pick) { 
13862                         pick->group_prev = join_tail;
13863                 }
13864         }
13865         else {
13866                 if (!first->defs) {
13867                         first = 0;
13868                 }
13869                 join = first;
13870         }
13871         return join;
13872 }
13873
13874 static void ids_from_rstate(struct compile_state *state, 
13875         struct reg_state *rstate)
13876 {
13877         struct triple *ins, *first;
13878         if (!rstate->defs) {
13879                 return;
13880         }
13881         /* Display the graph if desired */
13882         if (state->debug & DEBUG_INTERFERENCE) {
13883                 print_blocks(state, stdout);
13884                 print_control_flow(state);
13885         }
13886         first = RHS(state->main_function, 0);
13887         ins = first;
13888         do {
13889                 if (ins->id) {
13890                         struct live_range_def *lrd;
13891                         lrd = &rstate->lrd[ins->id];
13892                         ins->id = lrd->orig_id;
13893                 }
13894                 ins = ins->next;
13895         } while(ins != first);
13896 }
13897
13898 static void cleanup_live_edges(struct reg_state *rstate)
13899 {
13900         int i;
13901         /* Free the edges on each node */
13902         for(i = 1; i <= rstate->ranges; i++) {
13903                 remove_live_edges(rstate, &rstate->lr[i]);
13904         }
13905 }
13906
13907 static void cleanup_rstate(struct compile_state *state, struct reg_state *rstate)
13908 {
13909         cleanup_live_edges(rstate);
13910         xfree(rstate->lrd);
13911         xfree(rstate->lr);
13912
13913         /* Free the variable lifetime information */
13914         if (rstate->blocks) {
13915                 free_variable_lifetimes(state, rstate->blocks);
13916         }
13917         rstate->defs = 0;
13918         rstate->ranges = 0;
13919         rstate->lrd = 0;
13920         rstate->lr = 0;
13921         rstate->blocks = 0;
13922 }
13923
13924 static void verify_consistency(struct compile_state *state);
13925 static void allocate_registers(struct compile_state *state)
13926 {
13927         struct reg_state rstate;
13928         int colored;
13929
13930         /* Clear out the reg_state */
13931         memset(&rstate, 0, sizeof(rstate));
13932         rstate.max_passes = MAX_ALLOCATION_PASSES;
13933
13934         do {
13935                 struct live_range **point, **next;
13936                 int conflicts;
13937                 int tangles;
13938                 int coalesced;
13939
13940 #if DEBUG_RANGE_CONFLICTS
13941                 fprintf(stderr, "pass: %d\n", rstate.passes);
13942 #endif
13943
13944                 /* Restore ids */
13945                 ids_from_rstate(state, &rstate);
13946
13947                 /* Cleanup the temporary data structures */
13948                 cleanup_rstate(state, &rstate);
13949
13950                 /* Compute the variable lifetimes */
13951                 rstate.blocks = compute_variable_lifetimes(state);
13952
13953                 /* Fix invalid mandatory live range coalesce conflicts */
13954                 conflicts = correct_coalesce_conflicts(state, rstate.blocks);
13955
13956                 /* Fix two simultaneous uses of the same register.
13957                  * In a few pathlogical cases a partial untangle moves
13958                  * the tangle to a part of the graph we won't revisit.
13959                  * So we keep looping until we have no more tangle fixes
13960                  * to apply.
13961                  */
13962                 do {
13963                         tangles = correct_tangles(state, rstate.blocks);
13964                 } while(tangles);
13965
13966                 if (state->debug & DEBUG_INSERTED_COPIES) {
13967                         printf("After resolve_tangles\n");
13968                         print_blocks(state, stdout);
13969                         print_control_flow(state);
13970                 }
13971                 verify_consistency(state);
13972                 
13973                 /* Allocate and initialize the live ranges */
13974                 initialize_live_ranges(state, &rstate);
13975
13976                 /* Note current doing coalescing in a loop appears to 
13977                  * buys me nothing.  The code is left this way in case
13978                  * there is some value in it.  Or if a future bugfix
13979                  *  yields some benefit.
13980                  */
13981                 do {
13982 #if DEBUG_COALESCING
13983                         fprintf(stderr, "coalescing\n");
13984 #endif                  
13985                         /* Remove any previous live edge calculations */
13986                         cleanup_live_edges(&rstate);
13987
13988                         /* Compute the interference graph */
13989                         walk_variable_lifetimes(
13990                                 state, rstate.blocks, graph_ins, &rstate);
13991                         
13992                         /* Display the interference graph if desired */
13993                         if (state->debug & DEBUG_INTERFERENCE) {
13994                                 print_interference_blocks(state, &rstate, stdout, 1);
13995                                 printf("\nlive variables by instruction\n");
13996                                 walk_variable_lifetimes(
13997                                         state, rstate.blocks, 
13998                                         print_interference_ins, &rstate);
13999                         }
14000                         
14001                         coalesced = coalesce_live_ranges(state, &rstate);
14002
14003 #if DEBUG_COALESCING
14004                         fprintf(stderr, "coalesced: %d\n", coalesced);
14005 #endif
14006                 } while(coalesced);
14007
14008 #if DEBUG_CONSISTENCY > 1
14009 # if 0
14010                 fprintf(stderr, "verify_graph_ins...\n");
14011 # endif
14012                 /* Verify the interference graph */
14013                 walk_variable_lifetimes(
14014                         state, rstate.blocks, verify_graph_ins, &rstate);
14015 # if 0
14016                 fprintf(stderr, "verify_graph_ins done\n");
14017 #endif
14018 #endif
14019                         
14020                 /* Build the groups low and high.  But with the nodes
14021                  * first sorted by degree order.
14022                  */
14023                 rstate.low_tail  = &rstate.low;
14024                 rstate.high_tail = &rstate.high;
14025                 rstate.high = merge_sort_lr(&rstate.lr[1], &rstate.lr[rstate.ranges]);
14026                 if (rstate.high) {
14027                         rstate.high->group_prev = &rstate.high;
14028                 }
14029                 for(point = &rstate.high; *point; point = &(*point)->group_next)
14030                         ;
14031                 rstate.high_tail = point;
14032                 /* Walk through the high list and move everything that needs
14033                  * to be onto low.
14034                  */
14035                 for(point = &rstate.high; *point; point = next) {
14036                         struct live_range *range;
14037                         next = &(*point)->group_next;
14038                         range = *point;
14039                         
14040                         /* If it has a low degree or it already has a color
14041                          * place the node in low.
14042                          */
14043                         if ((range->degree < regc_max_size(state, range->classes)) ||
14044                                 (range->color != REG_UNSET)) {
14045                                 cgdebug_printf("Lo: %5d degree %5d%s\n", 
14046                                         range - rstate.lr, range->degree,
14047                                         (range->color != REG_UNSET) ? " (colored)": "");
14048                                 *range->group_prev = range->group_next;
14049                                 if (range->group_next) {
14050                                         range->group_next->group_prev = range->group_prev;
14051                                 }
14052                                 if (&range->group_next == rstate.high_tail) {
14053                                         rstate.high_tail = range->group_prev;
14054                                 }
14055                                 range->group_prev  = rstate.low_tail;
14056                                 range->group_next  = 0;
14057                                 *rstate.low_tail   = range;
14058                                 rstate.low_tail    = &range->group_next;
14059                                 next = point;
14060                         }
14061                         else {
14062                                 cgdebug_printf("hi: %5d degree %5d%s\n", 
14063                                         range - rstate.lr, range->degree,
14064                                         (range->color != REG_UNSET) ? " (colored)": "");
14065                         }
14066                 }
14067                 /* Color the live_ranges */
14068                 colored = color_graph(state, &rstate);
14069                 rstate.passes++;
14070         } while (!colored);
14071
14072         /* Verify the graph was properly colored */
14073         verify_colors(state, &rstate);
14074
14075         /* Move the colors from the graph to the triples */
14076         color_triples(state, &rstate);
14077
14078         /* Cleanup the temporary data structures */
14079         cleanup_rstate(state, &rstate);
14080 }
14081
14082 /* Sparce Conditional Constant Propogation
14083  * =========================================
14084  */
14085 struct ssa_edge;
14086 struct flow_block;
14087 struct lattice_node {
14088         unsigned old_id;
14089         struct triple *def;
14090         struct ssa_edge *out;
14091         struct flow_block *fblock;
14092         struct triple *val;
14093         /* lattice high   val && !is_const(val) 
14094          * lattice const  is_const(val)
14095          * lattice low    val == 0
14096          */
14097 };
14098 struct ssa_edge {
14099         struct lattice_node *src;
14100         struct lattice_node *dst;
14101         struct ssa_edge *work_next;
14102         struct ssa_edge *work_prev;
14103         struct ssa_edge *out_next;
14104 };
14105 struct flow_edge {
14106         struct flow_block *src;
14107         struct flow_block *dst;
14108         struct flow_edge *work_next;
14109         struct flow_edge *work_prev;
14110         struct flow_edge *in_next;
14111         struct flow_edge *out_next;
14112         int executable;
14113 };
14114 struct flow_block {
14115         struct block *block;
14116         struct flow_edge *in;
14117         struct flow_edge *out;
14118         struct flow_edge left, right;
14119 };
14120
14121 struct scc_state {
14122         int ins_count;
14123         struct lattice_node *lattice;
14124         struct ssa_edge     *ssa_edges;
14125         struct flow_block   *flow_blocks;
14126         struct flow_edge    *flow_work_list;
14127         struct ssa_edge     *ssa_work_list;
14128 };
14129
14130
14131 static void scc_add_fedge(struct compile_state *state, struct scc_state *scc, 
14132         struct flow_edge *fedge)
14133 {
14134         if (!scc->flow_work_list) {
14135                 scc->flow_work_list = fedge;
14136                 fedge->work_next = fedge->work_prev = fedge;
14137         }
14138         else {
14139                 struct flow_edge *ftail;
14140                 ftail = scc->flow_work_list->work_prev;
14141                 fedge->work_next = ftail->work_next;
14142                 fedge->work_prev = ftail;
14143                 fedge->work_next->work_prev = fedge;
14144                 fedge->work_prev->work_next = fedge;
14145         }
14146 }
14147
14148 static struct flow_edge *scc_next_fedge(
14149         struct compile_state *state, struct scc_state *scc)
14150 {
14151         struct flow_edge *fedge;
14152         fedge = scc->flow_work_list;
14153         if (fedge) {
14154                 fedge->work_next->work_prev = fedge->work_prev;
14155                 fedge->work_prev->work_next = fedge->work_next;
14156                 if (fedge->work_next != fedge) {
14157                         scc->flow_work_list = fedge->work_next;
14158                 } else {
14159                         scc->flow_work_list = 0;
14160                 }
14161         }
14162         return fedge;
14163 }
14164
14165 static void scc_add_sedge(struct compile_state *state, struct scc_state *scc,
14166         struct ssa_edge *sedge)
14167 {
14168         if (!scc->ssa_work_list) {
14169                 scc->ssa_work_list = sedge;
14170                 sedge->work_next = sedge->work_prev = sedge;
14171         }
14172         else {
14173                 struct ssa_edge *stail;
14174                 stail = scc->ssa_work_list->work_prev;
14175                 sedge->work_next = stail->work_next;
14176                 sedge->work_prev = stail;
14177                 sedge->work_next->work_prev = sedge;
14178                 sedge->work_prev->work_next = sedge;
14179         }
14180 }
14181
14182 static struct ssa_edge *scc_next_sedge(
14183         struct compile_state *state, struct scc_state *scc)
14184 {
14185         struct ssa_edge *sedge;
14186         sedge = scc->ssa_work_list;
14187         if (sedge) {
14188                 sedge->work_next->work_prev = sedge->work_prev;
14189                 sedge->work_prev->work_next = sedge->work_next;
14190                 if (sedge->work_next != sedge) {
14191                         scc->ssa_work_list = sedge->work_next;
14192                 } else {
14193                         scc->ssa_work_list = 0;
14194                 }
14195         }
14196         return sedge;
14197 }
14198
14199 static void initialize_scc_state(
14200         struct compile_state *state, struct scc_state *scc)
14201 {
14202         int ins_count, ssa_edge_count;
14203         int ins_index, ssa_edge_index, fblock_index;
14204         struct triple *first, *ins;
14205         struct block *block;
14206         struct flow_block *fblock;
14207
14208         memset(scc, 0, sizeof(*scc));
14209
14210         /* Inialize pass zero find out how much memory we need */
14211         first = RHS(state->main_function, 0);
14212         ins = first;
14213         ins_count = ssa_edge_count = 0;
14214         do {
14215                 struct triple_set *edge;
14216                 ins_count += 1;
14217                 for(edge = ins->use; edge; edge = edge->next) {
14218                         ssa_edge_count++;
14219                 }
14220                 ins = ins->next;
14221         } while(ins != first);
14222 #if DEBUG_SCC
14223         fprintf(stderr, "ins_count: %d ssa_edge_count: %d vertex_count: %d\n",
14224                 ins_count, ssa_edge_count, state->last_vertex);
14225 #endif
14226         scc->ins_count   = ins_count;
14227         scc->lattice     = 
14228                 xcmalloc(sizeof(*scc->lattice)*(ins_count + 1), "lattice");
14229         scc->ssa_edges   = 
14230                 xcmalloc(sizeof(*scc->ssa_edges)*(ssa_edge_count + 1), "ssa_edges");
14231         scc->flow_blocks = 
14232                 xcmalloc(sizeof(*scc->flow_blocks)*(state->last_vertex + 1), 
14233                         "flow_blocks");
14234
14235         /* Initialize pass one collect up the nodes */
14236         fblock = 0;
14237         block = 0;
14238         ins_index = ssa_edge_index = fblock_index = 0;
14239         ins = first;
14240         do {
14241                 if ((ins->op == OP_LABEL) && (block != ins->u.block)) {
14242                         block = ins->u.block;
14243                         if (!block) {
14244                                 internal_error(state, ins, "label without block");
14245                         }
14246                         fblock_index += 1;
14247                         block->vertex = fblock_index;
14248                         fblock = &scc->flow_blocks[fblock_index];
14249                         fblock->block = block;
14250                 }
14251                 {
14252                         struct lattice_node *lnode;
14253                         ins_index += 1;
14254                         lnode = &scc->lattice[ins_index];
14255                         lnode->def = ins;
14256                         lnode->out = 0;
14257                         lnode->fblock = fblock;
14258                         lnode->val = ins; /* LATTICE HIGH */
14259                         lnode->old_id = ins->id;
14260                         ins->id = ins_index;
14261                 }
14262                 ins = ins->next;
14263         } while(ins != first);
14264         /* Initialize pass two collect up the edges */
14265         block = 0;
14266         fblock = 0;
14267         ins = first;
14268         do {
14269                 if ((ins->op == OP_LABEL) && (block != ins->u.block)) {
14270                         struct flow_edge *fedge, **ftail;
14271                         struct block_set *bedge;
14272                         block = ins->u.block;
14273                         fblock = &scc->flow_blocks[block->vertex];
14274                         fblock->in = 0;
14275                         fblock->out = 0;
14276                         ftail = &fblock->out;
14277                         if (block->left) {
14278                                 fblock->left.dst = &scc->flow_blocks[block->left->vertex];
14279                                 if (fblock->left.dst->block != block->left) {
14280                                         internal_error(state, 0, "block mismatch");
14281                                 }
14282                                 fblock->left.out_next = 0;
14283                                 *ftail = &fblock->left;
14284                                 ftail = &fblock->left.out_next;
14285                         }
14286                         if (block->right) {
14287                                 fblock->right.dst = &scc->flow_blocks[block->right->vertex];
14288                                 if (fblock->right.dst->block != block->right) {
14289                                         internal_error(state, 0, "block mismatch");
14290                                 }
14291                                 fblock->right.out_next = 0;
14292                                 *ftail = &fblock->right;
14293                                 ftail = &fblock->right.out_next;
14294                         }
14295                         for(fedge = fblock->out; fedge; fedge = fedge->out_next) {
14296                                 fedge->src = fblock;
14297                                 fedge->work_next = fedge->work_prev = fedge;
14298                                 fedge->executable = 0;
14299                         }
14300                         ftail = &fblock->in;
14301                         for(bedge = block->use; bedge; bedge = bedge->next) {
14302                                 struct block *src_block;
14303                                 struct flow_block *sfblock;
14304                                 struct flow_edge *sfedge;
14305                                 src_block = bedge->member;
14306                                 sfblock = &scc->flow_blocks[src_block->vertex];
14307                                 sfedge = 0;
14308                                 if (src_block->left == block) {
14309                                         sfedge = &sfblock->left;
14310                                 } else {
14311                                         sfedge = &sfblock->right;
14312                                 }
14313                                 *ftail = sfedge;
14314                                 ftail = &sfedge->in_next;
14315                                 sfedge->in_next = 0;
14316                         }
14317                 }
14318                 {
14319                         struct triple_set *edge;
14320                         struct ssa_edge **stail;
14321                         struct lattice_node *lnode;
14322                         lnode = &scc->lattice[ins->id];
14323                         lnode->out = 0;
14324                         stail = &lnode->out;
14325                         for(edge = ins->use; edge; edge = edge->next) {
14326                                 struct ssa_edge *sedge;
14327                                 ssa_edge_index += 1;
14328                                 sedge = &scc->ssa_edges[ssa_edge_index];
14329                                 *stail = sedge;
14330                                 stail = &sedge->out_next;
14331                                 sedge->src = lnode;
14332                                 sedge->dst = &scc->lattice[edge->member->id];
14333                                 sedge->work_next = sedge->work_prev = sedge;
14334                                 sedge->out_next = 0;
14335                         }
14336                 }
14337                 ins = ins->next;
14338         } while(ins != first);
14339         /* Setup a dummy block 0 as a node above the start node */
14340         {
14341                 struct flow_block *fblock, *dst;
14342                 struct flow_edge *fedge;
14343                 fblock = &scc->flow_blocks[0];
14344                 fblock->block = 0;
14345                 fblock->in = 0;
14346                 fblock->out = &fblock->left;
14347                 dst = &scc->flow_blocks[state->first_block->vertex];
14348                 fedge = &fblock->left;
14349                 fedge->src        = fblock;
14350                 fedge->dst        = dst;
14351                 fedge->work_next  = fedge;
14352                 fedge->work_prev  = fedge;
14353                 fedge->in_next    = fedge->dst->in;
14354                 fedge->out_next   = 0;
14355                 fedge->executable = 0;
14356                 fedge->dst->in = fedge;
14357                 
14358                 /* Initialize the work lists */
14359                 scc->flow_work_list = 0;
14360                 scc->ssa_work_list  = 0;
14361                 scc_add_fedge(state, scc, fedge);
14362         }
14363 #if DEBUG_SCC
14364         fprintf(stderr, "ins_index: %d ssa_edge_index: %d fblock_index: %d\n",
14365                 ins_index, ssa_edge_index, fblock_index);
14366 #endif
14367 }
14368
14369         
14370 static void free_scc_state(
14371         struct compile_state *state, struct scc_state *scc)
14372 {
14373         xfree(scc->flow_blocks);
14374         xfree(scc->ssa_edges);
14375         xfree(scc->lattice);
14376         
14377 }
14378
14379 static struct lattice_node *triple_to_lattice(
14380         struct compile_state *state, struct scc_state *scc, struct triple *ins)
14381 {
14382         if (ins->id <= 0) {
14383                 internal_error(state, ins, "bad id");
14384         }
14385         return &scc->lattice[ins->id];
14386 }
14387
14388 static struct triple *preserve_lval(
14389         struct compile_state *state, struct lattice_node *lnode)
14390 {
14391         struct triple *old;
14392         /* Preserve the original value */
14393         if (lnode->val) {
14394                 old = dup_triple(state, lnode->val);
14395                 if (lnode->val != lnode->def) {
14396                         xfree(lnode->val);
14397                 }
14398                 lnode->val = 0;
14399         } else {
14400                 old = 0;
14401         }
14402         return old;
14403 }
14404
14405 static int lval_changed(struct compile_state *state, 
14406         struct triple *old, struct lattice_node *lnode)
14407 {
14408         int changed;
14409         /* See if the lattice value has changed */
14410         changed = 1;
14411         if (!old && !lnode->val) {
14412                 changed = 0;
14413         }
14414         if (changed && lnode->val && !is_const(lnode->val)) {
14415                 changed = 0;
14416         }
14417         if (changed &&
14418                 lnode->val && old &&
14419                 (memcmp(lnode->val->param, old->param,
14420                         TRIPLE_SIZE(lnode->val->sizes) * sizeof(lnode->val->param[0])) == 0) &&
14421                 (memcmp(&lnode->val->u, &old->u, sizeof(old->u)) == 0)) {
14422                 changed = 0;
14423         }
14424         if (old) {
14425                 xfree(old);
14426         }
14427         return changed;
14428
14429 }
14430
14431 static void scc_visit_phi(struct compile_state *state, struct scc_state *scc, 
14432         struct lattice_node *lnode)
14433 {
14434         struct lattice_node *tmp;
14435         struct triple **slot, *old;
14436         struct flow_edge *fedge;
14437         int index;
14438         if (lnode->def->op != OP_PHI) {
14439                 internal_error(state, lnode->def, "not phi");
14440         }
14441         /* Store the original value */
14442         old = preserve_lval(state, lnode);
14443
14444         /* default to lattice high */
14445         lnode->val = lnode->def;
14446         slot = &RHS(lnode->def, 0);
14447         index = 0;
14448         for(fedge = lnode->fblock->in; fedge; index++, fedge = fedge->in_next) {
14449                 if (!fedge->executable) {
14450                         continue;
14451                 }
14452                 if (!slot[index]) {
14453                         internal_error(state, lnode->def, "no phi value");
14454                 }
14455                 tmp = triple_to_lattice(state, scc, slot[index]);
14456                 /* meet(X, lattice low) = lattice low */
14457                 if (!tmp->val) {
14458                         lnode->val = 0;
14459                 }
14460                 /* meet(X, lattice high) = X */
14461                 else if (!tmp->val) {
14462                         lnode->val = lnode->val;
14463                 }
14464                 /* meet(lattice high, X) = X */
14465                 else if (!is_const(lnode->val)) {
14466                         lnode->val = dup_triple(state, tmp->val);
14467                         lnode->val->type = lnode->def->type;
14468                 }
14469                 /* meet(const, const) = const or lattice low */
14470                 else if (!constants_equal(state, lnode->val, tmp->val)) {
14471                         lnode->val = 0;
14472                 }
14473                 if (!lnode->val) {
14474                         break;
14475                 }
14476         }
14477 #if DEBUG_SCC
14478         fprintf(stderr, "phi: %d -> %s\n",
14479                 lnode->def->id,
14480                 (!lnode->val)? "lo": is_const(lnode->val)? "const": "hi");
14481 #endif
14482         /* If the lattice value has changed update the work lists. */
14483         if (lval_changed(state, old, lnode)) {
14484                 struct ssa_edge *sedge;
14485                 for(sedge = lnode->out; sedge; sedge = sedge->out_next) {
14486                         scc_add_sedge(state, scc, sedge);
14487                 }
14488         }
14489 }
14490
14491 static int compute_lnode_val(struct compile_state *state, struct scc_state *scc,
14492         struct lattice_node *lnode)
14493 {
14494         int changed;
14495         struct triple *old, *scratch;
14496         struct triple **dexpr, **vexpr;
14497         int count, i;
14498         
14499         /* Store the original value */
14500         old = preserve_lval(state, lnode);
14501
14502         /* Reinitialize the value */
14503         lnode->val = scratch = dup_triple(state, lnode->def);
14504         scratch->id = lnode->old_id;
14505         scratch->next     = scratch;
14506         scratch->prev     = scratch;
14507         scratch->use      = 0;
14508
14509         count = TRIPLE_SIZE(scratch->sizes);
14510         for(i = 0; i < count; i++) {
14511                 dexpr = &lnode->def->param[i];
14512                 vexpr = &scratch->param[i];
14513                 *vexpr = *dexpr;
14514                 if (((i < TRIPLE_MISC_OFF(scratch->sizes)) ||
14515                         (i >= TRIPLE_TARG_OFF(scratch->sizes))) &&
14516                         *dexpr) {
14517                         struct lattice_node *tmp;
14518                         tmp = triple_to_lattice(state, scc, *dexpr);
14519                         *vexpr = (tmp->val)? tmp->val : tmp->def;
14520                 }
14521         }
14522         if (scratch->op == OP_BRANCH) {
14523                 scratch->next = lnode->def->next;
14524         }
14525         /* Recompute the value */
14526 #warning "FIXME see if simplify does anything bad"
14527         /* So far it looks like only the strength reduction
14528          * optimization are things I need to worry about.
14529          */
14530         simplify(state, scratch);
14531         /* Cleanup my value */
14532         if (scratch->use) {
14533                 internal_error(state, lnode->def, "scratch used?");
14534         }
14535         if ((scratch->prev != scratch) ||
14536                 ((scratch->next != scratch) &&
14537                         ((lnode->def->op != OP_BRANCH) ||
14538                                 (scratch->next != lnode->def->next)))) {
14539                 internal_error(state, lnode->def, "scratch in list?");
14540         }
14541         /* undo any uses... */
14542         count = TRIPLE_SIZE(scratch->sizes);
14543         for(i = 0; i < count; i++) {
14544                 vexpr = &scratch->param[i];
14545                 if (*vexpr) {
14546                         unuse_triple(*vexpr, scratch);
14547                 }
14548         }
14549         if (!is_const(scratch)) {
14550                 for(i = 0; i < count; i++) {
14551                         dexpr = &lnode->def->param[i];
14552                         if (((i < TRIPLE_MISC_OFF(scratch->sizes)) ||
14553                                 (i >= TRIPLE_TARG_OFF(scratch->sizes))) &&
14554                                 *dexpr) {
14555                                 struct lattice_node *tmp;
14556                                 tmp = triple_to_lattice(state, scc, *dexpr);
14557                                 if (!tmp->val) {
14558                                         lnode->val = 0;
14559                                 }
14560                         }
14561                 }
14562         }
14563         if (lnode->val && 
14564                 (lnode->val->op == lnode->def->op) &&
14565                 (memcmp(lnode->val->param, lnode->def->param, 
14566                         count * sizeof(lnode->val->param[0])) == 0) &&
14567                 (memcmp(&lnode->val->u, &lnode->def->u, sizeof(lnode->def->u)) == 0)) {
14568                 lnode->val = lnode->def;
14569         }
14570         /* Find the cases that are always lattice lo */
14571         if (lnode->val && 
14572                 triple_is_def(state, lnode->val) &&
14573                 !triple_is_pure(state, lnode->val)) {
14574                 lnode->val = 0;
14575         }
14576         if (lnode->val && 
14577                 (lnode->val->op == OP_SDECL) && 
14578                 (lnode->val != lnode->def)) {
14579                 internal_error(state, lnode->def, "bad sdecl");
14580         }
14581         /* See if the lattice value has changed */
14582         changed = lval_changed(state, old, lnode);
14583         if (lnode->val != scratch) {
14584                 xfree(scratch);
14585         }
14586         return changed;
14587 }
14588
14589 static void scc_visit_branch(struct compile_state *state, struct scc_state *scc,
14590         struct lattice_node *lnode)
14591 {
14592         struct lattice_node *cond;
14593 #if DEBUG_SCC
14594         {
14595                 struct flow_edge *fedge;
14596                 fprintf(stderr, "branch: %d (",
14597                         lnode->def->id);
14598                 
14599                 for(fedge = lnode->fblock->out; fedge; fedge = fedge->out_next) {
14600                         fprintf(stderr, " %d", fedge->dst->block->vertex);
14601                 }
14602                 fprintf(stderr, " )");
14603                 if (TRIPLE_RHS(lnode->def->sizes) > 0) {
14604                         fprintf(stderr, " <- %d",
14605                                 RHS(lnode->def, 0)->id);
14606                 }
14607                 fprintf(stderr, "\n");
14608         }
14609 #endif
14610         if (lnode->def->op != OP_BRANCH) {
14611                 internal_error(state, lnode->def, "not branch");
14612         }
14613         /* This only applies to conditional branches */
14614         if (TRIPLE_RHS(lnode->def->sizes) == 0) {
14615                 return;
14616         }
14617         cond = triple_to_lattice(state, scc, RHS(lnode->def,0));
14618         if (cond->val && !is_const(cond->val)) {
14619 #warning "FIXME do I need to do something here?"
14620                 warning(state, cond->def, "condition not constant?");
14621                 return;
14622         }
14623         if (cond->val == 0) {
14624                 scc_add_fedge(state, scc, cond->fblock->out);
14625                 scc_add_fedge(state, scc, cond->fblock->out->out_next);
14626         }
14627         else if (cond->val->u.cval) {
14628                 scc_add_fedge(state, scc, cond->fblock->out->out_next);
14629                 
14630         } else {
14631                 scc_add_fedge(state, scc, cond->fblock->out);
14632         }
14633
14634 }
14635
14636 static void scc_visit_expr(struct compile_state *state, struct scc_state *scc,
14637         struct lattice_node *lnode)
14638 {
14639         int changed;
14640
14641         changed = compute_lnode_val(state, scc, lnode);
14642 #if DEBUG_SCC
14643         {
14644                 struct triple **expr;
14645                 fprintf(stderr, "expr: %3d %10s (",
14646                         lnode->def->id, tops(lnode->def->op));
14647                 expr = triple_rhs(state, lnode->def, 0);
14648                 for(;expr;expr = triple_rhs(state, lnode->def, expr)) {
14649                         if (*expr) {
14650                                 fprintf(stderr, " %d", (*expr)->id);
14651                         }
14652                 }
14653                 fprintf(stderr, " ) -> %s\n",
14654                         (!lnode->val)? "lo": is_const(lnode->val)? "const": "hi");
14655         }
14656 #endif
14657         if (lnode->def->op == OP_BRANCH) {
14658                 scc_visit_branch(state, scc, lnode);
14659
14660         }
14661         else if (changed) {
14662                 struct ssa_edge *sedge;
14663                 for(sedge = lnode->out; sedge; sedge = sedge->out_next) {
14664                         scc_add_sedge(state, scc, sedge);
14665                 }
14666         }
14667 }
14668
14669 static void scc_writeback_values(
14670         struct compile_state *state, struct scc_state *scc)
14671 {
14672         struct triple *first, *ins;
14673         first = RHS(state->main_function, 0);
14674         ins = first;
14675         do {
14676                 struct lattice_node *lnode;
14677                 lnode = triple_to_lattice(state, scc, ins);
14678                 /* Restore id */
14679                 ins->id = lnode->old_id;
14680 #if DEBUG_SCC
14681                 if (lnode->val && !is_const(lnode->val)) {
14682                         warning(state, lnode->def, 
14683                                 "lattice node still high?");
14684                 }
14685 #endif
14686                 if (lnode->val && (lnode->val != ins)) {
14687                         /* See if it something I know how to write back */
14688                         switch(lnode->val->op) {
14689                         case OP_INTCONST:
14690                                 mkconst(state, ins, lnode->val->u.cval);
14691                                 break;
14692                         case OP_ADDRCONST:
14693                                 mkaddr_const(state, ins, 
14694                                         MISC(lnode->val, 0), lnode->val->u.cval);
14695                                 break;
14696                         default:
14697                                 /* By default don't copy the changes,
14698                                  * recompute them in place instead.
14699                                  */
14700                                 simplify(state, ins);
14701                                 break;
14702                         }
14703                         if (is_const(lnode->val) &&
14704                                 !constants_equal(state, lnode->val, ins)) {
14705                                 internal_error(state, 0, "constants not equal");
14706                         }
14707                         /* Free the lattice nodes */
14708                         xfree(lnode->val);
14709                         lnode->val = 0;
14710                 }
14711                 ins = ins->next;
14712         } while(ins != first);
14713 }
14714
14715 static void scc_transform(struct compile_state *state)
14716 {
14717         struct scc_state scc;
14718
14719         initialize_scc_state(state, &scc);
14720
14721         while(scc.flow_work_list || scc.ssa_work_list) {
14722                 struct flow_edge *fedge;
14723                 struct ssa_edge *sedge;
14724                 struct flow_edge *fptr;
14725                 while((fedge = scc_next_fedge(state, &scc))) {
14726                         struct block *block;
14727                         struct triple *ptr;
14728                         struct flow_block *fblock;
14729                         int time;
14730                         int done;
14731                         if (fedge->executable) {
14732                                 continue;
14733                         }
14734                         if (!fedge->dst) {
14735                                 internal_error(state, 0, "fedge without dst");
14736                         }
14737                         if (!fedge->src) {
14738                                 internal_error(state, 0, "fedge without src");
14739                         }
14740                         fedge->executable = 1;
14741                         fblock = fedge->dst;
14742                         block = fblock->block;
14743                         time = 0;
14744                         for(fptr = fblock->in; fptr; fptr = fptr->in_next) {
14745                                 if (fptr->executable) {
14746                                         time++;
14747                                 }
14748                         }
14749 #if DEBUG_SCC
14750                         fprintf(stderr, "vertex: %d time: %d\n", 
14751                                 block->vertex, time);
14752                         
14753 #endif
14754                         done = 0;
14755                         for(ptr = block->first; !done; ptr = ptr->next) {
14756                                 struct lattice_node *lnode;
14757                                 done = (ptr == block->last);
14758                                 lnode = &scc.lattice[ptr->id];
14759                                 if (ptr->op == OP_PHI) {
14760                                         scc_visit_phi(state, &scc, lnode);
14761                                 }
14762                                 else if (time == 1) {
14763                                         scc_visit_expr(state, &scc, lnode);
14764                                 }
14765                         }
14766                         if (fblock->out && !fblock->out->out_next) {
14767                                 scc_add_fedge(state, &scc, fblock->out);
14768                         }
14769                 }
14770                 while((sedge = scc_next_sedge(state, &scc))) {
14771                         struct lattice_node *lnode;
14772                         struct flow_block *fblock;
14773                         lnode = sedge->dst;
14774                         fblock = lnode->fblock;
14775 #if DEBUG_SCC
14776                         fprintf(stderr, "sedge: %5d (%5d -> %5d)\n",
14777                                 sedge - scc.ssa_edges,
14778                                 sedge->src->def->id,
14779                                 sedge->dst->def->id);
14780 #endif
14781                         if (lnode->def->op == OP_PHI) {
14782                                 scc_visit_phi(state, &scc, lnode);
14783                         }
14784                         else {
14785                                 for(fptr = fblock->in; fptr; fptr = fptr->in_next) {
14786                                         if (fptr->executable) {
14787                                                 break;
14788                                         }
14789                                 }
14790                                 if (fptr) {
14791                                         scc_visit_expr(state, &scc, lnode);
14792                                 }
14793                         }
14794                 }
14795         }
14796         
14797         scc_writeback_values(state, &scc);
14798         free_scc_state(state, &scc);
14799 }
14800
14801
14802 static void transform_to_arch_instructions(struct compile_state *state)
14803 {
14804         struct triple *ins, *first;
14805         first = RHS(state->main_function, 0);
14806         ins = first;
14807         do {
14808                 ins = transform_to_arch_instruction(state, ins);
14809         } while(ins != first);
14810 }
14811
14812 #if DEBUG_CONSISTENCY
14813 static void verify_uses(struct compile_state *state)
14814 {
14815         struct triple *first, *ins;
14816         struct triple_set *set;
14817         first = RHS(state->main_function, 0);
14818         ins = first;
14819         do {
14820                 struct triple **expr;
14821                 expr = triple_rhs(state, ins, 0);
14822                 for(; expr; expr = triple_rhs(state, ins, expr)) {
14823                         struct triple *rhs;
14824                         rhs = *expr;
14825                         for(set = rhs?rhs->use:0; set; set = set->next) {
14826                                 if (set->member == ins) {
14827                                         break;
14828                                 }
14829                         }
14830                         if (!set) {
14831                                 internal_error(state, ins, "rhs not used");
14832                         }
14833                 }
14834                 expr = triple_lhs(state, ins, 0);
14835                 for(; expr; expr = triple_lhs(state, ins, expr)) {
14836                         struct triple *lhs;
14837                         lhs = *expr;
14838                         for(set =  lhs?lhs->use:0; set; set = set->next) {
14839                                 if (set->member == ins) {
14840                                         break;
14841                                 }
14842                         }
14843                         if (!set) {
14844                                 internal_error(state, ins, "lhs not used");
14845                         }
14846                 }
14847                 ins = ins->next;
14848         } while(ins != first);
14849         
14850 }
14851 static void verify_blocks_present(struct compile_state *state)
14852 {
14853         struct triple *first, *ins;
14854         if (!state->first_block) {
14855                 return;
14856         }
14857         first = RHS(state->main_function, 0);
14858         ins = first;
14859         do {
14860                 valid_ins(state, ins);
14861                 if (triple_stores_block(state, ins)) {
14862                         if (!ins->u.block) {
14863                                 internal_error(state, ins, 
14864                                         "%p not in a block?\n", ins);
14865                         }
14866                 }
14867                 ins = ins->next;
14868         } while(ins != first);
14869         
14870         
14871 }
14872 static void verify_blocks(struct compile_state *state)
14873 {
14874         struct triple *ins;
14875         struct block *block;
14876         int blocks;
14877         block = state->first_block;
14878         if (!block) {
14879                 return;
14880         }
14881         blocks = 0;
14882         do {
14883                 int users;
14884                 struct block_set *user;
14885                 blocks++;
14886                 for(ins = block->first; ins != block->last->next; ins = ins->next) {
14887                         if (triple_stores_block(state, ins) && (ins->u.block != block)) {
14888                                 internal_error(state, ins, "inconsitent block specified");
14889                         }
14890                         valid_ins(state, ins);
14891                 }
14892                 users = 0;
14893                 for(user = block->use; user; user = user->next) {
14894                         users++;
14895                         if ((block == state->last_block) &&
14896                                 (user->member == state->first_block)) {
14897                                 continue;
14898                         }
14899                         if ((user->member->left != block) &&
14900                                 (user->member->right != block)) {
14901                                 internal_error(state, user->member->first,
14902                                         "user does not use block");
14903                         }
14904                 }
14905                 if (triple_is_branch(state, block->last) &&
14906                         (block->right != block_of_triple(state, TARG(block->last, 0))))
14907                 {
14908                         internal_error(state, block->last, "block->right != TARG(0)");
14909                 }
14910                 if (!triple_is_uncond_branch(state, block->last) &&
14911                         (block != state->last_block) &&
14912                         (block->left != block_of_triple(state, block->last->next)))
14913                 {
14914                         internal_error(state, block->last, "block->left != block->last->next");
14915                 }
14916                 if (block->left) {
14917                         for(user = block->left->use; user; user = user->next) {
14918                                 if (user->member == block) {
14919                                         break;
14920                                 }
14921                         }
14922                         if (!user || user->member != block) {
14923                                 internal_error(state, block->first,
14924                                         "block does not use left");
14925                         }
14926                 }
14927                 if (block->right) {
14928                         for(user = block->right->use; user; user = user->next) {
14929                                 if (user->member == block) {
14930                                         break;
14931                                 }
14932                         }
14933                         if (!user || user->member != block) {
14934                                 internal_error(state, block->first,
14935                                         "block does not use right");
14936                         }
14937                 }
14938                 if (block->users != users) {
14939                         internal_error(state, block->first, 
14940                                 "computed users %d != stored users %d\n",
14941                                 users, block->users);
14942                 }
14943                 if (!triple_stores_block(state, block->last->next)) {
14944                         internal_error(state, block->last->next, 
14945                                 "cannot find next block");
14946                 }
14947                 block = block->last->next->u.block;
14948                 if (!block) {
14949                         internal_error(state, block->last->next,
14950                                 "bad next block");
14951                 }
14952         } while(block != state->first_block);
14953         if (blocks != state->last_vertex) {
14954                 internal_error(state, 0, "computed blocks != stored blocks %d\n",
14955                         blocks, state->last_vertex);
14956         }
14957 }
14958
14959 static void verify_domination(struct compile_state *state)
14960 {
14961         struct triple *first, *ins;
14962         struct triple_set *set;
14963         if (!state->first_block) {
14964                 return;
14965         }
14966         
14967         first = RHS(state->main_function, 0);
14968         ins = first;
14969         do {
14970                 for(set = ins->use; set; set = set->next) {
14971                         struct triple **slot;
14972                         struct triple *use_point;
14973                         int i, zrhs;
14974                         use_point = 0;
14975                         zrhs = TRIPLE_RHS(ins->sizes);
14976                         slot = &RHS(set->member, 0);
14977                         /* See if the use is on the right hand side */
14978                         for(i = 0; i < zrhs; i++) {
14979                                 if (slot[i] == ins) {
14980                                         break;
14981                                 }
14982                         }
14983                         if (i < zrhs) {
14984                                 use_point = set->member;
14985                                 if (set->member->op == OP_PHI) {
14986                                         struct block_set *bset;
14987                                         int edge;
14988                                         bset = set->member->u.block->use;
14989                                         for(edge = 0; bset && (edge < i); edge++) {
14990                                                 bset = bset->next;
14991                                         }
14992                                         if (!bset) {
14993                                                 internal_error(state, set->member, 
14994                                                         "no edge for phi rhs %d\n", i);
14995                                         }
14996                                         use_point = bset->member->last;
14997                                 }
14998                         }
14999                         if (use_point &&
15000                                 !tdominates(state, ins, use_point)) {
15001                                 internal_warning(state, ins, 
15002                                         "ins does not dominate rhs use");
15003                                 internal_error(state, use_point, 
15004                                         "non dominated rhs use point?");
15005                         }
15006                 }
15007                 ins = ins->next;
15008         } while(ins != first);
15009 }
15010
15011 static void verify_piece(struct compile_state *state)
15012 {
15013         struct triple *first, *ins;
15014         first = RHS(state->main_function, 0);
15015         ins = first;
15016         do {
15017                 struct triple *ptr;
15018                 int lhs, i;
15019                 lhs = TRIPLE_LHS(ins->sizes);
15020                 for(ptr = ins->next, i = 0; i < lhs; i++, ptr = ptr->next) {
15021                         if (ptr != LHS(ins, i)) {
15022                                 internal_error(state, ins, "malformed lhs on %s",
15023                                         tops(ins->op));
15024                         }
15025                         if (ptr->op != OP_PIECE) {
15026                                 internal_error(state, ins, "bad lhs op %s at %d on %s",
15027                                         tops(ptr->op), i, tops(ins->op));
15028                         }
15029                         if (ptr->u.cval != i) {
15030                                 internal_error(state, ins, "bad u.cval of %d %d expected",
15031                                         ptr->u.cval, i);
15032                         }
15033                 }
15034                 ins = ins->next;
15035         } while(ins != first);
15036 }
15037 static void verify_ins_colors(struct compile_state *state)
15038 {
15039         struct triple *first, *ins;
15040         
15041         first = RHS(state->main_function, 0);
15042         ins = first;
15043         do {
15044                 ins = ins->next;
15045         } while(ins != first);
15046 }
15047 static void verify_consistency(struct compile_state *state)
15048 {
15049         verify_uses(state);
15050         verify_blocks_present(state);
15051         verify_blocks(state);
15052         verify_domination(state);
15053         verify_piece(state);
15054         verify_ins_colors(state);
15055 }
15056 #else 
15057 static void verify_consistency(struct compile_state *state) {}
15058 #endif /* DEBUG_USES */
15059
15060 static void optimize(struct compile_state *state)
15061 {
15062         if (state->debug & DEBUG_TRIPLES) {
15063                 print_triples(state);
15064         }
15065         /* Replace structures with simpler data types */
15066         flatten_structures(state);
15067         if (state->debug & DEBUG_TRIPLES) {
15068                 print_triples(state);
15069         }
15070         verify_consistency(state);
15071         /* Analize the intermediate code */
15072         setup_basic_blocks(state);
15073         analyze_idominators(state);
15074         analyze_ipdominators(state);
15075
15076         /* Transform the code to ssa form. */
15077         /*
15078          * The transformation to ssa form puts a phi function
15079          * on each of edge of a dominance frontier where that
15080          * phi function might be needed.  At -O2 if we don't
15081          * eleminate the excess phi functions we can get an
15082          * exponential code size growth.  So I kill the extra
15083          * phi functions early and I kill them often.
15084          */
15085         transform_to_ssa_form(state);
15086         eliminate_inefectual_code(state);
15087
15088         verify_consistency(state);
15089         if (state->debug & DEBUG_CODE_ELIMINATION) {
15090                 fprintf(stdout, "After transform_to_ssa_form\n");
15091                 print_blocks(state, stdout);
15092         }
15093         /* Do strength reduction and simple constant optimizations */
15094         if (state->optimize >= 1) {
15095                 simplify_all(state);
15096                 transform_from_ssa_form(state);
15097                 free_basic_blocks(state);
15098                 setup_basic_blocks(state);
15099                 analyze_idominators(state);
15100                 analyze_ipdominators(state);
15101                 transform_to_ssa_form(state);
15102                 eliminate_inefectual_code(state);
15103         }
15104         if (state->debug & DEBUG_CODE_ELIMINATION) {
15105                 fprintf(stdout, "After simplify_all\n");
15106                 print_blocks(state, stdout);
15107         }
15108         verify_consistency(state);
15109         /* Propogate constants throughout the code */
15110         if (state->optimize >= 2) {
15111                 scc_transform(state);
15112                 transform_from_ssa_form(state);
15113                 free_basic_blocks(state);
15114                 setup_basic_blocks(state);
15115                 analyze_idominators(state);
15116                 analyze_ipdominators(state);
15117                 transform_to_ssa_form(state);
15118                 eliminate_inefectual_code(state);
15119         }
15120         verify_consistency(state);
15121 #warning "WISHLIST implement single use constants (least possible register pressure)"
15122 #warning "WISHLIST implement induction variable elimination"
15123         /* Select architecture instructions and an initial partial
15124          * coloring based on architecture constraints.
15125          */
15126         transform_to_arch_instructions(state);
15127         verify_consistency(state);
15128         if (state->debug & DEBUG_ARCH_CODE) {
15129                 printf("After transform_to_arch_instructions\n");
15130                 print_blocks(state, stdout);
15131                 print_control_flow(state);
15132         }
15133         eliminate_inefectual_code(state);
15134         verify_consistency(state);
15135         if (state->debug & DEBUG_CODE_ELIMINATION) {
15136                 printf("After eliminate_inefectual_code\n");
15137                 print_blocks(state, stdout);
15138                 print_control_flow(state);
15139         }
15140         verify_consistency(state);
15141         /* Color all of the variables to see if they will fit in registers */
15142         insert_copies_to_phi(state);
15143         if (state->debug & DEBUG_INSERTED_COPIES) {
15144                 printf("After insert_copies_to_phi\n");
15145                 print_blocks(state, stdout);
15146                 print_control_flow(state);
15147         }
15148         verify_consistency(state);
15149         insert_mandatory_copies(state);
15150         if (state->debug & DEBUG_INSERTED_COPIES) {
15151                 printf("After insert_mandatory_copies\n");
15152                 print_blocks(state, stdout);
15153                 print_control_flow(state);
15154         }
15155         verify_consistency(state);
15156         allocate_registers(state);
15157         verify_consistency(state);
15158         if (state->debug & DEBUG_INTERMEDIATE_CODE) {
15159                 print_blocks(state, stdout);
15160         }
15161         if (state->debug & DEBUG_CONTROL_FLOW) {
15162                 print_control_flow(state);
15163         }
15164         /* Remove the optimization information.
15165          * This is more to check for memory consistency than to free memory.
15166          */
15167         free_basic_blocks(state);
15168 }
15169
15170 static void print_op_asm(struct compile_state *state,
15171         struct triple *ins, FILE *fp)
15172 {
15173         struct asm_info *info;
15174         const char *ptr;
15175         unsigned lhs, rhs, i;
15176         info = ins->u.ainfo;
15177         lhs = TRIPLE_LHS(ins->sizes);
15178         rhs = TRIPLE_RHS(ins->sizes);
15179         /* Don't count the clobbers in lhs */
15180         for(i = 0; i < lhs; i++) {
15181                 if (LHS(ins, i)->type == &void_type) {
15182                         break;
15183                 }
15184         }
15185         lhs = i;
15186         fprintf(fp, "#ASM\n");
15187         fputc('\t', fp);
15188         for(ptr = info->str; *ptr; ptr++) {
15189                 char *next;
15190                 unsigned long param;
15191                 struct triple *piece;
15192                 if (*ptr != '%') {
15193                         fputc(*ptr, fp);
15194                         continue;
15195                 }
15196                 ptr++;
15197                 if (*ptr == '%') {
15198                         fputc('%', fp);
15199                         continue;
15200                 }
15201                 param = strtoul(ptr, &next, 10);
15202                 if (ptr == next) {
15203                         error(state, ins, "Invalid asm template");
15204                 }
15205                 if (param >= (lhs + rhs)) {
15206                         error(state, ins, "Invalid param %%%u in asm template",
15207                                 param);
15208                 }
15209                 piece = (param < lhs)? LHS(ins, param) : RHS(ins, param - lhs);
15210                 fprintf(fp, "%s", 
15211                         arch_reg_str(ID_REG(piece->id)));
15212                 ptr = next -1;
15213         }
15214         fprintf(fp, "\n#NOT ASM\n");
15215 }
15216
15217
15218 /* Only use the low x86 byte registers.  This allows me
15219  * allocate the entire register when a byte register is used.
15220  */
15221 #define X86_4_8BIT_GPRS 1
15222
15223 /* Recognized x86 cpu variants */
15224 #define BAD_CPU      0
15225 #define CPU_I386     1
15226 #define CPU_P3       2
15227 #define CPU_P4       3
15228 #define CPU_K7       4
15229 #define CPU_K8       5
15230
15231 #define CPU_DEFAULT  CPU_I386
15232
15233 /* The x86 register classes */
15234 #define REGC_FLAGS       0
15235 #define REGC_GPR8        1
15236 #define REGC_GPR16       2
15237 #define REGC_GPR32       3
15238 #define REGC_DIVIDEND64  4
15239 #define REGC_DIVIDEND32  5
15240 #define REGC_MMX         6
15241 #define REGC_XMM         7
15242 #define REGC_GPR32_8     8
15243 #define REGC_GPR16_8     9
15244 #define REGC_GPR8_LO    10
15245 #define REGC_IMM32      11
15246 #define REGC_IMM16      12
15247 #define REGC_IMM8       13
15248 #define LAST_REGC  REGC_IMM8
15249 #if LAST_REGC >= MAX_REGC
15250 #error "MAX_REGC is to low"
15251 #endif
15252
15253 /* Register class masks */
15254 #define REGCM_FLAGS      (1 << REGC_FLAGS)
15255 #define REGCM_GPR8       (1 << REGC_GPR8)
15256 #define REGCM_GPR16      (1 << REGC_GPR16)
15257 #define REGCM_GPR32      (1 << REGC_GPR32)
15258 #define REGCM_DIVIDEND64 (1 << REGC_DIVIDEND64)
15259 #define REGCM_DIVIDEND32 (1 << REGC_DIVIDEND32)
15260 #define REGCM_MMX        (1 << REGC_MMX)
15261 #define REGCM_XMM        (1 << REGC_XMM)
15262 #define REGCM_GPR32_8    (1 << REGC_GPR32_8)
15263 #define REGCM_GPR16_8    (1 << REGC_GPR16_8)
15264 #define REGCM_GPR8_LO    (1 << REGC_GPR8_LO)
15265 #define REGCM_IMM32      (1 << REGC_IMM32)
15266 #define REGCM_IMM16      (1 << REGC_IMM16)
15267 #define REGCM_IMM8       (1 << REGC_IMM8)
15268 #define REGCM_ALL        ((1 << (LAST_REGC + 1)) - 1)
15269
15270 /* The x86 registers */
15271 #define REG_EFLAGS  2
15272 #define REGC_FLAGS_FIRST REG_EFLAGS
15273 #define REGC_FLAGS_LAST  REG_EFLAGS
15274 #define REG_AL      3
15275 #define REG_BL      4
15276 #define REG_CL      5
15277 #define REG_DL      6
15278 #define REG_AH      7
15279 #define REG_BH      8
15280 #define REG_CH      9
15281 #define REG_DH      10
15282 #define REGC_GPR8_LO_FIRST REG_AL
15283 #define REGC_GPR8_LO_LAST  REG_DL
15284 #define REGC_GPR8_FIRST  REG_AL
15285 #define REGC_GPR8_LAST   REG_DH
15286 #define REG_AX     11
15287 #define REG_BX     12
15288 #define REG_CX     13
15289 #define REG_DX     14
15290 #define REG_SI     15
15291 #define REG_DI     16
15292 #define REG_BP     17
15293 #define REG_SP     18
15294 #define REGC_GPR16_FIRST REG_AX
15295 #define REGC_GPR16_LAST  REG_SP
15296 #define REG_EAX    19
15297 #define REG_EBX    20
15298 #define REG_ECX    21
15299 #define REG_EDX    22
15300 #define REG_ESI    23
15301 #define REG_EDI    24
15302 #define REG_EBP    25
15303 #define REG_ESP    26
15304 #define REGC_GPR32_FIRST REG_EAX
15305 #define REGC_GPR32_LAST  REG_ESP
15306 #define REG_EDXEAX 27
15307 #define REGC_DIVIDEND64_FIRST REG_EDXEAX
15308 #define REGC_DIVIDEND64_LAST  REG_EDXEAX
15309 #define REG_DXAX   28
15310 #define REGC_DIVIDEND32_FIRST REG_DXAX
15311 #define REGC_DIVIDEND32_LAST  REG_DXAX
15312 #define REG_MMX0   29
15313 #define REG_MMX1   30
15314 #define REG_MMX2   31
15315 #define REG_MMX3   32
15316 #define REG_MMX4   33
15317 #define REG_MMX5   34
15318 #define REG_MMX6   35
15319 #define REG_MMX7   36
15320 #define REGC_MMX_FIRST REG_MMX0
15321 #define REGC_MMX_LAST  REG_MMX7
15322 #define REG_XMM0   37
15323 #define REG_XMM1   38
15324 #define REG_XMM2   39
15325 #define REG_XMM3   40
15326 #define REG_XMM4   41
15327 #define REG_XMM5   42
15328 #define REG_XMM6   43
15329 #define REG_XMM7   44
15330 #define REGC_XMM_FIRST REG_XMM0
15331 #define REGC_XMM_LAST  REG_XMM7
15332 #warning "WISHLIST figure out how to use pinsrw and pextrw to better use extended regs"
15333 #define LAST_REG   REG_XMM7
15334
15335 #define REGC_GPR32_8_FIRST REG_EAX
15336 #define REGC_GPR32_8_LAST  REG_EDX
15337 #define REGC_GPR16_8_FIRST REG_AX
15338 #define REGC_GPR16_8_LAST  REG_DX
15339
15340 #define REGC_IMM8_FIRST    -1
15341 #define REGC_IMM8_LAST     -1
15342 #define REGC_IMM16_FIRST   -2
15343 #define REGC_IMM16_LAST    -1
15344 #define REGC_IMM32_FIRST   -4
15345 #define REGC_IMM32_LAST    -1
15346
15347 #if LAST_REG >= MAX_REGISTERS
15348 #error "MAX_REGISTERS to low"
15349 #endif
15350
15351
15352 static unsigned regc_size[LAST_REGC +1] = {
15353         [REGC_FLAGS]      = REGC_FLAGS_LAST      - REGC_FLAGS_FIRST + 1,
15354         [REGC_GPR8]       = REGC_GPR8_LAST       - REGC_GPR8_FIRST + 1,
15355         [REGC_GPR16]      = REGC_GPR16_LAST      - REGC_GPR16_FIRST + 1,
15356         [REGC_GPR32]      = REGC_GPR32_LAST      - REGC_GPR32_FIRST + 1,
15357         [REGC_DIVIDEND64] = REGC_DIVIDEND64_LAST - REGC_DIVIDEND64_FIRST + 1,
15358         [REGC_DIVIDEND32] = REGC_DIVIDEND32_LAST - REGC_DIVIDEND32_FIRST + 1,
15359         [REGC_MMX]        = REGC_MMX_LAST        - REGC_MMX_FIRST + 1,
15360         [REGC_XMM]        = REGC_XMM_LAST        - REGC_XMM_FIRST + 1,
15361         [REGC_GPR32_8]    = REGC_GPR32_8_LAST    - REGC_GPR32_8_FIRST + 1,
15362         [REGC_GPR16_8]    = REGC_GPR16_8_LAST    - REGC_GPR16_8_FIRST + 1,
15363         [REGC_GPR8_LO]    = REGC_GPR8_LO_LAST    - REGC_GPR8_LO_FIRST + 1,
15364         [REGC_IMM32]      = 0,
15365         [REGC_IMM16]      = 0,
15366         [REGC_IMM8]       = 0,
15367 };
15368
15369 static const struct {
15370         int first, last;
15371 } regcm_bound[LAST_REGC + 1] = {
15372         [REGC_FLAGS]      = { REGC_FLAGS_FIRST,      REGC_FLAGS_LAST },
15373         [REGC_GPR8]       = { REGC_GPR8_FIRST,       REGC_GPR8_LAST },
15374         [REGC_GPR16]      = { REGC_GPR16_FIRST,      REGC_GPR16_LAST },
15375         [REGC_GPR32]      = { REGC_GPR32_FIRST,      REGC_GPR32_LAST },
15376         [REGC_DIVIDEND64] = { REGC_DIVIDEND64_FIRST, REGC_DIVIDEND64_LAST },
15377         [REGC_DIVIDEND32] = { REGC_DIVIDEND32_FIRST, REGC_DIVIDEND32_LAST },
15378         [REGC_MMX]        = { REGC_MMX_FIRST,        REGC_MMX_LAST },
15379         [REGC_XMM]        = { REGC_XMM_FIRST,        REGC_XMM_LAST },
15380         [REGC_GPR32_8]    = { REGC_GPR32_8_FIRST,    REGC_GPR32_8_LAST },
15381         [REGC_GPR16_8]    = { REGC_GPR16_8_FIRST,    REGC_GPR16_8_LAST },
15382         [REGC_GPR8_LO]    = { REGC_GPR8_LO_FIRST,    REGC_GPR8_LO_LAST },
15383         [REGC_IMM32]      = { REGC_IMM32_FIRST,      REGC_IMM32_LAST },
15384         [REGC_IMM16]      = { REGC_IMM16_FIRST,      REGC_IMM16_LAST },
15385         [REGC_IMM8]       = { REGC_IMM8_FIRST,       REGC_IMM8_LAST },
15386 };
15387
15388 static int arch_encode_cpu(const char *cpu)
15389 {
15390         struct cpu {
15391                 const char *name;
15392                 int cpu;
15393         } cpus[] = {
15394                 { "i386", CPU_I386 },
15395                 { "p3",   CPU_P3 },
15396                 { "p4",   CPU_P4 },
15397                 { "k7",   CPU_K7 },
15398                 { "k8",   CPU_K8 },
15399                 {  0,     BAD_CPU }
15400         };
15401         struct cpu *ptr;
15402         for(ptr = cpus; ptr->name; ptr++) {
15403                 if (strcmp(ptr->name, cpu) == 0) {
15404                         break;
15405                 }
15406         }
15407         return ptr->cpu;
15408 }
15409
15410 static unsigned arch_regc_size(struct compile_state *state, int class)
15411 {
15412         if ((class < 0) || (class > LAST_REGC)) {
15413                 return 0;
15414         }
15415         return regc_size[class];
15416 }
15417
15418 static int arch_regcm_intersect(unsigned regcm1, unsigned regcm2)
15419 {
15420         /* See if two register classes may have overlapping registers */
15421         unsigned gpr_mask = REGCM_GPR8 | REGCM_GPR8_LO | REGCM_GPR16_8 | REGCM_GPR16 |
15422                 REGCM_GPR32_8 | REGCM_GPR32 | 
15423                 REGCM_DIVIDEND32 | REGCM_DIVIDEND64;
15424
15425         /* Special case for the immediates */
15426         if ((regcm1 & (REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8)) &&
15427                 ((regcm1 & ~(REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8)) == 0) &&
15428                 (regcm2 & (REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8)) &&
15429                 ((regcm2 & ~(REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8)) == 0)) { 
15430                 return 0;
15431         }
15432         return (regcm1 & regcm2) ||
15433                 ((regcm1 & gpr_mask) && (regcm2 & gpr_mask));
15434 }
15435
15436 static void arch_reg_equivs(
15437         struct compile_state *state, unsigned *equiv, int reg)
15438 {
15439         if ((reg < 0) || (reg > LAST_REG)) {
15440                 internal_error(state, 0, "invalid register");
15441         }
15442         *equiv++ = reg;
15443         switch(reg) {
15444         case REG_AL:
15445 #if X86_4_8BIT_GPRS
15446                 *equiv++ = REG_AH;
15447 #endif
15448                 *equiv++ = REG_AX;
15449                 *equiv++ = REG_EAX;
15450                 *equiv++ = REG_DXAX;
15451                 *equiv++ = REG_EDXEAX;
15452                 break;
15453         case REG_AH:
15454 #if X86_4_8BIT_GPRS
15455                 *equiv++ = REG_AL;
15456 #endif
15457                 *equiv++ = REG_AX;
15458                 *equiv++ = REG_EAX;
15459                 *equiv++ = REG_DXAX;
15460                 *equiv++ = REG_EDXEAX;
15461                 break;
15462         case REG_BL:  
15463 #if X86_4_8BIT_GPRS
15464                 *equiv++ = REG_BH;
15465 #endif
15466                 *equiv++ = REG_BX;
15467                 *equiv++ = REG_EBX;
15468                 break;
15469
15470         case REG_BH:
15471 #if X86_4_8BIT_GPRS
15472                 *equiv++ = REG_BL;
15473 #endif
15474                 *equiv++ = REG_BX;
15475                 *equiv++ = REG_EBX;
15476                 break;
15477         case REG_CL:
15478 #if X86_4_8BIT_GPRS
15479                 *equiv++ = REG_CH;
15480 #endif
15481                 *equiv++ = REG_CX;
15482                 *equiv++ = REG_ECX;
15483                 break;
15484
15485         case REG_CH:
15486 #if X86_4_8BIT_GPRS
15487                 *equiv++ = REG_CL;
15488 #endif
15489                 *equiv++ = REG_CX;
15490                 *equiv++ = REG_ECX;
15491                 break;
15492         case REG_DL:
15493 #if X86_4_8BIT_GPRS
15494                 *equiv++ = REG_DH;
15495 #endif
15496                 *equiv++ = REG_DX;
15497                 *equiv++ = REG_EDX;
15498                 *equiv++ = REG_DXAX;
15499                 *equiv++ = REG_EDXEAX;
15500                 break;
15501         case REG_DH:
15502 #if X86_4_8BIT_GPRS
15503                 *equiv++ = REG_DL;
15504 #endif
15505                 *equiv++ = REG_DX;
15506                 *equiv++ = REG_EDX;
15507                 *equiv++ = REG_DXAX;
15508                 *equiv++ = REG_EDXEAX;
15509                 break;
15510         case REG_AX:
15511                 *equiv++ = REG_AL;
15512                 *equiv++ = REG_AH;
15513                 *equiv++ = REG_EAX;
15514                 *equiv++ = REG_DXAX;
15515                 *equiv++ = REG_EDXEAX;
15516                 break;
15517         case REG_BX:
15518                 *equiv++ = REG_BL;
15519                 *equiv++ = REG_BH;
15520                 *equiv++ = REG_EBX;
15521                 break;
15522         case REG_CX:  
15523                 *equiv++ = REG_CL;
15524                 *equiv++ = REG_CH;
15525                 *equiv++ = REG_ECX;
15526                 break;
15527         case REG_DX:  
15528                 *equiv++ = REG_DL;
15529                 *equiv++ = REG_DH;
15530                 *equiv++ = REG_EDX;
15531                 *equiv++ = REG_DXAX;
15532                 *equiv++ = REG_EDXEAX;
15533                 break;
15534         case REG_SI:  
15535                 *equiv++ = REG_ESI;
15536                 break;
15537         case REG_DI:
15538                 *equiv++ = REG_EDI;
15539                 break;
15540         case REG_BP:
15541                 *equiv++ = REG_EBP;
15542                 break;
15543         case REG_SP:
15544                 *equiv++ = REG_ESP;
15545                 break;
15546         case REG_EAX:
15547                 *equiv++ = REG_AL;
15548                 *equiv++ = REG_AH;
15549                 *equiv++ = REG_AX;
15550                 *equiv++ = REG_DXAX;
15551                 *equiv++ = REG_EDXEAX;
15552                 break;
15553         case REG_EBX:
15554                 *equiv++ = REG_BL;
15555                 *equiv++ = REG_BH;
15556                 *equiv++ = REG_BX;
15557                 break;
15558         case REG_ECX:
15559                 *equiv++ = REG_CL;
15560                 *equiv++ = REG_CH;
15561                 *equiv++ = REG_CX;
15562                 break;
15563         case REG_EDX:
15564                 *equiv++ = REG_DL;
15565                 *equiv++ = REG_DH;
15566                 *equiv++ = REG_DX;
15567                 *equiv++ = REG_DXAX;
15568                 *equiv++ = REG_EDXEAX;
15569                 break;
15570         case REG_ESI: 
15571                 *equiv++ = REG_SI;
15572                 break;
15573         case REG_EDI: 
15574                 *equiv++ = REG_DI;
15575                 break;
15576         case REG_EBP: 
15577                 *equiv++ = REG_BP;
15578                 break;
15579         case REG_ESP: 
15580                 *equiv++ = REG_SP;
15581                 break;
15582         case REG_DXAX: 
15583                 *equiv++ = REG_AL;
15584                 *equiv++ = REG_AH;
15585                 *equiv++ = REG_DL;
15586                 *equiv++ = REG_DH;
15587                 *equiv++ = REG_AX;
15588                 *equiv++ = REG_DX;
15589                 *equiv++ = REG_EAX;
15590                 *equiv++ = REG_EDX;
15591                 *equiv++ = REG_EDXEAX;
15592                 break;
15593         case REG_EDXEAX: 
15594                 *equiv++ = REG_AL;
15595                 *equiv++ = REG_AH;
15596                 *equiv++ = REG_DL;
15597                 *equiv++ = REG_DH;
15598                 *equiv++ = REG_AX;
15599                 *equiv++ = REG_DX;
15600                 *equiv++ = REG_EAX;
15601                 *equiv++ = REG_EDX;
15602                 *equiv++ = REG_DXAX;
15603                 break;
15604         }
15605         *equiv++ = REG_UNSET; 
15606 }
15607
15608 static unsigned arch_avail_mask(struct compile_state *state)
15609 {
15610         unsigned avail_mask;
15611         /* REGCM_GPR8 is not available */
15612         avail_mask = REGCM_GPR8_LO | REGCM_GPR16_8 | REGCM_GPR16 | 
15613                 REGCM_GPR32 | REGCM_GPR32_8 | 
15614                 REGCM_DIVIDEND32 | REGCM_DIVIDEND64 |
15615                 REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8 | REGCM_FLAGS;
15616         switch(state->cpu) {
15617         case CPU_P3:
15618         case CPU_K7:
15619                 avail_mask |= REGCM_MMX;
15620                 break;
15621         case CPU_P4:
15622         case CPU_K8:
15623                 avail_mask |= REGCM_MMX | REGCM_XMM;
15624                 break;
15625         }
15626         return avail_mask;
15627 }
15628
15629 static unsigned arch_regcm_normalize(struct compile_state *state, unsigned regcm)
15630 {
15631         unsigned mask, result;
15632         int class, class2;
15633         result = regcm;
15634
15635         for(class = 0, mask = 1; mask; mask <<= 1, class++) {
15636                 if ((result & mask) == 0) {
15637                         continue;
15638                 }
15639                 if (class > LAST_REGC) {
15640                         result &= ~mask;
15641                 }
15642                 for(class2 = 0; class2 <= LAST_REGC; class2++) {
15643                         if ((regcm_bound[class2].first >= regcm_bound[class].first) &&
15644                                 (regcm_bound[class2].last <= regcm_bound[class].last)) {
15645                                 result |= (1 << class2);
15646                         }
15647                 }
15648         }
15649         result &= arch_avail_mask(state);
15650         return result;
15651 }
15652
15653 static unsigned arch_regcm_reg_normalize(struct compile_state *state, unsigned regcm)
15654 {
15655         /* Like arch_regcm_normalize except immediate register classes are excluded */
15656         regcm = arch_regcm_normalize(state, regcm);
15657         /* Remove the immediate register classes */
15658         regcm &= ~(REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8);
15659         return regcm;
15660         
15661 }
15662
15663 static unsigned arch_reg_regcm(struct compile_state *state, int reg)
15664 {
15665         unsigned mask;
15666         int class;
15667         mask = 0;
15668         for(class = 0; class <= LAST_REGC; class++) {
15669                 if ((reg >= regcm_bound[class].first) &&
15670                         (reg <= regcm_bound[class].last)) {
15671                         mask |= (1 << class);
15672                 }
15673         }
15674         if (!mask) {
15675                 internal_error(state, 0, "reg %d not in any class", reg);
15676         }
15677         return mask;
15678 }
15679
15680 static struct reg_info arch_reg_constraint(
15681         struct compile_state *state, struct type *type, const char *constraint)
15682 {
15683         static const struct {
15684                 char class;
15685                 unsigned int mask;
15686                 unsigned int reg;
15687         } constraints[] = {
15688                 { 'r', REGCM_GPR32,   REG_UNSET },
15689                 { 'g', REGCM_GPR32,   REG_UNSET },
15690                 { 'p', REGCM_GPR32,   REG_UNSET },
15691                 { 'q', REGCM_GPR8_LO, REG_UNSET },
15692                 { 'Q', REGCM_GPR32_8, REG_UNSET },
15693                 { 'x', REGCM_XMM,     REG_UNSET },
15694                 { 'y', REGCM_MMX,     REG_UNSET },
15695                 { 'a', REGCM_GPR32,   REG_EAX },
15696                 { 'b', REGCM_GPR32,   REG_EBX },
15697                 { 'c', REGCM_GPR32,   REG_ECX },
15698                 { 'd', REGCM_GPR32,   REG_EDX },
15699                 { 'D', REGCM_GPR32,   REG_EDI },
15700                 { 'S', REGCM_GPR32,   REG_ESI },
15701                 { '\0', 0, REG_UNSET },
15702         };
15703         unsigned int regcm;
15704         unsigned int mask, reg;
15705         struct reg_info result;
15706         const char *ptr;
15707         regcm = arch_type_to_regcm(state, type);
15708         reg = REG_UNSET;
15709         mask = 0;
15710         for(ptr = constraint; *ptr; ptr++) {
15711                 int i;
15712                 if (*ptr ==  ' ') {
15713                         continue;
15714                 }
15715                 for(i = 0; constraints[i].class != '\0'; i++) {
15716                         if (constraints[i].class == *ptr) {
15717                                 break;
15718                         }
15719                 }
15720                 if (constraints[i].class == '\0') {
15721                         error(state, 0, "invalid register constraint ``%c''", *ptr);
15722                         break;
15723                 }
15724                 if ((constraints[i].mask & regcm) == 0) {
15725                         error(state, 0, "invalid register class %c specified",
15726                                 *ptr);
15727                 }
15728                 mask |= constraints[i].mask;
15729                 if (constraints[i].reg != REG_UNSET) {
15730                         if ((reg != REG_UNSET) && (reg != constraints[i].reg)) {
15731                                 error(state, 0, "Only one register may be specified");
15732                         }
15733                         reg = constraints[i].reg;
15734                 }
15735         }
15736         result.reg = reg;
15737         result.regcm = mask;
15738         return result;
15739 }
15740
15741 static struct reg_info arch_reg_clobber(
15742         struct compile_state *state, const char *clobber)
15743 {
15744         struct reg_info result;
15745         if (strcmp(clobber, "memory") == 0) {
15746                 result.reg = REG_UNSET;
15747                 result.regcm = 0;
15748         }
15749         else if (strcmp(clobber, "%eax") == 0) {
15750                 result.reg = REG_EAX;
15751                 result.regcm = REGCM_GPR32;
15752         }
15753         else if (strcmp(clobber, "%ebx") == 0) {
15754                 result.reg = REG_EBX;
15755                 result.regcm = REGCM_GPR32;
15756         }
15757         else if (strcmp(clobber, "%ecx") == 0) {
15758                 result.reg = REG_ECX;
15759                 result.regcm = REGCM_GPR32;
15760         }
15761         else if (strcmp(clobber, "%edx") == 0) {
15762                 result.reg = REG_EDX;
15763                 result.regcm = REGCM_GPR32;
15764         }
15765         else if (strcmp(clobber, "%esi") == 0) {
15766                 result.reg = REG_ESI;
15767                 result.regcm = REGCM_GPR32;
15768         }
15769         else if (strcmp(clobber, "%edi") == 0) {
15770                 result.reg = REG_EDI;
15771                 result.regcm = REGCM_GPR32;
15772         }
15773         else if (strcmp(clobber, "%ebp") == 0) {
15774                 result.reg = REG_EBP;
15775                 result.regcm = REGCM_GPR32;
15776         }
15777         else if (strcmp(clobber, "%esp") == 0) {
15778                 result.reg = REG_ESP;
15779                 result.regcm = REGCM_GPR32;
15780         }
15781         else if (strcmp(clobber, "cc") == 0) {
15782                 result.reg = REG_EFLAGS;
15783                 result.regcm = REGCM_FLAGS;
15784         }
15785         else if ((strncmp(clobber, "xmm", 3) == 0)  &&
15786                 octdigitp(clobber[3]) && (clobber[4] == '\0')) {
15787                 result.reg = REG_XMM0 + octdigval(clobber[3]);
15788                 result.regcm = REGCM_XMM;
15789         }
15790         else if ((strncmp(clobber, "mmx", 3) == 0) &&
15791                 octdigitp(clobber[3]) && (clobber[4] == '\0')) {
15792                 result.reg = REG_MMX0 + octdigval(clobber[3]);
15793                 result.regcm = REGCM_MMX;
15794         }
15795         else {
15796                 error(state, 0, "Invalid register clobber");
15797                 result.reg = REG_UNSET;
15798                 result.regcm = 0;
15799         }
15800         return result;
15801 }
15802
15803 static int do_select_reg(struct compile_state *state, 
15804         char *used, int reg, unsigned classes)
15805 {
15806         unsigned mask;
15807         if (used[reg]) {
15808                 return REG_UNSET;
15809         }
15810         mask = arch_reg_regcm(state, reg);
15811         return (classes & mask) ? reg : REG_UNSET;
15812 }
15813
15814 static int arch_select_free_register(
15815         struct compile_state *state, char *used, int classes)
15816 {
15817         /* Live ranges with the most neighbors are colored first.
15818          *
15819          * Generally it does not matter which colors are given
15820          * as the register allocator attempts to color live ranges
15821          * in an order where you are guaranteed not to run out of colors.
15822          *
15823          * Occasionally the register allocator cannot find an order
15824          * of register selection that will find a free color.  To
15825          * increase the odds the register allocator will work when
15826          * it guesses first give out registers from register classes
15827          * least likely to run out of registers.
15828          * 
15829          */
15830         int i, reg;
15831         reg = REG_UNSET;
15832         for(i = REGC_XMM_FIRST; (reg == REG_UNSET) && (i <= REGC_XMM_LAST); i++) {
15833                 reg = do_select_reg(state, used, i, classes);
15834         }
15835         for(i = REGC_MMX_FIRST; (reg == REG_UNSET) && (i <= REGC_MMX_LAST); i++) {
15836                 reg = do_select_reg(state, used, i, classes);
15837         }
15838         for(i = REGC_GPR32_LAST; (reg == REG_UNSET) && (i >= REGC_GPR32_FIRST); i--) {
15839                 reg = do_select_reg(state, used, i, classes);
15840         }
15841         for(i = REGC_GPR16_FIRST; (reg == REG_UNSET) && (i <= REGC_GPR16_LAST); i++) {
15842                 reg = do_select_reg(state, used, i, classes);
15843         }
15844         for(i = REGC_GPR8_FIRST; (reg == REG_UNSET) && (i <= REGC_GPR8_LAST); i++) {
15845                 reg = do_select_reg(state, used, i, classes);
15846         }
15847         for(i = REGC_GPR8_LO_FIRST; (reg == REG_UNSET) && (i <= REGC_GPR8_LO_LAST); i++) {
15848                 reg = do_select_reg(state, used, i, classes);
15849         }
15850         for(i = REGC_DIVIDEND32_FIRST; (reg == REG_UNSET) && (i <= REGC_DIVIDEND32_LAST); i++) {
15851                 reg = do_select_reg(state, used, i, classes);
15852         }
15853         for(i = REGC_DIVIDEND64_FIRST; (reg == REG_UNSET) && (i <= REGC_DIVIDEND64_LAST); i++) {
15854                 reg = do_select_reg(state, used, i, classes);
15855         }
15856         for(i = REGC_FLAGS_FIRST; (reg == REG_UNSET) && (i <= REGC_FLAGS_LAST); i++) {
15857                 reg = do_select_reg(state, used, i, classes);
15858         }
15859         return reg;
15860 }
15861
15862
15863 static unsigned arch_type_to_regcm(struct compile_state *state, struct type *type) 
15864 {
15865 #warning "FIXME force types smaller (if legal) before I get here"
15866         unsigned mask;
15867         mask = 0;
15868         switch(type->type & TYPE_MASK) {
15869         case TYPE_ARRAY:
15870         case TYPE_VOID: 
15871                 mask = 0; 
15872                 break;
15873         case TYPE_CHAR:
15874         case TYPE_UCHAR:
15875                 mask = REGCM_GPR8 | REGCM_GPR8_LO |
15876                         REGCM_GPR16 | REGCM_GPR16_8 | 
15877                         REGCM_GPR32 | REGCM_GPR32_8 |
15878                         REGCM_DIVIDEND32 | REGCM_DIVIDEND64 |
15879                         REGCM_MMX | REGCM_XMM |
15880                         REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8;
15881                 break;
15882         case TYPE_SHORT:
15883         case TYPE_USHORT:
15884                 mask =  REGCM_GPR16 | REGCM_GPR16_8 |
15885                         REGCM_GPR32 | REGCM_GPR32_8 |
15886                         REGCM_DIVIDEND32 | REGCM_DIVIDEND64 |
15887                         REGCM_MMX | REGCM_XMM |
15888                         REGCM_IMM32 | REGCM_IMM16;
15889                 break;
15890         case TYPE_INT:
15891         case TYPE_UINT:
15892         case TYPE_LONG:
15893         case TYPE_ULONG:
15894         case TYPE_POINTER:
15895                 mask =  REGCM_GPR32 | REGCM_GPR32_8 |
15896                         REGCM_DIVIDEND32 | REGCM_DIVIDEND64 |
15897                         REGCM_MMX | REGCM_XMM |
15898                         REGCM_IMM32;
15899                 break;
15900         default:
15901                 internal_error(state, 0, "no register class for type");
15902                 break;
15903         }
15904         mask = arch_regcm_normalize(state, mask);
15905         return mask;
15906 }
15907
15908 static int is_imm32(struct triple *imm)
15909 {
15910         return ((imm->op == OP_INTCONST) && (imm->u.cval <= 0xffffffffUL)) ||
15911                 (imm->op == OP_ADDRCONST);
15912         
15913 }
15914 static int is_imm16(struct triple *imm)
15915 {
15916         return ((imm->op == OP_INTCONST) && (imm->u.cval <= 0xffff));
15917 }
15918 static int is_imm8(struct triple *imm)
15919 {
15920         return ((imm->op == OP_INTCONST) && (imm->u.cval <= 0xff));
15921 }
15922
15923 static int get_imm32(struct triple *ins, struct triple **expr)
15924 {
15925         struct triple *imm;
15926         imm = *expr;
15927         while(imm->op == OP_COPY) {
15928                 imm = RHS(imm, 0);
15929         }
15930         if (!is_imm32(imm)) {
15931                 return 0;
15932         }
15933         unuse_triple(*expr, ins);
15934         use_triple(imm, ins);
15935         *expr = imm;
15936         return 1;
15937 }
15938
15939 static int get_imm8(struct triple *ins, struct triple **expr)
15940 {
15941         struct triple *imm;
15942         imm = *expr;
15943         while(imm->op == OP_COPY) {
15944                 imm = RHS(imm, 0);
15945         }
15946         if (!is_imm8(imm)) {
15947                 return 0;
15948         }
15949         unuse_triple(*expr, ins);
15950         use_triple(imm, ins);
15951         *expr = imm;
15952         return 1;
15953 }
15954
15955 #define TEMPLATE_NOP           0
15956 #define TEMPLATE_INTCONST8     1
15957 #define TEMPLATE_INTCONST32    2
15958 #define TEMPLATE_COPY8_REG     3
15959 #define TEMPLATE_COPY16_REG    4
15960 #define TEMPLATE_COPY32_REG    5
15961 #define TEMPLATE_COPY_IMM8     6
15962 #define TEMPLATE_COPY_IMM16    7
15963 #define TEMPLATE_COPY_IMM32    8
15964 #define TEMPLATE_PHI8          9
15965 #define TEMPLATE_PHI16        10
15966 #define TEMPLATE_PHI32        11
15967 #define TEMPLATE_STORE8       12
15968 #define TEMPLATE_STORE16      13
15969 #define TEMPLATE_STORE32      14
15970 #define TEMPLATE_LOAD8        15
15971 #define TEMPLATE_LOAD16       16
15972 #define TEMPLATE_LOAD32       17
15973 #define TEMPLATE_BINARY8_REG  18
15974 #define TEMPLATE_BINARY16_REG 19
15975 #define TEMPLATE_BINARY32_REG 20
15976 #define TEMPLATE_BINARY8_IMM  21
15977 #define TEMPLATE_BINARY16_IMM 22
15978 #define TEMPLATE_BINARY32_IMM 23
15979 #define TEMPLATE_SL8_CL       24
15980 #define TEMPLATE_SL16_CL      25
15981 #define TEMPLATE_SL32_CL      26
15982 #define TEMPLATE_SL8_IMM      27
15983 #define TEMPLATE_SL16_IMM     28
15984 #define TEMPLATE_SL32_IMM     29
15985 #define TEMPLATE_UNARY8       30
15986 #define TEMPLATE_UNARY16      31
15987 #define TEMPLATE_UNARY32      32
15988 #define TEMPLATE_CMP8_REG     33
15989 #define TEMPLATE_CMP16_REG    34
15990 #define TEMPLATE_CMP32_REG    35
15991 #define TEMPLATE_CMP8_IMM     36
15992 #define TEMPLATE_CMP16_IMM    37
15993 #define TEMPLATE_CMP32_IMM    38
15994 #define TEMPLATE_TEST8        39
15995 #define TEMPLATE_TEST16       40
15996 #define TEMPLATE_TEST32       41
15997 #define TEMPLATE_SET          42
15998 #define TEMPLATE_JMP          43
15999 #define TEMPLATE_INB_DX       44
16000 #define TEMPLATE_INB_IMM      45
16001 #define TEMPLATE_INW_DX       46
16002 #define TEMPLATE_INW_IMM      47
16003 #define TEMPLATE_INL_DX       48
16004 #define TEMPLATE_INL_IMM      49
16005 #define TEMPLATE_OUTB_DX      50
16006 #define TEMPLATE_OUTB_IMM     51
16007 #define TEMPLATE_OUTW_DX      52
16008 #define TEMPLATE_OUTW_IMM     53
16009 #define TEMPLATE_OUTL_DX      54
16010 #define TEMPLATE_OUTL_IMM     55
16011 #define TEMPLATE_BSF          56
16012 #define TEMPLATE_RDMSR        57
16013 #define TEMPLATE_WRMSR        58
16014 #define TEMPLATE_UMUL8        59
16015 #define TEMPLATE_UMUL16       60
16016 #define TEMPLATE_UMUL32       61
16017 #define TEMPLATE_DIV8         62
16018 #define TEMPLATE_DIV16        63
16019 #define TEMPLATE_DIV32        64
16020 #define LAST_TEMPLATE       TEMPLATE_DIV32
16021 #if LAST_TEMPLATE >= MAX_TEMPLATES
16022 #error "MAX_TEMPLATES to low"
16023 #endif
16024
16025 #define COPY8_REGCM     (REGCM_DIVIDEND64 | REGCM_DIVIDEND32 | REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO | REGCM_MMX | REGCM_XMM)
16026 #define COPY16_REGCM    (REGCM_DIVIDEND64 | REGCM_DIVIDEND32 | REGCM_GPR32 | REGCM_GPR16 | REGCM_MMX | REGCM_XMM)  
16027 #define COPY32_REGCM    (REGCM_DIVIDEND64 | REGCM_DIVIDEND32 | REGCM_GPR32 | REGCM_MMX | REGCM_XMM)
16028
16029
16030 static struct ins_template templates[] = {
16031         [TEMPLATE_NOP]      = {},
16032         [TEMPLATE_INTCONST8] = { 
16033                 .lhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
16034         },
16035         [TEMPLATE_INTCONST32] = { 
16036                 .lhs = { [0] = { REG_UNNEEDED, REGCM_IMM32 } },
16037         },
16038         [TEMPLATE_COPY8_REG] = {
16039                 .lhs = { [0] = { REG_UNSET, COPY8_REGCM } },
16040                 .rhs = { [0] = { REG_UNSET, COPY8_REGCM }  },
16041         },
16042         [TEMPLATE_COPY16_REG] = {
16043                 .lhs = { [0] = { REG_UNSET, COPY16_REGCM } },
16044                 .rhs = { [0] = { REG_UNSET, COPY16_REGCM }  },
16045         },
16046         [TEMPLATE_COPY32_REG] = {
16047                 .lhs = { [0] = { REG_UNSET, COPY32_REGCM } },
16048                 .rhs = { [0] = { REG_UNSET, COPY32_REGCM }  },
16049         },
16050         [TEMPLATE_COPY_IMM8] = {
16051                 .lhs = { [0] = { REG_UNSET, COPY8_REGCM } },
16052                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
16053         },
16054         [TEMPLATE_COPY_IMM16] = {
16055                 .lhs = { [0] = { REG_UNSET, COPY16_REGCM } },
16056                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM16 | REGCM_IMM8 } },
16057         },
16058         [TEMPLATE_COPY_IMM32] = {
16059                 .lhs = { [0] = { REG_UNSET, COPY32_REGCM } },
16060                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8 } },
16061         },
16062         [TEMPLATE_PHI8] = { 
16063                 .lhs = { [0] = { REG_VIRT0, COPY8_REGCM } },
16064                 .rhs = { 
16065                         [ 0] = { REG_VIRT0, COPY8_REGCM },
16066                         [ 1] = { REG_VIRT0, COPY8_REGCM },
16067                         [ 2] = { REG_VIRT0, COPY8_REGCM },
16068                         [ 3] = { REG_VIRT0, COPY8_REGCM },
16069                         [ 4] = { REG_VIRT0, COPY8_REGCM },
16070                         [ 5] = { REG_VIRT0, COPY8_REGCM },
16071                         [ 6] = { REG_VIRT0, COPY8_REGCM },
16072                         [ 7] = { REG_VIRT0, COPY8_REGCM },
16073                         [ 8] = { REG_VIRT0, COPY8_REGCM },
16074                         [ 9] = { REG_VIRT0, COPY8_REGCM },
16075                         [10] = { REG_VIRT0, COPY8_REGCM },
16076                         [11] = { REG_VIRT0, COPY8_REGCM },
16077                         [12] = { REG_VIRT0, COPY8_REGCM },
16078                         [13] = { REG_VIRT0, COPY8_REGCM },
16079                         [14] = { REG_VIRT0, COPY8_REGCM },
16080                         [15] = { REG_VIRT0, COPY8_REGCM },
16081                 }, },
16082         [TEMPLATE_PHI16] = { 
16083                 .lhs = { [0] = { REG_VIRT0, COPY16_REGCM } },
16084                 .rhs = { 
16085                         [ 0] = { REG_VIRT0, COPY16_REGCM },
16086                         [ 1] = { REG_VIRT0, COPY16_REGCM },
16087                         [ 2] = { REG_VIRT0, COPY16_REGCM },
16088                         [ 3] = { REG_VIRT0, COPY16_REGCM },
16089                         [ 4] = { REG_VIRT0, COPY16_REGCM },
16090                         [ 5] = { REG_VIRT0, COPY16_REGCM },
16091                         [ 6] = { REG_VIRT0, COPY16_REGCM },
16092                         [ 7] = { REG_VIRT0, COPY16_REGCM },
16093                         [ 8] = { REG_VIRT0, COPY16_REGCM },
16094                         [ 9] = { REG_VIRT0, COPY16_REGCM },
16095                         [10] = { REG_VIRT0, COPY16_REGCM },
16096                         [11] = { REG_VIRT0, COPY16_REGCM },
16097                         [12] = { REG_VIRT0, COPY16_REGCM },
16098                         [13] = { REG_VIRT0, COPY16_REGCM },
16099                         [14] = { REG_VIRT0, COPY16_REGCM },
16100                         [15] = { REG_VIRT0, COPY16_REGCM },
16101                 }, },
16102         [TEMPLATE_PHI32] = { 
16103                 .lhs = { [0] = { REG_VIRT0, COPY32_REGCM } },
16104                 .rhs = { 
16105                         [ 0] = { REG_VIRT0, COPY32_REGCM },
16106                         [ 1] = { REG_VIRT0, COPY32_REGCM },
16107                         [ 2] = { REG_VIRT0, COPY32_REGCM },
16108                         [ 3] = { REG_VIRT0, COPY32_REGCM },
16109                         [ 4] = { REG_VIRT0, COPY32_REGCM },
16110                         [ 5] = { REG_VIRT0, COPY32_REGCM },
16111                         [ 6] = { REG_VIRT0, COPY32_REGCM },
16112                         [ 7] = { REG_VIRT0, COPY32_REGCM },
16113                         [ 8] = { REG_VIRT0, COPY32_REGCM },
16114                         [ 9] = { REG_VIRT0, COPY32_REGCM },
16115                         [10] = { REG_VIRT0, COPY32_REGCM },
16116                         [11] = { REG_VIRT0, COPY32_REGCM },
16117                         [12] = { REG_VIRT0, COPY32_REGCM },
16118                         [13] = { REG_VIRT0, COPY32_REGCM },
16119                         [14] = { REG_VIRT0, COPY32_REGCM },
16120                         [15] = { REG_VIRT0, COPY32_REGCM },
16121                 }, },
16122         [TEMPLATE_STORE8] = {
16123                 .rhs = { 
16124                         [0] = { REG_UNSET, REGCM_GPR32 },
16125                         [1] = { REG_UNSET, REGCM_GPR8_LO },
16126                 },
16127         },
16128         [TEMPLATE_STORE16] = {
16129                 .rhs = { 
16130                         [0] = { REG_UNSET, REGCM_GPR32 },
16131                         [1] = { REG_UNSET, REGCM_GPR16 },
16132                 },
16133         },
16134         [TEMPLATE_STORE32] = {
16135                 .rhs = { 
16136                         [0] = { REG_UNSET, REGCM_GPR32 },
16137                         [1] = { REG_UNSET, REGCM_GPR32 },
16138                 },
16139         },
16140         [TEMPLATE_LOAD8] = {
16141                 .lhs = { [0] = { REG_UNSET, REGCM_GPR8_LO } },
16142                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
16143         },
16144         [TEMPLATE_LOAD16] = {
16145                 .lhs = { [0] = { REG_UNSET, REGCM_GPR16 } },
16146                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
16147         },
16148         [TEMPLATE_LOAD32] = {
16149                 .lhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
16150                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
16151         },
16152         [TEMPLATE_BINARY8_REG] = {
16153                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
16154                 .rhs = { 
16155                         [0] = { REG_VIRT0, REGCM_GPR8_LO },
16156                         [1] = { REG_UNSET, REGCM_GPR8_LO },
16157                 },
16158         },
16159         [TEMPLATE_BINARY16_REG] = {
16160                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
16161                 .rhs = { 
16162                         [0] = { REG_VIRT0, REGCM_GPR16 },
16163                         [1] = { REG_UNSET, REGCM_GPR16 },
16164                 },
16165         },
16166         [TEMPLATE_BINARY32_REG] = {
16167                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
16168                 .rhs = { 
16169                         [0] = { REG_VIRT0, REGCM_GPR32 },
16170                         [1] = { REG_UNSET, REGCM_GPR32 },
16171                 },
16172         },
16173         [TEMPLATE_BINARY8_IMM] = {
16174                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
16175                 .rhs = { 
16176                         [0] = { REG_VIRT0,    REGCM_GPR8_LO },
16177                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
16178                 },
16179         },
16180         [TEMPLATE_BINARY16_IMM] = {
16181                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
16182                 .rhs = { 
16183                         [0] = { REG_VIRT0,    REGCM_GPR16 },
16184                         [1] = { REG_UNNEEDED, REGCM_IMM16 },
16185                 },
16186         },
16187         [TEMPLATE_BINARY32_IMM] = {
16188                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
16189                 .rhs = { 
16190                         [0] = { REG_VIRT0,    REGCM_GPR32 },
16191                         [1] = { REG_UNNEEDED, REGCM_IMM32 },
16192                 },
16193         },
16194         [TEMPLATE_SL8_CL] = {
16195                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
16196                 .rhs = { 
16197                         [0] = { REG_VIRT0, REGCM_GPR8_LO },
16198                         [1] = { REG_CL, REGCM_GPR8_LO },
16199                 },
16200         },
16201         [TEMPLATE_SL16_CL] = {
16202                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
16203                 .rhs = { 
16204                         [0] = { REG_VIRT0, REGCM_GPR16 },
16205                         [1] = { REG_CL, REGCM_GPR8_LO },
16206                 },
16207         },
16208         [TEMPLATE_SL32_CL] = {
16209                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
16210                 .rhs = { 
16211                         [0] = { REG_VIRT0, REGCM_GPR32 },
16212                         [1] = { REG_CL, REGCM_GPR8_LO },
16213                 },
16214         },
16215         [TEMPLATE_SL8_IMM] = {
16216                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
16217                 .rhs = { 
16218                         [0] = { REG_VIRT0,    REGCM_GPR8_LO },
16219                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
16220                 },
16221         },
16222         [TEMPLATE_SL16_IMM] = {
16223                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
16224                 .rhs = { 
16225                         [0] = { REG_VIRT0,    REGCM_GPR16 },
16226                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
16227                 },
16228         },
16229         [TEMPLATE_SL32_IMM] = {
16230                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
16231                 .rhs = { 
16232                         [0] = { REG_VIRT0,    REGCM_GPR32 },
16233                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
16234                 },
16235         },
16236         [TEMPLATE_UNARY8] = {
16237                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
16238                 .rhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
16239         },
16240         [TEMPLATE_UNARY16] = {
16241                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
16242                 .rhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
16243         },
16244         [TEMPLATE_UNARY32] = {
16245                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
16246                 .rhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
16247         },
16248         [TEMPLATE_CMP8_REG] = {
16249                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
16250                 .rhs = {
16251                         [0] = { REG_UNSET, REGCM_GPR8_LO },
16252                         [1] = { REG_UNSET, REGCM_GPR8_LO },
16253                 },
16254         },
16255         [TEMPLATE_CMP16_REG] = {
16256                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
16257                 .rhs = {
16258                         [0] = { REG_UNSET, REGCM_GPR16 },
16259                         [1] = { REG_UNSET, REGCM_GPR16 },
16260                 },
16261         },
16262         [TEMPLATE_CMP32_REG] = {
16263                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
16264                 .rhs = {
16265                         [0] = { REG_UNSET, REGCM_GPR32 },
16266                         [1] = { REG_UNSET, REGCM_GPR32 },
16267                 },
16268         },
16269         [TEMPLATE_CMP8_IMM] = {
16270                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
16271                 .rhs = {
16272                         [0] = { REG_UNSET, REGCM_GPR8_LO },
16273                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
16274                 },
16275         },
16276         [TEMPLATE_CMP16_IMM] = {
16277                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
16278                 .rhs = {
16279                         [0] = { REG_UNSET, REGCM_GPR16 },
16280                         [1] = { REG_UNNEEDED, REGCM_IMM16 },
16281                 },
16282         },
16283         [TEMPLATE_CMP32_IMM] = {
16284                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
16285                 .rhs = {
16286                         [0] = { REG_UNSET, REGCM_GPR32 },
16287                         [1] = { REG_UNNEEDED, REGCM_IMM32 },
16288                 },
16289         },
16290         [TEMPLATE_TEST8] = {
16291                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
16292                 .rhs = { [0] = { REG_UNSET, REGCM_GPR8_LO } },
16293         },
16294         [TEMPLATE_TEST16] = {
16295                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
16296                 .rhs = { [0] = { REG_UNSET, REGCM_GPR16 } },
16297         },
16298         [TEMPLATE_TEST32] = {
16299                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
16300                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
16301         },
16302         [TEMPLATE_SET] = {
16303                 .lhs = { [0] = { REG_UNSET, REGCM_GPR8_LO } },
16304                 .rhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
16305         },
16306         [TEMPLATE_JMP] = {
16307                 .rhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
16308         },
16309         [TEMPLATE_INB_DX] = {
16310                 .lhs = { [0] = { REG_AL,  REGCM_GPR8_LO } },  
16311                 .rhs = { [0] = { REG_DX, REGCM_GPR16 } },
16312         },
16313         [TEMPLATE_INB_IMM] = {
16314                 .lhs = { [0] = { REG_AL,  REGCM_GPR8_LO } },  
16315                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
16316         },
16317         [TEMPLATE_INW_DX]  = { 
16318                 .lhs = { [0] = { REG_AX,  REGCM_GPR16 } }, 
16319                 .rhs = { [0] = { REG_DX, REGCM_GPR16 } },
16320         },
16321         [TEMPLATE_INW_IMM] = { 
16322                 .lhs = { [0] = { REG_AX,  REGCM_GPR16 } }, 
16323                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
16324         },
16325         [TEMPLATE_INL_DX]  = {
16326                 .lhs = { [0] = { REG_EAX, REGCM_GPR32 } },
16327                 .rhs = { [0] = { REG_DX, REGCM_GPR16 } },
16328         },
16329         [TEMPLATE_INL_IMM] = {
16330                 .lhs = { [0] = { REG_EAX, REGCM_GPR32 } },
16331                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
16332         },
16333         [TEMPLATE_OUTB_DX] = { 
16334                 .rhs = {
16335                         [0] = { REG_AL,  REGCM_GPR8_LO },
16336                         [1] = { REG_DX, REGCM_GPR16 },
16337                 },
16338         },
16339         [TEMPLATE_OUTB_IMM] = { 
16340                 .rhs = {
16341                         [0] = { REG_AL,  REGCM_GPR8_LO },  
16342                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
16343                 },
16344         },
16345         [TEMPLATE_OUTW_DX] = { 
16346                 .rhs = {
16347                         [0] = { REG_AX,  REGCM_GPR16 },
16348                         [1] = { REG_DX, REGCM_GPR16 },
16349                 },
16350         },
16351         [TEMPLATE_OUTW_IMM] = {
16352                 .rhs = {
16353                         [0] = { REG_AX,  REGCM_GPR16 }, 
16354                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
16355                 },
16356         },
16357         [TEMPLATE_OUTL_DX] = { 
16358                 .rhs = {
16359                         [0] = { REG_EAX, REGCM_GPR32 },
16360                         [1] = { REG_DX, REGCM_GPR16 },
16361                 },
16362         },
16363         [TEMPLATE_OUTL_IMM] = { 
16364                 .rhs = {
16365                         [0] = { REG_EAX, REGCM_GPR32 }, 
16366                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
16367                 },
16368         },
16369         [TEMPLATE_BSF] = {
16370                 .lhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
16371                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
16372         },
16373         [TEMPLATE_RDMSR] = {
16374                 .lhs = { 
16375                         [0] = { REG_EAX, REGCM_GPR32 },
16376                         [1] = { REG_EDX, REGCM_GPR32 },
16377                 },
16378                 .rhs = { [0] = { REG_ECX, REGCM_GPR32 } },
16379         },
16380         [TEMPLATE_WRMSR] = {
16381                 .rhs = {
16382                         [0] = { REG_ECX, REGCM_GPR32 },
16383                         [1] = { REG_EAX, REGCM_GPR32 },
16384                         [2] = { REG_EDX, REGCM_GPR32 },
16385                 },
16386         },
16387         [TEMPLATE_UMUL8] = {
16388                 .lhs = { [0] = { REG_AX, REGCM_GPR16 } },
16389                 .rhs = { 
16390                         [0] = { REG_AL, REGCM_GPR8_LO },
16391                         [1] = { REG_UNSET, REGCM_GPR8_LO },
16392                 },
16393         },
16394         [TEMPLATE_UMUL16] = {
16395                 .lhs = { [0] = { REG_DXAX, REGCM_DIVIDEND32 } },
16396                 .rhs = { 
16397                         [0] = { REG_AX, REGCM_GPR16 },
16398                         [1] = { REG_UNSET, REGCM_GPR16 },
16399                 },
16400         },
16401         [TEMPLATE_UMUL32] = {
16402                 .lhs = { [0] = { REG_EDXEAX, REGCM_DIVIDEND64 } },
16403                 .rhs = { 
16404                         [0] = { REG_EAX, REGCM_GPR32 },
16405                         [1] = { REG_UNSET, REGCM_GPR32 },
16406                 },
16407         },
16408         [TEMPLATE_DIV8] = {
16409                 .lhs = { 
16410                         [0] = { REG_AL, REGCM_GPR8_LO },
16411                         [1] = { REG_AH, REGCM_GPR8 },
16412                 },
16413                 .rhs = {
16414                         [0] = { REG_AX, REGCM_GPR16 },
16415                         [1] = { REG_UNSET, REGCM_GPR8_LO },
16416                 },
16417         },
16418         [TEMPLATE_DIV16] = {
16419                 .lhs = { 
16420                         [0] = { REG_AX, REGCM_GPR16 },
16421                         [1] = { REG_DX, REGCM_GPR16 },
16422                 },
16423                 .rhs = {
16424                         [0] = { REG_DXAX, REGCM_DIVIDEND32 },
16425                         [1] = { REG_UNSET, REGCM_GPR16 },
16426                 },
16427         },
16428         [TEMPLATE_DIV32] = {
16429                 .lhs = { 
16430                         [0] = { REG_EAX, REGCM_GPR32 },
16431                         [1] = { REG_EDX, REGCM_GPR32 },
16432                 },
16433                 .rhs = {
16434                         [0] = { REG_EDXEAX, REGCM_DIVIDEND64 },
16435                         [1] = { REG_UNSET, REGCM_GPR32 },
16436                 },
16437         },
16438 };
16439
16440 static void fixup_branches(struct compile_state *state,
16441         struct triple *cmp, struct triple *use, int jmp_op)
16442 {
16443         struct triple_set *entry, *next;
16444         for(entry = use->use; entry; entry = next) {
16445                 next = entry->next;
16446                 if (entry->member->op == OP_COPY) {
16447                         fixup_branches(state, cmp, entry->member, jmp_op);
16448                 }
16449                 else if (entry->member->op == OP_BRANCH) {
16450                         struct triple *branch, *test;
16451                         struct triple *left, *right;
16452                         left = right = 0;
16453                         left = RHS(cmp, 0);
16454                         if (TRIPLE_RHS(cmp->sizes) > 1) {
16455                                 right = RHS(cmp, 1);
16456                         }
16457                         branch = entry->member;
16458                         test = pre_triple(state, branch,
16459                                 cmp->op, cmp->type, left, right);
16460                         test->template_id = TEMPLATE_TEST32; 
16461                         if (cmp->op == OP_CMP) {
16462                                 test->template_id = TEMPLATE_CMP32_REG;
16463                                 if (get_imm32(test, &RHS(test, 1))) {
16464                                         test->template_id = TEMPLATE_CMP32_IMM;
16465                                 }
16466                         }
16467                         use_triple(RHS(test, 0), test);
16468                         use_triple(RHS(test, 1), test);
16469                         unuse_triple(RHS(branch, 0), branch);
16470                         RHS(branch, 0) = test;
16471                         branch->op = jmp_op;
16472                         branch->template_id = TEMPLATE_JMP;
16473                         use_triple(RHS(branch, 0), branch);
16474                 }
16475         }
16476 }
16477
16478 static void bool_cmp(struct compile_state *state, 
16479         struct triple *ins, int cmp_op, int jmp_op, int set_op)
16480 {
16481         struct triple_set *entry, *next;
16482         struct triple *set;
16483
16484         /* Put a barrier up before the cmp which preceeds the
16485          * copy instruction.  If a set actually occurs this gives
16486          * us a chance to move variables in registers out of the way.
16487          */
16488
16489         /* Modify the comparison operator */
16490         ins->op = cmp_op;
16491         ins->template_id = TEMPLATE_TEST32;
16492         if (cmp_op == OP_CMP) {
16493                 ins->template_id = TEMPLATE_CMP32_REG;
16494                 if (get_imm32(ins, &RHS(ins, 1))) {
16495                         ins->template_id =  TEMPLATE_CMP32_IMM;
16496                 }
16497         }
16498         /* Generate the instruction sequence that will transform the
16499          * result of the comparison into a logical value.
16500          */
16501         set = post_triple(state, ins, set_op, &char_type, ins, 0);
16502         use_triple(ins, set);
16503         set->template_id = TEMPLATE_SET;
16504
16505         for(entry = ins->use; entry; entry = next) {
16506                 next = entry->next;
16507                 if (entry->member == set) {
16508                         continue;
16509                 }
16510                 replace_rhs_use(state, ins, set, entry->member);
16511         }
16512         fixup_branches(state, ins, set, jmp_op);
16513 }
16514
16515 static struct triple *after_lhs(struct compile_state *state, struct triple *ins)
16516 {
16517         struct triple *next;
16518         int lhs, i;
16519         lhs = TRIPLE_LHS(ins->sizes);
16520         for(next = ins->next, i = 0; i < lhs; i++, next = next->next) {
16521                 if (next != LHS(ins, i)) {
16522                         internal_error(state, ins, "malformed lhs on %s",
16523                                 tops(ins->op));
16524                 }
16525                 if (next->op != OP_PIECE) {
16526                         internal_error(state, ins, "bad lhs op %s at %d on %s",
16527                                 tops(next->op), i, tops(ins->op));
16528                 }
16529                 if (next->u.cval != i) {
16530                         internal_error(state, ins, "bad u.cval of %d %d expected",
16531                                 next->u.cval, i);
16532                 }
16533         }
16534         return next;
16535 }
16536
16537 struct reg_info arch_reg_lhs(struct compile_state *state, struct triple *ins, int index)
16538 {
16539         struct ins_template *template;
16540         struct reg_info result;
16541         int zlhs;
16542         if (ins->op == OP_PIECE) {
16543                 index = ins->u.cval;
16544                 ins = MISC(ins, 0);
16545         }
16546         zlhs = TRIPLE_LHS(ins->sizes);
16547         if (triple_is_def(state, ins)) {
16548                 zlhs = 1;
16549         }
16550         if (index >= zlhs) {
16551                 internal_error(state, ins, "index %d out of range for %s\n",
16552                         index, tops(ins->op));
16553         }
16554         switch(ins->op) {
16555         case OP_ASM:
16556                 template = &ins->u.ainfo->tmpl;
16557                 break;
16558         default:
16559                 if (ins->template_id > LAST_TEMPLATE) {
16560                         internal_error(state, ins, "bad template number %d", 
16561                                 ins->template_id);
16562                 }
16563                 template = &templates[ins->template_id];
16564                 break;
16565         }
16566         result = template->lhs[index];
16567         result.regcm = arch_regcm_normalize(state, result.regcm);
16568         if (result.reg != REG_UNNEEDED) {
16569                 result.regcm &= ~(REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8);
16570         }
16571         if (result.regcm == 0) {
16572                 internal_error(state, ins, "lhs %d regcm == 0", index);
16573         }
16574         return result;
16575 }
16576
16577 struct reg_info arch_reg_rhs(struct compile_state *state, struct triple *ins, int index)
16578 {
16579         struct reg_info result;
16580         struct ins_template *template;
16581         if ((index > TRIPLE_RHS(ins->sizes)) ||
16582                 (ins->op == OP_PIECE)) {
16583                 internal_error(state, ins, "index %d out of range for %s\n",
16584                         index, tops(ins->op));
16585         }
16586         switch(ins->op) {
16587         case OP_ASM:
16588                 template = &ins->u.ainfo->tmpl;
16589                 break;
16590         default:
16591                 if (ins->template_id > LAST_TEMPLATE) {
16592                         internal_error(state, ins, "bad template number %d", 
16593                                 ins->template_id);
16594                 }
16595                 template = &templates[ins->template_id];
16596                 break;
16597         }
16598         result = template->rhs[index];
16599         result.regcm = arch_regcm_normalize(state, result.regcm);
16600         if (result.regcm == 0) {
16601                 internal_error(state, ins, "rhs %d regcm == 0", index);
16602         }
16603         return result;
16604 }
16605
16606 static struct triple *mod_div(struct compile_state *state,
16607         struct triple *ins, int div_op, int index)
16608 {
16609         struct triple *div, *piece0, *piece1;
16610         
16611         /* Generate a piece to hold the remainder */
16612         piece1 = post_triple(state, ins, OP_PIECE, ins->type, 0, 0);
16613         piece1->u.cval = 1;
16614
16615         /* Generate a piece to hold the quotient */
16616         piece0 = post_triple(state, ins, OP_PIECE, ins->type, 0, 0);
16617         piece0->u.cval = 0;
16618
16619         /* Generate the appropriate division instruction */
16620         div = post_triple(state, ins, div_op, ins->type, 0, 0);
16621         RHS(div, 0) = RHS(ins, 0);
16622         RHS(div, 1) = RHS(ins, 1);
16623         LHS(div, 0) = piece0;
16624         LHS(div, 1) = piece1;
16625         div->template_id  = TEMPLATE_DIV32;
16626         use_triple(RHS(div, 0), div);
16627         use_triple(RHS(div, 1), div);
16628         use_triple(LHS(div, 0), div);
16629         use_triple(LHS(div, 1), div);
16630
16631         /* Hook on piece0 */
16632         MISC(piece0, 0) = div;
16633         use_triple(div, piece0);
16634
16635         /* Hook on piece1 */
16636         MISC(piece1, 0) = div;
16637         use_triple(div, piece1);
16638         
16639         /* Replate uses of ins with the appropriate piece of the div */
16640         propogate_use(state, ins, LHS(div, index));
16641         release_triple(state, ins);
16642
16643         /* Return the address of the next instruction */
16644         return piece1->next;
16645 }
16646
16647 static struct triple *transform_to_arch_instruction(
16648         struct compile_state *state, struct triple *ins)
16649 {
16650         /* Transform from generic 3 address instructions
16651          * to archtecture specific instructions.
16652          * And apply architecture specific constraints to instructions.
16653          * Copies are inserted to preserve the register flexibility
16654          * of 3 address instructions.
16655          */
16656         struct triple *next;
16657         size_t size;
16658         next = ins->next;
16659         switch(ins->op) {
16660         case OP_INTCONST:
16661                 ins->template_id = TEMPLATE_INTCONST32;
16662                 if (ins->u.cval < 256) {
16663                         ins->template_id = TEMPLATE_INTCONST8;
16664                 }
16665                 break;
16666         case OP_ADDRCONST:
16667                 ins->template_id = TEMPLATE_INTCONST32;
16668                 break;
16669         case OP_NOOP:
16670         case OP_SDECL:
16671         case OP_BLOBCONST:
16672         case OP_LABEL:
16673                 ins->template_id = TEMPLATE_NOP;
16674                 break;
16675         case OP_COPY:
16676                 size = size_of(state, ins->type);
16677                 if (is_imm8(RHS(ins, 0)) && (size <= 1)) {
16678                         ins->template_id = TEMPLATE_COPY_IMM8;
16679                 }
16680                 else if (is_imm16(RHS(ins, 0)) && (size <= 2)) {
16681                         ins->template_id = TEMPLATE_COPY_IMM16;
16682                 }
16683                 else if (is_imm32(RHS(ins, 0)) && (size <= 4)) {
16684                         ins->template_id = TEMPLATE_COPY_IMM32;
16685                 }
16686                 else if (is_const(RHS(ins, 0))) {
16687                         internal_error(state, ins, "bad constant passed to copy");
16688                 }
16689                 else if (size <= 1) {
16690                         ins->template_id = TEMPLATE_COPY8_REG;
16691                 }
16692                 else if (size <= 2) {
16693                         ins->template_id = TEMPLATE_COPY16_REG;
16694                 }
16695                 else if (size <= 4) {
16696                         ins->template_id = TEMPLATE_COPY32_REG;
16697                 }
16698                 else {
16699                         internal_error(state, ins, "bad type passed to copy");
16700                 }
16701                 break;
16702         case OP_PHI:
16703                 size = size_of(state, ins->type);
16704                 if (size <= 1) {
16705                         ins->template_id = TEMPLATE_PHI8;
16706                 }
16707                 else if (size <= 2) {
16708                         ins->template_id = TEMPLATE_PHI16;
16709                 }
16710                 else if (size <= 4) {
16711                         ins->template_id = TEMPLATE_PHI32;
16712                 }
16713                 else {
16714                         internal_error(state, ins, "bad type passed to phi");
16715                 }
16716                 break;
16717         case OP_STORE:
16718                 switch(ins->type->type & TYPE_MASK) {
16719                 case TYPE_CHAR:    case TYPE_UCHAR:
16720                         ins->template_id = TEMPLATE_STORE8;
16721                         break;
16722                 case TYPE_SHORT:   case TYPE_USHORT:
16723                         ins->template_id = TEMPLATE_STORE16;
16724                         break;
16725                 case TYPE_INT:     case TYPE_UINT:
16726                 case TYPE_LONG:    case TYPE_ULONG:
16727                 case TYPE_POINTER:
16728                         ins->template_id = TEMPLATE_STORE32;
16729                         break;
16730                 default:
16731                         internal_error(state, ins, "unknown type in store");
16732                         break;
16733                 }
16734                 break;
16735         case OP_LOAD:
16736                 switch(ins->type->type & TYPE_MASK) {
16737                 case TYPE_CHAR:   case TYPE_UCHAR:
16738                         ins->template_id = TEMPLATE_LOAD8;
16739                         break;
16740                 case TYPE_SHORT:
16741                 case TYPE_USHORT:
16742                         ins->template_id = TEMPLATE_LOAD16;
16743                         break;
16744                 case TYPE_INT:
16745                 case TYPE_UINT:
16746                 case TYPE_LONG:
16747                 case TYPE_ULONG:
16748                 case TYPE_POINTER:
16749                         ins->template_id = TEMPLATE_LOAD32;
16750                         break;
16751                 default:
16752                         internal_error(state, ins, "unknown type in load");
16753                         break;
16754                 }
16755                 break;
16756         case OP_ADD:
16757         case OP_SUB:
16758         case OP_AND:
16759         case OP_XOR:
16760         case OP_OR:
16761         case OP_SMUL:
16762                 ins->template_id = TEMPLATE_BINARY32_REG;
16763                 if (get_imm32(ins, &RHS(ins, 1))) {
16764                         ins->template_id = TEMPLATE_BINARY32_IMM;
16765                 }
16766                 break;
16767         case OP_SDIVT:
16768         case OP_UDIVT:
16769                 ins->template_id = TEMPLATE_DIV32;
16770                 next = after_lhs(state, ins);
16771                 break;
16772                 /* FIXME UMUL does not work yet.. */
16773         case OP_UMUL:
16774                 ins->template_id = TEMPLATE_UMUL32;
16775                 break;
16776         case OP_UDIV:
16777                 next = mod_div(state, ins, OP_UDIVT, 0);
16778                 break;
16779         case OP_SDIV:
16780                 next = mod_div(state, ins, OP_SDIVT, 0);
16781                 break;
16782         case OP_UMOD:
16783                 next = mod_div(state, ins, OP_UDIVT, 1);
16784                 break;
16785         case OP_SMOD:
16786                 next = mod_div(state, ins, OP_SDIVT, 1);
16787                 break;
16788         case OP_SL:
16789         case OP_SSR:
16790         case OP_USR:
16791                 ins->template_id = TEMPLATE_SL32_CL;
16792                 if (get_imm8(ins, &RHS(ins, 1))) {
16793                         ins->template_id = TEMPLATE_SL32_IMM;
16794                 } else if (size_of(state, RHS(ins, 1)->type) > 1) {
16795                         typed_pre_copy(state, &char_type, ins, 1);
16796                 }
16797                 break;
16798         case OP_INVERT:
16799         case OP_NEG:
16800                 ins->template_id = TEMPLATE_UNARY32;
16801                 break;
16802         case OP_EQ: 
16803                 bool_cmp(state, ins, OP_CMP, OP_JMP_EQ, OP_SET_EQ); 
16804                 break;
16805         case OP_NOTEQ:
16806                 bool_cmp(state, ins, OP_CMP, OP_JMP_NOTEQ, OP_SET_NOTEQ);
16807                 break;
16808         case OP_SLESS:
16809                 bool_cmp(state, ins, OP_CMP, OP_JMP_SLESS, OP_SET_SLESS);
16810                 break;
16811         case OP_ULESS:
16812                 bool_cmp(state, ins, OP_CMP, OP_JMP_ULESS, OP_SET_ULESS);
16813                 break;
16814         case OP_SMORE:
16815                 bool_cmp(state, ins, OP_CMP, OP_JMP_SMORE, OP_SET_SMORE);
16816                 break;
16817         case OP_UMORE:
16818                 bool_cmp(state, ins, OP_CMP, OP_JMP_UMORE, OP_SET_UMORE);
16819                 break;
16820         case OP_SLESSEQ:
16821                 bool_cmp(state, ins, OP_CMP, OP_JMP_SLESSEQ, OP_SET_SLESSEQ);
16822                 break;
16823         case OP_ULESSEQ:
16824                 bool_cmp(state, ins, OP_CMP, OP_JMP_ULESSEQ, OP_SET_ULESSEQ);
16825                 break;
16826         case OP_SMOREEQ:
16827                 bool_cmp(state, ins, OP_CMP, OP_JMP_SMOREEQ, OP_SET_SMOREEQ);
16828                 break;
16829         case OP_UMOREEQ:
16830                 bool_cmp(state, ins, OP_CMP, OP_JMP_UMOREEQ, OP_SET_UMOREEQ);
16831                 break;
16832         case OP_LTRUE:
16833                 bool_cmp(state, ins, OP_TEST, OP_JMP_NOTEQ, OP_SET_NOTEQ);
16834                 break;
16835         case OP_LFALSE:
16836                 bool_cmp(state, ins, OP_TEST, OP_JMP_EQ, OP_SET_EQ);
16837                 break;
16838         case OP_BRANCH:
16839                 if (TRIPLE_RHS(ins->sizes) > 0) {
16840                         internal_error(state, ins, "bad branch test");
16841                 }
16842                 ins->op = OP_JMP;
16843                 ins->template_id = TEMPLATE_NOP;
16844                 break;
16845         case OP_INB:
16846         case OP_INW:
16847         case OP_INL:
16848                 switch(ins->op) {
16849                 case OP_INB: ins->template_id = TEMPLATE_INB_DX; break;
16850                 case OP_INW: ins->template_id = TEMPLATE_INW_DX; break;
16851                 case OP_INL: ins->template_id = TEMPLATE_INL_DX; break;
16852                 }
16853                 if (get_imm8(ins, &RHS(ins, 0))) {
16854                         ins->template_id += 1;
16855                 }
16856                 break;
16857         case OP_OUTB:
16858         case OP_OUTW:
16859         case OP_OUTL:
16860                 switch(ins->op) {
16861                 case OP_OUTB: ins->template_id = TEMPLATE_OUTB_DX; break;
16862                 case OP_OUTW: ins->template_id = TEMPLATE_OUTW_DX; break;
16863                 case OP_OUTL: ins->template_id = TEMPLATE_OUTL_DX; break;
16864                 }
16865                 if (get_imm8(ins, &RHS(ins, 1))) {
16866                         ins->template_id += 1;
16867                 }
16868                 break;
16869         case OP_BSF:
16870         case OP_BSR:
16871                 ins->template_id = TEMPLATE_BSF;
16872                 break;
16873         case OP_RDMSR:
16874                 ins->template_id = TEMPLATE_RDMSR;
16875                 next = after_lhs(state, ins);
16876                 break;
16877         case OP_WRMSR:
16878                 ins->template_id = TEMPLATE_WRMSR;
16879                 break;
16880         case OP_HLT:
16881                 ins->template_id = TEMPLATE_NOP;
16882                 break;
16883         case OP_ASM:
16884                 ins->template_id = TEMPLATE_NOP;
16885                 next = after_lhs(state, ins);
16886                 break;
16887                 /* Already transformed instructions */
16888         case OP_TEST:
16889                 ins->template_id = TEMPLATE_TEST32;
16890                 break;
16891         case OP_CMP:
16892                 ins->template_id = TEMPLATE_CMP32_REG;
16893                 if (get_imm32(ins, &RHS(ins, 1))) {
16894                         ins->template_id = TEMPLATE_CMP32_IMM;
16895                 }
16896                 break;
16897         case OP_JMP_EQ:      case OP_JMP_NOTEQ:
16898         case OP_JMP_SLESS:   case OP_JMP_ULESS:
16899         case OP_JMP_SMORE:   case OP_JMP_UMORE:
16900         case OP_JMP_SLESSEQ: case OP_JMP_ULESSEQ:
16901         case OP_JMP_SMOREEQ: case OP_JMP_UMOREEQ:
16902                 ins->template_id = TEMPLATE_JMP;
16903                 break;
16904         case OP_SET_EQ:      case OP_SET_NOTEQ:
16905         case OP_SET_SLESS:   case OP_SET_ULESS:
16906         case OP_SET_SMORE:   case OP_SET_UMORE:
16907         case OP_SET_SLESSEQ: case OP_SET_ULESSEQ:
16908         case OP_SET_SMOREEQ: case OP_SET_UMOREEQ:
16909                 ins->template_id = TEMPLATE_SET;
16910                 break;
16911                 /* Unhandled instructions */
16912         case OP_PIECE:
16913         default:
16914                 internal_error(state, ins, "unhandled ins: %d %s\n",
16915                         ins->op, tops(ins->op));
16916                 break;
16917         }
16918         return next;
16919 }
16920
16921 static long next_label(struct compile_state *state)
16922 {
16923         static long label_counter = 0;
16924         return ++label_counter;
16925 }
16926 static void generate_local_labels(struct compile_state *state)
16927 {
16928         struct triple *first, *label;
16929         first = RHS(state->main_function, 0);
16930         label = first;
16931         do {
16932                 if ((label->op == OP_LABEL) || 
16933                         (label->op == OP_SDECL)) {
16934                         if (label->use) {
16935                                 label->u.cval = next_label(state);
16936                         } else {
16937                                 label->u.cval = 0;
16938                         }
16939                         
16940                 }
16941                 label = label->next;
16942         } while(label != first);
16943 }
16944
16945 static int check_reg(struct compile_state *state, 
16946         struct triple *triple, int classes)
16947 {
16948         unsigned mask;
16949         int reg;
16950         reg = ID_REG(triple->id);
16951         if (reg == REG_UNSET) {
16952                 internal_error(state, triple, "register not set");
16953         }
16954         mask = arch_reg_regcm(state, reg);
16955         if (!(classes & mask)) {
16956                 internal_error(state, triple, "reg %d in wrong class",
16957                         reg);
16958         }
16959         return reg;
16960 }
16961
16962 static const char *arch_reg_str(int reg)
16963 {
16964 #if REG_XMM7 != 44
16965 #error "Registers have renumberd fix arch_reg_str"
16966 #endif
16967         static const char *regs[] = {
16968                 "%unset",
16969                 "%unneeded",
16970                 "%eflags",
16971                 "%al", "%bl", "%cl", "%dl", "%ah", "%bh", "%ch", "%dh",
16972                 "%ax", "%bx", "%cx", "%dx", "%si", "%di", "%bp", "%sp",
16973                 "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi", "%ebp", "%esp",
16974                 "%edx:%eax",
16975                 "%dx:%ax",
16976                 "%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7",
16977                 "%xmm0", "%xmm1", "%xmm2", "%xmm3", 
16978                 "%xmm4", "%xmm5", "%xmm6", "%xmm7",
16979         };
16980         if (!((reg >= REG_EFLAGS) && (reg <= REG_XMM7))) {
16981                 reg = 0;
16982         }
16983         return regs[reg];
16984 }
16985
16986
16987 static const char *reg(struct compile_state *state, struct triple *triple,
16988         int classes)
16989 {
16990         int reg;
16991         reg = check_reg(state, triple, classes);
16992         return arch_reg_str(reg);
16993 }
16994
16995 const char *type_suffix(struct compile_state *state, struct type *type)
16996 {
16997         const char *suffix;
16998         switch(size_of(state, type)) {
16999         case 1: suffix = "b"; break;
17000         case 2: suffix = "w"; break;
17001         case 4: suffix = "l"; break;
17002         default:
17003                 internal_error(state, 0, "unknown suffix");
17004                 suffix = 0;
17005                 break;
17006         }
17007         return suffix;
17008 }
17009
17010 static void print_const_val(
17011         struct compile_state *state, struct triple *ins, FILE *fp)
17012 {
17013         switch(ins->op) {
17014         case OP_INTCONST:
17015                 fprintf(fp, " $%ld ", 
17016                         (long_t)(ins->u.cval));
17017                 break;
17018         case OP_ADDRCONST:
17019                 if (MISC(ins, 0)->op != OP_SDECL) {
17020                         internal_error(state, ins, "bad base for addrconst");
17021                 }
17022                 if (MISC(ins, 0)->u.cval <= 0) {
17023                         internal_error(state, ins, "unlabeled constant");
17024                 }
17025                 fprintf(fp, " $L%s%lu+%lu ",
17026                         state->label_prefix, 
17027                         MISC(ins, 0)->u.cval,
17028                         ins->u.cval);
17029                 break;
17030         default:
17031                 internal_error(state, ins, "unknown constant type");
17032                 break;
17033         }
17034 }
17035
17036 static void print_const(struct compile_state *state,
17037         struct triple *ins, FILE *fp)
17038 {
17039         switch(ins->op) {
17040         case OP_INTCONST:
17041                 switch(ins->type->type & TYPE_MASK) {
17042                 case TYPE_CHAR:
17043                 case TYPE_UCHAR:
17044                         fprintf(fp, ".byte 0x%02lx\n", ins->u.cval);
17045                         break;
17046                 case TYPE_SHORT:
17047                 case TYPE_USHORT:
17048                         fprintf(fp, ".short 0x%04lx\n", ins->u.cval);
17049                         break;
17050                 case TYPE_INT:
17051                 case TYPE_UINT:
17052                 case TYPE_LONG:
17053                 case TYPE_ULONG:
17054                         fprintf(fp, ".int %lu\n", ins->u.cval);
17055                         break;
17056                 default:
17057                         internal_error(state, ins, "Unknown constant type");
17058                 }
17059                 break;
17060         case OP_ADDRCONST:
17061                 if (MISC(ins, 0)->op != OP_SDECL) {
17062                         internal_error(state, ins, "bad base for addrconst");
17063                 }
17064                 if (MISC(ins, 0)->u.cval <= 0) {
17065                         internal_error(state, ins, "unlabeled constant");
17066                 }
17067                 fprintf(fp, ".int L%s%lu+%lu\n",
17068                         state->label_prefix,
17069                         MISC(ins, 0)->u.cval,
17070                         ins->u.cval);
17071                 break;
17072         case OP_BLOBCONST:
17073         {
17074                 unsigned char *blob;
17075                 size_t size, i;
17076                 size = size_of(state, ins->type);
17077                 blob = ins->u.blob;
17078                 for(i = 0; i < size; i++) {
17079                         fprintf(fp, ".byte 0x%02x\n",
17080                                 blob[i]);
17081                 }
17082                 break;
17083         }
17084         default:
17085                 internal_error(state, ins, "Unknown constant type");
17086                 break;
17087         }
17088 }
17089
17090 #define TEXT_SECTION ".rom.text"
17091 #define DATA_SECTION ".rom.data"
17092
17093 static long get_const_pool_ref(
17094         struct compile_state *state, struct triple *ins, FILE *fp)
17095 {
17096         long ref;
17097         ref = next_label(state);
17098         fprintf(fp, ".section \"" DATA_SECTION "\"\n");
17099         fprintf(fp, ".balign %d\n", align_of(state, ins->type));
17100         fprintf(fp, "L%s%lu:\n", state->label_prefix, ref);
17101         print_const(state, ins, fp);
17102         fprintf(fp, ".section \"" TEXT_SECTION "\"\n");
17103         return ref;
17104 }
17105
17106 static void print_binary_op(struct compile_state *state,
17107         const char *op, struct triple *ins, FILE *fp) 
17108 {
17109         unsigned mask;
17110         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO;
17111         if (RHS(ins, 0)->id != ins->id) {
17112                 internal_error(state, ins, "invalid register assignment");
17113         }
17114         if (is_const(RHS(ins, 1))) {
17115                 fprintf(fp, "\t%s ", op);
17116                 print_const_val(state, RHS(ins, 1), fp);
17117                 fprintf(fp, ", %s\n",
17118                         reg(state, RHS(ins, 0), mask));
17119         }
17120         else {
17121                 unsigned lmask, rmask;
17122                 int lreg, rreg;
17123                 lreg = check_reg(state, RHS(ins, 0), mask);
17124                 rreg = check_reg(state, RHS(ins, 1), mask);
17125                 lmask = arch_reg_regcm(state, lreg);
17126                 rmask = arch_reg_regcm(state, rreg);
17127                 mask = lmask & rmask;
17128                 fprintf(fp, "\t%s %s, %s\n",
17129                         op,
17130                         reg(state, RHS(ins, 1), mask),
17131                         reg(state, RHS(ins, 0), mask));
17132         }
17133 }
17134 static void print_unary_op(struct compile_state *state, 
17135         const char *op, struct triple *ins, FILE *fp)
17136 {
17137         unsigned mask;
17138         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO;
17139         fprintf(fp, "\t%s %s\n",
17140                 op,
17141                 reg(state, RHS(ins, 0), mask));
17142 }
17143
17144 static void print_op_shift(struct compile_state *state,
17145         const char *op, struct triple *ins, FILE *fp)
17146 {
17147         unsigned mask;
17148         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO;
17149         if (RHS(ins, 0)->id != ins->id) {
17150                 internal_error(state, ins, "invalid register assignment");
17151         }
17152         if (is_const(RHS(ins, 1))) {
17153                 fprintf(fp, "\t%s ", op);
17154                 print_const_val(state, RHS(ins, 1), fp);
17155                 fprintf(fp, ", %s\n",
17156                         reg(state, RHS(ins, 0), mask));
17157         }
17158         else {
17159                 fprintf(fp, "\t%s %s, %s\n",
17160                         op,
17161                         reg(state, RHS(ins, 1), REGCM_GPR8_LO),
17162                         reg(state, RHS(ins, 0), mask));
17163         }
17164 }
17165
17166 static void print_op_in(struct compile_state *state, struct triple *ins, FILE *fp)
17167 {
17168         const char *op;
17169         int mask;
17170         int dreg;
17171         mask = 0;
17172         switch(ins->op) {
17173         case OP_INB: op = "inb", mask = REGCM_GPR8_LO; break;
17174         case OP_INW: op = "inw", mask = REGCM_GPR16; break;
17175         case OP_INL: op = "inl", mask = REGCM_GPR32; break;
17176         default:
17177                 internal_error(state, ins, "not an in operation");
17178                 op = 0;
17179                 break;
17180         }
17181         dreg = check_reg(state, ins, mask);
17182         if (!reg_is_reg(state, dreg, REG_EAX)) {
17183                 internal_error(state, ins, "dst != %%eax");
17184         }
17185         if (is_const(RHS(ins, 0))) {
17186                 fprintf(fp, "\t%s ", op);
17187                 print_const_val(state, RHS(ins, 0), fp);
17188                 fprintf(fp, ", %s\n",
17189                         reg(state, ins, mask));
17190         }
17191         else {
17192                 int addr_reg;
17193                 addr_reg = check_reg(state, RHS(ins, 0), REGCM_GPR16);
17194                 if (!reg_is_reg(state, addr_reg, REG_DX)) {
17195                         internal_error(state, ins, "src != %%dx");
17196                 }
17197                 fprintf(fp, "\t%s %s, %s\n",
17198                         op, 
17199                         reg(state, RHS(ins, 0), REGCM_GPR16),
17200                         reg(state, ins, mask));
17201         }
17202 }
17203
17204 static void print_op_out(struct compile_state *state, struct triple *ins, FILE *fp)
17205 {
17206         const char *op;
17207         int mask;
17208         int lreg;
17209         mask = 0;
17210         switch(ins->op) {
17211         case OP_OUTB: op = "outb", mask = REGCM_GPR8_LO; break;
17212         case OP_OUTW: op = "outw", mask = REGCM_GPR16; break;
17213         case OP_OUTL: op = "outl", mask = REGCM_GPR32; break;
17214         default:
17215                 internal_error(state, ins, "not an out operation");
17216                 op = 0;
17217                 break;
17218         }
17219         lreg = check_reg(state, RHS(ins, 0), mask);
17220         if (!reg_is_reg(state, lreg, REG_EAX)) {
17221                 internal_error(state, ins, "src != %%eax");
17222         }
17223         if (is_const(RHS(ins, 1))) {
17224                 fprintf(fp, "\t%s %s,", 
17225                         op, reg(state, RHS(ins, 0), mask));
17226                 print_const_val(state, RHS(ins, 1), fp);
17227                 fprintf(fp, "\n");
17228         }
17229         else {
17230                 int addr_reg;
17231                 addr_reg = check_reg(state, RHS(ins, 1), REGCM_GPR16);
17232                 if (!reg_is_reg(state, addr_reg, REG_DX)) {
17233                         internal_error(state, ins, "dst != %%dx");
17234                 }
17235                 fprintf(fp, "\t%s %s, %s\n",
17236                         op, 
17237                         reg(state, RHS(ins, 0), mask),
17238                         reg(state, RHS(ins, 1), REGCM_GPR16));
17239         }
17240 }
17241
17242 static void print_op_move(struct compile_state *state,
17243         struct triple *ins, FILE *fp)
17244 {
17245         /* op_move is complex because there are many types
17246          * of registers we can move between.
17247          * Because OP_COPY will be introduced in arbitrary locations
17248          * OP_COPY must not affect flags.
17249          */
17250         int omit_copy = 1; /* Is it o.k. to omit a noop copy? */
17251         struct triple *dst, *src;
17252         if (ins->op == OP_COPY) {
17253                 src = RHS(ins, 0);
17254                 dst = ins;
17255         }
17256         else {
17257                 internal_error(state, ins, "unknown move operation");
17258                 src = dst = 0;
17259         }
17260         if (!is_const(src)) {
17261                 int src_reg, dst_reg;
17262                 int src_regcm, dst_regcm;
17263                 src_reg   = ID_REG(src->id);
17264                 dst_reg   = ID_REG(dst->id);
17265                 src_regcm = arch_reg_regcm(state, src_reg);
17266                 dst_regcm = arch_reg_regcm(state, dst_reg);
17267                 /* If the class is the same just move the register */
17268                 if (src_regcm & dst_regcm & 
17269                         (REGCM_GPR8_LO | REGCM_GPR16 | REGCM_GPR32)) {
17270                         if ((src_reg != dst_reg) || !omit_copy) {
17271                                 fprintf(fp, "\tmov %s, %s\n",
17272                                         reg(state, src, src_regcm),
17273                                         reg(state, dst, dst_regcm));
17274                         }
17275                 }
17276                 /* Move 32bit to 16bit */
17277                 else if ((src_regcm & REGCM_GPR32) &&
17278                         (dst_regcm & REGCM_GPR16)) {
17279                         src_reg = (src_reg - REGC_GPR32_FIRST) + REGC_GPR16_FIRST;
17280                         if ((src_reg != dst_reg) || !omit_copy) {
17281                                 fprintf(fp, "\tmovw %s, %s\n",
17282                                         arch_reg_str(src_reg), 
17283                                         arch_reg_str(dst_reg));
17284                         }
17285                 }
17286                 /* Move from 32bit gprs to 16bit gprs */
17287                 else if ((src_regcm & REGCM_GPR32) &&
17288                         (dst_regcm & REGCM_GPR16)) {
17289                         dst_reg = (dst_reg - REGC_GPR16_FIRST) + REGC_GPR32_FIRST;
17290                         if ((src_reg != dst_reg) || !omit_copy) {
17291                                 fprintf(fp, "\tmov %s, %s\n",
17292                                         arch_reg_str(src_reg),
17293                                         arch_reg_str(dst_reg));
17294                         }
17295                 }
17296                 /* Move 32bit to 8bit */
17297                 else if ((src_regcm & REGCM_GPR32_8) &&
17298                         (dst_regcm & REGCM_GPR8_LO))
17299                 {
17300                         src_reg = (src_reg - REGC_GPR32_8_FIRST) + REGC_GPR8_FIRST;
17301                         if ((src_reg != dst_reg) || !omit_copy) {
17302                                 fprintf(fp, "\tmovb %s, %s\n",
17303                                         arch_reg_str(src_reg),
17304                                         arch_reg_str(dst_reg));
17305                         }
17306                 }
17307                 /* Move 16bit to 8bit */
17308                 else if ((src_regcm & REGCM_GPR16_8) &&
17309                         (dst_regcm & REGCM_GPR8_LO))
17310                 {
17311                         src_reg = (src_reg - REGC_GPR16_8_FIRST) + REGC_GPR8_FIRST;
17312                         if ((src_reg != dst_reg) || !omit_copy) {
17313                                 fprintf(fp, "\tmovb %s, %s\n",
17314                                         arch_reg_str(src_reg),
17315                                         arch_reg_str(dst_reg));
17316                         }
17317                 }
17318                 /* Move 8/16bit to 16/32bit */
17319                 else if ((src_regcm & (REGCM_GPR8_LO | REGCM_GPR16)) && 
17320                         (dst_regcm & (REGCM_GPR16 | REGCM_GPR32))) {
17321                         const char *op;
17322                         op = is_signed(src->type)? "movsx": "movzx";
17323                         fprintf(fp, "\t%s %s, %s\n",
17324                                 op,
17325                                 reg(state, src, src_regcm),
17326                                 reg(state, dst, dst_regcm));
17327                 }
17328                 /* Move between sse registers */
17329                 else if ((src_regcm & dst_regcm & REGCM_XMM)) {
17330                         if ((src_reg != dst_reg) || !omit_copy) {
17331                                 fprintf(fp, "\tmovdqa %s, %s\n",
17332                                         reg(state, src, src_regcm),
17333                                         reg(state, dst, dst_regcm));
17334                         }
17335                 }
17336                 /* Move between mmx registers */
17337                 else if ((src_regcm & dst_regcm & REGCM_MMX)) {
17338                         if ((src_reg != dst_reg) || !omit_copy) {
17339                                 fprintf(fp, "\tmovq %s, %s\n",
17340                                         reg(state, src, src_regcm),
17341                                         reg(state, dst, dst_regcm));
17342                         }
17343                 }
17344                 /* Move from sse to mmx registers */
17345                 else if ((src_regcm & REGCM_XMM) && (dst_regcm & REGCM_MMX)) {
17346                         fprintf(fp, "\tmovdq2q %s, %s\n",
17347                                 reg(state, src, src_regcm),
17348                                 reg(state, dst, dst_regcm));
17349                 }
17350                 /* Move from mmx to sse registers */
17351                 else if ((src_regcm & REGCM_MMX) && (dst_regcm & REGCM_XMM)) {
17352                         fprintf(fp, "\tmovq2dq %s, %s\n",
17353                                 reg(state, src, src_regcm),
17354                                 reg(state, dst, dst_regcm));
17355                 }
17356                 /* Move between 32bit gprs & mmx/sse registers */
17357                 else if ((src_regcm & (REGCM_GPR32 | REGCM_MMX | REGCM_XMM)) &&
17358                         (dst_regcm & (REGCM_GPR32 | REGCM_MMX | REGCM_XMM))) {
17359                         fprintf(fp, "\tmovd %s, %s\n",
17360                                 reg(state, src, src_regcm),
17361                                 reg(state, dst, dst_regcm));
17362                 }
17363                 /* Move from 16bit gprs &  mmx/sse registers */
17364                 else if ((src_regcm & REGCM_GPR16) &&
17365                         (dst_regcm & (REGCM_MMX | REGCM_XMM))) {
17366                         const char *op;
17367                         int mid_reg;
17368                         op = is_signed(src->type)? "movsx":"movzx";
17369                         mid_reg = (src_reg - REGC_GPR16_FIRST) + REGC_GPR32_FIRST;
17370                         fprintf(fp, "\t%s %s, %s\n\tmovd %s, %s\n",
17371                                 op,
17372                                 arch_reg_str(src_reg),
17373                                 arch_reg_str(mid_reg),
17374                                 arch_reg_str(mid_reg),
17375                                 arch_reg_str(dst_reg));
17376                 }
17377                 /* Move from mmx/sse registers to 16bit gprs */
17378                 else if ((src_regcm & (REGCM_MMX | REGCM_XMM)) &&
17379                         (dst_regcm & REGCM_GPR16)) {
17380                         dst_reg = (dst_reg - REGC_GPR16_FIRST) + REGC_GPR32_FIRST;
17381                         fprintf(fp, "\tmovd %s, %s\n",
17382                                 arch_reg_str(src_reg),
17383                                 arch_reg_str(dst_reg));
17384                 }
17385                 /* Move from gpr to 64bit dividend */
17386                 else if ((src_regcm & (REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO))  &&
17387                         (dst_regcm & REGCM_DIVIDEND64)) {
17388                         const char *extend;
17389                         extend = is_signed(src->type)? "cltd":"movl $0, %edx";
17390                         fprintf(fp, "\tmov %s, %%eax\n\t%s\n",
17391                                 arch_reg_str(src_reg), 
17392                                 extend);
17393                 }
17394                 /* Move from 64bit gpr to gpr */
17395                 else if ((src_regcm & REGCM_DIVIDEND64) &&
17396                         (dst_regcm & (REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO))) {
17397                         if (dst_regcm & REGCM_GPR32) {
17398                                 src_reg = REG_EAX;
17399                         } 
17400                         else if (dst_regcm & REGCM_GPR16) {
17401                                 src_reg = REG_AX;
17402                         }
17403                         else if (dst_regcm & REGCM_GPR8_LO) {
17404                                 src_reg = REG_AL;
17405                         }
17406                         fprintf(fp, "\tmov %s, %s\n",
17407                                 arch_reg_str(src_reg),
17408                                 arch_reg_str(dst_reg));
17409                 }
17410                 /* Move from mmx/sse registers to 64bit gpr */
17411                 else if ((src_regcm & (REGCM_MMX | REGCM_XMM)) &&
17412                         (dst_regcm & REGCM_DIVIDEND64)) {
17413                         const char *extend;
17414                         extend = is_signed(src->type)? "cltd": "movl $0, %edx";
17415                         fprintf(fp, "\tmovd %s, %%eax\n\t%s\n",
17416                                 arch_reg_str(src_reg),
17417                                 extend);
17418                 }
17419                 /* Move from 64bit gpr to mmx/sse register */
17420                 else if ((src_regcm & REGCM_DIVIDEND64) &&
17421                         (dst_regcm & (REGCM_XMM | REGCM_MMX))) {
17422                         fprintf(fp, "\tmovd %%eax, %s\n",
17423                                 arch_reg_str(dst_reg));
17424                 }
17425 #if X86_4_8BIT_GPRS
17426                 /* Move from 8bit gprs to  mmx/sse registers */
17427                 else if ((src_regcm & REGCM_GPR8_LO) && (src_reg <= REG_DL) &&
17428                         (dst_regcm & (REGCM_MMX | REGCM_XMM))) {
17429                         const char *op;
17430                         int mid_reg;
17431                         op = is_signed(src->type)? "movsx":"movzx";
17432                         mid_reg = (src_reg - REGC_GPR8_FIRST) + REGC_GPR32_FIRST;
17433                         fprintf(fp, "\t%s %s, %s\n\tmovd %s, %s\n",
17434                                 op,
17435                                 reg(state, src, src_regcm),
17436                                 arch_reg_str(mid_reg),
17437                                 arch_reg_str(mid_reg),
17438                                 reg(state, dst, dst_regcm));
17439                 }
17440                 /* Move from mmx/sse registers and 8bit gprs */
17441                 else if ((src_regcm & (REGCM_MMX | REGCM_XMM)) &&
17442                         (dst_regcm & REGCM_GPR8_LO) && (dst_reg <= REG_DL)) {
17443                         int mid_reg;
17444                         mid_reg = (dst_reg - REGC_GPR8_FIRST) + REGC_GPR32_FIRST;
17445                         fprintf(fp, "\tmovd %s, %s\n",
17446                                 reg(state, src, src_regcm),
17447                                 arch_reg_str(mid_reg));
17448                 }
17449                 /* Move from 32bit gprs to 8bit gprs */
17450                 else if ((src_regcm & REGCM_GPR32) &&
17451                         (dst_regcm & REGCM_GPR8_LO)) {
17452                         dst_reg = (dst_reg - REGC_GPR8_FIRST) + REGC_GPR32_FIRST;
17453                         if ((src_reg != dst_reg) || !omit_copy) {
17454                                 fprintf(fp, "\tmov %s, %s\n",
17455                                         arch_reg_str(src_reg),
17456                                         arch_reg_str(dst_reg));
17457                         }
17458                 }
17459                 /* Move from 16bit gprs to 8bit gprs */
17460                 else if ((src_regcm & REGCM_GPR16) &&
17461                         (dst_regcm & REGCM_GPR8_LO)) {
17462                         dst_reg = (dst_reg - REGC_GPR8_FIRST) + REGC_GPR16_FIRST;
17463                         if ((src_reg != dst_reg) || !omit_copy) {
17464                                 fprintf(fp, "\tmov %s, %s\n",
17465                                         arch_reg_str(src_reg),
17466                                         arch_reg_str(dst_reg));
17467                         }
17468                 }
17469 #endif /* X86_4_8BIT_GPRS */
17470                 else {
17471                         internal_error(state, ins, "unknown copy type");
17472                 }
17473         }
17474         else {
17475                 int dst_reg;
17476                 int dst_regcm;
17477                 dst_reg = ID_REG(dst->id);
17478                 dst_regcm = arch_reg_regcm(state, dst_reg);
17479                 if (dst_regcm & (REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO)) {
17480                         fprintf(fp, "\tmov ");
17481                         print_const_val(state, src, fp);
17482                         fprintf(fp, ", %s\n",
17483                                 reg(state, dst, REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO));
17484                 }
17485                 else if (dst_regcm & REGCM_DIVIDEND64) {
17486                         if (size_of(state, dst->type) > 4) {
17487                                 internal_error(state, ins, "64bit constant...");
17488                         }
17489                         fprintf(fp, "\tmov $0, %%edx\n");
17490                         fprintf(fp, "\tmov ");
17491                         print_const_val(state, src, fp);
17492                         fprintf(fp, ", %%eax\n");
17493                 }
17494                 else if (dst_regcm & REGCM_DIVIDEND32) {
17495                         if (size_of(state, dst->type) > 2) {
17496                                 internal_error(state, ins, "32bit constant...");
17497                         }
17498                         fprintf(fp, "\tmov $0, %%dx\n");
17499                         fprintf(fp, "\tmov ");
17500                         print_const_val(state, src, fp);
17501                         fprintf(fp, ", %%ax");
17502                 }
17503                 else if (dst_regcm & (REGCM_XMM | REGCM_MMX)) {
17504                         long ref;
17505                         ref = get_const_pool_ref(state, src, fp);
17506                         fprintf(fp, "\tmovq L%s%lu, %s\n",
17507                                 state->label_prefix, ref,
17508                                 reg(state, dst, (REGCM_XMM | REGCM_MMX)));
17509                 }
17510                 else {
17511                         internal_error(state, ins, "unknown copy immediate type");
17512                 }
17513         }
17514 }
17515
17516 static void print_op_load(struct compile_state *state,
17517         struct triple *ins, FILE *fp)
17518 {
17519         struct triple *dst, *src;
17520         dst = ins;
17521         src = RHS(ins, 0);
17522         if (is_const(src) || is_const(dst)) {
17523                 internal_error(state, ins, "unknown load operation");
17524         }
17525         fprintf(fp, "\tmov (%s), %s\n",
17526                 reg(state, src, REGCM_GPR32),
17527                 reg(state, dst, REGCM_GPR8_LO | REGCM_GPR16 | REGCM_GPR32));
17528 }
17529
17530
17531 static void print_op_store(struct compile_state *state,
17532         struct triple *ins, FILE *fp)
17533 {
17534         struct triple *dst, *src;
17535         dst = RHS(ins, 0);
17536         src = RHS(ins, 1);
17537         if (is_const(src) && (src->op == OP_INTCONST)) {
17538                 long_t value;
17539                 value = (long_t)(src->u.cval);
17540                 fprintf(fp, "\tmov%s $%ld, (%s)\n",
17541                         type_suffix(state, src->type),
17542                         value,
17543                         reg(state, dst, REGCM_GPR32));
17544         }
17545         else if (is_const(dst) && (dst->op == OP_INTCONST)) {
17546                 fprintf(fp, "\tmov%s %s, 0x%08lx\n",
17547                         type_suffix(state, src->type),
17548                         reg(state, src, REGCM_GPR8_LO | REGCM_GPR16 | REGCM_GPR32),
17549                         dst->u.cval);
17550         }
17551         else {
17552                 if (is_const(src) || is_const(dst)) {
17553                         internal_error(state, ins, "unknown store operation");
17554                 }
17555                 fprintf(fp, "\tmov%s %s, (%s)\n",
17556                         type_suffix(state, src->type),
17557                         reg(state, src, REGCM_GPR8_LO | REGCM_GPR16 | REGCM_GPR32),
17558                         reg(state, dst, REGCM_GPR32));
17559         }
17560         
17561         
17562 }
17563
17564 static void print_op_smul(struct compile_state *state,
17565         struct triple *ins, FILE *fp)
17566 {
17567         if (!is_const(RHS(ins, 1))) {
17568                 fprintf(fp, "\timul %s, %s\n",
17569                         reg(state, RHS(ins, 1), REGCM_GPR32),
17570                         reg(state, RHS(ins, 0), REGCM_GPR32));
17571         }
17572         else {
17573                 fprintf(fp, "\timul ");
17574                 print_const_val(state, RHS(ins, 1), fp);
17575                 fprintf(fp, ", %s\n", reg(state, RHS(ins, 0), REGCM_GPR32));
17576         }
17577 }
17578
17579 static void print_op_cmp(struct compile_state *state,
17580         struct triple *ins, FILE *fp)
17581 {
17582         unsigned mask;
17583         int dreg;
17584         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO;
17585         dreg = check_reg(state, ins, REGCM_FLAGS);
17586         if (!reg_is_reg(state, dreg, REG_EFLAGS)) {
17587                 internal_error(state, ins, "bad dest register for cmp");
17588         }
17589         if (is_const(RHS(ins, 1))) {
17590                 fprintf(fp, "\tcmp ");
17591                 print_const_val(state, RHS(ins, 1), fp);
17592                 fprintf(fp, ", %s\n", reg(state, RHS(ins, 0), mask));
17593         }
17594         else {
17595                 unsigned lmask, rmask;
17596                 int lreg, rreg;
17597                 lreg = check_reg(state, RHS(ins, 0), mask);
17598                 rreg = check_reg(state, RHS(ins, 1), mask);
17599                 lmask = arch_reg_regcm(state, lreg);
17600                 rmask = arch_reg_regcm(state, rreg);
17601                 mask = lmask & rmask;
17602                 fprintf(fp, "\tcmp %s, %s\n",
17603                         reg(state, RHS(ins, 1), mask),
17604                         reg(state, RHS(ins, 0), mask));
17605         }
17606 }
17607
17608 static void print_op_test(struct compile_state *state,
17609         struct triple *ins, FILE *fp)
17610 {
17611         unsigned mask;
17612         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO;
17613         fprintf(fp, "\ttest %s, %s\n",
17614                 reg(state, RHS(ins, 0), mask),
17615                 reg(state, RHS(ins, 0), mask));
17616 }
17617
17618 static void print_op_branch(struct compile_state *state,
17619         struct triple *branch, FILE *fp)
17620 {
17621         const char *bop = "j";
17622         if (branch->op == OP_JMP) {
17623                 if (TRIPLE_RHS(branch->sizes) != 0) {
17624                         internal_error(state, branch, "jmp with condition?");
17625                 }
17626                 bop = "jmp";
17627         }
17628         else {
17629                 struct triple *ptr;
17630                 if (TRIPLE_RHS(branch->sizes) != 1) {
17631                         internal_error(state, branch, "jmpcc without condition?");
17632                 }
17633                 check_reg(state, RHS(branch, 0), REGCM_FLAGS);
17634                 if ((RHS(branch, 0)->op != OP_CMP) &&
17635                         (RHS(branch, 0)->op != OP_TEST)) {
17636                         internal_error(state, branch, "bad branch test");
17637                 }
17638 #warning "FIXME I have observed instructions between the test and branch instructions"
17639                 ptr = RHS(branch, 0);
17640                 for(ptr = RHS(branch, 0)->next; ptr != branch; ptr = ptr->next) {
17641                         if (ptr->op != OP_COPY) {
17642                                 internal_error(state, branch, "branch does not follow test");
17643                         }
17644                 }
17645                 switch(branch->op) {
17646                 case OP_JMP_EQ:       bop = "jz";  break;
17647                 case OP_JMP_NOTEQ:    bop = "jnz"; break;
17648                 case OP_JMP_SLESS:    bop = "jl";  break;
17649                 case OP_JMP_ULESS:    bop = "jb";  break;
17650                 case OP_JMP_SMORE:    bop = "jg";  break;
17651                 case OP_JMP_UMORE:    bop = "ja";  break;
17652                 case OP_JMP_SLESSEQ:  bop = "jle"; break;
17653                 case OP_JMP_ULESSEQ:  bop = "jbe"; break;
17654                 case OP_JMP_SMOREEQ:  bop = "jge"; break;
17655                 case OP_JMP_UMOREEQ:  bop = "jae"; break;
17656                 default:
17657                         internal_error(state, branch, "Invalid branch op");
17658                         break;
17659                 }
17660                 
17661         }
17662         fprintf(fp, "\t%s L%s%lu\n",
17663                 bop, 
17664                 state->label_prefix,
17665                 TARG(branch, 0)->u.cval);
17666 }
17667
17668 static void print_op_set(struct compile_state *state,
17669         struct triple *set, FILE *fp)
17670 {
17671         const char *sop = "set";
17672         if (TRIPLE_RHS(set->sizes) != 1) {
17673                 internal_error(state, set, "setcc without condition?");
17674         }
17675         check_reg(state, RHS(set, 0), REGCM_FLAGS);
17676         if ((RHS(set, 0)->op != OP_CMP) &&
17677                 (RHS(set, 0)->op != OP_TEST)) {
17678                 internal_error(state, set, "bad set test");
17679         }
17680         if (RHS(set, 0)->next != set) {
17681                 internal_error(state, set, "set does not follow test");
17682         }
17683         switch(set->op) {
17684         case OP_SET_EQ:       sop = "setz";  break;
17685         case OP_SET_NOTEQ:    sop = "setnz"; break;
17686         case OP_SET_SLESS:    sop = "setl";  break;
17687         case OP_SET_ULESS:    sop = "setb";  break;
17688         case OP_SET_SMORE:    sop = "setg";  break;
17689         case OP_SET_UMORE:    sop = "seta";  break;
17690         case OP_SET_SLESSEQ:  sop = "setle"; break;
17691         case OP_SET_ULESSEQ:  sop = "setbe"; break;
17692         case OP_SET_SMOREEQ:  sop = "setge"; break;
17693         case OP_SET_UMOREEQ:  sop = "setae"; break;
17694         default:
17695                 internal_error(state, set, "Invalid set op");
17696                 break;
17697         }
17698         fprintf(fp, "\t%s %s\n",
17699                 sop, reg(state, set, REGCM_GPR8_LO));
17700 }
17701
17702 static void print_op_bit_scan(struct compile_state *state, 
17703         struct triple *ins, FILE *fp) 
17704 {
17705         const char *op;
17706         switch(ins->op) {
17707         case OP_BSF: op = "bsf"; break;
17708         case OP_BSR: op = "bsr"; break;
17709         default: 
17710                 internal_error(state, ins, "unknown bit scan");
17711                 op = 0;
17712                 break;
17713         }
17714         fprintf(fp, 
17715                 "\t%s %s, %s\n"
17716                 "\tjnz 1f\n"
17717                 "\tmovl $-1, %s\n"
17718                 "1:\n",
17719                 op,
17720                 reg(state, RHS(ins, 0), REGCM_GPR32),
17721                 reg(state, ins, REGCM_GPR32),
17722                 reg(state, ins, REGCM_GPR32));
17723 }
17724
17725
17726 static void print_sdecl(struct compile_state *state,
17727         struct triple *ins, FILE *fp)
17728 {
17729         fprintf(fp, ".section \"" DATA_SECTION "\"\n");
17730         fprintf(fp, ".balign %d\n", align_of(state, ins->type));
17731         fprintf(fp, "L%s%lu:\n", state->label_prefix, ins->u.cval);
17732         print_const(state, MISC(ins, 0), fp);
17733         fprintf(fp, ".section \"" TEXT_SECTION "\"\n");
17734                 
17735 }
17736
17737 static void print_instruction(struct compile_state *state,
17738         struct triple *ins, FILE *fp)
17739 {
17740         /* Assumption: after I have exted the register allocator
17741          * everything is in a valid register. 
17742          */
17743         switch(ins->op) {
17744         case OP_ASM:
17745                 print_op_asm(state, ins, fp);
17746                 break;
17747         case OP_ADD:    print_binary_op(state, "add", ins, fp); break;
17748         case OP_SUB:    print_binary_op(state, "sub", ins, fp); break;
17749         case OP_AND:    print_binary_op(state, "and", ins, fp); break;
17750         case OP_XOR:    print_binary_op(state, "xor", ins, fp); break;
17751         case OP_OR:     print_binary_op(state, "or",  ins, fp); break;
17752         case OP_SL:     print_op_shift(state, "shl", ins, fp); break;
17753         case OP_USR:    print_op_shift(state, "shr", ins, fp); break;
17754         case OP_SSR:    print_op_shift(state, "sar", ins, fp); break;
17755         case OP_POS:    break;
17756         case OP_NEG:    print_unary_op(state, "neg", ins, fp); break;
17757         case OP_INVERT: print_unary_op(state, "not", ins, fp); break;
17758         case OP_INTCONST:
17759         case OP_ADDRCONST:
17760         case OP_BLOBCONST:
17761                 /* Don't generate anything here for constants */
17762         case OP_PHI:
17763                 /* Don't generate anything for variable declarations. */
17764                 break;
17765         case OP_SDECL:
17766                 print_sdecl(state, ins, fp);
17767                 break;
17768         case OP_COPY:   
17769                 print_op_move(state, ins, fp);
17770                 break;
17771         case OP_LOAD:
17772                 print_op_load(state, ins, fp);
17773                 break;
17774         case OP_STORE:
17775                 print_op_store(state, ins, fp);
17776                 break;
17777         case OP_SMUL:
17778                 print_op_smul(state, ins, fp);
17779                 break;
17780         case OP_CMP:    print_op_cmp(state, ins, fp); break;
17781         case OP_TEST:   print_op_test(state, ins, fp); break;
17782         case OP_JMP:
17783         case OP_JMP_EQ:      case OP_JMP_NOTEQ:
17784         case OP_JMP_SLESS:   case OP_JMP_ULESS:
17785         case OP_JMP_SMORE:   case OP_JMP_UMORE:
17786         case OP_JMP_SLESSEQ: case OP_JMP_ULESSEQ:
17787         case OP_JMP_SMOREEQ: case OP_JMP_UMOREEQ:
17788                 print_op_branch(state, ins, fp);
17789                 break;
17790         case OP_SET_EQ:      case OP_SET_NOTEQ:
17791         case OP_SET_SLESS:   case OP_SET_ULESS:
17792         case OP_SET_SMORE:   case OP_SET_UMORE:
17793         case OP_SET_SLESSEQ: case OP_SET_ULESSEQ:
17794         case OP_SET_SMOREEQ: case OP_SET_UMOREEQ:
17795                 print_op_set(state, ins, fp);
17796                 break;
17797         case OP_INB:  case OP_INW:  case OP_INL:
17798                 print_op_in(state, ins, fp); 
17799                 break;
17800         case OP_OUTB: case OP_OUTW: case OP_OUTL:
17801                 print_op_out(state, ins, fp); 
17802                 break;
17803         case OP_BSF:
17804         case OP_BSR:
17805                 print_op_bit_scan(state, ins, fp);
17806                 break;
17807         case OP_RDMSR:
17808                 after_lhs(state, ins);
17809                 fprintf(fp, "\trdmsr\n");
17810                 break;
17811         case OP_WRMSR:
17812                 fprintf(fp, "\twrmsr\n");
17813                 break;
17814         case OP_HLT:
17815                 fprintf(fp, "\thlt\n");
17816                 break;
17817         case OP_SDIVT:
17818                 fprintf(fp, "\tidiv %s\n", reg(state, RHS(ins, 1), REGCM_GPR32));
17819                 break;
17820         case OP_UDIVT:
17821                 fprintf(fp, "\tdiv %s\n", reg(state, RHS(ins, 1), REGCM_GPR32));
17822                 break;
17823         case OP_UMUL:
17824                 fprintf(fp, "\tmul %s\n", reg(state, RHS(ins, 1), REGCM_GPR32));
17825                 break;
17826         case OP_LABEL:
17827                 if (!ins->use) {
17828                         return;
17829                 }
17830                 fprintf(fp, "L%s%lu:\n", state->label_prefix, ins->u.cval);
17831                 break;
17832                 /* Ignore OP_PIECE */
17833         case OP_PIECE:
17834                 break;
17835                 /* Operations that should never get here */
17836         case OP_SDIV: case OP_UDIV:
17837         case OP_SMOD: case OP_UMOD:
17838         case OP_LTRUE:   case OP_LFALSE:  case OP_EQ:      case OP_NOTEQ:
17839         case OP_SLESS:   case OP_ULESS:   case OP_SMORE:   case OP_UMORE:
17840         case OP_SLESSEQ: case OP_ULESSEQ: case OP_SMOREEQ: case OP_UMOREEQ:
17841         default:
17842                 internal_error(state, ins, "unknown op: %d %s",
17843                         ins->op, tops(ins->op));
17844                 break;
17845         }
17846 }
17847
17848 static void print_instructions(struct compile_state *state)
17849 {
17850         struct triple *first, *ins;
17851         int print_location;
17852         struct occurance *last_occurance;
17853         FILE *fp;
17854         int max_inline_depth;
17855         max_inline_depth = 0;
17856         print_location = 1;
17857         last_occurance = 0;
17858         fp = state->output;
17859         fprintf(fp, ".section \"" TEXT_SECTION "\"\n");
17860         first = RHS(state->main_function, 0);
17861         ins = first;
17862         do {
17863                 if (print_location && 
17864                         last_occurance != ins->occurance) {
17865                         if (!ins->occurance->parent) {
17866                                 fprintf(fp, "\t/* %s,%s:%d.%d */\n",
17867                                         ins->occurance->function,
17868                                         ins->occurance->filename,
17869                                         ins->occurance->line,
17870                                         ins->occurance->col);
17871                         }
17872                         else {
17873                                 struct occurance *ptr;
17874                                 int inline_depth;
17875                                 fprintf(fp, "\t/*\n");
17876                                 inline_depth = 0;
17877                                 for(ptr = ins->occurance; ptr; ptr = ptr->parent) {
17878                                         inline_depth++;
17879                                         fprintf(fp, "\t * %s,%s:%d.%d\n",
17880                                                 ptr->function,
17881                                                 ptr->filename,
17882                                                 ptr->line,
17883                                                 ptr->col);
17884                                 }
17885                                 fprintf(fp, "\t */\n");
17886                                 if (inline_depth > max_inline_depth) {
17887                                         max_inline_depth = inline_depth;
17888                                 }
17889                         }
17890                         if (last_occurance) {
17891                                 put_occurance(last_occurance);
17892                         }
17893                         get_occurance(ins->occurance);
17894                         last_occurance = ins->occurance;
17895                 }
17896
17897                 print_instruction(state, ins, fp);
17898                 ins = ins->next;
17899         } while(ins != first);
17900         if (print_location) {
17901                 fprintf(fp, "/* max inline depth %d */\n",
17902                         max_inline_depth);
17903         }
17904 }
17905
17906 static void generate_code(struct compile_state *state)
17907 {
17908         generate_local_labels(state);
17909         print_instructions(state);
17910         
17911 }
17912
17913 static void print_tokens(struct compile_state *state)
17914 {
17915         struct token *tk;
17916         tk = &state->token[0];
17917         do {
17918 #if 1
17919                 token(state, 0);
17920 #else
17921                 next_token(state, 0);
17922 #endif
17923                 loc(stdout, state, 0);
17924                 printf("%s <- `%s'\n",
17925                         tokens[tk->tok],
17926                         tk->ident ? tk->ident->name :
17927                         tk->str_len ? tk->val.str : "");
17928                 
17929         } while(tk->tok != TOK_EOF);
17930 }
17931
17932 static void compile(const char *filename, const char *ofilename, 
17933         int cpu, int debug, int opt, const char *label_prefix)
17934 {
17935         int i;
17936         struct compile_state state;
17937         memset(&state, 0, sizeof(state));
17938         state.file = 0;
17939         for(i = 0; i < sizeof(state.token)/sizeof(state.token[0]); i++) {
17940                 memset(&state.token[i], 0, sizeof(state.token[i]));
17941                 state.token[i].tok = -1;
17942         }
17943         /* Remember the debug settings */
17944         state.cpu      = cpu;
17945         state.debug    = debug;
17946         state.optimize = opt;
17947         /* Remember the output filename */
17948         state.ofilename = ofilename;
17949         state.output    = fopen(state.ofilename, "w");
17950         if (!state.output) {
17951                 error(&state, 0, "Cannot open output file %s\n",
17952                         ofilename);
17953         }
17954         /* Remember the label prefix */
17955         state.label_prefix = label_prefix;
17956         /* Prep the preprocessor */
17957         state.if_depth = 0;
17958         state.if_value = 0;
17959         /* register the C keywords */
17960         register_keywords(&state);
17961         /* register the keywords the macro preprocessor knows */
17962         register_macro_keywords(&state);
17963         /* Memorize where some special keywords are. */
17964         state.i_continue = lookup(&state, "continue", 8);
17965         state.i_break    = lookup(&state, "break", 5);
17966         /* Enter the globl definition scope */
17967         start_scope(&state);
17968         register_builtins(&state);
17969         compile_file(&state, filename, 1);
17970 #if 0
17971         print_tokens(&state);
17972 #endif  
17973         decls(&state);
17974         /* Exit the global definition scope */
17975         end_scope(&state);
17976
17977         /* Now that basic compilation has happened 
17978          * optimize the intermediate code 
17979          */
17980         optimize(&state);
17981
17982         generate_code(&state);
17983         if (state.debug) {
17984                 fprintf(stderr, "done\n");
17985         }
17986 }
17987
17988 static void version(void)
17989 {
17990         printf("romcc " VERSION " released " RELEASE_DATE "\n");
17991 }
17992
17993 static void usage(void)
17994 {
17995         version();
17996         printf(
17997                 "Usage: romcc <source>.c\n"
17998                 "Compile a C source file without using ram\n"
17999         );
18000 }
18001
18002 static void arg_error(char *fmt, ...)
18003 {
18004         va_list args;
18005         va_start(args, fmt);
18006         vfprintf(stderr, fmt, args);
18007         va_end(args);
18008         usage();
18009         exit(1);
18010 }
18011
18012 int main(int argc, char **argv)
18013 {
18014         const char *filename;
18015         const char *ofilename;
18016         const char *label_prefix;
18017         int cpu;
18018         int last_argc;
18019         int debug;
18020         int optimize;
18021         cpu = CPU_DEFAULT;
18022         label_prefix = "";
18023         ofilename = "auto.inc";
18024         optimize = 0;
18025         debug = 0;
18026         last_argc = -1;
18027         while((argc > 1) && (argc != last_argc)) {
18028                 last_argc = argc;
18029                 if (strncmp(argv[1], "--debug=", 8) == 0) {
18030                         debug = atoi(argv[1] + 8);
18031                         argv++;
18032                         argc--;
18033                 }
18034                 else if (strncmp(argv[1], "--label-prefix=", 15) == 0) {
18035                         label_prefix= argv[1] + 15;
18036                         argv++;
18037                         argc--;
18038                 }
18039                 else if ((strcmp(argv[1],"-O") == 0) ||
18040                         (strcmp(argv[1], "-O1") == 0)) {
18041                         optimize = 1;
18042                         argv++;
18043                         argc--;
18044                 }
18045                 else if (strcmp(argv[1],"-O2") == 0) {
18046                         optimize = 2;
18047                         argv++;
18048                         argc--;
18049                 }
18050                 else if ((strcmp(argv[1], "-o") == 0) && (argc > 2)) {
18051                         ofilename = argv[2];
18052                         argv += 2;
18053                         argc -= 2;
18054                 }
18055                 else if (strncmp(argv[1], "-mcpu=", 6) == 0) {
18056                         cpu = arch_encode_cpu(argv[1] + 6);
18057                         if (cpu == BAD_CPU) {
18058                                 arg_error("Invalid cpu specified: %s\n",
18059                                         argv[1] + 6);
18060                         }
18061                         argv++;
18062                         argc--;
18063                 }
18064         }
18065         if (argc != 2) {
18066                 arg_error("Wrong argument count %d\n", argc);
18067         }
18068         filename = argv[1];
18069         compile(filename, ofilename, cpu, debug, optimize, label_prefix);
18070
18071         return 0;
18072 }