Make the kconfig-style build work in mingw:
[coreboot.git] / util / romcc / romcc.c
1 #undef VERSION_MAJOR
2 #undef VERSION_MINOR
3 #undef RELEASE_DATE
4 #undef VERSION
5 #define VERSION_MAJOR "0"
6 #define VERSION_MINOR "71"
7 #define RELEASE_DATE "03 April 2009"
8 #define VERSION VERSION_MAJOR "." VERSION_MINOR
9
10 #include <stdarg.h>
11 #include <errno.h>
12 #include <stdint.h>
13 #include <stdlib.h>
14 #include <stdio.h>
15 #include <sys/types.h>
16 #include <sys/stat.h>
17 #include <fcntl.h>
18 #include <unistd.h>
19 #include <stdio.h>
20 #include <string.h>
21 #include <limits.h>
22 #include <locale.h>
23 #include <time.h>
24
25 #define MAX_CWD_SIZE 4096
26 #define MAX_ALLOCATION_PASSES 100
27
28 /* NOTE: Before you even start thinking to touch anything 
29  * in this code, set DEBUG_ROMCC_WARNINGS to 1 to get an
30  * insight on the original author's thoughts. We introduced 
31  * this switch as romcc was about the only thing producing
32  * massive warnings in our code..
33  */
34 #define DEBUG_ROMCC_WARNINGS 0
35
36 #define DEBUG_CONSISTENCY 1
37 #define DEBUG_SDP_BLOCKS 0
38 #define DEBUG_TRIPLE_COLOR 0
39
40 #define DEBUG_DISPLAY_USES 1
41 #define DEBUG_DISPLAY_TYPES 1
42 #define DEBUG_REPLACE_CLOSURE_TYPE_HIRES 0
43 #define DEBUG_DECOMPOSE_PRINT_TUPLES 0
44 #define DEBUG_DECOMPOSE_HIRES  0
45 #define DEBUG_INITIALIZER 0
46 #define DEBUG_UPDATE_CLOSURE_TYPE 0
47 #define DEBUG_LOCAL_TRIPLE 0
48 #define DEBUG_BASIC_BLOCKS_VERBOSE 0
49 #define DEBUG_CPS_RENAME_VARIABLES_HIRES 0
50 #define DEBUG_SIMPLIFY_HIRES 0
51 #define DEBUG_SHRINKING 0
52 #define DEBUG_COALESCE_HITCHES 0
53 #define DEBUG_CODE_ELIMINATION 0
54
55 #define DEBUG_EXPLICIT_CLOSURES 0
56
57 #if DEBUG_ROMCC_WARNINGS
58 #warning "FIXME give clear error messages about unused variables"
59 #warning "FIXME properly handle multi dimensional arrays"
60 #warning "FIXME handle multiple register sizes"
61 #endif
62
63 /*  Control flow graph of a loop without goto.
64  * 
65  *        AAA
66  *   +---/
67  *  /
68  * / +--->CCC
69  * | |    / \
70  * | |  DDD EEE    break;
71  * | |    \    \
72  * | |    FFF   \
73  *  \|    / \    \
74  *   |\ GGG HHH   |   continue;
75  *   | \  \   |   |
76  *   |  \ III |  /
77  *   |   \ | /  / 
78  *   |    vvv  /  
79  *   +----BBB /   
80  *         | /
81  *         vv
82  *        JJJ
83  *
84  * 
85  *             AAA
86  *     +-----+  |  +----+
87  *     |      \ | /     |
88  *     |       BBB  +-+ |
89  *     |       / \ /  | |
90  *     |     CCC JJJ / /
91  *     |     / \    / / 
92  *     |   DDD EEE / /  
93  *     |    |   +-/ /
94  *     |   FFF     /    
95  *     |   / \    /     
96  *     | GGG HHH /      
97  *     |  |   +-/
98  *     | III
99  *     +--+ 
100  *
101  * 
102  * DFlocal(X) = { Y <- Succ(X) | idom(Y) != X }
103  * DFup(Z)    = { Y <- DF(Z) | idom(Y) != X }
104  *
105  *
106  * [] == DFlocal(X) U DF(X)
107  * () == DFup(X)
108  *
109  * Dominator graph of the same nodes.
110  *
111  *           AAA     AAA: [ ] ()
112  *          /   \
113  *        BBB    JJJ BBB: [ JJJ ] ( JJJ )  JJJ: [ ] ()
114  *         |
115  *        CCC        CCC: [ ] ( BBB, JJJ )
116  *        / \
117  *     DDD   EEE     DDD: [ ] ( BBB ) EEE: [ JJJ ] ()
118  *      |
119  *     FFF           FFF: [ ] ( BBB )
120  *     / \         
121  *  GGG   HHH        GGG: [ ] ( BBB ) HHH: [ BBB ] ()
122  *   |
123  *  III              III: [ BBB ] ()
124  *
125  *
126  * BBB and JJJ are definitely the dominance frontier.
127  * Where do I place phi functions and how do I make that decision.
128  *   
129  */
130 static void die(char *fmt, ...)
131 {
132         va_list args;
133
134         va_start(args, fmt);
135         vfprintf(stderr, fmt, args);
136         va_end(args);
137         fflush(stdout);
138         fflush(stderr);
139         exit(1);
140 }
141
142 static void *xmalloc(size_t size, const char *name)
143 {
144         void *buf;
145         buf = malloc(size);
146         if (!buf) {
147                 die("Cannot malloc %ld bytes to hold %s: %s\n",
148                         size + 0UL, name, strerror(errno));
149         }
150         return buf;
151 }
152
153 static void *xcmalloc(size_t size, const char *name)
154 {
155         void *buf;
156         buf = xmalloc(size, name);
157         memset(buf, 0, size);
158         return buf;
159 }
160
161 static void *xrealloc(void *ptr, size_t size, const char *name)
162 {
163         void *buf;
164         buf = realloc(ptr, size);
165         if (!buf) {
166                 die("Cannot realloc %ld bytes to hold %s: %s\n",
167                         size + 0UL, name, strerror(errno));
168         }
169         return buf;
170 }
171
172 static void xfree(const void *ptr)
173 {
174         free((void *)ptr);
175 }
176
177 static char *xstrdup(const char *str)
178 {
179         char *new;
180         int len;
181         len = strlen(str);
182         new = xmalloc(len + 1, "xstrdup string");
183         memcpy(new, str, len);
184         new[len] = '\0';
185         return new;
186 }
187
188 static void xchdir(const char *path)
189 {
190         if (chdir(path) != 0) {
191                 die("chdir to `%s' failed: %s\n",
192                         path, strerror(errno));
193         }
194 }
195
196 static int exists(const char *dirname, const char *filename)
197 {
198         char cwd[MAX_CWD_SIZE];
199         int does_exist;
200
201         if (getcwd(cwd, sizeof(cwd)) == 0) {
202                 die("cwd buffer to small");
203         }
204
205         does_exist = 1;
206         if (chdir(dirname) != 0) {
207                 does_exist = 0;
208         }
209         if (does_exist && (access(filename, O_RDONLY) < 0)) {
210                 if ((errno != EACCES) && (errno != EROFS)) {
211                         does_exist = 0;
212                 }
213         }
214         xchdir(cwd);
215         return does_exist;
216 }
217
218
219 static char *slurp_file(const char *dirname, const char *filename, off_t *r_size)
220 {
221         char cwd[MAX_CWD_SIZE];
222         char *buf;
223         off_t size, progress;
224         ssize_t result;
225         FILE* file;
226         
227         if (!filename) {
228                 *r_size = 0;
229                 return 0;
230         }
231         if (getcwd(cwd, sizeof(cwd)) == 0) {
232                 die("cwd buffer to small");
233         }
234         xchdir(dirname);
235         file = fopen(filename, "rb");
236         xchdir(cwd);
237         if (file == NULL) {
238                 die("Cannot open '%s' : %s\n",
239                         filename, strerror(errno));
240         }
241         fseek(file, 0, SEEK_END);
242         size = ftell(file);
243         fseek(file, 0, SEEK_SET);
244         *r_size = size +1;
245         buf = xmalloc(size +2, filename);
246         buf[size] = '\n'; /* Make certain the file is newline terminated */
247         buf[size+1] = '\0'; /* Null terminate the file for good measure */
248         progress = 0;
249         while(progress < size) {
250                 result = fread(buf + progress, 1, size - progress, file);
251                 if (result < 0) {
252                         if ((errno == EINTR) || (errno == EAGAIN))
253                                 continue;
254                         die("read on %s of %ld bytes failed: %s\n",
255                                 filename, (size - progress)+ 0UL, strerror(errno));
256                 }
257                 progress += result;
258         }
259         fclose(file);
260         return buf;
261 }
262
263 /* Types on the destination platform */
264 #if DEBUG_ROMCC_WARNINGS
265 #warning "FIXME this assumes 32bit x86 is the destination"
266 #endif
267 typedef int8_t   schar_t;
268 typedef uint8_t  uchar_t;
269 typedef int8_t   char_t;
270 typedef int16_t  short_t;
271 typedef uint16_t ushort_t;
272 typedef int32_t  int_t;
273 typedef uint32_t uint_t;
274 typedef int32_t  long_t;
275 #define ulong_t uint32_t
276
277 #define SCHAR_T_MIN (-128)
278 #define SCHAR_T_MAX 127
279 #define UCHAR_T_MAX 255
280 #define CHAR_T_MIN  SCHAR_T_MIN
281 #define CHAR_T_MAX  SCHAR_T_MAX
282 #define SHRT_T_MIN  (-32768)
283 #define SHRT_T_MAX  32767
284 #define USHRT_T_MAX 65535
285 #define INT_T_MIN   (-LONG_T_MAX - 1)
286 #define INT_T_MAX   2147483647
287 #define UINT_T_MAX  4294967295U
288 #define LONG_T_MIN  (-LONG_T_MAX - 1)
289 #define LONG_T_MAX  2147483647
290 #define ULONG_T_MAX 4294967295U
291
292 #define SIZEOF_I8    8
293 #define SIZEOF_I16   16
294 #define SIZEOF_I32   32
295 #define SIZEOF_I64   64
296
297 #define SIZEOF_CHAR    8
298 #define SIZEOF_SHORT   16
299 #define SIZEOF_INT     32
300 #define SIZEOF_LONG    (sizeof(long_t)*SIZEOF_CHAR)
301
302
303 #define ALIGNOF_CHAR    8
304 #define ALIGNOF_SHORT   16
305 #define ALIGNOF_INT     32
306 #define ALIGNOF_LONG    (sizeof(long_t)*SIZEOF_CHAR)
307
308 #define REG_SIZEOF_REG     32
309 #define REG_SIZEOF_CHAR    REG_SIZEOF_REG
310 #define REG_SIZEOF_SHORT   REG_SIZEOF_REG
311 #define REG_SIZEOF_INT     REG_SIZEOF_REG
312 #define REG_SIZEOF_LONG    REG_SIZEOF_REG
313
314 #define REG_ALIGNOF_REG     REG_SIZEOF_REG
315 #define REG_ALIGNOF_CHAR    REG_SIZEOF_REG
316 #define REG_ALIGNOF_SHORT   REG_SIZEOF_REG
317 #define REG_ALIGNOF_INT     REG_SIZEOF_REG
318 #define REG_ALIGNOF_LONG    REG_SIZEOF_REG
319
320 /* Additional definitions for clarity.
321  * I currently assume a long is the largest native
322  * machine word and that a pointer fits into it.
323  */
324 #define SIZEOF_WORD     SIZEOF_LONG
325 #define SIZEOF_POINTER  SIZEOF_LONG
326 #define ALIGNOF_WORD    ALIGNOF_LONG
327 #define ALIGNOF_POINTER ALIGNOF_LONG
328 #define REG_SIZEOF_POINTER  REG_SIZEOF_LONG
329 #define REG_ALIGNOF_POINTER REG_ALIGNOF_LONG
330
331 struct file_state {
332         struct file_state *prev;
333         const char *basename;
334         char *dirname;
335         const char *buf;
336         off_t size;
337         const char *pos;
338         int line;
339         const char *line_start;
340         int report_line;
341         const char *report_name;
342         const char *report_dir;
343         int macro      : 1;
344         int trigraphs  : 1;
345         int join_lines : 1;
346 };
347 struct hash_entry;
348 struct token {
349         int tok;
350         struct hash_entry *ident;
351         const char *pos;
352         int str_len;
353         union {
354                 ulong_t integer;
355                 const char *str;
356                 int notmacro;
357         } val;
358 };
359
360 /* I have two classes of types:
361  * Operational types.
362  * Logical types.  (The type the C standard says the operation is of)
363  *
364  * The operational types are:
365  * chars
366  * shorts
367  * ints
368  * longs
369  *
370  * floats
371  * doubles
372  * long doubles
373  *
374  * pointer
375  */
376
377
378 /* Machine model.
379  * No memory is useable by the compiler.
380  * There is no floating point support.
381  * All operations take place in general purpose registers.
382  * There is one type of general purpose register.
383  * Unsigned longs are stored in that general purpose register.
384  */
385
386 /* Operations on general purpose registers.
387  */
388
389 #define OP_SDIVT      0
390 #define OP_UDIVT      1
391 #define OP_SMUL       2
392 #define OP_UMUL       3
393 #define OP_SDIV       4
394 #define OP_UDIV       5
395 #define OP_SMOD       6
396 #define OP_UMOD       7
397 #define OP_ADD        8
398 #define OP_SUB        9
399 #define OP_SL        10
400 #define OP_USR       11
401 #define OP_SSR       12 
402 #define OP_AND       13 
403 #define OP_XOR       14
404 #define OP_OR        15
405 #define OP_POS       16 /* Dummy positive operator don't use it */
406 #define OP_NEG       17
407 #define OP_INVERT    18
408                      
409 #define OP_EQ        20
410 #define OP_NOTEQ     21
411 #define OP_SLESS     22
412 #define OP_ULESS     23
413 #define OP_SMORE     24
414 #define OP_UMORE     25
415 #define OP_SLESSEQ   26
416 #define OP_ULESSEQ   27
417 #define OP_SMOREEQ   28
418 #define OP_UMOREEQ   29
419                      
420 #define OP_LFALSE    30  /* Test if the expression is logically false */
421 #define OP_LTRUE     31  /* Test if the expression is logcially true */
422
423 #define OP_LOAD      32
424 #define OP_STORE     33
425 /* For OP_STORE ->type holds the type
426  * RHS(0) holds the destination address
427  * RHS(1) holds the value to store.
428  */
429
430 #define OP_UEXTRACT  34
431 /* OP_UEXTRACT extracts an unsigned bitfield from a pseudo register
432  * RHS(0) holds the psuedo register to extract from
433  * ->type holds the size of the bitfield.
434  * ->u.bitfield.size holds the size of the bitfield.
435  * ->u.bitfield.offset holds the offset to extract from
436  */
437 #define OP_SEXTRACT  35
438 /* OP_SEXTRACT extracts a signed bitfield from a pseudo register
439  * RHS(0) holds the psuedo register to extract from
440  * ->type holds the size of the bitfield.
441  * ->u.bitfield.size holds the size of the bitfield.
442  * ->u.bitfield.offset holds the offset to extract from
443  */
444 #define OP_DEPOSIT   36
445 /* OP_DEPOSIT replaces a bitfield with a new value.
446  * RHS(0) holds the value to replace a bitifield in.
447  * RHS(1) holds the replacement value
448  * ->u.bitfield.size holds the size of the bitfield.
449  * ->u.bitfield.offset holds the deposit into
450  */
451
452 #define OP_NOOP      37
453
454 #define OP_MIN_CONST 50
455 #define OP_MAX_CONST 58
456 #define IS_CONST_OP(X) (((X) >= OP_MIN_CONST) && ((X) <= OP_MAX_CONST))
457 #define OP_INTCONST  50
458 /* For OP_INTCONST ->type holds the type.
459  * ->u.cval holds the constant value.
460  */
461 #define OP_BLOBCONST 51
462 /* For OP_BLOBCONST ->type holds the layout and size
463  * information.  u.blob holds a pointer to the raw binary
464  * data for the constant initializer.
465  */
466 #define OP_ADDRCONST 52
467 /* For OP_ADDRCONST ->type holds the type.
468  * MISC(0) holds the reference to the static variable.
469  * ->u.cval holds an offset from that value.
470  */
471 #define OP_UNKNOWNVAL 59
472 /* For OP_UNKNOWNAL ->type holds the type.
473  * For some reason we don't know what value this type has.
474  * This allows for variables that have don't have values
475  * assigned yet, or variables whose value we simply do not know.
476  */
477
478 #define OP_WRITE     60 
479 /* OP_WRITE moves one pseudo register to another.
480  * MISC(0) holds the destination pseudo register, which must be an OP_DECL.
481  * RHS(0) holds the psuedo to move.
482  */
483
484 #define OP_READ      61
485 /* OP_READ reads the value of a variable and makes
486  * it available for the pseudo operation.
487  * Useful for things like def-use chains.
488  * RHS(0) holds points to the triple to read from.
489  */
490 #define OP_COPY      62
491 /* OP_COPY makes a copy of the pseudo register or constant in RHS(0).
492  */
493 #define OP_CONVERT   63
494 /* OP_CONVERT makes a copy of the pseudo register or constant in RHS(0).
495  * And then the type is converted appropriately.
496  */
497 #define OP_PIECE     64
498 /* OP_PIECE returns one piece of a instruction that returns a structure.
499  * MISC(0) is the instruction
500  * u.cval is the LHS piece of the instruction to return.
501  */
502 #define OP_ASM       65
503 /* OP_ASM holds a sequence of assembly instructions, the result
504  * of a C asm directive.
505  * RHS(x) holds input value x to the assembly sequence.
506  * LHS(x) holds the output value x from the assembly sequence.
507  * u.blob holds the string of assembly instructions.
508  */
509
510 #define OP_DEREF     66
511 /* OP_DEREF generates an lvalue from a pointer.
512  * RHS(0) holds the pointer value.
513  * OP_DEREF serves as a place holder to indicate all necessary
514  * checks have been done to indicate a value is an lvalue.
515  */
516 #define OP_DOT       67
517 /* OP_DOT references a submember of a structure lvalue.
518  * MISC(0) holds the lvalue.
519  * ->u.field holds the name of the field we want.
520  *
521  * Not seen after structures are flattened.
522  */
523 #define OP_INDEX     68
524 /* OP_INDEX references a submember of a tuple or array lvalue.
525  * MISC(0) holds the lvalue.
526  * ->u.cval holds the index into the lvalue.
527  *
528  * Not seen after structures are flattened.
529  */
530 #define OP_VAL       69
531 /* OP_VAL returns the value of a subexpression of the current expression.
532  * Useful for operators that have side effects.
533  * RHS(0) holds the expression.
534  * MISC(0) holds the subexpression of RHS(0) that is the
535  * value of the expression.
536  *
537  * Not seen outside of expressions.
538  */
539
540 #define OP_TUPLE     70
541 /* OP_TUPLE is an array of triples that are either variable
542  * or values for a structure or an array.  It is used as
543  * a place holder when flattening compound types.
544  * The value represented by an OP_TUPLE is held in N registers.
545  * LHS(0..N-1) refer to those registers.
546  * ->use is a list of statements that use the value.
547  * 
548  * Although OP_TUPLE always has register sized pieces they are not
549  * used until structures are flattened/decomposed into their register
550  * components. 
551  * ???? registers ????
552  */
553
554 #define OP_BITREF    71
555 /* OP_BITREF describes a bitfield as an lvalue.
556  * RHS(0) holds the register value.
557  * ->type holds the type of the bitfield.
558  * ->u.bitfield.size holds the size of the bitfield.
559  * ->u.bitfield.offset holds the offset of the bitfield in the register
560  */
561
562
563 #define OP_FCALL     72
564 /* OP_FCALL performs a procedure call. 
565  * MISC(0) holds a pointer to the OP_LIST of a function
566  * RHS(x) holds argument x of a function
567  * 
568  * Currently not seen outside of expressions.
569  */
570 #define OP_PROG      73
571 /* OP_PROG is an expression that holds a list of statements, or
572  * expressions.  The final expression is the value of the expression.
573  * RHS(0) holds the start of the list.
574  */
575
576 /* statements */
577 #define OP_LIST      80
578 /* OP_LIST Holds a list of statements that compose a function, and a result value.
579  * RHS(0) holds the list of statements.
580  * A list of all functions is maintained.
581  */
582
583 #define OP_BRANCH    81 /* an unconditional branch */
584 /* For branch instructions
585  * TARG(0) holds the branch target.
586  * ->next holds where to branch to if the branch is not taken.
587  * The branch target can only be a label
588  */
589
590 #define OP_CBRANCH   82 /* a conditional branch */
591 /* For conditional branch instructions
592  * RHS(0) holds the branch condition.
593  * TARG(0) holds the branch target.
594  * ->next holds where to branch to if the branch is not taken.
595  * The branch target can only be a label
596  */
597
598 #define OP_CALL      83 /* an uncontional branch that will return */
599 /* For call instructions
600  * MISC(0) holds the OP_RET that returns from the branch
601  * TARG(0) holds the branch target.
602  * ->next holds where to branch to if the branch is not taken.
603  * The branch target can only be a label
604  */
605
606 #define OP_RET       84 /* an uncontinonal branch through a variable back to an OP_CALL */
607 /* For call instructions
608  * RHS(0) holds the variable with the return address
609  * The branch target can only be a label
610  */
611
612 #define OP_LABEL     86
613 /* OP_LABEL is a triple that establishes an target for branches.
614  * ->use is the list of all branches that use this label.
615  */
616
617 #define OP_ADECL     87 
618 /* OP_ADECL is a triple that establishes an lvalue for assignments.
619  * A variable takes N registers to contain.
620  * LHS(0..N-1) refer to an OP_PIECE triple that represents
621  * the Xth register that the variable is stored in.
622  * ->use is a list of statements that use the variable.
623  * 
624  * Although OP_ADECL always has register sized pieces they are not
625  * used until structures are flattened/decomposed into their register
626  * components. 
627  */
628
629 #define OP_SDECL     88
630 /* OP_SDECL is a triple that establishes a variable of static
631  * storage duration.
632  * ->use is a list of statements that use the variable.
633  * MISC(0) holds the initializer expression.
634  */
635
636
637 #define OP_PHI       89
638 /* OP_PHI is a triple used in SSA form code.  
639  * It is used when multiple code paths merge and a variable needs
640  * a single assignment from any of those code paths.
641  * The operation is a cross between OP_DECL and OP_WRITE, which
642  * is what OP_PHI is generated from.
643  * 
644  * RHS(x) points to the value from code path x
645  * The number of RHS entries is the number of control paths into the block
646  * in which OP_PHI resides.  The elements of the array point to point
647  * to the variables OP_PHI is derived from.
648  *
649  * MISC(0) holds a pointer to the orginal OP_DECL node.
650  */
651
652 #if 0
653 /* continuation helpers
654  */
655 #define OP_CPS_BRANCH    90 /* an unconditional branch */
656 /* OP_CPS_BRANCH calls a continuation 
657  * RHS(x) holds argument x of the function
658  * TARG(0) holds OP_CPS_START target
659  */
660 #define OP_CPS_CBRANCH   91  /* a conditional branch */
661 /* OP_CPS_CBRANCH conditionally calls one of two continuations 
662  * RHS(0) holds the branch condition
663  * RHS(x + 1) holds argument x of the function
664  * TARG(0) holds the OP_CPS_START to jump to when true
665  * ->next holds the OP_CPS_START to jump to when false
666  */
667 #define OP_CPS_CALL      92  /* an uncontional branch that will return */
668 /* For OP_CPS_CALL instructions
669  * RHS(x) holds argument x of the function
670  * MISC(0) holds the OP_CPS_RET that returns from the branch
671  * TARG(0) holds the branch target.
672  * ->next holds where the OP_CPS_RET will return to.
673  */
674 #define OP_CPS_RET       93
675 /* OP_CPS_RET conditionally calls one of two continuations 
676  * RHS(0) holds the variable with the return function address
677  * RHS(x + 1) holds argument x of the function
678  * The branch target may be any OP_CPS_START
679  */
680 #define OP_CPS_END       94
681 /* OP_CPS_END is the triple at the end of the program.
682  * For most practical purposes it is a branch.
683  */
684 #define OP_CPS_START     95
685 /* OP_CPS_START is a triple at the start of a continuation
686  * The arguments variables takes N registers to contain.
687  * LHS(0..N-1) refer to an OP_PIECE triple that represents
688  * the Xth register that the arguments are stored in.
689  */
690 #endif
691
692 /* Architecture specific instructions */
693 #define OP_CMP         100
694 #define OP_TEST        101
695 #define OP_SET_EQ      102
696 #define OP_SET_NOTEQ   103
697 #define OP_SET_SLESS   104
698 #define OP_SET_ULESS   105
699 #define OP_SET_SMORE   106
700 #define OP_SET_UMORE   107
701 #define OP_SET_SLESSEQ 108
702 #define OP_SET_ULESSEQ 109
703 #define OP_SET_SMOREEQ 110
704 #define OP_SET_UMOREEQ 111
705
706 #define OP_JMP         112
707 #define OP_JMP_EQ      113
708 #define OP_JMP_NOTEQ   114
709 #define OP_JMP_SLESS   115
710 #define OP_JMP_ULESS   116
711 #define OP_JMP_SMORE   117
712 #define OP_JMP_UMORE   118
713 #define OP_JMP_SLESSEQ 119
714 #define OP_JMP_ULESSEQ 120
715 #define OP_JMP_SMOREEQ 121
716 #define OP_JMP_UMOREEQ 122
717
718 /* Builtin operators that it is just simpler to use the compiler for */
719 #define OP_INB         130
720 #define OP_INW         131
721 #define OP_INL         132
722 #define OP_OUTB        133
723 #define OP_OUTW        134
724 #define OP_OUTL        135
725 #define OP_BSF         136
726 #define OP_BSR         137
727 #define OP_RDMSR       138
728 #define OP_WRMSR       139
729 #define OP_HLT         140
730
731 struct op_info {
732         const char *name;
733         unsigned flags;
734 #define PURE       0x001 /* Triple has no side effects */
735 #define IMPURE     0x002 /* Triple has side effects */
736 #define PURE_BITS(FLAGS) ((FLAGS) & 0x3)
737 #define DEF        0x004 /* Triple is a variable definition */
738 #define BLOCK      0x008 /* Triple stores the current block */
739 #define STRUCTURAL 0x010 /* Triple does not generate a machine instruction */
740 #define BRANCH_BITS(FLAGS) ((FLAGS) & 0xe0 )
741 #define UBRANCH    0x020 /* Triple is an unconditional branch instruction */
742 #define CBRANCH    0x040 /* Triple is a conditional branch instruction */
743 #define RETBRANCH  0x060 /* Triple is a return instruction */
744 #define CALLBRANCH 0x080 /* Triple is a call instruction */
745 #define ENDBRANCH  0x0a0 /* Triple is an end instruction */
746 #define PART       0x100 /* Triple is really part of another triple */
747 #define BITFIELD   0x200 /* Triple manipulates a bitfield */
748         signed char lhs, rhs, misc, targ;
749 };
750
751 #define OP(LHS, RHS, MISC, TARG, FLAGS, NAME) { \
752         .name = (NAME), \
753         .flags = (FLAGS), \
754         .lhs = (LHS), \
755         .rhs = (RHS), \
756         .misc = (MISC), \
757         .targ = (TARG), \
758          }
759 static const struct op_info table_ops[] = {
760 [OP_SDIVT      ] = OP( 2,  2, 0, 0, PURE | BLOCK , "sdivt"),
761 [OP_UDIVT      ] = OP( 2,  2, 0, 0, PURE | BLOCK , "udivt"),
762 [OP_SMUL       ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "smul"),
763 [OP_UMUL       ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "umul"),
764 [OP_SDIV       ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "sdiv"),
765 [OP_UDIV       ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "udiv"),
766 [OP_SMOD       ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "smod"),
767 [OP_UMOD       ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "umod"),
768 [OP_ADD        ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "add"),
769 [OP_SUB        ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "sub"),
770 [OP_SL         ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "sl"),
771 [OP_USR        ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "usr"),
772 [OP_SSR        ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "ssr"),
773 [OP_AND        ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "and"),
774 [OP_XOR        ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "xor"),
775 [OP_OR         ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "or"),
776 [OP_POS        ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK , "pos"),
777 [OP_NEG        ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK , "neg"),
778 [OP_INVERT     ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK , "invert"),
779
780 [OP_EQ         ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "eq"),
781 [OP_NOTEQ      ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "noteq"),
782 [OP_SLESS      ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "sless"),
783 [OP_ULESS      ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "uless"),
784 [OP_SMORE      ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "smore"),
785 [OP_UMORE      ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "umore"),
786 [OP_SLESSEQ    ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "slesseq"),
787 [OP_ULESSEQ    ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "ulesseq"),
788 [OP_SMOREEQ    ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "smoreeq"),
789 [OP_UMOREEQ    ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "umoreeq"),
790 [OP_LFALSE     ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK , "lfalse"),
791 [OP_LTRUE      ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK , "ltrue"),
792
793 [OP_LOAD       ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "load"),
794 [OP_STORE      ] = OP( 0,  2, 0, 0, PURE | BLOCK , "store"),
795
796 [OP_UEXTRACT   ] = OP( 0,  1, 0, 0, PURE | DEF | BITFIELD, "uextract"),
797 [OP_SEXTRACT   ] = OP( 0,  1, 0, 0, PURE | DEF | BITFIELD, "sextract"),
798 [OP_DEPOSIT    ] = OP( 0,  2, 0, 0, PURE | DEF | BITFIELD, "deposit"),
799
800 [OP_NOOP       ] = OP( 0,  0, 0, 0, PURE | BLOCK | STRUCTURAL, "noop"),
801
802 [OP_INTCONST   ] = OP( 0,  0, 0, 0, PURE | DEF, "intconst"),
803 [OP_BLOBCONST  ] = OP( 0,  0, 0, 0, PURE , "blobconst"),
804 [OP_ADDRCONST  ] = OP( 0,  0, 1, 0, PURE | DEF, "addrconst"),
805 [OP_UNKNOWNVAL ] = OP( 0,  0, 0, 0, PURE | DEF, "unknown"),
806
807 #if DEBUG_ROMCC_WARNINGS
808 #warning "FIXME is it correct for OP_WRITE to be a def?  I currently use it as one..."
809 #endif
810 [OP_WRITE      ] = OP( 0,  1, 1, 0, PURE | DEF | BLOCK, "write"),
811 [OP_READ       ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "read"),
812 [OP_COPY       ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "copy"),
813 [OP_CONVERT    ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "convert"),
814 [OP_PIECE      ] = OP( 0,  0, 1, 0, PURE | DEF | STRUCTURAL | PART, "piece"),
815 [OP_ASM        ] = OP(-1, -1, 0, 0, PURE, "asm"),
816 [OP_DEREF      ] = OP( 0,  1, 0, 0, 0 | DEF | BLOCK, "deref"), 
817 [OP_DOT        ] = OP( 0,  0, 1, 0, PURE | DEF | PART, "dot"),
818 [OP_INDEX      ] = OP( 0,  0, 1, 0, PURE | DEF | PART, "index"),
819
820 [OP_VAL        ] = OP( 0,  1, 1, 0, 0 | DEF | BLOCK, "val"),
821 [OP_TUPLE      ] = OP(-1,  0, 0, 0, 0 | PURE | BLOCK | STRUCTURAL, "tuple"),
822 [OP_BITREF     ] = OP( 0,  1, 0, 0, 0 | DEF | PURE | STRUCTURAL | BITFIELD, "bitref"),
823 /* Call is special most it can stand in for anything so it depends on context */
824 [OP_FCALL      ] = OP( 0, -1, 1, 0, 0 | BLOCK | CALLBRANCH, "fcall"),
825 [OP_PROG       ] = OP( 0,  1, 0, 0, 0 | IMPURE | BLOCK | STRUCTURAL, "prog"),
826 /* The sizes of OP_FCALL depends upon context */
827
828 [OP_LIST       ] = OP( 0,  1, 1, 0, 0 | DEF | STRUCTURAL, "list"),
829 [OP_BRANCH     ] = OP( 0,  0, 0, 1, PURE | BLOCK | UBRANCH, "branch"),
830 [OP_CBRANCH    ] = OP( 0,  1, 0, 1, PURE | BLOCK | CBRANCH, "cbranch"),
831 [OP_CALL       ] = OP( 0,  0, 1, 1, PURE | BLOCK | CALLBRANCH, "call"),
832 [OP_RET        ] = OP( 0,  1, 0, 0, PURE | BLOCK | RETBRANCH, "ret"),
833 [OP_LABEL      ] = OP( 0,  0, 0, 0, PURE | BLOCK | STRUCTURAL, "label"),
834 [OP_ADECL      ] = OP( 0,  0, 0, 0, PURE | BLOCK | STRUCTURAL, "adecl"),
835 [OP_SDECL      ] = OP( 0,  0, 1, 0, PURE | BLOCK | STRUCTURAL, "sdecl"),
836 /* The number of RHS elements of OP_PHI depend upon context */
837 [OP_PHI        ] = OP( 0, -1, 1, 0, PURE | DEF | BLOCK, "phi"),
838
839 #if 0
840 [OP_CPS_BRANCH ] = OP( 0, -1, 0, 1, PURE | BLOCK | UBRANCH,     "cps_branch"),
841 [OP_CPS_CBRANCH] = OP( 0, -1, 0, 1, PURE | BLOCK | CBRANCH,     "cps_cbranch"),
842 [OP_CPS_CALL   ] = OP( 0, -1, 1, 1, PURE | BLOCK | CALLBRANCH,  "cps_call"),
843 [OP_CPS_RET    ] = OP( 0, -1, 0, 0, PURE | BLOCK | RETBRANCH,   "cps_ret"),
844 [OP_CPS_END    ] = OP( 0, -1, 0, 0, IMPURE | BLOCK | ENDBRANCH, "cps_end"),
845 [OP_CPS_START  ] = OP( -1, 0, 0, 0, PURE | BLOCK | STRUCTURAL,  "cps_start"),
846 #endif
847
848 [OP_CMP        ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK, "cmp"),
849 [OP_TEST       ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "test"),
850 [OP_SET_EQ     ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_eq"),
851 [OP_SET_NOTEQ  ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_noteq"),
852 [OP_SET_SLESS  ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_sless"),
853 [OP_SET_ULESS  ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_uless"),
854 [OP_SET_SMORE  ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_smore"),
855 [OP_SET_UMORE  ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_umore"),
856 [OP_SET_SLESSEQ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_slesseq"),
857 [OP_SET_ULESSEQ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_ulesseq"),
858 [OP_SET_SMOREEQ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_smoreq"),
859 [OP_SET_UMOREEQ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_umoreq"),
860 [OP_JMP        ] = OP( 0,  0, 0, 1, PURE | BLOCK | UBRANCH, "jmp"),
861 [OP_JMP_EQ     ] = OP( 0,  1, 0, 1, PURE | BLOCK | CBRANCH, "jmp_eq"),
862 [OP_JMP_NOTEQ  ] = OP( 0,  1, 0, 1, PURE | BLOCK | CBRANCH, "jmp_noteq"),
863 [OP_JMP_SLESS  ] = OP( 0,  1, 0, 1, PURE | BLOCK | CBRANCH, "jmp_sless"),
864 [OP_JMP_ULESS  ] = OP( 0,  1, 0, 1, PURE | BLOCK | CBRANCH, "jmp_uless"),
865 [OP_JMP_SMORE  ] = OP( 0,  1, 0, 1, PURE | BLOCK | CBRANCH, "jmp_smore"),
866 [OP_JMP_UMORE  ] = OP( 0,  1, 0, 1, PURE | BLOCK | CBRANCH, "jmp_umore"),
867 [OP_JMP_SLESSEQ] = OP( 0,  1, 0, 1, PURE | BLOCK | CBRANCH, "jmp_slesseq"),
868 [OP_JMP_ULESSEQ] = OP( 0,  1, 0, 1, PURE | BLOCK | CBRANCH, "jmp_ulesseq"),
869 [OP_JMP_SMOREEQ] = OP( 0,  1, 0, 1, PURE | BLOCK | CBRANCH, "jmp_smoreq"),
870 [OP_JMP_UMOREEQ] = OP( 0,  1, 0, 1, PURE | BLOCK | CBRANCH, "jmp_umoreq"),
871
872 [OP_INB        ] = OP( 0,  1, 0, 0, IMPURE | DEF | BLOCK, "__inb"),
873 [OP_INW        ] = OP( 0,  1, 0, 0, IMPURE | DEF | BLOCK, "__inw"),
874 [OP_INL        ] = OP( 0,  1, 0, 0, IMPURE | DEF | BLOCK, "__inl"),
875 [OP_OUTB       ] = OP( 0,  2, 0, 0, IMPURE| BLOCK, "__outb"),
876 [OP_OUTW       ] = OP( 0,  2, 0, 0, IMPURE| BLOCK, "__outw"),
877 [OP_OUTL       ] = OP( 0,  2, 0, 0, IMPURE| BLOCK, "__outl"),
878 [OP_BSF        ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "__bsf"),
879 [OP_BSR        ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "__bsr"),
880 [OP_RDMSR      ] = OP( 2,  1, 0, 0, IMPURE | BLOCK, "__rdmsr"),
881 [OP_WRMSR      ] = OP( 0,  3, 0, 0, IMPURE | BLOCK, "__wrmsr"),
882 [OP_HLT        ] = OP( 0,  0, 0, 0, IMPURE | BLOCK, "__hlt"),
883 };
884 #undef OP
885 #define OP_MAX      (sizeof(table_ops)/sizeof(table_ops[0]))
886
887 static const char *tops(int index) 
888 {
889         static const char unknown[] = "unknown op";
890         if (index < 0) {
891                 return unknown;
892         }
893         if (index > OP_MAX) {
894                 return unknown;
895         }
896         return table_ops[index].name;
897 }
898
899 struct asm_info;
900 struct triple;
901 struct block;
902 struct triple_set {
903         struct triple_set *next;
904         struct triple *member;
905 };
906
907 #define MAX_LHS  63
908 #define MAX_RHS  127
909 #define MAX_MISC 3
910 #define MAX_TARG 1
911
912 struct occurance {
913         int count;
914         const char *filename;
915         const char *function;
916         int line;
917         int col;
918         struct occurance *parent;
919 };
920 struct bitfield {
921         ulong_t size : 8;
922         ulong_t offset : 24;
923 };
924 struct triple {
925         struct triple *next, *prev;
926         struct triple_set *use;
927         struct type *type;
928         unsigned int op : 8;
929         unsigned int template_id : 7;
930         unsigned int lhs  : 6;
931         unsigned int rhs  : 7;
932         unsigned int misc : 2;
933         unsigned int targ : 1;
934 #define TRIPLE_SIZE(TRIPLE) \
935         ((TRIPLE)->lhs + (TRIPLE)->rhs + (TRIPLE)->misc + (TRIPLE)->targ)
936 #define TRIPLE_LHS_OFF(PTR)  (0)
937 #define TRIPLE_RHS_OFF(PTR)  (TRIPLE_LHS_OFF(PTR) + (PTR)->lhs)
938 #define TRIPLE_MISC_OFF(PTR) (TRIPLE_RHS_OFF(PTR) + (PTR)->rhs)
939 #define TRIPLE_TARG_OFF(PTR) (TRIPLE_MISC_OFF(PTR) + (PTR)->misc)
940 #define LHS(PTR,INDEX) ((PTR)->param[TRIPLE_LHS_OFF(PTR) + (INDEX)])
941 #define RHS(PTR,INDEX) ((PTR)->param[TRIPLE_RHS_OFF(PTR) + (INDEX)])
942 #define TARG(PTR,INDEX) ((PTR)->param[TRIPLE_TARG_OFF(PTR) + (INDEX)])
943 #define MISC(PTR,INDEX) ((PTR)->param[TRIPLE_MISC_OFF(PTR) + (INDEX)])
944         unsigned id; /* A scratch value and finally the register */
945 #define TRIPLE_FLAG_FLATTENED   (1 << 31)
946 #define TRIPLE_FLAG_PRE_SPLIT   (1 << 30)
947 #define TRIPLE_FLAG_POST_SPLIT  (1 << 29)
948 #define TRIPLE_FLAG_VOLATILE    (1 << 28)
949 #define TRIPLE_FLAG_INLINE      (1 << 27) /* ???? */
950 #define TRIPLE_FLAG_LOCAL       (1 << 26)
951
952 #define TRIPLE_FLAG_COPY TRIPLE_FLAG_VOLATILE
953         struct occurance *occurance;
954         union {
955                 ulong_t cval;
956                 struct bitfield bitfield;
957                 struct block  *block;
958                 void *blob;
959                 struct hash_entry *field;
960                 struct asm_info *ainfo;
961                 struct triple *func;
962                 struct symbol *symbol;
963         } u;
964         struct triple *param[2];
965 };
966
967 struct reg_info {
968         unsigned reg;
969         unsigned regcm;
970 };
971 struct ins_template {
972         struct reg_info lhs[MAX_LHS + 1], rhs[MAX_RHS + 1];
973 };
974
975 struct asm_info {
976         struct ins_template tmpl;
977         char *str;
978 };
979
980 struct block_set {
981         struct block_set *next;
982         struct block *member;
983 };
984 struct block {
985         struct block *work_next;
986         struct triple *first, *last;
987         int edge_count;
988         struct block_set *edges;
989         int users;
990         struct block_set *use;
991         struct block_set *idominates;
992         struct block_set *domfrontier;
993         struct block *idom;
994         struct block_set *ipdominates;
995         struct block_set *ipdomfrontier;
996         struct block *ipdom;
997         int vertex;
998         
999 };
1000
1001 struct symbol {
1002         struct symbol *next;
1003         struct hash_entry *ident;
1004         struct triple *def;
1005         struct type *type;
1006         int scope_depth;
1007 };
1008
1009 struct macro_arg {
1010         struct macro_arg *next;
1011         struct hash_entry *ident;
1012 };
1013 struct macro {
1014         struct hash_entry *ident;
1015         const char *buf;
1016         int buf_len;
1017         struct macro_arg *args;
1018         int argc;
1019 };
1020
1021 struct hash_entry {
1022         struct hash_entry *next;
1023         const char *name;
1024         int name_len;
1025         int tok;
1026         struct macro *sym_define;
1027         struct symbol *sym_label;
1028         struct symbol *sym_tag;
1029         struct symbol *sym_ident;
1030 };
1031
1032 #define HASH_TABLE_SIZE 2048
1033
1034 struct compiler_state {
1035         const char *label_prefix;
1036         const char *ofilename;
1037         unsigned long flags;
1038         unsigned long debug;
1039         unsigned long max_allocation_passes;
1040
1041         size_t include_path_count;
1042         const char **include_paths;
1043
1044         size_t define_count;
1045         const char **defines;
1046
1047         size_t undef_count;
1048         const char **undefs;
1049 };
1050 struct arch_state {
1051         unsigned long features;
1052 };
1053 struct basic_blocks {
1054         struct triple *func;
1055         struct triple *first;
1056         struct block *first_block, *last_block;
1057         int last_vertex;
1058 };
1059 #define MAX_PP_IF_DEPTH 63
1060 struct compile_state {
1061         struct compiler_state *compiler;
1062         struct arch_state *arch;
1063         FILE *output;
1064         FILE *errout;
1065         FILE *dbgout;
1066         struct file_state *file;
1067         struct occurance *last_occurance;
1068         const char *function;
1069         int    token_base;
1070         struct token token[6];
1071         struct hash_entry *hash_table[HASH_TABLE_SIZE];
1072         struct hash_entry *i_switch;
1073         struct hash_entry *i_case;
1074         struct hash_entry *i_continue;
1075         struct hash_entry *i_break;
1076         struct hash_entry *i_default;
1077         struct hash_entry *i_return;
1078         /* Additional hash entries for predefined macros */
1079         struct hash_entry *i_defined;
1080         struct hash_entry *i___VA_ARGS__;
1081         struct hash_entry *i___FILE__;
1082         struct hash_entry *i___LINE__;
1083         /* Additional hash entries for predefined identifiers */
1084         struct hash_entry *i___func__;
1085         /* Additional hash entries for attributes */
1086         struct hash_entry *i_noinline;
1087         struct hash_entry *i_always_inline;
1088         int scope_depth;
1089         unsigned char if_bytes[(MAX_PP_IF_DEPTH + CHAR_BIT -1)/CHAR_BIT];
1090         int if_depth;
1091         int eat_depth, eat_targ;
1092         struct file_state *macro_file;
1093         struct triple *functions;
1094         struct triple *main_function;
1095         struct triple *first;
1096         struct triple *global_pool;
1097         struct basic_blocks bb;
1098         int functions_joined;
1099 };
1100
1101 /* visibility global/local */
1102 /* static/auto duration */
1103 /* typedef, register, inline */
1104 #define STOR_SHIFT         0
1105 #define STOR_MASK     0x001f
1106 /* Visibility */
1107 #define STOR_GLOBAL   0x0001
1108 /* Duration */
1109 #define STOR_PERM     0x0002
1110 /* Definition locality */
1111 #define STOR_NONLOCAL 0x0004  /* The definition is not in this translation unit */
1112 /* Storage specifiers */
1113 #define STOR_AUTO     0x0000
1114 #define STOR_STATIC   0x0002
1115 #define STOR_LOCAL    0x0003
1116 #define STOR_EXTERN   0x0007
1117 #define STOR_INLINE   0x0008
1118 #define STOR_REGISTER 0x0010
1119 #define STOR_TYPEDEF  0x0018
1120
1121 #define QUAL_SHIFT         5
1122 #define QUAL_MASK     0x00e0
1123 #define QUAL_NONE     0x0000
1124 #define QUAL_CONST    0x0020
1125 #define QUAL_VOLATILE 0x0040
1126 #define QUAL_RESTRICT 0x0080
1127
1128 #define TYPE_SHIFT         8
1129 #define TYPE_MASK     0x1f00
1130 #define TYPE_INTEGER(TYPE)    ((((TYPE) >= TYPE_CHAR) && ((TYPE) <= TYPE_ULLONG)) || ((TYPE) == TYPE_ENUM) || ((TYPE) == TYPE_BITFIELD))
1131 #define TYPE_ARITHMETIC(TYPE) ((((TYPE) >= TYPE_CHAR) && ((TYPE) <= TYPE_LDOUBLE)) || ((TYPE) == TYPE_ENUM) || ((TYPE) == TYPE_BITFIELD))
1132 #define TYPE_UNSIGNED(TYPE)   ((TYPE) & 0x0100)
1133 #define TYPE_SIGNED(TYPE)     (!TYPE_UNSIGNED(TYPE))
1134 #define TYPE_MKUNSIGNED(TYPE) (((TYPE) & ~0xF000) | 0x0100)
1135 #define TYPE_RANK(TYPE)       ((TYPE) & ~0xF1FF)
1136 #define TYPE_PTR(TYPE)        (((TYPE) & TYPE_MASK) == TYPE_POINTER)
1137 #define TYPE_DEFAULT  0x0000
1138 #define TYPE_VOID     0x0100
1139 #define TYPE_CHAR     0x0200
1140 #define TYPE_UCHAR    0x0300
1141 #define TYPE_SHORT    0x0400
1142 #define TYPE_USHORT   0x0500
1143 #define TYPE_INT      0x0600
1144 #define TYPE_UINT     0x0700
1145 #define TYPE_LONG     0x0800
1146 #define TYPE_ULONG    0x0900
1147 #define TYPE_LLONG    0x0a00 /* long long */
1148 #define TYPE_ULLONG   0x0b00
1149 #define TYPE_FLOAT    0x0c00
1150 #define TYPE_DOUBLE   0x0d00
1151 #define TYPE_LDOUBLE  0x0e00 /* long double */
1152
1153 /* Note: TYPE_ENUM is chosen very carefully so TYPE_RANK works */
1154 #define TYPE_ENUM     0x1600
1155 #define TYPE_LIST     0x1700
1156 /* TYPE_LIST is a basic building block when defining enumerations
1157  * type->field_ident holds the name of this enumeration entry.
1158  * type->right holds the entry in the list.
1159  */
1160
1161 #define TYPE_STRUCT   0x1000
1162 /* For TYPE_STRUCT
1163  * type->left holds the link list of TYPE_PRODUCT entries that
1164  * make up the structure.
1165  * type->elements hold the length of the linked list
1166  */
1167 #define TYPE_UNION    0x1100
1168 /* For TYPE_UNION
1169  * type->left holds the link list of TYPE_OVERLAP entries that
1170  * make up the union.
1171  * type->elements hold the length of the linked list
1172  */
1173 #define TYPE_POINTER  0x1200 
1174 /* For TYPE_POINTER:
1175  * type->left holds the type pointed to.
1176  */
1177 #define TYPE_FUNCTION 0x1300 
1178 /* For TYPE_FUNCTION:
1179  * type->left holds the return type.
1180  * type->right holds the type of the arguments
1181  * type->elements holds the count of the arguments
1182  */
1183 #define TYPE_PRODUCT  0x1400
1184 /* TYPE_PRODUCT is a basic building block when defining structures
1185  * type->left holds the type that appears first in memory.
1186  * type->right holds the type that appears next in memory.
1187  */
1188 #define TYPE_OVERLAP  0x1500
1189 /* TYPE_OVERLAP is a basic building block when defining unions
1190  * type->left and type->right holds to types that overlap
1191  * each other in memory.
1192  */
1193 #define TYPE_ARRAY    0x1800
1194 /* TYPE_ARRAY is a basic building block when definitng arrays.
1195  * type->left holds the type we are an array of.
1196  * type->elements holds the number of elements.
1197  */
1198 #define TYPE_TUPLE    0x1900
1199 /* TYPE_TUPLE is a basic building block when defining 
1200  * positionally reference type conglomerations. (i.e. closures)
1201  * In essence it is a wrapper for TYPE_PRODUCT, like TYPE_STRUCT
1202  * except it has no field names.
1203  * type->left holds the liked list of TYPE_PRODUCT entries that
1204  * make up the closure type.
1205  * type->elements hold the number of elements in the closure.
1206  */
1207 #define TYPE_JOIN     0x1a00
1208 /* TYPE_JOIN is a basic building block when defining 
1209  * positionally reference type conglomerations. (i.e. closures)
1210  * In essence it is a wrapper for TYPE_OVERLAP, like TYPE_UNION
1211  * except it has no field names.
1212  * type->left holds the liked list of TYPE_OVERLAP entries that
1213  * make up the closure type.
1214  * type->elements hold the number of elements in the closure.
1215  */
1216 #define TYPE_BITFIELD 0x1b00
1217 /* TYPE_BITFIED is the type of a bitfield.
1218  * type->left holds the type basic type TYPE_BITFIELD is derived from.
1219  * type->elements holds the number of bits in the bitfield.
1220  */
1221 #define TYPE_UNKNOWN  0x1c00
1222 /* TYPE_UNKNOWN is the type of an unknown value.
1223  * Used on unknown consts and other places where I don't know the type.
1224  */
1225
1226 #define ATTRIB_SHIFT                 16
1227 #define ATTRIB_MASK          0xffff0000
1228 #define ATTRIB_NOINLINE      0x00010000
1229 #define ATTRIB_ALWAYS_INLINE 0x00020000
1230
1231 #define ELEMENT_COUNT_UNSPECIFIED ULONG_T_MAX
1232
1233 struct type {
1234         unsigned int type;
1235         struct type *left, *right;
1236         ulong_t elements;
1237         struct hash_entry *field_ident;
1238         struct hash_entry *type_ident;
1239 };
1240
1241 #define TEMPLATE_BITS      7
1242 #define MAX_TEMPLATES      (1<<TEMPLATE_BITS)
1243 #define MAX_REG_EQUIVS     16
1244 #define MAX_REGC           14
1245 #define MAX_REGISTERS      75
1246 #define REGISTER_BITS      7
1247 #define MAX_VIRT_REGISTERS (1<<REGISTER_BITS)
1248 #define REG_ERROR          0
1249 #define REG_UNSET          1
1250 #define REG_UNNEEDED       2
1251 #define REG_VIRT0          (MAX_REGISTERS + 0)
1252 #define REG_VIRT1          (MAX_REGISTERS + 1)
1253 #define REG_VIRT2          (MAX_REGISTERS + 2)
1254 #define REG_VIRT3          (MAX_REGISTERS + 3)
1255 #define REG_VIRT4          (MAX_REGISTERS + 4)
1256 #define REG_VIRT5          (MAX_REGISTERS + 5)
1257 #define REG_VIRT6          (MAX_REGISTERS + 6)
1258 #define REG_VIRT7          (MAX_REGISTERS + 7)
1259 #define REG_VIRT8          (MAX_REGISTERS + 8)
1260 #define REG_VIRT9          (MAX_REGISTERS + 9)
1261
1262 #if (MAX_REGISTERS + 9) > MAX_VIRT_REGISTERS
1263 #error "MAX_VIRT_REGISTERS to small"
1264 #endif
1265 #if (MAX_REGC + REGISTER_BITS) >= 26
1266 #error "Too many id bits used"
1267 #endif
1268
1269 /* Provision for 8 register classes */
1270 #define REG_SHIFT  0
1271 #define REGC_SHIFT REGISTER_BITS
1272 #define REGC_MASK (((1 << MAX_REGC) - 1) << REGISTER_BITS)
1273 #define REG_MASK (MAX_VIRT_REGISTERS -1)
1274 #define ID_REG(ID)              ((ID) & REG_MASK)
1275 #define SET_REG(ID, REG)        ((ID) = (((ID) & ~REG_MASK) | ((REG) & REG_MASK)))
1276 #define ID_REGCM(ID)            (((ID) & REGC_MASK) >> REGC_SHIFT)
1277 #define SET_REGCM(ID, REGCM)    ((ID) = (((ID) & ~REGC_MASK) | (((REGCM) << REGC_SHIFT) & REGC_MASK)))
1278 #define SET_INFO(ID, INFO)      ((ID) = (((ID) & ~(REG_MASK | REGC_MASK)) | \
1279                 (((INFO).reg) & REG_MASK) | ((((INFO).regcm) << REGC_SHIFT) & REGC_MASK)))
1280
1281 #define ARCH_INPUT_REGS 4
1282 #define ARCH_OUTPUT_REGS 4
1283
1284 static const struct reg_info arch_input_regs[ARCH_INPUT_REGS];
1285 static const struct reg_info arch_output_regs[ARCH_OUTPUT_REGS];
1286 static unsigned arch_reg_regcm(struct compile_state *state, int reg);
1287 static unsigned arch_regcm_normalize(struct compile_state *state, unsigned regcm);
1288 static unsigned arch_regcm_reg_normalize(struct compile_state *state, unsigned regcm);
1289 static void arch_reg_equivs(
1290         struct compile_state *state, unsigned *equiv, int reg);
1291 static int arch_select_free_register(
1292         struct compile_state *state, char *used, int classes);
1293 static unsigned arch_regc_size(struct compile_state *state, int class);
1294 static int arch_regcm_intersect(unsigned regcm1, unsigned regcm2);
1295 static unsigned arch_type_to_regcm(struct compile_state *state, struct type *type);
1296 static const char *arch_reg_str(int reg);
1297 static struct reg_info arch_reg_constraint(
1298         struct compile_state *state, struct type *type, const char *constraint);
1299 static struct reg_info arch_reg_clobber(
1300         struct compile_state *state, const char *clobber);
1301 static struct reg_info arch_reg_lhs(struct compile_state *state, 
1302         struct triple *ins, int index);
1303 static struct reg_info arch_reg_rhs(struct compile_state *state, 
1304         struct triple *ins, int index);
1305 static int arch_reg_size(int reg);
1306 static struct triple *transform_to_arch_instruction(
1307         struct compile_state *state, struct triple *ins);
1308 static struct triple *flatten(
1309         struct compile_state *state, struct triple *first, struct triple *ptr);
1310 static void print_dominators(struct compile_state *state,
1311         FILE *fp, struct basic_blocks *bb);
1312 static void print_dominance_frontiers(struct compile_state *state,
1313         FILE *fp, struct basic_blocks *bb);
1314
1315
1316
1317 #define DEBUG_ABORT_ON_ERROR    0x00000001
1318 #define DEBUG_BASIC_BLOCKS      0x00000002
1319 #define DEBUG_FDOMINATORS       0x00000004
1320 #define DEBUG_RDOMINATORS       0x00000008
1321 #define DEBUG_TRIPLES           0x00000010
1322 #define DEBUG_INTERFERENCE      0x00000020
1323 #define DEBUG_SCC_TRANSFORM     0x00000040
1324 #define DEBUG_SCC_TRANSFORM2    0x00000080
1325 #define DEBUG_REBUILD_SSA_FORM  0x00000100
1326 #define DEBUG_INLINE            0x00000200
1327 #define DEBUG_RANGE_CONFLICTS   0x00000400
1328 #define DEBUG_RANGE_CONFLICTS2  0x00000800
1329 #define DEBUG_COLOR_GRAPH       0x00001000
1330 #define DEBUG_COLOR_GRAPH2      0x00002000
1331 #define DEBUG_COALESCING        0x00004000
1332 #define DEBUG_COALESCING2       0x00008000
1333 #define DEBUG_VERIFICATION      0x00010000
1334 #define DEBUG_CALLS             0x00020000
1335 #define DEBUG_CALLS2            0x00040000
1336 #define DEBUG_TOKENS            0x80000000
1337
1338 #define DEBUG_DEFAULT ( \
1339         DEBUG_ABORT_ON_ERROR | \
1340         DEBUG_BASIC_BLOCKS | \
1341         DEBUG_FDOMINATORS | \
1342         DEBUG_RDOMINATORS | \
1343         DEBUG_TRIPLES | \
1344         0 )
1345
1346 #define DEBUG_ALL ( \
1347         DEBUG_ABORT_ON_ERROR   | \
1348         DEBUG_BASIC_BLOCKS     | \
1349         DEBUG_FDOMINATORS      | \
1350         DEBUG_RDOMINATORS      | \
1351         DEBUG_TRIPLES          | \
1352         DEBUG_INTERFERENCE     | \
1353         DEBUG_SCC_TRANSFORM    | \
1354         DEBUG_SCC_TRANSFORM2   | \
1355         DEBUG_REBUILD_SSA_FORM | \
1356         DEBUG_INLINE           | \
1357         DEBUG_RANGE_CONFLICTS  | \
1358         DEBUG_RANGE_CONFLICTS2 | \
1359         DEBUG_COLOR_GRAPH      | \
1360         DEBUG_COLOR_GRAPH2     | \
1361         DEBUG_COALESCING       | \
1362         DEBUG_COALESCING2      | \
1363         DEBUG_VERIFICATION     | \
1364         DEBUG_CALLS            | \
1365         DEBUG_CALLS2           | \
1366         DEBUG_TOKENS           | \
1367         0 )
1368
1369 #define COMPILER_INLINE_MASK               0x00000007
1370 #define COMPILER_INLINE_ALWAYS             0x00000000
1371 #define COMPILER_INLINE_NEVER              0x00000001
1372 #define COMPILER_INLINE_DEFAULTON          0x00000002
1373 #define COMPILER_INLINE_DEFAULTOFF         0x00000003
1374 #define COMPILER_INLINE_NOPENALTY          0x00000004
1375 #define COMPILER_ELIMINATE_INEFECTUAL_CODE 0x00000008
1376 #define COMPILER_SIMPLIFY                  0x00000010
1377 #define COMPILER_SCC_TRANSFORM             0x00000020
1378 #define COMPILER_SIMPLIFY_OP               0x00000040
1379 #define COMPILER_SIMPLIFY_PHI              0x00000080
1380 #define COMPILER_SIMPLIFY_LABEL            0x00000100
1381 #define COMPILER_SIMPLIFY_BRANCH           0x00000200
1382 #define COMPILER_SIMPLIFY_COPY             0x00000400
1383 #define COMPILER_SIMPLIFY_ARITH            0x00000800
1384 #define COMPILER_SIMPLIFY_SHIFT            0x00001000
1385 #define COMPILER_SIMPLIFY_BITWISE          0x00002000
1386 #define COMPILER_SIMPLIFY_LOGICAL          0x00004000
1387 #define COMPILER_SIMPLIFY_BITFIELD         0x00008000
1388
1389 #define COMPILER_TRIGRAPHS                 0x40000000
1390 #define COMPILER_PP_ONLY                   0x80000000
1391
1392 #define COMPILER_DEFAULT_FLAGS ( \
1393         COMPILER_TRIGRAPHS | \
1394         COMPILER_ELIMINATE_INEFECTUAL_CODE | \
1395         COMPILER_INLINE_DEFAULTON | \
1396         COMPILER_SIMPLIFY_OP | \
1397         COMPILER_SIMPLIFY_PHI | \
1398         COMPILER_SIMPLIFY_LABEL | \
1399         COMPILER_SIMPLIFY_BRANCH | \
1400         COMPILER_SIMPLIFY_COPY | \
1401         COMPILER_SIMPLIFY_ARITH | \
1402         COMPILER_SIMPLIFY_SHIFT | \
1403         COMPILER_SIMPLIFY_BITWISE | \
1404         COMPILER_SIMPLIFY_LOGICAL | \
1405         COMPILER_SIMPLIFY_BITFIELD | \
1406         0 )
1407
1408 #define GLOBAL_SCOPE_DEPTH   1
1409 #define FUNCTION_SCOPE_DEPTH (GLOBAL_SCOPE_DEPTH + 1)
1410
1411 static void compile_file(struct compile_state *old_state, const char *filename, int local);
1412
1413
1414
1415 static void init_compiler_state(struct compiler_state *compiler)
1416 {
1417         memset(compiler, 0, sizeof(*compiler));
1418         compiler->label_prefix = "";
1419         compiler->ofilename = "auto.inc";
1420         compiler->flags = COMPILER_DEFAULT_FLAGS;
1421         compiler->debug = 0;
1422         compiler->max_allocation_passes = MAX_ALLOCATION_PASSES;
1423         compiler->include_path_count = 1;
1424         compiler->include_paths      = xcmalloc(sizeof(char *), "include_paths");
1425         compiler->define_count       = 1;
1426         compiler->defines            = xcmalloc(sizeof(char *), "defines");
1427         compiler->undef_count        = 1;
1428         compiler->undefs             = xcmalloc(sizeof(char *), "undefs");
1429 }
1430
1431 struct compiler_flag {
1432         const char *name;
1433         unsigned long flag;
1434 };
1435
1436 struct compiler_arg {
1437         const char *name;
1438         unsigned long mask;
1439         struct compiler_flag flags[16];
1440 };
1441
1442 static int set_flag(
1443         const struct compiler_flag *ptr, unsigned long *flags,
1444         int act, const char *flag)
1445 {
1446         int result = -1;
1447         for(; ptr->name; ptr++) {
1448                 if (strcmp(ptr->name, flag) == 0) {
1449                         break;
1450                 }
1451         }
1452         if (ptr->name) {
1453                 result = 0;
1454                 *flags &= ~(ptr->flag);
1455                 if (act) {
1456                         *flags |= ptr->flag;
1457                 }
1458         }
1459         return result;
1460 }
1461
1462 static int set_arg(
1463         const struct compiler_arg *ptr, unsigned long *flags, const char *arg)
1464 {
1465         const char *val;
1466         int result = -1;
1467         int len;
1468         val = strchr(arg, '=');
1469         if (val) {
1470                 len = val - arg;
1471                 val++;
1472                 for(; ptr->name; ptr++) {
1473                         if (strncmp(ptr->name, arg, len) == 0) {
1474                                 break;
1475                         }
1476                 }
1477                 if (ptr->name) {
1478                         *flags &= ~ptr->mask;
1479                         result = set_flag(&ptr->flags[0], flags, 1, val);
1480                 }
1481         }
1482         return result;
1483 }
1484         
1485
1486 static void flag_usage(FILE *fp, const struct compiler_flag *ptr, 
1487         const char *prefix, const char *invert_prefix)
1488 {
1489         for(;ptr->name; ptr++) {
1490                 fprintf(fp, "%s%s\n", prefix, ptr->name);
1491                 if (invert_prefix) {
1492                         fprintf(fp, "%s%s\n", invert_prefix, ptr->name);
1493                 }
1494         }
1495 }
1496
1497 static void arg_usage(FILE *fp, const struct compiler_arg *ptr,
1498         const char *prefix)
1499 {
1500         for(;ptr->name; ptr++) {
1501                 const struct compiler_flag *flag;
1502                 for(flag = &ptr->flags[0]; flag->name; flag++) {
1503                         fprintf(fp, "%s%s=%s\n", 
1504                                 prefix, ptr->name, flag->name);
1505                 }
1506         }
1507 }
1508
1509 static int append_string(size_t *max, const char ***vec, const char *str,
1510         const char *name)
1511 {
1512         size_t count;
1513         count = ++(*max);
1514         *vec = xrealloc(*vec, sizeof(char *)*count, "name");
1515         (*vec)[count -1] = 0;
1516         (*vec)[count -2] = str; 
1517         return 0;
1518 }
1519
1520 static void arg_error(char *fmt, ...);
1521 static const char *identifier(const char *str, const char *end);
1522
1523 static int append_include_path(struct compiler_state *compiler, const char *str)
1524 {
1525         int result;
1526         if (!exists(str, ".")) {
1527                 arg_error("Nonexistent include path: `%s'\n",
1528                         str);
1529         }
1530         result = append_string(&compiler->include_path_count,
1531                 &compiler->include_paths, str, "include_paths");
1532         return result;
1533 }
1534
1535 static int append_define(struct compiler_state *compiler, const char *str)
1536 {
1537         const char *end, *rest;
1538         int result;
1539
1540         end = strchr(str, '=');
1541         if (!end) {
1542                 end = str + strlen(str);
1543         }
1544         rest = identifier(str, end);
1545         if (rest != end) {
1546                 int len = end - str - 1;
1547                 arg_error("Invalid name cannot define macro: `%*.*s'\n", 
1548                         len, len, str);
1549         }
1550         result = append_string(&compiler->define_count,
1551                 &compiler->defines, str, "defines");
1552         return result;
1553 }
1554
1555 static int append_undef(struct compiler_state *compiler, const char *str)
1556 {
1557         const char *end, *rest;
1558         int result;
1559
1560         end = str + strlen(str);
1561         rest = identifier(str, end);
1562         if (rest != end) {
1563                 int len = end - str - 1;
1564                 arg_error("Invalid name cannot undefine macro: `%*.*s'\n", 
1565                         len, len, str);
1566         }
1567         result = append_string(&compiler->undef_count,
1568                 &compiler->undefs, str, "undefs");
1569         return result;
1570 }
1571
1572 static const struct compiler_flag romcc_flags[] = {
1573         { "trigraphs",                 COMPILER_TRIGRAPHS },
1574         { "pp-only",                   COMPILER_PP_ONLY },
1575         { "eliminate-inefectual-code", COMPILER_ELIMINATE_INEFECTUAL_CODE },
1576         { "simplify",                  COMPILER_SIMPLIFY },
1577         { "scc-transform",             COMPILER_SCC_TRANSFORM },
1578         { "simplify-op",               COMPILER_SIMPLIFY_OP },
1579         { "simplify-phi",              COMPILER_SIMPLIFY_PHI },
1580         { "simplify-label",            COMPILER_SIMPLIFY_LABEL },
1581         { "simplify-branch",           COMPILER_SIMPLIFY_BRANCH },
1582         { "simplify-copy",             COMPILER_SIMPLIFY_COPY },
1583         { "simplify-arith",            COMPILER_SIMPLIFY_ARITH },
1584         { "simplify-shift",            COMPILER_SIMPLIFY_SHIFT },
1585         { "simplify-bitwise",          COMPILER_SIMPLIFY_BITWISE },
1586         { "simplify-logical",          COMPILER_SIMPLIFY_LOGICAL },
1587         { "simplify-bitfield",         COMPILER_SIMPLIFY_BITFIELD },
1588         { 0, 0 },
1589 };
1590 static const struct compiler_arg romcc_args[] = {
1591         { "inline-policy",             COMPILER_INLINE_MASK,
1592                 {
1593                         { "always",      COMPILER_INLINE_ALWAYS, },
1594                         { "never",       COMPILER_INLINE_NEVER, },
1595                         { "defaulton",   COMPILER_INLINE_DEFAULTON, },
1596                         { "defaultoff",  COMPILER_INLINE_DEFAULTOFF, },
1597                         { "nopenalty",   COMPILER_INLINE_NOPENALTY, },
1598                         { 0, 0 },
1599                 },
1600         },
1601         { 0, 0 },
1602 };
1603 static const struct compiler_flag romcc_opt_flags[] = {
1604         { "-O",  COMPILER_SIMPLIFY },
1605         { "-O2", COMPILER_SIMPLIFY | COMPILER_SCC_TRANSFORM },
1606         { "-E",  COMPILER_PP_ONLY },
1607         { 0, 0, },
1608 };
1609 static const struct compiler_flag romcc_debug_flags[] = {
1610         { "all",                   DEBUG_ALL },
1611         { "abort-on-error",        DEBUG_ABORT_ON_ERROR },
1612         { "basic-blocks",          DEBUG_BASIC_BLOCKS },
1613         { "fdominators",           DEBUG_FDOMINATORS },
1614         { "rdominators",           DEBUG_RDOMINATORS },
1615         { "triples",               DEBUG_TRIPLES },
1616         { "interference",          DEBUG_INTERFERENCE },
1617         { "scc-transform",         DEBUG_SCC_TRANSFORM },
1618         { "scc-transform2",        DEBUG_SCC_TRANSFORM2 },
1619         { "rebuild-ssa-form",      DEBUG_REBUILD_SSA_FORM },
1620         { "inline",                DEBUG_INLINE },
1621         { "live-range-conflicts",  DEBUG_RANGE_CONFLICTS },
1622         { "live-range-conflicts2", DEBUG_RANGE_CONFLICTS2 },
1623         { "color-graph",           DEBUG_COLOR_GRAPH },
1624         { "color-graph2",          DEBUG_COLOR_GRAPH2 },
1625         { "coalescing",            DEBUG_COALESCING },
1626         { "coalescing2",           DEBUG_COALESCING2 },
1627         { "verification",          DEBUG_VERIFICATION },
1628         { "calls",                 DEBUG_CALLS },
1629         { "calls2",                DEBUG_CALLS2 },
1630         { "tokens",                DEBUG_TOKENS },
1631         { 0, 0 },
1632 };
1633
1634 static int compiler_encode_flag(
1635         struct compiler_state *compiler, const char *flag)
1636 {
1637         int act;
1638         int result;
1639
1640         act = 1;
1641         result = -1;
1642         if (strncmp(flag, "no-", 3) == 0) {
1643                 flag += 3;
1644                 act = 0;
1645         }
1646         if (strncmp(flag, "-O", 2) == 0) {
1647                 result = set_flag(romcc_opt_flags, &compiler->flags, act, flag);
1648         }
1649         else if (strncmp(flag, "-E", 2) == 0) {
1650                 result = set_flag(romcc_opt_flags, &compiler->flags, act, flag);
1651         }
1652         else if (strncmp(flag, "-I", 2) == 0) {
1653                 result = append_include_path(compiler, flag + 2);
1654         }
1655         else if (strncmp(flag, "-D", 2) == 0) {
1656                 result = append_define(compiler, flag + 2);
1657         }
1658         else if (strncmp(flag, "-U", 2) == 0) {
1659                 result = append_undef(compiler, flag + 2);
1660         }
1661         else if (act && strncmp(flag, "label-prefix=", 13) == 0) {
1662                 result = 0;
1663                 compiler->label_prefix = flag + 13;
1664         }
1665         else if (act && strncmp(flag, "max-allocation-passes=", 22) == 0) {
1666                 unsigned long max_passes;
1667                 char *end;
1668                 max_passes = strtoul(flag + 22, &end, 10);
1669                 if (end[0] == '\0') {
1670                         result = 0;
1671                         compiler->max_allocation_passes = max_passes;
1672                 }
1673         }
1674         else if (act && strcmp(flag, "debug") == 0) {
1675                 result = 0;
1676                 compiler->debug |= DEBUG_DEFAULT;
1677         }
1678         else if (strncmp(flag, "debug-", 6) == 0) {
1679                 flag += 6;
1680                 result = set_flag(romcc_debug_flags, &compiler->debug, act, flag);
1681         }
1682         else {
1683                 result = set_flag(romcc_flags, &compiler->flags, act, flag);
1684                 if (result < 0) {
1685                         result = set_arg(romcc_args, &compiler->flags, flag);
1686                 }
1687         }
1688         return result;
1689 }
1690
1691 static void compiler_usage(FILE *fp)
1692 {
1693         flag_usage(fp, romcc_opt_flags, "", 0);
1694         flag_usage(fp, romcc_flags, "-f", "-fno-");
1695         arg_usage(fp,  romcc_args, "-f");
1696         flag_usage(fp, romcc_debug_flags, "-fdebug-", "-fno-debug-");
1697         fprintf(fp, "-flabel-prefix=<prefix for assembly language labels>\n");
1698         fprintf(fp, "--label-prefix=<prefix for assembly language labels>\n");
1699         fprintf(fp, "-I<include path>\n");
1700         fprintf(fp, "-D<macro>[=defn]\n");
1701         fprintf(fp, "-U<macro>\n");
1702 }
1703
1704 static void do_cleanup(struct compile_state *state)
1705 {
1706         if (state->output) {
1707                 fclose(state->output);
1708                 unlink(state->compiler->ofilename);
1709                 state->output = 0;
1710         }
1711         if (state->dbgout) {
1712                 fflush(state->dbgout);
1713         }
1714         if (state->errout) {
1715                 fflush(state->errout);
1716         }
1717 }
1718
1719 static struct compile_state *exit_state;
1720 static void exit_cleanup(void)
1721 {
1722         if (exit_state) {
1723                 do_cleanup(exit_state);
1724         }
1725 }
1726
1727 static int get_col(struct file_state *file)
1728 {
1729         int col;
1730         const char *ptr, *end;
1731         ptr = file->line_start;
1732         end = file->pos;
1733         for(col = 0; ptr < end; ptr++) {
1734                 if (*ptr != '\t') {
1735                         col++;
1736                 } 
1737                 else {
1738                         col = (col & ~7) + 8;
1739                 }
1740         }
1741         return col;
1742 }
1743
1744 static void loc(FILE *fp, struct compile_state *state, struct triple *triple)
1745 {
1746         int col;
1747         if (triple && triple->occurance) {
1748                 struct occurance *spot;
1749                 for(spot = triple->occurance; spot; spot = spot->parent) {
1750                         fprintf(fp, "%s:%d.%d: ", 
1751                                 spot->filename, spot->line, spot->col);
1752                 }
1753                 return;
1754         }
1755         if (!state->file) {
1756                 return;
1757         }
1758         col = get_col(state->file);
1759         fprintf(fp, "%s:%d.%d: ", 
1760                 state->file->report_name, state->file->report_line, col);
1761 }
1762
1763 static void __attribute__ ((noreturn)) internal_error(struct compile_state *state, struct triple *ptr, 
1764         const char *fmt, ...)
1765 {
1766         FILE *fp = state->errout;
1767         va_list args;
1768         va_start(args, fmt);
1769         loc(fp, state, ptr);
1770         fputc('\n', fp);
1771         if (ptr) {
1772                 fprintf(fp, "%p %-10s ", ptr, tops(ptr->op));
1773         }
1774         fprintf(fp, "Internal compiler error: ");
1775         vfprintf(fp, fmt, args);
1776         fprintf(fp, "\n");
1777         va_end(args);
1778         do_cleanup(state);
1779         abort();
1780 }
1781
1782
1783 static void internal_warning(struct compile_state *state, struct triple *ptr, 
1784         const char *fmt, ...)
1785 {
1786         FILE *fp = state->errout;
1787         va_list args;
1788         va_start(args, fmt);
1789         loc(fp, state, ptr);
1790         if (ptr) {
1791                 fprintf(fp, "%p %-10s ", ptr, tops(ptr->op));
1792         }
1793         fprintf(fp, "Internal compiler warning: ");
1794         vfprintf(fp, fmt, args);
1795         fprintf(fp, "\n");
1796         va_end(args);
1797 }
1798
1799
1800
1801 static void __attribute__ ((noreturn)) error(struct compile_state *state, struct triple *ptr, 
1802         const char *fmt, ...)
1803 {
1804         FILE *fp = state->errout;
1805         va_list args;
1806         va_start(args, fmt);
1807         loc(fp, state, ptr);
1808         fputc('\n', fp);
1809         if (ptr && (state->compiler->debug & DEBUG_ABORT_ON_ERROR)) {
1810                 fprintf(fp, "%p %-10s ", ptr, tops(ptr->op));
1811         }
1812         vfprintf(fp, fmt, args);
1813         va_end(args);
1814         fprintf(fp, "\n");
1815         do_cleanup(state);
1816         if (state->compiler->debug & DEBUG_ABORT_ON_ERROR) {
1817                 abort();
1818         }
1819         exit(1);
1820 }
1821
1822 static void warning(struct compile_state *state, struct triple *ptr, 
1823         const char *fmt, ...)
1824 {
1825         FILE *fp = state->errout;
1826         va_list args;
1827         va_start(args, fmt);
1828         loc(fp, state, ptr);
1829         fprintf(fp, "warning: "); 
1830         if (ptr && (state->compiler->debug & DEBUG_ABORT_ON_ERROR)) {
1831                 fprintf(fp, "%p %-10s ", ptr, tops(ptr->op));
1832         }
1833         vfprintf(fp, fmt, args);
1834         fprintf(fp, "\n");
1835         va_end(args);
1836 }
1837
1838 #define FINISHME() warning(state, 0, "FINISHME @ %s.%s:%d", __FILE__, __func__, __LINE__)
1839
1840 static void valid_op(struct compile_state *state, int op)
1841 {
1842         char *fmt = "invalid op: %d";
1843         if (op >= OP_MAX) {
1844                 internal_error(state, 0, fmt, op);
1845         }
1846         if (op < 0) {
1847                 internal_error(state, 0, fmt, op);
1848         }
1849 }
1850
1851 static void valid_ins(struct compile_state *state, struct triple *ptr)
1852 {
1853         valid_op(state, ptr->op);
1854 }
1855
1856 #if DEBUG_ROMCC_WARNING
1857 static void valid_param_count(struct compile_state *state, struct triple *ins)
1858 {
1859         int lhs, rhs, misc, targ;
1860         valid_ins(state, ins);
1861         lhs  = table_ops[ins->op].lhs;
1862         rhs  = table_ops[ins->op].rhs;
1863         misc = table_ops[ins->op].misc;
1864         targ = table_ops[ins->op].targ;
1865
1866         if ((lhs >= 0) && (ins->lhs != lhs)) {
1867                 internal_error(state, ins, "Bad lhs count");
1868         }
1869         if ((rhs >= 0) && (ins->rhs != rhs)) {
1870                 internal_error(state, ins, "Bad rhs count");
1871         }
1872         if ((misc >= 0) && (ins->misc != misc)) {
1873                 internal_error(state, ins, "Bad misc count");
1874         }
1875         if ((targ >= 0) && (ins->targ != targ)) {
1876                 internal_error(state, ins, "Bad targ count");
1877         }
1878 }
1879 #endif
1880
1881 static struct type void_type;
1882 static struct type unknown_type;
1883 static void use_triple(struct triple *used, struct triple *user)
1884 {
1885         struct triple_set **ptr, *new;
1886         if (!used)
1887                 return;
1888         if (!user)
1889                 return;
1890         ptr = &used->use;
1891         while(*ptr) {
1892                 if ((*ptr)->member == user) {
1893                         return;
1894                 }
1895                 ptr = &(*ptr)->next;
1896         }
1897         /* Append new to the head of the list, 
1898          * copy_func and rename_block_variables
1899          * depends on this.
1900          */
1901         new = xcmalloc(sizeof(*new), "triple_set");
1902         new->member = user;
1903         new->next   = used->use;
1904         used->use   = new;
1905 }
1906
1907 static void unuse_triple(struct triple *used, struct triple *unuser)
1908 {
1909         struct triple_set *use, **ptr;
1910         if (!used) {
1911                 return;
1912         }
1913         ptr = &used->use;
1914         while(*ptr) {
1915                 use = *ptr;
1916                 if (use->member == unuser) {
1917                         *ptr = use->next;
1918                         xfree(use);
1919                 }
1920                 else {
1921                         ptr = &use->next;
1922                 }
1923         }
1924 }
1925
1926 static void put_occurance(struct occurance *occurance)
1927 {
1928         if (occurance) {
1929                 occurance->count -= 1;
1930                 if (occurance->count <= 0) {
1931                         if (occurance->parent) {
1932                                 put_occurance(occurance->parent);
1933                         }
1934                         xfree(occurance);
1935                 }
1936         }
1937 }
1938
1939 static void get_occurance(struct occurance *occurance)
1940 {
1941         if (occurance) {
1942                 occurance->count += 1;
1943         }
1944 }
1945
1946
1947 static struct occurance *new_occurance(struct compile_state *state)
1948 {
1949         struct occurance *result, *last;
1950         const char *filename;
1951         const char *function;
1952         int line, col;
1953
1954         function = "";
1955         filename = 0;
1956         line = 0;
1957         col  = 0;
1958         if (state->file) {
1959                 filename = state->file->report_name;
1960                 line     = state->file->report_line;
1961                 col      = get_col(state->file);
1962         }
1963         if (state->function) {
1964                 function = state->function;
1965         }
1966         last = state->last_occurance;
1967         if (last &&
1968                 (last->col == col) &&
1969                 (last->line == line) &&
1970                 (last->function == function) &&
1971                 ((last->filename == filename) ||
1972                         (strcmp(last->filename, filename) == 0))) 
1973         {
1974                 get_occurance(last);
1975                 return last;
1976         }
1977         if (last) {
1978                 state->last_occurance = 0;
1979                 put_occurance(last);
1980         }
1981         result = xmalloc(sizeof(*result), "occurance");
1982         result->count    = 2;
1983         result->filename = filename;
1984         result->function = function;
1985         result->line     = line;
1986         result->col      = col;
1987         result->parent   = 0;
1988         state->last_occurance = result;
1989         return result;
1990 }
1991
1992 static struct occurance *inline_occurance(struct compile_state *state,
1993         struct occurance *base, struct occurance *top)
1994 {
1995         struct occurance *result, *last;
1996         if (top->parent) {
1997                 internal_error(state, 0, "inlining an already inlined function?");
1998         }
1999         /* If I have a null base treat it that way */
2000         if ((base->parent == 0) &&
2001                 (base->col == 0) &&
2002                 (base->line == 0) &&
2003                 (base->function[0] == '\0') &&
2004                 (base->filename[0] == '\0')) {
2005                 base = 0;
2006         }
2007         /* See if I can reuse the last occurance I had */
2008         last = state->last_occurance;
2009         if (last &&
2010                 (last->parent   == base) &&
2011                 (last->col      == top->col) &&
2012                 (last->line     == top->line) &&
2013                 (last->function == top->function) &&
2014                 (last->filename == top->filename)) {
2015                 get_occurance(last);
2016                 return last;
2017         }
2018         /* I can't reuse the last occurance so free it */
2019         if (last) {
2020                 state->last_occurance = 0;
2021                 put_occurance(last);
2022         }
2023         /* Generate a new occurance structure */
2024         get_occurance(base);
2025         result = xmalloc(sizeof(*result), "occurance");
2026         result->count    = 2;
2027         result->filename = top->filename;
2028         result->function = top->function;
2029         result->line     = top->line;
2030         result->col      = top->col;
2031         result->parent   = base;
2032         state->last_occurance = result;
2033         return result;
2034 }
2035
2036 static struct occurance dummy_occurance = {
2037         .count    = 2,
2038         .filename = __FILE__,
2039         .function = "",
2040         .line     = __LINE__,
2041         .col      = 0,
2042         .parent   = 0,
2043 };
2044
2045 /* The undef triple is used as a place holder when we are removing pointers
2046  * from a triple.  Having allows certain sanity checks to pass even
2047  * when the original triple that was pointed to is gone.
2048  */
2049 static struct triple unknown_triple = {
2050         .next      = &unknown_triple,
2051         .prev      = &unknown_triple,
2052         .use       = 0,
2053         .op        = OP_UNKNOWNVAL,
2054         .lhs       = 0,
2055         .rhs       = 0,
2056         .misc      = 0,
2057         .targ      = 0,
2058         .type      = &unknown_type,
2059         .id        = -1, /* An invalid id */
2060         .u = { .cval = 0, },
2061         .occurance = &dummy_occurance,
2062         .param = { [0] = 0, [1] = 0, },
2063 };
2064
2065
2066 static size_t registers_of(struct compile_state *state, struct type *type);
2067
2068 static struct triple *alloc_triple(struct compile_state *state, 
2069         int op, struct type *type, int lhs_wanted, int rhs_wanted,
2070         struct occurance *occurance)
2071 {
2072         size_t size, extra_count, min_count;
2073         int lhs, rhs, misc, targ;
2074         struct triple *ret, dummy;
2075         dummy.op = op;
2076         dummy.occurance = occurance;
2077         valid_op(state, op);
2078         lhs = table_ops[op].lhs;
2079         rhs = table_ops[op].rhs;
2080         misc = table_ops[op].misc;
2081         targ = table_ops[op].targ;
2082
2083         switch(op) {
2084         case OP_FCALL:
2085                 rhs = rhs_wanted;
2086                 break;
2087         case OP_PHI:
2088                 rhs = rhs_wanted;
2089                 break;
2090         case OP_ADECL:
2091                 lhs = registers_of(state, type);
2092                 break;
2093         case OP_TUPLE:
2094                 lhs = registers_of(state, type);
2095                 break;
2096         case OP_ASM:
2097                 rhs = rhs_wanted;
2098                 lhs = lhs_wanted;
2099                 break;
2100         }
2101         if ((rhs < 0) || (rhs > MAX_RHS)) {
2102                 internal_error(state, &dummy, "bad rhs count %d", rhs);
2103         }
2104         if ((lhs < 0) || (lhs > MAX_LHS)) {
2105                 internal_error(state, &dummy, "bad lhs count %d", lhs);
2106         }
2107         if ((misc < 0) || (misc > MAX_MISC)) {
2108                 internal_error(state, &dummy, "bad misc count %d", misc);
2109         }
2110         if ((targ < 0) || (targ > MAX_TARG)) {
2111                 internal_error(state, &dummy, "bad targs count %d", targ);
2112         }
2113
2114         min_count = sizeof(ret->param)/sizeof(ret->param[0]);
2115         extra_count = lhs + rhs + misc + targ;
2116         extra_count = (extra_count < min_count)? 0 : extra_count - min_count;
2117
2118         size = sizeof(*ret) + sizeof(ret->param[0]) * extra_count;
2119         ret = xcmalloc(size, "tripple");
2120         ret->op        = op;
2121         ret->lhs       = lhs;
2122         ret->rhs       = rhs;
2123         ret->misc      = misc;
2124         ret->targ      = targ;
2125         ret->type      = type;
2126         ret->next      = ret;
2127         ret->prev      = ret;
2128         ret->occurance = occurance;
2129         /* A simple sanity check */
2130         if ((ret->op != op) ||
2131                 (ret->lhs != lhs) ||
2132                 (ret->rhs != rhs) ||
2133                 (ret->misc != misc) ||
2134                 (ret->targ != targ) ||
2135                 (ret->type != type) ||
2136                 (ret->next != ret) ||
2137                 (ret->prev != ret) ||
2138                 (ret->occurance != occurance)) {
2139                 internal_error(state, ret, "huh?");
2140         }
2141         return ret;
2142 }
2143
2144 struct triple *dup_triple(struct compile_state *state, struct triple *src)
2145 {
2146         struct triple *dup;
2147         int src_lhs, src_rhs, src_size;
2148         src_lhs = src->lhs;
2149         src_rhs = src->rhs;
2150         src_size = TRIPLE_SIZE(src);
2151         get_occurance(src->occurance);
2152         dup = alloc_triple(state, src->op, src->type, src_lhs, src_rhs,
2153                 src->occurance);
2154         memcpy(dup, src, sizeof(*src));
2155         memcpy(dup->param, src->param, src_size * sizeof(src->param[0]));
2156         return dup;
2157 }
2158
2159 static struct triple *copy_triple(struct compile_state *state, struct triple *src)
2160 {
2161         struct triple *copy;
2162         copy = dup_triple(state, src);
2163         copy->use = 0;
2164         copy->next = copy->prev = copy;
2165         return copy;
2166 }
2167
2168 static struct triple *new_triple(struct compile_state *state, 
2169         int op, struct type *type, int lhs, int rhs)
2170 {
2171         struct triple *ret;
2172         struct occurance *occurance;
2173         occurance = new_occurance(state);
2174         ret = alloc_triple(state, op, type, lhs, rhs, occurance);
2175         return ret;
2176 }
2177
2178 static struct triple *build_triple(struct compile_state *state, 
2179         int op, struct type *type, struct triple *left, struct triple *right,
2180         struct occurance *occurance)
2181 {
2182         struct triple *ret;
2183         size_t count;
2184         ret = alloc_triple(state, op, type, -1, -1, occurance);
2185         count = TRIPLE_SIZE(ret);
2186         if (count > 0) {
2187                 ret->param[0] = left;
2188         }
2189         if (count > 1) {
2190                 ret->param[1] = right;
2191         }
2192         return ret;
2193 }
2194
2195 static struct triple *triple(struct compile_state *state, 
2196         int op, struct type *type, struct triple *left, struct triple *right)
2197 {
2198         struct triple *ret;
2199         size_t count;
2200         ret = new_triple(state, op, type, -1, -1);
2201         count = TRIPLE_SIZE(ret);
2202         if (count >= 1) {
2203                 ret->param[0] = left;
2204         }
2205         if (count >= 2) {
2206                 ret->param[1] = right;
2207         }
2208         return ret;
2209 }
2210
2211 static struct triple *branch(struct compile_state *state, 
2212         struct triple *targ, struct triple *test)
2213 {
2214         struct triple *ret;
2215         if (test) {
2216                 ret = new_triple(state, OP_CBRANCH, &void_type, -1, 1);
2217                 RHS(ret, 0) = test;
2218         } else {
2219                 ret = new_triple(state, OP_BRANCH, &void_type, -1, 0);
2220         }
2221         TARG(ret, 0) = targ;
2222         /* record the branch target was used */
2223         if (!targ || (targ->op != OP_LABEL)) {
2224                 internal_error(state, 0, "branch not to label");
2225         }
2226         return ret;
2227 }
2228
2229 static int triple_is_label(struct compile_state *state, struct triple *ins);
2230 static int triple_is_call(struct compile_state *state, struct triple *ins);
2231 static int triple_is_cbranch(struct compile_state *state, struct triple *ins);
2232 static void insert_triple(struct compile_state *state,
2233         struct triple *first, struct triple *ptr)
2234 {
2235         if (ptr) {
2236                 if ((ptr->id & TRIPLE_FLAG_FLATTENED) || (ptr->next != ptr)) {
2237                         internal_error(state, ptr, "expression already used");
2238                 }
2239                 ptr->next       = first;
2240                 ptr->prev       = first->prev;
2241                 ptr->prev->next = ptr;
2242                 ptr->next->prev = ptr;
2243
2244                 if (triple_is_cbranch(state, ptr->prev) ||
2245                         triple_is_call(state, ptr->prev)) {
2246                         unuse_triple(first, ptr->prev);
2247                         use_triple(ptr, ptr->prev);
2248                 }
2249         }
2250 }
2251
2252 static int triple_stores_block(struct compile_state *state, struct triple *ins)
2253 {
2254         /* This function is used to determine if u.block 
2255          * is utilized to store the current block number.
2256          */
2257         int stores_block;
2258         valid_ins(state, ins);
2259         stores_block = (table_ops[ins->op].flags & BLOCK) == BLOCK;
2260         return stores_block;
2261 }
2262
2263 static int triple_is_branch(struct compile_state *state, struct triple *ins);
2264 static struct block *block_of_triple(struct compile_state *state, 
2265         struct triple *ins)
2266 {
2267         struct triple *first;
2268         if (!ins || ins == &unknown_triple) {
2269                 return 0;
2270         }
2271         first = state->first;
2272         while(ins != first && !triple_is_branch(state, ins->prev) &&
2273                 !triple_stores_block(state, ins)) 
2274         { 
2275                 if (ins == ins->prev) {
2276                         internal_error(state, ins, "ins == ins->prev?");
2277                 }
2278                 ins = ins->prev;
2279         }
2280         return triple_stores_block(state, ins)? ins->u.block: 0;
2281 }
2282
2283 static void generate_lhs_pieces(struct compile_state *state, struct triple *ins);
2284 static struct triple *pre_triple(struct compile_state *state,
2285         struct triple *base,
2286         int op, struct type *type, struct triple *left, struct triple *right)
2287 {
2288         struct block *block;
2289         struct triple *ret;
2290         int i;
2291         /* If I am an OP_PIECE jump to the real instruction */
2292         if (base->op == OP_PIECE) {
2293                 base = MISC(base, 0);
2294         }
2295         block = block_of_triple(state, base);
2296         get_occurance(base->occurance);
2297         ret = build_triple(state, op, type, left, right, base->occurance);
2298         generate_lhs_pieces(state, ret);
2299         if (triple_stores_block(state, ret)) {
2300                 ret->u.block = block;
2301         }
2302         insert_triple(state, base, ret);
2303         for(i = 0; i < ret->lhs; i++) {
2304                 struct triple *piece;
2305                 piece = LHS(ret, i);
2306                 insert_triple(state, base, piece);
2307                 use_triple(ret, piece);
2308                 use_triple(piece, ret);
2309         }
2310         if (block && (block->first == base)) {
2311                 block->first = ret;
2312         }
2313         return ret;
2314 }
2315
2316 static struct triple *post_triple(struct compile_state *state,
2317         struct triple *base,
2318         int op, struct type *type, struct triple *left, struct triple *right)
2319 {
2320         struct block *block;
2321         struct triple *ret, *next;
2322         int zlhs, i;
2323         /* If I am an OP_PIECE jump to the real instruction */
2324         if (base->op == OP_PIECE) {
2325                 base = MISC(base, 0);
2326         }
2327         /* If I have a left hand side skip over it */
2328         zlhs = base->lhs;
2329         if (zlhs) {
2330                 base = LHS(base, zlhs - 1);
2331         }
2332
2333         block = block_of_triple(state, base);
2334         get_occurance(base->occurance);
2335         ret = build_triple(state, op, type, left, right, base->occurance);
2336         generate_lhs_pieces(state, ret);
2337         if (triple_stores_block(state, ret)) {
2338                 ret->u.block = block;
2339         }
2340         next = base->next;
2341         insert_triple(state, next, ret);
2342         zlhs = ret->lhs;
2343         for(i = 0; i < zlhs; i++) {
2344                 struct triple *piece;
2345                 piece = LHS(ret, i);
2346                 insert_triple(state, next, piece);
2347                 use_triple(ret, piece);
2348                 use_triple(piece, ret);
2349         }
2350         if (block && (block->last == base)) {
2351                 block->last = ret;
2352                 if (zlhs) {
2353                         block->last = LHS(ret, zlhs - 1);
2354                 }
2355         }
2356         return ret;
2357 }
2358
2359 static struct type *reg_type(
2360         struct compile_state *state, struct type *type, int reg);
2361
2362 static void generate_lhs_piece(
2363         struct compile_state *state, struct triple *ins, int index)
2364 {
2365         struct type *piece_type;
2366         struct triple *piece;
2367         get_occurance(ins->occurance);
2368         piece_type = reg_type(state, ins->type, index * REG_SIZEOF_REG);
2369
2370         if ((piece_type->type & TYPE_MASK) == TYPE_BITFIELD) {
2371                 piece_type = piece_type->left;
2372         }
2373 #if 0
2374 {
2375         static void name_of(FILE *fp, struct type *type);
2376         FILE * fp = state->errout;
2377         fprintf(fp, "piece_type(%d): ", index);
2378         name_of(fp, piece_type);
2379         fprintf(fp, "\n");
2380 }
2381 #endif
2382         piece = alloc_triple(state, OP_PIECE, piece_type, -1, -1, ins->occurance);
2383         piece->u.cval  = index;
2384         LHS(ins, piece->u.cval) = piece;
2385         MISC(piece, 0) = ins;
2386 }
2387
2388 static void generate_lhs_pieces(struct compile_state *state, struct triple *ins)
2389 {
2390         int i, zlhs;
2391         zlhs = ins->lhs;
2392         for(i = 0; i < zlhs; i++) {
2393                 generate_lhs_piece(state, ins, i);
2394         }
2395 }
2396
2397 static struct triple *label(struct compile_state *state)
2398 {
2399         /* Labels don't get a type */
2400         struct triple *result;
2401         result = triple(state, OP_LABEL, &void_type, 0, 0);
2402         return result;
2403 }
2404
2405 static struct triple *mkprog(struct compile_state *state, ...)
2406 {
2407         struct triple *prog, *head, *arg;
2408         va_list args;
2409         int i;
2410
2411         head = label(state);
2412         prog = new_triple(state, OP_PROG, &void_type, -1, -1);
2413         RHS(prog, 0) = head;
2414         va_start(args, state);
2415         i = 0;
2416         while((arg = va_arg(args, struct triple *)) != 0) {
2417                 if (++i >= 100) {
2418                         internal_error(state, 0, "too many arguments to mkprog");
2419                 }
2420                 flatten(state, head, arg);
2421         }
2422         va_end(args);
2423         prog->type = head->prev->type;
2424         return prog;
2425 }
2426 static void name_of(FILE *fp, struct type *type);
2427 static void display_triple(FILE *fp, struct triple *ins)
2428 {
2429         struct occurance *ptr;
2430         const char *reg;
2431         char pre, post, vol;
2432         pre = post = vol = ' ';
2433         if (ins) {
2434                 if (ins->id & TRIPLE_FLAG_PRE_SPLIT) {
2435                         pre = '^';
2436                 }
2437                 if (ins->id & TRIPLE_FLAG_POST_SPLIT) {
2438                         post = ',';
2439                 }
2440                 if (ins->id & TRIPLE_FLAG_VOLATILE) {
2441                         vol = 'v';
2442                 }
2443                 reg = arch_reg_str(ID_REG(ins->id));
2444         }
2445         if (ins == 0) {
2446                 fprintf(fp, "(%p) <nothing> ", ins);
2447         }
2448         else if (ins->op == OP_INTCONST) {
2449                 fprintf(fp, "(%p) %c%c%c %-7s %-2d %-10s <0x%08lx>         ",
2450                         ins, pre, post, vol, reg, ins->template_id, tops(ins->op), 
2451                         (unsigned long)(ins->u.cval));
2452         }
2453         else if (ins->op == OP_ADDRCONST) {
2454                 fprintf(fp, "(%p) %c%c%c %-7s %-2d %-10s %-10p <0x%08lx>",
2455                         ins, pre, post, vol, reg, ins->template_id, tops(ins->op), 
2456                         MISC(ins, 0), (unsigned long)(ins->u.cval));
2457         }
2458         else if (ins->op == OP_INDEX) {
2459                 fprintf(fp, "(%p) %c%c%c %-7s %-2d %-10s %-10p <0x%08lx>",
2460                         ins, pre, post, vol, reg, ins->template_id, tops(ins->op), 
2461                         RHS(ins, 0), (unsigned long)(ins->u.cval));
2462         }
2463         else if (ins->op == OP_PIECE) {
2464                 fprintf(fp, "(%p) %c%c%c %-7s %-2d %-10s %-10p <0x%08lx>",
2465                         ins, pre, post, vol, reg, ins->template_id, tops(ins->op), 
2466                         MISC(ins, 0), (unsigned long)(ins->u.cval));
2467         }
2468         else {
2469                 int i, count;
2470                 fprintf(fp, "(%p) %c%c%c %-7s %-2d %-10s", 
2471                         ins, pre, post, vol, reg, ins->template_id, tops(ins->op));
2472                 if (table_ops[ins->op].flags & BITFIELD) {
2473                         fprintf(fp, " <%2d-%2d:%2d>", 
2474                                 ins->u.bitfield.offset,
2475                                 ins->u.bitfield.offset + ins->u.bitfield.size,
2476                                 ins->u.bitfield.size);
2477                 }
2478                 count = TRIPLE_SIZE(ins);
2479                 for(i = 0; i < count; i++) {
2480                         fprintf(fp, " %-10p", ins->param[i]);
2481                 }
2482                 for(; i < 2; i++) {
2483                         fprintf(fp, "           ");
2484                 }
2485         }
2486         if (ins) {
2487                 struct triple_set *user;
2488 #if DEBUG_DISPLAY_TYPES
2489                 fprintf(fp, " <");
2490                 name_of(fp, ins->type);
2491                 fprintf(fp, "> ");
2492 #endif
2493 #if DEBUG_DISPLAY_USES
2494                 fprintf(fp, " [");
2495                 for(user = ins->use; user; user = user->next) {
2496                         fprintf(fp, " %-10p", user->member);
2497                 }
2498                 fprintf(fp, " ]");
2499 #endif
2500                 fprintf(fp, " @");
2501                 for(ptr = ins->occurance; ptr; ptr = ptr->parent) {
2502                         fprintf(fp, " %s,%s:%d.%d",
2503                                 ptr->function, 
2504                                 ptr->filename,
2505                                 ptr->line, 
2506                                 ptr->col);
2507                 }
2508                 if (ins->op == OP_ASM) {
2509                         fprintf(fp, "\n\t%s", ins->u.ainfo->str);
2510                 }
2511         }
2512         fprintf(fp, "\n");
2513         fflush(fp);
2514 }
2515
2516 static int equiv_types(struct type *left, struct type *right);
2517 static void display_triple_changes(
2518         FILE *fp, const struct triple *new, const struct triple *orig)
2519 {
2520
2521         int new_count, orig_count;
2522         new_count = TRIPLE_SIZE(new);
2523         orig_count = TRIPLE_SIZE(orig);
2524         if ((new->op != orig->op) ||
2525                 (new_count != orig_count) ||
2526                 (memcmp(orig->param, new->param,        
2527                         orig_count * sizeof(orig->param[0])) != 0) ||
2528                 (memcmp(&orig->u, &new->u, sizeof(orig->u)) != 0)) 
2529         {
2530                 struct occurance *ptr;
2531                 int i, min_count, indent;
2532                 fprintf(fp, "(%p %p)", new, orig);
2533                 if (orig->op == new->op) {
2534                         fprintf(fp, " %-11s", tops(orig->op));
2535                 } else {
2536                         fprintf(fp, " [%-10s %-10s]", 
2537                                 tops(new->op), tops(orig->op));
2538                 }
2539                 min_count = new_count;
2540                 if (min_count > orig_count) {
2541                         min_count = orig_count;
2542                 }
2543                 for(indent = i = 0; i < min_count; i++) {
2544                         if (orig->param[i] == new->param[i]) {
2545                                 fprintf(fp, " %-11p", 
2546                                         orig->param[i]);
2547                                 indent += 12;
2548                         } else {
2549                                 fprintf(fp, " [%-10p %-10p]",
2550                                         new->param[i], 
2551                                         orig->param[i]);
2552                                 indent += 24;
2553                         }
2554                 }
2555                 for(; i < orig_count; i++) {
2556                         fprintf(fp, " [%-9p]", orig->param[i]);
2557                         indent += 12;
2558                 }
2559                 for(; i < new_count; i++) {
2560                         fprintf(fp, " [%-9p]", new->param[i]);
2561                         indent += 12;
2562                 }
2563                 if ((new->op == OP_INTCONST)||
2564                         (new->op == OP_ADDRCONST)) {
2565                         fprintf(fp, " <0x%08lx>", 
2566                                 (unsigned long)(new->u.cval));
2567                         indent += 13;
2568                 }
2569                 for(;indent < 36; indent++) {
2570                         putc(' ', fp);
2571                 }
2572
2573 #if DEBUG_DISPLAY_TYPES
2574                 fprintf(fp, " <");
2575                 name_of(fp, new->type);
2576                 if (!equiv_types(new->type, orig->type)) {
2577                         fprintf(fp, " -- ");
2578                         name_of(fp, orig->type);
2579                 }
2580                 fprintf(fp, "> ");
2581 #endif
2582
2583                 fprintf(fp, " @");
2584                 for(ptr = orig->occurance; ptr; ptr = ptr->parent) {
2585                         fprintf(fp, " %s,%s:%d.%d",
2586                                 ptr->function, 
2587                                 ptr->filename,
2588                                 ptr->line, 
2589                                 ptr->col);
2590                         
2591                 }
2592                 fprintf(fp, "\n");
2593                 fflush(fp);
2594         }
2595 }
2596
2597 static int triple_is_pure(struct compile_state *state, struct triple *ins, unsigned id)
2598 {
2599         /* Does the triple have no side effects.
2600          * I.e. Rexecuting the triple with the same arguments 
2601          * gives the same value.
2602          */
2603         unsigned pure;
2604         valid_ins(state, ins);
2605         pure = PURE_BITS(table_ops[ins->op].flags);
2606         if ((pure != PURE) && (pure != IMPURE)) {
2607                 internal_error(state, 0, "Purity of %s not known",
2608                         tops(ins->op));
2609         }
2610         return (pure == PURE) && !(id & TRIPLE_FLAG_VOLATILE);
2611 }
2612
2613 static int triple_is_branch_type(struct compile_state *state, 
2614         struct triple *ins, unsigned type)
2615 {
2616         /* Is this one of the passed branch types? */
2617         valid_ins(state, ins);
2618         return (BRANCH_BITS(table_ops[ins->op].flags) == type);
2619 }
2620
2621 static int triple_is_branch(struct compile_state *state, struct triple *ins)
2622 {
2623         /* Is this triple a branch instruction? */
2624         valid_ins(state, ins);
2625         return (BRANCH_BITS(table_ops[ins->op].flags) != 0);
2626 }
2627
2628 static int triple_is_cbranch(struct compile_state *state, struct triple *ins)
2629 {
2630         /* Is this triple a conditional branch instruction? */
2631         return triple_is_branch_type(state, ins, CBRANCH);
2632 }
2633
2634 static int triple_is_ubranch(struct compile_state *state, struct triple *ins)
2635 {
2636         /* Is this triple a unconditional branch instruction? */
2637         unsigned type;
2638         valid_ins(state, ins);
2639         type = BRANCH_BITS(table_ops[ins->op].flags);
2640         return (type != 0) && (type != CBRANCH);
2641 }
2642
2643 static int triple_is_call(struct compile_state *state, struct triple *ins)
2644 {
2645         /* Is this triple a call instruction? */
2646         return triple_is_branch_type(state, ins, CALLBRANCH);
2647 }
2648
2649 static int triple_is_ret(struct compile_state *state, struct triple *ins)
2650 {
2651         /* Is this triple a return instruction? */
2652         return triple_is_branch_type(state, ins, RETBRANCH);
2653 }
2654  
2655 #if DEBUG_ROMCC_WARNING
2656 static int triple_is_simple_ubranch(struct compile_state *state, struct triple *ins)
2657 {
2658         /* Is this triple an unconditional branch and not a call or a
2659          * return? */
2660         return triple_is_branch_type(state, ins, UBRANCH);
2661 }
2662 #endif
2663
2664 static int triple_is_end(struct compile_state *state, struct triple *ins)
2665 {
2666         return triple_is_branch_type(state, ins, ENDBRANCH);
2667 }
2668
2669 static int triple_is_label(struct compile_state *state, struct triple *ins)
2670 {
2671         valid_ins(state, ins);
2672         return (ins->op == OP_LABEL);
2673 }
2674
2675 static struct triple *triple_to_block_start(
2676         struct compile_state *state, struct triple *start)
2677 {
2678         while(!triple_is_branch(state, start->prev) &&
2679                 (!triple_is_label(state, start) || !start->use)) {
2680                 start = start->prev;
2681         }
2682         return start;
2683 }
2684
2685 static int triple_is_def(struct compile_state *state, struct triple *ins)
2686 {
2687         /* This function is used to determine which triples need
2688          * a register.
2689          */
2690         int is_def;
2691         valid_ins(state, ins);
2692         is_def = (table_ops[ins->op].flags & DEF) == DEF;
2693         if (ins->lhs >= 1) {
2694                 is_def = 0;
2695         }
2696         return is_def;
2697 }
2698
2699 static int triple_is_structural(struct compile_state *state, struct triple *ins)
2700 {
2701         int is_structural;
2702         valid_ins(state, ins);
2703         is_structural = (table_ops[ins->op].flags & STRUCTURAL) == STRUCTURAL;
2704         return is_structural;
2705 }
2706
2707 static int triple_is_part(struct compile_state *state, struct triple *ins)
2708 {
2709         int is_part;
2710         valid_ins(state, ins);
2711         is_part = (table_ops[ins->op].flags & PART) == PART;
2712         return is_part;
2713 }
2714
2715 static int triple_is_auto_var(struct compile_state *state, struct triple *ins)
2716 {
2717         return (ins->op == OP_PIECE) && (MISC(ins, 0)->op == OP_ADECL);
2718 }
2719
2720 static struct triple **triple_iter(struct compile_state *state,
2721         size_t count, struct triple **vector,
2722         struct triple *ins, struct triple **last)
2723 {
2724         struct triple **ret;
2725         ret = 0;
2726         if (count) {
2727                 if (!last) {
2728                         ret = vector;
2729                 }
2730                 else if ((last >= vector) && (last < (vector + count - 1))) {
2731                         ret = last + 1;
2732                 }
2733         }
2734         return ret;
2735         
2736 }
2737
2738 static struct triple **triple_lhs(struct compile_state *state,
2739         struct triple *ins, struct triple **last)
2740 {
2741         return triple_iter(state, ins->lhs, &LHS(ins,0), 
2742                 ins, last);
2743 }
2744
2745 static struct triple **triple_rhs(struct compile_state *state,
2746         struct triple *ins, struct triple **last)
2747 {
2748         return triple_iter(state, ins->rhs, &RHS(ins,0), 
2749                 ins, last);
2750 }
2751
2752 static struct triple **triple_misc(struct compile_state *state,
2753         struct triple *ins, struct triple **last)
2754 {
2755         return triple_iter(state, ins->misc, &MISC(ins,0), 
2756                 ins, last);
2757 }
2758
2759 static struct triple **do_triple_targ(struct compile_state *state,
2760         struct triple *ins, struct triple **last, int call_edges, int next_edges)
2761 {
2762         size_t count;
2763         struct triple **ret, **vector;
2764         int next_is_targ;
2765         ret = 0;
2766         count = ins->targ;
2767         next_is_targ = 0;
2768         if (triple_is_cbranch(state, ins)) {
2769                 next_is_targ = 1;
2770         }
2771         if (!call_edges && triple_is_call(state, ins)) {
2772                 count = 0;
2773         }
2774         if (next_edges && triple_is_call(state, ins)) {
2775                 next_is_targ = 1;
2776         }
2777         vector = &TARG(ins, 0);
2778         if (!ret && next_is_targ) {
2779                 if (!last) {
2780                         ret = &ins->next;
2781                 } else if (last == &ins->next) {
2782                         last = 0;
2783                 }
2784         }
2785         if (!ret && count) {
2786                 if (!last) {
2787                         ret = vector;
2788                 }
2789                 else if ((last >= vector) && (last < (vector + count - 1))) {
2790                         ret = last + 1;
2791                 }
2792                 else if (last == vector + count - 1) {
2793                         last = 0;
2794                 }
2795         }
2796         if (!ret && triple_is_ret(state, ins) && call_edges) {
2797                 struct triple_set *use;
2798                 for(use = ins->use; use; use = use->next) {
2799                         if (!triple_is_call(state, use->member)) {
2800                                 continue;
2801                         }
2802                         if (!last) {
2803                                 ret = &use->member->next;
2804                                 break;
2805                         }
2806                         else if (last == &use->member->next) {
2807                                 last = 0;
2808                         }
2809                 }
2810         }
2811         return ret;
2812 }
2813
2814 static struct triple **triple_targ(struct compile_state *state,
2815         struct triple *ins, struct triple **last)
2816 {
2817         return do_triple_targ(state, ins, last, 1, 1);
2818 }
2819
2820 static struct triple **triple_edge_targ(struct compile_state *state,
2821         struct triple *ins, struct triple **last)
2822 {
2823         return do_triple_targ(state, ins, last, 
2824                 state->functions_joined, !state->functions_joined);
2825 }
2826
2827 static struct triple *after_lhs(struct compile_state *state, struct triple *ins)
2828 {
2829         struct triple *next;
2830         int lhs, i;
2831         lhs = ins->lhs;
2832         next = ins->next;
2833         for(i = 0; i < lhs; i++) {
2834                 struct triple *piece;
2835                 piece = LHS(ins, i);
2836                 if (next != piece) {
2837                         internal_error(state, ins, "malformed lhs on %s",
2838                                 tops(ins->op));
2839                 }
2840                 if (next->op != OP_PIECE) {
2841                         internal_error(state, ins, "bad lhs op %s at %d on %s",
2842                                 tops(next->op), i, tops(ins->op));
2843                 }
2844                 if (next->u.cval != i) {
2845                         internal_error(state, ins, "bad u.cval of %d %d expected",
2846                                 next->u.cval, i);
2847                 }
2848                 next = next->next;
2849         }
2850         return next;
2851 }
2852
2853 /* Function piece accessor functions */
2854 static struct triple *do_farg(struct compile_state *state, 
2855         struct triple *func, unsigned index)
2856 {
2857         struct type *ftype;
2858         struct triple *first, *arg;
2859         unsigned i;
2860
2861         ftype = func->type;
2862         if((index < 0) || (index >= (ftype->elements + 2))) {
2863                 internal_error(state, func, "bad argument index: %d", index);
2864         }
2865         first = RHS(func, 0);
2866         arg = first->next;
2867         for(i = 0; i < index; i++, arg = after_lhs(state, arg)) {
2868                 /* do nothing */
2869         }
2870         if (arg->op != OP_ADECL) {
2871                 internal_error(state, 0, "arg not adecl?");
2872         }
2873         return arg;
2874 }
2875 static struct triple *fresult(struct compile_state *state, struct triple *func)
2876 {
2877         return do_farg(state, func, 0);
2878 }
2879 static struct triple *fretaddr(struct compile_state *state, struct triple *func)
2880 {
2881         return do_farg(state, func, 1);
2882 }
2883 static struct triple *farg(struct compile_state *state, 
2884         struct triple *func, unsigned index)
2885 {
2886         return do_farg(state, func, index + 2);
2887 }
2888
2889
2890 static void display_func(struct compile_state *state, FILE *fp, struct triple *func)
2891 {
2892         struct triple *first, *ins;
2893         fprintf(fp, "display_func %s\n", func->type->type_ident->name);
2894         first = ins = RHS(func, 0);
2895         do {
2896                 if (triple_is_label(state, ins) && ins->use) {
2897                         fprintf(fp, "%p:\n", ins);
2898                 }
2899                 display_triple(fp, ins);
2900
2901                 if (triple_is_branch(state, ins)) {
2902                         fprintf(fp, "\n");
2903                 }
2904                 if (ins->next->prev != ins) {
2905                         internal_error(state, ins->next, "bad prev");
2906                 }
2907                 ins = ins->next;
2908         } while(ins != first);
2909 }
2910
2911 static void verify_use(struct compile_state *state,
2912         struct triple *user, struct triple *used)
2913 {
2914         int size, i;
2915         size = TRIPLE_SIZE(user);
2916         for(i = 0; i < size; i++) {
2917                 if (user->param[i] == used) {
2918                         break;
2919                 }
2920         }
2921         if (triple_is_branch(state, user)) {
2922                 if (user->next == used) {
2923                         i = -1;
2924                 }
2925         }
2926         if (i == size) {
2927                 internal_error(state, user, "%s(%p) does not use %s(%p)",
2928                         tops(user->op), user, tops(used->op), used);
2929         }
2930 }
2931
2932 static int find_rhs_use(struct compile_state *state, 
2933         struct triple *user, struct triple *used)
2934 {
2935         struct triple **param;
2936         int size, i;
2937         verify_use(state, user, used);
2938
2939 #if DEBUG_ROMCC_WARNINGS
2940 #warning "AUDIT ME ->rhs"
2941 #endif
2942         size = user->rhs;
2943         param = &RHS(user, 0);
2944         for(i = 0; i < size; i++) {
2945                 if (param[i] == used) {
2946                         return i;
2947                 }
2948         }
2949         return -1;
2950 }
2951
2952 static void free_triple(struct compile_state *state, struct triple *ptr)
2953 {
2954         size_t size;
2955         size = sizeof(*ptr) - sizeof(ptr->param) +
2956                 (sizeof(ptr->param[0])*TRIPLE_SIZE(ptr));
2957         ptr->prev->next = ptr->next;
2958         ptr->next->prev = ptr->prev;
2959         if (ptr->use) {
2960                 internal_error(state, ptr, "ptr->use != 0");
2961         }
2962         put_occurance(ptr->occurance);
2963         memset(ptr, -1, size);
2964         xfree(ptr);
2965 }
2966
2967 static void release_triple(struct compile_state *state, struct triple *ptr)
2968 {
2969         struct triple_set *set, *next;
2970         struct triple **expr;
2971         struct block *block;
2972         if (ptr == &unknown_triple) {
2973                 return;
2974         }
2975         valid_ins(state, ptr);
2976         /* Make certain the we are not the first or last element of a block */
2977         block = block_of_triple(state, ptr);
2978         if (block) {
2979                 if ((block->last == ptr) && (block->first == ptr)) {
2980                         block->last = block->first = 0;
2981                 }
2982                 else if (block->last == ptr) {
2983                         block->last = ptr->prev;
2984                 }
2985                 else if (block->first == ptr) {
2986                         block->first = ptr->next;
2987                 }
2988         }
2989         /* Remove ptr from use chains where it is the user */
2990         expr = triple_rhs(state, ptr, 0);
2991         for(; expr; expr = triple_rhs(state, ptr, expr)) {
2992                 if (*expr) {
2993                         unuse_triple(*expr, ptr);
2994                 }
2995         }
2996         expr = triple_lhs(state, ptr, 0);
2997         for(; expr; expr = triple_lhs(state, ptr, expr)) {
2998                 if (*expr) {
2999                         unuse_triple(*expr, ptr);
3000                 }
3001         }
3002         expr = triple_misc(state, ptr, 0);
3003         for(; expr; expr = triple_misc(state, ptr, expr)) {
3004                 if (*expr) {
3005                         unuse_triple(*expr, ptr);
3006                 }
3007         }
3008         expr = triple_targ(state, ptr, 0);
3009         for(; expr; expr = triple_targ(state, ptr, expr)) {
3010                 if (*expr){
3011                         unuse_triple(*expr, ptr);
3012                 }
3013         }
3014         /* Reomve ptr from use chains where it is used */
3015         for(set = ptr->use; set; set = next) {
3016                 next = set->next;
3017                 valid_ins(state, set->member);
3018                 expr = triple_rhs(state, set->member, 0);
3019                 for(; expr; expr = triple_rhs(state, set->member, expr)) {
3020                         if (*expr == ptr) {
3021                                 *expr = &unknown_triple;
3022                         }
3023                 }
3024                 expr = triple_lhs(state, set->member, 0);
3025                 for(; expr; expr = triple_lhs(state, set->member, expr)) {
3026                         if (*expr == ptr) {
3027                                 *expr = &unknown_triple;
3028                         }
3029                 }
3030                 expr = triple_misc(state, set->member, 0);
3031                 for(; expr; expr = triple_misc(state, set->member, expr)) {
3032                         if (*expr == ptr) {
3033                                 *expr = &unknown_triple;
3034                         }
3035                 }
3036                 expr = triple_targ(state, set->member, 0);
3037                 for(; expr; expr = triple_targ(state, set->member, expr)) {
3038                         if (*expr == ptr) {
3039                                 *expr = &unknown_triple;
3040                         }
3041                 }
3042                 unuse_triple(ptr, set->member);
3043         }
3044         free_triple(state, ptr);
3045 }
3046
3047 static void print_triples(struct compile_state *state);
3048 static void print_blocks(struct compile_state *state, const char *func, FILE *fp);
3049
3050 #define TOK_UNKNOWN       0
3051 #define TOK_SPACE         1
3052 #define TOK_SEMI          2
3053 #define TOK_LBRACE        3
3054 #define TOK_RBRACE        4
3055 #define TOK_COMMA         5
3056 #define TOK_EQ            6
3057 #define TOK_COLON         7
3058 #define TOK_LBRACKET      8
3059 #define TOK_RBRACKET      9
3060 #define TOK_LPAREN        10
3061 #define TOK_RPAREN        11
3062 #define TOK_STAR          12
3063 #define TOK_DOTS          13
3064 #define TOK_MORE          14
3065 #define TOK_LESS          15
3066 #define TOK_TIMESEQ       16
3067 #define TOK_DIVEQ         17
3068 #define TOK_MODEQ         18
3069 #define TOK_PLUSEQ        19
3070 #define TOK_MINUSEQ       20
3071 #define TOK_SLEQ          21
3072 #define TOK_SREQ          22
3073 #define TOK_ANDEQ         23
3074 #define TOK_XOREQ         24
3075 #define TOK_OREQ          25
3076 #define TOK_EQEQ          26
3077 #define TOK_NOTEQ         27
3078 #define TOK_QUEST         28
3079 #define TOK_LOGOR         29
3080 #define TOK_LOGAND        30
3081 #define TOK_OR            31
3082 #define TOK_AND           32
3083 #define TOK_XOR           33
3084 #define TOK_LESSEQ        34
3085 #define TOK_MOREEQ        35
3086 #define TOK_SL            36
3087 #define TOK_SR            37
3088 #define TOK_PLUS          38
3089 #define TOK_MINUS         39
3090 #define TOK_DIV           40
3091 #define TOK_MOD           41
3092 #define TOK_PLUSPLUS      42
3093 #define TOK_MINUSMINUS    43
3094 #define TOK_BANG          44
3095 #define TOK_ARROW         45
3096 #define TOK_DOT           46
3097 #define TOK_TILDE         47
3098 #define TOK_LIT_STRING    48
3099 #define TOK_LIT_CHAR      49
3100 #define TOK_LIT_INT       50
3101 #define TOK_LIT_FLOAT     51
3102 #define TOK_MACRO         52
3103 #define TOK_CONCATENATE   53
3104
3105 #define TOK_IDENT         54
3106 #define TOK_STRUCT_NAME   55
3107 #define TOK_ENUM_CONST    56
3108 #define TOK_TYPE_NAME     57
3109
3110 #define TOK_AUTO          58
3111 #define TOK_BREAK         59
3112 #define TOK_CASE          60
3113 #define TOK_CHAR          61
3114 #define TOK_CONST         62
3115 #define TOK_CONTINUE      63
3116 #define TOK_DEFAULT       64
3117 #define TOK_DO            65
3118 #define TOK_DOUBLE        66
3119 #define TOK_ELSE          67
3120 #define TOK_ENUM          68
3121 #define TOK_EXTERN        69
3122 #define TOK_FLOAT         70
3123 #define TOK_FOR           71
3124 #define TOK_GOTO          72
3125 #define TOK_IF            73
3126 #define TOK_INLINE        74
3127 #define TOK_INT           75
3128 #define TOK_LONG          76
3129 #define TOK_REGISTER      77
3130 #define TOK_RESTRICT      78
3131 #define TOK_RETURN        79
3132 #define TOK_SHORT         80
3133 #define TOK_SIGNED        81
3134 #define TOK_SIZEOF        82
3135 #define TOK_STATIC        83
3136 #define TOK_STRUCT        84
3137 #define TOK_SWITCH        85
3138 #define TOK_TYPEDEF       86
3139 #define TOK_UNION         87
3140 #define TOK_UNSIGNED      88
3141 #define TOK_VOID          89
3142 #define TOK_VOLATILE      90
3143 #define TOK_WHILE         91
3144 #define TOK_ASM           92
3145 #define TOK_ATTRIBUTE     93
3146 #define TOK_ALIGNOF       94
3147 #define TOK_FIRST_KEYWORD TOK_AUTO
3148 #define TOK_LAST_KEYWORD  TOK_ALIGNOF
3149
3150 #define TOK_MDEFINE       100
3151 #define TOK_MDEFINED      101
3152 #define TOK_MUNDEF        102
3153 #define TOK_MINCLUDE      103
3154 #define TOK_MLINE         104
3155 #define TOK_MERROR        105
3156 #define TOK_MWARNING      106
3157 #define TOK_MPRAGMA       107
3158 #define TOK_MIFDEF        108
3159 #define TOK_MIFNDEF       109
3160 #define TOK_MELIF         110
3161 #define TOK_MENDIF        111
3162
3163 #define TOK_FIRST_MACRO   TOK_MDEFINE
3164 #define TOK_LAST_MACRO    TOK_MENDIF
3165          
3166 #define TOK_MIF           112
3167 #define TOK_MELSE         113
3168 #define TOK_MIDENT        114
3169
3170 #define TOK_EOL           115
3171 #define TOK_EOF           116
3172
3173 static const char *tokens[] = {
3174 [TOK_UNKNOWN     ] = ":unknown:",
3175 [TOK_SPACE       ] = ":space:",
3176 [TOK_SEMI        ] = ";",
3177 [TOK_LBRACE      ] = "{",
3178 [TOK_RBRACE      ] = "}",
3179 [TOK_COMMA       ] = ",",
3180 [TOK_EQ          ] = "=",
3181 [TOK_COLON       ] = ":",
3182 [TOK_LBRACKET    ] = "[",
3183 [TOK_RBRACKET    ] = "]",
3184 [TOK_LPAREN      ] = "(",
3185 [TOK_RPAREN      ] = ")",
3186 [TOK_STAR        ] = "*",
3187 [TOK_DOTS        ] = "...",
3188 [TOK_MORE        ] = ">",
3189 [TOK_LESS        ] = "<",
3190 [TOK_TIMESEQ     ] = "*=",
3191 [TOK_DIVEQ       ] = "/=",
3192 [TOK_MODEQ       ] = "%=",
3193 [TOK_PLUSEQ      ] = "+=",
3194 [TOK_MINUSEQ     ] = "-=",
3195 [TOK_SLEQ        ] = "<<=",
3196 [TOK_SREQ        ] = ">>=",
3197 [TOK_ANDEQ       ] = "&=",
3198 [TOK_XOREQ       ] = "^=",
3199 [TOK_OREQ        ] = "|=",
3200 [TOK_EQEQ        ] = "==",
3201 [TOK_NOTEQ       ] = "!=",
3202 [TOK_QUEST       ] = "?",
3203 [TOK_LOGOR       ] = "||",
3204 [TOK_LOGAND      ] = "&&",
3205 [TOK_OR          ] = "|",
3206 [TOK_AND         ] = "&",
3207 [TOK_XOR         ] = "^",
3208 [TOK_LESSEQ      ] = "<=",
3209 [TOK_MOREEQ      ] = ">=",
3210 [TOK_SL          ] = "<<",
3211 [TOK_SR          ] = ">>",
3212 [TOK_PLUS        ] = "+",
3213 [TOK_MINUS       ] = "-",
3214 [TOK_DIV         ] = "/",
3215 [TOK_MOD         ] = "%",
3216 [TOK_PLUSPLUS    ] = "++",
3217 [TOK_MINUSMINUS  ] = "--",
3218 [TOK_BANG        ] = "!",
3219 [TOK_ARROW       ] = "->",
3220 [TOK_DOT         ] = ".",
3221 [TOK_TILDE       ] = "~",
3222 [TOK_LIT_STRING  ] = ":string:",
3223 [TOK_IDENT       ] = ":ident:",
3224 [TOK_TYPE_NAME   ] = ":typename:",
3225 [TOK_LIT_CHAR    ] = ":char:",
3226 [TOK_LIT_INT     ] = ":integer:",
3227 [TOK_LIT_FLOAT   ] = ":float:",
3228 [TOK_MACRO       ] = "#",
3229 [TOK_CONCATENATE ] = "##",
3230
3231 [TOK_AUTO        ] = "auto",
3232 [TOK_BREAK       ] = "break",
3233 [TOK_CASE        ] = "case",
3234 [TOK_CHAR        ] = "char",
3235 [TOK_CONST       ] = "const",
3236 [TOK_CONTINUE    ] = "continue",
3237 [TOK_DEFAULT     ] = "default",
3238 [TOK_DO          ] = "do",
3239 [TOK_DOUBLE      ] = "double",
3240 [TOK_ELSE        ] = "else",
3241 [TOK_ENUM        ] = "enum",
3242 [TOK_EXTERN      ] = "extern",
3243 [TOK_FLOAT       ] = "float",
3244 [TOK_FOR         ] = "for",
3245 [TOK_GOTO        ] = "goto",
3246 [TOK_IF          ] = "if",
3247 [TOK_INLINE      ] = "inline",
3248 [TOK_INT         ] = "int",
3249 [TOK_LONG        ] = "long",
3250 [TOK_REGISTER    ] = "register",
3251 [TOK_RESTRICT    ] = "restrict",
3252 [TOK_RETURN      ] = "return",
3253 [TOK_SHORT       ] = "short",
3254 [TOK_SIGNED      ] = "signed",
3255 [TOK_SIZEOF      ] = "sizeof",
3256 [TOK_STATIC      ] = "static",
3257 [TOK_STRUCT      ] = "struct",
3258 [TOK_SWITCH      ] = "switch",
3259 [TOK_TYPEDEF     ] = "typedef",
3260 [TOK_UNION       ] = "union",
3261 [TOK_UNSIGNED    ] = "unsigned",
3262 [TOK_VOID        ] = "void",
3263 [TOK_VOLATILE    ] = "volatile",
3264 [TOK_WHILE       ] = "while",
3265 [TOK_ASM         ] = "asm",
3266 [TOK_ATTRIBUTE   ] = "__attribute__",
3267 [TOK_ALIGNOF     ] = "__alignof__",
3268
3269 [TOK_MDEFINE     ] = "#define",
3270 [TOK_MDEFINED    ] = "#defined",
3271 [TOK_MUNDEF      ] = "#undef",
3272 [TOK_MINCLUDE    ] = "#include",
3273 [TOK_MLINE       ] = "#line",
3274 [TOK_MERROR      ] = "#error",
3275 [TOK_MWARNING    ] = "#warning",
3276 [TOK_MPRAGMA     ] = "#pragma",
3277 [TOK_MIFDEF      ] = "#ifdef",
3278 [TOK_MIFNDEF     ] = "#ifndef",
3279 [TOK_MELIF       ] = "#elif",
3280 [TOK_MENDIF      ] = "#endif",
3281
3282 [TOK_MIF         ] = "#if",
3283 [TOK_MELSE       ] = "#else",
3284 [TOK_MIDENT      ] = "#:ident:",
3285 [TOK_EOL         ] = "EOL", 
3286 [TOK_EOF         ] = "EOF",
3287 };
3288
3289 static unsigned int hash(const char *str, int str_len)
3290 {
3291         unsigned int hash;
3292         const char *end;
3293         end = str + str_len;
3294         hash = 0;
3295         for(; str < end; str++) {
3296                 hash = (hash *263) + *str;
3297         }
3298         hash = hash & (HASH_TABLE_SIZE -1);
3299         return hash;
3300 }
3301
3302 static struct hash_entry *lookup(
3303         struct compile_state *state, const char *name, int name_len)
3304 {
3305         struct hash_entry *entry;
3306         unsigned int index;
3307         index = hash(name, name_len);
3308         entry = state->hash_table[index];
3309         while(entry && 
3310                 ((entry->name_len != name_len) ||
3311                         (memcmp(entry->name, name, name_len) != 0))) {
3312                 entry = entry->next;
3313         }
3314         if (!entry) {
3315                 char *new_name;
3316                 /* Get a private copy of the name */
3317                 new_name = xmalloc(name_len + 1, "hash_name");
3318                 memcpy(new_name, name, name_len);
3319                 new_name[name_len] = '\0';
3320
3321                 /* Create a new hash entry */
3322                 entry = xcmalloc(sizeof(*entry), "hash_entry");
3323                 entry->next = state->hash_table[index];
3324                 entry->name = new_name;
3325                 entry->name_len = name_len;
3326
3327                 /* Place the new entry in the hash table */
3328                 state->hash_table[index] = entry;
3329         }
3330         return entry;
3331 }
3332
3333 static void ident_to_keyword(struct compile_state *state, struct token *tk)
3334 {
3335         struct hash_entry *entry;
3336         entry = tk->ident;
3337         if (entry && ((entry->tok == TOK_TYPE_NAME) ||
3338                 (entry->tok == TOK_ENUM_CONST) ||
3339                 ((entry->tok >= TOK_FIRST_KEYWORD) && 
3340                         (entry->tok <= TOK_LAST_KEYWORD)))) {
3341                 tk->tok = entry->tok;
3342         }
3343 }
3344
3345 static void ident_to_macro(struct compile_state *state, struct token *tk)
3346 {
3347         struct hash_entry *entry;
3348         entry = tk->ident;
3349         if (!entry)
3350                 return;
3351         if ((entry->tok >= TOK_FIRST_MACRO) && (entry->tok <= TOK_LAST_MACRO)) {
3352                 tk->tok = entry->tok;
3353         }
3354         else if (entry->tok == TOK_IF) {
3355                 tk->tok = TOK_MIF;
3356         }
3357         else if (entry->tok == TOK_ELSE) {
3358                 tk->tok = TOK_MELSE;
3359         }
3360         else {
3361                 tk->tok = TOK_MIDENT;
3362         }
3363 }
3364
3365 static void hash_keyword(
3366         struct compile_state *state, const char *keyword, int tok)
3367 {
3368         struct hash_entry *entry;
3369         entry = lookup(state, keyword, strlen(keyword));
3370         if (entry && entry->tok != TOK_UNKNOWN) {
3371                 die("keyword %s already hashed", keyword);
3372         }
3373         entry->tok  = tok;
3374 }
3375
3376 static void romcc_symbol(
3377         struct compile_state *state, struct hash_entry *ident,
3378         struct symbol **chain, struct triple *def, struct type *type, int depth)
3379 {
3380         struct symbol *sym;
3381         if (*chain && ((*chain)->scope_depth >= depth)) {
3382                 error(state, 0, "%s already defined", ident->name);
3383         }
3384         sym = xcmalloc(sizeof(*sym), "symbol");
3385         sym->ident = ident;
3386         sym->def   = def;
3387         sym->type  = type;
3388         sym->scope_depth = depth;
3389         sym->next = *chain;
3390         *chain    = sym;
3391 }
3392
3393 static void symbol(
3394         struct compile_state *state, struct hash_entry *ident,
3395         struct symbol **chain, struct triple *def, struct type *type)
3396 {
3397         romcc_symbol(state, ident, chain, def, type, state->scope_depth);
3398 }
3399
3400 static void var_symbol(struct compile_state *state, 
3401         struct hash_entry *ident, struct triple *def)
3402 {
3403         if ((def->type->type & TYPE_MASK) == TYPE_PRODUCT) {
3404                 internal_error(state, 0, "bad var type");
3405         }
3406         symbol(state, ident, &ident->sym_ident, def, def->type);
3407 }
3408
3409 static void label_symbol(struct compile_state *state, 
3410         struct hash_entry *ident, struct triple *label, int depth)
3411 {
3412         romcc_symbol(state, ident, &ident->sym_label, label, &void_type, depth);
3413 }
3414
3415 static void start_scope(struct compile_state *state)
3416 {
3417         state->scope_depth++;
3418 }
3419
3420 static void end_scope_syms(struct compile_state *state,
3421         struct symbol **chain, int depth)
3422 {
3423         struct symbol *sym, *next;
3424         sym = *chain;
3425         while(sym && (sym->scope_depth == depth)) {
3426                 next = sym->next;
3427                 xfree(sym);
3428                 sym = next;
3429         }
3430         *chain = sym;
3431 }
3432
3433 static void end_scope(struct compile_state *state)
3434 {
3435         int i;
3436         int depth;
3437         /* Walk through the hash table and remove all symbols
3438          * in the current scope. 
3439          */
3440         depth = state->scope_depth;
3441         for(i = 0; i < HASH_TABLE_SIZE; i++) {
3442                 struct hash_entry *entry;
3443                 entry = state->hash_table[i];
3444                 while(entry) {
3445                         end_scope_syms(state, &entry->sym_label, depth);
3446                         end_scope_syms(state, &entry->sym_tag,   depth);
3447                         end_scope_syms(state, &entry->sym_ident, depth);
3448                         entry = entry->next;
3449                 }
3450         }
3451         state->scope_depth = depth - 1;
3452 }
3453
3454 static void register_keywords(struct compile_state *state)
3455 {
3456         hash_keyword(state, "auto",          TOK_AUTO);
3457         hash_keyword(state, "break",         TOK_BREAK);
3458         hash_keyword(state, "case",          TOK_CASE);
3459         hash_keyword(state, "char",          TOK_CHAR);
3460         hash_keyword(state, "const",         TOK_CONST);
3461         hash_keyword(state, "continue",      TOK_CONTINUE);
3462         hash_keyword(state, "default",       TOK_DEFAULT);
3463         hash_keyword(state, "do",            TOK_DO);
3464         hash_keyword(state, "double",        TOK_DOUBLE);
3465         hash_keyword(state, "else",          TOK_ELSE);
3466         hash_keyword(state, "enum",          TOK_ENUM);
3467         hash_keyword(state, "extern",        TOK_EXTERN);
3468         hash_keyword(state, "float",         TOK_FLOAT);
3469         hash_keyword(state, "for",           TOK_FOR);
3470         hash_keyword(state, "goto",          TOK_GOTO);
3471         hash_keyword(state, "if",            TOK_IF);
3472         hash_keyword(state, "inline",        TOK_INLINE);
3473         hash_keyword(state, "int",           TOK_INT);
3474         hash_keyword(state, "long",          TOK_LONG);
3475         hash_keyword(state, "register",      TOK_REGISTER);
3476         hash_keyword(state, "restrict",      TOK_RESTRICT);
3477         hash_keyword(state, "return",        TOK_RETURN);
3478         hash_keyword(state, "short",         TOK_SHORT);
3479         hash_keyword(state, "signed",        TOK_SIGNED);
3480         hash_keyword(state, "sizeof",        TOK_SIZEOF);
3481         hash_keyword(state, "static",        TOK_STATIC);
3482         hash_keyword(state, "struct",        TOK_STRUCT);
3483         hash_keyword(state, "switch",        TOK_SWITCH);
3484         hash_keyword(state, "typedef",       TOK_TYPEDEF);
3485         hash_keyword(state, "union",         TOK_UNION);
3486         hash_keyword(state, "unsigned",      TOK_UNSIGNED);
3487         hash_keyword(state, "void",          TOK_VOID);
3488         hash_keyword(state, "volatile",      TOK_VOLATILE);
3489         hash_keyword(state, "__volatile__",  TOK_VOLATILE);
3490         hash_keyword(state, "while",         TOK_WHILE);
3491         hash_keyword(state, "asm",           TOK_ASM);
3492         hash_keyword(state, "__asm__",       TOK_ASM);
3493         hash_keyword(state, "__attribute__", TOK_ATTRIBUTE);
3494         hash_keyword(state, "__alignof__",   TOK_ALIGNOF);
3495 }
3496
3497 static void register_macro_keywords(struct compile_state *state)
3498 {
3499         hash_keyword(state, "define",        TOK_MDEFINE);
3500         hash_keyword(state, "defined",       TOK_MDEFINED);
3501         hash_keyword(state, "undef",         TOK_MUNDEF);
3502         hash_keyword(state, "include",       TOK_MINCLUDE);
3503         hash_keyword(state, "line",          TOK_MLINE);
3504         hash_keyword(state, "error",         TOK_MERROR);
3505         hash_keyword(state, "warning",       TOK_MWARNING);
3506         hash_keyword(state, "pragma",        TOK_MPRAGMA);
3507         hash_keyword(state, "ifdef",         TOK_MIFDEF);
3508         hash_keyword(state, "ifndef",        TOK_MIFNDEF);
3509         hash_keyword(state, "elif",          TOK_MELIF);
3510         hash_keyword(state, "endif",         TOK_MENDIF);
3511 }
3512
3513
3514 static void undef_macro(struct compile_state *state, struct hash_entry *ident)
3515 {
3516         if (ident->sym_define != 0) {
3517                 struct macro *macro;
3518                 struct macro_arg *arg, *anext;
3519                 macro = ident->sym_define;
3520                 ident->sym_define = 0;
3521                 
3522                 /* Free the macro arguments... */
3523                 anext = macro->args;
3524                 while(anext) {
3525                         arg = anext;
3526                         anext = arg->next;
3527                         xfree(arg);
3528                 }
3529
3530                 /* Free the macro buffer */
3531                 xfree(macro->buf);
3532
3533                 /* Now free the macro itself */
3534                 xfree(macro);
3535         }
3536 }
3537
3538 static void do_define_macro(struct compile_state *state, 
3539         struct hash_entry *ident, const char *body, 
3540         int argc, struct macro_arg *args)
3541 {
3542         struct macro *macro;
3543         struct macro_arg *arg;
3544         size_t body_len;
3545
3546         /* Find the length of the body */
3547         body_len = strlen(body);
3548         macro = ident->sym_define;
3549         if (macro != 0) {
3550                 int identical_bodies, identical_args;
3551                 struct macro_arg *oarg;
3552                 /* Explicitly allow identical redfinitions of the same macro */
3553                 identical_bodies = 
3554                         (macro->buf_len == body_len) &&
3555                         (memcmp(macro->buf, body, body_len) == 0);
3556                 identical_args = macro->argc == argc;
3557                 oarg = macro->args;
3558                 arg = args;
3559                 while(identical_args && arg) {
3560                         identical_args = oarg->ident == arg->ident;
3561                         arg = arg->next;
3562                         oarg = oarg->next;
3563                 }
3564                 if (identical_bodies && identical_args) {
3565                         xfree(body);
3566                         return;
3567                 }
3568                 error(state, 0, "macro %s already defined\n", ident->name);
3569         }
3570 #if 0
3571         fprintf(state->errout, "#define %s: `%*.*s'\n",
3572                 ident->name, body_len, body_len, body);
3573 #endif
3574         macro = xmalloc(sizeof(*macro), "macro");
3575         macro->ident   = ident;
3576         macro->buf     = body;
3577         macro->buf_len = body_len;
3578         macro->args    = args;
3579         macro->argc    = argc;
3580
3581         ident->sym_define = macro;
3582 }
3583         
3584 static void define_macro(
3585         struct compile_state *state,
3586         struct hash_entry *ident,
3587         const char *body, int body_len,
3588         int argc, struct macro_arg *args)
3589 {
3590         char *buf;
3591         buf = xmalloc(body_len + 1, "macro buf");
3592         memcpy(buf, body, body_len);
3593         buf[body_len] = '\0';
3594         do_define_macro(state, ident, buf, argc, args);
3595 }
3596
3597 static void register_builtin_macro(struct compile_state *state,
3598         const char *name, const char *value)
3599 {
3600         struct hash_entry *ident;
3601
3602         if (value[0] == '(') {
3603                 internal_error(state, 0, "Builtin macros with arguments not supported");
3604         }
3605         ident = lookup(state, name, strlen(name));
3606         define_macro(state, ident, value, strlen(value), -1, 0);
3607 }
3608
3609 static void register_builtin_macros(struct compile_state *state)
3610 {
3611         char buf[30];
3612         char scratch[30];
3613         time_t now;
3614         struct tm *tm;
3615         now = time(NULL);
3616         tm = localtime(&now);
3617
3618         register_builtin_macro(state, "__ROMCC__", VERSION_MAJOR);
3619         register_builtin_macro(state, "__ROMCC_MINOR__", VERSION_MINOR);
3620         register_builtin_macro(state, "__FILE__", "\"This should be the filename\"");
3621         register_builtin_macro(state, "__LINE__", "54321");
3622
3623         strftime(scratch, sizeof(scratch), "%b %e %Y", tm);
3624         sprintf(buf, "\"%s\"", scratch);
3625         register_builtin_macro(state, "__DATE__", buf);
3626
3627         strftime(scratch, sizeof(scratch), "%H:%M:%S", tm);
3628         sprintf(buf, "\"%s\"", scratch);
3629         register_builtin_macro(state, "__TIME__", buf);
3630
3631         /* I can't be a conforming implementation of C :( */
3632         register_builtin_macro(state, "__STDC__", "0");
3633         /* In particular I don't conform to C99 */
3634         register_builtin_macro(state, "__STDC_VERSION__", "199901L");
3635         
3636 }
3637
3638 static void process_cmdline_macros(struct compile_state *state)
3639 {
3640         const char **macro, *name;
3641         struct hash_entry *ident;
3642         for(macro = state->compiler->defines; (name = *macro); macro++) {
3643                 const char *body;
3644                 size_t name_len;
3645
3646                 name_len = strlen(name);
3647                 body = strchr(name, '=');
3648                 if (!body) {
3649                         body = "\0";
3650                 } else {
3651                         name_len = body - name;
3652                         body++;
3653                 }
3654                 ident = lookup(state, name, name_len);
3655                 define_macro(state, ident, body, strlen(body), -1, 0);
3656         }
3657         for(macro = state->compiler->undefs; (name = *macro); macro++) {
3658                 ident = lookup(state, name, strlen(name));
3659                 undef_macro(state, ident);
3660         }
3661 }
3662
3663 static int spacep(int c)
3664 {
3665         int ret = 0;
3666         switch(c) {
3667         case ' ':
3668         case '\t':
3669         case '\f':
3670         case '\v':
3671         case '\r':
3672                 ret = 1;
3673                 break;
3674         }
3675         return ret;
3676 }
3677
3678 static int digitp(int c)
3679 {
3680         int ret = 0;
3681         switch(c) {
3682         case '0': case '1': case '2': case '3': case '4': 
3683         case '5': case '6': case '7': case '8': case '9':
3684                 ret = 1;
3685                 break;
3686         }
3687         return ret;
3688 }
3689 static int digval(int c)
3690 {
3691         int val = -1;
3692         if ((c >= '0') && (c <= '9')) {
3693                 val = c - '0';
3694         }
3695         return val;
3696 }
3697
3698 static int hexdigitp(int c)
3699 {
3700         int ret = 0;
3701         switch(c) {
3702         case '0': case '1': case '2': case '3': case '4': 
3703         case '5': case '6': case '7': case '8': case '9':
3704         case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
3705         case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
3706                 ret = 1;
3707                 break;
3708         }
3709         return ret;
3710 }
3711 static int hexdigval(int c) 
3712 {
3713         int val = -1;
3714         if ((c >= '0') && (c <= '9')) {
3715                 val = c - '0';
3716         }
3717         else if ((c >= 'A') && (c <= 'F')) {
3718                 val = 10 + (c - 'A');
3719         }
3720         else if ((c >= 'a') && (c <= 'f')) {
3721                 val = 10 + (c - 'a');
3722         }
3723         return val;
3724 }
3725
3726 static int octdigitp(int c)
3727 {
3728         int ret = 0;
3729         switch(c) {
3730         case '0': case '1': case '2': case '3': 
3731         case '4': case '5': case '6': case '7':
3732                 ret = 1;
3733                 break;
3734         }
3735         return ret;
3736 }
3737 static int octdigval(int c)
3738 {
3739         int val = -1;
3740         if ((c >= '0') && (c <= '7')) {
3741                 val = c - '0';
3742         }
3743         return val;
3744 }
3745
3746 static int letterp(int c)
3747 {
3748         int ret = 0;
3749         switch(c) {
3750         case 'a': case 'b': case 'c': case 'd': case 'e':
3751         case 'f': case 'g': case 'h': case 'i': case 'j':
3752         case 'k': case 'l': case 'm': case 'n': case 'o':
3753         case 'p': case 'q': case 'r': case 's': case 't':
3754         case 'u': case 'v': case 'w': case 'x': case 'y':
3755         case 'z':
3756         case 'A': case 'B': case 'C': case 'D': case 'E':
3757         case 'F': case 'G': case 'H': case 'I': case 'J':
3758         case 'K': case 'L': case 'M': case 'N': case 'O':
3759         case 'P': case 'Q': case 'R': case 'S': case 'T':
3760         case 'U': case 'V': case 'W': case 'X': case 'Y':
3761         case 'Z':
3762         case '_':
3763                 ret = 1;
3764                 break;
3765         }
3766         return ret;
3767 }
3768
3769 static const char *identifier(const char *str, const char *end)
3770 {
3771         if (letterp(*str)) {
3772                 for(; str < end; str++) {
3773                         int c;
3774                         c = *str;
3775                         if (!letterp(c) && !digitp(c)) {
3776                                 break;
3777                         }
3778                 }
3779         }
3780         return str;
3781 }
3782
3783 static int char_value(struct compile_state *state,
3784         const signed char **strp, const signed char *end)
3785 {
3786         const signed char *str;
3787         int c;
3788         str = *strp;
3789         c = *str++;
3790         if ((c == '\\') && (str < end)) {
3791                 switch(*str) {
3792                 case 'n':  c = '\n'; str++; break;
3793                 case 't':  c = '\t'; str++; break;
3794                 case 'v':  c = '\v'; str++; break;
3795                 case 'b':  c = '\b'; str++; break;
3796                 case 'r':  c = '\r'; str++; break;
3797                 case 'f':  c = '\f'; str++; break;
3798                 case 'a':  c = '\a'; str++; break;
3799                 case '\\': c = '\\'; str++; break;
3800                 case '?':  c = '?';  str++; break;
3801                 case '\'': c = '\''; str++; break;
3802                 case '"':  c = '"';  str++; break;
3803                 case 'x': 
3804                         c = 0;
3805                         str++;
3806                         while((str < end) && hexdigitp(*str)) {
3807                                 c <<= 4;
3808                                 c += hexdigval(*str);
3809                                 str++;
3810                         }
3811                         break;
3812                 case '0': case '1': case '2': case '3': 
3813                 case '4': case '5': case '6': case '7':
3814                         c = 0;
3815                         while((str < end) && octdigitp(*str)) {
3816                                 c <<= 3;
3817                                 c += octdigval(*str);
3818                                 str++;
3819                         }
3820                         break;
3821                 default:
3822                         error(state, 0, "Invalid character constant");
3823                         break;
3824                 }
3825         }
3826         *strp = str;
3827         return c;
3828 }
3829
3830 static const char *next_char(struct file_state *file, const char *pos, int index)
3831 {
3832         const char *end = file->buf + file->size;
3833         while(pos < end) {
3834                 /* Lookup the character */
3835                 int size = 1;
3836                 int c = *pos;
3837                 /* Is this a trigraph? */
3838                 if (file->trigraphs &&
3839                         (c == '?') && ((end - pos) >= 3) && (pos[1] == '?')) 
3840                 {
3841                         switch(pos[2]) {
3842                         case '=': c = '#'; break;
3843                         case '/': c = '\\'; break;
3844                         case '\'': c = '^'; break;
3845                         case '(': c = '['; break;
3846                         case ')': c = ']'; break;
3847                         case '!': c = '!'; break;
3848                         case '<': c = '{'; break;
3849                         case '>': c = '}'; break;
3850                         case '-': c = '~'; break;
3851                         }
3852                         if (c != '?') {
3853                                 size = 3;
3854                         }
3855                 }
3856                 /* Is this an escaped newline? */
3857                 if (file->join_lines &&
3858                         (c == '\\') && (pos + size < end) && ((pos[1] == '\n') || ((pos[1] == '\r') && (pos[2] == '\n'))))
3859                 {
3860                         int cr_offset = ((pos[1] == '\r') && (pos[2] == '\n'))?1:0;
3861                         /* At the start of a line just eat it */
3862                         if (pos == file->pos) {
3863                                 file->line++;
3864                                 file->report_line++;
3865                                 file->line_start = pos + size + 1 + cr_offset;
3866                         }
3867                         pos += size + 1 + cr_offset;
3868                 }
3869                 /* Do I need to ga any farther? */
3870                 else if (index == 0) {
3871                         break;
3872                 }
3873                 /* Process a normal character */
3874                 else {
3875                         pos += size;
3876                         index -= 1;
3877                 }
3878         }
3879         return pos;
3880 }
3881
3882 static int get_char(struct file_state *file, const char *pos)
3883 {
3884         const char *end = file->buf + file->size;
3885         int c;
3886         c = -1;
3887         pos = next_char(file, pos, 0);
3888         if (pos < end) {
3889                 /* Lookup the character */
3890                 c = *pos;
3891                 /* If it is a trigraph get the trigraph value */
3892                 if (file->trigraphs &&
3893                         (c == '?') && ((end - pos) >= 3) && (pos[1] == '?')) 
3894                 {
3895                         switch(pos[2]) {
3896                         case '=': c = '#'; break;
3897                         case '/': c = '\\'; break;
3898                         case '\'': c = '^'; break;
3899                         case '(': c = '['; break;
3900                         case ')': c = ']'; break;
3901                         case '!': c = '!'; break;
3902                         case '<': c = '{'; break;
3903                         case '>': c = '}'; break;
3904                         case '-': c = '~'; break;
3905                         }
3906                 }
3907         }
3908         return c;
3909 }
3910
3911 static void eat_chars(struct file_state *file, const char *targ)
3912 {
3913         const char *pos = file->pos;
3914         while(pos < targ) {
3915                 /* Do we have a newline? */
3916                 if (pos[0] == '\n') {
3917                         file->line++;
3918                         file->report_line++;
3919                         file->line_start = pos + 1;
3920                 }
3921                 pos++;
3922         }
3923         file->pos = pos;
3924 }
3925
3926
3927 static size_t char_strlen(struct file_state *file, const char *src, const char *end)
3928 {
3929         size_t len;
3930         len = 0;
3931         while(src < end) {
3932                 src = next_char(file, src, 1);
3933                 len++;
3934         }
3935         return len;
3936 }
3937
3938 static void char_strcpy(char *dest, 
3939         struct file_state *file, const char *src, const char *end)
3940 {
3941         while(src < end) {
3942                 int c;
3943                 c = get_char(file, src);
3944                 src = next_char(file, src, 1);
3945                 *dest++ = c;
3946         }
3947 }
3948
3949 static char *char_strdup(struct file_state *file, 
3950         const char *start, const char *end, const char *id)
3951 {
3952         char *str;
3953         size_t str_len;
3954         str_len = char_strlen(file, start, end);
3955         str = xcmalloc(str_len + 1, id);
3956         char_strcpy(str, file, start, end);
3957         str[str_len] = '\0';
3958         return str;
3959 }
3960
3961 static const char *after_digits(struct file_state *file, const char *ptr)
3962 {
3963         while(digitp(get_char(file, ptr))) {
3964                 ptr = next_char(file, ptr, 1);
3965         }
3966         return ptr;
3967 }
3968
3969 static const char *after_octdigits(struct file_state *file, const char *ptr)
3970 {
3971         while(octdigitp(get_char(file, ptr))) {
3972                 ptr = next_char(file, ptr, 1);
3973         }
3974         return ptr;
3975 }
3976
3977 static const char *after_hexdigits(struct file_state *file, const char *ptr)
3978 {
3979         while(hexdigitp(get_char(file, ptr))) {
3980                 ptr = next_char(file, ptr, 1);
3981         }
3982         return ptr;
3983 }
3984
3985 static const char *after_alnums(struct file_state *file, const char *ptr)
3986 {
3987         int c;
3988         c = get_char(file, ptr);
3989         while(letterp(c) || digitp(c)) {
3990                 ptr = next_char(file, ptr, 1);
3991                 c = get_char(file, ptr);
3992         }
3993         return ptr;
3994 }
3995
3996 static void save_string(struct file_state *file,
3997         struct token *tk, const char *start, const char *end, const char *id)
3998 {
3999         char *str;
4000
4001         /* Create a private copy of the string */
4002         str = char_strdup(file, start, end, id);
4003
4004         /* Store the copy in the token */
4005         tk->val.str = str;
4006         tk->str_len = strlen(str);
4007 }
4008
4009 static void raw_next_token(struct compile_state *state, 
4010         struct file_state *file, struct token *tk)
4011 {
4012         const char *token;
4013         int c, c1, c2, c3;
4014         const char *tokp;
4015         int eat;
4016         int tok;
4017
4018         tk->str_len = 0;
4019         tk->ident = 0;
4020         token = tokp = next_char(file, file->pos, 0);
4021         tok = TOK_UNKNOWN;
4022         c  = get_char(file, tokp);
4023         tokp = next_char(file, tokp, 1);
4024         eat = 0;
4025         c1 = get_char(file, tokp);
4026         c2 = get_char(file, next_char(file, tokp, 1));
4027         c3 = get_char(file, next_char(file, tokp, 2));
4028
4029         /* The end of the file */
4030         if (c == -1) {
4031                 tok = TOK_EOF;
4032         }
4033         /* Whitespace */
4034         else if (spacep(c)) {
4035                 tok = TOK_SPACE;
4036                 while (spacep(get_char(file, tokp))) {
4037                         tokp = next_char(file, tokp, 1);
4038                 }
4039         }
4040         /* EOL Comments */
4041         else if ((c == '/') && (c1 == '/')) {
4042                 tok = TOK_SPACE;
4043                 tokp = next_char(file, tokp, 1);
4044                 while((c = get_char(file, tokp)) != -1) {
4045                         /* Advance to the next character only after we verify
4046                          * the current character is not a newline.  
4047                          * EOL is special to the preprocessor so we don't
4048                          * want to loose any.
4049                          */
4050                         if (c == '\n') {
4051                                 break;
4052                         }
4053                         tokp = next_char(file, tokp, 1);
4054                 }
4055         }
4056         /* Comments */
4057         else if ((c == '/') && (c1 == '*')) {
4058                 tokp = next_char(file, tokp, 2);
4059                 c = c2;
4060                 while((c1 = get_char(file, tokp)) != -1) {
4061                         tokp = next_char(file, tokp, 1);
4062                         if ((c == '*') && (c1 == '/')) {
4063                                 tok = TOK_SPACE;
4064                                 break;
4065                         }
4066                         c = c1;
4067                 }
4068                 if (tok == TOK_UNKNOWN) {
4069                         error(state, 0, "unterminated comment");
4070                 }
4071         }
4072         /* string constants */
4073         else if ((c == '"') || ((c == 'L') && (c1 == '"'))) {
4074                 int wchar, multiline;
4075
4076                 wchar = 0;
4077                 multiline = 0;
4078                 if (c == 'L') {
4079                         wchar = 1;
4080                         tokp = next_char(file, tokp, 1);
4081                 }
4082                 while((c = get_char(file, tokp)) != -1) {
4083                         tokp = next_char(file, tokp, 1);
4084                         if (c == '\n') {
4085                                 multiline = 1;
4086                         }
4087                         else if (c == '\\') {
4088                                 tokp = next_char(file, tokp, 1);
4089                         }
4090                         else if (c == '"') {
4091                                 tok = TOK_LIT_STRING;
4092                                 break;
4093                         }
4094                 }
4095                 if (tok == TOK_UNKNOWN) {
4096                         error(state, 0, "unterminated string constant");
4097                 }
4098                 if (multiline) {
4099                         warning(state, 0, "multiline string constant");
4100                 }
4101
4102                 /* Save the string value */
4103                 save_string(file, tk, token, tokp, "literal string");
4104         }
4105         /* character constants */
4106         else if ((c == '\'') || ((c == 'L') && (c1 == '\''))) {
4107                 int wchar, multiline;
4108
4109                 wchar = 0;
4110                 multiline = 0;
4111                 if (c == 'L') {
4112                         wchar = 1;
4113                         tokp = next_char(file, tokp, 1);
4114                 }
4115                 while((c = get_char(file, tokp)) != -1) {
4116                         tokp = next_char(file, tokp, 1);
4117                         if (c == '\n') {
4118                                 multiline = 1;
4119                         }
4120                         else if (c == '\\') {
4121                                 tokp = next_char(file, tokp, 1);
4122                         }
4123                         else if (c == '\'') {
4124                                 tok = TOK_LIT_CHAR;
4125                                 break;
4126                         }
4127                 }
4128                 if (tok == TOK_UNKNOWN) {
4129                         error(state, 0, "unterminated character constant");
4130                 }
4131                 if (multiline) {
4132                         warning(state, 0, "multiline character constant");
4133                 }
4134
4135                 /* Save the character value */
4136                 save_string(file, tk, token, tokp, "literal character");
4137         }
4138         /* integer and floating constants 
4139          * Integer Constants
4140          * {digits}
4141          * 0[Xx]{hexdigits}
4142          * 0{octdigit}+
4143          * 
4144          * Floating constants
4145          * {digits}.{digits}[Ee][+-]?{digits}
4146          * {digits}.{digits}
4147          * {digits}[Ee][+-]?{digits}
4148          * .{digits}[Ee][+-]?{digits}
4149          * .{digits}
4150          */
4151         else if (digitp(c) || ((c == '.') && (digitp(c1)))) {
4152                 const char *next;
4153                 int is_float;
4154                 int cn;
4155                 is_float = 0;
4156                 if (c != '.') {
4157                         next = after_digits(file, tokp);
4158                 }
4159                 else {
4160                         next = token;
4161                 }
4162                 cn = get_char(file, next);
4163                 if (cn == '.') {
4164                         next = next_char(file, next, 1);
4165                         next = after_digits(file, next);
4166                         is_float = 1;
4167                 }
4168                 cn = get_char(file, next);
4169                 if ((cn == 'e') || (cn == 'E')) {
4170                         const char *new;
4171                         next = next_char(file, next, 1);
4172                         cn = get_char(file, next);
4173                         if ((cn == '+') || (cn == '-')) {
4174                                 next = next_char(file, next, 1);
4175                         }
4176                         new = after_digits(file, next);
4177                         is_float |= (new != next);
4178                         next = new;
4179                 }
4180                 if (is_float) {
4181                         tok = TOK_LIT_FLOAT;
4182                         cn = get_char(file, next);
4183                         if ((cn  == 'f') || (cn == 'F') || (cn == 'l') || (cn == 'L')) {
4184                                 next = next_char(file, next, 1);
4185                         }
4186                 }
4187                 if (!is_float && digitp(c)) {
4188                         tok = TOK_LIT_INT;
4189                         if ((c == '0') && ((c1 == 'x') || (c1 == 'X'))) {
4190                                 next = next_char(file, tokp, 1);
4191                                 next = after_hexdigits(file, next);
4192                         }
4193                         else if (c == '0') {
4194                                 next = after_octdigits(file, tokp);
4195                         }
4196                         else {
4197                                 next = after_digits(file, tokp);
4198                         }
4199                         /* crazy integer suffixes */
4200                         cn = get_char(file, next);
4201                         if ((cn == 'u') || (cn == 'U')) {
4202                                 next = next_char(file, next, 1);
4203                                 cn = get_char(file, next);
4204                                 if ((cn == 'l') || (cn == 'L')) {
4205                                         next = next_char(file, next, 1);
4206                                         cn = get_char(file, next);
4207                                 }
4208                                 if ((cn == 'l') || (cn == 'L')) {
4209                                         next = next_char(file, next, 1);
4210                                 }
4211                         }
4212                         else if ((cn == 'l') || (cn == 'L')) {
4213                                 next = next_char(file, next, 1);
4214                                 cn = get_char(file, next);
4215                                 if ((cn == 'l') || (cn == 'L')) {
4216                                         next = next_char(file, next, 1);
4217                                         cn = get_char(file, next);
4218                                 }
4219                                 if ((cn == 'u') || (cn == 'U')) {
4220                                         next = next_char(file, next, 1);
4221                                 }
4222                         }
4223                 }
4224                 tokp = next;
4225
4226                 /* Save the integer/floating point value */
4227                 save_string(file, tk, token, tokp, "literal number");
4228         }
4229         /* identifiers */
4230         else if (letterp(c)) {
4231                 tok = TOK_IDENT;
4232
4233                 /* Find and save the identifier string */
4234                 tokp = after_alnums(file, tokp);
4235                 save_string(file, tk, token, tokp, "identifier");
4236
4237                 /* Look up to see which identifier it is */
4238                 tk->ident = lookup(state, tk->val.str, tk->str_len);
4239
4240                 /* Free the identifier string */
4241                 tk->str_len = 0;
4242                 xfree(tk->val.str);
4243
4244                 /* See if this identifier can be macro expanded */
4245                 tk->val.notmacro = 0;
4246                 c = get_char(file, tokp);
4247                 if (c == '$') {
4248                         tokp = next_char(file, tokp, 1);
4249                         tk->val.notmacro = 1;
4250                 }
4251         }
4252         /* C99 alternate macro characters */
4253         else if ((c == '%') && (c1 == ':') && (c2 == '%') && (c3 == ':')) { 
4254                 eat += 3;
4255                 tok = TOK_CONCATENATE; 
4256         }
4257         else if ((c == '.') && (c1 == '.') && (c2 == '.')) { eat += 2; tok = TOK_DOTS; }
4258         else if ((c == '<') && (c1 == '<') && (c2 == '=')) { eat += 2; tok = TOK_SLEQ; }
4259         else if ((c == '>') && (c1 == '>') && (c2 == '=')) { eat += 2; tok = TOK_SREQ; }
4260         else if ((c == '*') && (c1 == '=')) { eat += 1; tok = TOK_TIMESEQ; }
4261         else if ((c == '/') && (c1 == '=')) { eat += 1; tok = TOK_DIVEQ; }
4262         else if ((c == '%') && (c1 == '=')) { eat += 1; tok = TOK_MODEQ; }
4263         else if ((c == '+') && (c1 == '=')) { eat += 1; tok = TOK_PLUSEQ; }
4264         else if ((c == '-') && (c1 == '=')) { eat += 1; tok = TOK_MINUSEQ; }
4265         else if ((c == '&') && (c1 == '=')) { eat += 1; tok = TOK_ANDEQ; }
4266         else if ((c == '^') && (c1 == '=')) { eat += 1; tok = TOK_XOREQ; }
4267         else if ((c == '|') && (c1 == '=')) { eat += 1; tok = TOK_OREQ; }
4268         else if ((c == '=') && (c1 == '=')) { eat += 1; tok = TOK_EQEQ; }
4269         else if ((c == '!') && (c1 == '=')) { eat += 1; tok = TOK_NOTEQ; }
4270         else if ((c == '|') && (c1 == '|')) { eat += 1; tok = TOK_LOGOR; }
4271         else if ((c == '&') && (c1 == '&')) { eat += 1; tok = TOK_LOGAND; }
4272         else if ((c == '<') && (c1 == '=')) { eat += 1; tok = TOK_LESSEQ; }
4273         else if ((c == '>') && (c1 == '=')) { eat += 1; tok = TOK_MOREEQ; }
4274         else if ((c == '<') && (c1 == '<')) { eat += 1; tok = TOK_SL; }
4275         else if ((c == '>') && (c1 == '>')) { eat += 1; tok = TOK_SR; }
4276         else if ((c == '+') && (c1 == '+')) { eat += 1; tok = TOK_PLUSPLUS; }
4277         else if ((c == '-') && (c1 == '-')) { eat += 1; tok = TOK_MINUSMINUS; }
4278         else if ((c == '-') && (c1 == '>')) { eat += 1; tok = TOK_ARROW; }
4279         else if ((c == '<') && (c1 == ':')) { eat += 1; tok = TOK_LBRACKET; }
4280         else if ((c == ':') && (c1 == '>')) { eat += 1; tok = TOK_RBRACKET; }
4281         else if ((c == '<') && (c1 == '%')) { eat += 1; tok = TOK_LBRACE; }
4282         else if ((c == '%') && (c1 == '>')) { eat += 1; tok = TOK_RBRACE; }
4283         else if ((c == '%') && (c1 == ':')) { eat += 1; tok = TOK_MACRO; }
4284         else if ((c == '#') && (c1 == '#')) { eat += 1; tok = TOK_CONCATENATE; }
4285         else if (c == ';') { tok = TOK_SEMI; }
4286         else if (c == '{') { tok = TOK_LBRACE; }
4287         else if (c == '}') { tok = TOK_RBRACE; }
4288         else if (c == ',') { tok = TOK_COMMA; }
4289         else if (c == '=') { tok = TOK_EQ; }
4290         else if (c == ':') { tok = TOK_COLON; }
4291         else if (c == '[') { tok = TOK_LBRACKET; }
4292         else if (c == ']') { tok = TOK_RBRACKET; }
4293         else if (c == '(') { tok = TOK_LPAREN; }
4294         else if (c == ')') { tok = TOK_RPAREN; }
4295         else if (c == '*') { tok = TOK_STAR; }
4296         else if (c == '>') { tok = TOK_MORE; }
4297         else if (c == '<') { tok = TOK_LESS; }
4298         else if (c == '?') { tok = TOK_QUEST; }
4299         else if (c == '|') { tok = TOK_OR; }
4300         else if (c == '&') { tok = TOK_AND; }
4301         else if (c == '^') { tok = TOK_XOR; }
4302         else if (c == '+') { tok = TOK_PLUS; }
4303         else if (c == '-') { tok = TOK_MINUS; }
4304         else if (c == '/') { tok = TOK_DIV; }
4305         else if (c == '%') { tok = TOK_MOD; }
4306         else if (c == '!') { tok = TOK_BANG; }
4307         else if (c == '.') { tok = TOK_DOT; }
4308         else if (c == '~') { tok = TOK_TILDE; }
4309         else if (c == '#') { tok = TOK_MACRO; }
4310         else if (c == '\n') { tok = TOK_EOL; }
4311
4312         tokp = next_char(file, tokp, eat);
4313         eat_chars(file, tokp);
4314         tk->tok = tok;
4315         tk->pos = token;
4316 }
4317
4318 static void check_tok(struct compile_state *state, struct token *tk, int tok)
4319 {
4320         if (tk->tok != tok) {
4321                 const char *name1, *name2;
4322                 name1 = tokens[tk->tok];
4323                 name2 = "";
4324                 if ((tk->tok == TOK_IDENT) || (tk->tok == TOK_MIDENT)) {
4325                         name2 = tk->ident->name;
4326                 }
4327                 error(state, 0, "\tfound %s %s expected %s",
4328                         name1, name2, tokens[tok]);
4329         }
4330 }
4331
4332 struct macro_arg_value {
4333         struct hash_entry *ident;
4334         char *value;
4335         size_t len;
4336 };
4337 static struct macro_arg_value *read_macro_args(
4338         struct compile_state *state, struct macro *macro, 
4339         struct file_state *file, struct token *tk)
4340 {
4341         struct macro_arg_value *argv;
4342         struct macro_arg *arg;
4343         int paren_depth;
4344         int i;
4345
4346         if (macro->argc == 0) {
4347                 do {
4348                         raw_next_token(state, file, tk);
4349                 } while(tk->tok == TOK_SPACE);
4350                 return NULL;
4351         }
4352         argv = xcmalloc(sizeof(*argv) * macro->argc, "macro args");
4353         for(i = 0, arg = macro->args; arg; arg = arg->next, i++) {
4354                 argv[i].value = 0;
4355                 argv[i].len   = 0;
4356                 argv[i].ident = arg->ident;
4357         }
4358         paren_depth = 0;
4359         i = 0;
4360         
4361         for(;;) {
4362                 const char *start;
4363                 size_t len;
4364                 start = file->pos;
4365                 raw_next_token(state, file, tk);
4366                 
4367                 if (!paren_depth && (tk->tok == TOK_COMMA) &&
4368                         (argv[i].ident != state->i___VA_ARGS__)) 
4369                 {
4370                         i++;
4371                         if (i >= macro->argc) {
4372                                 error(state, 0, "too many args to %s\n",
4373                                         macro->ident->name);
4374                         }
4375                         continue;
4376                 }
4377                 
4378                 if (tk->tok == TOK_LPAREN) {
4379                         paren_depth++;
4380                 }
4381                 
4382                 if (tk->tok == TOK_RPAREN) {
4383                         if (paren_depth == 0) {
4384                                 break;
4385                         }
4386                         paren_depth--;
4387                 }
4388                 if (tk->tok == TOK_EOF) {
4389                         error(state, 0, "End of file encountered while parsing macro arguments");
4390                 }
4391
4392                 len = char_strlen(file, start, file->pos);
4393                 argv[i].value = xrealloc(
4394                         argv[i].value, argv[i].len + len, "macro args");
4395                 char_strcpy((char *)argv[i].value + argv[i].len, file, start, file->pos);
4396                 argv[i].len += len;
4397         }
4398         if (i != macro->argc -1) {
4399                 error(state, 0, "missing %s arg %d\n", 
4400                         macro->ident->name, i +2);
4401         }
4402         return argv;
4403 }
4404
4405
4406 static void free_macro_args(struct macro *macro, struct macro_arg_value *argv)
4407 {
4408         int i;
4409         for(i = 0; i < macro->argc; i++) {
4410                 xfree(argv[i].value);
4411         }
4412         xfree(argv);
4413 }
4414
4415 struct macro_buf {
4416         char *str;
4417         size_t len, pos;
4418 };
4419
4420 static void grow_macro_buf(struct compile_state *state,
4421         const char *id, struct macro_buf *buf,
4422         size_t grow)
4423 {
4424         if ((buf->pos + grow) >= buf->len) {
4425                 buf->str = xrealloc(buf->str, buf->len + grow, id);
4426                 buf->len += grow;
4427         }
4428 }
4429
4430 static void append_macro_text(struct compile_state *state,
4431         const char *id, struct macro_buf *buf,
4432         const char *fstart, size_t flen)
4433 {
4434         grow_macro_buf(state, id, buf, flen);
4435         memcpy(buf->str + buf->pos, fstart, flen);
4436 #if 0
4437         fprintf(state->errout, "append: `%*.*s' `%*.*s'\n",
4438                 buf->pos, buf->pos, buf->str,
4439                 flen, flen, buf->str + buf->pos);
4440 #endif
4441         buf->pos += flen;
4442 }
4443
4444
4445 static void append_macro_chars(struct compile_state *state,
4446         const char *id, struct macro_buf *buf,
4447         struct file_state *file, const char *start, const char *end)
4448 {
4449         size_t flen;
4450         flen = char_strlen(file, start, end);
4451         grow_macro_buf(state, id, buf, flen);
4452         char_strcpy(buf->str + buf->pos, file, start, end);
4453 #if 0
4454         fprintf(state->errout, "append: `%*.*s' `%*.*s'\n",
4455                 buf->pos, buf->pos, buf->str,
4456                 flen, flen, buf->str + buf->pos);
4457 #endif
4458         buf->pos += flen;
4459 }
4460
4461 static int compile_macro(struct compile_state *state, 
4462         struct file_state **filep, struct token *tk);
4463
4464 static void macro_expand_args(struct compile_state *state, 
4465         struct macro *macro, struct macro_arg_value *argv, struct token *tk)
4466 {
4467         int i;
4468         
4469         for(i = 0; i < macro->argc; i++) {
4470                 struct file_state fmacro, *file;
4471                 struct macro_buf buf;
4472
4473                 fmacro.prev        = 0;
4474                 fmacro.basename    = argv[i].ident->name;
4475                 fmacro.dirname     = "";
4476                 fmacro.buf         = (char *)argv[i].value;
4477                 fmacro.size        = argv[i].len;
4478                 fmacro.pos         = fmacro.buf;
4479                 fmacro.line        = 1;
4480                 fmacro.line_start  = fmacro.buf;
4481                 fmacro.report_line = 1;
4482                 fmacro.report_name = fmacro.basename;
4483                 fmacro.report_dir  = fmacro.dirname;
4484                 fmacro.macro       = 1;
4485                 fmacro.trigraphs   = 0;
4486                 fmacro.join_lines  = 0;
4487
4488                 buf.len = argv[i].len;
4489                 buf.str = xmalloc(buf.len, argv[i].ident->name);
4490                 buf.pos = 0;
4491
4492                 file = &fmacro;
4493                 for(;;) {
4494                         raw_next_token(state, file, tk);
4495                         
4496                         /* If we have recursed into another macro body
4497                          * get out of it.
4498                          */
4499                         if (tk->tok == TOK_EOF) {
4500                                 struct file_state *old;
4501                                 old = file;
4502                                 file = file->prev;
4503                                 if (!file) {
4504                                         break;
4505                                 }
4506                                 /* old->basename is used keep it */
4507                                 xfree(old->dirname);
4508                                 xfree(old->buf);
4509                                 xfree(old);
4510                                 continue;
4511                         }
4512                         else if (tk->ident && tk->ident->sym_define) {
4513                                 if (compile_macro(state, &file, tk)) {
4514                                         continue;
4515                                 }
4516                         }
4517
4518                         append_macro_chars(state, macro->ident->name, &buf,
4519                                 file, tk->pos, file->pos);
4520                 }
4521                         
4522                 xfree(argv[i].value);
4523                 argv[i].value = buf.str;
4524                 argv[i].len   = buf.pos;
4525         }
4526         return;
4527 }
4528
4529 static void expand_macro(struct compile_state *state,
4530         struct macro *macro, struct macro_buf *buf,
4531         struct macro_arg_value *argv, struct token *tk)
4532 {
4533         struct file_state fmacro;
4534         const char space[] = " ";
4535         const char *fstart;
4536         size_t flen;
4537         int i, j;
4538
4539         /* Place the macro body in a dummy file */
4540         fmacro.prev        = 0;
4541         fmacro.basename    = macro->ident->name;
4542         fmacro.dirname     = "";
4543         fmacro.buf         = macro->buf;
4544         fmacro.size        = macro->buf_len;
4545         fmacro.pos         = fmacro.buf;
4546         fmacro.line        = 1;
4547         fmacro.line_start  = fmacro.buf;
4548         fmacro.report_line = 1;
4549         fmacro.report_name = fmacro.basename;
4550         fmacro.report_dir  = fmacro.dirname;
4551         fmacro.macro       = 1;
4552         fmacro.trigraphs   = 0;
4553         fmacro.join_lines  = 0;
4554         
4555         /* Allocate a buffer to hold the macro expansion */
4556         buf->len = macro->buf_len + 3;
4557         buf->str = xmalloc(buf->len, macro->ident->name);
4558         buf->pos = 0;
4559         
4560         fstart = fmacro.pos;
4561         raw_next_token(state, &fmacro, tk);
4562         while(tk->tok != TOK_EOF) {
4563                 flen = fmacro.pos - fstart;
4564                 switch(tk->tok) {
4565                 case TOK_IDENT:
4566                         for(i = 0; i < macro->argc; i++) {
4567                                 if (argv[i].ident == tk->ident) {
4568                                         break;
4569                                 }
4570                         }
4571                         if (i >= macro->argc) {
4572                                 break;
4573                         }
4574                         /* Substitute macro parameter */
4575                         fstart = argv[i].value;
4576                         flen   = argv[i].len;
4577                         break;
4578                 case TOK_MACRO:
4579                         if (macro->argc < 0) {
4580                                 break;
4581                         }
4582                         do {
4583                                 raw_next_token(state, &fmacro, tk);
4584                         } while(tk->tok == TOK_SPACE);
4585                         check_tok(state, tk, TOK_IDENT);
4586                         for(i = 0; i < macro->argc; i++) {
4587                                 if (argv[i].ident == tk->ident) {
4588                                         break;
4589                                 }
4590                         }
4591                         if (i >= macro->argc) {
4592                                 error(state, 0, "parameter `%s' not found",
4593                                         tk->ident->name);
4594                         }
4595                         /* Stringize token */
4596                         append_macro_text(state, macro->ident->name, buf, "\"", 1);
4597                         for(j = 0; j < argv[i].len; j++) {
4598                                 char *str = argv[i].value + j;
4599                                 size_t len = 1;
4600                                 if (*str == '\\') {
4601                                         str = "\\";
4602                                         len = 2;
4603                                 } 
4604                                 else if (*str == '"') {
4605                                         str = "\\\"";
4606                                         len = 2;
4607                                 }
4608                                 append_macro_text(state, macro->ident->name, buf, str, len);
4609                         }
4610                         append_macro_text(state, macro->ident->name, buf, "\"", 1);
4611                         fstart = 0;
4612                         flen   = 0;
4613                         break;
4614                 case TOK_CONCATENATE:
4615                         /* Concatenate tokens */
4616                         /* Delete the previous whitespace token */
4617                         if (buf->str[buf->pos - 1] == ' ') {
4618                                 buf->pos -= 1;
4619                         }
4620                         /* Skip the next sequence of whitspace tokens */
4621                         do {
4622                                 fstart = fmacro.pos;
4623                                 raw_next_token(state, &fmacro, tk);
4624                         } while(tk->tok == TOK_SPACE);
4625                         /* Restart at the top of the loop.
4626                          * I need to process the non white space token.
4627                          */
4628                         continue;
4629                         break;
4630                 case TOK_SPACE:
4631                         /* Collapse multiple spaces into one */
4632                         if (buf->str[buf->pos - 1] != ' ') {
4633                                 fstart = space;
4634                                 flen   = 1;
4635                         } else {
4636                                 fstart = 0;
4637                                 flen   = 0;
4638                         }
4639                         break;
4640                 default:
4641                         break;
4642                 }
4643
4644                 append_macro_text(state, macro->ident->name, buf, fstart, flen);
4645                 
4646                 fstart = fmacro.pos;
4647                 raw_next_token(state, &fmacro, tk);
4648         }
4649 }
4650
4651 static void tag_macro_name(struct compile_state *state,
4652         struct macro *macro, struct macro_buf *buf,
4653         struct token *tk)
4654 {
4655         /* Guard all instances of the macro name in the replacement
4656          * text from further macro expansion.
4657          */
4658         struct file_state fmacro;
4659         const char *fstart;
4660         size_t flen;
4661
4662         /* Put the old macro expansion buffer in a file */
4663         fmacro.prev        = 0;
4664         fmacro.basename    = macro->ident->name;
4665         fmacro.dirname     = "";
4666         fmacro.buf         = buf->str;
4667         fmacro.size        = buf->pos;
4668         fmacro.pos         = fmacro.buf;
4669         fmacro.line        = 1;
4670         fmacro.line_start  = fmacro.buf;
4671         fmacro.report_line = 1;
4672         fmacro.report_name = fmacro.basename;
4673         fmacro.report_dir  = fmacro.dirname;
4674         fmacro.macro       = 1;
4675         fmacro.trigraphs   = 0;
4676         fmacro.join_lines  = 0;
4677         
4678         /* Allocate a new macro expansion buffer */
4679         buf->len = macro->buf_len + 3;
4680         buf->str = xmalloc(buf->len, macro->ident->name);
4681         buf->pos = 0;
4682         
4683         fstart = fmacro.pos;
4684         raw_next_token(state, &fmacro, tk);
4685         while(tk->tok != TOK_EOF) {
4686                 flen = fmacro.pos - fstart;
4687                 if ((tk->tok == TOK_IDENT) &&
4688                         (tk->ident == macro->ident) &&
4689                         (tk->val.notmacro == 0)) 
4690                 {
4691                         append_macro_text(state, macro->ident->name, buf, fstart, flen);
4692                         fstart = "$";
4693                         flen   = 1;
4694                 }
4695
4696                 append_macro_text(state, macro->ident->name, buf, fstart, flen);
4697                 
4698                 fstart = fmacro.pos;
4699                 raw_next_token(state, &fmacro, tk);
4700         }
4701         xfree(fmacro.buf);
4702 }
4703
4704 static int compile_macro(struct compile_state *state, 
4705         struct file_state **filep, struct token *tk)
4706 {
4707         struct file_state *file;
4708         struct hash_entry *ident;
4709         struct macro *macro;
4710         struct macro_arg_value *argv;
4711         struct macro_buf buf;
4712
4713 #if 0
4714         fprintf(state->errout, "macro: %s\n", tk->ident->name);
4715 #endif
4716         ident = tk->ident;
4717         macro = ident->sym_define;
4718
4719         /* If this token comes from a macro expansion ignore it */
4720         if (tk->val.notmacro) {
4721                 return 0;
4722         }
4723         /* If I am a function like macro and the identifier is not followed
4724          * by a left parenthesis, do nothing.
4725          */
4726         if ((macro->argc >= 0) && (get_char(*filep, (*filep)->pos) != '(')) {
4727                 return 0;
4728         }
4729
4730         /* Read in the macro arguments */
4731         argv = 0;
4732         if (macro->argc >= 0) {
4733                 raw_next_token(state, *filep, tk);
4734                 check_tok(state, tk, TOK_LPAREN);
4735
4736                 argv = read_macro_args(state, macro, *filep, tk);
4737
4738                 check_tok(state, tk, TOK_RPAREN);
4739         }
4740         /* Macro expand the macro arguments */
4741         macro_expand_args(state, macro, argv, tk);
4742
4743         buf.str = 0;
4744         buf.len = 0;
4745         buf.pos = 0;
4746         if (ident == state->i___FILE__) {
4747                 buf.len = strlen(state->file->basename) + 1 + 2 + 3;
4748                 buf.str = xmalloc(buf.len, ident->name);
4749                 sprintf(buf.str, "\"%s\"", state->file->basename);
4750                 buf.pos = strlen(buf.str);
4751         }
4752         else if (ident == state->i___LINE__) {
4753                 buf.len = 30;
4754                 buf.str = xmalloc(buf.len, ident->name);
4755                 sprintf(buf.str, "%d", state->file->line);
4756                 buf.pos = strlen(buf.str);
4757         }
4758         else {
4759                 expand_macro(state, macro, &buf, argv, tk);
4760         }
4761         /* Tag the macro name with a $ so it will no longer
4762          * be regonized as a canidate for macro expansion.
4763          */
4764         tag_macro_name(state, macro, &buf, tk);
4765
4766 #if 0
4767         fprintf(state->errout, "%s: %d -> `%*.*s'\n",
4768                 ident->name, buf.pos, buf.pos, (int)(buf.pos), buf.str);
4769 #endif
4770
4771         free_macro_args(macro, argv);
4772
4773         file = xmalloc(sizeof(*file), "file_state");
4774         file->prev        = *filep;
4775         file->basename    = xstrdup(ident->name);
4776         file->dirname     = xstrdup("");
4777         file->buf         = buf.str;
4778         file->size        = buf.pos;
4779         file->pos         = file->buf;
4780         file->line        = 1;
4781         file->line_start  = file->pos;
4782         file->report_line = 1;
4783         file->report_name = file->basename;
4784         file->report_dir  = file->dirname;
4785         file->macro       = 1;
4786         file->trigraphs   = 0;
4787         file->join_lines  = 0;
4788         *filep = file;
4789         return 1;
4790 }
4791
4792 static void eat_tokens(struct compile_state *state, int targ_tok)
4793 {
4794         if (state->eat_depth > 0) {
4795                 internal_error(state, 0, "Already eating...");
4796         }
4797         state->eat_depth = state->if_depth;
4798         state->eat_targ = targ_tok;
4799 }
4800 static int if_eat(struct compile_state *state)
4801 {
4802         return state->eat_depth > 0;
4803 }
4804 static int if_value(struct compile_state *state)
4805 {
4806         int index, offset;
4807         index = state->if_depth / CHAR_BIT;
4808         offset = state->if_depth % CHAR_BIT;
4809         return !!(state->if_bytes[index] & (1 << (offset)));
4810 }
4811 static void set_if_value(struct compile_state *state, int value) 
4812 {
4813         int index, offset;
4814         index = state->if_depth / CHAR_BIT;
4815         offset = state->if_depth % CHAR_BIT;
4816
4817         state->if_bytes[index] &= ~(1 << offset);
4818         if (value) {
4819                 state->if_bytes[index] |= (1 << offset);
4820         }
4821 }
4822 static void in_if(struct compile_state *state, const char *name)
4823 {
4824         if (state->if_depth <= 0) {
4825                 error(state, 0, "%s without #if", name);
4826         }
4827 }
4828 static void enter_if(struct compile_state *state)
4829 {
4830         state->if_depth += 1;
4831         if (state->if_depth > MAX_PP_IF_DEPTH) {
4832                 error(state, 0, "#if depth too great");
4833         }
4834 }
4835 static void reenter_if(struct compile_state *state, const char *name)
4836 {
4837         in_if(state, name);
4838         if ((state->eat_depth == state->if_depth) &&
4839                 (state->eat_targ == TOK_MELSE)) {
4840                 state->eat_depth = 0;
4841                 state->eat_targ = 0;
4842         }
4843 }
4844 static void enter_else(struct compile_state *state, const char *name)
4845 {
4846         in_if(state, name);
4847         if ((state->eat_depth == state->if_depth) &&
4848                 (state->eat_targ == TOK_MELSE)) {
4849                 state->eat_depth = 0;
4850                 state->eat_targ = 0;
4851         }
4852 }
4853 static void exit_if(struct compile_state *state, const char *name)
4854 {
4855         in_if(state, name);
4856         if (state->eat_depth == state->if_depth) {
4857                 state->eat_depth = 0;
4858                 state->eat_targ = 0;
4859         }
4860         state->if_depth -= 1;
4861 }
4862
4863 static void raw_token(struct compile_state *state, struct token *tk)
4864 {
4865         struct file_state *file;
4866         int rescan;
4867
4868         file = state->file;
4869         raw_next_token(state, file, tk);
4870         do {
4871                 rescan = 0;
4872                 file = state->file;
4873                 /* Exit out of an include directive or macro call */
4874                 if ((tk->tok == TOK_EOF) && 
4875                         (file != state->macro_file) && file->prev) 
4876                 {
4877                         state->file = file->prev;
4878                         /* file->basename is used keep it */
4879                         xfree(file->dirname);
4880                         xfree(file->buf);
4881                         xfree(file);
4882                         file = 0;
4883                         raw_next_token(state, state->file, tk);
4884                         rescan = 1;
4885                 }
4886         } while(rescan);
4887 }
4888
4889 static void pp_token(struct compile_state *state, struct token *tk)
4890 {
4891         struct file_state *file;
4892         int rescan;
4893
4894         raw_token(state, tk);
4895         do {
4896                 rescan = 0;
4897                 file = state->file;
4898                 if (tk->tok == TOK_SPACE) {
4899                         raw_token(state, tk);
4900                         rescan = 1;
4901                 }
4902                 else if (tk->tok == TOK_IDENT) {
4903                         if (state->token_base == 0) {
4904                                 ident_to_keyword(state, tk);
4905                         } else {
4906                                 ident_to_macro(state, tk);
4907                         }
4908                 }
4909         } while(rescan);
4910 }
4911
4912 static void preprocess(struct compile_state *state, struct token *tk);
4913
4914 static void token(struct compile_state *state, struct token *tk)
4915 {
4916         int rescan;
4917         pp_token(state, tk);
4918         do {
4919                 rescan = 0;
4920                 /* Process a macro directive */
4921                 if (tk->tok == TOK_MACRO) {
4922                         /* Only match preprocessor directives at the start of a line */
4923                         const char *ptr;
4924                         ptr = state->file->line_start;
4925                         while((ptr < tk->pos)
4926                                 && spacep(get_char(state->file, ptr)))
4927                         {
4928                                 ptr = next_char(state->file, ptr, 1);
4929                         }
4930                         if (ptr == tk->pos) {
4931                                 preprocess(state, tk);
4932                                 rescan = 1;
4933                         }
4934                 }
4935                 /* Expand a macro call */
4936                 else if (tk->ident && tk->ident->sym_define) {
4937                         rescan = compile_macro(state, &state->file, tk);
4938                         if (rescan) {
4939                                 pp_token(state, tk);
4940                         }
4941                 }
4942                 /* Eat tokens disabled by the preprocessor 
4943                  * (Unless we are parsing a preprocessor directive 
4944                  */
4945                 else if (if_eat(state) && (state->token_base == 0)) {
4946                         pp_token(state, tk);
4947                         rescan = 1;
4948                 }
4949                 /* Make certain EOL only shows up in preprocessor directives */
4950                 else if ((tk->tok == TOK_EOL) && (state->token_base == 0)) {
4951                         pp_token(state, tk);
4952                         rescan = 1;
4953                 }
4954                 /* Error on unknown tokens */
4955                 else if (tk->tok == TOK_UNKNOWN) {
4956                         error(state, 0, "unknown token");
4957                 }
4958         } while(rescan);
4959 }
4960
4961
4962 static inline struct token *get_token(struct compile_state *state, int offset)
4963 {
4964         int index;
4965         index = state->token_base + offset;
4966         if (index >= sizeof(state->token)/sizeof(state->token[0])) {
4967                 internal_error(state, 0, "token array to small");
4968         }
4969         return &state->token[index];
4970 }
4971
4972 static struct token *do_eat_token(struct compile_state *state, int tok)
4973 {
4974         struct token *tk;
4975         int i;
4976         check_tok(state, get_token(state, 1), tok);
4977         
4978         /* Free the old token value */
4979         tk = get_token(state, 0);
4980         if (tk->str_len) {
4981                 memset((void *)tk->val.str, -1, tk->str_len);
4982                 xfree(tk->val.str);
4983         }
4984         /* Overwrite the old token with newer tokens */
4985         for(i = state->token_base; i < sizeof(state->token)/sizeof(state->token[0]) - 1; i++) {
4986                 state->token[i] = state->token[i + 1];
4987         }
4988         /* Clear the last token */
4989         memset(&state->token[i], 0, sizeof(state->token[i]));
4990         state->token[i].tok = -1;
4991
4992         /* Return the token */
4993         return tk;
4994 }
4995
4996 static int raw_peek(struct compile_state *state)
4997 {
4998         struct token *tk1;
4999         tk1 = get_token(state, 1);
5000         if (tk1->tok == -1) {
5001                 raw_token(state, tk1);
5002         }
5003         return tk1->tok;
5004 }
5005
5006 static struct token *raw_eat(struct compile_state *state, int tok)
5007 {
5008         raw_peek(state);
5009         return do_eat_token(state, tok);
5010 }
5011
5012 static int pp_peek(struct compile_state *state)
5013 {
5014         struct token *tk1;
5015         tk1 = get_token(state, 1);
5016         if (tk1->tok == -1) {
5017                 pp_token(state, tk1);
5018         }
5019         return tk1->tok;
5020 }
5021
5022 static struct token *pp_eat(struct compile_state *state, int tok)
5023 {
5024         pp_peek(state);
5025         return do_eat_token(state, tok);
5026 }
5027
5028 static int peek(struct compile_state *state)
5029 {
5030         struct token *tk1;
5031         tk1 = get_token(state, 1);
5032         if (tk1->tok == -1) {
5033                 token(state, tk1);
5034         }
5035         return tk1->tok;
5036 }
5037
5038 static int peek2(struct compile_state *state)
5039 {
5040         struct token *tk1, *tk2;
5041         tk1 = get_token(state, 1);
5042         tk2 = get_token(state, 2);
5043         if (tk1->tok == -1) {
5044                 token(state, tk1);
5045         }
5046         if (tk2->tok == -1) {
5047                 token(state, tk2);
5048         }
5049         return tk2->tok;
5050 }
5051
5052 static struct token *eat(struct compile_state *state, int tok)
5053 {
5054         peek(state);
5055         return do_eat_token(state, tok);
5056 }
5057
5058 static void compile_file(struct compile_state *state, const char *filename, int local)
5059 {
5060         char cwd[MAX_CWD_SIZE];
5061         const char *subdir, *base;
5062         int subdir_len;
5063         struct file_state *file;
5064         char *basename;
5065         file = xmalloc(sizeof(*file), "file_state");
5066
5067         base = strrchr(filename, '/');
5068         subdir = filename;
5069         if (base != 0) {
5070                 subdir_len = base - filename;
5071                 base++;
5072         }
5073         else {
5074                 base = filename;
5075                 subdir_len = 0;
5076         }
5077         basename = xmalloc(strlen(base) +1, "basename");
5078         strcpy(basename, base);
5079         file->basename = basename;
5080
5081         if (getcwd(cwd, sizeof(cwd)) == 0) {
5082                 die("cwd buffer to small");
5083         }
5084         if ((subdir[0] == '/') || ((subdir[1] == ':') && ((subdir[2] == '/') || (subdir[2] == '\\')))) {
5085                 file->dirname = xmalloc(subdir_len + 1, "dirname");
5086                 memcpy(file->dirname, subdir, subdir_len);
5087                 file->dirname[subdir_len] = '\0';
5088         }
5089         else {
5090                 const char *dir;
5091                 int dirlen;
5092                 const char **path;
5093                 /* Find the appropriate directory... */
5094                 dir = 0;
5095                 if (!state->file && exists(cwd, filename)) {
5096                         dir = cwd;
5097                 }
5098                 if (local && state->file && exists(state->file->dirname, filename)) {
5099                         dir = state->file->dirname;
5100                 }
5101                 for(path = state->compiler->include_paths; !dir && *path; path++) {
5102                         if (exists(*path, filename)) {
5103                                 dir = *path;
5104                         }
5105                 }
5106                 if (!dir) {
5107                         error(state, 0, "Cannot open `%s'\n", filename);
5108                 }
5109                 dirlen = strlen(dir);
5110                 file->dirname = xmalloc(dirlen + 1 + subdir_len + 1, "dirname");
5111                 memcpy(file->dirname, dir, dirlen);
5112                 file->dirname[dirlen] = '/';
5113                 memcpy(file->dirname + dirlen + 1, subdir, subdir_len);
5114                 file->dirname[dirlen + 1 + subdir_len] = '\0';
5115         }
5116         file->buf = slurp_file(file->dirname, file->basename, &file->size);
5117
5118         file->pos = file->buf;
5119         file->line_start = file->pos;
5120         file->line = 1;
5121
5122         file->report_line = 1;
5123         file->report_name = file->basename;
5124         file->report_dir  = file->dirname;
5125         file->macro       = 0;
5126         file->trigraphs   = (state->compiler->flags & COMPILER_TRIGRAPHS)? 1: 0;
5127         file->join_lines  = 1;
5128
5129         file->prev = state->file;
5130         state->file = file;
5131 }
5132
5133 static struct triple *constant_expr(struct compile_state *state);
5134 static void integral(struct compile_state *state, struct triple *def);
5135
5136 static int mcexpr(struct compile_state *state)
5137 {
5138         struct triple *cvalue;
5139         cvalue = constant_expr(state);
5140         integral(state, cvalue);
5141         if (cvalue->op != OP_INTCONST) {
5142                 error(state, 0, "integer constant expected");
5143         }
5144         return cvalue->u.cval != 0;
5145 }
5146
5147 static void preprocess(struct compile_state *state, struct token *current_token)
5148 {
5149         /* Doing much more with the preprocessor would require
5150          * a parser and a major restructuring.
5151          * Postpone that for later.
5152          */
5153         int old_token_base;
5154         int tok;
5155         
5156         state->macro_file = state->file;
5157
5158         old_token_base = state->token_base;
5159         state->token_base = current_token - state->token;
5160
5161         tok = pp_peek(state);
5162         switch(tok) {
5163         case TOK_LIT_INT:
5164         {
5165                 struct token *tk;
5166                 int override_line;
5167                 tk = pp_eat(state, TOK_LIT_INT);
5168                 override_line = strtoul(tk->val.str, 0, 10);
5169                 /* I have a preprocessor  line marker parse it */
5170                 if (pp_peek(state) == TOK_LIT_STRING) {
5171                         const char *token, *base;
5172                         char *name, *dir;
5173                         int name_len, dir_len;
5174                         tk = pp_eat(state, TOK_LIT_STRING);
5175                         name = xmalloc(tk->str_len, "report_name");
5176                         token = tk->val.str + 1;
5177                         base = strrchr(token, '/');
5178                         name_len = tk->str_len -2;
5179                         if (base != 0) {
5180                                 dir_len = base - token;
5181                                 base++;
5182                                 name_len -= base - token;
5183                         } else {
5184                                 dir_len = 0;
5185                                 base = token;
5186                         }
5187                         memcpy(name, base, name_len);
5188                         name[name_len] = '\0';
5189                         dir = xmalloc(dir_len + 1, "report_dir");
5190                         memcpy(dir, token, dir_len);
5191                         dir[dir_len] = '\0';
5192                         state->file->report_line = override_line - 1;
5193                         state->file->report_name = name;
5194                         state->file->report_dir = dir;
5195                         state->file->macro      = 0;
5196                 }
5197                 break;
5198         }
5199         case TOK_MLINE:
5200         {
5201                 struct token *tk;
5202                 pp_eat(state, TOK_MLINE);
5203                 tk = eat(state, TOK_LIT_INT);
5204                 state->file->report_line = strtoul(tk->val.str, 0, 10) -1;
5205                 if (pp_peek(state) == TOK_LIT_STRING) {
5206                         const char *token, *base;
5207                         char *name, *dir;
5208                         int name_len, dir_len;
5209                         tk = pp_eat(state, TOK_LIT_STRING);
5210                         name = xmalloc(tk->str_len, "report_name");
5211                         token = tk->val.str + 1;
5212                         base = strrchr(token, '/');
5213                         name_len = tk->str_len - 2;
5214                         if (base != 0) {
5215                                 dir_len = base - token;
5216                                 base++;
5217                                 name_len -= base - token;
5218                         } else {
5219                                 dir_len = 0;
5220                                 base = token;
5221                         }
5222                         memcpy(name, base, name_len);
5223                         name[name_len] = '\0';
5224                         dir = xmalloc(dir_len + 1, "report_dir");
5225                         memcpy(dir, token, dir_len);
5226                         dir[dir_len] = '\0';
5227                         state->file->report_name = name;
5228                         state->file->report_dir = dir;
5229                         state->file->macro      = 0;
5230                 }
5231                 break;
5232         }
5233         case TOK_MUNDEF:
5234         {
5235                 struct hash_entry *ident;
5236                 pp_eat(state, TOK_MUNDEF);
5237                 if (if_eat(state))  /* quit early when #if'd out */
5238                         break;
5239                 
5240                 ident = pp_eat(state, TOK_MIDENT)->ident;
5241
5242                 undef_macro(state, ident);
5243                 break;
5244         }
5245         case TOK_MPRAGMA:
5246                 pp_eat(state, TOK_MPRAGMA);
5247                 if (if_eat(state))  /* quit early when #if'd out */
5248                         break;
5249                 warning(state, 0, "Ignoring pragma"); 
5250                 break;
5251         case TOK_MELIF:
5252                 pp_eat(state, TOK_MELIF);
5253                 reenter_if(state, "#elif");
5254                 if (if_eat(state))   /* quit early when #if'd out */
5255                         break;
5256                 /* If the #if was taken the #elif just disables the following code */
5257                 if (if_value(state)) {
5258                         eat_tokens(state, TOK_MENDIF);
5259                 }
5260                 /* If the previous #if was not taken see if the #elif enables the 
5261                  * trailing code.
5262                  */
5263                 else {
5264                         set_if_value(state, mcexpr(state));
5265                         if (!if_value(state)) {
5266                                 eat_tokens(state, TOK_MELSE);
5267                         }
5268                 }
5269                 break;
5270         case TOK_MIF:
5271                 pp_eat(state, TOK_MIF);
5272                 enter_if(state);
5273                 if (if_eat(state))  /* quit early when #if'd out */
5274                         break;
5275                 set_if_value(state, mcexpr(state));
5276                 if (!if_value(state)) {
5277                         eat_tokens(state, TOK_MELSE);
5278                 }
5279                 break;
5280         case TOK_MIFNDEF:
5281         {
5282                 struct hash_entry *ident;
5283
5284                 pp_eat(state, TOK_MIFNDEF);
5285                 enter_if(state);
5286                 if (if_eat(state))  /* quit early when #if'd out */
5287                         break;
5288                 ident = pp_eat(state, TOK_MIDENT)->ident;
5289                 set_if_value(state, ident->sym_define == 0);
5290                 if (!if_value(state)) {
5291                         eat_tokens(state, TOK_MELSE);
5292                 }
5293                 break;
5294         }
5295         case TOK_MIFDEF:
5296         {
5297                 struct hash_entry *ident;
5298                 pp_eat(state, TOK_MIFDEF);
5299                 enter_if(state);
5300                 if (if_eat(state))  /* quit early when #if'd out */
5301                         break;
5302                 ident = pp_eat(state, TOK_MIDENT)->ident;
5303                 set_if_value(state, ident->sym_define != 0);
5304                 if (!if_value(state)) {
5305                         eat_tokens(state, TOK_MELSE);
5306                 }
5307                 break;
5308         }
5309         case TOK_MELSE:
5310                 pp_eat(state, TOK_MELSE);
5311                 enter_else(state, "#else");
5312                 if (!if_eat(state) && if_value(state)) {
5313                         eat_tokens(state, TOK_MENDIF);
5314                 }
5315                 break;
5316         case TOK_MENDIF:
5317                 pp_eat(state, TOK_MENDIF);
5318                 exit_if(state, "#endif");
5319                 break;
5320         case TOK_MDEFINE:
5321         {
5322                 struct hash_entry *ident;
5323                 struct macro_arg *args, **larg;
5324                 const char *mstart, *mend;
5325                 int argc;
5326
5327                 pp_eat(state, TOK_MDEFINE);
5328                 if (if_eat(state))  /* quit early when #if'd out */
5329                         break;
5330                 ident = pp_eat(state, TOK_MIDENT)->ident;
5331                 argc = -1;
5332                 args = 0;
5333                 larg = &args;
5334
5335                 /* Parse macro parameters */
5336                 if (raw_peek(state) == TOK_LPAREN) {
5337                         raw_eat(state, TOK_LPAREN);
5338                         argc += 1;
5339
5340                         for(;;) {
5341                                 struct macro_arg *narg, *arg;
5342                                 struct hash_entry *aident;
5343                                 int tok;
5344
5345                                 tok = pp_peek(state);
5346                                 if (!args && (tok == TOK_RPAREN)) {
5347                                         break;
5348                                 }
5349                                 else if (tok == TOK_DOTS) {
5350                                         pp_eat(state, TOK_DOTS);
5351                                         aident = state->i___VA_ARGS__;
5352                                 } 
5353                                 else {
5354                                         aident = pp_eat(state, TOK_MIDENT)->ident;
5355                                 }
5356                                 
5357                                 narg = xcmalloc(sizeof(*arg), "macro arg");
5358                                 narg->ident = aident;
5359
5360                                 /* Verify I don't have a duplicate identifier */
5361                                 for(arg = args; arg; arg = arg->next) {
5362                                         if (arg->ident == narg->ident) {
5363                                                 error(state, 0, "Duplicate macro arg `%s'",
5364                                                         narg->ident->name);
5365                                         }
5366                                 }
5367                                 /* Add the new argument to the end of the list */
5368                                 *larg = narg;
5369                                 larg = &narg->next;
5370                                 argc += 1;
5371
5372                                 if ((aident == state->i___VA_ARGS__) ||
5373                                         (pp_peek(state) != TOK_COMMA)) {
5374                                         break;
5375                                 }
5376                                 pp_eat(state, TOK_COMMA);
5377                         }
5378                         pp_eat(state, TOK_RPAREN);
5379                 }
5380                 /* Remove leading whitespace */
5381                 while(raw_peek(state) == TOK_SPACE) {
5382                         raw_eat(state, TOK_SPACE);
5383                 }
5384
5385                 /* Remember the start of the macro body */
5386                 tok = raw_peek(state);
5387                 mend = mstart = get_token(state, 1)->pos;
5388
5389                 /* Find the end of the macro */
5390                 for(tok = raw_peek(state); tok != TOK_EOL; tok = raw_peek(state)) {
5391                         raw_eat(state, tok);
5392                         /* Remember the end of the last non space token */
5393                         raw_peek(state);
5394                         if (tok != TOK_SPACE) {
5395                                 mend = get_token(state, 1)->pos;
5396                         }
5397                 }
5398                 
5399                 /* Now that I have found the body defined the token */
5400                 do_define_macro(state, ident,
5401                         char_strdup(state->file, mstart, mend, "macro buf"),
5402                         argc, args);
5403                 break;
5404         }
5405         case TOK_MERROR:
5406         {
5407                 const char *start, *end;
5408                 int len;
5409                 
5410                 pp_eat(state, TOK_MERROR);
5411                 /* Find the start of the line */
5412                 raw_peek(state);
5413                 start = get_token(state, 1)->pos;
5414
5415                 /* Find the end of the line */
5416                 while((tok = raw_peek(state)) != TOK_EOL) {
5417                         raw_eat(state, tok);
5418                 }
5419                 end = get_token(state, 1)->pos;
5420                 len = end - start;
5421                 if (!if_eat(state)) {
5422                         error(state, 0, "%*.*s", len, len, start);
5423                 }
5424                 break;
5425         }
5426         case TOK_MWARNING:
5427         {
5428                 const char *start, *end;
5429                 int len;
5430                 
5431                 pp_eat(state, TOK_MWARNING);
5432
5433                 /* Find the start of the line */
5434                 raw_peek(state);
5435                 start = get_token(state, 1)->pos;
5436                  
5437                 /* Find the end of the line */
5438                 while((tok = raw_peek(state)) != TOK_EOL) {
5439                         raw_eat(state, tok);
5440                 }
5441                 end = get_token(state, 1)->pos;
5442                 len = end - start;
5443                 if (!if_eat(state)) {
5444                         warning(state, 0, "%*.*s", len, len, start);
5445                 }
5446                 break;
5447         }
5448         case TOK_MINCLUDE:
5449         {
5450                 char *name;
5451                 int local;
5452                 local = 0;
5453                 name = 0;
5454
5455                 pp_eat(state, TOK_MINCLUDE);
5456                 tok = peek(state);
5457                 if (tok == TOK_LIT_STRING) {
5458                         struct token *tk;
5459                         const char *token;
5460                         int name_len;
5461                         tk = eat(state, TOK_LIT_STRING);
5462                         name = xmalloc(tk->str_len, "include");
5463                         token = tk->val.str +1;
5464                         name_len = tk->str_len -2;
5465                         if (*token == '"') {
5466                                 token++;
5467                                 name_len--;
5468                         }
5469                         memcpy(name, token, name_len);
5470                         name[name_len] = '\0';
5471                         local = 1;
5472                 }
5473                 else if (tok == TOK_LESS) {
5474                         struct macro_buf buf;
5475                         eat(state, TOK_LESS);
5476
5477                         buf.len = 40;
5478                         buf.str = xmalloc(buf.len, "include");
5479                         buf.pos = 0;
5480
5481                         tok = peek(state);
5482                         while((tok != TOK_MORE) &&
5483                                 (tok != TOK_EOL) && (tok != TOK_EOF))
5484                         {
5485                                 struct token *tk;
5486                                 tk = eat(state, tok);
5487                                 append_macro_chars(state, "include", &buf,
5488                                         state->file, tk->pos, state->file->pos);
5489                                 tok = peek(state);
5490                         }
5491                         append_macro_text(state, "include", &buf, "\0", 1);
5492                         if (peek(state) != TOK_MORE) {
5493                                 error(state, 0, "Unterminated include directive");
5494                         }
5495                         eat(state, TOK_MORE);
5496                         local = 0;
5497                         name = buf.str;
5498                 }
5499                 else {
5500                         error(state, 0, "Invalid include directive");
5501                 }
5502                 /* Error if there are any tokens after the include */
5503                 if (pp_peek(state) != TOK_EOL) {
5504                         error(state, 0, "garbage after include directive");
5505                 }
5506                 if (!if_eat(state)) {
5507                         compile_file(state, name, local);
5508                 }
5509                 xfree(name);
5510                 break;
5511         }
5512         case TOK_EOL:
5513                 /* Ignore # without a follwing ident */
5514                 break;
5515         default:
5516         {
5517                 const char *name1, *name2;
5518                 name1 = tokens[tok];
5519                 name2 = "";
5520                 if (tok == TOK_MIDENT) {
5521                         name2 = get_token(state, 1)->ident->name;
5522                 }
5523                 error(state, 0, "Invalid preprocessor directive: %s %s", 
5524                         name1, name2);
5525                 break;
5526         }
5527         }
5528         /* Consume the rest of the macro line */
5529         do {
5530                 tok = pp_peek(state);
5531                 pp_eat(state, tok);
5532         } while((tok != TOK_EOF) && (tok != TOK_EOL));
5533         state->token_base = old_token_base;
5534         state->macro_file = NULL;
5535         return;
5536 }
5537
5538 /* Type helper functions */
5539
5540 static struct type *new_type(
5541         unsigned int type, struct type *left, struct type *right)
5542 {
5543         struct type *result;
5544         result = xmalloc(sizeof(*result), "type");
5545         result->type = type;
5546         result->left = left;
5547         result->right = right;
5548         result->field_ident = 0;
5549         result->type_ident = 0;
5550         result->elements = 0;
5551         return result;
5552 }
5553
5554 static struct type *clone_type(unsigned int specifiers, struct type *old)
5555 {
5556         struct type *result;
5557         result = xmalloc(sizeof(*result), "type");
5558         memcpy(result, old, sizeof(*result));
5559         result->type &= TYPE_MASK;
5560         result->type |= specifiers;
5561         return result;
5562 }
5563
5564 static struct type *dup_type(struct compile_state *state, struct type *orig)
5565 {
5566         struct type *new;
5567         new = xcmalloc(sizeof(*new), "type");
5568         new->type = orig->type;
5569         new->field_ident = orig->field_ident;
5570         new->type_ident  = orig->type_ident;
5571         new->elements    = orig->elements;
5572         if (orig->left) {
5573                 new->left = dup_type(state, orig->left);
5574         }
5575         if (orig->right) {
5576                 new->right = dup_type(state, orig->right);
5577         }
5578         return new;
5579 }
5580
5581
5582 static struct type *invalid_type(struct compile_state *state, struct type *type)
5583 {
5584         struct type *invalid, *member;
5585         invalid = 0;
5586         if (!type) {
5587                 internal_error(state, 0, "type missing?");
5588         }
5589         switch(type->type & TYPE_MASK) {
5590         case TYPE_VOID:
5591         case TYPE_CHAR:         case TYPE_UCHAR:
5592         case TYPE_SHORT:        case TYPE_USHORT:
5593         case TYPE_INT:          case TYPE_UINT:
5594         case TYPE_LONG:         case TYPE_ULONG:
5595         case TYPE_LLONG:        case TYPE_ULLONG:
5596         case TYPE_POINTER:
5597         case TYPE_ENUM:
5598                 break;
5599         case TYPE_BITFIELD:
5600                 invalid = invalid_type(state, type->left);
5601                 break;
5602         case TYPE_ARRAY:
5603                 invalid = invalid_type(state, type->left);
5604                 break;
5605         case TYPE_STRUCT:
5606         case TYPE_TUPLE:
5607                 member = type->left;
5608                 while(member && (invalid == 0) && 
5609                         ((member->type & TYPE_MASK) == TYPE_PRODUCT)) {
5610                         invalid = invalid_type(state, member->left);
5611                         member = member->right;
5612                 }
5613                 if (!invalid) {
5614                         invalid = invalid_type(state, member);
5615                 }
5616                 break;
5617         case TYPE_UNION:
5618         case TYPE_JOIN:
5619                 member = type->left;
5620                 while(member && (invalid == 0) &&
5621                         ((member->type & TYPE_MASK) == TYPE_OVERLAP)) {
5622                         invalid = invalid_type(state, member->left);
5623                         member = member->right;
5624                 }
5625                 if (!invalid) {
5626                         invalid = invalid_type(state, member);
5627                 }
5628                 break;
5629         default:
5630                 invalid = type;
5631                 break;
5632         }
5633         return invalid;
5634         
5635 }
5636
5637 #define MASK_UCHAR(X)    ((X) & ((ulong_t)0xff))
5638 #define MASK_USHORT(X)   ((X) & (((ulong_t)1 << (SIZEOF_SHORT)) - 1))
5639 static inline ulong_t mask_uint(ulong_t x)
5640 {
5641         if (SIZEOF_INT < SIZEOF_LONG) {
5642                 ulong_t mask = (1ULL << ((ulong_t)(SIZEOF_INT))) -1;
5643                 x &= mask;
5644         }
5645         return x;
5646 }
5647 #define MASK_UINT(X)      (mask_uint(X))
5648 #define MASK_ULONG(X)    (X)
5649
5650 static struct type void_type    = { .type  = TYPE_VOID };
5651 static struct type char_type    = { .type  = TYPE_CHAR };
5652 static struct type uchar_type   = { .type  = TYPE_UCHAR };
5653 #if DEBUG_ROMCC_WARNING
5654 static struct type short_type   = { .type  = TYPE_SHORT };
5655 #endif
5656 static struct type ushort_type  = { .type  = TYPE_USHORT };
5657 static struct type int_type     = { .type  = TYPE_INT };
5658 static struct type uint_type    = { .type  = TYPE_UINT };
5659 static struct type long_type    = { .type  = TYPE_LONG };
5660 static struct type ulong_type   = { .type  = TYPE_ULONG };
5661 static struct type unknown_type = { .type  = TYPE_UNKNOWN };
5662
5663 static struct type void_ptr_type  = {
5664         .type = TYPE_POINTER,
5665         .left = &void_type,
5666 };
5667
5668 #if DEBUG_ROMCC_WARNING
5669 static struct type void_func_type = { 
5670         .type  = TYPE_FUNCTION,
5671         .left  = &void_type,
5672         .right = &void_type,
5673 };
5674 #endif
5675
5676 static size_t bits_to_bytes(size_t size)
5677 {
5678         return (size + SIZEOF_CHAR - 1)/SIZEOF_CHAR;
5679 }
5680
5681 static struct triple *variable(struct compile_state *state, struct type *type)
5682 {
5683         struct triple *result;
5684         if ((type->type & STOR_MASK) != STOR_PERM) {
5685                 result = triple(state, OP_ADECL, type, 0, 0);
5686                 generate_lhs_pieces(state, result);
5687         }
5688         else {
5689                 result = triple(state, OP_SDECL, type, 0, 0);
5690         }
5691         return result;
5692 }
5693
5694 static void stor_of(FILE *fp, struct type *type)
5695 {
5696         switch(type->type & STOR_MASK) {
5697         case STOR_AUTO:
5698                 fprintf(fp, "auto ");
5699                 break;
5700         case STOR_STATIC:
5701                 fprintf(fp, "static ");
5702                 break;
5703         case STOR_LOCAL:
5704                 fprintf(fp, "local ");
5705                 break;
5706         case STOR_EXTERN:
5707                 fprintf(fp, "extern ");
5708                 break;
5709         case STOR_REGISTER:
5710                 fprintf(fp, "register ");
5711                 break;
5712         case STOR_TYPEDEF:
5713                 fprintf(fp, "typedef ");
5714                 break;
5715         case STOR_INLINE | STOR_LOCAL:
5716                 fprintf(fp, "inline ");
5717                 break;
5718         case STOR_INLINE | STOR_STATIC:
5719                 fprintf(fp, "static inline");
5720                 break;
5721         case STOR_INLINE | STOR_EXTERN:
5722                 fprintf(fp, "extern inline");
5723                 break;
5724         default:
5725                 fprintf(fp, "stor:%x", type->type & STOR_MASK);
5726                 break;
5727         }
5728 }
5729 static void qual_of(FILE *fp, struct type *type)
5730 {
5731         if (type->type & QUAL_CONST) {
5732                 fprintf(fp, " const");
5733         }
5734         if (type->type & QUAL_VOLATILE) {
5735                 fprintf(fp, " volatile");
5736         }
5737         if (type->type & QUAL_RESTRICT) {
5738                 fprintf(fp, " restrict");
5739         }
5740 }
5741
5742 static void name_of(FILE *fp, struct type *type)
5743 {
5744         unsigned int base_type;
5745         base_type = type->type & TYPE_MASK;
5746         if ((base_type != TYPE_PRODUCT) && (base_type != TYPE_OVERLAP)) {
5747                 stor_of(fp, type);
5748         }
5749         switch(base_type) {
5750         case TYPE_VOID:
5751                 fprintf(fp, "void");
5752                 qual_of(fp, type);
5753                 break;
5754         case TYPE_CHAR:
5755                 fprintf(fp, "signed char");
5756                 qual_of(fp, type);
5757                 break;
5758         case TYPE_UCHAR:
5759                 fprintf(fp, "unsigned char");
5760                 qual_of(fp, type);
5761                 break;
5762         case TYPE_SHORT:
5763                 fprintf(fp, "signed short");
5764                 qual_of(fp, type);
5765                 break;
5766         case TYPE_USHORT:
5767                 fprintf(fp, "unsigned short");
5768                 qual_of(fp, type);
5769                 break;
5770         case TYPE_INT:
5771                 fprintf(fp, "signed int");
5772                 qual_of(fp, type);
5773                 break;
5774         case TYPE_UINT:
5775                 fprintf(fp, "unsigned int");
5776                 qual_of(fp, type);
5777                 break;
5778         case TYPE_LONG:
5779                 fprintf(fp, "signed long");
5780                 qual_of(fp, type);
5781                 break;
5782         case TYPE_ULONG:
5783                 fprintf(fp, "unsigned long");
5784                 qual_of(fp, type);
5785                 break;
5786         case TYPE_POINTER:
5787                 name_of(fp, type->left);
5788                 fprintf(fp, " * ");
5789                 qual_of(fp, type);
5790                 break;
5791         case TYPE_PRODUCT:
5792                 name_of(fp, type->left);
5793                 fprintf(fp, ", ");
5794                 name_of(fp, type->right);
5795                 break;
5796         case TYPE_OVERLAP:
5797                 name_of(fp, type->left);
5798                 fprintf(fp, ",| ");
5799                 name_of(fp, type->right);
5800                 break;
5801         case TYPE_ENUM:
5802                 fprintf(fp, "enum %s", 
5803                         (type->type_ident)? type->type_ident->name : "");
5804                 qual_of(fp, type);
5805                 break;
5806         case TYPE_STRUCT:
5807                 fprintf(fp, "struct %s { ", 
5808                         (type->type_ident)? type->type_ident->name : "");
5809                 name_of(fp, type->left);
5810                 fprintf(fp, " } ");
5811                 qual_of(fp, type);
5812                 break;
5813         case TYPE_UNION:
5814                 fprintf(fp, "union %s { ", 
5815                         (type->type_ident)? type->type_ident->name : "");
5816                 name_of(fp, type->left);
5817                 fprintf(fp, " } ");
5818                 qual_of(fp, type);
5819                 break;
5820         case TYPE_FUNCTION:
5821                 name_of(fp, type->left);
5822                 fprintf(fp, " (*)(");
5823                 name_of(fp, type->right);
5824                 fprintf(fp, ")");
5825                 break;
5826         case TYPE_ARRAY:
5827                 name_of(fp, type->left);
5828                 fprintf(fp, " [%ld]", (long)(type->elements));
5829                 break;
5830         case TYPE_TUPLE:
5831                 fprintf(fp, "tuple { "); 
5832                 name_of(fp, type->left);
5833                 fprintf(fp, " } ");
5834                 qual_of(fp, type);
5835                 break;
5836         case TYPE_JOIN:
5837                 fprintf(fp, "join { ");
5838                 name_of(fp, type->left);
5839                 fprintf(fp, " } ");
5840                 qual_of(fp, type);
5841                 break;
5842         case TYPE_BITFIELD:
5843                 name_of(fp, type->left);
5844                 fprintf(fp, " : %d ", type->elements);
5845                 qual_of(fp, type);
5846                 break;
5847         case TYPE_UNKNOWN:
5848                 fprintf(fp, "unknown_t");
5849                 break;
5850         default:
5851                 fprintf(fp, "????: %x", base_type);
5852                 break;
5853         }
5854         if (type->field_ident && type->field_ident->name) {
5855                 fprintf(fp, " .%s", type->field_ident->name);
5856         }
5857 }
5858
5859 static size_t align_of(struct compile_state *state, struct type *type)
5860 {
5861         size_t align;
5862         align = 0;
5863         switch(type->type & TYPE_MASK) {
5864         case TYPE_VOID:
5865                 align = 1;
5866                 break;
5867         case TYPE_BITFIELD:
5868                 align = 1;
5869                 break;
5870         case TYPE_CHAR:
5871         case TYPE_UCHAR:
5872                 align = ALIGNOF_CHAR;
5873                 break;
5874         case TYPE_SHORT:
5875         case TYPE_USHORT:
5876                 align = ALIGNOF_SHORT;
5877                 break;
5878         case TYPE_INT:
5879         case TYPE_UINT:
5880         case TYPE_ENUM:
5881                 align = ALIGNOF_INT;
5882                 break;
5883         case TYPE_LONG:
5884         case TYPE_ULONG:
5885                 align = ALIGNOF_LONG;
5886                 break;
5887         case TYPE_POINTER:
5888                 align = ALIGNOF_POINTER;
5889                 break;
5890         case TYPE_PRODUCT:
5891         case TYPE_OVERLAP:
5892         {
5893                 size_t left_align, right_align;
5894                 left_align  = align_of(state, type->left);
5895                 right_align = align_of(state, type->right);
5896                 align = (left_align >= right_align) ? left_align : right_align;
5897                 break;
5898         }
5899         case TYPE_ARRAY:
5900                 align = align_of(state, type->left);
5901                 break;
5902         case TYPE_STRUCT:
5903         case TYPE_TUPLE:
5904         case TYPE_UNION:
5905         case TYPE_JOIN:
5906                 align = align_of(state, type->left);
5907                 break;
5908         default:
5909                 error(state, 0, "alignof not yet defined for type\n");
5910                 break;
5911         }
5912         return align;
5913 }
5914
5915 static size_t reg_align_of(struct compile_state *state, struct type *type)
5916 {
5917         size_t align;
5918         align = 0;
5919         switch(type->type & TYPE_MASK) {
5920         case TYPE_VOID:
5921                 align = 1;
5922                 break;
5923         case TYPE_BITFIELD:
5924                 align = 1;
5925                 break;
5926         case TYPE_CHAR:
5927         case TYPE_UCHAR:
5928                 align = REG_ALIGNOF_CHAR;
5929                 break;
5930         case TYPE_SHORT:
5931         case TYPE_USHORT:
5932                 align = REG_ALIGNOF_SHORT;
5933                 break;
5934         case TYPE_INT:
5935         case TYPE_UINT:
5936         case TYPE_ENUM:
5937                 align = REG_ALIGNOF_INT;
5938                 break;
5939         case TYPE_LONG:
5940         case TYPE_ULONG:
5941                 align = REG_ALIGNOF_LONG;
5942                 break;
5943         case TYPE_POINTER:
5944                 align = REG_ALIGNOF_POINTER;
5945                 break;
5946         case TYPE_PRODUCT:
5947         case TYPE_OVERLAP:
5948         {
5949                 size_t left_align, right_align;
5950                 left_align  = reg_align_of(state, type->left);
5951                 right_align = reg_align_of(state, type->right);
5952                 align = (left_align >= right_align) ? left_align : right_align;
5953                 break;
5954         }
5955         case TYPE_ARRAY:
5956                 align = reg_align_of(state, type->left);
5957                 break;
5958         case TYPE_STRUCT:
5959         case TYPE_UNION:
5960         case TYPE_TUPLE:
5961         case TYPE_JOIN:
5962                 align = reg_align_of(state, type->left);
5963                 break;
5964         default:
5965                 error(state, 0, "alignof not yet defined for type\n");
5966                 break;
5967         }
5968         return align;
5969 }
5970
5971 static size_t align_of_in_bytes(struct compile_state *state, struct type *type)
5972 {
5973         return bits_to_bytes(align_of(state, type));
5974 }
5975 static size_t size_of(struct compile_state *state, struct type *type);
5976 static size_t reg_size_of(struct compile_state *state, struct type *type);
5977
5978 static size_t needed_padding(struct compile_state *state, 
5979         struct type *type, size_t offset)
5980 {
5981         size_t padding, align;
5982         align = align_of(state, type);
5983         /* Align to the next machine word if the bitfield does completely
5984          * fit into the current word.
5985          */
5986         if ((type->type & TYPE_MASK) == TYPE_BITFIELD) {
5987                 size_t size;
5988                 size = size_of(state, type);
5989                 if ((offset + type->elements)/size != offset/size) {
5990                         align = size;
5991                 }
5992         }
5993         padding = 0;
5994         if (offset % align) {
5995                 padding = align - (offset % align);
5996         }
5997         return padding;
5998 }
5999
6000 static size_t reg_needed_padding(struct compile_state *state, 
6001         struct type *type, size_t offset)
6002 {
6003         size_t padding, align;
6004         align = reg_align_of(state, type);
6005         /* Align to the next register word if the bitfield does completely
6006          * fit into the current register.
6007          */
6008         if (((type->type & TYPE_MASK) == TYPE_BITFIELD) &&
6009                 (((offset + type->elements)/REG_SIZEOF_REG) != (offset/REG_SIZEOF_REG))) 
6010         {
6011                 align = REG_SIZEOF_REG;
6012         }
6013         padding = 0;
6014         if (offset % align) {
6015                 padding = align - (offset % align);
6016         }
6017         return padding;
6018 }
6019
6020 static size_t size_of(struct compile_state *state, struct type *type)
6021 {
6022         size_t size;
6023         size = 0;
6024         switch(type->type & TYPE_MASK) {
6025         case TYPE_VOID:
6026                 size = 0;
6027                 break;
6028         case TYPE_BITFIELD:
6029                 size = type->elements;
6030                 break;
6031         case TYPE_CHAR:
6032         case TYPE_UCHAR:
6033                 size = SIZEOF_CHAR;
6034                 break;
6035         case TYPE_SHORT:
6036         case TYPE_USHORT:
6037                 size = SIZEOF_SHORT;
6038                 break;
6039         case TYPE_INT:
6040         case TYPE_UINT:
6041         case TYPE_ENUM:
6042                 size = SIZEOF_INT;
6043                 break;
6044         case TYPE_LONG:
6045         case TYPE_ULONG:
6046                 size = SIZEOF_LONG;
6047                 break;
6048         case TYPE_POINTER:
6049                 size = SIZEOF_POINTER;
6050                 break;
6051         case TYPE_PRODUCT:
6052         {
6053                 size_t pad;
6054                 size = 0;
6055                 while((type->type & TYPE_MASK) == TYPE_PRODUCT) {
6056                         pad = needed_padding(state, type->left, size);
6057                         size = size + pad + size_of(state, type->left);
6058                         type = type->right;
6059                 }
6060                 pad = needed_padding(state, type, size);
6061                 size = size + pad + size_of(state, type);
6062                 break;
6063         }
6064         case TYPE_OVERLAP:
6065         {
6066                 size_t size_left, size_right;
6067                 size_left = size_of(state, type->left);
6068                 size_right = size_of(state, type->right);
6069                 size = (size_left >= size_right)? size_left : size_right;
6070                 break;
6071         }
6072         case TYPE_ARRAY:
6073                 if (type->elements == ELEMENT_COUNT_UNSPECIFIED) {
6074                         internal_error(state, 0, "Invalid array type");
6075                 } else {
6076                         size = size_of(state, type->left) * type->elements;
6077                 }
6078                 break;
6079         case TYPE_STRUCT:
6080         case TYPE_TUPLE:
6081         {
6082                 size_t pad;
6083                 size = size_of(state, type->left);
6084                 /* Pad structures so their size is a multiples of their alignment */
6085                 pad = needed_padding(state, type, size);
6086                 size = size + pad;
6087                 break;
6088         }
6089         case TYPE_UNION:
6090         case TYPE_JOIN:
6091         {
6092                 size_t pad;
6093                 size = size_of(state, type->left);
6094                 /* Pad unions so their size is a multiple of their alignment */
6095                 pad = needed_padding(state, type, size);
6096                 size = size + pad;
6097                 break;
6098         }
6099         default:
6100                 internal_error(state, 0, "sizeof not yet defined for type");
6101                 break;
6102         }
6103         return size;
6104 }
6105
6106 static size_t reg_size_of(struct compile_state *state, struct type *type)
6107 {
6108         size_t size;
6109         size = 0;
6110         switch(type->type & TYPE_MASK) {
6111         case TYPE_VOID:
6112                 size = 0;
6113                 break;
6114         case TYPE_BITFIELD:
6115                 size = type->elements;
6116                 break;
6117         case TYPE_CHAR:
6118         case TYPE_UCHAR:
6119                 size = REG_SIZEOF_CHAR;
6120                 break;
6121         case TYPE_SHORT:
6122         case TYPE_USHORT:
6123                 size = REG_SIZEOF_SHORT;
6124                 break;
6125         case TYPE_INT:
6126         case TYPE_UINT:
6127         case TYPE_ENUM:
6128                 size = REG_SIZEOF_INT;
6129                 break;
6130         case TYPE_LONG:
6131         case TYPE_ULONG:
6132                 size = REG_SIZEOF_LONG;
6133                 break;
6134         case TYPE_POINTER:
6135                 size = REG_SIZEOF_POINTER;
6136                 break;
6137         case TYPE_PRODUCT:
6138         {
6139                 size_t pad;
6140                 size = 0;
6141                 while((type->type & TYPE_MASK) == TYPE_PRODUCT) {
6142                         pad = reg_needed_padding(state, type->left, size);
6143                         size = size + pad + reg_size_of(state, type->left);
6144                         type = type->right;
6145                 }
6146                 pad = reg_needed_padding(state, type, size);
6147                 size = size + pad + reg_size_of(state, type);
6148                 break;
6149         }
6150         case TYPE_OVERLAP:
6151         {
6152                 size_t size_left, size_right;
6153                 size_left  = reg_size_of(state, type->left);
6154                 size_right = reg_size_of(state, type->right);
6155                 size = (size_left >= size_right)? size_left : size_right;
6156                 break;
6157         }
6158         case TYPE_ARRAY:
6159                 if (type->elements == ELEMENT_COUNT_UNSPECIFIED) {
6160                         internal_error(state, 0, "Invalid array type");
6161                 } else {
6162                         size = reg_size_of(state, type->left) * type->elements;
6163                 }
6164                 break;
6165         case TYPE_STRUCT:
6166         case TYPE_TUPLE:
6167         {
6168                 size_t pad;
6169                 size = reg_size_of(state, type->left);
6170                 /* Pad structures so their size is a multiples of their alignment */
6171                 pad = reg_needed_padding(state, type, size);
6172                 size = size + pad;
6173                 break;
6174         }
6175         case TYPE_UNION:
6176         case TYPE_JOIN:
6177         {
6178                 size_t pad;
6179                 size = reg_size_of(state, type->left);
6180                 /* Pad unions so their size is a multiple of their alignment */
6181                 pad = reg_needed_padding(state, type, size);
6182                 size = size + pad;
6183                 break;
6184         }
6185         default:
6186                 internal_error(state, 0, "sizeof not yet defined for type");
6187                 break;
6188         }
6189         return size;
6190 }
6191
6192 static size_t registers_of(struct compile_state *state, struct type *type)
6193 {
6194         size_t registers;
6195         registers = reg_size_of(state, type);
6196         registers += REG_SIZEOF_REG - 1;
6197         registers /= REG_SIZEOF_REG;
6198         return registers;
6199 }
6200
6201 static size_t size_of_in_bytes(struct compile_state *state, struct type *type)
6202 {
6203         return bits_to_bytes(size_of(state, type));
6204 }
6205
6206 static size_t field_offset(struct compile_state *state, 
6207         struct type *type, struct hash_entry *field)
6208 {
6209         struct type *member;
6210         size_t size;
6211
6212         size = 0;
6213         member = 0;
6214         if ((type->type & TYPE_MASK) == TYPE_STRUCT) {
6215                 member = type->left;
6216                 while(member && ((member->type & TYPE_MASK) == TYPE_PRODUCT)) {
6217                         size += needed_padding(state, member->left, size);
6218                         if (member->left->field_ident == field) {
6219                                 member = member->left;
6220                                 break;
6221                         }
6222                         size += size_of(state, member->left);
6223                         member = member->right;
6224                 }
6225                 size += needed_padding(state, member, size);
6226         }
6227         else if ((type->type & TYPE_MASK) == TYPE_UNION) {
6228                 member = type->left;
6229                 while(member && ((member->type & TYPE_MASK) == TYPE_OVERLAP)) {
6230                         if (member->left->field_ident == field) {
6231                                 member = member->left;
6232                                 break;
6233                         }
6234                         member = member->right;
6235                 }
6236         }
6237         else {
6238                 internal_error(state, 0, "field_offset only works on structures and unions");
6239         }
6240
6241         if (!member || (member->field_ident != field)) {
6242                 error(state, 0, "member %s not present", field->name);
6243         }
6244         return size;
6245 }
6246
6247 static size_t field_reg_offset(struct compile_state *state, 
6248         struct type *type, struct hash_entry *field)
6249 {
6250         struct type *member;
6251         size_t size;
6252
6253         size = 0;
6254         member = 0;
6255         if ((type->type & TYPE_MASK) == TYPE_STRUCT) {
6256                 member = type->left;
6257                 while(member && ((member->type & TYPE_MASK) == TYPE_PRODUCT)) {
6258                         size += reg_needed_padding(state, member->left, size);
6259                         if (member->left->field_ident == field) {
6260                                 member = member->left;
6261                                 break;
6262                         }
6263                         size += reg_size_of(state, member->left);
6264                         member = member->right;
6265                 }
6266         }
6267         else if ((type->type & TYPE_MASK) == TYPE_UNION) {
6268                 member = type->left;
6269                 while(member && ((member->type & TYPE_MASK) == TYPE_OVERLAP)) {
6270                         if (member->left->field_ident == field) {
6271                                 member = member->left;
6272                                 break;
6273                         }
6274                         member = member->right;
6275                 }
6276         }
6277         else {
6278                 internal_error(state, 0, "field_reg_offset only works on structures and unions");
6279         }
6280
6281         size += reg_needed_padding(state, member, size);
6282         if (!member || (member->field_ident != field)) {
6283                 error(state, 0, "member %s not present", field->name);
6284         }
6285         return size;
6286 }
6287
6288 static struct type *field_type(struct compile_state *state, 
6289         struct type *type, struct hash_entry *field)
6290 {
6291         struct type *member;
6292
6293         member = 0;
6294         if ((type->type & TYPE_MASK) == TYPE_STRUCT) {
6295                 member = type->left;
6296                 while(member && ((member->type & TYPE_MASK) == TYPE_PRODUCT)) {
6297                         if (member->left->field_ident == field) {
6298                                 member = member->left;
6299                                 break;
6300                         }
6301                         member = member->right;
6302                 }
6303         }
6304         else if ((type->type & TYPE_MASK) == TYPE_UNION) {
6305                 member = type->left;
6306                 while(member && ((member->type & TYPE_MASK) == TYPE_OVERLAP)) {
6307                         if (member->left->field_ident == field) {
6308                                 member = member->left;
6309                                 break;
6310                         }
6311                         member = member->right;
6312                 }
6313         }
6314         else {
6315                 internal_error(state, 0, "field_type only works on structures and unions");
6316         }
6317         
6318         if (!member || (member->field_ident != field)) {
6319                 error(state, 0, "member %s not present", field->name);
6320         }
6321         return member;
6322 }
6323
6324 static size_t index_offset(struct compile_state *state, 
6325         struct type *type, ulong_t index)
6326 {
6327         struct type *member;
6328         size_t size;
6329         size = 0;
6330         if ((type->type & TYPE_MASK) == TYPE_ARRAY) {
6331                 size = size_of(state, type->left) * index;
6332         }
6333         else if ((type->type & TYPE_MASK) == TYPE_TUPLE) {
6334                 ulong_t i;
6335                 member = type->left;
6336                 i = 0;
6337                 while(member && ((member->type & TYPE_MASK) == TYPE_PRODUCT)) {
6338                         size += needed_padding(state, member->left, size);
6339                         if (i == index) {
6340                                 member = member->left;
6341                                 break;
6342                         }
6343                         size += size_of(state, member->left);
6344                         i++;
6345                         member = member->right;
6346                 }
6347                 size += needed_padding(state, member, size);
6348                 if (i != index) {
6349                         internal_error(state, 0, "Missing member index: %u", index);
6350                 }
6351         }
6352         else if ((type->type & TYPE_MASK) == TYPE_JOIN) {
6353                 ulong_t i;
6354                 size = 0;
6355                 member = type->left;
6356                 i = 0;
6357                 while(member && ((member->type & TYPE_MASK) == TYPE_OVERLAP)) {
6358                         if (i == index) {
6359                                 member = member->left;
6360                                 break;
6361                         }
6362                         i++;
6363                         member = member->right;
6364                 }
6365                 if (i != index) {
6366                         internal_error(state, 0, "Missing member index: %u", index);
6367                 }
6368         }
6369         else {
6370                 internal_error(state, 0, 
6371                         "request for index %u in something not an array, tuple or join",
6372                         index);
6373         }
6374         return size;
6375 }
6376
6377 static size_t index_reg_offset(struct compile_state *state, 
6378         struct type *type, ulong_t index)
6379 {
6380         struct type *member;
6381         size_t size;
6382         size = 0;
6383         if ((type->type & TYPE_MASK) == TYPE_ARRAY) {
6384                 size = reg_size_of(state, type->left) * index;
6385         }
6386         else if ((type->type & TYPE_MASK) == TYPE_TUPLE) {
6387                 ulong_t i;
6388                 member = type->left;
6389                 i = 0;
6390                 while(member && ((member->type & TYPE_MASK) == TYPE_PRODUCT)) {
6391                         size += reg_needed_padding(state, member->left, size);
6392                         if (i == index) {
6393                                 member = member->left;
6394                                 break;
6395                         }
6396                         size += reg_size_of(state, member->left);
6397                         i++;
6398                         member = member->right;
6399                 }
6400                 size += reg_needed_padding(state, member, size);
6401                 if (i != index) {
6402                         internal_error(state, 0, "Missing member index: %u", index);
6403                 }
6404                 
6405         }
6406         else if ((type->type & TYPE_MASK) == TYPE_JOIN) {
6407                 ulong_t i;
6408                 size = 0;
6409                 member = type->left;
6410                 i = 0;
6411                 while(member && ((member->type & TYPE_MASK) == TYPE_OVERLAP)) {
6412                         if (i == index) {
6413                                 member = member->left;
6414                                 break;
6415                         }
6416                         i++;
6417                         member = member->right;
6418                 }
6419                 if (i != index) {
6420                         internal_error(state, 0, "Missing member index: %u", index);
6421                 }
6422         }
6423         else {
6424                 internal_error(state, 0, 
6425                         "request for index %u in something not an array, tuple or join",
6426                         index);
6427         }
6428         return size;
6429 }
6430
6431 static struct type *index_type(struct compile_state *state,
6432         struct type *type, ulong_t index)
6433 {
6434         struct type *member;
6435         if (index >= type->elements) {
6436                 internal_error(state, 0, "Invalid element %u requested", index);
6437         }
6438         if ((type->type & TYPE_MASK) == TYPE_ARRAY) {
6439                 member = type->left;
6440         }
6441         else if ((type->type & TYPE_MASK) == TYPE_TUPLE) {
6442                 ulong_t i;
6443                 member = type->left;
6444                 i = 0;
6445                 while(member && ((member->type & TYPE_MASK) == TYPE_PRODUCT)) {
6446                         if (i == index) {
6447                                 member = member->left;
6448                                 break;
6449                         }
6450                         i++;
6451                         member = member->right;
6452                 }
6453                 if (i != index) {
6454                         internal_error(state, 0, "Missing member index: %u", index);
6455                 }
6456         }
6457         else if ((type->type & TYPE_MASK) == TYPE_JOIN) {
6458                 ulong_t i;
6459                 member = type->left;
6460                 i = 0;
6461                 while(member && ((member->type & TYPE_MASK) == TYPE_OVERLAP)) {
6462                         if (i == index) {
6463                                 member = member->left;
6464                                 break;
6465                         }
6466                         i++;
6467                         member = member->right;
6468                 }
6469                 if (i != index) {
6470                         internal_error(state, 0, "Missing member index: %u", index);
6471                 }
6472         }
6473         else {
6474                 member = 0;
6475                 internal_error(state, 0, 
6476                         "request for index %u in something not an array, tuple or join",
6477                         index);
6478         }
6479         return member;
6480 }
6481
6482 static struct type *unpack_type(struct compile_state *state, struct type *type)
6483 {
6484         /* If I have a single register compound type not a bit-field
6485          * find the real type.
6486          */
6487         struct type *start_type;
6488         size_t size;
6489         /* Get out early if I need multiple registers for this type */
6490         size = reg_size_of(state, type);
6491         if (size > REG_SIZEOF_REG) {
6492                 return type;
6493         }
6494         /* Get out early if I don't need any registers for this type */
6495         if (size == 0) {
6496                 return &void_type;
6497         }
6498         /* Loop until I have no more layers I can remove */
6499         do {
6500                 start_type = type;
6501                 switch(type->type & TYPE_MASK) {
6502                 case TYPE_ARRAY:
6503                         /* If I have a single element the unpacked type
6504                          * is that element.
6505                          */
6506                         if (type->elements == 1) {
6507                                 type = type->left;
6508                         }
6509                         break;
6510                 case TYPE_STRUCT:
6511                 case TYPE_TUPLE:
6512                         /* If I have a single element the unpacked type
6513                          * is that element.
6514                          */
6515                         if (type->elements == 1) {
6516                                 type = type->left;
6517                         }
6518                         /* If I have multiple elements the unpacked
6519                          * type is the non-void element.
6520                          */
6521                         else {
6522                                 struct type *next, *member;
6523                                 struct type *sub_type;
6524                                 sub_type = 0;
6525                                 next = type->left;
6526                                 while(next) {
6527                                         member = next;
6528                                         next = 0;
6529                                         if ((member->type & TYPE_MASK) == TYPE_PRODUCT) {
6530                                                 next = member->right;
6531                                                 member = member->left;
6532                                         }
6533                                         if (reg_size_of(state, member) > 0) {
6534                                                 if (sub_type) {
6535                                                         internal_error(state, 0, "true compound type in a register");
6536                                                 }
6537                                                 sub_type = member;
6538                                         }
6539                                 }
6540                                 if (sub_type) {
6541                                         type = sub_type;
6542                                 }
6543                         }
6544                         break;
6545
6546                 case TYPE_UNION:
6547                 case TYPE_JOIN:
6548                         /* If I have a single element the unpacked type
6549                          * is that element.
6550                          */
6551                         if (type->elements == 1) {
6552                                 type = type->left;
6553                         }
6554                         /* I can't in general unpack union types */
6555                         break;
6556                 default:
6557                         /* If I'm not a compound type I can't unpack it */
6558                         break;
6559                 }
6560         } while(start_type != type);
6561         switch(type->type & TYPE_MASK) {
6562         case TYPE_STRUCT:
6563         case TYPE_ARRAY:
6564         case TYPE_TUPLE:
6565                 internal_error(state, 0, "irredicible type?");
6566                 break;
6567         }
6568         return type;
6569 }
6570
6571 static int equiv_types(struct type *left, struct type *right);
6572 static int is_compound_type(struct type *type);
6573
6574 static struct type *reg_type(
6575         struct compile_state *state, struct type *type, int reg_offset)
6576 {
6577         struct type *member;
6578         size_t size;
6579 #if 1
6580         struct type *invalid;
6581         invalid = invalid_type(state, type);
6582         if (invalid) {
6583                 fprintf(state->errout, "type: ");
6584                 name_of(state->errout, type);
6585                 fprintf(state->errout, "\n");
6586                 fprintf(state->errout, "invalid: ");
6587                 name_of(state->errout, invalid);
6588                 fprintf(state->errout, "\n");
6589                 internal_error(state, 0, "bad input type?");
6590         }
6591 #endif
6592
6593         size = reg_size_of(state, type);
6594         if (reg_offset > size) {
6595                 member = 0;
6596                 fprintf(state->errout, "type: ");
6597                 name_of(state->errout, type);
6598                 fprintf(state->errout, "\n");
6599                 internal_error(state, 0, "offset outside of type");
6600         }
6601         else {
6602                 switch(type->type & TYPE_MASK) {
6603                         /* Don't do anything with the basic types */
6604                 case TYPE_VOID:
6605                 case TYPE_CHAR:         case TYPE_UCHAR:
6606                 case TYPE_SHORT:        case TYPE_USHORT:
6607                 case TYPE_INT:          case TYPE_UINT:
6608                 case TYPE_LONG:         case TYPE_ULONG:
6609                 case TYPE_LLONG:        case TYPE_ULLONG:
6610                 case TYPE_FLOAT:        case TYPE_DOUBLE:
6611                 case TYPE_LDOUBLE:
6612                 case TYPE_POINTER:
6613                 case TYPE_ENUM:
6614                 case TYPE_BITFIELD:
6615                         member = type;
6616                         break;
6617                 case TYPE_ARRAY:
6618                         member = type->left;
6619                         size = reg_size_of(state, member);
6620                         if (size > REG_SIZEOF_REG) {
6621                                 member = reg_type(state, member, reg_offset % size);
6622                         }
6623                         break;
6624                 case TYPE_STRUCT:
6625                 case TYPE_TUPLE:
6626                 {
6627                         size_t offset;
6628                         offset = 0;
6629                         member = type->left;
6630                         while(member && ((member->type & TYPE_MASK) == TYPE_PRODUCT)) {
6631                                 size = reg_size_of(state, member->left);
6632                                 offset += reg_needed_padding(state, member->left, offset);
6633                                 if ((offset + size) > reg_offset) {
6634                                         member = member->left;
6635                                         break;
6636                                 }
6637                                 offset += size;
6638                                 member = member->right;
6639                         }
6640                         offset += reg_needed_padding(state, member, offset);
6641                         member = reg_type(state, member, reg_offset - offset);
6642                         break;
6643                 }
6644                 case TYPE_UNION:
6645                 case TYPE_JOIN:
6646                 {
6647                         struct type *join, **jnext, *mnext;
6648                         join = new_type(TYPE_JOIN, 0, 0);
6649                         jnext = &join->left;
6650                         mnext = type->left;
6651                         while(mnext) {
6652                                 size_t size;
6653                                 member = mnext;
6654                                 mnext = 0;
6655                                 if ((member->type & TYPE_MASK) == TYPE_OVERLAP) {
6656                                         mnext = member->right;
6657                                         member = member->left;
6658                                 }
6659                                 size = reg_size_of(state, member);
6660                                 if (size > reg_offset) {
6661                                         struct type *part, *hunt;
6662                                         part = reg_type(state, member, reg_offset);
6663                                         /* See if this type is already in the union */
6664                                         hunt = join->left;
6665                                         while(hunt) {
6666                                                 struct type *test = hunt;
6667                                                 hunt = 0;
6668                                                 if ((test->type & TYPE_MASK) == TYPE_OVERLAP) {
6669                                                         hunt = test->right;
6670                                                         test = test->left;
6671                                                 }
6672                                                 if (equiv_types(part, test)) {
6673                                                         goto next;
6674                                                 }
6675                                         }
6676                                         /* Nope add it */
6677                                         if (!*jnext) {
6678                                                 *jnext = part;
6679                                         } else {
6680                                                 *jnext = new_type(TYPE_OVERLAP, *jnext, part);
6681                                                 jnext = &(*jnext)->right;
6682                                         }
6683                                         join->elements++;
6684                                 }
6685                         next:
6686                                 ;
6687                         }
6688                         if (join->elements == 0) {
6689                                 internal_error(state, 0, "No elements?");
6690                         }
6691                         member = join;
6692                         break;
6693                 }
6694                 default:
6695                         member = 0;
6696                         fprintf(state->errout, "type: ");
6697                         name_of(state->errout, type);
6698                         fprintf(state->errout, "\n");
6699                         internal_error(state, 0, "reg_type not yet defined for type");
6700                         
6701                 }
6702         }
6703         /* If I have a single register compound type not a bit-field
6704          * find the real type.
6705          */
6706         member = unpack_type(state, member);
6707                 ;
6708         size  = reg_size_of(state, member);
6709         if (size > REG_SIZEOF_REG) {
6710                 internal_error(state, 0, "Cannot find type of single register");
6711         }
6712 #if 1
6713         invalid = invalid_type(state, member);
6714         if (invalid) {
6715                 fprintf(state->errout, "type: ");
6716                 name_of(state->errout, member);
6717                 fprintf(state->errout, "\n");
6718                 fprintf(state->errout, "invalid: ");
6719                 name_of(state->errout, invalid);
6720                 fprintf(state->errout, "\n");
6721                 internal_error(state, 0, "returning bad type?");
6722         }
6723 #endif
6724         return member;
6725 }
6726
6727 static struct type *next_field(struct compile_state *state,
6728         struct type *type, struct type *prev_member) 
6729 {
6730         struct type *member;
6731         if ((type->type & TYPE_MASK) != TYPE_STRUCT) {
6732                 internal_error(state, 0, "next_field only works on structures");
6733         }
6734         member = type->left;
6735         while((member->type & TYPE_MASK) == TYPE_PRODUCT) {
6736                 if (!prev_member) {
6737                         member = member->left;
6738                         break;
6739                 }
6740                 if (member->left == prev_member) {
6741                         prev_member = 0;
6742                 }
6743                 member = member->right;
6744         }
6745         if (member == prev_member) {
6746                 prev_member = 0;
6747         }
6748         if (prev_member) {
6749                 internal_error(state, 0, "prev_member %s not present", 
6750                         prev_member->field_ident->name);
6751         }
6752         return member;
6753 }
6754
6755 typedef void (*walk_type_fields_cb_t)(struct compile_state *state, struct type *type, 
6756         size_t ret_offset, size_t mem_offset, void *arg);
6757
6758 static void walk_type_fields(struct compile_state *state,
6759         struct type *type, size_t reg_offset, size_t mem_offset,
6760         walk_type_fields_cb_t cb, void *arg);
6761
6762 static void walk_struct_fields(struct compile_state *state,
6763         struct type *type, size_t reg_offset, size_t mem_offset,
6764         walk_type_fields_cb_t cb, void *arg)
6765 {
6766         struct type *tptr;
6767         ulong_t i;
6768         if ((type->type & TYPE_MASK) != TYPE_STRUCT) {
6769                 internal_error(state, 0, "walk_struct_fields only works on structures");
6770         }
6771         tptr = type->left;
6772         for(i = 0; i < type->elements; i++) {
6773                 struct type *mtype;
6774                 mtype = tptr;
6775                 if ((mtype->type & TYPE_MASK) == TYPE_PRODUCT) {
6776                         mtype = mtype->left;
6777                 }
6778                 walk_type_fields(state, mtype, 
6779                         reg_offset + 
6780                         field_reg_offset(state, type, mtype->field_ident),
6781                         mem_offset + 
6782                         field_offset(state, type, mtype->field_ident),
6783                         cb, arg);
6784                 tptr = tptr->right;
6785         }
6786         
6787 }
6788
6789 static void walk_type_fields(struct compile_state *state,
6790         struct type *type, size_t reg_offset, size_t mem_offset,
6791         walk_type_fields_cb_t cb, void *arg)
6792 {
6793         switch(type->type & TYPE_MASK) {
6794         case TYPE_STRUCT:
6795                 walk_struct_fields(state, type, reg_offset, mem_offset, cb, arg);
6796                 break;
6797         case TYPE_CHAR:
6798         case TYPE_UCHAR:
6799         case TYPE_SHORT:
6800         case TYPE_USHORT:
6801         case TYPE_INT:
6802         case TYPE_UINT:
6803         case TYPE_LONG:
6804         case TYPE_ULONG:
6805                 cb(state, type, reg_offset, mem_offset, arg);
6806                 break;
6807         case TYPE_VOID:
6808                 break;
6809         default:
6810                 internal_error(state, 0, "walk_type_fields not yet implemented for type");
6811         }
6812 }
6813
6814 static void arrays_complete(struct compile_state *state, struct type *type)
6815 {
6816         if ((type->type & TYPE_MASK) == TYPE_ARRAY) {
6817                 if (type->elements == ELEMENT_COUNT_UNSPECIFIED) {
6818                         error(state, 0, "array size not specified");
6819                 }
6820                 arrays_complete(state, type->left);
6821         }
6822 }
6823
6824 static unsigned int get_basic_type(struct type *type)
6825 {
6826         unsigned int basic;
6827         basic = type->type & TYPE_MASK;
6828         /* Convert enums to ints */
6829         if (basic == TYPE_ENUM) {
6830                 basic = TYPE_INT;
6831         }
6832         /* Convert bitfields to standard types */
6833         else if (basic == TYPE_BITFIELD) {
6834                 if (type->elements <= SIZEOF_CHAR) {
6835                         basic = TYPE_CHAR;
6836                 }
6837                 else if (type->elements <= SIZEOF_SHORT) {
6838                         basic = TYPE_SHORT;
6839                 }
6840                 else if (type->elements <= SIZEOF_INT) {
6841                         basic = TYPE_INT;
6842                 }
6843                 else if (type->elements <= SIZEOF_LONG) {
6844                         basic = TYPE_LONG;
6845                 }
6846                 if (!TYPE_SIGNED(type->left->type)) {
6847                         basic += 1;
6848                 }
6849         }
6850         return basic;
6851 }
6852
6853 static unsigned int do_integral_promotion(unsigned int type)
6854 {
6855         if (TYPE_INTEGER(type) && (TYPE_RANK(type) < TYPE_RANK(TYPE_INT))) {
6856                 type = TYPE_INT;
6857         }
6858         return type;
6859 }
6860
6861 static unsigned int do_arithmetic_conversion(
6862         unsigned int left, unsigned int right)
6863 {
6864         if ((left == TYPE_LDOUBLE) || (right == TYPE_LDOUBLE)) {
6865                 return TYPE_LDOUBLE;
6866         }
6867         else if ((left == TYPE_DOUBLE) || (right == TYPE_DOUBLE)) {
6868                 return TYPE_DOUBLE;
6869         }
6870         else if ((left == TYPE_FLOAT) || (right == TYPE_FLOAT)) {
6871                 return TYPE_FLOAT;
6872         }
6873         left = do_integral_promotion(left);
6874         right = do_integral_promotion(right);
6875         /* If both operands have the same size done */
6876         if (left == right) {
6877                 return left;
6878         }
6879         /* If both operands have the same signedness pick the larger */
6880         else if (!!TYPE_UNSIGNED(left) == !!TYPE_UNSIGNED(right)) {
6881                 return (TYPE_RANK(left) >= TYPE_RANK(right)) ? left : right;
6882         }
6883         /* If the signed type can hold everything use it */
6884         else if (TYPE_SIGNED(left) && (TYPE_RANK(left) > TYPE_RANK(right))) {
6885                 return left;
6886         }
6887         else if (TYPE_SIGNED(right) && (TYPE_RANK(right) > TYPE_RANK(left))) {
6888                 return right;
6889         }
6890         /* Convert to the unsigned type with the same rank as the signed type */
6891         else if (TYPE_SIGNED(left)) {
6892                 return TYPE_MKUNSIGNED(left);
6893         }
6894         else {
6895                 return TYPE_MKUNSIGNED(right);
6896         }
6897 }
6898
6899 /* see if two types are the same except for qualifiers */
6900 static int equiv_types(struct type *left, struct type *right)
6901 {
6902         unsigned int type;
6903         /* Error if the basic types do not match */
6904         if ((left->type & TYPE_MASK) != (right->type & TYPE_MASK)) {
6905                 return 0;
6906         }
6907         type = left->type & TYPE_MASK;
6908         /* If the basic types match and it is a void type we are done */
6909         if (type == TYPE_VOID) {
6910                 return 1;
6911         }
6912         /* For bitfields we need to compare the sizes */
6913         else if (type == TYPE_BITFIELD) {
6914                 return (left->elements == right->elements) &&
6915                         (TYPE_SIGNED(left->left->type) == TYPE_SIGNED(right->left->type));
6916         }
6917         /* if the basic types match and it is an arithmetic type we are done */
6918         else if (TYPE_ARITHMETIC(type)) {
6919                 return 1;
6920         }
6921         /* If it is a pointer type recurse and keep testing */
6922         else if (type == TYPE_POINTER) {
6923                 return equiv_types(left->left, right->left);
6924         }
6925         else if (type == TYPE_ARRAY) {
6926                 return (left->elements == right->elements) &&
6927                         equiv_types(left->left, right->left);
6928         }
6929         /* test for struct equality */
6930         else if (type == TYPE_STRUCT) {
6931                 return left->type_ident == right->type_ident;
6932         }
6933         /* test for union equality */
6934         else if (type == TYPE_UNION) {
6935                 return left->type_ident == right->type_ident;
6936         }
6937         /* Test for equivalent functions */
6938         else if (type == TYPE_FUNCTION) {
6939                 return equiv_types(left->left, right->left) &&
6940                         equiv_types(left->right, right->right);
6941         }
6942         /* We only see TYPE_PRODUCT as part of function equivalence matching */
6943         /* We also see TYPE_PRODUCT as part of of tuple equivalence matchin */
6944         else if (type == TYPE_PRODUCT) {
6945                 return equiv_types(left->left, right->left) &&
6946                         equiv_types(left->right, right->right);
6947         }
6948         /* We should see TYPE_OVERLAP when comparing joins */
6949         else if (type == TYPE_OVERLAP) {
6950                 return equiv_types(left->left, right->left) &&
6951                         equiv_types(left->right, right->right);
6952         }
6953         /* Test for equivalence of tuples */
6954         else if (type == TYPE_TUPLE) {
6955                 return (left->elements == right->elements) &&
6956                         equiv_types(left->left, right->left);
6957         }
6958         /* Test for equivalence of joins */
6959         else if (type == TYPE_JOIN) {
6960                 return (left->elements == right->elements) &&
6961                         equiv_types(left->left, right->left);
6962         }
6963         else {
6964                 return 0;
6965         }
6966 }
6967
6968 static int equiv_ptrs(struct type *left, struct type *right)
6969 {
6970         if (((left->type & TYPE_MASK) != TYPE_POINTER) ||
6971                 ((right->type & TYPE_MASK) != TYPE_POINTER)) {
6972                 return 0;
6973         }
6974         return equiv_types(left->left, right->left);
6975 }
6976
6977 static struct type *compatible_types(struct type *left, struct type *right)
6978 {
6979         struct type *result;
6980         unsigned int type, qual_type;
6981         /* Error if the basic types do not match */
6982         if ((left->type & TYPE_MASK) != (right->type & TYPE_MASK)) {
6983                 return 0;
6984         }
6985         type = left->type & TYPE_MASK;
6986         qual_type = (left->type & ~STOR_MASK) | (right->type & ~STOR_MASK);
6987         result = 0;
6988         /* if the basic types match and it is an arithmetic type we are done */
6989         if (TYPE_ARITHMETIC(type)) {
6990                 result = new_type(qual_type, 0, 0);
6991         }
6992         /* If it is a pointer type recurse and keep testing */
6993         else if (type == TYPE_POINTER) {
6994                 result = compatible_types(left->left, right->left);
6995                 if (result) {
6996                         result = new_type(qual_type, result, 0);
6997                 }
6998         }
6999         /* test for struct equality */
7000         else if (type == TYPE_STRUCT) {
7001                 if (left->type_ident == right->type_ident) {
7002                         result = left;
7003                 }
7004         }
7005         /* test for union equality */
7006         else if (type == TYPE_UNION) {
7007                 if (left->type_ident == right->type_ident) {
7008                         result = left;
7009                 }
7010         }
7011         /* Test for equivalent functions */
7012         else if (type == TYPE_FUNCTION) {
7013                 struct type *lf, *rf;
7014                 lf = compatible_types(left->left, right->left);
7015                 rf = compatible_types(left->right, right->right);
7016                 if (lf && rf) {
7017                         result = new_type(qual_type, lf, rf);
7018                 }
7019         }
7020         /* We only see TYPE_PRODUCT as part of function equivalence matching */
7021         else if (type == TYPE_PRODUCT) {
7022                 struct type *lf, *rf;
7023                 lf = compatible_types(left->left, right->left);
7024                 rf = compatible_types(left->right, right->right);
7025                 if (lf && rf) {
7026                         result = new_type(qual_type, lf, rf);
7027                 }
7028         }
7029         else {
7030                 /* Nothing else is compatible */
7031         }
7032         return result;
7033 }
7034
7035 /* See if left is a equivalent to right or right is a union member of left */
7036 static int is_subset_type(struct type *left, struct type *right)
7037 {
7038         if (equiv_types(left, right)) {
7039                 return 1;
7040         }
7041         if ((left->type & TYPE_MASK) == TYPE_JOIN) {
7042                 struct type *member, *mnext;
7043                 mnext = left->left;
7044                 while(mnext) {
7045                         member = mnext;
7046                         mnext = 0;
7047                         if ((member->type & TYPE_MASK) == TYPE_OVERLAP) {
7048                                 mnext = member->right;
7049                                 member = member->left;
7050                         }
7051                         if (is_subset_type( member, right)) {
7052                                 return 1;
7053                         }
7054                 }
7055         }
7056         return 0;
7057 }
7058
7059 static struct type *compatible_ptrs(struct type *left, struct type *right)
7060 {
7061         struct type *result;
7062         if (((left->type & TYPE_MASK) != TYPE_POINTER) ||
7063                 ((right->type & TYPE_MASK) != TYPE_POINTER)) {
7064                 return 0;
7065         }
7066         result = compatible_types(left->left, right->left);
7067         if (result) {
7068                 unsigned int qual_type;
7069                 qual_type = (left->type & ~STOR_MASK) | (right->type & ~STOR_MASK);
7070                 result = new_type(qual_type, result, 0);
7071         }
7072         return result;
7073         
7074 }
7075 static struct triple *integral_promotion(
7076         struct compile_state *state, struct triple *def)
7077 {
7078         struct type *type;
7079         type = def->type;
7080         /* As all operations are carried out in registers
7081          * the values are converted on load I just convert
7082          * logical type of the operand.
7083          */
7084         if (TYPE_INTEGER(type->type)) {
7085                 unsigned int int_type;
7086                 int_type = type->type & ~TYPE_MASK;
7087                 int_type |= do_integral_promotion(get_basic_type(type));
7088                 if (int_type != type->type) {
7089                         if (def->op != OP_LOAD) {
7090                                 def->type = new_type(int_type, 0, 0);
7091                         }
7092                         else {
7093                                 def = triple(state, OP_CONVERT, 
7094                                         new_type(int_type, 0, 0), def, 0);
7095                         }
7096                 }
7097         }
7098         return def;
7099 }
7100
7101
7102 static void arithmetic(struct compile_state *state, struct triple *def)
7103 {
7104         if (!TYPE_ARITHMETIC(def->type->type)) {
7105                 error(state, 0, "arithmetic type expexted");
7106         }
7107 }
7108
7109 static void ptr_arithmetic(struct compile_state *state, struct triple *def)
7110 {
7111         if (!TYPE_PTR(def->type->type) && !TYPE_ARITHMETIC(def->type->type)) {
7112                 error(state, def, "pointer or arithmetic type expected");
7113         }
7114 }
7115
7116 static int is_integral(struct triple *ins)
7117 {
7118         return TYPE_INTEGER(ins->type->type);
7119 }
7120
7121 static void integral(struct compile_state *state, struct triple *def)
7122 {
7123         if (!is_integral(def)) {
7124                 error(state, 0, "integral type expected");
7125         }
7126 }
7127
7128
7129 static void bool(struct compile_state *state, struct triple *def)
7130 {
7131         if (!TYPE_ARITHMETIC(def->type->type) &&
7132                 ((def->type->type & TYPE_MASK) != TYPE_POINTER)) {
7133                 error(state, 0, "arithmetic or pointer type expected");
7134         }
7135 }
7136
7137 static int is_signed(struct type *type)
7138 {
7139         if ((type->type & TYPE_MASK) == TYPE_BITFIELD) {
7140                 type = type->left;
7141         }
7142         return !!TYPE_SIGNED(type->type);
7143 }
7144 static int is_compound_type(struct type *type)
7145 {
7146         int is_compound;
7147         switch((type->type & TYPE_MASK)) {
7148         case TYPE_ARRAY:
7149         case TYPE_STRUCT:
7150         case TYPE_TUPLE:
7151         case TYPE_UNION:
7152         case TYPE_JOIN: 
7153                 is_compound = 1;
7154                 break;
7155         default:
7156                 is_compound = 0;
7157                 break;
7158         }
7159         return is_compound;
7160 }
7161
7162 /* Is this value located in a register otherwise it must be in memory */
7163 static int is_in_reg(struct compile_state *state, struct triple *def)
7164 {
7165         int in_reg;
7166         if (def->op == OP_ADECL) {
7167                 in_reg = 1;
7168         }
7169         else if ((def->op == OP_SDECL) || (def->op == OP_DEREF)) {
7170                 in_reg = 0;
7171         }
7172         else if (triple_is_part(state, def)) {
7173                 in_reg = is_in_reg(state, MISC(def, 0));
7174         }
7175         else {
7176                 internal_error(state, def, "unknown expr storage location");
7177                 in_reg = -1;
7178         }
7179         return in_reg;
7180 }
7181
7182 /* Is this an auto or static variable location? Something that can
7183  * be assigned to.  Otherwise it must must be a pure value, a temporary.
7184  */
7185 static int is_lvalue(struct compile_state *state, struct triple *def)
7186 {
7187         int ret;
7188         ret = 0;
7189         if (!def) {
7190                 return 0;
7191         }
7192         if ((def->op == OP_ADECL) || 
7193                 (def->op == OP_SDECL) || 
7194                 (def->op == OP_DEREF) ||
7195                 (def->op == OP_BLOBCONST) ||
7196                 (def->op == OP_LIST)) {
7197                 ret = 1;
7198         }
7199         else if (triple_is_part(state, def)) {
7200                 ret = is_lvalue(state, MISC(def, 0));
7201         }
7202         return ret;
7203 }
7204
7205 static void clvalue(struct compile_state *state, struct triple *def)
7206 {
7207         if (!def) {
7208                 internal_error(state, def, "nothing where lvalue expected?");
7209         }
7210         if (!is_lvalue(state, def)) { 
7211                 error(state, def, "lvalue expected");
7212         }
7213 }
7214 static void lvalue(struct compile_state *state, struct triple *def)
7215 {
7216         clvalue(state, def);
7217         if (def->type->type & QUAL_CONST) {
7218                 error(state, def, "modifable lvalue expected");
7219         }
7220 }
7221
7222 static int is_pointer(struct triple *def)
7223 {
7224         return (def->type->type & TYPE_MASK) == TYPE_POINTER;
7225 }
7226
7227 static void pointer(struct compile_state *state, struct triple *def)
7228 {
7229         if (!is_pointer(def)) {
7230                 error(state, def, "pointer expected");
7231         }
7232 }
7233
7234 static struct triple *int_const(
7235         struct compile_state *state, struct type *type, ulong_t value)
7236 {
7237         struct triple *result;
7238         switch(type->type & TYPE_MASK) {
7239         case TYPE_CHAR:
7240         case TYPE_INT:   case TYPE_UINT:
7241         case TYPE_LONG:  case TYPE_ULONG:
7242                 break;
7243         default:
7244                 internal_error(state, 0, "constant for unknown type");
7245         }
7246         result = triple(state, OP_INTCONST, type, 0, 0);
7247         result->u.cval = value;
7248         return result;
7249 }
7250
7251
7252 static struct triple *read_expr(struct compile_state *state, struct triple *def);
7253
7254 static struct triple *do_mk_addr_expr(struct compile_state *state, 
7255         struct triple *expr, struct type *type, ulong_t offset)
7256 {
7257         struct triple *result;
7258         struct type *ptr_type;
7259         clvalue(state, expr);
7260
7261         ptr_type = new_type(TYPE_POINTER | (type->type & QUAL_MASK), type, 0);
7262
7263         
7264         result = 0;
7265         if (expr->op == OP_ADECL) {
7266                 error(state, expr, "address of auto variables not supported");
7267         }
7268         else if (expr->op == OP_SDECL) {
7269                 result = triple(state, OP_ADDRCONST, ptr_type, 0, 0);
7270                 MISC(result, 0) = expr;
7271                 result->u.cval = offset;
7272         }
7273         else if (expr->op == OP_DEREF) {
7274                 result = triple(state, OP_ADD, ptr_type,
7275                         RHS(expr, 0),
7276                         int_const(state, &ulong_type, offset));
7277         }
7278         else if (expr->op == OP_BLOBCONST) {
7279                 FINISHME();
7280                 internal_error(state, expr, "not yet implemented");
7281         }
7282         else if (expr->op == OP_LIST) {
7283                 error(state, 0, "Function addresses not supported");
7284         }
7285         else if (triple_is_part(state, expr)) {
7286                 struct triple *part;
7287                 part = expr;
7288                 expr = MISC(expr, 0);
7289                 if (part->op == OP_DOT) {
7290                         offset += bits_to_bytes(
7291                                 field_offset(state, expr->type, part->u.field));
7292                 }
7293                 else if (part->op == OP_INDEX) {
7294                         offset += bits_to_bytes(
7295                                 index_offset(state, expr->type, part->u.cval));
7296                 }
7297                 else {
7298                         internal_error(state, part, "unhandled part type");
7299                 }
7300                 result = do_mk_addr_expr(state, expr, type, offset);
7301         }
7302         if (!result) {
7303                 internal_error(state, expr, "cannot take address of expression");
7304         }
7305         return result;
7306 }
7307
7308 static struct triple *mk_addr_expr(
7309         struct compile_state *state, struct triple *expr, ulong_t offset)
7310 {
7311         return do_mk_addr_expr(state, expr, expr->type, offset);
7312 }
7313
7314 static struct triple *mk_deref_expr(
7315         struct compile_state *state, struct triple *expr)
7316 {
7317         struct type *base_type;
7318         pointer(state, expr);
7319         base_type = expr->type->left;
7320         return triple(state, OP_DEREF, base_type, expr, 0);
7321 }
7322
7323 /* lvalue conversions always apply except when certain operators
7324  * are applied.  So I apply apply it when I know no more
7325  * operators will be applied.
7326  */
7327 static struct triple *lvalue_conversion(struct compile_state *state, struct triple *def)
7328 {
7329         /* Tranform an array to a pointer to the first element */
7330         if ((def->type->type & TYPE_MASK) == TYPE_ARRAY) {
7331                 struct type *type;
7332                 type = new_type(
7333                         TYPE_POINTER | (def->type->type & QUAL_MASK),
7334                         def->type->left, 0);
7335                 if ((def->op == OP_SDECL) || IS_CONST_OP(def->op)) {
7336                         struct triple *addrconst;
7337                         if ((def->op != OP_SDECL) && (def->op != OP_BLOBCONST)) {
7338                                 internal_error(state, def, "bad array constant");
7339                         }
7340                         addrconst = triple(state, OP_ADDRCONST, type, 0, 0);
7341                         MISC(addrconst, 0) = def;
7342                         def = addrconst;
7343                 }
7344                 else {
7345                         def = triple(state, OP_CONVERT, type, def, 0);
7346                 }
7347         }
7348         /* Transform a function to a pointer to it */
7349         else if ((def->type->type & TYPE_MASK) == TYPE_FUNCTION) {
7350                 def = mk_addr_expr(state, def, 0);
7351         }
7352         return def;
7353 }
7354
7355 static struct triple *deref_field(
7356         struct compile_state *state, struct triple *expr, struct hash_entry *field)
7357 {
7358         struct triple *result;
7359         struct type *type, *member;
7360         ulong_t offset;
7361         if (!field) {
7362                 internal_error(state, 0, "No field passed to deref_field");
7363         }
7364         result = 0;
7365         type = expr->type;
7366         if (((type->type & TYPE_MASK) != TYPE_STRUCT) &&
7367                 ((type->type & TYPE_MASK) != TYPE_UNION)) {
7368                 error(state, 0, "request for member %s in something not a struct or union",
7369                         field->name);
7370         }
7371         member = field_type(state, type, field);
7372         if ((type->type & STOR_MASK) == STOR_PERM) {
7373                 /* Do the pointer arithmetic to get a deref the field */
7374                 offset = bits_to_bytes(field_offset(state, type, field));
7375                 result = do_mk_addr_expr(state, expr, member, offset);
7376                 result = mk_deref_expr(state, result);
7377         }
7378         else {
7379                 /* Find the variable for the field I want. */
7380                 result = triple(state, OP_DOT, member, expr, 0);
7381                 result->u.field = field;
7382         }
7383         return result;
7384 }
7385
7386 static struct triple *deref_index(
7387         struct compile_state *state, struct triple *expr, size_t index)
7388 {
7389         struct triple *result;
7390         struct type *type, *member;
7391         ulong_t offset;
7392
7393         result = 0;
7394         type = expr->type;
7395         member = index_type(state, type, index);
7396
7397         if ((type->type & STOR_MASK) == STOR_PERM) {
7398                 offset = bits_to_bytes(index_offset(state, type, index));
7399                 result = do_mk_addr_expr(state, expr, member, offset);
7400                 result = mk_deref_expr(state, result);
7401         }
7402         else {
7403                 result = triple(state, OP_INDEX, member, expr, 0);
7404                 result->u.cval = index;
7405         }
7406         return result;
7407 }
7408
7409 static struct triple *read_expr(struct compile_state *state, struct triple *def)
7410 {
7411         int op;
7412         if  (!def) {
7413                 return 0;
7414         }
7415 #if DEBUG_ROMCC_WARNINGS
7416 #warning "CHECK_ME is this the only place I need to do lvalue conversions?"
7417 #endif
7418         /* Transform lvalues into something we can read */
7419         def = lvalue_conversion(state, def);
7420         if (!is_lvalue(state, def)) {
7421                 return def;
7422         }
7423         if (is_in_reg(state, def)) {
7424                 op = OP_READ;
7425         } else {
7426                 if (def->op == OP_SDECL) {
7427                         def = mk_addr_expr(state, def, 0);
7428                         def = mk_deref_expr(state, def);
7429                 }
7430                 op = OP_LOAD;
7431         }
7432         def = triple(state, op, def->type, def, 0);
7433         if (def->type->type & QUAL_VOLATILE) {
7434                 def->id |= TRIPLE_FLAG_VOLATILE;
7435         }
7436         return def;
7437 }
7438
7439 int is_write_compatible(struct compile_state *state, 
7440         struct type *dest, struct type *rval)
7441 {
7442         int compatible = 0;
7443         /* Both operands have arithmetic type */
7444         if (TYPE_ARITHMETIC(dest->type) && TYPE_ARITHMETIC(rval->type)) {
7445                 compatible = 1;
7446         }
7447         /* One operand is a pointer and the other is a pointer to void */
7448         else if (((dest->type & TYPE_MASK) == TYPE_POINTER) &&
7449                 ((rval->type & TYPE_MASK) == TYPE_POINTER) &&
7450                 (((dest->left->type & TYPE_MASK) == TYPE_VOID) ||
7451                         ((rval->left->type & TYPE_MASK) == TYPE_VOID))) {
7452                 compatible = 1;
7453         }
7454         /* If both types are the same without qualifiers we are good */
7455         else if (equiv_ptrs(dest, rval)) {
7456                 compatible = 1;
7457         }
7458         /* test for struct/union equality  */
7459         else if (equiv_types(dest, rval)) {
7460                 compatible = 1;
7461         }
7462         return compatible;
7463 }
7464
7465 static void write_compatible(struct compile_state *state,
7466         struct type *dest, struct type *rval)
7467 {
7468         if (!is_write_compatible(state, dest, rval)) {
7469                 FILE *fp = state->errout;
7470                 fprintf(fp, "dest: ");
7471                 name_of(fp, dest);
7472                 fprintf(fp,"\nrval: ");
7473                 name_of(fp, rval);
7474                 fprintf(fp, "\n");
7475                 error(state, 0, "Incompatible types in assignment");
7476         }
7477 }
7478
7479 static int is_init_compatible(struct compile_state *state,
7480         struct type *dest, struct type *rval)
7481 {
7482         int compatible = 0;
7483         if (is_write_compatible(state, dest, rval)) {
7484                 compatible = 1;
7485         }
7486         else if (equiv_types(dest, rval)) {
7487                 compatible = 1;
7488         }
7489         return compatible;
7490 }
7491
7492 static struct triple *write_expr(
7493         struct compile_state *state, struct triple *dest, struct triple *rval)
7494 {
7495         struct triple *def;
7496         int op;
7497
7498         def = 0;
7499         if (!rval) {
7500                 internal_error(state, 0, "missing rval");
7501         }
7502
7503         if (rval->op == OP_LIST) {
7504                 internal_error(state, 0, "expression of type OP_LIST?");
7505         }
7506         if (!is_lvalue(state, dest)) {
7507                 internal_error(state, 0, "writing to a non lvalue?");
7508         }
7509         if (dest->type->type & QUAL_CONST) {
7510                 internal_error(state, 0, "modifable lvalue expexted");
7511         }
7512
7513         write_compatible(state, dest->type, rval->type);
7514         if (!equiv_types(dest->type, rval->type)) {
7515                 rval = triple(state, OP_CONVERT, dest->type, rval, 0);
7516         }
7517
7518         /* Now figure out which assignment operator to use */
7519         op = -1;
7520         if (is_in_reg(state, dest)) {
7521                 def = triple(state, OP_WRITE, dest->type, rval, dest);
7522                 if (MISC(def, 0) != dest) {
7523                         internal_error(state, def, "huh?");
7524                 }
7525                 if (RHS(def, 0) != rval) {
7526                         internal_error(state, def, "huh?");
7527                 }
7528         } else {
7529                 def = triple(state, OP_STORE, dest->type, dest, rval);
7530         }
7531         if (def->type->type & QUAL_VOLATILE) {
7532                 def->id |= TRIPLE_FLAG_VOLATILE;
7533         }
7534         return def;
7535 }
7536
7537 static struct triple *init_expr(
7538         struct compile_state *state, struct triple *dest, struct triple *rval)
7539 {
7540         struct triple *def;
7541
7542         def = 0;
7543         if (!rval) {
7544                 internal_error(state, 0, "missing rval");
7545         }
7546         if ((dest->type->type & STOR_MASK) != STOR_PERM) {
7547                 rval = read_expr(state, rval);
7548                 def = write_expr(state, dest, rval);
7549         }
7550         else {
7551                 /* Fill in the array size if necessary */
7552                 if (((dest->type->type & TYPE_MASK) == TYPE_ARRAY) &&
7553                         ((rval->type->type & TYPE_MASK) == TYPE_ARRAY)) {
7554                         if (dest->type->elements == ELEMENT_COUNT_UNSPECIFIED) {
7555                                 dest->type->elements = rval->type->elements;
7556                         }
7557                 }
7558                 if (!equiv_types(dest->type, rval->type)) {
7559                         error(state, 0, "Incompatible types in inializer");
7560                 }
7561                 MISC(dest, 0) = rval;
7562                 insert_triple(state, dest, rval);
7563                 rval->id |= TRIPLE_FLAG_FLATTENED;
7564                 use_triple(MISC(dest, 0), dest);
7565         }
7566         return def;
7567 }
7568
7569 struct type *arithmetic_result(
7570         struct compile_state *state, struct triple *left, struct triple *right)
7571 {
7572         struct type *type;
7573         /* Sanity checks to ensure I am working with arithmetic types */
7574         arithmetic(state, left);
7575         arithmetic(state, right);
7576         type = new_type(
7577                 do_arithmetic_conversion(
7578                         get_basic_type(left->type),
7579                         get_basic_type(right->type)),
7580                 0, 0);
7581         return type;
7582 }
7583
7584 struct type *ptr_arithmetic_result(
7585         struct compile_state *state, struct triple *left, struct triple *right)
7586 {
7587         struct type *type;
7588         /* Sanity checks to ensure I am working with the proper types */
7589         ptr_arithmetic(state, left);
7590         arithmetic(state, right);
7591         if (TYPE_ARITHMETIC(left->type->type) && 
7592                 TYPE_ARITHMETIC(right->type->type)) {
7593                 type = arithmetic_result(state, left, right);
7594         }
7595         else if (TYPE_PTR(left->type->type)) {
7596                 type = left->type;
7597         }
7598         else {
7599                 internal_error(state, 0, "huh?");
7600                 type = 0;
7601         }
7602         return type;
7603 }
7604
7605 /* boolean helper function */
7606
7607 static struct triple *ltrue_expr(struct compile_state *state, 
7608         struct triple *expr)
7609 {
7610         switch(expr->op) {
7611         case OP_LTRUE:   case OP_LFALSE:  case OP_EQ:      case OP_NOTEQ:
7612         case OP_SLESS:   case OP_ULESS:   case OP_SMORE:   case OP_UMORE:
7613         case OP_SLESSEQ: case OP_ULESSEQ: case OP_SMOREEQ: case OP_UMOREEQ:
7614                 /* If the expression is already boolean do nothing */
7615                 break;
7616         default:
7617                 expr = triple(state, OP_LTRUE, &int_type, expr, 0);
7618                 break;
7619         }
7620         return expr;
7621 }
7622
7623 static struct triple *lfalse_expr(struct compile_state *state, 
7624         struct triple *expr)
7625 {
7626         return triple(state, OP_LFALSE, &int_type, expr, 0);
7627 }
7628
7629 static struct triple *mkland_expr(
7630         struct compile_state *state,
7631         struct triple *left, struct triple *right)
7632 {
7633         struct triple *def, *val, *var, *jmp, *mid, *end;
7634         struct triple *lstore, *rstore;
7635
7636         /* Generate some intermediate triples */
7637         end = label(state);
7638         var = variable(state, &int_type);
7639         
7640         /* Store the left hand side value */
7641         lstore = write_expr(state, var, left);
7642
7643         /* Jump if the value is false */
7644         jmp =  branch(state, end, 
7645                 lfalse_expr(state, read_expr(state, var)));
7646         mid = label(state);
7647         
7648         /* Store the right hand side value */
7649         rstore = write_expr(state, var, right);
7650
7651         /* An expression for the computed value */
7652         val = read_expr(state, var);
7653
7654         /* Generate the prog for a logical and */
7655         def = mkprog(state, var, lstore, jmp, mid, rstore, end, val, 0UL);
7656         
7657         return def;
7658 }
7659
7660 static struct triple *mklor_expr(
7661         struct compile_state *state,
7662         struct triple *left, struct triple *right)
7663 {
7664         struct triple *def, *val, *var, *jmp, *mid, *end;
7665
7666         /* Generate some intermediate triples */
7667         end = label(state);
7668         var = variable(state, &int_type);
7669         
7670         /* Store the left hand side value */
7671         left = write_expr(state, var, left);
7672         
7673         /* Jump if the value is true */
7674         jmp = branch(state, end, read_expr(state, var));
7675         mid = label(state);
7676         
7677         /* Store the right hand side value */
7678         right = write_expr(state, var, right);
7679                 
7680         /* An expression for the computed value*/
7681         val = read_expr(state, var);
7682
7683         /* Generate the prog for a logical or */
7684         def = mkprog(state, var, left, jmp, mid, right, end, val, 0UL);
7685
7686         return def;
7687 }
7688
7689 static struct triple *mkcond_expr(
7690         struct compile_state *state, 
7691         struct triple *test, struct triple *left, struct triple *right)
7692 {
7693         struct triple *def, *val, *var, *jmp1, *jmp2, *top, *mid, *end;
7694         struct type *result_type;
7695         unsigned int left_type, right_type;
7696         bool(state, test);
7697         left_type = left->type->type;
7698         right_type = right->type->type;
7699         result_type = 0;
7700         /* Both operands have arithmetic type */
7701         if (TYPE_ARITHMETIC(left_type) && TYPE_ARITHMETIC(right_type)) {
7702                 result_type = arithmetic_result(state, left, right);
7703         }
7704         /* Both operands have void type */
7705         else if (((left_type & TYPE_MASK) == TYPE_VOID) &&
7706                 ((right_type & TYPE_MASK) == TYPE_VOID)) {
7707                 result_type = &void_type;
7708         }
7709         /* pointers to the same type... */
7710         else if ((result_type = compatible_ptrs(left->type, right->type))) {
7711                 ;
7712         }
7713         /* Both operands are pointers and left is a pointer to void */
7714         else if (((left_type & TYPE_MASK) == TYPE_POINTER) &&
7715                 ((right_type & TYPE_MASK) == TYPE_POINTER) &&
7716                 ((left->type->left->type & TYPE_MASK) == TYPE_VOID)) {
7717                 result_type = right->type;
7718         }
7719         /* Both operands are pointers and right is a pointer to void */
7720         else if (((left_type & TYPE_MASK) == TYPE_POINTER) &&
7721                 ((right_type & TYPE_MASK) == TYPE_POINTER) &&
7722                 ((right->type->left->type & TYPE_MASK) == TYPE_VOID)) {
7723                 result_type = left->type;
7724         }
7725         if (!result_type) {
7726                 error(state, 0, "Incompatible types in conditional expression");
7727         }
7728         /* Generate some intermediate triples */
7729         mid = label(state);
7730         end = label(state);
7731         var = variable(state, result_type);
7732
7733         /* Branch if the test is false */
7734         jmp1 = branch(state, mid, lfalse_expr(state, read_expr(state, test)));
7735         top = label(state);
7736
7737         /* Store the left hand side value */
7738         left = write_expr(state, var, left);
7739
7740         /* Branch to the end */
7741         jmp2 = branch(state, end, 0);
7742
7743         /* Store the right hand side value */
7744         right = write_expr(state, var, right);
7745         
7746         /* An expression for the computed value */
7747         val = read_expr(state, var);
7748
7749         /* Generate the prog for a conditional expression */
7750         def = mkprog(state, var, jmp1, top, left, jmp2, mid, right, end, val, 0UL);
7751
7752         return def;
7753 }
7754
7755
7756 static int expr_depth(struct compile_state *state, struct triple *ins)
7757 {
7758 #if DEBUG_ROMCC_WARNINGS
7759 #warning "FIXME move optimal ordering of subexpressions into the optimizer"
7760 #endif
7761         int count;
7762         count = 0;
7763         if (!ins || (ins->id & TRIPLE_FLAG_FLATTENED)) {
7764                 count = 0;
7765         }
7766         else if (ins->op == OP_DEREF) {
7767                 count = expr_depth(state, RHS(ins, 0)) - 1;
7768         }
7769         else if (ins->op == OP_VAL) {
7770                 count = expr_depth(state, RHS(ins, 0)) - 1;
7771         }
7772         else if (ins->op == OP_FCALL) {
7773                 /* Don't figure the depth of a call just guess it is huge */
7774                 count = 1000;
7775         }
7776         else {
7777                 struct triple **expr;
7778                 expr = triple_rhs(state, ins, 0);
7779                 for(;expr; expr = triple_rhs(state, ins, expr)) {
7780                         if (*expr) {
7781                                 int depth;
7782                                 depth = expr_depth(state, *expr);
7783                                 if (depth > count) {
7784                                         count = depth;
7785                                 }
7786                         }
7787                 }
7788         }
7789         return count + 1;
7790 }
7791
7792 static struct triple *flatten_generic(
7793         struct compile_state *state, struct triple *first, struct triple *ptr,
7794         int ignored)
7795 {
7796         struct rhs_vector {
7797                 int depth;
7798                 struct triple **ins;
7799         } vector[MAX_RHS];
7800         int i, rhs, lhs;
7801         /* Only operations with just a rhs and a lhs should come here */
7802         rhs = ptr->rhs;
7803         lhs = ptr->lhs;
7804         if (TRIPLE_SIZE(ptr) != lhs + rhs + ignored) {
7805                 internal_error(state, ptr, "unexpected args for: %d %s",
7806                         ptr->op, tops(ptr->op));
7807         }
7808         /* Find the depth of the rhs elements */
7809         for(i = 0; i < rhs; i++) {
7810                 vector[i].ins = &RHS(ptr, i);
7811                 vector[i].depth = expr_depth(state, *vector[i].ins);
7812         }
7813         /* Selection sort the rhs */
7814         for(i = 0; i < rhs; i++) {
7815                 int j, max = i;
7816                 for(j = i + 1; j < rhs; j++ ) {
7817                         if (vector[j].depth > vector[max].depth) {
7818                                 max = j;
7819                         }
7820                 }
7821                 if (max != i) {
7822                         struct rhs_vector tmp;
7823                         tmp = vector[i];
7824                         vector[i] = vector[max];
7825                         vector[max] = tmp;
7826                 }
7827         }
7828         /* Now flatten the rhs elements */
7829         for(i = 0; i < rhs; i++) {
7830                 *vector[i].ins = flatten(state, first, *vector[i].ins);
7831                 use_triple(*vector[i].ins, ptr);
7832         }
7833         if (lhs) {
7834                 insert_triple(state, first, ptr);
7835                 ptr->id |= TRIPLE_FLAG_FLATTENED;
7836                 ptr->id &= ~TRIPLE_FLAG_LOCAL;
7837                 
7838                 /* Now flatten the lhs elements */
7839                 for(i = 0; i < lhs; i++) {
7840                         struct triple **ins = &LHS(ptr, i);
7841                         *ins = flatten(state, first, *ins);
7842                         use_triple(*ins, ptr);
7843                 }
7844         }
7845         return ptr;
7846 }
7847
7848 static struct triple *flatten_prog(
7849         struct compile_state *state, struct triple *first, struct triple *ptr)
7850 {
7851         struct triple *head, *body, *val;
7852         head = RHS(ptr, 0);
7853         RHS(ptr, 0) = 0;
7854         val  = head->prev;
7855         body = head->next;
7856         release_triple(state, head);
7857         release_triple(state, ptr);
7858         val->next        = first;
7859         body->prev       = first->prev;
7860         body->prev->next = body;
7861         val->next->prev  = val;
7862
7863         if (triple_is_cbranch(state, body->prev) ||
7864                 triple_is_call(state, body->prev)) {
7865                 unuse_triple(first, body->prev);
7866                 use_triple(body, body->prev);
7867         }
7868         
7869         if (!(val->id & TRIPLE_FLAG_FLATTENED)) {
7870                 internal_error(state, val, "val not flattened?");
7871         }
7872
7873         return val;
7874 }
7875
7876
7877 static struct triple *flatten_part(
7878         struct compile_state *state, struct triple *first, struct triple *ptr)
7879 {
7880         if (!triple_is_part(state, ptr)) {
7881                 internal_error(state, ptr,  "not a part");
7882         }
7883         if (ptr->rhs || ptr->lhs || ptr->targ || (ptr->misc != 1)) {
7884                 internal_error(state, ptr, "unexpected args for: %d %s",
7885                         ptr->op, tops(ptr->op));
7886         }
7887         MISC(ptr, 0) = flatten(state, first, MISC(ptr, 0));
7888         use_triple(MISC(ptr, 0), ptr);
7889         return flatten_generic(state, first, ptr, 1);
7890 }
7891
7892 static struct triple *flatten(
7893         struct compile_state *state, struct triple *first, struct triple *ptr)
7894 {
7895         struct triple *orig_ptr;
7896         if (!ptr)
7897                 return 0;
7898         do {
7899                 orig_ptr = ptr;
7900                 /* Only flatten triples once */
7901                 if (ptr->id & TRIPLE_FLAG_FLATTENED) {
7902                         return ptr;
7903                 }
7904                 switch(ptr->op) {
7905                 case OP_VAL:
7906                         RHS(ptr, 0) = flatten(state, first, RHS(ptr, 0));
7907                         return MISC(ptr, 0);
7908                         break;
7909                 case OP_PROG:
7910                         ptr = flatten_prog(state, first, ptr);
7911                         break;
7912                 case OP_FCALL:
7913                         ptr = flatten_generic(state, first, ptr, 1);
7914                         insert_triple(state, first, ptr);
7915                         ptr->id |= TRIPLE_FLAG_FLATTENED;
7916                         ptr->id &= ~TRIPLE_FLAG_LOCAL;
7917                         if (ptr->next != ptr) {
7918                                 use_triple(ptr->next, ptr);
7919                         }
7920                         break;
7921                 case OP_READ:
7922                 case OP_LOAD:
7923                         RHS(ptr, 0) = flatten(state, first, RHS(ptr, 0));
7924                         use_triple(RHS(ptr, 0), ptr);
7925                         break;
7926                 case OP_WRITE:
7927                         ptr = flatten_generic(state, first, ptr, 1);
7928                         MISC(ptr, 0) = flatten(state, first, MISC(ptr, 0));
7929                         use_triple(MISC(ptr, 0), ptr);
7930                         break;
7931                 case OP_BRANCH:
7932                         use_triple(TARG(ptr, 0), ptr);
7933                         break;
7934                 case OP_CBRANCH:
7935                         RHS(ptr, 0) = flatten(state, first, RHS(ptr, 0));
7936                         use_triple(RHS(ptr, 0), ptr);
7937                         use_triple(TARG(ptr, 0), ptr);
7938                         insert_triple(state, first, ptr);
7939                         ptr->id |= TRIPLE_FLAG_FLATTENED;
7940                         ptr->id &= ~TRIPLE_FLAG_LOCAL;
7941                         if (ptr->next != ptr) {
7942                                 use_triple(ptr->next, ptr);
7943                         }
7944                         break;
7945                 case OP_CALL:
7946                         MISC(ptr, 0) = flatten(state, first, MISC(ptr, 0));
7947                         use_triple(MISC(ptr, 0), ptr);
7948                         use_triple(TARG(ptr, 0), ptr);
7949                         insert_triple(state, first, ptr);
7950                         ptr->id |= TRIPLE_FLAG_FLATTENED;
7951                         ptr->id &= ~TRIPLE_FLAG_LOCAL;
7952                         if (ptr->next != ptr) {
7953                                 use_triple(ptr->next, ptr);
7954                         }
7955                         break;
7956                 case OP_RET:
7957                         RHS(ptr, 0) = flatten(state, first, RHS(ptr, 0));
7958                         use_triple(RHS(ptr, 0), ptr);
7959                         break;
7960                 case OP_BLOBCONST:
7961                         insert_triple(state, state->global_pool, ptr);
7962                         ptr->id |= TRIPLE_FLAG_FLATTENED;
7963                         ptr->id &= ~TRIPLE_FLAG_LOCAL;
7964                         ptr = triple(state, OP_SDECL, ptr->type, ptr, 0);
7965                         use_triple(MISC(ptr, 0), ptr);
7966                         break;
7967                 case OP_DEREF:
7968                         /* Since OP_DEREF is just a marker delete it when I flatten it */
7969                         ptr = RHS(ptr, 0);
7970                         RHS(orig_ptr, 0) = 0;
7971                         free_triple(state, orig_ptr);
7972                         break;
7973                 case OP_DOT:
7974                         if (RHS(ptr, 0)->op == OP_DEREF) {
7975                                 struct triple *base, *left;
7976                                 ulong_t offset;
7977                                 base = MISC(ptr, 0);
7978                                 offset = bits_to_bytes(field_offset(state, base->type, ptr->u.field));
7979                                 left = RHS(base, 0);
7980                                 ptr = triple(state, OP_ADD, left->type, 
7981                                         read_expr(state, left),
7982                                         int_const(state, &ulong_type, offset));
7983                                 free_triple(state, base);
7984                         }
7985                         else {
7986                                 ptr = flatten_part(state, first, ptr);
7987                         }
7988                         break;
7989                 case OP_INDEX:
7990                         if (RHS(ptr, 0)->op == OP_DEREF) {
7991                                 struct triple *base, *left;
7992                                 ulong_t offset;
7993                                 base = MISC(ptr, 0);
7994                                 offset = bits_to_bytes(index_offset(state, base->type, ptr->u.cval));
7995                                 left = RHS(base, 0);
7996                                 ptr = triple(state, OP_ADD, left->type,
7997                                         read_expr(state, left),
7998                                         int_const(state, &long_type, offset));
7999                                 free_triple(state, base);
8000                         }
8001                         else {
8002                                 ptr = flatten_part(state, first, ptr);
8003                         }
8004                         break;
8005                 case OP_PIECE:
8006                         ptr = flatten_part(state, first, ptr);
8007                         use_triple(ptr, MISC(ptr, 0));
8008                         break;
8009                 case OP_ADDRCONST:
8010                         MISC(ptr, 0) = flatten(state, first, MISC(ptr, 0));
8011                         use_triple(MISC(ptr, 0), ptr);
8012                         break;
8013                 case OP_SDECL:
8014                         first = state->global_pool;
8015                         MISC(ptr, 0) = flatten(state, first, MISC(ptr, 0));
8016                         use_triple(MISC(ptr, 0), ptr);
8017                         insert_triple(state, first, ptr);
8018                         ptr->id |= TRIPLE_FLAG_FLATTENED;
8019                         ptr->id &= ~TRIPLE_FLAG_LOCAL;
8020                         return ptr;
8021                 case OP_ADECL:
8022                         ptr = flatten_generic(state, first, ptr, 0);
8023                         break;
8024                 default:
8025                         /* Flatten the easy cases we don't override */
8026                         ptr = flatten_generic(state, first, ptr, 0);
8027                         break;
8028                 }
8029         } while(ptr && (ptr != orig_ptr));
8030         if (ptr && !(ptr->id & TRIPLE_FLAG_FLATTENED)) {
8031                 insert_triple(state, first, ptr);
8032                 ptr->id |= TRIPLE_FLAG_FLATTENED;
8033                 ptr->id &= ~TRIPLE_FLAG_LOCAL;
8034         }
8035         return ptr;
8036 }
8037
8038 static void release_expr(struct compile_state *state, struct triple *expr)
8039 {
8040         struct triple *head;
8041         head = label(state);
8042         flatten(state, head, expr);
8043         while(head->next != head) {
8044                 release_triple(state, head->next);
8045         }
8046         free_triple(state, head);
8047 }
8048
8049 static int replace_rhs_use(struct compile_state *state,
8050         struct triple *orig, struct triple *new, struct triple *use)
8051 {
8052         struct triple **expr;
8053         int found;
8054         found = 0;
8055         expr = triple_rhs(state, use, 0);
8056         for(;expr; expr = triple_rhs(state, use, expr)) {
8057                 if (*expr == orig) {
8058                         *expr = new;
8059                         found = 1;
8060                 }
8061         }
8062         if (found) {
8063                 unuse_triple(orig, use);
8064                 use_triple(new, use);
8065         }
8066         return found;
8067 }
8068
8069 static int replace_lhs_use(struct compile_state *state,
8070         struct triple *orig, struct triple *new, struct triple *use)
8071 {
8072         struct triple **expr;
8073         int found;
8074         found = 0;
8075         expr = triple_lhs(state, use, 0);
8076         for(;expr; expr = triple_lhs(state, use, expr)) {
8077                 if (*expr == orig) {
8078                         *expr = new;
8079                         found = 1;
8080                 }
8081         }
8082         if (found) {
8083                 unuse_triple(orig, use);
8084                 use_triple(new, use);
8085         }
8086         return found;
8087 }
8088
8089 static int replace_misc_use(struct compile_state *state,
8090         struct triple *orig, struct triple *new, struct triple *use)
8091 {
8092         struct triple **expr;
8093         int found;
8094         found = 0;
8095         expr = triple_misc(state, use, 0);
8096         for(;expr; expr = triple_misc(state, use, expr)) {
8097                 if (*expr == orig) {
8098                         *expr = new;
8099                         found = 1;
8100                 }
8101         }
8102         if (found) {
8103                 unuse_triple(orig, use);
8104                 use_triple(new, use);
8105         }
8106         return found;
8107 }
8108
8109 static int replace_targ_use(struct compile_state *state,
8110         struct triple *orig, struct triple *new, struct triple *use)
8111 {
8112         struct triple **expr;
8113         int found;
8114         found = 0;
8115         expr = triple_targ(state, use, 0);
8116         for(;expr; expr = triple_targ(state, use, expr)) {
8117                 if (*expr == orig) {
8118                         *expr = new;
8119                         found = 1;
8120                 }
8121         }
8122         if (found) {
8123                 unuse_triple(orig, use);
8124                 use_triple(new, use);
8125         }
8126         return found;
8127 }
8128
8129 static void replace_use(struct compile_state *state,
8130         struct triple *orig, struct triple *new, struct triple *use)
8131 {
8132         int found;
8133         found = 0;
8134         found |= replace_rhs_use(state, orig, new, use);
8135         found |= replace_lhs_use(state, orig, new, use);
8136         found |= replace_misc_use(state, orig, new, use);
8137         found |= replace_targ_use(state, orig, new, use);
8138         if (!found) {
8139                 internal_error(state, use, "use without use");
8140         }
8141 }
8142
8143 static void propogate_use(struct compile_state *state,
8144         struct triple *orig, struct triple *new)
8145 {
8146         struct triple_set *user, *next;
8147         for(user = orig->use; user; user = next) {
8148                 /* Careful replace_use modifies the use chain and
8149                  * removes use.  So we must get a copy of the next
8150                  * entry early.
8151                  */
8152                 next = user->next;
8153                 replace_use(state, orig, new, user->member);
8154         }
8155         if (orig->use) {
8156                 internal_error(state, orig, "used after propogate_use");
8157         }
8158 }
8159
8160 /*
8161  * Code generators
8162  * ===========================
8163  */
8164
8165 static struct triple *mk_cast_expr(
8166         struct compile_state *state, struct type *type, struct triple *expr)
8167 {
8168         struct triple *def;
8169         def = read_expr(state, expr);
8170         def = triple(state, OP_CONVERT, type, def, 0);
8171         return def;
8172 }
8173
8174 static struct triple *mk_add_expr(
8175         struct compile_state *state, struct triple *left, struct triple *right)
8176 {
8177         struct type *result_type;
8178         /* Put pointer operands on the left */
8179         if (is_pointer(right)) {
8180                 struct triple *tmp;
8181                 tmp = left;
8182                 left = right;
8183                 right = tmp;
8184         }
8185         left  = read_expr(state, left);
8186         right = read_expr(state, right);
8187         result_type = ptr_arithmetic_result(state, left, right);
8188         if (is_pointer(left)) {
8189                 struct type *ptr_math;
8190                 int op;
8191                 if (is_signed(right->type)) {
8192                         ptr_math = &long_type;
8193                         op = OP_SMUL;
8194                 } else {
8195                         ptr_math = &ulong_type;
8196                         op = OP_UMUL;
8197                 }
8198                 if (!equiv_types(right->type, ptr_math)) {
8199                         right = mk_cast_expr(state, ptr_math, right);
8200                 }
8201                 right = triple(state, op, ptr_math, right, 
8202                         int_const(state, ptr_math, 
8203                                 size_of_in_bytes(state, left->type->left)));
8204         }
8205         return triple(state, OP_ADD, result_type, left, right);
8206 }
8207
8208 static struct triple *mk_sub_expr(
8209         struct compile_state *state, struct triple *left, struct triple *right)
8210 {
8211         struct type *result_type;
8212         result_type = ptr_arithmetic_result(state, left, right);
8213         left  = read_expr(state, left);
8214         right = read_expr(state, right);
8215         if (is_pointer(left)) {
8216                 struct type *ptr_math;
8217                 int op;
8218                 if (is_signed(right->type)) {
8219                         ptr_math = &long_type;
8220                         op = OP_SMUL;
8221                 } else {
8222                         ptr_math = &ulong_type;
8223                         op = OP_UMUL;
8224                 }
8225                 if (!equiv_types(right->type, ptr_math)) {
8226                         right = mk_cast_expr(state, ptr_math, right);
8227                 }
8228                 right = triple(state, op, ptr_math, right, 
8229                         int_const(state, ptr_math, 
8230                                 size_of_in_bytes(state, left->type->left)));
8231         }
8232         return triple(state, OP_SUB, result_type, left, right);
8233 }
8234
8235 static struct triple *mk_pre_inc_expr(
8236         struct compile_state *state, struct triple *def)
8237 {
8238         struct triple *val;
8239         lvalue(state, def);
8240         val = mk_add_expr(state, def, int_const(state, &int_type, 1));
8241         return triple(state, OP_VAL, def->type,
8242                 write_expr(state, def, val),
8243                 val);
8244 }
8245
8246 static struct triple *mk_pre_dec_expr(
8247         struct compile_state *state, struct triple *def)
8248 {
8249         struct triple *val;
8250         lvalue(state, def);
8251         val = mk_sub_expr(state, def, int_const(state, &int_type, 1));
8252         return triple(state, OP_VAL, def->type,
8253                 write_expr(state, def, val),
8254                 val);
8255 }
8256
8257 static struct triple *mk_post_inc_expr(
8258         struct compile_state *state, struct triple *def)
8259 {
8260         struct triple *val;
8261         lvalue(state, def);
8262         val = read_expr(state, def);
8263         return triple(state, OP_VAL, def->type,
8264                 write_expr(state, def,
8265                         mk_add_expr(state, val, int_const(state, &int_type, 1)))
8266                 , val);
8267 }
8268
8269 static struct triple *mk_post_dec_expr(
8270         struct compile_state *state, struct triple *def)
8271 {
8272         struct triple *val;
8273         lvalue(state, def);
8274         val = read_expr(state, def);
8275         return triple(state, OP_VAL, def->type, 
8276                 write_expr(state, def,
8277                         mk_sub_expr(state, val, int_const(state, &int_type, 1)))
8278                 , val);
8279 }
8280
8281 static struct triple *mk_subscript_expr(
8282         struct compile_state *state, struct triple *left, struct triple *right)
8283 {
8284         left  = read_expr(state, left);
8285         right = read_expr(state, right);
8286         if (!is_pointer(left) && !is_pointer(right)) {
8287                 error(state, left, "subscripted value is not a pointer");
8288         }
8289         return mk_deref_expr(state, mk_add_expr(state, left, right));
8290 }
8291
8292
8293 /*
8294  * Compile time evaluation
8295  * ===========================
8296  */
8297 static int is_const(struct triple *ins)
8298 {
8299         return IS_CONST_OP(ins->op);
8300 }
8301
8302 static int is_simple_const(struct triple *ins)
8303 {
8304         /* Is this a constant that u.cval has the value.
8305          * Or equivalently is this a constant that read_const
8306          * works on.
8307          * So far only OP_INTCONST qualifies.  
8308          */
8309         return (ins->op == OP_INTCONST);
8310 }
8311
8312 static int constants_equal(struct compile_state *state, 
8313         struct triple *left, struct triple *right)
8314 {
8315         int equal;
8316         if ((left->op == OP_UNKNOWNVAL) || (right->op == OP_UNKNOWNVAL)) {
8317                 equal = 0;
8318         }
8319         else if (!is_const(left) || !is_const(right)) {
8320                 equal = 0;
8321         }
8322         else if (left->op != right->op) {
8323                 equal = 0;
8324         }
8325         else if (!equiv_types(left->type, right->type)) {
8326                 equal = 0;
8327         }
8328         else {
8329                 equal = 0;
8330                 switch(left->op) {
8331                 case OP_INTCONST:
8332                         if (left->u.cval == right->u.cval) {
8333                                 equal = 1;
8334                         }
8335                         break;
8336                 case OP_BLOBCONST:
8337                 {
8338                         size_t lsize, rsize, bytes;
8339                         lsize = size_of(state, left->type);
8340                         rsize = size_of(state, right->type);
8341                         if (lsize != rsize) {
8342                                 break;
8343                         }
8344                         bytes = bits_to_bytes(lsize);
8345                         if (memcmp(left->u.blob, right->u.blob, bytes) == 0) {
8346                                 equal = 1;
8347                         }
8348                         break;
8349                 }
8350                 case OP_ADDRCONST:
8351                         if ((MISC(left, 0) == MISC(right, 0)) &&
8352                                 (left->u.cval == right->u.cval)) {
8353                                 equal = 1;
8354                         }
8355                         break;
8356                 default:
8357                         internal_error(state, left, "uknown constant type");
8358                         break;
8359                 }
8360         }
8361         return equal;
8362 }
8363
8364 static int is_zero(struct triple *ins)
8365 {
8366         return is_simple_const(ins) && (ins->u.cval == 0);
8367 }
8368
8369 static int is_one(struct triple *ins)
8370 {
8371         return is_simple_const(ins) && (ins->u.cval == 1);
8372 }
8373
8374 #if DEBUG_ROMCC_WARNING
8375 static long_t bit_count(ulong_t value)
8376 {
8377         int count;
8378         int i;
8379         count = 0;
8380         for(i = (sizeof(ulong_t)*8) -1; i >= 0; i--) {
8381                 ulong_t mask;
8382                 mask = 1;
8383                 mask <<= i;
8384                 if (value & mask) {
8385                         count++;
8386                 }
8387         }
8388         return count;
8389         
8390 }
8391 #endif
8392
8393 static long_t bsr(ulong_t value)
8394 {
8395         int i;
8396         for(i = (sizeof(ulong_t)*8) -1; i >= 0; i--) {
8397                 ulong_t mask;
8398                 mask = 1;
8399                 mask <<= i;
8400                 if (value & mask) {
8401                         return i;
8402                 }
8403         }
8404         return -1;
8405 }
8406
8407 static long_t bsf(ulong_t value)
8408 {
8409         int i;
8410         for(i = 0; i < (sizeof(ulong_t)*8); i++) {
8411                 ulong_t mask;
8412                 mask = 1;
8413                 mask <<= 1;
8414                 if (value & mask) {
8415                         return i;
8416                 }
8417         }
8418         return -1;
8419 }
8420
8421 static long_t ilog2(ulong_t value)
8422 {
8423         return bsr(value);
8424 }
8425
8426 static long_t tlog2(struct triple *ins)
8427 {
8428         return ilog2(ins->u.cval);
8429 }
8430
8431 static int is_pow2(struct triple *ins)
8432 {
8433         ulong_t value, mask;
8434         long_t log;
8435         if (!is_const(ins)) {
8436                 return 0;
8437         }
8438         value = ins->u.cval;
8439         log = ilog2(value);
8440         if (log == -1) {
8441                 return 0;
8442         }
8443         mask = 1;
8444         mask <<= log;
8445         return  ((value & mask) == value);
8446 }
8447
8448 static ulong_t read_const(struct compile_state *state,
8449         struct triple *ins, struct triple *rhs)
8450 {
8451         switch(rhs->type->type &TYPE_MASK) {
8452         case TYPE_CHAR:   
8453         case TYPE_SHORT:
8454         case TYPE_INT:
8455         case TYPE_LONG:
8456         case TYPE_UCHAR:   
8457         case TYPE_USHORT:  
8458         case TYPE_UINT:
8459         case TYPE_ULONG:
8460         case TYPE_POINTER:
8461         case TYPE_BITFIELD:
8462                 break;
8463         default:
8464                 fprintf(state->errout, "type: ");
8465                 name_of(state->errout, rhs->type);
8466                 fprintf(state->errout, "\n");
8467                 internal_warning(state, rhs, "bad type to read_const");
8468                 break;
8469         }
8470         if (!is_simple_const(rhs)) {
8471                 internal_error(state, rhs, "bad op to read_const");
8472         }
8473         return rhs->u.cval;
8474 }
8475
8476 static long_t read_sconst(struct compile_state *state,
8477         struct triple *ins, struct triple *rhs)
8478 {
8479         return (long_t)(rhs->u.cval);
8480 }
8481
8482 int const_ltrue(struct compile_state *state, struct triple *ins, struct triple *rhs)
8483 {
8484         if (!is_const(rhs)) {
8485                 internal_error(state, 0, "non const passed to const_true");
8486         }
8487         return !is_zero(rhs);
8488 }
8489
8490 int const_eq(struct compile_state *state, struct triple *ins,
8491         struct triple *left, struct triple *right)
8492 {
8493         int result;
8494         if (!is_const(left) || !is_const(right)) {
8495                 internal_warning(state, ins, "non const passed to const_eq");
8496                 result = -1;
8497         }
8498         else if (left == right) {
8499                 result = 1;
8500         }
8501         else if (is_simple_const(left) && is_simple_const(right)) {
8502                 ulong_t lval, rval;
8503                 lval = read_const(state, ins, left);
8504                 rval = read_const(state, ins, right);
8505                 result = (lval == rval);
8506         }
8507         else if ((left->op == OP_ADDRCONST) && 
8508                 (right->op == OP_ADDRCONST)) {
8509                 result = (MISC(left, 0) == MISC(right, 0)) &&
8510                         (left->u.cval == right->u.cval);
8511         }
8512         else {
8513                 internal_warning(state, ins, "incomparable constants passed to const_eq");
8514                 result = -1;
8515         }
8516         return result;
8517         
8518 }
8519
8520 int const_ucmp(struct compile_state *state, struct triple *ins,
8521         struct triple *left, struct triple *right)
8522 {
8523         int result;
8524         if (!is_const(left) || !is_const(right)) {
8525                 internal_warning(state, ins, "non const past to const_ucmp");
8526                 result = -2;
8527         }
8528         else if (left == right) {
8529                 result = 0;
8530         }
8531         else if (is_simple_const(left) && is_simple_const(right)) {
8532                 ulong_t lval, rval;
8533                 lval = read_const(state, ins, left);
8534                 rval = read_const(state, ins, right);
8535                 result = 0;
8536                 if (lval > rval) {
8537                         result = 1;
8538                 } else if (rval > lval) {
8539                         result = -1;
8540                 }
8541         }
8542         else if ((left->op == OP_ADDRCONST) && 
8543                 (right->op == OP_ADDRCONST) &&
8544                 (MISC(left, 0) == MISC(right, 0))) {
8545                 result = 0;
8546                 if (left->u.cval > right->u.cval) {
8547                         result = 1;
8548                 } else if (left->u.cval < right->u.cval) {
8549                         result = -1;
8550                 }
8551         }
8552         else {
8553                 internal_warning(state, ins, "incomparable constants passed to const_ucmp");
8554                 result = -2;
8555         }
8556         return result;
8557 }
8558
8559 int const_scmp(struct compile_state *state, struct triple *ins,
8560         struct triple *left, struct triple *right)
8561 {
8562         int result;
8563         if (!is_const(left) || !is_const(right)) {
8564                 internal_warning(state, ins, "non const past to ucmp_const");
8565                 result = -2;
8566         }
8567         else if (left == right) {
8568                 result = 0;
8569         }
8570         else if (is_simple_const(left) && is_simple_const(right)) {
8571                 long_t lval, rval;
8572                 lval = read_sconst(state, ins, left);
8573                 rval = read_sconst(state, ins, right);
8574                 result = 0;
8575                 if (lval > rval) {
8576                         result = 1;
8577                 } else if (rval > lval) {
8578                         result = -1;
8579                 }
8580         }
8581         else {
8582                 internal_warning(state, ins, "incomparable constants passed to const_scmp");
8583                 result = -2;
8584         }
8585         return result;
8586 }
8587
8588 static void unuse_rhs(struct compile_state *state, struct triple *ins)
8589 {
8590         struct triple **expr;
8591         expr = triple_rhs(state, ins, 0);
8592         for(;expr;expr = triple_rhs(state, ins, expr)) {
8593                 if (*expr) {
8594                         unuse_triple(*expr, ins);
8595                         *expr = 0;
8596                 }
8597         }
8598 }
8599
8600 static void unuse_lhs(struct compile_state *state, struct triple *ins)
8601 {
8602         struct triple **expr;
8603         expr = triple_lhs(state, ins, 0);
8604         for(;expr;expr = triple_lhs(state, ins, expr)) {
8605                 unuse_triple(*expr, ins);
8606                 *expr = 0;
8607         }
8608 }
8609
8610 #if DEBUG_ROMCC_WARNING
8611 static void unuse_misc(struct compile_state *state, struct triple *ins)
8612 {
8613         struct triple **expr;
8614         expr = triple_misc(state, ins, 0);
8615         for(;expr;expr = triple_misc(state, ins, expr)) {
8616                 unuse_triple(*expr, ins);
8617                 *expr = 0;
8618         }
8619 }
8620
8621 static void unuse_targ(struct compile_state *state, struct triple *ins)
8622 {
8623         int i;
8624         struct triple **slot;
8625         slot = &TARG(ins, 0);
8626         for(i = 0; i < ins->targ; i++) {
8627                 unuse_triple(slot[i], ins);
8628                 slot[i] = 0;
8629         }
8630 }
8631
8632 static void check_lhs(struct compile_state *state, struct triple *ins)
8633 {
8634         struct triple **expr;
8635         expr = triple_lhs(state, ins, 0);
8636         for(;expr;expr = triple_lhs(state, ins, expr)) {
8637                 internal_error(state, ins, "unexpected lhs");
8638         }
8639         
8640 }
8641 #endif
8642
8643 static void check_misc(struct compile_state *state, struct triple *ins)
8644 {
8645         struct triple **expr;
8646         expr = triple_misc(state, ins, 0);
8647         for(;expr;expr = triple_misc(state, ins, expr)) {
8648                 if (*expr) {
8649                         internal_error(state, ins, "unexpected misc");
8650                 }
8651         }
8652 }
8653
8654 static void check_targ(struct compile_state *state, struct triple *ins)
8655 {
8656         struct triple **expr;
8657         expr = triple_targ(state, ins, 0);
8658         for(;expr;expr = triple_targ(state, ins, expr)) {
8659                 internal_error(state, ins, "unexpected targ");
8660         }
8661 }
8662
8663 static void wipe_ins(struct compile_state *state, struct triple *ins)
8664 {
8665         /* Becareful which instructions you replace the wiped
8666          * instruction with, as there are not enough slots
8667          * in all instructions to hold all others.
8668          */
8669         check_targ(state, ins);
8670         check_misc(state, ins);
8671         unuse_rhs(state, ins);
8672         unuse_lhs(state, ins);
8673         ins->lhs  = 0;
8674         ins->rhs  = 0;
8675         ins->misc = 0;
8676         ins->targ = 0;
8677 }
8678
8679 #if DEBUG_ROMCC_WARNING
8680 static void wipe_branch(struct compile_state *state, struct triple *ins)
8681 {
8682         /* Becareful which instructions you replace the wiped
8683          * instruction with, as there are not enough slots
8684          * in all instructions to hold all others.
8685          */
8686         unuse_rhs(state, ins);
8687         unuse_lhs(state, ins);
8688         unuse_misc(state, ins);
8689         unuse_targ(state, ins);
8690         ins->lhs  = 0;
8691         ins->rhs  = 0;
8692         ins->misc = 0;
8693         ins->targ = 0;
8694 }
8695 #endif
8696
8697 static void mkcopy(struct compile_state *state, 
8698         struct triple *ins, struct triple *rhs)
8699 {
8700         struct block *block;
8701         if (!equiv_types(ins->type, rhs->type)) {
8702                 FILE *fp = state->errout;
8703                 fprintf(fp, "src type: ");
8704                 name_of(fp, rhs->type);
8705                 fprintf(fp, "\ndst type: ");
8706                 name_of(fp, ins->type);
8707                 fprintf(fp, "\n");
8708                 internal_error(state, ins, "mkcopy type mismatch");
8709         }
8710         block = block_of_triple(state, ins);
8711         wipe_ins(state, ins);
8712         ins->op = OP_COPY;
8713         ins->rhs  = 1;
8714         ins->u.block = block;
8715         RHS(ins, 0) = rhs;
8716         use_triple(RHS(ins, 0), ins);
8717 }
8718
8719 static void mkconst(struct compile_state *state, 
8720         struct triple *ins, ulong_t value)
8721 {
8722         if (!is_integral(ins) && !is_pointer(ins)) {
8723                 fprintf(state->errout, "type: ");
8724                 name_of(state->errout, ins->type);
8725                 fprintf(state->errout, "\n");
8726                 internal_error(state, ins, "unknown type to make constant value: %ld",
8727                         value);
8728         }
8729         wipe_ins(state, ins);
8730         ins->op = OP_INTCONST;
8731         ins->u.cval = value;
8732 }
8733
8734 static void mkaddr_const(struct compile_state *state,
8735         struct triple *ins, struct triple *sdecl, ulong_t value)
8736 {
8737         if ((sdecl->op != OP_SDECL) && (sdecl->op != OP_LABEL)) {
8738                 internal_error(state, ins, "bad base for addrconst");
8739         }
8740         wipe_ins(state, ins);
8741         ins->op = OP_ADDRCONST;
8742         ins->misc = 1;
8743         MISC(ins, 0) = sdecl;
8744         ins->u.cval = value;
8745         use_triple(sdecl, ins);
8746 }
8747
8748 #if DEBUG_DECOMPOSE_PRINT_TUPLES
8749 static void print_tuple(struct compile_state *state, 
8750         struct triple *ins, struct triple *tuple)
8751 {
8752         FILE *fp = state->dbgout;
8753         fprintf(fp, "%5s %p tuple: %p ", tops(ins->op), ins, tuple);
8754         name_of(fp, tuple->type);
8755         if (tuple->lhs > 0) {
8756                 fprintf(fp, " lhs: ");
8757                 name_of(fp, LHS(tuple, 0)->type);
8758         }
8759         fprintf(fp, "\n");
8760         
8761 }
8762 #endif
8763
8764 static struct triple *decompose_with_tuple(struct compile_state *state, 
8765         struct triple *ins, struct triple *tuple)
8766 {
8767         struct triple *next;
8768         next = ins->next;
8769         flatten(state, next, tuple);
8770 #if DEBUG_DECOMPOSE_PRINT_TUPLES
8771         print_tuple(state, ins, tuple);
8772 #endif
8773
8774         if (!is_compound_type(tuple->type) && (tuple->lhs > 0)) {
8775                 struct triple *tmp;
8776                 if (tuple->lhs != 1) {
8777                         internal_error(state, tuple, "plain type in multiple registers?");
8778                 }
8779                 tmp = LHS(tuple, 0);
8780                 release_triple(state, tuple);
8781                 tuple = tmp;
8782         }
8783
8784         propogate_use(state, ins, tuple);
8785         release_triple(state, ins);
8786         
8787         return next;
8788 }
8789
8790 static struct triple *decompose_unknownval(struct compile_state *state,
8791         struct triple *ins)
8792 {
8793         struct triple *tuple;
8794         ulong_t i;
8795
8796 #if DEBUG_DECOMPOSE_HIRES
8797         FILE *fp = state->dbgout;
8798         fprintf(fp, "unknown type: ");
8799         name_of(fp, ins->type);
8800         fprintf(fp, "\n");
8801 #endif
8802
8803         get_occurance(ins->occurance);
8804         tuple = alloc_triple(state, OP_TUPLE, ins->type, -1, -1, 
8805                 ins->occurance);
8806
8807         for(i = 0; i < tuple->lhs; i++) {
8808                 struct type *piece_type;
8809                 struct triple *unknown;
8810
8811                 piece_type = reg_type(state, ins->type, i * REG_SIZEOF_REG);
8812                 get_occurance(tuple->occurance);
8813                 unknown = alloc_triple(state, OP_UNKNOWNVAL, piece_type, 0, 0,
8814                         tuple->occurance);
8815                 LHS(tuple, i) = unknown;
8816         }
8817         return decompose_with_tuple(state, ins, tuple);
8818 }
8819
8820
8821 static struct triple *decompose_read(struct compile_state *state, 
8822         struct triple *ins)
8823 {
8824         struct triple *tuple, *lval;
8825         ulong_t i;
8826
8827         lval = RHS(ins, 0);
8828
8829         if (lval->op == OP_PIECE) {
8830                 return ins->next;
8831         }
8832         get_occurance(ins->occurance);
8833         tuple = alloc_triple(state, OP_TUPLE, lval->type, -1, -1,
8834                 ins->occurance);
8835
8836         if ((tuple->lhs != lval->lhs) &&
8837                 (!triple_is_def(state, lval) || (tuple->lhs != 1))) 
8838         {
8839                 internal_error(state, ins, "lhs size inconsistency?");
8840         }
8841         for(i = 0; i < tuple->lhs; i++) {
8842                 struct triple *piece, *read, *bitref;
8843                 if ((i != 0) || !triple_is_def(state, lval)) {
8844                         piece = LHS(lval, i);
8845                 } else {
8846                         piece = lval;
8847                 }
8848
8849                 /* See if the piece is really a bitref */
8850                 bitref = 0;
8851                 if (piece->op == OP_BITREF) {
8852                         bitref = piece;
8853                         piece = RHS(bitref, 0);
8854                 }
8855
8856                 get_occurance(tuple->occurance);
8857                 read = alloc_triple(state, OP_READ, piece->type, -1, -1, 
8858                         tuple->occurance);
8859                 RHS(read, 0) = piece;
8860
8861                 if (bitref) {
8862                         struct triple *extract;
8863                         int op;
8864                         if (is_signed(bitref->type->left)) {
8865                                 op = OP_SEXTRACT;
8866                         } else {
8867                                 op = OP_UEXTRACT;
8868                         }
8869                         get_occurance(tuple->occurance);
8870                         extract = alloc_triple(state, op, bitref->type, -1, -1,
8871                                 tuple->occurance);
8872                         RHS(extract, 0) = read;
8873                         extract->u.bitfield.size   = bitref->u.bitfield.size;
8874                         extract->u.bitfield.offset = bitref->u.bitfield.offset;
8875
8876                         read = extract;
8877                 }
8878
8879                 LHS(tuple, i) = read;
8880         }
8881         return decompose_with_tuple(state, ins, tuple);
8882 }
8883
8884 static struct triple *decompose_write(struct compile_state *state, 
8885         struct triple *ins)
8886 {
8887         struct triple *tuple, *lval, *val;
8888         ulong_t i;
8889         
8890         lval = MISC(ins, 0);
8891         val = RHS(ins, 0);
8892         get_occurance(ins->occurance);
8893         tuple = alloc_triple(state, OP_TUPLE, ins->type, -1, -1,
8894                 ins->occurance);
8895
8896         if ((tuple->lhs != lval->lhs) &&
8897                 (!triple_is_def(state, lval) || tuple->lhs != 1)) 
8898         {
8899                 internal_error(state, ins, "lhs size inconsistency?");
8900         }
8901         for(i = 0; i < tuple->lhs; i++) {
8902                 struct triple *piece, *write, *pval, *bitref;
8903                 if ((i != 0) || !triple_is_def(state, lval)) {
8904                         piece = LHS(lval, i);
8905                 } else {
8906                         piece = lval;
8907                 }
8908                 if ((i == 0) && (tuple->lhs == 1) && (val->lhs == 0)) {
8909                         pval = val;
8910                 }
8911                 else {
8912                         if (i > val->lhs) {
8913                                 internal_error(state, ins, "lhs size inconsistency?");
8914                         }
8915                         pval = LHS(val, i);
8916                 }
8917                 
8918                 /* See if the piece is really a bitref */
8919                 bitref = 0;
8920                 if (piece->op == OP_BITREF) {
8921                         struct triple *read, *deposit;
8922                         bitref = piece;
8923                         piece = RHS(bitref, 0);
8924
8925                         /* Read the destination register */
8926                         get_occurance(tuple->occurance);
8927                         read = alloc_triple(state, OP_READ, piece->type, -1, -1,
8928                                 tuple->occurance);
8929                         RHS(read, 0) = piece;
8930
8931                         /* Deposit the new bitfield value */
8932                         get_occurance(tuple->occurance);
8933                         deposit = alloc_triple(state, OP_DEPOSIT, piece->type, -1, -1,
8934                                 tuple->occurance);
8935                         RHS(deposit, 0) = read;
8936                         RHS(deposit, 1) = pval;
8937                         deposit->u.bitfield.size   = bitref->u.bitfield.size;
8938                         deposit->u.bitfield.offset = bitref->u.bitfield.offset;
8939
8940                         /* Now write the newly generated value */
8941                         pval = deposit;
8942                 }
8943
8944                 get_occurance(tuple->occurance);
8945                 write = alloc_triple(state, OP_WRITE, piece->type, -1, -1, 
8946                         tuple->occurance);
8947                 MISC(write, 0) = piece;
8948                 RHS(write, 0) = pval;
8949                 LHS(tuple, i) = write;
8950         }
8951         return decompose_with_tuple(state, ins, tuple);
8952 }
8953
8954 struct decompose_load_info {
8955         struct occurance *occurance;
8956         struct triple *lval;
8957         struct triple *tuple;
8958 };
8959 static void decompose_load_cb(struct compile_state *state,
8960         struct type *type, size_t reg_offset, size_t mem_offset, void *arg)
8961 {
8962         struct decompose_load_info *info = arg;
8963         struct triple *load;
8964         
8965         if (reg_offset > info->tuple->lhs) {
8966                 internal_error(state, info->tuple, "lhs to small?");
8967         }
8968         get_occurance(info->occurance);
8969         load = alloc_triple(state, OP_LOAD, type, -1, -1, info->occurance);
8970         RHS(load, 0) = mk_addr_expr(state, info->lval, mem_offset);
8971         LHS(info->tuple, reg_offset/REG_SIZEOF_REG) = load;
8972 }
8973
8974 static struct triple *decompose_load(struct compile_state *state, 
8975         struct triple *ins)
8976 {
8977         struct triple *tuple;
8978         struct decompose_load_info info;
8979
8980         if (!is_compound_type(ins->type)) {
8981                 return ins->next;
8982         }
8983         get_occurance(ins->occurance);
8984         tuple = alloc_triple(state, OP_TUPLE, ins->type, -1, -1,
8985                 ins->occurance);
8986
8987         info.occurance = ins->occurance;
8988         info.lval      = RHS(ins, 0);
8989         info.tuple     = tuple;
8990         walk_type_fields(state, ins->type, 0, 0, decompose_load_cb, &info);
8991
8992         return decompose_with_tuple(state, ins, tuple);
8993 }
8994
8995
8996 struct decompose_store_info {
8997         struct occurance *occurance;
8998         struct triple *lval;
8999         struct triple *val;
9000         struct triple *tuple;
9001 };
9002 static void decompose_store_cb(struct compile_state *state,
9003         struct type *type, size_t reg_offset, size_t mem_offset, void *arg)
9004 {
9005         struct decompose_store_info *info = arg;
9006         struct triple *store;
9007         
9008         if (reg_offset > info->tuple->lhs) {
9009                 internal_error(state, info->tuple, "lhs to small?");
9010         }
9011         get_occurance(info->occurance);
9012         store = alloc_triple(state, OP_STORE, type, -1, -1, info->occurance);
9013         RHS(store, 0) = mk_addr_expr(state, info->lval, mem_offset);
9014         RHS(store, 1) = LHS(info->val, reg_offset);
9015         LHS(info->tuple, reg_offset/REG_SIZEOF_REG) = store;
9016 }
9017
9018 static struct triple *decompose_store(struct compile_state *state, 
9019         struct triple *ins)
9020 {
9021         struct triple *tuple;
9022         struct decompose_store_info info;
9023
9024         if (!is_compound_type(ins->type)) {
9025                 return ins->next;
9026         }
9027         get_occurance(ins->occurance);
9028         tuple = alloc_triple(state, OP_TUPLE, ins->type, -1, -1,
9029                 ins->occurance);
9030
9031         info.occurance = ins->occurance;
9032         info.lval      = RHS(ins, 0);
9033         info.val       = RHS(ins, 1);
9034         info.tuple     = tuple;
9035         walk_type_fields(state, ins->type, 0, 0, decompose_store_cb, &info);
9036
9037         return decompose_with_tuple(state, ins, tuple);
9038 }
9039
9040 static struct triple *decompose_dot(struct compile_state *state, 
9041         struct triple *ins)
9042 {
9043         struct triple *tuple, *lval;
9044         struct type *type;
9045         size_t reg_offset;
9046         int i, idx;
9047
9048         lval = MISC(ins, 0);
9049         reg_offset = field_reg_offset(state, lval->type, ins->u.field);
9050         idx  = reg_offset/REG_SIZEOF_REG;
9051         type = field_type(state, lval->type, ins->u.field);
9052 #if DEBUG_DECOMPOSE_HIRES
9053         {
9054                 FILE *fp = state->dbgout;
9055                 fprintf(fp, "field type: ");
9056                 name_of(fp, type);
9057                 fprintf(fp, "\n");
9058         }
9059 #endif
9060
9061         get_occurance(ins->occurance);
9062         tuple = alloc_triple(state, OP_TUPLE, type, -1, -1, 
9063                 ins->occurance);
9064
9065         if (((ins->type->type & TYPE_MASK) == TYPE_BITFIELD) &&
9066                 (tuple->lhs != 1))
9067         {
9068                 internal_error(state, ins, "multi register bitfield?");
9069         }
9070
9071         for(i = 0; i < tuple->lhs; i++, idx++) {
9072                 struct triple *piece;
9073                 if (!triple_is_def(state, lval)) {
9074                         if (idx > lval->lhs) {
9075                                 internal_error(state, ins, "inconsistent lhs count");
9076                         }
9077                         piece = LHS(lval, idx);
9078                 } else {
9079                         if (idx != 0) {
9080                                 internal_error(state, ins, "bad reg_offset into def");
9081                         }
9082                         if (i != 0) {
9083                                 internal_error(state, ins, "bad reg count from def");
9084                         }
9085                         piece = lval;
9086                 }
9087
9088                 /* Remember the offset of the bitfield */
9089                 if ((type->type & TYPE_MASK) == TYPE_BITFIELD) {
9090                         get_occurance(ins->occurance);
9091                         piece = build_triple(state, OP_BITREF, type, piece, 0,
9092                                 ins->occurance);
9093                         piece->u.bitfield.size   = size_of(state, type);
9094                         piece->u.bitfield.offset = reg_offset % REG_SIZEOF_REG;
9095                 }
9096                 else if ((reg_offset % REG_SIZEOF_REG) != 0) {
9097                         internal_error(state, ins, 
9098                                 "request for a nonbitfield sub register?");
9099                 }
9100
9101                 LHS(tuple, i) = piece;
9102         }
9103
9104         return decompose_with_tuple(state, ins, tuple);
9105 }
9106
9107 static struct triple *decompose_index(struct compile_state *state, 
9108         struct triple *ins)
9109 {
9110         struct triple *tuple, *lval;
9111         struct type *type;
9112         int i, idx;
9113
9114         lval = MISC(ins, 0);
9115         idx = index_reg_offset(state, lval->type, ins->u.cval)/REG_SIZEOF_REG;
9116         type = index_type(state, lval->type, ins->u.cval);
9117 #if DEBUG_DECOMPOSE_HIRES
9118 {
9119         FILE *fp = state->dbgout;
9120         fprintf(fp, "index type: ");
9121         name_of(fp, type);
9122         fprintf(fp, "\n");
9123 }
9124 #endif
9125
9126         get_occurance(ins->occurance);
9127         tuple = alloc_triple(state, OP_TUPLE, type, -1, -1, 
9128                 ins->occurance);
9129
9130         for(i = 0; i < tuple->lhs; i++, idx++) {
9131                 struct triple *piece;
9132                 if (!triple_is_def(state, lval)) {
9133                         if (idx > lval->lhs) {
9134                                 internal_error(state, ins, "inconsistent lhs count");
9135                         }
9136                         piece = LHS(lval, idx);
9137                 } else {
9138                         if (idx != 0) {
9139                                 internal_error(state, ins, "bad reg_offset into def");
9140                         }
9141                         if (i != 0) {
9142                                 internal_error(state, ins, "bad reg count from def");
9143                         }
9144                         piece = lval;
9145                 }
9146                 LHS(tuple, i) = piece;
9147         }
9148
9149         return decompose_with_tuple(state, ins, tuple);
9150 }
9151
9152 static void decompose_compound_types(struct compile_state *state)
9153 {
9154         struct triple *ins, *next, *first;
9155         FILE *fp;
9156         fp = state->dbgout;
9157         first = state->first;
9158         ins = first;
9159
9160         /* Pass one expand compound values into pseudo registers.
9161          */
9162         next = first;
9163         do {
9164                 ins = next;
9165                 next = ins->next;
9166                 switch(ins->op) {
9167                 case OP_UNKNOWNVAL:
9168                         next = decompose_unknownval(state, ins);
9169                         break;
9170
9171                 case OP_READ:
9172                         next = decompose_read(state, ins);
9173                         break;
9174
9175                 case OP_WRITE:
9176                         next = decompose_write(state, ins);
9177                         break;
9178
9179
9180                 /* Be very careful with the load/store logic. These
9181                  * operations must convert from the in register layout
9182                  * to the in memory layout, which is nontrivial.
9183                  */
9184                 case OP_LOAD:
9185                         next = decompose_load(state, ins);
9186                         break;
9187                 case OP_STORE:
9188                         next = decompose_store(state, ins);
9189                         break;
9190
9191                 case OP_DOT:
9192                         next = decompose_dot(state, ins);
9193                         break;
9194                 case OP_INDEX:
9195                         next = decompose_index(state, ins);
9196                         break;
9197                         
9198                 }
9199 #if DEBUG_DECOMPOSE_HIRES
9200                 fprintf(fp, "decompose next: %p \n", next);
9201                 fflush(fp);
9202                 fprintf(fp, "next->op: %d %s\n",
9203                         next->op, tops(next->op));
9204                 /* High resolution debugging mode */
9205                 print_triples(state);
9206 #endif
9207         } while (next != first);
9208
9209         /* Pass two remove the tuples.
9210          */
9211         ins = first;
9212         do {
9213                 next = ins->next;
9214                 if (ins->op == OP_TUPLE) {
9215                         if (ins->use) {
9216                                 internal_error(state, ins, "tuple used");
9217                         }
9218                         else {
9219                                 release_triple(state, ins);
9220                         }
9221                 } 
9222                 ins = next;
9223         } while(ins != first);
9224         ins = first;
9225         do {
9226                 next = ins->next;
9227                 if (ins->op == OP_BITREF) {
9228                         if (ins->use) {
9229                                 internal_error(state, ins, "bitref used");
9230                         } 
9231                         else {
9232                                 release_triple(state, ins);
9233                         }
9234                 }
9235                 ins = next;
9236         } while(ins != first);
9237
9238         /* Pass three verify the state and set ->id to 0.
9239          */
9240         next = first;
9241         do {
9242                 ins = next;
9243                 next = ins->next;
9244                 ins->id &= ~TRIPLE_FLAG_FLATTENED;
9245                 if (triple_stores_block(state, ins)) {
9246                         ins->u.block = 0;
9247                 }
9248                 if (triple_is_def(state, ins)) {
9249                         if (reg_size_of(state, ins->type) > REG_SIZEOF_REG) {
9250                                 internal_error(state, ins, "multi register value remains?");
9251                         }
9252                 }
9253                 if (ins->op == OP_DOT) {
9254                         internal_error(state, ins, "OP_DOT remains?");
9255                 }
9256                 if (ins->op == OP_INDEX) {
9257                         internal_error(state, ins, "OP_INDEX remains?");
9258                 }
9259                 if (ins->op == OP_BITREF) {
9260                         internal_error(state, ins, "OP_BITREF remains?");
9261                 }
9262                 if (ins->op == OP_TUPLE) {
9263                         internal_error(state, ins, "OP_TUPLE remains?");
9264                 }
9265         } while(next != first);
9266 }
9267
9268 /* For those operations that cannot be simplified */
9269 static void simplify_noop(struct compile_state *state, struct triple *ins)
9270 {
9271         return;
9272 }
9273
9274 static void simplify_smul(struct compile_state *state, struct triple *ins)
9275 {
9276         if (is_const(RHS(ins, 0)) && !is_const(RHS(ins, 1))) {
9277                 struct triple *tmp;
9278                 tmp = RHS(ins, 0);
9279                 RHS(ins, 0) = RHS(ins, 1);
9280                 RHS(ins, 1) = tmp;
9281         }
9282         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
9283                 long_t left, right;
9284                 left  = read_sconst(state, ins, RHS(ins, 0));
9285                 right = read_sconst(state, ins, RHS(ins, 1));
9286                 mkconst(state, ins, left * right);
9287         }
9288         else if (is_zero(RHS(ins, 1))) {
9289                 mkconst(state, ins, 0);
9290         }
9291         else if (is_one(RHS(ins, 1))) {
9292                 mkcopy(state, ins, RHS(ins, 0));
9293         }
9294         else if (is_pow2(RHS(ins, 1))) {
9295                 struct triple *val;
9296                 val = int_const(state, ins->type, tlog2(RHS(ins, 1)));
9297                 ins->op = OP_SL;
9298                 insert_triple(state, state->global_pool, val);
9299                 unuse_triple(RHS(ins, 1), ins);
9300                 use_triple(val, ins);
9301                 RHS(ins, 1) = val;
9302         }
9303 }
9304
9305 static void simplify_umul(struct compile_state *state, struct triple *ins)
9306 {
9307         if (is_const(RHS(ins, 0)) && !is_const(RHS(ins, 1))) {
9308                 struct triple *tmp;
9309                 tmp = RHS(ins, 0);
9310                 RHS(ins, 0) = RHS(ins, 1);
9311                 RHS(ins, 1) = tmp;
9312         }
9313         if (is_simple_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9314                 ulong_t left, right;
9315                 left  = read_const(state, ins, RHS(ins, 0));
9316                 right = read_const(state, ins, RHS(ins, 1));
9317                 mkconst(state, ins, left * right);
9318         }
9319         else if (is_zero(RHS(ins, 1))) {
9320                 mkconst(state, ins, 0);
9321         }
9322         else if (is_one(RHS(ins, 1))) {
9323                 mkcopy(state, ins, RHS(ins, 0));
9324         }
9325         else if (is_pow2(RHS(ins, 1))) {
9326                 struct triple *val;
9327                 val = int_const(state, ins->type, tlog2(RHS(ins, 1)));
9328                 ins->op = OP_SL;
9329                 insert_triple(state, state->global_pool, val);
9330                 unuse_triple(RHS(ins, 1), ins);
9331                 use_triple(val, ins);
9332                 RHS(ins, 1) = val;
9333         }
9334 }
9335
9336 static void simplify_sdiv(struct compile_state *state, struct triple *ins)
9337 {
9338         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
9339                 long_t left, right;
9340                 left  = read_sconst(state, ins, RHS(ins, 0));
9341                 right = read_sconst(state, ins, RHS(ins, 1));
9342                 mkconst(state, ins, left / right);
9343         }
9344         else if (is_zero(RHS(ins, 0))) {
9345                 mkconst(state, ins, 0);
9346         }
9347         else if (is_zero(RHS(ins, 1))) {
9348                 error(state, ins, "division by zero");
9349         }
9350         else if (is_one(RHS(ins, 1))) {
9351                 mkcopy(state, ins, RHS(ins, 0));
9352         }
9353         else if (is_pow2(RHS(ins, 1))) {
9354                 struct triple *val;
9355                 val = int_const(state, ins->type, tlog2(RHS(ins, 1)));
9356                 ins->op = OP_SSR;
9357                 insert_triple(state, state->global_pool, val);
9358                 unuse_triple(RHS(ins, 1), ins);
9359                 use_triple(val, ins);
9360                 RHS(ins, 1) = val;
9361         }
9362 }
9363
9364 static void simplify_udiv(struct compile_state *state, struct triple *ins)
9365 {
9366         if (is_simple_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9367                 ulong_t left, right;
9368                 left  = read_const(state, ins, RHS(ins, 0));
9369                 right = read_const(state, ins, RHS(ins, 1));
9370                 mkconst(state, ins, left / right);
9371         }
9372         else if (is_zero(RHS(ins, 0))) {
9373                 mkconst(state, ins, 0);
9374         }
9375         else if (is_zero(RHS(ins, 1))) {
9376                 error(state, ins, "division by zero");
9377         }
9378         else if (is_one(RHS(ins, 1))) {
9379                 mkcopy(state, ins, RHS(ins, 0));
9380         }
9381         else if (is_pow2(RHS(ins, 1))) {
9382                 struct triple *val;
9383                 val = int_const(state, ins->type, tlog2(RHS(ins, 1)));
9384                 ins->op = OP_USR;
9385                 insert_triple(state, state->global_pool, val);
9386                 unuse_triple(RHS(ins, 1), ins);
9387                 use_triple(val, ins);
9388                 RHS(ins, 1) = val;
9389         }
9390 }
9391
9392 static void simplify_smod(struct compile_state *state, struct triple *ins)
9393 {
9394         if (is_simple_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9395                 long_t left, right;
9396                 left  = read_const(state, ins, RHS(ins, 0));
9397                 right = read_const(state, ins, RHS(ins, 1));
9398                 mkconst(state, ins, left % right);
9399         }
9400         else if (is_zero(RHS(ins, 0))) {
9401                 mkconst(state, ins, 0);
9402         }
9403         else if (is_zero(RHS(ins, 1))) {
9404                 error(state, ins, "division by zero");
9405         }
9406         else if (is_one(RHS(ins, 1))) {
9407                 mkconst(state, ins, 0);
9408         }
9409         else if (is_pow2(RHS(ins, 1))) {
9410                 struct triple *val;
9411                 val = int_const(state, ins->type, RHS(ins, 1)->u.cval - 1);
9412                 ins->op = OP_AND;
9413                 insert_triple(state, state->global_pool, val);
9414                 unuse_triple(RHS(ins, 1), ins);
9415                 use_triple(val, ins);
9416                 RHS(ins, 1) = val;
9417         }
9418 }
9419
9420 static void simplify_umod(struct compile_state *state, struct triple *ins)
9421 {
9422         if (is_simple_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9423                 ulong_t left, right;
9424                 left  = read_const(state, ins, RHS(ins, 0));
9425                 right = read_const(state, ins, RHS(ins, 1));
9426                 mkconst(state, ins, left % right);
9427         }
9428         else if (is_zero(RHS(ins, 0))) {
9429                 mkconst(state, ins, 0);
9430         }
9431         else if (is_zero(RHS(ins, 1))) {
9432                 error(state, ins, "division by zero");
9433         }
9434         else if (is_one(RHS(ins, 1))) {
9435                 mkconst(state, ins, 0);
9436         }
9437         else if (is_pow2(RHS(ins, 1))) {
9438                 struct triple *val;
9439                 val = int_const(state, ins->type, RHS(ins, 1)->u.cval - 1);
9440                 ins->op = OP_AND;
9441                 insert_triple(state, state->global_pool, val);
9442                 unuse_triple(RHS(ins, 1), ins);
9443                 use_triple(val, ins);
9444                 RHS(ins, 1) = val;
9445         }
9446 }
9447
9448 static void simplify_add(struct compile_state *state, struct triple *ins)
9449 {
9450         /* start with the pointer on the left */
9451         if (is_pointer(RHS(ins, 1))) {
9452                 struct triple *tmp;
9453                 tmp = RHS(ins, 0);
9454                 RHS(ins, 0) = RHS(ins, 1);
9455                 RHS(ins, 1) = tmp;
9456         }
9457         if (is_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9458                 if (RHS(ins, 0)->op == OP_INTCONST) {
9459                         ulong_t left, right;
9460                         left  = read_const(state, ins, RHS(ins, 0));
9461                         right = read_const(state, ins, RHS(ins, 1));
9462                         mkconst(state, ins, left + right);
9463                 }
9464                 else if (RHS(ins, 0)->op == OP_ADDRCONST) {
9465                         struct triple *sdecl;
9466                         ulong_t left, right;
9467                         sdecl = MISC(RHS(ins, 0), 0);
9468                         left  = RHS(ins, 0)->u.cval;
9469                         right = RHS(ins, 1)->u.cval;
9470                         mkaddr_const(state, ins, sdecl, left + right);
9471                 }
9472                 else {
9473                         internal_warning(state, ins, "Optimize me!");
9474                 }
9475         }
9476         else if (is_const(RHS(ins, 0)) && !is_const(RHS(ins, 1))) {
9477                 struct triple *tmp;
9478                 tmp = RHS(ins, 1);
9479                 RHS(ins, 1) = RHS(ins, 0);
9480                 RHS(ins, 0) = tmp;
9481         }
9482 }
9483
9484 static void simplify_sub(struct compile_state *state, struct triple *ins)
9485 {
9486         if (is_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9487                 if (RHS(ins, 0)->op == OP_INTCONST) {
9488                         ulong_t left, right;
9489                         left  = read_const(state, ins, RHS(ins, 0));
9490                         right = read_const(state, ins, RHS(ins, 1));
9491                         mkconst(state, ins, left - right);
9492                 }
9493                 else if (RHS(ins, 0)->op == OP_ADDRCONST) {
9494                         struct triple *sdecl;
9495                         ulong_t left, right;
9496                         sdecl = MISC(RHS(ins, 0), 0);
9497                         left  = RHS(ins, 0)->u.cval;
9498                         right = RHS(ins, 1)->u.cval;
9499                         mkaddr_const(state, ins, sdecl, left - right);
9500                 }
9501                 else {
9502                         internal_warning(state, ins, "Optimize me!");
9503                 }
9504         }
9505 }
9506
9507 static void simplify_sl(struct compile_state *state, struct triple *ins)
9508 {
9509         if (is_simple_const(RHS(ins, 1))) {
9510                 ulong_t right;
9511                 right = read_const(state, ins, RHS(ins, 1));
9512                 if (right >= (size_of(state, ins->type))) {
9513                         warning(state, ins, "left shift count >= width of type");
9514                 }
9515         }
9516         if (is_simple_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9517                 ulong_t left, right;
9518                 left  = read_const(state, ins, RHS(ins, 0));
9519                 right = read_const(state, ins, RHS(ins, 1));
9520                 mkconst(state, ins,  left << right);
9521         }
9522 }
9523
9524 static void simplify_usr(struct compile_state *state, struct triple *ins)
9525 {
9526         if (is_simple_const(RHS(ins, 1))) {
9527                 ulong_t right;
9528                 right = read_const(state, ins, RHS(ins, 1));
9529                 if (right >= (size_of(state, ins->type))) {
9530                         warning(state, ins, "right shift count >= width of type");
9531                 }
9532         }
9533         if (is_simple_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9534                 ulong_t left, right;
9535                 left  = read_const(state, ins, RHS(ins, 0));
9536                 right = read_const(state, ins, RHS(ins, 1));
9537                 mkconst(state, ins, left >> right);
9538         }
9539 }
9540
9541 static void simplify_ssr(struct compile_state *state, struct triple *ins)
9542 {
9543         if (is_simple_const(RHS(ins, 1))) {
9544                 ulong_t right;
9545                 right = read_const(state, ins, RHS(ins, 1));
9546                 if (right >= (size_of(state, ins->type))) {
9547                         warning(state, ins, "right shift count >= width of type");
9548                 }
9549         }
9550         if (is_simple_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9551                 long_t left, right;
9552                 left  = read_sconst(state, ins, RHS(ins, 0));
9553                 right = read_sconst(state, ins, RHS(ins, 1));
9554                 mkconst(state, ins, left >> right);
9555         }
9556 }
9557
9558 static void simplify_and(struct compile_state *state, struct triple *ins)
9559 {
9560         struct triple *left, *right;
9561         left = RHS(ins, 0);
9562         right = RHS(ins, 1);
9563
9564         if (is_simple_const(left) && is_simple_const(right)) {
9565                 ulong_t lval, rval;
9566                 lval = read_const(state, ins, left);
9567                 rval = read_const(state, ins, right);
9568                 mkconst(state, ins, lval & rval);
9569         }
9570         else if (is_zero(right) || is_zero(left)) {
9571                 mkconst(state, ins, 0);
9572         }
9573 }
9574
9575 static void simplify_or(struct compile_state *state, struct triple *ins)
9576 {
9577         struct triple *left, *right;
9578         left = RHS(ins, 0);
9579         right = RHS(ins, 1);
9580
9581         if (is_simple_const(left) && is_simple_const(right)) {
9582                 ulong_t lval, rval;
9583                 lval = read_const(state, ins, left);
9584                 rval = read_const(state, ins, right);
9585                 mkconst(state, ins, lval | rval);
9586         }
9587 #if 0 /* I need to handle type mismatches here... */
9588         else if (is_zero(right)) {
9589                 mkcopy(state, ins, left);
9590         }
9591         else if (is_zero(left)) {
9592                 mkcopy(state, ins, right);
9593         }
9594 #endif
9595 }
9596
9597 static void simplify_xor(struct compile_state *state, struct triple *ins)
9598 {
9599         if (is_simple_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9600                 ulong_t left, right;
9601                 left  = read_const(state, ins, RHS(ins, 0));
9602                 right = read_const(state, ins, RHS(ins, 1));
9603                 mkconst(state, ins, left ^ right);
9604         }
9605 }
9606
9607 static void simplify_pos(struct compile_state *state, struct triple *ins)
9608 {
9609         if (is_const(RHS(ins, 0))) {
9610                 mkconst(state, ins, RHS(ins, 0)->u.cval);
9611         }
9612         else {
9613                 mkcopy(state, ins, RHS(ins, 0));
9614         }
9615 }
9616
9617 static void simplify_neg(struct compile_state *state, struct triple *ins)
9618 {
9619         if (is_simple_const(RHS(ins, 0))) {
9620                 ulong_t left;
9621                 left = read_const(state, ins, RHS(ins, 0));
9622                 mkconst(state, ins, -left);
9623         }
9624         else if (RHS(ins, 0)->op == OP_NEG) {
9625                 mkcopy(state, ins, RHS(RHS(ins, 0), 0));
9626         }
9627 }
9628
9629 static void simplify_invert(struct compile_state *state, struct triple *ins)
9630 {
9631         if (is_simple_const(RHS(ins, 0))) {
9632                 ulong_t left;
9633                 left = read_const(state, ins, RHS(ins, 0));
9634                 mkconst(state, ins, ~left);
9635         }
9636 }
9637
9638 static void simplify_eq(struct compile_state *state, struct triple *ins)
9639 {
9640         struct triple *left, *right;
9641         left = RHS(ins, 0);
9642         right = RHS(ins, 1);
9643
9644         if (is_const(left) && is_const(right)) {
9645                 int val;
9646                 val = const_eq(state, ins, left, right);
9647                 if (val >= 0) {
9648                         mkconst(state, ins, val == 1);
9649                 }
9650         }
9651         else if (left == right) {
9652                 mkconst(state, ins, 1);
9653         }
9654 }
9655
9656 static void simplify_noteq(struct compile_state *state, struct triple *ins)
9657 {
9658         struct triple *left, *right;
9659         left = RHS(ins, 0);
9660         right = RHS(ins, 1);
9661
9662         if (is_const(left) && is_const(right)) {
9663                 int val;
9664                 val = const_eq(state, ins, left, right);
9665                 if (val >= 0) {
9666                         mkconst(state, ins, val != 1);
9667                 }
9668         }
9669         if (left == right) {
9670                 mkconst(state, ins, 0);
9671         }
9672 }
9673
9674 static void simplify_sless(struct compile_state *state, struct triple *ins)
9675 {
9676         struct triple *left, *right;
9677         left = RHS(ins, 0);
9678         right = RHS(ins, 1);
9679
9680         if (is_const(left) && is_const(right)) {
9681                 int val;
9682                 val = const_scmp(state, ins, left, right);
9683                 if ((val >= -1) && (val <= 1)) {
9684                         mkconst(state, ins, val < 0);
9685                 }
9686         }
9687         else if (left == right) {
9688                 mkconst(state, ins, 0);
9689         }
9690 }
9691
9692 static void simplify_uless(struct compile_state *state, struct triple *ins)
9693 {
9694         struct triple *left, *right;
9695         left = RHS(ins, 0);
9696         right = RHS(ins, 1);
9697
9698         if (is_const(left) && is_const(right)) {
9699                 int val;
9700                 val = const_ucmp(state, ins, left, right);
9701                 if ((val >= -1) && (val <= 1)) {
9702                         mkconst(state, ins, val < 0);
9703                 }
9704         }
9705         else if (is_zero(right)) {
9706                 mkconst(state, ins, 0);
9707         }
9708         else if (left == right) {
9709                 mkconst(state, ins, 0);
9710         }
9711 }
9712
9713 static void simplify_smore(struct compile_state *state, struct triple *ins)
9714 {
9715         struct triple *left, *right;
9716         left = RHS(ins, 0);
9717         right = RHS(ins, 1);
9718
9719         if (is_const(left) && is_const(right)) {
9720                 int val;
9721                 val = const_scmp(state, ins, left, right);
9722                 if ((val >= -1) && (val <= 1)) {
9723                         mkconst(state, ins, val > 0);
9724                 }
9725         }
9726         else if (left == right) {
9727                 mkconst(state, ins, 0);
9728         }
9729 }
9730
9731 static void simplify_umore(struct compile_state *state, struct triple *ins)
9732 {
9733         struct triple *left, *right;
9734         left = RHS(ins, 0);
9735         right = RHS(ins, 1);
9736
9737         if (is_const(left) && is_const(right)) {
9738                 int val;
9739                 val = const_ucmp(state, ins, left, right);
9740                 if ((val >= -1) && (val <= 1)) {
9741                         mkconst(state, ins, val > 0);
9742                 }
9743         }
9744         else if (is_zero(left)) {
9745                 mkconst(state, ins, 0);
9746         }
9747         else if (left == right) {
9748                 mkconst(state, ins, 0);
9749         }
9750 }
9751
9752
9753 static void simplify_slesseq(struct compile_state *state, struct triple *ins)
9754 {
9755         struct triple *left, *right;
9756         left = RHS(ins, 0);
9757         right = RHS(ins, 1);
9758
9759         if (is_const(left) && is_const(right)) {
9760                 int val;
9761                 val = const_scmp(state, ins, left, right);
9762                 if ((val >= -1) && (val <= 1)) {
9763                         mkconst(state, ins, val <= 0);
9764                 }
9765         }
9766         else if (left == right) {
9767                 mkconst(state, ins, 1);
9768         }
9769 }
9770
9771 static void simplify_ulesseq(struct compile_state *state, struct triple *ins)
9772 {
9773         struct triple *left, *right;
9774         left = RHS(ins, 0);
9775         right = RHS(ins, 1);
9776
9777         if (is_const(left) && is_const(right)) {
9778                 int val;
9779                 val = const_ucmp(state, ins, left, right);
9780                 if ((val >= -1) && (val <= 1)) {
9781                         mkconst(state, ins, val <= 0);
9782                 }
9783         }
9784         else if (is_zero(left)) {
9785                 mkconst(state, ins, 1);
9786         }
9787         else if (left == right) {
9788                 mkconst(state, ins, 1);
9789         }
9790 }
9791
9792 static void simplify_smoreeq(struct compile_state *state, struct triple *ins)
9793 {
9794         struct triple *left, *right;
9795         left = RHS(ins, 0);
9796         right = RHS(ins, 1);
9797
9798         if (is_const(left) && is_const(right)) {
9799                 int val;
9800                 val = const_scmp(state, ins, left, right);
9801                 if ((val >= -1) && (val <= 1)) {
9802                         mkconst(state, ins, val >= 0);
9803                 }
9804         }
9805         else if (left == right) {
9806                 mkconst(state, ins, 1);
9807         }
9808 }
9809
9810 static void simplify_umoreeq(struct compile_state *state, struct triple *ins)
9811 {
9812         struct triple *left, *right;
9813         left = RHS(ins, 0);
9814         right = RHS(ins, 1);
9815
9816         if (is_const(left) && is_const(right)) {
9817                 int val;
9818                 val = const_ucmp(state, ins, left, right);
9819                 if ((val >= -1) && (val <= 1)) {
9820                         mkconst(state, ins, val >= 0);
9821                 }
9822         }
9823         else if (is_zero(right)) {
9824                 mkconst(state, ins, 1);
9825         }
9826         else if (left == right) {
9827                 mkconst(state, ins, 1);
9828         }
9829 }
9830
9831 static void simplify_lfalse(struct compile_state *state, struct triple *ins)
9832 {
9833         struct triple *rhs;
9834         rhs = RHS(ins, 0);
9835
9836         if (is_const(rhs)) {
9837                 mkconst(state, ins, !const_ltrue(state, ins, rhs));
9838         }
9839         /* Otherwise if I am the only user... */
9840         else if ((rhs->use) &&
9841                 (rhs->use->member == ins) && (rhs->use->next == 0)) {
9842                 int need_copy = 1;
9843                 /* Invert a boolean operation */
9844                 switch(rhs->op) {
9845                 case OP_LTRUE:   rhs->op = OP_LFALSE;  break;
9846                 case OP_LFALSE:  rhs->op = OP_LTRUE;   break;
9847                 case OP_EQ:      rhs->op = OP_NOTEQ;   break;
9848                 case OP_NOTEQ:   rhs->op = OP_EQ;      break;
9849                 case OP_SLESS:   rhs->op = OP_SMOREEQ; break;
9850                 case OP_ULESS:   rhs->op = OP_UMOREEQ; break;
9851                 case OP_SMORE:   rhs->op = OP_SLESSEQ; break;
9852                 case OP_UMORE:   rhs->op = OP_ULESSEQ; break;
9853                 case OP_SLESSEQ: rhs->op = OP_SMORE;   break;
9854                 case OP_ULESSEQ: rhs->op = OP_UMORE;   break;
9855                 case OP_SMOREEQ: rhs->op = OP_SLESS;   break;
9856                 case OP_UMOREEQ: rhs->op = OP_ULESS;   break;
9857                 default:
9858                         need_copy = 0;
9859                         break;
9860                 }
9861                 if (need_copy) {
9862                         mkcopy(state, ins, rhs);
9863                 }
9864         }
9865 }
9866
9867 static void simplify_ltrue (struct compile_state *state, struct triple *ins)
9868 {
9869         struct triple *rhs;
9870         rhs = RHS(ins, 0);
9871
9872         if (is_const(rhs)) {
9873                 mkconst(state, ins, const_ltrue(state, ins, rhs));
9874         }
9875         else switch(rhs->op) {
9876         case OP_LTRUE:   case OP_LFALSE:  case OP_EQ:      case OP_NOTEQ:
9877         case OP_SLESS:   case OP_ULESS:   case OP_SMORE:   case OP_UMORE:
9878         case OP_SLESSEQ: case OP_ULESSEQ: case OP_SMOREEQ: case OP_UMOREEQ:
9879                 mkcopy(state, ins, rhs);
9880         }
9881
9882 }
9883
9884 static void simplify_load(struct compile_state *state, struct triple *ins)
9885 {
9886         struct triple *addr, *sdecl, *blob;
9887
9888         /* If I am doing a load with a constant pointer from a constant
9889          * table get the value.
9890          */
9891         addr = RHS(ins, 0);
9892         if ((addr->op == OP_ADDRCONST) && (sdecl = MISC(addr, 0)) &&
9893                 (sdecl->op == OP_SDECL) && (blob = MISC(sdecl, 0)) &&
9894                 (blob->op == OP_BLOBCONST)) {
9895                 unsigned char buffer[SIZEOF_WORD];
9896                 size_t reg_size, mem_size;
9897                 const char *src, *end;
9898                 ulong_t val;
9899                 reg_size = reg_size_of(state, ins->type);
9900                 if (reg_size > REG_SIZEOF_REG) {
9901                         internal_error(state, ins, "load size greater than register");
9902                 }
9903                 mem_size = size_of(state, ins->type);
9904                 end = blob->u.blob;
9905                 end += bits_to_bytes(size_of(state, sdecl->type));
9906                 src = blob->u.blob;
9907                 src += addr->u.cval;
9908
9909                 if (src > end) {
9910                         error(state, ins, "Load address out of bounds");
9911                 }
9912
9913                 memset(buffer, 0, sizeof(buffer));
9914                 memcpy(buffer, src, bits_to_bytes(mem_size));
9915
9916                 switch(mem_size) {
9917                 case SIZEOF_I8:  val = *((uint8_t *) buffer); break;
9918                 case SIZEOF_I16: val = *((uint16_t *)buffer); break;
9919                 case SIZEOF_I32: val = *((uint32_t *)buffer); break;
9920                 case SIZEOF_I64: val = *((uint64_t *)buffer); break;
9921                 default:
9922                         internal_error(state, ins, "mem_size: %d not handled",
9923                                 mem_size);
9924                         val = 0;
9925                         break;
9926                 }
9927                 mkconst(state, ins, val);
9928         }
9929 }
9930
9931 static void simplify_uextract(struct compile_state *state, struct triple *ins)
9932 {
9933         if (is_simple_const(RHS(ins, 0))) {
9934                 ulong_t val;
9935                 ulong_t mask;
9936                 val = read_const(state, ins, RHS(ins, 0));
9937                 mask = 1;
9938                 mask <<= ins->u.bitfield.size;
9939                 mask -= 1;
9940                 val >>= ins->u.bitfield.offset;
9941                 val &= mask;
9942                 mkconst(state, ins, val);
9943         }
9944 }
9945
9946 static void simplify_sextract(struct compile_state *state, struct triple *ins)
9947 {
9948         if (is_simple_const(RHS(ins, 0))) {
9949                 ulong_t val;
9950                 ulong_t mask;
9951                 long_t sval;
9952                 val = read_const(state, ins, RHS(ins, 0));
9953                 mask = 1;
9954                 mask <<= ins->u.bitfield.size;
9955                 mask -= 1;
9956                 val >>= ins->u.bitfield.offset;
9957                 val &= mask;
9958                 val <<= (SIZEOF_LONG - ins->u.bitfield.size);
9959                 sval = val;
9960                 sval >>= (SIZEOF_LONG - ins->u.bitfield.size); 
9961                 mkconst(state, ins, sval);
9962         }
9963 }
9964
9965 static void simplify_deposit(struct compile_state *state, struct triple *ins)
9966 {
9967         if (is_simple_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9968                 ulong_t targ, val;
9969                 ulong_t mask;
9970                 targ = read_const(state, ins, RHS(ins, 0));
9971                 val  = read_const(state, ins, RHS(ins, 1));
9972                 mask = 1;
9973                 mask <<= ins->u.bitfield.size;
9974                 mask -= 1;
9975                 mask <<= ins->u.bitfield.offset;
9976                 targ &= ~mask;
9977                 val <<= ins->u.bitfield.offset;
9978                 val &= mask;
9979                 targ |= val;
9980                 mkconst(state, ins, targ);
9981         }
9982 }
9983
9984 static void simplify_copy(struct compile_state *state, struct triple *ins)
9985 {
9986         struct triple *right;
9987         right = RHS(ins, 0);
9988         if (is_subset_type(ins->type, right->type)) {
9989                 ins->type = right->type;
9990         }
9991         if (equiv_types(ins->type, right->type)) {
9992                 ins->op = OP_COPY;/* I don't need to convert if the types match */
9993         } else {
9994                 if (ins->op == OP_COPY) {
9995                         internal_error(state, ins, "type mismatch on copy");
9996                 }
9997         }
9998         if (is_const(right) && (right->op == OP_ADDRCONST) && is_pointer(ins)) {
9999                 struct triple *sdecl;
10000                 ulong_t offset;
10001                 sdecl  = MISC(right, 0);
10002                 offset = right->u.cval;
10003                 mkaddr_const(state, ins, sdecl, offset);
10004         }
10005         else if (is_const(right) && is_write_compatible(state, ins->type, right->type)) {
10006                 switch(right->op) {
10007                 case OP_INTCONST:
10008                 {
10009                         ulong_t left;
10010                         left = read_const(state, ins, right);
10011                         /* Ensure I have not overflowed the destination. */
10012                         if (size_of(state, right->type) > size_of(state, ins->type)) {
10013                                 ulong_t mask;
10014                                 mask = 1;
10015                                 mask <<= size_of(state, ins->type);
10016                                 mask -= 1;
10017                                 left &= mask;
10018                         }
10019                         /* Ensure I am properly sign extended */
10020                         if (size_of(state, right->type) < size_of(state, ins->type) &&
10021                                 is_signed(right->type)) {
10022                                 long_t val;
10023                                 int shift;
10024                                 shift = SIZEOF_LONG - size_of(state, right->type);
10025                                 val = left;
10026                                 val <<= shift;
10027                                 val >>= shift;
10028                                 left = val;
10029                         }
10030                         mkconst(state, ins, left);
10031                         break;
10032                 }
10033                 default:
10034                         internal_error(state, ins, "uknown constant");
10035                         break;
10036                 }
10037         }
10038 }
10039
10040 static int phi_present(struct block *block)
10041 {
10042         struct triple *ptr;
10043         if (!block) {
10044                 return 0;
10045         }
10046         ptr = block->first;
10047         do {
10048                 if (ptr->op == OP_PHI) {
10049                         return 1;
10050                 }
10051                 ptr = ptr->next;
10052         } while(ptr != block->last);
10053         return 0;
10054 }
10055
10056 static int phi_dependency(struct block *block)
10057 {
10058         /* A block has a phi dependency if a phi function
10059          * depends on that block to exist, and makes a block
10060          * that is otherwise useless unsafe to remove.
10061          */
10062         if (block) {
10063                 struct block_set *edge;
10064                 for(edge = block->edges; edge; edge = edge->next) {
10065                         if (phi_present(edge->member)) {
10066                                 return 1;
10067                         }
10068                 }
10069         }
10070         return 0;
10071 }
10072
10073 static struct triple *branch_target(struct compile_state *state, struct triple *ins)
10074 {
10075         struct triple *targ;
10076         targ = TARG(ins, 0);
10077         /* During scc_transform temporary triples are allocated that
10078          * loop back onto themselves. If I see one don't advance the
10079          * target.
10080          */
10081         while(triple_is_structural(state, targ) && 
10082                 (targ->next != targ) && (targ->next != state->first)) {
10083                 targ = targ->next;
10084         }
10085         return targ;
10086 }
10087
10088
10089 static void simplify_branch(struct compile_state *state, struct triple *ins)
10090 {
10091         int simplified, loops;
10092         if ((ins->op != OP_BRANCH) && (ins->op != OP_CBRANCH)) {
10093                 internal_error(state, ins, "not branch");
10094         }
10095         if (ins->use != 0) {
10096                 internal_error(state, ins, "branch use");
10097         }
10098         /* The challenge here with simplify branch is that I need to 
10099          * make modifications to the control flow graph as well
10100          * as to the branch instruction itself.  That is handled
10101          * by rebuilding the basic blocks after simplify all is called.
10102          */
10103
10104         /* If we have a branch to an unconditional branch update
10105          * our target.  But watch out for dependencies from phi
10106          * functions.
10107          * Also only do this a limited number of times so
10108          * we don't get into an infinite loop.
10109          */
10110         loops = 0;
10111         do {
10112                 struct triple *targ;
10113                 simplified = 0;
10114                 targ = branch_target(state, ins);
10115                 if ((targ != ins) && (targ->op == OP_BRANCH) && 
10116                         !phi_dependency(targ->u.block))
10117                 {
10118                         unuse_triple(TARG(ins, 0), ins);
10119                         TARG(ins, 0) = TARG(targ, 0);
10120                         use_triple(TARG(ins, 0), ins);
10121                         simplified = 1;
10122                 }
10123         } while(simplified && (++loops < 20));
10124
10125         /* If we have a conditional branch with a constant condition
10126          * make it an unconditional branch.
10127          */
10128         if ((ins->op == OP_CBRANCH) && is_simple_const(RHS(ins, 0))) {
10129                 struct triple *targ;
10130                 ulong_t value;
10131                 value = read_const(state, ins, RHS(ins, 0));
10132                 unuse_triple(RHS(ins, 0), ins);
10133                 targ = TARG(ins, 0);
10134                 ins->rhs  = 0;
10135                 ins->targ = 1;
10136                 ins->op = OP_BRANCH;
10137                 if (value) {
10138                         unuse_triple(ins->next, ins);
10139                         TARG(ins, 0) = targ;
10140                 }
10141                 else {
10142                         unuse_triple(targ, ins);
10143                         TARG(ins, 0) = ins->next;
10144                 }
10145         }
10146
10147         /* If we have a branch to the next instruction,
10148          * make it a noop.
10149          */
10150         if (TARG(ins, 0) == ins->next) {
10151                 unuse_triple(TARG(ins, 0), ins);
10152                 if (ins->op == OP_CBRANCH) {
10153                         unuse_triple(RHS(ins, 0), ins);
10154                         unuse_triple(ins->next, ins);
10155                 }
10156                 ins->lhs = 0;
10157                 ins->rhs = 0;
10158                 ins->misc = 0;
10159                 ins->targ = 0;
10160                 ins->op = OP_NOOP;
10161                 if (ins->use) {
10162                         internal_error(state, ins, "noop use != 0");
10163                 }
10164         }
10165 }
10166
10167 static void simplify_label(struct compile_state *state, struct triple *ins)
10168 {
10169         /* Ignore volatile labels */
10170         if (!triple_is_pure(state, ins, ins->id)) {
10171                 return;
10172         }
10173         if (ins->use == 0) {
10174                 ins->op = OP_NOOP;
10175         }
10176         else if (ins->prev->op == OP_LABEL) {
10177                 /* In general it is not safe to merge one label that
10178                  * imediately follows another.  The problem is that the empty
10179                  * looking block may have phi functions that depend on it.
10180                  */
10181                 if (!phi_dependency(ins->prev->u.block)) {
10182                         struct triple_set *user, *next;
10183                         ins->op = OP_NOOP;
10184                         for(user = ins->use; user; user = next) {
10185                                 struct triple *use, **expr;
10186                                 next = user->next;
10187                                 use = user->member;
10188                                 expr = triple_targ(state, use, 0);
10189                                 for(;expr; expr = triple_targ(state, use, expr)) {
10190                                         if (*expr == ins) {
10191                                                 *expr = ins->prev;
10192                                                 unuse_triple(ins, use);
10193                                                 use_triple(ins->prev, use);
10194                                         }
10195                                         
10196                                 }
10197                         }
10198                         if (ins->use) {
10199                                 internal_error(state, ins, "noop use != 0");
10200                         }
10201                 }
10202         }
10203 }
10204
10205 static void simplify_phi(struct compile_state *state, struct triple *ins)
10206 {
10207         struct triple **slot;
10208         struct triple *value;
10209         int zrhs, i;
10210         ulong_t cvalue;
10211         slot = &RHS(ins, 0);
10212         zrhs = ins->rhs;
10213         if (zrhs == 0) {
10214                 return;
10215         }
10216         /* See if all of the rhs members of a phi have the same value */
10217         if (slot[0] && is_simple_const(slot[0])) {
10218                 cvalue = read_const(state, ins, slot[0]);
10219                 for(i = 1; i < zrhs; i++) {
10220                         if (    !slot[i] ||
10221                                 !is_simple_const(slot[i]) ||
10222                                 !equiv_types(slot[0]->type, slot[i]->type) ||
10223                                 (cvalue != read_const(state, ins, slot[i]))) {
10224                                 break;
10225                         }
10226                 }
10227                 if (i == zrhs) {
10228                         mkconst(state, ins, cvalue);
10229                         return;
10230                 }
10231         }
10232         
10233         /* See if all of rhs members of a phi are the same */
10234         value = slot[0];
10235         for(i = 1; i < zrhs; i++) {
10236                 if (slot[i] != value) {
10237                         break;
10238                 }
10239         }
10240         if (i == zrhs) {
10241                 /* If the phi has a single value just copy it */
10242                 if (!is_subset_type(ins->type, value->type)) {
10243                         internal_error(state, ins, "bad input type to phi");
10244                 }
10245                 /* Make the types match */
10246                 if (!equiv_types(ins->type, value->type)) {
10247                         ins->type = value->type;
10248                 }
10249                 /* Now make the actual copy */
10250                 mkcopy(state, ins, value);
10251                 return;
10252         }
10253 }
10254
10255
10256 static void simplify_bsf(struct compile_state *state, struct triple *ins)
10257 {
10258         if (is_simple_const(RHS(ins, 0))) {
10259                 ulong_t left;
10260                 left = read_const(state, ins, RHS(ins, 0));
10261                 mkconst(state, ins, bsf(left));
10262         }
10263 }
10264
10265 static void simplify_bsr(struct compile_state *state, struct triple *ins)
10266 {
10267         if (is_simple_const(RHS(ins, 0))) {
10268                 ulong_t left;
10269                 left = read_const(state, ins, RHS(ins, 0));
10270                 mkconst(state, ins, bsr(left));
10271         }
10272 }
10273
10274
10275 typedef void (*simplify_t)(struct compile_state *state, struct triple *ins);
10276 static const struct simplify_table {
10277         simplify_t func;
10278         unsigned long flag;
10279 } table_simplify[] = {
10280 #define simplify_sdivt    simplify_noop
10281 #define simplify_udivt    simplify_noop
10282 #define simplify_piece    simplify_noop
10283
10284 [OP_SDIVT      ] = { simplify_sdivt,    COMPILER_SIMPLIFY_ARITH },
10285 [OP_UDIVT      ] = { simplify_udivt,    COMPILER_SIMPLIFY_ARITH },
10286 [OP_SMUL       ] = { simplify_smul,     COMPILER_SIMPLIFY_ARITH },
10287 [OP_UMUL       ] = { simplify_umul,     COMPILER_SIMPLIFY_ARITH },
10288 [OP_SDIV       ] = { simplify_sdiv,     COMPILER_SIMPLIFY_ARITH },
10289 [OP_UDIV       ] = { simplify_udiv,     COMPILER_SIMPLIFY_ARITH },
10290 [OP_SMOD       ] = { simplify_smod,     COMPILER_SIMPLIFY_ARITH },
10291 [OP_UMOD       ] = { simplify_umod,     COMPILER_SIMPLIFY_ARITH },
10292 [OP_ADD        ] = { simplify_add,      COMPILER_SIMPLIFY_ARITH },
10293 [OP_SUB        ] = { simplify_sub,      COMPILER_SIMPLIFY_ARITH },
10294 [OP_SL         ] = { simplify_sl,       COMPILER_SIMPLIFY_SHIFT },
10295 [OP_USR        ] = { simplify_usr,      COMPILER_SIMPLIFY_SHIFT },
10296 [OP_SSR        ] = { simplify_ssr,      COMPILER_SIMPLIFY_SHIFT },
10297 [OP_AND        ] = { simplify_and,      COMPILER_SIMPLIFY_BITWISE },
10298 [OP_XOR        ] = { simplify_xor,      COMPILER_SIMPLIFY_BITWISE },
10299 [OP_OR         ] = { simplify_or,       COMPILER_SIMPLIFY_BITWISE },
10300 [OP_POS        ] = { simplify_pos,      COMPILER_SIMPLIFY_ARITH },
10301 [OP_NEG        ] = { simplify_neg,      COMPILER_SIMPLIFY_ARITH },
10302 [OP_INVERT     ] = { simplify_invert,   COMPILER_SIMPLIFY_BITWISE },
10303
10304 [OP_EQ         ] = { simplify_eq,       COMPILER_SIMPLIFY_LOGICAL },
10305 [OP_NOTEQ      ] = { simplify_noteq,    COMPILER_SIMPLIFY_LOGICAL },
10306 [OP_SLESS      ] = { simplify_sless,    COMPILER_SIMPLIFY_LOGICAL },
10307 [OP_ULESS      ] = { simplify_uless,    COMPILER_SIMPLIFY_LOGICAL },
10308 [OP_SMORE      ] = { simplify_smore,    COMPILER_SIMPLIFY_LOGICAL },
10309 [OP_UMORE      ] = { simplify_umore,    COMPILER_SIMPLIFY_LOGICAL },
10310 [OP_SLESSEQ    ] = { simplify_slesseq,  COMPILER_SIMPLIFY_LOGICAL },
10311 [OP_ULESSEQ    ] = { simplify_ulesseq,  COMPILER_SIMPLIFY_LOGICAL },
10312 [OP_SMOREEQ    ] = { simplify_smoreeq,  COMPILER_SIMPLIFY_LOGICAL },
10313 [OP_UMOREEQ    ] = { simplify_umoreeq,  COMPILER_SIMPLIFY_LOGICAL },
10314 [OP_LFALSE     ] = { simplify_lfalse,   COMPILER_SIMPLIFY_LOGICAL },
10315 [OP_LTRUE      ] = { simplify_ltrue,    COMPILER_SIMPLIFY_LOGICAL },
10316
10317 [OP_LOAD       ] = { simplify_load,     COMPILER_SIMPLIFY_OP },
10318 [OP_STORE      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10319
10320 [OP_UEXTRACT   ] = { simplify_uextract, COMPILER_SIMPLIFY_BITFIELD },
10321 [OP_SEXTRACT   ] = { simplify_sextract, COMPILER_SIMPLIFY_BITFIELD },
10322 [OP_DEPOSIT    ] = { simplify_deposit,  COMPILER_SIMPLIFY_BITFIELD },
10323
10324 [OP_NOOP       ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10325
10326 [OP_INTCONST   ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10327 [OP_BLOBCONST  ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10328 [OP_ADDRCONST  ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10329 [OP_UNKNOWNVAL ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10330
10331 [OP_WRITE      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10332 [OP_READ       ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10333 [OP_COPY       ] = { simplify_copy,     COMPILER_SIMPLIFY_COPY },
10334 [OP_CONVERT    ] = { simplify_copy,     COMPILER_SIMPLIFY_COPY },
10335 [OP_PIECE      ] = { simplify_piece,    COMPILER_SIMPLIFY_OP },
10336 [OP_ASM        ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10337
10338 [OP_DOT        ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10339 [OP_INDEX      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10340
10341 [OP_LIST       ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10342 [OP_BRANCH     ] = { simplify_branch,   COMPILER_SIMPLIFY_BRANCH },
10343 [OP_CBRANCH    ] = { simplify_branch,   COMPILER_SIMPLIFY_BRANCH },
10344 [OP_CALL       ] = { simplify_noop,     COMPILER_SIMPLIFY_BRANCH },
10345 [OP_RET        ] = { simplify_noop,     COMPILER_SIMPLIFY_BRANCH },
10346 [OP_LABEL      ] = { simplify_label,    COMPILER_SIMPLIFY_LABEL },
10347 [OP_ADECL      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10348 [OP_SDECL      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10349 [OP_PHI        ] = { simplify_phi,      COMPILER_SIMPLIFY_PHI },
10350
10351 [OP_INB        ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10352 [OP_INW        ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10353 [OP_INL        ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10354 [OP_OUTB       ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10355 [OP_OUTW       ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10356 [OP_OUTL       ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10357 [OP_BSF        ] = { simplify_bsf,      COMPILER_SIMPLIFY_OP },
10358 [OP_BSR        ] = { simplify_bsr,      COMPILER_SIMPLIFY_OP },
10359 [OP_RDMSR      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10360 [OP_WRMSR      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },               
10361 [OP_HLT        ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10362 };
10363
10364 static inline void debug_simplify(struct compile_state *state, 
10365         simplify_t do_simplify, struct triple *ins)
10366 {
10367 #if DEBUG_SIMPLIFY_HIRES
10368                 if (state->functions_joined && (do_simplify != simplify_noop)) {
10369                         /* High resolution debugging mode */
10370                         fprintf(state->dbgout, "simplifing: ");
10371                         display_triple(state->dbgout, ins);
10372                 }
10373 #endif
10374                 do_simplify(state, ins);
10375 #if DEBUG_SIMPLIFY_HIRES
10376                 if (state->functions_joined && (do_simplify != simplify_noop)) {
10377                         /* High resolution debugging mode */
10378                         fprintf(state->dbgout, "simplified: ");
10379                         display_triple(state->dbgout, ins);
10380                 }
10381 #endif
10382 }
10383 static void simplify(struct compile_state *state, struct triple *ins)
10384 {
10385         int op;
10386         simplify_t do_simplify;
10387         if (ins == &unknown_triple) {
10388                 internal_error(state, ins, "simplifying the unknown triple?");
10389         }
10390         do {
10391                 op = ins->op;
10392                 do_simplify = 0;
10393                 if ((op < 0) || (op > sizeof(table_simplify)/sizeof(table_simplify[0]))) {
10394                         do_simplify = 0;
10395                 }
10396                 else {
10397                         do_simplify = table_simplify[op].func;
10398                 }
10399                 if (do_simplify && 
10400                         !(state->compiler->flags & table_simplify[op].flag)) {
10401                         do_simplify = simplify_noop;
10402                 }
10403                 if (do_simplify && (ins->id & TRIPLE_FLAG_VOLATILE)) {
10404                         do_simplify = simplify_noop;
10405                 }
10406         
10407                 if (!do_simplify) {
10408                         internal_error(state, ins, "cannot simplify op: %d %s",
10409                                 op, tops(op));
10410                         return;
10411                 }
10412                 debug_simplify(state, do_simplify, ins);
10413         } while(ins->op != op);
10414 }
10415
10416 static void rebuild_ssa_form(struct compile_state *state);
10417
10418 static void simplify_all(struct compile_state *state)
10419 {
10420         struct triple *ins, *first;
10421         if (!(state->compiler->flags & COMPILER_SIMPLIFY)) {
10422                 return;
10423         }
10424         first = state->first;
10425         ins = first->prev;
10426         do {
10427                 simplify(state, ins);
10428                 ins = ins->prev;
10429         } while(ins != first->prev);
10430         ins = first;
10431         do {
10432                 simplify(state, ins);
10433                 ins = ins->next;
10434         }while(ins != first);
10435         rebuild_ssa_form(state);
10436
10437         print_blocks(state, __func__, state->dbgout);
10438 }
10439
10440 /*
10441  * Builtins....
10442  * ============================
10443  */
10444
10445 static void register_builtin_function(struct compile_state *state,
10446         const char *name, int op, struct type *rtype, ...)
10447 {
10448         struct type *ftype, *atype, *ctype, *crtype, *param, **next;
10449         struct triple *def, *arg, *result, *work, *last, *first, *retvar, *ret;
10450         struct hash_entry *ident;
10451         struct file_state file;
10452         int parameters;
10453         int name_len;
10454         va_list args;
10455         int i;
10456
10457         /* Dummy file state to get debug handling right */
10458         memset(&file, 0, sizeof(file));
10459         file.basename = "<built-in>";
10460         file.line = 1;
10461         file.report_line = 1;
10462         file.report_name = file.basename;
10463         file.prev = state->file;
10464         state->file = &file;
10465         state->function = name;
10466
10467         /* Find the Parameter count */
10468         valid_op(state, op);
10469         parameters = table_ops[op].rhs;
10470         if (parameters < 0 ) {
10471                 internal_error(state, 0, "Invalid builtin parameter count");
10472         }
10473
10474         /* Find the function type */
10475         ftype = new_type(TYPE_FUNCTION | STOR_INLINE | STOR_STATIC, rtype, 0);
10476         ftype->elements = parameters;
10477         next = &ftype->right;
10478         va_start(args, rtype);
10479         for(i = 0; i < parameters; i++) {
10480                 atype = va_arg(args, struct type *);
10481                 if (!*next) {
10482                         *next = atype;
10483                 } else {
10484                         *next = new_type(TYPE_PRODUCT, *next, atype);
10485                         next = &((*next)->right);
10486                 }
10487         }
10488         if (!*next) {
10489                 *next = &void_type;
10490         }
10491         va_end(args);
10492
10493         /* Get the initial closure type */
10494         ctype = new_type(TYPE_JOIN, &void_type, 0);
10495         ctype->elements = 1;
10496
10497         /* Get the return type */
10498         crtype = new_type(TYPE_TUPLE, new_type(TYPE_PRODUCT, ctype, rtype), 0);
10499         crtype->elements = 2;
10500
10501         /* Generate the needed triples */
10502         def = triple(state, OP_LIST, ftype, 0, 0);
10503         first = label(state);
10504         RHS(def, 0) = first;
10505         result = flatten(state, first, variable(state, crtype));
10506         retvar = flatten(state, first, variable(state, &void_ptr_type));
10507         ret = triple(state, OP_RET, &void_type, read_expr(state, retvar), 0);
10508
10509         /* Now string them together */
10510         param = ftype->right;
10511         for(i = 0; i < parameters; i++) {
10512                 if ((param->type & TYPE_MASK) == TYPE_PRODUCT) {
10513                         atype = param->left;
10514                 } else {
10515                         atype = param;
10516                 }
10517                 arg = flatten(state, first, variable(state, atype));
10518                 param = param->right;
10519         }
10520         work = new_triple(state, op, rtype, -1, parameters);
10521         generate_lhs_pieces(state, work);
10522         for(i = 0; i < parameters; i++) {
10523                 RHS(work, i) = read_expr(state, farg(state, def, i));
10524         }
10525         if ((rtype->type & TYPE_MASK) != TYPE_VOID) {
10526                 work = write_expr(state, deref_index(state, result, 1), work);
10527         }
10528         work = flatten(state, first, work);
10529         last = flatten(state, first, label(state));
10530         ret  = flatten(state, first, ret);
10531         name_len = strlen(name);
10532         ident = lookup(state, name, name_len);
10533         ftype->type_ident = ident;
10534         symbol(state, ident, &ident->sym_ident, def, ftype);
10535         
10536         state->file = file.prev;
10537         state->function = 0;
10538         state->main_function = 0;
10539
10540         if (!state->functions) {
10541                 state->functions = def;
10542         } else {
10543                 insert_triple(state, state->functions, def);
10544         }
10545         if (state->compiler->debug & DEBUG_INLINE) {
10546                 FILE *fp = state->dbgout;
10547                 fprintf(fp, "\n");
10548                 loc(fp, state, 0);
10549                 fprintf(fp, "\n__________ %s _________\n", __FUNCTION__);
10550                 display_func(state, fp, def);
10551                 fprintf(fp, "__________ %s _________ done\n\n", __FUNCTION__);
10552         }
10553 }
10554
10555 static struct type *partial_struct(struct compile_state *state,
10556         const char *field_name, struct type *type, struct type *rest)
10557 {
10558         struct hash_entry *field_ident;
10559         struct type *result;
10560         int field_name_len;
10561
10562         field_name_len = strlen(field_name);
10563         field_ident = lookup(state, field_name, field_name_len);
10564
10565         result = clone_type(0, type);
10566         result->field_ident = field_ident;
10567
10568         if (rest) {
10569                 result = new_type(TYPE_PRODUCT, result, rest);
10570         }
10571         return result;
10572 }
10573
10574 static struct type *register_builtin_type(struct compile_state *state,
10575         const char *name, struct type *type)
10576 {
10577         struct hash_entry *ident;
10578         int name_len;
10579
10580         name_len = strlen(name);
10581         ident = lookup(state, name, name_len);
10582         
10583         if ((type->type & TYPE_MASK) == TYPE_PRODUCT) {
10584                 ulong_t elements = 0;
10585                 struct type *field;
10586                 type = new_type(TYPE_STRUCT, type, 0);
10587                 field = type->left;
10588                 while((field->type & TYPE_MASK) == TYPE_PRODUCT) {
10589                         elements++;
10590                         field = field->right;
10591                 }
10592                 elements++;
10593                 symbol(state, ident, &ident->sym_tag, 0, type);
10594                 type->type_ident = ident;
10595                 type->elements = elements;
10596         }
10597         symbol(state, ident, &ident->sym_ident, 0, type);
10598         ident->tok = TOK_TYPE_NAME;
10599         return type;
10600 }
10601
10602
10603 static void register_builtins(struct compile_state *state)
10604 {
10605         struct type *div_type, *ldiv_type;
10606         struct type *udiv_type, *uldiv_type;
10607         struct type *msr_type;
10608
10609         div_type = register_builtin_type(state, "__builtin_div_t",
10610                 partial_struct(state, "quot", &int_type,
10611                 partial_struct(state, "rem",  &int_type, 0)));
10612         ldiv_type = register_builtin_type(state, "__builtin_ldiv_t",
10613                 partial_struct(state, "quot", &long_type,
10614                 partial_struct(state, "rem",  &long_type, 0)));
10615         udiv_type = register_builtin_type(state, "__builtin_udiv_t",
10616                 partial_struct(state, "quot", &uint_type,
10617                 partial_struct(state, "rem",  &uint_type, 0)));
10618         uldiv_type = register_builtin_type(state, "__builtin_uldiv_t",
10619                 partial_struct(state, "quot", &ulong_type,
10620                 partial_struct(state, "rem",  &ulong_type, 0)));
10621
10622         register_builtin_function(state, "__builtin_div",   OP_SDIVT, div_type,
10623                 &int_type, &int_type);
10624         register_builtin_function(state, "__builtin_ldiv",  OP_SDIVT, ldiv_type,
10625                 &long_type, &long_type);
10626         register_builtin_function(state, "__builtin_udiv",  OP_UDIVT, udiv_type,
10627                 &uint_type, &uint_type);
10628         register_builtin_function(state, "__builtin_uldiv", OP_UDIVT, uldiv_type,
10629                 &ulong_type, &ulong_type);
10630
10631         register_builtin_function(state, "__builtin_inb", OP_INB, &uchar_type, 
10632                 &ushort_type);
10633         register_builtin_function(state, "__builtin_inw", OP_INW, &ushort_type,
10634                 &ushort_type);
10635         register_builtin_function(state, "__builtin_inl", OP_INL, &uint_type,   
10636                 &ushort_type);
10637
10638         register_builtin_function(state, "__builtin_outb", OP_OUTB, &void_type, 
10639                 &uchar_type, &ushort_type);
10640         register_builtin_function(state, "__builtin_outw", OP_OUTW, &void_type, 
10641                 &ushort_type, &ushort_type);
10642         register_builtin_function(state, "__builtin_outl", OP_OUTL, &void_type, 
10643                 &uint_type, &ushort_type);
10644         
10645         register_builtin_function(state, "__builtin_bsf", OP_BSF, &int_type, 
10646                 &int_type);
10647         register_builtin_function(state, "__builtin_bsr", OP_BSR, &int_type, 
10648                 &int_type);
10649
10650         msr_type = register_builtin_type(state, "__builtin_msr_t",
10651                 partial_struct(state, "lo", &ulong_type,
10652                 partial_struct(state, "hi", &ulong_type, 0)));
10653
10654         register_builtin_function(state, "__builtin_rdmsr", OP_RDMSR, msr_type,
10655                 &ulong_type);
10656         register_builtin_function(state, "__builtin_wrmsr", OP_WRMSR, &void_type,
10657                 &ulong_type, &ulong_type, &ulong_type);
10658         
10659         register_builtin_function(state, "__builtin_hlt", OP_HLT, &void_type, 
10660                 &void_type);
10661 }
10662
10663 static struct type *declarator(
10664         struct compile_state *state, struct type *type, 
10665         struct hash_entry **ident, int need_ident);
10666 static void decl(struct compile_state *state, struct triple *first);
10667 static struct type *specifier_qualifier_list(struct compile_state *state);
10668 #if DEBUG_ROMCC_WARNING
10669 static int isdecl_specifier(int tok);
10670 #endif
10671 static struct type *decl_specifiers(struct compile_state *state);
10672 static int istype(int tok);
10673 static struct triple *expr(struct compile_state *state);
10674 static struct triple *assignment_expr(struct compile_state *state);
10675 static struct type *type_name(struct compile_state *state);
10676 static void statement(struct compile_state *state, struct triple *first);
10677
10678 static struct triple *call_expr(
10679         struct compile_state *state, struct triple *func)
10680 {
10681         struct triple *def;
10682         struct type *param, *type;
10683         ulong_t pvals, index;
10684
10685         if ((func->type->type & TYPE_MASK) != TYPE_FUNCTION) {
10686                 error(state, 0, "Called object is not a function");
10687         }
10688         if (func->op != OP_LIST) {
10689                 internal_error(state, 0, "improper function");
10690         }
10691         eat(state, TOK_LPAREN);
10692         /* Find the return type without any specifiers */
10693         type = clone_type(0, func->type->left);
10694         /* Count the number of rhs entries for OP_FCALL */
10695         param = func->type->right;
10696         pvals = 0;
10697         while((param->type & TYPE_MASK) == TYPE_PRODUCT) {
10698                 pvals++;
10699                 param = param->right;
10700         }
10701         if ((param->type & TYPE_MASK) != TYPE_VOID) {
10702                 pvals++;
10703         }
10704         def = new_triple(state, OP_FCALL, type, -1, pvals);
10705         MISC(def, 0) = func;
10706
10707         param = func->type->right;
10708         for(index = 0; index < pvals; index++) {
10709                 struct triple *val;
10710                 struct type *arg_type;
10711                 val = read_expr(state, assignment_expr(state));
10712                 arg_type = param;
10713                 if ((param->type & TYPE_MASK) == TYPE_PRODUCT) {
10714                         arg_type = param->left;
10715                 }
10716                 write_compatible(state, arg_type, val->type);
10717                 RHS(def, index) = val;
10718                 if (index != (pvals - 1)) {
10719                         eat(state, TOK_COMMA);
10720                         param = param->right;
10721                 }
10722         }
10723         eat(state, TOK_RPAREN);
10724         return def;
10725 }
10726
10727
10728 static struct triple *character_constant(struct compile_state *state)
10729 {
10730         struct triple *def;
10731         struct token *tk;
10732         const signed char *str, *end;
10733         int c;
10734         int str_len;
10735         tk = eat(state, TOK_LIT_CHAR);
10736         str = (signed char *)tk->val.str + 1;
10737         str_len = tk->str_len - 2;
10738         if (str_len <= 0) {
10739                 error(state, 0, "empty character constant");
10740         }
10741         end = str + str_len;
10742         c = char_value(state, &str, end);
10743         if (str != end) {
10744                 error(state, 0, "multibyte character constant not supported");
10745         }
10746         def = int_const(state, &char_type, (ulong_t)((long_t)c));
10747         return def;
10748 }
10749
10750 static struct triple *string_constant(struct compile_state *state)
10751 {
10752         struct triple *def;
10753         struct token *tk;
10754         struct type *type;
10755         const signed char *str, *end;
10756         signed char *buf, *ptr;
10757         int str_len;
10758
10759         buf = 0;
10760         type = new_type(TYPE_ARRAY, &char_type, 0);
10761         type->elements = 0;
10762         /* The while loop handles string concatenation */
10763         do {
10764                 tk = eat(state, TOK_LIT_STRING);
10765                 str = (signed char *)tk->val.str + 1;
10766                 str_len = tk->str_len - 2;
10767                 if (str_len < 0) {
10768                         error(state, 0, "negative string constant length");
10769                 }
10770                 end = str + str_len;
10771                 ptr = buf;
10772                 buf = xmalloc(type->elements + str_len + 1, "string_constant");
10773                 memcpy(buf, ptr, type->elements);
10774                 ptr = buf + type->elements;
10775                 do {
10776                         *ptr++ = char_value(state, &str, end);
10777                 } while(str < end);
10778                 type->elements = ptr - buf;
10779         } while(peek(state) == TOK_LIT_STRING);
10780         *ptr = '\0';
10781         type->elements += 1;
10782         def = triple(state, OP_BLOBCONST, type, 0, 0);
10783         def->u.blob = buf;
10784
10785         return def;
10786 }
10787
10788
10789 static struct triple *integer_constant(struct compile_state *state)
10790 {
10791         struct triple *def;
10792         unsigned long val;
10793         struct token *tk;
10794         char *end;
10795         int u, l, decimal;
10796         struct type *type;
10797
10798         tk = eat(state, TOK_LIT_INT);
10799         errno = 0;
10800         decimal = (tk->val.str[0] != '0');
10801         val = strtoul(tk->val.str, &end, 0);
10802         if ((val > ULONG_T_MAX) || ((val == ULONG_MAX) && (errno == ERANGE))) {
10803                 error(state, 0, "Integer constant to large");
10804         }
10805         u = l = 0;
10806         if ((*end == 'u') || (*end == 'U')) {
10807                 u = 1;
10808                         end++;
10809         }
10810         if ((*end == 'l') || (*end == 'L')) {
10811                 l = 1;
10812                 end++;
10813         }
10814         if ((*end == 'u') || (*end == 'U')) {
10815                 u = 1;
10816                 end++;
10817         }
10818         if (*end) {
10819                 error(state, 0, "Junk at end of integer constant");
10820         }
10821         if (u && l)  {
10822                 type = &ulong_type;
10823         }
10824         else if (l) {
10825                 type = &long_type;
10826                 if (!decimal && (val > LONG_T_MAX)) {
10827                         type = &ulong_type;
10828                 }
10829         }
10830         else if (u) {
10831                 type = &uint_type;
10832                 if (val > UINT_T_MAX) {
10833                         type = &ulong_type;
10834                 }
10835         }
10836         else {
10837                 type = &int_type;
10838                 if (!decimal && (val > INT_T_MAX) && (val <= UINT_T_MAX)) {
10839                         type = &uint_type;
10840                 }
10841                 else if (!decimal && (val > LONG_T_MAX)) {
10842                         type = &ulong_type;
10843                 }
10844                 else if (val > INT_T_MAX) {
10845                         type = &long_type;
10846                 }
10847         }
10848         def = int_const(state, type, val);
10849         return def;
10850 }
10851
10852 static struct triple *primary_expr(struct compile_state *state)
10853 {
10854         struct triple *def;
10855         int tok;
10856         tok = peek(state);
10857         switch(tok) {
10858         case TOK_IDENT:
10859         {
10860                 struct hash_entry *ident;
10861                 /* Here ident is either:
10862                  * a varable name
10863                  * a function name
10864                  */
10865                 ident = eat(state, TOK_IDENT)->ident;
10866                 if (!ident->sym_ident) {
10867                         error(state, 0, "%s undeclared", ident->name);
10868                 }
10869                 def = ident->sym_ident->def;
10870                 break;
10871         }
10872         case TOK_ENUM_CONST:
10873         {
10874                 struct hash_entry *ident;
10875                 /* Here ident is an enumeration constant */
10876                 ident = eat(state, TOK_ENUM_CONST)->ident;
10877                 if (!ident->sym_ident) {
10878                         error(state, 0, "%s undeclared", ident->name);
10879                 }
10880                 def = ident->sym_ident->def;
10881                 break;
10882         }
10883         case TOK_MIDENT:
10884         {
10885                 struct hash_entry *ident;
10886                 ident = eat(state, TOK_MIDENT)->ident;
10887                 warning(state, 0, "Replacing undefined macro: %s with 0",
10888                         ident->name);
10889                 def = int_const(state, &int_type, 0);
10890                 break;
10891         }
10892         case TOK_LPAREN:
10893                 eat(state, TOK_LPAREN);
10894                 def = expr(state);
10895                 eat(state, TOK_RPAREN);
10896                 break;
10897         case TOK_LIT_INT:
10898                 def = integer_constant(state);
10899                 break;
10900         case TOK_LIT_FLOAT:
10901                 eat(state, TOK_LIT_FLOAT);
10902                 error(state, 0, "Floating point constants not supported");
10903                 def = 0;
10904                 FINISHME();
10905                 break;
10906         case TOK_LIT_CHAR:
10907                 def = character_constant(state);
10908                 break;
10909         case TOK_LIT_STRING:
10910                 def = string_constant(state);
10911                 break;
10912         default:
10913                 def = 0;
10914                 error(state, 0, "Unexpected token: %s\n", tokens[tok]);
10915         }
10916         return def;
10917 }
10918
10919 static struct triple *postfix_expr(struct compile_state *state)
10920 {
10921         struct triple *def;
10922         int postfix;
10923         def = primary_expr(state);
10924         do {
10925                 struct triple *left;
10926                 int tok;
10927                 postfix = 1;
10928                 left = def;
10929                 switch((tok = peek(state))) {
10930                 case TOK_LBRACKET:
10931                         eat(state, TOK_LBRACKET);
10932                         def = mk_subscript_expr(state, left, expr(state));
10933                         eat(state, TOK_RBRACKET);
10934                         break;
10935                 case TOK_LPAREN:
10936                         def = call_expr(state, def);
10937                         break;
10938                 case TOK_DOT:
10939                 {
10940                         struct hash_entry *field;
10941                         eat(state, TOK_DOT);
10942                         field = eat(state, TOK_IDENT)->ident;
10943                         def = deref_field(state, def, field);
10944                         break;
10945                 }
10946                 case TOK_ARROW:
10947                 {
10948                         struct hash_entry *field;
10949                         eat(state, TOK_ARROW);
10950                         field = eat(state, TOK_IDENT)->ident;
10951                         def = mk_deref_expr(state, read_expr(state, def));
10952                         def = deref_field(state, def, field);
10953                         break;
10954                 }
10955                 case TOK_PLUSPLUS:
10956                         eat(state, TOK_PLUSPLUS);
10957                         def = mk_post_inc_expr(state, left);
10958                         break;
10959                 case TOK_MINUSMINUS:
10960                         eat(state, TOK_MINUSMINUS);
10961                         def = mk_post_dec_expr(state, left);
10962                         break;
10963                 default:
10964                         postfix = 0;
10965                         break;
10966                 }
10967         } while(postfix);
10968         return def;
10969 }
10970
10971 static struct triple *cast_expr(struct compile_state *state);
10972
10973 static struct triple *unary_expr(struct compile_state *state)
10974 {
10975         struct triple *def, *right;
10976         int tok;
10977         switch((tok = peek(state))) {
10978         case TOK_PLUSPLUS:
10979                 eat(state, TOK_PLUSPLUS);
10980                 def = mk_pre_inc_expr(state, unary_expr(state));
10981                 break;
10982         case TOK_MINUSMINUS:
10983                 eat(state, TOK_MINUSMINUS);
10984                 def = mk_pre_dec_expr(state, unary_expr(state));
10985                 break;
10986         case TOK_AND:
10987                 eat(state, TOK_AND);
10988                 def = mk_addr_expr(state, cast_expr(state), 0);
10989                 break;
10990         case TOK_STAR:
10991                 eat(state, TOK_STAR);
10992                 def = mk_deref_expr(state, read_expr(state, cast_expr(state)));
10993                 break;
10994         case TOK_PLUS:
10995                 eat(state, TOK_PLUS);
10996                 right = read_expr(state, cast_expr(state));
10997                 arithmetic(state, right);
10998                 def = integral_promotion(state, right);
10999                 break;
11000         case TOK_MINUS:
11001                 eat(state, TOK_MINUS);
11002                 right = read_expr(state, cast_expr(state));
11003                 arithmetic(state, right);
11004                 def = integral_promotion(state, right);
11005                 def = triple(state, OP_NEG, def->type, def, 0);
11006                 break;
11007         case TOK_TILDE:
11008                 eat(state, TOK_TILDE);
11009                 right = read_expr(state, cast_expr(state));
11010                 integral(state, right);
11011                 def = integral_promotion(state, right);
11012                 def = triple(state, OP_INVERT, def->type, def, 0);
11013                 break;
11014         case TOK_BANG:
11015                 eat(state, TOK_BANG);
11016                 right = read_expr(state, cast_expr(state));
11017                 bool(state, right);
11018                 def = lfalse_expr(state, right);
11019                 break;
11020         case TOK_SIZEOF:
11021         {
11022                 struct type *type;
11023                 int tok1, tok2;
11024                 eat(state, TOK_SIZEOF);
11025                 tok1 = peek(state);
11026                 tok2 = peek2(state);
11027                 if ((tok1 == TOK_LPAREN) && istype(tok2)) {
11028                         eat(state, TOK_LPAREN);
11029                         type = type_name(state);
11030                         eat(state, TOK_RPAREN);
11031                 }
11032                 else {
11033                         struct triple *expr;
11034                         expr = unary_expr(state);
11035                         type = expr->type;
11036                         release_expr(state, expr);
11037                 }
11038                 def = int_const(state, &ulong_type, size_of_in_bytes(state, type));
11039                 break;
11040         }
11041         case TOK_ALIGNOF:
11042         {
11043                 struct type *type;
11044                 int tok1, tok2;
11045                 eat(state, TOK_ALIGNOF);
11046                 tok1 = peek(state);
11047                 tok2 = peek2(state);
11048                 if ((tok1 == TOK_LPAREN) && istype(tok2)) {
11049                         eat(state, TOK_LPAREN);
11050                         type = type_name(state);
11051                         eat(state, TOK_RPAREN);
11052                 }
11053                 else {
11054                         struct triple *expr;
11055                         expr = unary_expr(state);
11056                         type = expr->type;
11057                         release_expr(state, expr);
11058                 }
11059                 def = int_const(state, &ulong_type, align_of_in_bytes(state, type));
11060                 break;
11061         }
11062         case TOK_MDEFINED:
11063         {
11064                 /* We only come here if we are called from the preprocessor */
11065                 struct hash_entry *ident;
11066                 int parens;
11067                 eat(state, TOK_MDEFINED);
11068                 parens = 0;
11069                 if (pp_peek(state) == TOK_LPAREN) {
11070                         pp_eat(state, TOK_LPAREN);
11071                         parens = 1;
11072                 }
11073                 ident = pp_eat(state, TOK_MIDENT)->ident;
11074                 if (parens) {
11075                         eat(state, TOK_RPAREN);
11076                 }
11077                 def = int_const(state, &int_type, ident->sym_define != 0);
11078                 break;
11079         }
11080         default:
11081                 def = postfix_expr(state);
11082                 break;
11083         }
11084         return def;
11085 }
11086
11087 static struct triple *cast_expr(struct compile_state *state)
11088 {
11089         struct triple *def;
11090         int tok1, tok2;
11091         tok1 = peek(state);
11092         tok2 = peek2(state);
11093         if ((tok1 == TOK_LPAREN) && istype(tok2)) {
11094                 struct type *type;
11095                 eat(state, TOK_LPAREN);
11096                 type = type_name(state);
11097                 eat(state, TOK_RPAREN);
11098                 def = mk_cast_expr(state, type, cast_expr(state));
11099         }
11100         else {
11101                 def = unary_expr(state);
11102         }
11103         return def;
11104 }
11105
11106 static struct triple *mult_expr(struct compile_state *state)
11107 {
11108         struct triple *def;
11109         int done;
11110         def = cast_expr(state);
11111         do {
11112                 struct triple *left, *right;
11113                 struct type *result_type;
11114                 int tok, op, sign;
11115                 done = 0;
11116                 tok = peek(state);
11117                 switch(tok) {
11118                 case TOK_STAR:
11119                 case TOK_DIV:
11120                 case TOK_MOD:
11121                         left = read_expr(state, def);
11122                         arithmetic(state, left);
11123
11124                         eat(state, tok);
11125
11126                         right = read_expr(state, cast_expr(state));
11127                         arithmetic(state, right);
11128
11129                         result_type = arithmetic_result(state, left, right);
11130                         sign = is_signed(result_type);
11131                         op = -1;
11132                         switch(tok) {
11133                         case TOK_STAR: op = sign? OP_SMUL : OP_UMUL; break;
11134                         case TOK_DIV:  op = sign? OP_SDIV : OP_UDIV; break;
11135                         case TOK_MOD:  op = sign? OP_SMOD : OP_UMOD; break;
11136                         }
11137                         def = triple(state, op, result_type, left, right);
11138                         break;
11139                 default:
11140                         done = 1;
11141                         break;
11142                 }
11143         } while(!done);
11144         return def;
11145 }
11146
11147 static struct triple *add_expr(struct compile_state *state)
11148 {
11149         struct triple *def;
11150         int done;
11151         def = mult_expr(state);
11152         do {
11153                 done = 0;
11154                 switch( peek(state)) {
11155                 case TOK_PLUS:
11156                         eat(state, TOK_PLUS);
11157                         def = mk_add_expr(state, def, mult_expr(state));
11158                         break;
11159                 case TOK_MINUS:
11160                         eat(state, TOK_MINUS);
11161                         def = mk_sub_expr(state, def, mult_expr(state));
11162                         break;
11163                 default:
11164                         done = 1;
11165                         break;
11166                 }
11167         } while(!done);
11168         return def;
11169 }
11170
11171 static struct triple *shift_expr(struct compile_state *state)
11172 {
11173         struct triple *def;
11174         int done;
11175         def = add_expr(state);
11176         do {
11177                 struct triple *left, *right;
11178                 int tok, op;
11179                 done = 0;
11180                 switch((tok = peek(state))) {
11181                 case TOK_SL:
11182                 case TOK_SR:
11183                         left = read_expr(state, def);
11184                         integral(state, left);
11185                         left = integral_promotion(state, left);
11186
11187                         eat(state, tok);
11188
11189                         right = read_expr(state, add_expr(state));
11190                         integral(state, right);
11191                         right = integral_promotion(state, right);
11192                         
11193                         op = (tok == TOK_SL)? OP_SL : 
11194                                 is_signed(left->type)? OP_SSR: OP_USR;
11195
11196                         def = triple(state, op, left->type, left, right);
11197                         break;
11198                 default:
11199                         done = 1;
11200                         break;
11201                 }
11202         } while(!done);
11203         return def;
11204 }
11205
11206 static struct triple *relational_expr(struct compile_state *state)
11207 {
11208 #if DEBUG_ROMCC_WARNINGS
11209 #warning "Extend relational exprs to work on more than arithmetic types"
11210 #endif
11211         struct triple *def;
11212         int done;
11213         def = shift_expr(state);
11214         do {
11215                 struct triple *left, *right;
11216                 struct type *arg_type;
11217                 int tok, op, sign;
11218                 done = 0;
11219                 switch((tok = peek(state))) {
11220                 case TOK_LESS:
11221                 case TOK_MORE:
11222                 case TOK_LESSEQ:
11223                 case TOK_MOREEQ:
11224                         left = read_expr(state, def);
11225                         arithmetic(state, left);
11226
11227                         eat(state, tok);
11228
11229                         right = read_expr(state, shift_expr(state));
11230                         arithmetic(state, right);
11231
11232                         arg_type = arithmetic_result(state, left, right);
11233                         sign = is_signed(arg_type);
11234                         op = -1;
11235                         switch(tok) {
11236                         case TOK_LESS:   op = sign? OP_SLESS : OP_ULESS; break;
11237                         case TOK_MORE:   op = sign? OP_SMORE : OP_UMORE; break;
11238                         case TOK_LESSEQ: op = sign? OP_SLESSEQ : OP_ULESSEQ; break;
11239                         case TOK_MOREEQ: op = sign? OP_SMOREEQ : OP_UMOREEQ; break;
11240                         }
11241                         def = triple(state, op, &int_type, left, right);
11242                         break;
11243                 default:
11244                         done = 1;
11245                         break;
11246                 }
11247         } while(!done);
11248         return def;
11249 }
11250
11251 static struct triple *equality_expr(struct compile_state *state)
11252 {
11253 #if DEBUG_ROMCC_WARNINGS
11254 #warning "Extend equality exprs to work on more than arithmetic types"
11255 #endif
11256         struct triple *def;
11257         int done;
11258         def = relational_expr(state);
11259         do {
11260                 struct triple *left, *right;
11261                 int tok, op;
11262                 done = 0;
11263                 switch((tok = peek(state))) {
11264                 case TOK_EQEQ:
11265                 case TOK_NOTEQ:
11266                         left = read_expr(state, def);
11267                         arithmetic(state, left);
11268                         eat(state, tok);
11269                         right = read_expr(state, relational_expr(state));
11270                         arithmetic(state, right);
11271                         op = (tok == TOK_EQEQ) ? OP_EQ: OP_NOTEQ;
11272                         def = triple(state, op, &int_type, left, right);
11273                         break;
11274                 default:
11275                         done = 1;
11276                         break;
11277                 }
11278         } while(!done);
11279         return def;
11280 }
11281
11282 static struct triple *and_expr(struct compile_state *state)
11283 {
11284         struct triple *def;
11285         def = equality_expr(state);
11286         while(peek(state) == TOK_AND) {
11287                 struct triple *left, *right;
11288                 struct type *result_type;
11289                 left = read_expr(state, def);
11290                 integral(state, left);
11291                 eat(state, TOK_AND);
11292                 right = read_expr(state, equality_expr(state));
11293                 integral(state, right);
11294                 result_type = arithmetic_result(state, left, right);
11295                 def = triple(state, OP_AND, result_type, left, right);
11296         }
11297         return def;
11298 }
11299
11300 static struct triple *xor_expr(struct compile_state *state)
11301 {
11302         struct triple *def;
11303         def = and_expr(state);
11304         while(peek(state) == TOK_XOR) {
11305                 struct triple *left, *right;
11306                 struct type *result_type;
11307                 left = read_expr(state, def);
11308                 integral(state, left);
11309                 eat(state, TOK_XOR);
11310                 right = read_expr(state, and_expr(state));
11311                 integral(state, right);
11312                 result_type = arithmetic_result(state, left, right);
11313                 def = triple(state, OP_XOR, result_type, left, right);
11314         }
11315         return def;
11316 }
11317
11318 static struct triple *or_expr(struct compile_state *state)
11319 {
11320         struct triple *def;
11321         def = xor_expr(state);
11322         while(peek(state) == TOK_OR) {
11323                 struct triple *left, *right;
11324                 struct type *result_type;
11325                 left = read_expr(state, def);
11326                 integral(state, left);
11327                 eat(state, TOK_OR);
11328                 right = read_expr(state, xor_expr(state));
11329                 integral(state, right);
11330                 result_type = arithmetic_result(state, left, right);
11331                 def = triple(state, OP_OR, result_type, left, right);
11332         }
11333         return def;
11334 }
11335
11336 static struct triple *land_expr(struct compile_state *state)
11337 {
11338         struct triple *def;
11339         def = or_expr(state);
11340         while(peek(state) == TOK_LOGAND) {
11341                 struct triple *left, *right;
11342                 left = read_expr(state, def);
11343                 bool(state, left);
11344                 eat(state, TOK_LOGAND);
11345                 right = read_expr(state, or_expr(state));
11346                 bool(state, right);
11347
11348                 def = mkland_expr(state,
11349                         ltrue_expr(state, left),
11350                         ltrue_expr(state, right));
11351         }
11352         return def;
11353 }
11354
11355 static struct triple *lor_expr(struct compile_state *state)
11356 {
11357         struct triple *def;
11358         def = land_expr(state);
11359         while(peek(state) == TOK_LOGOR) {
11360                 struct triple *left, *right;
11361                 left = read_expr(state, def);
11362                 bool(state, left);
11363                 eat(state, TOK_LOGOR);
11364                 right = read_expr(state, land_expr(state));
11365                 bool(state, right);
11366
11367                 def = mklor_expr(state, 
11368                         ltrue_expr(state, left),
11369                         ltrue_expr(state, right));
11370         }
11371         return def;
11372 }
11373
11374 static struct triple *conditional_expr(struct compile_state *state)
11375 {
11376         struct triple *def;
11377         def = lor_expr(state);
11378         if (peek(state) == TOK_QUEST) {
11379                 struct triple *test, *left, *right;
11380                 bool(state, def);
11381                 test = ltrue_expr(state, read_expr(state, def));
11382                 eat(state, TOK_QUEST);
11383                 left = read_expr(state, expr(state));
11384                 eat(state, TOK_COLON);
11385                 right = read_expr(state, conditional_expr(state));
11386
11387                 def = mkcond_expr(state, test, left, right);
11388         }
11389         return def;
11390 }
11391
11392 struct cv_triple {
11393         struct triple *val;
11394         int id;
11395 };
11396
11397 static void set_cv(struct compile_state *state, struct cv_triple *cv,
11398         struct triple *dest, struct triple *val)
11399 {
11400         if (cv[dest->id].val) {
11401                 free_triple(state, cv[dest->id].val);
11402         }
11403         cv[dest->id].val = val;
11404 }
11405 static struct triple *get_cv(struct compile_state *state, struct cv_triple *cv,
11406         struct triple *src)
11407 {
11408         return cv[src->id].val;
11409 }
11410
11411 static struct triple *eval_const_expr(
11412         struct compile_state *state, struct triple *expr)
11413 {
11414         struct triple *def;
11415         if (is_const(expr)) {
11416                 def = expr;
11417         }
11418         else {
11419                 /* If we don't start out as a constant simplify into one */
11420                 struct triple *head, *ptr;
11421                 struct cv_triple *cv;
11422                 int i, count;
11423                 head = label(state); /* dummy initial triple */
11424                 flatten(state, head, expr);
11425                 count = 1;
11426                 for(ptr = head->next; ptr != head; ptr = ptr->next) {
11427                         count++;
11428                 }
11429                 cv = xcmalloc(sizeof(struct cv_triple)*count, "const value vector");
11430                 i = 1;
11431                 for(ptr = head->next; ptr != head; ptr = ptr->next) {
11432                         cv[i].val = 0;
11433                         cv[i].id  = ptr->id;
11434                         ptr->id   = i;
11435                         i++;
11436                 }
11437                 ptr = head->next;
11438                 do {
11439                         valid_ins(state, ptr);
11440                         if ((ptr->op == OP_PHI) || (ptr->op == OP_LIST)) {
11441                                 internal_error(state, ptr, 
11442                                         "unexpected %s in constant expression",
11443                                         tops(ptr->op));
11444                         }
11445                         else if (ptr->op == OP_LIST) {
11446                         }
11447                         else if (triple_is_structural(state, ptr)) {
11448                                 ptr = ptr->next;
11449                         }
11450                         else if (triple_is_ubranch(state, ptr)) {
11451                                 ptr = TARG(ptr, 0);
11452                         }
11453                         else if (triple_is_cbranch(state, ptr)) {
11454                                 struct triple *cond_val;
11455                                 cond_val = get_cv(state, cv, RHS(ptr, 0));
11456                                 if (!cond_val || !is_const(cond_val) || 
11457                                         (cond_val->op != OP_INTCONST)) 
11458                                 {
11459                                         internal_error(state, ptr, "bad branch condition");
11460                                 }
11461                                 if (cond_val->u.cval == 0) {
11462                                         ptr = ptr->next;
11463                                 } else {
11464                                         ptr = TARG(ptr, 0);
11465                                 }
11466                         }
11467                         else if (triple_is_branch(state, ptr)) {
11468                                 error(state, ptr, "bad branch type in constant expression");
11469                         }
11470                         else if (ptr->op == OP_WRITE) {
11471                                 struct triple *val;
11472                                 val = get_cv(state, cv, RHS(ptr, 0));
11473                                 
11474                                 set_cv(state, cv, MISC(ptr, 0), 
11475                                         copy_triple(state, val));
11476                                 set_cv(state, cv, ptr, 
11477                                         copy_triple(state, val));
11478                                 ptr = ptr->next;
11479                         }
11480                         else if (ptr->op == OP_READ) {
11481                                 set_cv(state, cv, ptr, 
11482                                         copy_triple(state, 
11483                                                 get_cv(state, cv, RHS(ptr, 0))));
11484                                 ptr = ptr->next;
11485                         }
11486                         else if (triple_is_pure(state, ptr, cv[ptr->id].id)) {
11487                                 struct triple *val, **rhs;
11488                                 val = copy_triple(state, ptr);
11489                                 rhs = triple_rhs(state, val, 0);
11490                                 for(; rhs; rhs = triple_rhs(state, val, rhs)) {
11491                                         if (!*rhs) {
11492                                                 internal_error(state, ptr, "Missing rhs");
11493                                         }
11494                                         *rhs = get_cv(state, cv, *rhs);
11495                                 }
11496                                 simplify(state, val);
11497                                 set_cv(state, cv, ptr, val);
11498                                 ptr = ptr->next;
11499                         }
11500                         else {
11501                                 error(state, ptr, "impure operation in constant expression");
11502                         }
11503                         
11504                 } while(ptr != head);
11505
11506                 /* Get the result value */
11507                 def = get_cv(state, cv, head->prev);
11508                 cv[head->prev->id].val = 0;
11509
11510                 /* Free the temporary values */
11511                 for(i = 0; i < count; i++) {
11512                         if (cv[i].val) {
11513                                 free_triple(state, cv[i].val);
11514                                 cv[i].val = 0;
11515                         }
11516                 }
11517                 xfree(cv);
11518                 /* Free the intermediate expressions */
11519                 while(head->next != head) {
11520                         release_triple(state, head->next);
11521                 }
11522                 free_triple(state, head);
11523         }
11524         if (!is_const(def)) {
11525                 error(state, expr, "Not a constant expression");
11526         }
11527         return def;
11528 }
11529
11530 static struct triple *constant_expr(struct compile_state *state)
11531 {
11532         return eval_const_expr(state, conditional_expr(state));
11533 }
11534
11535 static struct triple *assignment_expr(struct compile_state *state)
11536 {
11537         struct triple *def, *left, *right;
11538         int tok, op, sign;
11539         /* The C grammer in K&R shows assignment expressions
11540          * only taking unary expressions as input on their
11541          * left hand side.  But specifies the precedence of
11542          * assignemnt as the lowest operator except for comma.
11543          *
11544          * Allowing conditional expressions on the left hand side
11545          * of an assignement results in a grammar that accepts
11546          * a larger set of statements than standard C.   As long
11547          * as the subset of the grammar that is standard C behaves
11548          * correctly this should cause no problems.
11549          * 
11550          * For the extra token strings accepted by the grammar
11551          * none of them should produce a valid lvalue, so they
11552          * should not produce functioning programs.
11553          *
11554          * GCC has this bug as well, so surprises should be minimal.
11555          */
11556         def = conditional_expr(state);
11557         left = def;
11558         switch((tok = peek(state))) {
11559         case TOK_EQ:
11560                 lvalue(state, left);
11561                 eat(state, TOK_EQ);
11562                 def = write_expr(state, left, 
11563                         read_expr(state, assignment_expr(state)));
11564                 break;
11565         case TOK_TIMESEQ:
11566         case TOK_DIVEQ:
11567         case TOK_MODEQ:
11568                 lvalue(state, left);
11569                 arithmetic(state, left);
11570                 eat(state, tok);
11571                 right = read_expr(state, assignment_expr(state));
11572                 arithmetic(state, right);
11573
11574                 sign = is_signed(left->type);
11575                 op = -1;
11576                 switch(tok) {
11577                 case TOK_TIMESEQ: op = sign? OP_SMUL : OP_UMUL; break;
11578                 case TOK_DIVEQ:   op = sign? OP_SDIV : OP_UDIV; break;
11579                 case TOK_MODEQ:   op = sign? OP_SMOD : OP_UMOD; break;
11580                 }
11581                 def = write_expr(state, left,
11582                         triple(state, op, left->type, 
11583                                 read_expr(state, left), right));
11584                 break;
11585         case TOK_PLUSEQ:
11586                 lvalue(state, left);
11587                 eat(state, TOK_PLUSEQ);
11588                 def = write_expr(state, left,
11589                         mk_add_expr(state, left, assignment_expr(state)));
11590                 break;
11591         case TOK_MINUSEQ:
11592                 lvalue(state, left);
11593                 eat(state, TOK_MINUSEQ);
11594                 def = write_expr(state, left,
11595                         mk_sub_expr(state, left, assignment_expr(state)));
11596                 break;
11597         case TOK_SLEQ:
11598         case TOK_SREQ:
11599         case TOK_ANDEQ:
11600         case TOK_XOREQ:
11601         case TOK_OREQ:
11602                 lvalue(state, left);
11603                 integral(state, left);
11604                 eat(state, tok);
11605                 right = read_expr(state, assignment_expr(state));
11606                 integral(state, right);
11607                 right = integral_promotion(state, right);
11608                 sign = is_signed(left->type);
11609                 op = -1;
11610                 switch(tok) {
11611                 case TOK_SLEQ:  op = OP_SL; break;
11612                 case TOK_SREQ:  op = sign? OP_SSR: OP_USR; break;
11613                 case TOK_ANDEQ: op = OP_AND; break;
11614                 case TOK_XOREQ: op = OP_XOR; break;
11615                 case TOK_OREQ:  op = OP_OR; break;
11616                 }
11617                 def = write_expr(state, left,
11618                         triple(state, op, left->type, 
11619                                 read_expr(state, left), right));
11620                 break;
11621         }
11622         return def;
11623 }
11624
11625 static struct triple *expr(struct compile_state *state)
11626 {
11627         struct triple *def;
11628         def = assignment_expr(state);
11629         while(peek(state) == TOK_COMMA) {
11630                 eat(state, TOK_COMMA);
11631                 def = mkprog(state, def, assignment_expr(state), 0UL);
11632         }
11633         return def;
11634 }
11635
11636 static void expr_statement(struct compile_state *state, struct triple *first)
11637 {
11638         if (peek(state) != TOK_SEMI) {
11639                 /* lvalue conversions always apply except when certian operators
11640                  * are applied.  I apply the lvalue conversions here
11641                  * as I know no more operators will be applied.
11642                  */
11643                 flatten(state, first, lvalue_conversion(state, expr(state)));
11644         }
11645         eat(state, TOK_SEMI);
11646 }
11647
11648 static void if_statement(struct compile_state *state, struct triple *first)
11649 {
11650         struct triple *test, *jmp1, *jmp2, *middle, *end;
11651
11652         jmp1 = jmp2 = middle = 0;
11653         eat(state, TOK_IF);
11654         eat(state, TOK_LPAREN);
11655         test = expr(state);
11656         bool(state, test);
11657         /* Cleanup and invert the test */
11658         test = lfalse_expr(state, read_expr(state, test));
11659         eat(state, TOK_RPAREN);
11660         /* Generate the needed pieces */
11661         middle = label(state);
11662         jmp1 = branch(state, middle, test);
11663         /* Thread the pieces together */
11664         flatten(state, first, test);
11665         flatten(state, first, jmp1);
11666         flatten(state, first, label(state));
11667         statement(state, first);
11668         if (peek(state) == TOK_ELSE) {
11669                 eat(state, TOK_ELSE);
11670                 /* Generate the rest of the pieces */
11671                 end = label(state);
11672                 jmp2 = branch(state, end, 0);
11673                 /* Thread them together */
11674                 flatten(state, first, jmp2);
11675                 flatten(state, first, middle);
11676                 statement(state, first);
11677                 flatten(state, first, end);
11678         }
11679         else {
11680                 flatten(state, first, middle);
11681         }
11682 }
11683
11684 static void for_statement(struct compile_state *state, struct triple *first)
11685 {
11686         struct triple *head, *test, *tail, *jmp1, *jmp2, *end;
11687         struct triple *label1, *label2, *label3;
11688         struct hash_entry *ident;
11689
11690         eat(state, TOK_FOR);
11691         eat(state, TOK_LPAREN);
11692         head = test = tail = jmp1 = jmp2 = 0;
11693         if (peek(state) != TOK_SEMI) {
11694                 head = expr(state);
11695         } 
11696         eat(state, TOK_SEMI);
11697         if (peek(state) != TOK_SEMI) {
11698                 test = expr(state);
11699                 bool(state, test);
11700                 test = ltrue_expr(state, read_expr(state, test));
11701         }
11702         eat(state, TOK_SEMI);
11703         if (peek(state) != TOK_RPAREN) {
11704                 tail = expr(state);
11705         }
11706         eat(state, TOK_RPAREN);
11707         /* Generate the needed pieces */
11708         label1 = label(state);
11709         label2 = label(state);
11710         label3 = label(state);
11711         if (test) {
11712                 jmp1 = branch(state, label3, 0);
11713                 jmp2 = branch(state, label1, test);
11714         }
11715         else {
11716                 jmp2 = branch(state, label1, 0);
11717         }
11718         end = label(state);
11719         /* Remember where break and continue go */
11720         start_scope(state);
11721         ident = state->i_break;
11722         symbol(state, ident, &ident->sym_ident, end, end->type);
11723         ident = state->i_continue;
11724         symbol(state, ident, &ident->sym_ident, label2, label2->type);
11725         /* Now include the body */
11726         flatten(state, first, head);
11727         flatten(state, first, jmp1);
11728         flatten(state, first, label1);
11729         statement(state, first);
11730         flatten(state, first, label2);
11731         flatten(state, first, tail);
11732         flatten(state, first, label3);
11733         flatten(state, first, test);
11734         flatten(state, first, jmp2);
11735         flatten(state, first, end);
11736         /* Cleanup the break/continue scope */
11737         end_scope(state);
11738 }
11739
11740 static void while_statement(struct compile_state *state, struct triple *first)
11741 {
11742         struct triple *label1, *test, *label2, *jmp1, *jmp2, *end;
11743         struct hash_entry *ident;
11744         eat(state, TOK_WHILE);
11745         eat(state, TOK_LPAREN);
11746         test = expr(state);
11747         bool(state, test);
11748         test = ltrue_expr(state, read_expr(state, test));
11749         eat(state, TOK_RPAREN);
11750         /* Generate the needed pieces */
11751         label1 = label(state);
11752         label2 = label(state);
11753         jmp1 = branch(state, label2, 0);
11754         jmp2 = branch(state, label1, test);
11755         end = label(state);
11756         /* Remember where break and continue go */
11757         start_scope(state);
11758         ident = state->i_break;
11759         symbol(state, ident, &ident->sym_ident, end, end->type);
11760         ident = state->i_continue;
11761         symbol(state, ident, &ident->sym_ident, label2, label2->type);
11762         /* Thread them together */
11763         flatten(state, first, jmp1);
11764         flatten(state, first, label1);
11765         statement(state, first);
11766         flatten(state, first, label2);
11767         flatten(state, first, test);
11768         flatten(state, first, jmp2);
11769         flatten(state, first, end);
11770         /* Cleanup the break/continue scope */
11771         end_scope(state);
11772 }
11773
11774 static void do_statement(struct compile_state *state, struct triple *first)
11775 {
11776         struct triple *label1, *label2, *test, *end;
11777         struct hash_entry *ident;
11778         eat(state, TOK_DO);
11779         /* Generate the needed pieces */
11780         label1 = label(state);
11781         label2 = label(state);
11782         end = label(state);
11783         /* Remember where break and continue go */
11784         start_scope(state);
11785         ident = state->i_break;
11786         symbol(state, ident, &ident->sym_ident, end, end->type);
11787         ident = state->i_continue;
11788         symbol(state, ident, &ident->sym_ident, label2, label2->type);
11789         /* Now include the body */
11790         flatten(state, first, label1);
11791         statement(state, first);
11792         /* Cleanup the break/continue scope */
11793         end_scope(state);
11794         /* Eat the rest of the loop */
11795         eat(state, TOK_WHILE);
11796         eat(state, TOK_LPAREN);
11797         test = read_expr(state, expr(state));
11798         bool(state, test);
11799         eat(state, TOK_RPAREN);
11800         eat(state, TOK_SEMI);
11801         /* Thread the pieces together */
11802         test = ltrue_expr(state, test);
11803         flatten(state, first, label2);
11804         flatten(state, first, test);
11805         flatten(state, first, branch(state, label1, test));
11806         flatten(state, first, end);
11807 }
11808
11809
11810 static void return_statement(struct compile_state *state, struct triple *first)
11811 {
11812         struct triple *jmp, *mv, *dest, *var, *val;
11813         int last;
11814         eat(state, TOK_RETURN);
11815
11816 #if DEBUG_ROMCC_WARNINGS
11817 #warning "FIXME implement a more general excess branch elimination"
11818 #endif
11819         val = 0;
11820         /* If we have a return value do some more work */
11821         if (peek(state) != TOK_SEMI) {
11822                 val = read_expr(state, expr(state));
11823         }
11824         eat(state, TOK_SEMI);
11825
11826         /* See if this last statement in a function */
11827         last = ((peek(state) == TOK_RBRACE) && 
11828                 (state->scope_depth == GLOBAL_SCOPE_DEPTH +2));
11829
11830         /* Find the return variable */
11831         var = fresult(state, state->main_function);
11832
11833         /* Find the return destination */
11834         dest = state->i_return->sym_ident->def;
11835         mv = jmp = 0;
11836         /* If needed generate a jump instruction */
11837         if (!last) {
11838                 jmp = branch(state, dest, 0);
11839         }
11840         /* If needed generate an assignment instruction */
11841         if (val) {
11842                 mv = write_expr(state, deref_index(state, var, 1), val);
11843         }
11844         /* Now put the code together */
11845         if (mv) {
11846                 flatten(state, first, mv);
11847                 flatten(state, first, jmp);
11848         }
11849         else if (jmp) {
11850                 flatten(state, first, jmp);
11851         }
11852 }
11853
11854 static void break_statement(struct compile_state *state, struct triple *first)
11855 {
11856         struct triple *dest;
11857         eat(state, TOK_BREAK);
11858         eat(state, TOK_SEMI);
11859         if (!state->i_break->sym_ident) {
11860                 error(state, 0, "break statement not within loop or switch");
11861         }
11862         dest = state->i_break->sym_ident->def;
11863         flatten(state, first, branch(state, dest, 0));
11864 }
11865
11866 static void continue_statement(struct compile_state *state, struct triple *first)
11867 {
11868         struct triple *dest;
11869         eat(state, TOK_CONTINUE);
11870         eat(state, TOK_SEMI);
11871         if (!state->i_continue->sym_ident) {
11872                 error(state, 0, "continue statement outside of a loop");
11873         }
11874         dest = state->i_continue->sym_ident->def;
11875         flatten(state, first, branch(state, dest, 0));
11876 }
11877
11878 static void goto_statement(struct compile_state *state, struct triple *first)
11879 {
11880         struct hash_entry *ident;
11881         eat(state, TOK_GOTO);
11882         ident = eat(state, TOK_IDENT)->ident;
11883         if (!ident->sym_label) {
11884                 /* If this is a forward branch allocate the label now,
11885                  * it will be flattend in the appropriate location later.
11886                  */
11887                 struct triple *ins;
11888                 ins = label(state);
11889                 label_symbol(state, ident, ins, FUNCTION_SCOPE_DEPTH);
11890         }
11891         eat(state, TOK_SEMI);
11892
11893         flatten(state, first, branch(state, ident->sym_label->def, 0));
11894 }
11895
11896 static void labeled_statement(struct compile_state *state, struct triple *first)
11897 {
11898         struct triple *ins;
11899         struct hash_entry *ident;
11900
11901         ident = eat(state, TOK_IDENT)->ident;
11902         if (ident->sym_label && ident->sym_label->def) {
11903                 ins = ident->sym_label->def;
11904                 put_occurance(ins->occurance);
11905                 ins->occurance = new_occurance(state);
11906         }
11907         else {
11908                 ins = label(state);
11909                 label_symbol(state, ident, ins, FUNCTION_SCOPE_DEPTH);
11910         }
11911         if (ins->id & TRIPLE_FLAG_FLATTENED) {
11912                 error(state, 0, "label %s already defined", ident->name);
11913         }
11914         flatten(state, first, ins);
11915
11916         eat(state, TOK_COLON);
11917         statement(state, first);
11918 }
11919
11920 static void switch_statement(struct compile_state *state, struct triple *first)
11921 {
11922         struct triple *value, *top, *end, *dbranch;
11923         struct hash_entry *ident;
11924
11925         /* See if we have a valid switch statement */
11926         eat(state, TOK_SWITCH);
11927         eat(state, TOK_LPAREN);
11928         value = expr(state);
11929         integral(state, value);
11930         value = read_expr(state, value);
11931         eat(state, TOK_RPAREN);
11932         /* Generate the needed pieces */
11933         top = label(state);
11934         end = label(state);
11935         dbranch = branch(state, end, 0);
11936         /* Remember where case branches and break goes */
11937         start_scope(state);
11938         ident = state->i_switch;
11939         symbol(state, ident, &ident->sym_ident, value, value->type);
11940         ident = state->i_case;
11941         symbol(state, ident, &ident->sym_ident, top, top->type);
11942         ident = state->i_break;
11943         symbol(state, ident, &ident->sym_ident, end, end->type);
11944         ident = state->i_default;
11945         symbol(state, ident, &ident->sym_ident, dbranch, dbranch->type);
11946         /* Thread them together */
11947         flatten(state, first, value);
11948         flatten(state, first, top);
11949         flatten(state, first, dbranch);
11950         statement(state, first);
11951         flatten(state, first, end);
11952         /* Cleanup the switch scope */
11953         end_scope(state);
11954 }
11955
11956 static void case_statement(struct compile_state *state, struct triple *first)
11957 {
11958         struct triple *cvalue, *dest, *test, *jmp;
11959         struct triple *ptr, *value, *top, *dbranch;
11960
11961         /* See if w have a valid case statement */
11962         eat(state, TOK_CASE);
11963         cvalue = constant_expr(state);
11964         integral(state, cvalue);
11965         if (cvalue->op != OP_INTCONST) {
11966                 error(state, 0, "integer constant expected");
11967         }
11968         eat(state, TOK_COLON);
11969         if (!state->i_case->sym_ident) {
11970                 error(state, 0, "case statement not within a switch");
11971         }
11972
11973         /* Lookup the interesting pieces */
11974         top = state->i_case->sym_ident->def;
11975         value = state->i_switch->sym_ident->def;
11976         dbranch = state->i_default->sym_ident->def;
11977
11978         /* See if this case label has already been used */
11979         for(ptr = top; ptr != dbranch; ptr = ptr->next) {
11980                 if (ptr->op != OP_EQ) {
11981                         continue;
11982                 }
11983                 if (RHS(ptr, 1)->u.cval == cvalue->u.cval) {
11984                         error(state, 0, "duplicate case %d statement",
11985                                 cvalue->u.cval);
11986                 }
11987         }
11988         /* Generate the needed pieces */
11989         dest = label(state);
11990         test = triple(state, OP_EQ, &int_type, value, cvalue);
11991         jmp = branch(state, dest, test);
11992         /* Thread the pieces together */
11993         flatten(state, dbranch, test);
11994         flatten(state, dbranch, jmp);
11995         flatten(state, dbranch, label(state));
11996         flatten(state, first, dest);
11997         statement(state, first);
11998 }
11999
12000 static void default_statement(struct compile_state *state, struct triple *first)
12001 {
12002         struct triple *dest;
12003         struct triple *dbranch, *end;
12004
12005         /* See if we have a valid default statement */
12006         eat(state, TOK_DEFAULT);
12007         eat(state, TOK_COLON);
12008
12009         if (!state->i_case->sym_ident) {
12010                 error(state, 0, "default statement not within a switch");
12011         }
12012
12013         /* Lookup the interesting pieces */
12014         dbranch = state->i_default->sym_ident->def;
12015         end = state->i_break->sym_ident->def;
12016
12017         /* See if a default statement has already happened */
12018         if (TARG(dbranch, 0) != end) {
12019                 error(state, 0, "duplicate default statement");
12020         }
12021
12022         /* Generate the needed pieces */
12023         dest = label(state);
12024
12025         /* Blame the branch on the default statement */
12026         put_occurance(dbranch->occurance);
12027         dbranch->occurance = new_occurance(state);
12028
12029         /* Thread the pieces together */
12030         TARG(dbranch, 0) = dest;
12031         use_triple(dest, dbranch);
12032         flatten(state, first, dest);
12033         statement(state, first);
12034 }
12035
12036 static void asm_statement(struct compile_state *state, struct triple *first)
12037 {
12038         struct asm_info *info;
12039         struct {
12040                 struct triple *constraint;
12041                 struct triple *expr;
12042         } out_param[MAX_LHS], in_param[MAX_RHS], clob_param[MAX_LHS];
12043         struct triple *def, *asm_str;
12044         int out, in, clobbers, more, colons, i;
12045         int flags;
12046
12047         flags = 0;
12048         eat(state, TOK_ASM);
12049         /* For now ignore the qualifiers */
12050         switch(peek(state)) {
12051         case TOK_CONST:
12052                 eat(state, TOK_CONST);
12053                 break;
12054         case TOK_VOLATILE:
12055                 eat(state, TOK_VOLATILE);
12056                 flags |= TRIPLE_FLAG_VOLATILE;
12057                 break;
12058         }
12059         eat(state, TOK_LPAREN);
12060         asm_str = string_constant(state);
12061
12062         colons = 0;
12063         out = in = clobbers = 0;
12064         /* Outputs */
12065         if ((colons == 0) && (peek(state) == TOK_COLON)) {
12066                 eat(state, TOK_COLON);
12067                 colons++;
12068                 more = (peek(state) == TOK_LIT_STRING);
12069                 while(more) {
12070                         struct triple *var;
12071                         struct triple *constraint;
12072                         char *str;
12073                         more = 0;
12074                         if (out > MAX_LHS) {
12075                                 error(state, 0, "Maximum output count exceeded.");
12076                         }
12077                         constraint = string_constant(state);
12078                         str = constraint->u.blob;
12079                         if (str[0] != '=') {
12080                                 error(state, 0, "Output constraint does not start with =");
12081                         }
12082                         constraint->u.blob = str + 1;
12083                         eat(state, TOK_LPAREN);
12084                         var = conditional_expr(state);
12085                         eat(state, TOK_RPAREN);
12086
12087                         lvalue(state, var);
12088                         out_param[out].constraint = constraint;
12089                         out_param[out].expr       = var;
12090                         if (peek(state) == TOK_COMMA) {
12091                                 eat(state, TOK_COMMA);
12092                                 more = 1;
12093                         }
12094                         out++;
12095                 }
12096         }
12097         /* Inputs */
12098         if ((colons == 1) && (peek(state) == TOK_COLON)) {
12099                 eat(state, TOK_COLON);
12100                 colons++;
12101                 more = (peek(state) == TOK_LIT_STRING);
12102                 while(more) {
12103                         struct triple *val;
12104                         struct triple *constraint;
12105                         char *str;
12106                         more = 0;
12107                         if (in > MAX_RHS) {
12108                                 error(state, 0, "Maximum input count exceeded.");
12109                         }
12110                         constraint = string_constant(state);
12111                         str = constraint->u.blob;
12112                         if (digitp(str[0] && str[1] == '\0')) {
12113                                 int val;
12114                                 val = digval(str[0]);
12115                                 if ((val < 0) || (val >= out)) {
12116                                         error(state, 0, "Invalid input constraint %d", val);
12117                                 }
12118                         }
12119                         eat(state, TOK_LPAREN);
12120                         val = conditional_expr(state);
12121                         eat(state, TOK_RPAREN);
12122
12123                         in_param[in].constraint = constraint;
12124                         in_param[in].expr       = val;
12125                         if (peek(state) == TOK_COMMA) {
12126                                 eat(state, TOK_COMMA);
12127                                 more = 1;
12128                         }
12129                         in++;
12130                 }
12131         }
12132
12133         /* Clobber */
12134         if ((colons == 2) && (peek(state) == TOK_COLON)) {
12135                 eat(state, TOK_COLON);
12136                 colons++;
12137                 more = (peek(state) == TOK_LIT_STRING);
12138                 while(more) {
12139                         struct triple *clobber;
12140                         more = 0;
12141                         if ((clobbers + out) > MAX_LHS) {
12142                                 error(state, 0, "Maximum clobber limit exceeded.");
12143                         }
12144                         clobber = string_constant(state);
12145
12146                         clob_param[clobbers].constraint = clobber;
12147                         if (peek(state) == TOK_COMMA) {
12148                                 eat(state, TOK_COMMA);
12149                                 more = 1;
12150                         }
12151                         clobbers++;
12152                 }
12153         }
12154         eat(state, TOK_RPAREN);
12155         eat(state, TOK_SEMI);
12156
12157
12158         info = xcmalloc(sizeof(*info), "asm_info");
12159         info->str = asm_str->u.blob;
12160         free_triple(state, asm_str);
12161
12162         def = new_triple(state, OP_ASM, &void_type, clobbers + out, in);
12163         def->u.ainfo = info;
12164         def->id |= flags;
12165
12166         /* Find the register constraints */
12167         for(i = 0; i < out; i++) {
12168                 struct triple *constraint;
12169                 constraint = out_param[i].constraint;
12170                 info->tmpl.lhs[i] = arch_reg_constraint(state, 
12171                         out_param[i].expr->type, constraint->u.blob);
12172                 free_triple(state, constraint);
12173         }
12174         for(; i - out < clobbers; i++) {
12175                 struct triple *constraint;
12176                 constraint = clob_param[i - out].constraint;
12177                 info->tmpl.lhs[i] = arch_reg_clobber(state, constraint->u.blob);
12178                 free_triple(state, constraint);
12179         }
12180         for(i = 0; i < in; i++) {
12181                 struct triple *constraint;
12182                 const char *str;
12183                 constraint = in_param[i].constraint;
12184                 str = constraint->u.blob;
12185                 if (digitp(str[0]) && str[1] == '\0') {
12186                         struct reg_info cinfo;
12187                         int val;
12188                         val = digval(str[0]);
12189                         cinfo.reg = info->tmpl.lhs[val].reg;
12190                         cinfo.regcm = arch_type_to_regcm(state, in_param[i].expr->type);
12191                         cinfo.regcm &= info->tmpl.lhs[val].regcm;
12192                         if (cinfo.reg == REG_UNSET) {
12193                                 cinfo.reg = REG_VIRT0 + val;
12194                         }
12195                         if (cinfo.regcm == 0) {
12196                                 error(state, 0, "No registers for %d", val);
12197                         }
12198                         info->tmpl.lhs[val] = cinfo;
12199                         info->tmpl.rhs[i]   = cinfo;
12200                                 
12201                 } else {
12202                         info->tmpl.rhs[i] = arch_reg_constraint(state, 
12203                                 in_param[i].expr->type, str);
12204                 }
12205                 free_triple(state, constraint);
12206         }
12207
12208         /* Now build the helper expressions */
12209         for(i = 0; i < in; i++) {
12210                 RHS(def, i) = read_expr(state, in_param[i].expr);
12211         }
12212         flatten(state, first, def);
12213         for(i = 0; i < (out + clobbers); i++) {
12214                 struct type *type;
12215                 struct triple *piece;
12216                 if (i < out) {
12217                         type = out_param[i].expr->type;
12218                 } else {
12219                         size_t size = arch_reg_size(info->tmpl.lhs[i].reg);
12220                         if (size >= SIZEOF_LONG) {
12221                                 type = &ulong_type;
12222                         } 
12223                         else if (size >= SIZEOF_INT) {
12224                                 type = &uint_type;
12225                         }
12226                         else if (size >= SIZEOF_SHORT) {
12227                                 type = &ushort_type;
12228                         }
12229                         else {
12230                                 type = &uchar_type;
12231                         }
12232                 }
12233                 piece = triple(state, OP_PIECE, type, def, 0);
12234                 piece->u.cval = i;
12235                 LHS(def, i) = piece;
12236                 flatten(state, first, piece);
12237         }
12238         /* And write the helpers to their destinations */
12239         for(i = 0; i < out; i++) {
12240                 struct triple *piece;
12241                 piece = LHS(def, i);
12242                 flatten(state, first,
12243                         write_expr(state, out_param[i].expr, piece));
12244         }
12245 }
12246
12247
12248 static int isdecl(int tok)
12249 {
12250         switch(tok) {
12251         case TOK_AUTO:
12252         case TOK_REGISTER:
12253         case TOK_STATIC:
12254         case TOK_EXTERN:
12255         case TOK_TYPEDEF:
12256         case TOK_CONST:
12257         case TOK_RESTRICT:
12258         case TOK_VOLATILE:
12259         case TOK_VOID:
12260         case TOK_CHAR:
12261         case TOK_SHORT:
12262         case TOK_INT:
12263         case TOK_LONG:
12264         case TOK_FLOAT:
12265         case TOK_DOUBLE:
12266         case TOK_SIGNED:
12267         case TOK_UNSIGNED:
12268         case TOK_STRUCT:
12269         case TOK_UNION:
12270         case TOK_ENUM:
12271         case TOK_TYPE_NAME: /* typedef name */
12272                 return 1;
12273         default:
12274                 return 0;
12275         }
12276 }
12277
12278 static void compound_statement(struct compile_state *state, struct triple *first)
12279 {
12280         eat(state, TOK_LBRACE);
12281         start_scope(state);
12282
12283         /* statement-list opt */
12284         while (peek(state) != TOK_RBRACE) {
12285                 statement(state, first);
12286         }
12287         end_scope(state);
12288         eat(state, TOK_RBRACE);
12289 }
12290
12291 static void statement(struct compile_state *state, struct triple *first)
12292 {
12293         int tok;
12294         tok = peek(state);
12295         if (tok == TOK_LBRACE) {
12296                 compound_statement(state, first);
12297         }
12298         else if (tok == TOK_IF) {
12299                 if_statement(state, first); 
12300         }
12301         else if (tok == TOK_FOR) {
12302                 for_statement(state, first);
12303         }
12304         else if (tok == TOK_WHILE) {
12305                 while_statement(state, first);
12306         }
12307         else if (tok == TOK_DO) {
12308                 do_statement(state, first);
12309         }
12310         else if (tok == TOK_RETURN) {
12311                 return_statement(state, first);
12312         }
12313         else if (tok == TOK_BREAK) {
12314                 break_statement(state, first);
12315         }
12316         else if (tok == TOK_CONTINUE) {
12317                 continue_statement(state, first);
12318         }
12319         else if (tok == TOK_GOTO) {
12320                 goto_statement(state, first);
12321         }
12322         else if (tok == TOK_SWITCH) {
12323                 switch_statement(state, first);
12324         }
12325         else if (tok == TOK_ASM) {
12326                 asm_statement(state, first);
12327         }
12328         else if ((tok == TOK_IDENT) && (peek2(state) == TOK_COLON)) {
12329                 labeled_statement(state, first); 
12330         }
12331         else if (tok == TOK_CASE) {
12332                 case_statement(state, first);
12333         }
12334         else if (tok == TOK_DEFAULT) {
12335                 default_statement(state, first);
12336         }
12337         else if (isdecl(tok)) {
12338                 /* This handles C99 intermixing of statements and decls */
12339                 decl(state, first);
12340         }
12341         else {
12342                 expr_statement(state, first);
12343         }
12344 }
12345
12346 static struct type *param_decl(struct compile_state *state)
12347 {
12348         struct type *type;
12349         struct hash_entry *ident;
12350         /* Cheat so the declarator will know we are not global */
12351         start_scope(state); 
12352         ident = 0;
12353         type = decl_specifiers(state);
12354         type = declarator(state, type, &ident, 0);
12355         type->field_ident = ident;
12356         end_scope(state);
12357         return type;
12358 }
12359
12360 static struct type *param_type_list(struct compile_state *state, struct type *type)
12361 {
12362         struct type *ftype, **next;
12363         ftype = new_type(TYPE_FUNCTION | (type->type & STOR_MASK), type, param_decl(state));
12364         next = &ftype->right;
12365         ftype->elements = 1;
12366         while(peek(state) == TOK_COMMA) {
12367                 eat(state, TOK_COMMA);
12368                 if (peek(state) == TOK_DOTS) {
12369                         eat(state, TOK_DOTS);
12370                         error(state, 0, "variadic functions not supported");
12371                 }
12372                 else {
12373                         *next = new_type(TYPE_PRODUCT, *next, param_decl(state));
12374                         next = &((*next)->right);
12375                         ftype->elements++;
12376                 }
12377         }
12378         return ftype;
12379 }
12380
12381 static struct type *type_name(struct compile_state *state)
12382 {
12383         struct type *type;
12384         type = specifier_qualifier_list(state);
12385         /* abstract-declarator (may consume no tokens) */
12386         type = declarator(state, type, 0, 0);
12387         return type;
12388 }
12389
12390 static struct type *direct_declarator(
12391         struct compile_state *state, struct type *type, 
12392         struct hash_entry **pident, int need_ident)
12393 {
12394         struct hash_entry *ident;
12395         struct type *outer;
12396         int op;
12397         outer = 0;
12398         arrays_complete(state, type);
12399         switch(peek(state)) {
12400         case TOK_IDENT:
12401                 ident = eat(state, TOK_IDENT)->ident;
12402                 if (!ident) {
12403                         error(state, 0, "Unexpected identifier found");
12404                 }
12405                 /* The name of what we are declaring */
12406                 *pident = ident;
12407                 break;
12408         case TOK_LPAREN:
12409                 eat(state, TOK_LPAREN);
12410                 outer = declarator(state, type, pident, need_ident);
12411                 eat(state, TOK_RPAREN);
12412                 break;
12413         default:
12414                 if (need_ident) {
12415                         error(state, 0, "Identifier expected");
12416                 }
12417                 break;
12418         }
12419         do {
12420                 op = 1;
12421                 arrays_complete(state, type);
12422                 switch(peek(state)) {
12423                 case TOK_LPAREN:
12424                         eat(state, TOK_LPAREN);
12425                         type = param_type_list(state, type);
12426                         eat(state, TOK_RPAREN);
12427                         break;
12428                 case TOK_LBRACKET:
12429                 {
12430                         unsigned int qualifiers;
12431                         struct triple *value;
12432                         value = 0;
12433                         eat(state, TOK_LBRACKET);
12434                         if (peek(state) != TOK_RBRACKET) {
12435                                 value = constant_expr(state);
12436                                 integral(state, value);
12437                         }
12438                         eat(state, TOK_RBRACKET);
12439
12440                         qualifiers = type->type & (QUAL_MASK | STOR_MASK);
12441                         type = new_type(TYPE_ARRAY | qualifiers, type, 0);
12442                         if (value) {
12443                                 type->elements = value->u.cval;
12444                                 free_triple(state, value);
12445                         } else {
12446                                 type->elements = ELEMENT_COUNT_UNSPECIFIED;
12447                                 op = 0;
12448                         }
12449                 }
12450                         break;
12451                 default:
12452                         op = 0;
12453                         break;
12454                 }
12455         } while(op);
12456         if (outer) {
12457                 struct type *inner;
12458                 arrays_complete(state, type);
12459                 FINISHME();
12460                 for(inner = outer; inner->left; inner = inner->left)
12461                         ;
12462                 inner->left = type;
12463                 type = outer;
12464         }
12465         return type;
12466 }
12467
12468 static struct type *declarator(
12469         struct compile_state *state, struct type *type, 
12470         struct hash_entry **pident, int need_ident)
12471 {
12472         while(peek(state) == TOK_STAR) {
12473                 eat(state, TOK_STAR);
12474                 type = new_type(TYPE_POINTER | (type->type & STOR_MASK), type, 0);
12475         }
12476         type = direct_declarator(state, type, pident, need_ident);
12477         return type;
12478 }
12479
12480 static struct type *typedef_name(
12481         struct compile_state *state, unsigned int specifiers)
12482 {
12483         struct hash_entry *ident;
12484         struct type *type;
12485         ident = eat(state, TOK_TYPE_NAME)->ident;
12486         type = ident->sym_ident->type;
12487         specifiers |= type->type & QUAL_MASK;
12488         if ((specifiers & (STOR_MASK | QUAL_MASK)) != 
12489                 (type->type & (STOR_MASK | QUAL_MASK))) {
12490                 type = clone_type(specifiers, type);
12491         }
12492         return type;
12493 }
12494
12495 static struct type *enum_specifier(
12496         struct compile_state *state, unsigned int spec)
12497 {
12498         struct hash_entry *ident;
12499         ulong_t base;
12500         int tok;
12501         struct type *enum_type;
12502         enum_type = 0;
12503         ident = 0;
12504         eat(state, TOK_ENUM);
12505         tok = peek(state);
12506         if ((tok == TOK_IDENT) || (tok == TOK_ENUM_CONST) || (tok == TOK_TYPE_NAME)) {
12507                 ident = eat(state, tok)->ident;
12508         }
12509         base = 0;
12510         if (!ident || (peek(state) == TOK_LBRACE)) {
12511                 struct type **next;
12512                 eat(state, TOK_LBRACE);
12513                 enum_type = new_type(TYPE_ENUM | spec, 0, 0);
12514                 enum_type->type_ident = ident;
12515                 next = &enum_type->right;
12516                 do {
12517                         struct hash_entry *eident;
12518                         struct triple *value;
12519                         struct type *entry;
12520                         eident = eat(state, TOK_IDENT)->ident;
12521                         if (eident->sym_ident) {
12522                                 error(state, 0, "%s already declared", 
12523                                         eident->name);
12524                         }
12525                         eident->tok = TOK_ENUM_CONST;
12526                         if (peek(state) == TOK_EQ) {
12527                                 struct triple *val;
12528                                 eat(state, TOK_EQ);
12529                                 val = constant_expr(state);
12530                                 integral(state, val);
12531                                 base = val->u.cval;
12532                         }
12533                         value = int_const(state, &int_type, base);
12534                         symbol(state, eident, &eident->sym_ident, value, &int_type);
12535                         entry = new_type(TYPE_LIST, 0, 0);
12536                         entry->field_ident = eident;
12537                         *next = entry;
12538                         next = &entry->right;
12539                         base += 1;
12540                         if (peek(state) == TOK_COMMA) {
12541                                 eat(state, TOK_COMMA);
12542                         }
12543                 } while(peek(state) != TOK_RBRACE);
12544                 eat(state, TOK_RBRACE);
12545                 if (ident) {
12546                         symbol(state, ident, &ident->sym_tag, 0, enum_type);
12547                 }
12548         }
12549         if (ident && ident->sym_tag &&
12550                 ident->sym_tag->type &&
12551                 ((ident->sym_tag->type->type & TYPE_MASK) == TYPE_ENUM)) {
12552                 enum_type = clone_type(spec, ident->sym_tag->type);
12553         }
12554         else if (ident && !enum_type) {
12555                 error(state, 0, "enum %s undeclared", ident->name);
12556         }
12557         return enum_type;
12558 }
12559
12560 static struct type *struct_declarator(
12561         struct compile_state *state, struct type *type, struct hash_entry **ident)
12562 {
12563         if (peek(state) != TOK_COLON) {
12564                 type = declarator(state, type, ident, 1);
12565         }
12566         if (peek(state) == TOK_COLON) {
12567                 struct triple *value;
12568                 eat(state, TOK_COLON);
12569                 value = constant_expr(state);
12570                 if (value->op != OP_INTCONST) {
12571                         error(state, 0, "Invalid constant expression");
12572                 }
12573                 if (value->u.cval > size_of(state, type)) {
12574                         error(state, 0, "bitfield larger than base type");
12575                 }
12576                 if (!TYPE_INTEGER(type->type) || ((type->type & TYPE_MASK) == TYPE_BITFIELD)) {
12577                         error(state, 0, "bitfield base not an integer type");
12578                 }
12579                 type = new_type(TYPE_BITFIELD, type, 0);
12580                 type->elements = value->u.cval;
12581         }
12582         return type;
12583 }
12584
12585 static struct type *struct_or_union_specifier(
12586         struct compile_state *state, unsigned int spec)
12587 {
12588         struct type *struct_type;
12589         struct hash_entry *ident;
12590         unsigned int type_main;
12591         unsigned int type_join;
12592         int tok;
12593         struct_type = 0;
12594         ident = 0;
12595         switch(peek(state)) {
12596         case TOK_STRUCT:
12597                 eat(state, TOK_STRUCT);
12598                 type_main = TYPE_STRUCT;
12599                 type_join = TYPE_PRODUCT;
12600                 break;
12601         case TOK_UNION:
12602                 eat(state, TOK_UNION);
12603                 type_main = TYPE_UNION;
12604                 type_join = TYPE_OVERLAP;
12605                 break;
12606         default:
12607                 eat(state, TOK_STRUCT);
12608                 type_main = TYPE_STRUCT;
12609                 type_join = TYPE_PRODUCT;
12610                 break;
12611         }
12612         tok = peek(state);
12613         if ((tok == TOK_IDENT) || (tok == TOK_ENUM_CONST) || (tok == TOK_TYPE_NAME)) {
12614                 ident = eat(state, tok)->ident;
12615         }
12616         if (!ident || (peek(state) == TOK_LBRACE)) {
12617                 ulong_t elements;
12618                 struct type **next;
12619                 elements = 0;
12620                 eat(state, TOK_LBRACE);
12621                 next = &struct_type;
12622                 do {
12623                         struct type *base_type;
12624                         int done;
12625                         base_type = specifier_qualifier_list(state);
12626                         do {
12627                                 struct type *type;
12628                                 struct hash_entry *fident;
12629                                 done = 1;
12630                                 type = struct_declarator(state, base_type, &fident);
12631                                 elements++;
12632                                 if (peek(state) == TOK_COMMA) {
12633                                         done = 0;
12634                                         eat(state, TOK_COMMA);
12635                                 }
12636                                 type = clone_type(0, type);
12637                                 type->field_ident = fident;
12638                                 if (*next) {
12639                                         *next = new_type(type_join, *next, type);
12640                                         next = &((*next)->right);
12641                                 } else {
12642                                         *next = type;
12643                                 }
12644                         } while(!done);
12645                         eat(state, TOK_SEMI);
12646                 } while(peek(state) != TOK_RBRACE);
12647                 eat(state, TOK_RBRACE);
12648                 struct_type = new_type(type_main | spec, struct_type, 0);
12649                 struct_type->type_ident = ident;
12650                 struct_type->elements = elements;
12651                 if (ident) {
12652                         symbol(state, ident, &ident->sym_tag, 0, struct_type);
12653                 }
12654         }
12655         if (ident && ident->sym_tag && 
12656                 ident->sym_tag->type && 
12657                 ((ident->sym_tag->type->type & TYPE_MASK) == type_main)) {
12658                 struct_type = clone_type(spec, ident->sym_tag->type);
12659         }
12660         else if (ident && !struct_type) {
12661                 error(state, 0, "%s %s undeclared", 
12662                         (type_main == TYPE_STRUCT)?"struct" : "union",
12663                         ident->name);
12664         }
12665         return struct_type;
12666 }
12667
12668 static unsigned int storage_class_specifier_opt(struct compile_state *state)
12669 {
12670         unsigned int specifiers;
12671         switch(peek(state)) {
12672         case TOK_AUTO:
12673                 eat(state, TOK_AUTO);
12674                 specifiers = STOR_AUTO;
12675                 break;
12676         case TOK_REGISTER:
12677                 eat(state, TOK_REGISTER);
12678                 specifiers = STOR_REGISTER;
12679                 break;
12680         case TOK_STATIC:
12681                 eat(state, TOK_STATIC);
12682                 specifiers = STOR_STATIC;
12683                 break;
12684         case TOK_EXTERN:
12685                 eat(state, TOK_EXTERN);
12686                 specifiers = STOR_EXTERN;
12687                 break;
12688         case TOK_TYPEDEF:
12689                 eat(state, TOK_TYPEDEF);
12690                 specifiers = STOR_TYPEDEF;
12691                 break;
12692         default:
12693                 if (state->scope_depth <= GLOBAL_SCOPE_DEPTH) {
12694                         specifiers = STOR_LOCAL;
12695                 }
12696                 else {
12697                         specifiers = STOR_AUTO;
12698                 }
12699         }
12700         return specifiers;
12701 }
12702
12703 static unsigned int function_specifier_opt(struct compile_state *state)
12704 {
12705         /* Ignore the inline keyword */
12706         unsigned int specifiers;
12707         specifiers = 0;
12708         switch(peek(state)) {
12709         case TOK_INLINE:
12710                 eat(state, TOK_INLINE);
12711                 specifiers = STOR_INLINE;
12712         }
12713         return specifiers;
12714 }
12715
12716 static unsigned int attrib(struct compile_state *state, unsigned int attributes)
12717 {
12718         int tok = peek(state);
12719         switch(tok) {
12720         case TOK_COMMA:
12721         case TOK_LPAREN:
12722                 /* The empty attribute ignore it */
12723                 break;
12724         case TOK_IDENT:
12725         case TOK_ENUM_CONST:
12726         case TOK_TYPE_NAME:
12727         {
12728                 struct hash_entry *ident;
12729                 ident = eat(state, TOK_IDENT)->ident;
12730
12731                 if (ident == state->i_noinline) {
12732                         if (attributes & ATTRIB_ALWAYS_INLINE) {
12733                                 error(state, 0, "both always_inline and noinline attribtes");
12734                         }
12735                         attributes |= ATTRIB_NOINLINE;
12736                 }
12737                 else if (ident == state->i_always_inline) {
12738                         if (attributes & ATTRIB_NOINLINE) {
12739                                 error(state, 0, "both noinline and always_inline attribtes");
12740                         }
12741                         attributes |= ATTRIB_ALWAYS_INLINE;
12742                 }
12743                 else {
12744                         error(state, 0, "Unknown attribute:%s", ident->name);
12745                 }
12746                 break;
12747         }
12748         default:
12749                 error(state, 0, "Unexpected token: %s\n", tokens[tok]);
12750                 break;
12751         }
12752         return attributes;
12753 }
12754
12755 static unsigned int attribute_list(struct compile_state *state, unsigned type)
12756 {
12757         type = attrib(state, type);
12758         while(peek(state) == TOK_COMMA) {
12759                 eat(state, TOK_COMMA);
12760                 type = attrib(state, type);
12761         }
12762         return type;
12763 }
12764
12765 static unsigned int attributes_opt(struct compile_state *state, unsigned type)
12766 {
12767         if (peek(state) == TOK_ATTRIBUTE) {
12768                 eat(state, TOK_ATTRIBUTE);
12769                 eat(state, TOK_LPAREN);
12770                 eat(state, TOK_LPAREN);
12771                 type = attribute_list(state, type);
12772                 eat(state, TOK_RPAREN);
12773                 eat(state, TOK_RPAREN);
12774         }
12775         return type;
12776 }
12777
12778 static unsigned int type_qualifiers(struct compile_state *state)
12779 {
12780         unsigned int specifiers;
12781         int done;
12782         done = 0;
12783         specifiers = QUAL_NONE;
12784         do {
12785                 switch(peek(state)) {
12786                 case TOK_CONST:
12787                         eat(state, TOK_CONST);
12788                         specifiers |= QUAL_CONST;
12789                         break;
12790                 case TOK_VOLATILE:
12791                         eat(state, TOK_VOLATILE);
12792                         specifiers |= QUAL_VOLATILE;
12793                         break;
12794                 case TOK_RESTRICT:
12795                         eat(state, TOK_RESTRICT);
12796                         specifiers |= QUAL_RESTRICT;
12797                         break;
12798                 default:
12799                         done = 1;
12800                         break;
12801                 }
12802         } while(!done);
12803         return specifiers;
12804 }
12805
12806 static struct type *type_specifier(
12807         struct compile_state *state, unsigned int spec)
12808 {
12809         struct type *type;
12810         int tok;
12811         type = 0;
12812         switch((tok = peek(state))) {
12813         case TOK_VOID:
12814                 eat(state, TOK_VOID);
12815                 type = new_type(TYPE_VOID | spec, 0, 0);
12816                 break;
12817         case TOK_CHAR:
12818                 eat(state, TOK_CHAR);
12819                 type = new_type(TYPE_CHAR | spec, 0, 0);
12820                 break;
12821         case TOK_SHORT:
12822                 eat(state, TOK_SHORT);
12823                 if (peek(state) == TOK_INT) {
12824                         eat(state, TOK_INT);
12825                 }
12826                 type = new_type(TYPE_SHORT | spec, 0, 0);
12827                 break;
12828         case TOK_INT:
12829                 eat(state, TOK_INT);
12830                 type = new_type(TYPE_INT | spec, 0, 0);
12831                 break;
12832         case TOK_LONG:
12833                 eat(state, TOK_LONG);
12834                 switch(peek(state)) {
12835                 case TOK_LONG:
12836                         eat(state, TOK_LONG);
12837                         error(state, 0, "long long not supported");
12838                         break;
12839                 case TOK_DOUBLE:
12840                         eat(state, TOK_DOUBLE);
12841                         error(state, 0, "long double not supported");
12842                         break;
12843                 case TOK_INT:
12844                         eat(state, TOK_INT);
12845                         type = new_type(TYPE_LONG | spec, 0, 0);
12846                         break;
12847                 default:
12848                         type = new_type(TYPE_LONG | spec, 0, 0);
12849                         break;
12850                 }
12851                 break;
12852         case TOK_FLOAT:
12853                 eat(state, TOK_FLOAT);
12854                 error(state, 0, "type float not supported");
12855                 break;
12856         case TOK_DOUBLE:
12857                 eat(state, TOK_DOUBLE);
12858                 error(state, 0, "type double not supported");
12859                 break;
12860         case TOK_SIGNED:
12861                 eat(state, TOK_SIGNED);
12862                 switch(peek(state)) {
12863                 case TOK_LONG:
12864                         eat(state, TOK_LONG);
12865                         switch(peek(state)) {
12866                         case TOK_LONG:
12867                                 eat(state, TOK_LONG);
12868                                 error(state, 0, "type long long not supported");
12869                                 break;
12870                         case TOK_INT:
12871                                 eat(state, TOK_INT);
12872                                 type = new_type(TYPE_LONG | spec, 0, 0);
12873                                 break;
12874                         default:
12875                                 type = new_type(TYPE_LONG | spec, 0, 0);
12876                                 break;
12877                         }
12878                         break;
12879                 case TOK_INT:
12880                         eat(state, TOK_INT);
12881                         type = new_type(TYPE_INT | spec, 0, 0);
12882                         break;
12883                 case TOK_SHORT:
12884                         eat(state, TOK_SHORT);
12885                         type = new_type(TYPE_SHORT | spec, 0, 0);
12886                         break;
12887                 case TOK_CHAR:
12888                         eat(state, TOK_CHAR);
12889                         type = new_type(TYPE_CHAR | spec, 0, 0);
12890                         break;
12891                 default:
12892                         type = new_type(TYPE_INT | spec, 0, 0);
12893                         break;
12894                 }
12895                 break;
12896         case TOK_UNSIGNED:
12897                 eat(state, TOK_UNSIGNED);
12898                 switch(peek(state)) {
12899                 case TOK_LONG:
12900                         eat(state, TOK_LONG);
12901                         switch(peek(state)) {
12902                         case TOK_LONG:
12903                                 eat(state, TOK_LONG);
12904                                 error(state, 0, "unsigned long long not supported");
12905                                 break;
12906                         case TOK_INT:
12907                                 eat(state, TOK_INT);
12908                                 type = new_type(TYPE_ULONG | spec, 0, 0);
12909                                 break;
12910                         default:
12911                                 type = new_type(TYPE_ULONG | spec, 0, 0);
12912                                 break;
12913                         }
12914                         break;
12915                 case TOK_INT:
12916                         eat(state, TOK_INT);
12917                         type = new_type(TYPE_UINT | spec, 0, 0);
12918                         break;
12919                 case TOK_SHORT:
12920                         eat(state, TOK_SHORT);
12921                         type = new_type(TYPE_USHORT | spec, 0, 0);
12922                         break;
12923                 case TOK_CHAR:
12924                         eat(state, TOK_CHAR);
12925                         type = new_type(TYPE_UCHAR | spec, 0, 0);
12926                         break;
12927                 default:
12928                         type = new_type(TYPE_UINT | spec, 0, 0);
12929                         break;
12930                 }
12931                 break;
12932                 /* struct or union specifier */
12933         case TOK_STRUCT:
12934         case TOK_UNION:
12935                 type = struct_or_union_specifier(state, spec);
12936                 break;
12937                 /* enum-spefifier */
12938         case TOK_ENUM:
12939                 type = enum_specifier(state, spec);
12940                 break;
12941                 /* typedef name */
12942         case TOK_TYPE_NAME:
12943                 type = typedef_name(state, spec);
12944                 break;
12945         default:
12946                 error(state, 0, "bad type specifier %s", 
12947                         tokens[tok]);
12948                 break;
12949         }
12950         return type;
12951 }
12952
12953 static int istype(int tok)
12954 {
12955         switch(tok) {
12956         case TOK_CONST:
12957         case TOK_RESTRICT:
12958         case TOK_VOLATILE:
12959         case TOK_VOID:
12960         case TOK_CHAR:
12961         case TOK_SHORT:
12962         case TOK_INT:
12963         case TOK_LONG:
12964         case TOK_FLOAT:
12965         case TOK_DOUBLE:
12966         case TOK_SIGNED:
12967         case TOK_UNSIGNED:
12968         case TOK_STRUCT:
12969         case TOK_UNION:
12970         case TOK_ENUM:
12971         case TOK_TYPE_NAME:
12972                 return 1;
12973         default:
12974                 return 0;
12975         }
12976 }
12977
12978
12979 static struct type *specifier_qualifier_list(struct compile_state *state)
12980 {
12981         struct type *type;
12982         unsigned int specifiers = 0;
12983
12984         /* type qualifiers */
12985         specifiers |= type_qualifiers(state);
12986
12987         /* type specifier */
12988         type = type_specifier(state, specifiers);
12989
12990         return type;
12991 }
12992
12993 #if DEBUG_ROMCC_WARNING
12994 static int isdecl_specifier(int tok)
12995 {
12996         switch(tok) {
12997                 /* storage class specifier */
12998         case TOK_AUTO:
12999         case TOK_REGISTER:
13000         case TOK_STATIC:
13001         case TOK_EXTERN:
13002         case TOK_TYPEDEF:
13003                 /* type qualifier */
13004         case TOK_CONST:
13005         case TOK_RESTRICT:
13006         case TOK_VOLATILE:
13007                 /* type specifiers */
13008         case TOK_VOID:
13009         case TOK_CHAR:
13010         case TOK_SHORT:
13011         case TOK_INT:
13012         case TOK_LONG:
13013         case TOK_FLOAT:
13014         case TOK_DOUBLE:
13015         case TOK_SIGNED:
13016         case TOK_UNSIGNED:
13017                 /* struct or union specifier */
13018         case TOK_STRUCT:
13019         case TOK_UNION:
13020                 /* enum-spefifier */
13021         case TOK_ENUM:
13022                 /* typedef name */
13023         case TOK_TYPE_NAME:
13024                 /* function specifiers */
13025         case TOK_INLINE:
13026                 return 1;
13027         default:
13028                 return 0;
13029         }
13030 }
13031 #endif
13032
13033 static struct type *decl_specifiers(struct compile_state *state)
13034 {
13035         struct type *type;
13036         unsigned int specifiers;
13037         /* I am overly restrictive in the arragement of specifiers supported.
13038          * C is overly flexible in this department it makes interpreting
13039          * the parse tree difficult.
13040          */
13041         specifiers = 0;
13042
13043         /* storage class specifier */
13044         specifiers |= storage_class_specifier_opt(state);
13045
13046         /* function-specifier */
13047         specifiers |= function_specifier_opt(state);
13048
13049         /* attributes */
13050         specifiers |= attributes_opt(state, 0);
13051
13052         /* type qualifier */
13053         specifiers |= type_qualifiers(state);
13054
13055         /* type specifier */
13056         type = type_specifier(state, specifiers);
13057         return type;
13058 }
13059
13060 struct field_info {
13061         struct type *type;
13062         size_t offset;
13063 };
13064
13065 static struct field_info designator(struct compile_state *state, struct type *type)
13066 {
13067         int tok;
13068         struct field_info info;
13069         info.offset = ~0U;
13070         info.type = 0;
13071         do {
13072                 switch(peek(state)) {
13073                 case TOK_LBRACKET:
13074                 {
13075                         struct triple *value;
13076                         if ((type->type & TYPE_MASK) != TYPE_ARRAY) {
13077                                 error(state, 0, "Array designator not in array initializer");
13078                         }
13079                         eat(state, TOK_LBRACKET);
13080                         value = constant_expr(state);
13081                         eat(state, TOK_RBRACKET);
13082
13083                         info.type = type->left;
13084                         info.offset = value->u.cval * size_of(state, info.type);
13085                         break;
13086                 }
13087                 case TOK_DOT:
13088                 {
13089                         struct hash_entry *field;
13090                         if (((type->type & TYPE_MASK) != TYPE_STRUCT) &&
13091                                 ((type->type & TYPE_MASK) != TYPE_UNION))
13092                         {
13093                                 error(state, 0, "Struct designator not in struct initializer");
13094                         }
13095                         eat(state, TOK_DOT);
13096                         field = eat(state, TOK_IDENT)->ident;
13097                         info.offset = field_offset(state, type, field);
13098                         info.type   = field_type(state, type, field);
13099                         break;
13100                 }
13101                 default:
13102                         error(state, 0, "Invalid designator");
13103                 }
13104                 tok = peek(state);
13105         } while((tok == TOK_LBRACKET) || (tok == TOK_DOT));
13106         eat(state, TOK_EQ);
13107         return info;
13108 }
13109
13110 static struct triple *initializer(
13111         struct compile_state *state, struct type *type)
13112 {
13113         struct triple *result;
13114 #if DEBUG_ROMCC_WARNINGS
13115 #warning "FIXME more consistent initializer handling (where should eval_const_expr go?"
13116 #endif
13117         if (peek(state) != TOK_LBRACE) {
13118                 result = assignment_expr(state);
13119                 if (((type->type & TYPE_MASK) == TYPE_ARRAY) &&
13120                         (type->elements == ELEMENT_COUNT_UNSPECIFIED) &&
13121                         ((result->type->type & TYPE_MASK) == TYPE_ARRAY) &&
13122                         (result->type->elements != ELEMENT_COUNT_UNSPECIFIED) &&
13123                         (equiv_types(type->left, result->type->left))) {
13124                         type->elements = result->type->elements;
13125                 }
13126                 if (is_lvalue(state, result) && 
13127                         ((result->type->type & TYPE_MASK) == TYPE_ARRAY) &&
13128                         (type->type & TYPE_MASK) != TYPE_ARRAY)
13129                 {
13130                         result = lvalue_conversion(state, result);
13131                 }
13132                 if (!is_init_compatible(state, type, result->type)) {
13133                         error(state, 0, "Incompatible types in initializer");
13134                 }
13135                 if (!equiv_types(type, result->type)) {
13136                         result = mk_cast_expr(state, type, result);
13137                 }
13138         }
13139         else {
13140                 int comma;
13141                 size_t max_offset;
13142                 struct field_info info;
13143                 void *buf;
13144                 if (((type->type & TYPE_MASK) != TYPE_ARRAY) &&
13145                         ((type->type & TYPE_MASK) != TYPE_STRUCT)) {
13146                         internal_error(state, 0, "unknown initializer type");
13147                 }
13148                 info.offset = 0;
13149                 info.type = type->left;
13150                 if ((type->type & TYPE_MASK) == TYPE_STRUCT) {
13151                         info.type = next_field(state, type, 0);
13152                 }
13153                 if (type->elements == ELEMENT_COUNT_UNSPECIFIED) {
13154                         max_offset = 0;
13155                 } else {
13156                         max_offset = size_of(state, type);
13157                 }
13158                 buf = xcmalloc(bits_to_bytes(max_offset), "initializer");
13159                 eat(state, TOK_LBRACE);
13160                 do {
13161                         struct triple *value;
13162                         struct type *value_type;
13163                         size_t value_size;
13164                         void *dest;
13165                         int tok;
13166                         comma = 0;
13167                         tok = peek(state);
13168                         if ((tok == TOK_LBRACKET) || (tok == TOK_DOT)) {
13169                                 info = designator(state, type);
13170                         }
13171                         if ((type->elements != ELEMENT_COUNT_UNSPECIFIED) &&
13172                                 (info.offset >= max_offset)) {
13173                                 error(state, 0, "element beyond bounds");
13174                         }
13175                         value_type = info.type;
13176                         value = eval_const_expr(state, initializer(state, value_type));
13177                         value_size = size_of(state, value_type);
13178                         if (((type->type & TYPE_MASK) == TYPE_ARRAY) &&
13179                                 (type->elements == ELEMENT_COUNT_UNSPECIFIED) &&
13180                                 (max_offset <= info.offset)) {
13181                                 void *old_buf;
13182                                 size_t old_size;
13183                                 old_buf = buf;
13184                                 old_size = max_offset;
13185                                 max_offset = info.offset + value_size;
13186                                 buf = xmalloc(bits_to_bytes(max_offset), "initializer");
13187                                 memcpy(buf, old_buf, bits_to_bytes(old_size));
13188                                 xfree(old_buf);
13189                         }
13190                         dest = ((char *)buf) + bits_to_bytes(info.offset);
13191 #if DEBUG_INITIALIZER
13192                         fprintf(state->errout, "dest = buf + %d max_offset: %d value_size: %d op: %d\n", 
13193                                 dest - buf,
13194                                 bits_to_bytes(max_offset),
13195                                 bits_to_bytes(value_size),
13196                                 value->op);
13197 #endif
13198                         if (value->op == OP_BLOBCONST) {
13199                                 memcpy(dest, value->u.blob, bits_to_bytes(value_size));
13200                         }
13201                         else if ((value->op == OP_INTCONST) && (value_size == SIZEOF_I8)) {
13202 #if DEBUG_INITIALIZER
13203                                 fprintf(state->errout, "byte: %02x\n", value->u.cval & 0xff);
13204 #endif
13205                                 *((uint8_t *)dest) = value->u.cval & 0xff;
13206                         }
13207                         else if ((value->op == OP_INTCONST) && (value_size == SIZEOF_I16)) {
13208                                 *((uint16_t *)dest) = value->u.cval & 0xffff;
13209                         }
13210                         else if ((value->op == OP_INTCONST) && (value_size == SIZEOF_I32)) {
13211                                 *((uint32_t *)dest) = value->u.cval & 0xffffffff;
13212                         }
13213                         else {
13214                                 internal_error(state, 0, "unhandled constant initializer");
13215                         }
13216                         free_triple(state, value);
13217                         if (peek(state) == TOK_COMMA) {
13218                                 eat(state, TOK_COMMA);
13219                                 comma = 1;
13220                         }
13221                         info.offset += value_size;
13222                         if ((type->type & TYPE_MASK) == TYPE_STRUCT) {
13223                                 info.type = next_field(state, type, info.type);
13224                                 info.offset = field_offset(state, type, 
13225                                         info.type->field_ident);
13226                         }
13227                 } while(comma && (peek(state) != TOK_RBRACE));
13228                 if ((type->elements == ELEMENT_COUNT_UNSPECIFIED) &&
13229                         ((type->type & TYPE_MASK) == TYPE_ARRAY)) {
13230                         type->elements = max_offset / size_of(state, type->left);
13231                 }
13232                 eat(state, TOK_RBRACE);
13233                 result = triple(state, OP_BLOBCONST, type, 0, 0);
13234                 result->u.blob = buf;
13235         }
13236         return result;
13237 }
13238
13239 static void resolve_branches(struct compile_state *state, struct triple *first)
13240 {
13241         /* Make a second pass and finish anything outstanding
13242          * with respect to branches.  The only outstanding item
13243          * is to see if there are goto to labels that have not
13244          * been defined and to error about them.
13245          */
13246         int i;
13247         struct triple *ins;
13248         /* Also error on branches that do not use their targets */
13249         ins = first;
13250         do {
13251                 if (!triple_is_ret(state, ins)) {
13252                         struct triple **expr ;
13253                         struct triple_set *set;
13254                         expr = triple_targ(state, ins, 0);
13255                         for(; expr; expr = triple_targ(state, ins, expr)) {
13256                                 struct triple *targ;
13257                                 targ = *expr;
13258                                 for(set = targ?targ->use:0; set; set = set->next) {
13259                                         if (set->member == ins) {
13260                                                 break;
13261                                         }
13262                                 }
13263                                 if (!set) {
13264                                         internal_error(state, ins, "targ not used");
13265                                 }
13266                         }
13267                 }
13268                 ins = ins->next;
13269         } while(ins != first);
13270         /* See if there are goto to labels that have not been defined */
13271         for(i = 0; i < HASH_TABLE_SIZE; i++) {
13272                 struct hash_entry *entry;
13273                 for(entry = state->hash_table[i]; entry; entry = entry->next) {
13274                         struct triple *ins;
13275                         if (!entry->sym_label) {
13276                                 continue;
13277                         }
13278                         ins = entry->sym_label->def;
13279                         if (!(ins->id & TRIPLE_FLAG_FLATTENED)) {
13280                                 error(state, ins, "label `%s' used but not defined",
13281                                         entry->name);
13282                         }
13283                 }
13284         }
13285 }
13286
13287 static struct triple *function_definition(
13288         struct compile_state *state, struct type *type)
13289 {
13290         struct triple *def, *tmp, *first, *end, *retvar, *result, *ret;
13291         struct triple *fname;
13292         struct type *fname_type;
13293         struct hash_entry *ident;
13294         struct type *param, *crtype, *ctype;
13295         int i;
13296         if ((type->type &TYPE_MASK) != TYPE_FUNCTION) {
13297                 error(state, 0, "Invalid function header");
13298         }
13299
13300         /* Verify the function type */
13301         if (((type->right->type & TYPE_MASK) != TYPE_VOID)  &&
13302                 ((type->right->type & TYPE_MASK) != TYPE_PRODUCT) &&
13303                 (type->right->field_ident == 0)) {
13304                 error(state, 0, "Invalid function parameters");
13305         }
13306         param = type->right;
13307         i = 0;
13308         while((param->type & TYPE_MASK) == TYPE_PRODUCT) {
13309                 i++;
13310                 if (!param->left->field_ident) {
13311                         error(state, 0, "No identifier for parameter %d\n", i);
13312                 }
13313                 param = param->right;
13314         }
13315         i++;
13316         if (((param->type & TYPE_MASK) != TYPE_VOID) && !param->field_ident) {
13317                 error(state, 0, "No identifier for paramter %d\n", i);
13318         }
13319         
13320         /* Get a list of statements for this function. */
13321         def = triple(state, OP_LIST, type, 0, 0);
13322
13323         /* Start a new scope for the passed parameters */
13324         start_scope(state);
13325
13326         /* Put a label at the very start of a function */
13327         first = label(state);
13328         RHS(def, 0) = first;
13329
13330         /* Put a label at the very end of a function */
13331         end = label(state);
13332         flatten(state, first, end);
13333         /* Remember where return goes */
13334         ident = state->i_return;
13335         symbol(state, ident, &ident->sym_ident, end, end->type);
13336
13337         /* Get the initial closure type */
13338         ctype = new_type(TYPE_JOIN, &void_type, 0);
13339         ctype->elements = 1;
13340
13341         /* Add a variable for the return value */
13342         crtype = new_type(TYPE_TUPLE, 
13343                 /* Remove all type qualifiers from the return type */
13344                 new_type(TYPE_PRODUCT, ctype, clone_type(0, type->left)), 0);
13345         crtype->elements = 2;
13346         result = flatten(state, end, variable(state, crtype));
13347
13348         /* Allocate a variable for the return address */
13349         retvar = flatten(state, end, variable(state, &void_ptr_type));
13350
13351         /* Add in the return instruction */
13352         ret = triple(state, OP_RET, &void_type, read_expr(state, retvar), 0);
13353         ret = flatten(state, first, ret);
13354
13355         /* Walk through the parameters and create symbol table entries
13356          * for them.
13357          */
13358         param = type->right;
13359         while((param->type & TYPE_MASK) == TYPE_PRODUCT) {
13360                 ident = param->left->field_ident;
13361                 tmp = variable(state, param->left);
13362                 var_symbol(state, ident, tmp);
13363                 flatten(state, end, tmp);
13364                 param = param->right;
13365         }
13366         if ((param->type & TYPE_MASK) != TYPE_VOID) {
13367                 /* And don't forget the last parameter */
13368                 ident = param->field_ident;
13369                 tmp = variable(state, param);
13370                 symbol(state, ident, &ident->sym_ident, tmp, tmp->type);
13371                 flatten(state, end, tmp);
13372         }
13373
13374         /* Add the declaration static const char __func__ [] = "func-name"  */
13375         fname_type = new_type(TYPE_ARRAY, 
13376                 clone_type(QUAL_CONST | STOR_STATIC, &char_type), 0);
13377         fname_type->type |= QUAL_CONST | STOR_STATIC;
13378         fname_type->elements = strlen(state->function) + 1;
13379
13380         fname = triple(state, OP_BLOBCONST, fname_type, 0, 0);
13381         fname->u.blob = (void *)state->function;
13382         fname = flatten(state, end, fname);
13383
13384         ident = state->i___func__;
13385         symbol(state, ident, &ident->sym_ident, fname, fname_type);
13386
13387         /* Remember which function I am compiling.
13388          * Also assume the last defined function is the main function.
13389          */
13390         state->main_function = def;
13391
13392         /* Now get the actual function definition */
13393         compound_statement(state, end);
13394
13395         /* Finish anything unfinished with branches */
13396         resolve_branches(state, first);
13397
13398         /* Remove the parameter scope */
13399         end_scope(state);
13400
13401
13402         /* Remember I have defined a function */
13403         if (!state->functions) {
13404                 state->functions = def;
13405         } else {
13406                 insert_triple(state, state->functions, def);
13407         }
13408         if (state->compiler->debug & DEBUG_INLINE) {
13409                 FILE *fp = state->dbgout;
13410                 fprintf(fp, "\n");
13411                 loc(fp, state, 0);
13412                 fprintf(fp, "\n__________ %s _________\n", __FUNCTION__);
13413                 display_func(state, fp, def);
13414                 fprintf(fp, "__________ %s _________ done\n\n", __FUNCTION__);
13415         }
13416
13417         return def;
13418 }
13419
13420 static struct triple *do_decl(struct compile_state *state, 
13421         struct type *type, struct hash_entry *ident)
13422 {
13423         struct triple *def;
13424         def = 0;
13425         /* Clean up the storage types used */
13426         switch (type->type & STOR_MASK) {
13427         case STOR_AUTO:
13428         case STOR_STATIC:
13429                 /* These are the good types I am aiming for */
13430                 break;
13431         case STOR_REGISTER:
13432                 type->type &= ~STOR_MASK;
13433                 type->type |= STOR_AUTO;
13434                 break;
13435         case STOR_LOCAL:
13436         case STOR_EXTERN:
13437                 type->type &= ~STOR_MASK;
13438                 type->type |= STOR_STATIC;
13439                 break;
13440         case STOR_TYPEDEF:
13441                 if (!ident) {
13442                         error(state, 0, "typedef without name");
13443                 }
13444                 symbol(state, ident, &ident->sym_ident, 0, type);
13445                 ident->tok = TOK_TYPE_NAME;
13446                 return 0;
13447                 break;
13448         default:
13449                 internal_error(state, 0, "Undefined storage class");
13450         }
13451         if ((type->type & TYPE_MASK) == TYPE_FUNCTION) {
13452                 error(state, 0, "Function prototypes not supported");
13453         }
13454         if (ident && 
13455                 ((type->type & STOR_MASK) == STOR_STATIC) &&
13456                 ((type->type & QUAL_CONST) == 0)) {
13457                 error(state, 0, "non const static variables not supported");
13458         }
13459         if (ident) {
13460                 def = variable(state, type);
13461                 var_symbol(state, ident, def);
13462         }
13463         return def;
13464 }
13465
13466 static void decl(struct compile_state *state, struct triple *first)
13467 {
13468         struct type *base_type, *type;
13469         struct hash_entry *ident;
13470         struct triple *def;
13471         int global;
13472         global = (state->scope_depth <= GLOBAL_SCOPE_DEPTH);
13473         base_type = decl_specifiers(state);
13474         ident = 0;
13475         type = declarator(state, base_type, &ident, 0);
13476         type->type = attributes_opt(state, type->type);
13477         if (global && ident && (peek(state) == TOK_LBRACE)) {
13478                 /* function */
13479                 type->type_ident = ident;
13480                 state->function = ident->name;
13481                 def = function_definition(state, type);
13482                 symbol(state, ident, &ident->sym_ident, def, type);
13483                 state->function = 0;
13484         }
13485         else {
13486                 int done;
13487                 flatten(state, first, do_decl(state, type, ident));
13488                 /* type or variable definition */
13489                 do {
13490                         done = 1;
13491                         if (peek(state) == TOK_EQ) {
13492                                 if (!ident) {
13493                                         error(state, 0, "cannot assign to a type");
13494                                 }
13495                                 eat(state, TOK_EQ);
13496                                 flatten(state, first,
13497                                         init_expr(state, 
13498                                                 ident->sym_ident->def, 
13499                                                 initializer(state, type)));
13500                         }
13501                         arrays_complete(state, type);
13502                         if (peek(state) == TOK_COMMA) {
13503                                 eat(state, TOK_COMMA);
13504                                 ident = 0;
13505                                 type = declarator(state, base_type, &ident, 0);
13506                                 flatten(state, first, do_decl(state, type, ident));
13507                                 done = 0;
13508                         }
13509                 } while(!done);
13510                 eat(state, TOK_SEMI);
13511         }
13512 }
13513
13514 static void decls(struct compile_state *state)
13515 {
13516         struct triple *list;
13517         int tok;
13518         list = label(state);
13519         while(1) {
13520                 tok = peek(state);
13521                 if (tok == TOK_EOF) {
13522                         return;
13523                 }
13524                 if (tok == TOK_SPACE) {
13525                         eat(state, TOK_SPACE);
13526                 }
13527                 decl(state, list);
13528                 if (list->next != list) {
13529                         error(state, 0, "global variables not supported");
13530                 }
13531         }
13532 }
13533
13534 /* 
13535  * Function inlining
13536  */
13537 struct triple_reg_set {
13538         struct triple_reg_set *next;
13539         struct triple *member;
13540         struct triple *new;
13541 };
13542 struct reg_block {
13543         struct block *block;
13544         struct triple_reg_set *in;
13545         struct triple_reg_set *out;
13546         int vertex;
13547 };
13548 static void setup_basic_blocks(struct compile_state *, struct basic_blocks *bb);
13549 static void analyze_basic_blocks(struct compile_state *state, struct basic_blocks *bb);
13550 static void free_basic_blocks(struct compile_state *, struct basic_blocks *bb);
13551 static int tdominates(struct compile_state *state, struct triple *dom, struct triple *sub);
13552 static void walk_blocks(struct compile_state *state, struct basic_blocks *bb,
13553         void (*cb)(struct compile_state *state, struct block *block, void *arg),
13554         void *arg);
13555 static void print_block(
13556         struct compile_state *state, struct block *block, void *arg);
13557 static int do_triple_set(struct triple_reg_set **head, 
13558         struct triple *member, struct triple *new_member);
13559 static void do_triple_unset(struct triple_reg_set **head, struct triple *member);
13560 static struct reg_block *compute_variable_lifetimes(
13561         struct compile_state *state, struct basic_blocks *bb);
13562 static void free_variable_lifetimes(struct compile_state *state, 
13563         struct basic_blocks *bb, struct reg_block *blocks);
13564 #if DEBUG_EXPLICIT_CLOSURES
13565 static void print_live_variables(struct compile_state *state, 
13566         struct basic_blocks *bb, struct reg_block *rb, FILE *fp);
13567 #endif
13568
13569
13570 static struct triple *call(struct compile_state *state,
13571         struct triple *retvar, struct triple *ret_addr, 
13572         struct triple *targ, struct triple *ret)
13573 {
13574         struct triple *call;
13575
13576         if (!retvar || !is_lvalue(state, retvar)) {
13577                 internal_error(state, 0, "writing to a non lvalue?");
13578         }
13579         write_compatible(state, retvar->type, &void_ptr_type);
13580
13581         call = new_triple(state, OP_CALL, &void_type, 1, 0);
13582         TARG(call, 0) = targ;
13583         MISC(call, 0) = ret;
13584         if (!targ || (targ->op != OP_LABEL)) {
13585                 internal_error(state, 0, "call not to a label");
13586         }
13587         if (!ret || (ret->op != OP_RET)) {
13588                 internal_error(state, 0, "call not matched with return");
13589         }
13590         return call;
13591 }
13592
13593 static void walk_functions(struct compile_state *state,
13594         void (*cb)(struct compile_state *state, struct triple *func, void *arg),
13595         void *arg)
13596 {
13597         struct triple *func, *first;
13598         func = first = state->functions;
13599         do {
13600                 cb(state, func, arg);
13601                 func = func->next;
13602         } while(func != first);
13603 }
13604
13605 static void reverse_walk_functions(struct compile_state *state,
13606         void (*cb)(struct compile_state *state, struct triple *func, void *arg),
13607         void *arg)
13608 {
13609         struct triple *func, *first;
13610         func = first = state->functions;
13611         do {
13612                 func = func->prev;
13613                 cb(state, func, arg);
13614         } while(func != first);
13615 }
13616
13617
13618 static void mark_live(struct compile_state *state, struct triple *func, void *arg)
13619 {
13620         struct triple *ptr, *first;
13621         if (func->u.cval == 0) {
13622                 return;
13623         }
13624         ptr = first = RHS(func, 0);
13625         do {
13626                 if (ptr->op == OP_FCALL) {
13627                         struct triple *called_func;
13628                         called_func = MISC(ptr, 0);
13629                         /* Mark the called function as used */
13630                         if (!(func->id & TRIPLE_FLAG_FLATTENED)) {
13631                                 called_func->u.cval++;
13632                         }
13633                         /* Remove the called function from the list */
13634                         called_func->prev->next = called_func->next;
13635                         called_func->next->prev = called_func->prev;
13636
13637                         /* Place the called function before me on the list */
13638                         called_func->next       = func;
13639                         called_func->prev       = func->prev;
13640                         called_func->prev->next = called_func;
13641                         called_func->next->prev = called_func;
13642                 }
13643                 ptr = ptr->next;
13644         } while(ptr != first);
13645         func->id |= TRIPLE_FLAG_FLATTENED;
13646 }
13647
13648 static void mark_live_functions(struct compile_state *state)
13649 {
13650         /* Ensure state->main_function is the last function in 
13651          * the list of functions.
13652          */
13653         if ((state->main_function->next != state->functions) ||
13654                 (state->functions->prev != state->main_function)) {
13655                 internal_error(state, 0, 
13656                         "state->main_function is not at the end of the function list ");
13657         }
13658         state->main_function->u.cval = 1;
13659         reverse_walk_functions(state, mark_live, 0);
13660 }
13661
13662 static int local_triple(struct compile_state *state, 
13663         struct triple *func, struct triple *ins)
13664 {
13665         int local = (ins->id & TRIPLE_FLAG_LOCAL);
13666 #if 0
13667         if (!local) {
13668                 FILE *fp = state->errout;
13669                 fprintf(fp, "global: ");
13670                 display_triple(fp, ins);
13671         }
13672 #endif
13673         return local;
13674 }
13675
13676 struct triple *copy_func(struct compile_state *state, struct triple *ofunc, 
13677         struct occurance *base_occurance)
13678 {
13679         struct triple *nfunc;
13680         struct triple *nfirst, *ofirst;
13681         struct triple *new, *old;
13682
13683         if (state->compiler->debug & DEBUG_INLINE) {
13684                 FILE *fp = state->dbgout;
13685                 fprintf(fp, "\n");
13686                 loc(fp, state, 0);
13687                 fprintf(fp, "\n__________ %s _________\n", __FUNCTION__);
13688                 display_func(state, fp, ofunc);
13689                 fprintf(fp, "__________ %s _________ done\n\n", __FUNCTION__);
13690         }
13691
13692         /* Make a new copy of the old function */
13693         nfunc = triple(state, OP_LIST, ofunc->type, 0, 0);
13694         nfirst = 0;
13695         ofirst = old = RHS(ofunc, 0);
13696         do {
13697                 struct triple *new;
13698                 struct occurance *occurance;
13699                 int old_lhs, old_rhs;
13700                 old_lhs = old->lhs;
13701                 old_rhs = old->rhs;
13702                 occurance = inline_occurance(state, base_occurance, old->occurance);
13703                 if (ofunc->u.cval && (old->op == OP_FCALL)) {
13704                         MISC(old, 0)->u.cval += 1;
13705                 }
13706                 new = alloc_triple(state, old->op, old->type, old_lhs, old_rhs,
13707                         occurance);
13708                 if (!triple_stores_block(state, new)) {
13709                         memcpy(&new->u, &old->u, sizeof(new->u));
13710                 }
13711                 if (!nfirst) {
13712                         RHS(nfunc, 0) = nfirst = new;
13713                 }
13714                 else {
13715                         insert_triple(state, nfirst, new);
13716                 }
13717                 new->id |= TRIPLE_FLAG_FLATTENED;
13718                 new->id |= old->id & TRIPLE_FLAG_COPY;
13719                 
13720                 /* During the copy remember new as user of old */
13721                 use_triple(old, new);
13722
13723                 /* Remember which instructions are local */
13724                 old->id |= TRIPLE_FLAG_LOCAL;
13725                 old = old->next;
13726         } while(old != ofirst);
13727
13728         /* Make a second pass to fix up any unresolved references */
13729         old = ofirst;
13730         new = nfirst;
13731         do {
13732                 struct triple **oexpr, **nexpr;
13733                 int count, i;
13734                 /* Lookup where the copy is, to join pointers */
13735                 count = TRIPLE_SIZE(old);
13736                 for(i = 0; i < count; i++) {
13737                         oexpr = &old->param[i];
13738                         nexpr = &new->param[i];
13739                         if (*oexpr && !*nexpr) {
13740                                 if (!local_triple(state, ofunc, *oexpr)) {
13741                                         *nexpr = *oexpr;
13742                                 }
13743                                 else if ((*oexpr)->use) {
13744                                         *nexpr = (*oexpr)->use->member;
13745                                 }
13746                                 if (*nexpr == old) {
13747                                         internal_error(state, 0, "new == old?");
13748                                 }
13749                                 use_triple(*nexpr, new);
13750                         }
13751                         if (!*nexpr && *oexpr) {
13752                                 internal_error(state, 0, "Could not copy %d", i);
13753                         }
13754                 }
13755                 old = old->next;
13756                 new = new->next;
13757         } while((old != ofirst) && (new != nfirst));
13758         
13759         /* Make a third pass to cleanup the extra useses */
13760         old = ofirst;
13761         new = nfirst;
13762         do {
13763                 unuse_triple(old, new);
13764                 /* Forget which instructions are local */
13765                 old->id &= ~TRIPLE_FLAG_LOCAL;
13766                 old = old->next;
13767                 new = new->next;
13768         } while ((old != ofirst) && (new != nfirst));
13769         return nfunc;
13770 }
13771
13772 static void expand_inline_call(
13773         struct compile_state *state, struct triple *me, struct triple *fcall)
13774 {
13775         /* Inline the function call */
13776         struct type *ptype;
13777         struct triple *ofunc, *nfunc, *nfirst, *result, *retvar, *ins;
13778         struct triple *end, *nend;
13779         int pvals, i;
13780
13781         /* Find the triples */
13782         ofunc = MISC(fcall, 0);
13783         if (ofunc->op != OP_LIST) {
13784                 internal_error(state, 0, "improper function");
13785         }
13786         nfunc = copy_func(state, ofunc, fcall->occurance);
13787         /* Prepend the parameter reading into the new function list */
13788         ptype = nfunc->type->right;
13789         pvals = fcall->rhs;
13790         for(i = 0; i < pvals; i++) {
13791                 struct type *atype;
13792                 struct triple *arg, *param;
13793                 atype = ptype;
13794                 if ((ptype->type & TYPE_MASK) == TYPE_PRODUCT) {
13795                         atype = ptype->left;
13796                 }
13797                 param = farg(state, nfunc, i);
13798                 if ((param->type->type & TYPE_MASK) != (atype->type & TYPE_MASK)) {
13799                         internal_error(state, fcall, "param %d type mismatch", i);
13800                 }
13801                 arg = RHS(fcall, i);
13802                 flatten(state, fcall, write_expr(state, param, arg));
13803                 ptype = ptype->right;
13804         }
13805         result = 0;
13806         if ((nfunc->type->left->type & TYPE_MASK) != TYPE_VOID) {
13807                 result = read_expr(state, 
13808                         deref_index(state, fresult(state, nfunc), 1));
13809         }
13810         if (state->compiler->debug & DEBUG_INLINE) {
13811                 FILE *fp = state->dbgout;
13812                 fprintf(fp, "\n");
13813                 loc(fp, state, 0);
13814                 fprintf(fp, "\n__________ %s _________\n", __FUNCTION__);
13815                 display_func(state, fp, nfunc);
13816                 fprintf(fp, "__________ %s _________ done\n\n", __FUNCTION__);
13817         }
13818
13819         /* 
13820          * Get rid of the extra triples 
13821          */
13822         /* Remove the read of the return address */
13823         ins = RHS(nfunc, 0)->prev->prev;
13824         if ((ins->op != OP_READ) || (RHS(ins, 0) != fretaddr(state, nfunc))) {
13825                 internal_error(state, ins, "Not return addres read?");
13826         }
13827         release_triple(state, ins);
13828         /* Remove the return instruction */
13829         ins = RHS(nfunc, 0)->prev;
13830         if (ins->op != OP_RET) {
13831                 internal_error(state, ins, "Not return?");
13832         }
13833         release_triple(state, ins);
13834         /* Remove the retaddres variable */
13835         retvar = fretaddr(state, nfunc);
13836         if ((retvar->lhs != 1) || 
13837                 (retvar->op != OP_ADECL) ||
13838                 (retvar->next->op != OP_PIECE) ||
13839                 (MISC(retvar->next, 0) != retvar)) {
13840                 internal_error(state, retvar, "Not the return address?");
13841         }
13842         release_triple(state, retvar->next);
13843         release_triple(state, retvar);
13844
13845         /* Remove the label at the start of the function */
13846         ins = RHS(nfunc, 0);
13847         if (ins->op != OP_LABEL) {
13848                 internal_error(state, ins, "Not label?");
13849         }
13850         nfirst = ins->next;
13851         free_triple(state, ins);
13852         /* Release the new function header */
13853         RHS(nfunc, 0) = 0;
13854         free_triple(state, nfunc);
13855
13856         /* Append the new function list onto the return list */
13857         end = fcall->prev;
13858         nend = nfirst->prev;
13859         end->next    = nfirst;
13860         nfirst->prev = end;
13861         nend->next   = fcall;
13862         fcall->prev  = nend;
13863
13864         /* Now the result reading code */
13865         if (result) {
13866                 result = flatten(state, fcall, result);
13867                 propogate_use(state, fcall, result);
13868         }
13869
13870         /* Release the original fcall instruction */
13871         release_triple(state, fcall);
13872
13873         return;
13874 }
13875
13876 /*
13877  *
13878  * Type of the result variable.
13879  * 
13880  *                                     result
13881  *                                        |
13882  *                             +----------+------------+
13883  *                             |                       |
13884  *                     union of closures         result_type
13885  *                             |
13886  *          +------------------+---------------+
13887  *          |                                  |
13888  *       closure1                    ...   closuerN
13889  *          |                                  | 
13890  *  +----+--+-+--------+-----+       +----+----+---+-----+
13891  *  |    |    |        |     |       |    |        |     |
13892  * var1 var2 var3 ... varN result   var1 var2 ... varN result
13893  *                           |
13894  *                  +--------+---------+
13895  *                  |                  |
13896  *          union of closures     result_type
13897  *                  |
13898  *            +-----+-------------------+
13899  *            |                         |
13900  *         closure1            ...  closureN
13901  *            |                         |
13902  *  +-----+---+----+----+      +----+---+----+-----+
13903  *  |     |        |    |      |    |        |     |
13904  * var1 var2 ... varN result  var1 var2 ... varN result
13905  */
13906
13907 static int add_closure_type(struct compile_state *state, 
13908         struct triple *func, struct type *closure_type)
13909 {
13910         struct type *type, *ctype, **next;
13911         struct triple *var, *new_var;
13912         int i;
13913
13914 #if 0
13915         FILE *fp = state->errout;
13916         fprintf(fp, "original_type: ");
13917         name_of(fp, fresult(state, func)->type);
13918         fprintf(fp, "\n");
13919 #endif
13920         /* find the original type */
13921         var = fresult(state, func);
13922         type = var->type;
13923         if (type->elements != 2) {
13924                 internal_error(state, var, "bad return type");
13925         }
13926
13927         /* Find the complete closure type and update it */
13928         ctype = type->left->left;
13929         next = &ctype->left;
13930         while(((*next)->type & TYPE_MASK) == TYPE_OVERLAP) {
13931                 next = &(*next)->right;
13932         }
13933         *next = new_type(TYPE_OVERLAP, *next, dup_type(state, closure_type));
13934         ctype->elements += 1;
13935
13936 #if 0
13937         fprintf(fp, "new_type: ");
13938         name_of(fp, type);
13939         fprintf(fp, "\n");
13940         fprintf(fp, "ctype: %p %d bits: %d ", 
13941                 ctype, ctype->elements, reg_size_of(state, ctype));
13942         name_of(fp, ctype);
13943         fprintf(fp, "\n");
13944 #endif
13945         
13946         /* Regenerate the variable with the new type definition */
13947         new_var = pre_triple(state, var, OP_ADECL, type, 0, 0);
13948         new_var->id |= TRIPLE_FLAG_FLATTENED;
13949         for(i = 0; i < new_var->lhs; i++) {
13950                 LHS(new_var, i)->id |= TRIPLE_FLAG_FLATTENED;
13951         }
13952         
13953         /* Point everyone at the new variable */
13954         propogate_use(state, var, new_var);
13955
13956         /* Release the original variable */
13957         for(i = 0; i < var->lhs; i++) {
13958                 release_triple(state, LHS(var, i));
13959         }
13960         release_triple(state, var);
13961         
13962         /* Return the index of the added closure type */
13963         return ctype->elements - 1;
13964 }
13965
13966 static struct triple *closure_expr(struct compile_state *state,
13967         struct triple *func, int closure_idx, int var_idx)
13968 {
13969         return deref_index(state,
13970                 deref_index(state,
13971                         deref_index(state, fresult(state, func), 0),
13972                         closure_idx),
13973                 var_idx);
13974 }
13975
13976
13977 static void insert_triple_set(
13978         struct triple_reg_set **head, struct triple *member)
13979 {
13980         struct triple_reg_set *new;
13981         new = xcmalloc(sizeof(*new), "triple_set");
13982         new->member = member;
13983         new->new    = 0;
13984         new->next   = *head;
13985         *head       = new;
13986 }
13987
13988 static int ordered_triple_set(
13989         struct triple_reg_set **head, struct triple *member)
13990 {
13991         struct triple_reg_set **ptr;
13992         if (!member)
13993                 return 0;
13994         ptr = head;
13995         while(*ptr) {
13996                 if (member == (*ptr)->member) {
13997                         return 0;
13998                 }
13999                 /* keep the list ordered */
14000                 if (member->id < (*ptr)->member->id) {
14001                         break;
14002                 }
14003                 ptr = &(*ptr)->next;
14004         }
14005         insert_triple_set(ptr, member);
14006         return 1;
14007 }
14008
14009
14010 static void free_closure_variables(struct compile_state *state,
14011         struct triple_reg_set **enclose)
14012 {
14013         struct triple_reg_set *entry, *next;
14014         for(entry = *enclose; entry; entry = next) {
14015                 next = entry->next;
14016                 do_triple_unset(enclose, entry->member);
14017         }
14018 }
14019
14020 static int lookup_closure_index(struct compile_state *state,
14021         struct triple *me, struct triple *val)
14022 {
14023         struct triple *first, *ins, *next;
14024         first = RHS(me, 0);
14025         ins = next = first;
14026         do {
14027                 struct triple *result;
14028                 struct triple *index0, *index1, *index2, *read, *write;
14029                 ins = next;
14030                 next = ins->next;
14031                 if (ins->op != OP_CALL) {
14032                         continue;
14033                 }
14034                 /* I am at a previous call point examine it closely */
14035                 if (ins->next->op != OP_LABEL) {
14036                         internal_error(state, ins, "call not followed by label");
14037                 }
14038                 /* Does this call does not enclose any variables? */
14039                 if ((ins->next->next->op != OP_INDEX) ||
14040                         (ins->next->next->u.cval != 0) ||
14041                         (result = MISC(ins->next->next, 0)) ||
14042                         (result->id & TRIPLE_FLAG_LOCAL)) {
14043                         continue;
14044                 }
14045                 index0 = ins->next->next;
14046                 /* The pattern is:
14047                  * 0 index result < 0 >
14048                  * 1 index 0 < ? >
14049                  * 2 index 1 < ? >
14050                  * 3 read  2
14051                  * 4 write 3 var
14052                  */
14053                 for(index0 = ins->next->next;
14054                         (index0->op == OP_INDEX) &&
14055                                 (MISC(index0, 0) == result) &&
14056                                 (index0->u.cval == 0) ; 
14057                         index0 = write->next)
14058                 {
14059                         index1 = index0->next;
14060                         index2 = index1->next;
14061                         read   = index2->next;
14062                         write  = read->next;
14063                         if ((index0->op != OP_INDEX) ||
14064                                 (index1->op != OP_INDEX) ||
14065                                 (index2->op != OP_INDEX) ||
14066                                 (read->op != OP_READ) ||
14067                                 (write->op != OP_WRITE) ||
14068                                 (MISC(index1, 0) != index0) ||
14069                                 (MISC(index2, 0) != index1) ||
14070                                 (RHS(read, 0) != index2) ||
14071                                 (RHS(write, 0) != read)) {
14072                                 internal_error(state, index0, "bad var read");
14073                         }
14074                         if (MISC(write, 0) == val) {
14075                                 return index2->u.cval;
14076                         }
14077                 }
14078         } while(next != first);
14079         return -1;
14080 }
14081
14082 static inline int enclose_triple(struct triple *ins)
14083 {
14084         return (ins && ((ins->type->type & TYPE_MASK) != TYPE_VOID));
14085 }
14086
14087 static void compute_closure_variables(struct compile_state *state,
14088         struct triple *me, struct triple *fcall, struct triple_reg_set **enclose)
14089 {
14090         struct triple_reg_set *set, *vars, **last_var;
14091         struct basic_blocks bb;
14092         struct reg_block *rb;
14093         struct block *block;
14094         struct triple *old_result, *first, *ins;
14095         size_t count, idx;
14096         unsigned long used_indicies;
14097         int i, max_index;
14098 #define MAX_INDICIES (sizeof(used_indicies)*CHAR_BIT)
14099 #define ID_BITS(X) ((X) & (TRIPLE_FLAG_LOCAL -1))
14100         struct { 
14101                 unsigned id;
14102                 int index;
14103         } *info;
14104
14105         
14106         /* Find the basic blocks of this function */
14107         bb.func = me;
14108         bb.first = RHS(me, 0);
14109         old_result = 0;
14110         if (!triple_is_ret(state, bb.first->prev)) {
14111                 bb.func = 0;
14112         } else {
14113                 old_result = fresult(state, me);
14114         }
14115         analyze_basic_blocks(state, &bb);
14116
14117         /* Find which variables are currently alive in a given block */
14118         rb = compute_variable_lifetimes(state, &bb);
14119
14120         /* Find the variables that are currently alive */
14121         block = block_of_triple(state, fcall);
14122         if (!block || (block->vertex <= 0) || (block->vertex > bb.last_vertex)) {
14123                 internal_error(state, fcall, "No reg block? block: %p", block);
14124         }
14125
14126 #if DEBUG_EXPLICIT_CLOSURES
14127         print_live_variables(state, &bb, rb, state->dbgout);
14128         fflush(state->dbgout);
14129 #endif
14130
14131         /* Count the number of triples in the function */
14132         first = RHS(me, 0);
14133         ins = first;
14134         count = 0;
14135         do {
14136                 count++;
14137                 ins = ins->next;
14138         } while(ins != first);
14139
14140         /* Allocate some memory to temorary hold the id info */
14141         info = xcmalloc(sizeof(*info) * (count +1), "info");
14142
14143         /* Mark the local function */
14144         first = RHS(me, 0);
14145         ins = first;
14146         idx = 1;
14147         do {
14148                 info[idx].id = ins->id;
14149                 ins->id = TRIPLE_FLAG_LOCAL | idx;
14150                 idx++;
14151                 ins = ins->next;
14152         } while(ins != first);
14153
14154         /* 
14155          * Build the list of variables to enclose.
14156          *
14157          * A target it to put the same variable in the
14158          * same slot for ever call of a given function.
14159          * After coloring this removes all of the variable
14160          * manipulation code.
14161          *
14162          * The list of variables to enclose is built ordered
14163          * program order because except in corner cases this
14164          * gives me the stability of assignment I need.
14165          *
14166          * To gurantee that stability I lookup the variables
14167          * to see where they have been used before and
14168          * I build my final list with the assigned indicies.
14169          */
14170         vars = 0;
14171         if (enclose_triple(old_result)) {
14172                 ordered_triple_set(&vars, old_result);
14173         }
14174         for(set = rb[block->vertex].out; set; set = set->next) {
14175                 if (!enclose_triple(set->member)) {
14176                         continue;
14177                 }
14178                 if ((set->member == fcall) || (set->member == old_result)) {
14179                         continue;
14180                 }
14181                 if (!local_triple(state, me, set->member)) {
14182                         internal_error(state, set->member, "not local?");
14183                 }
14184                 ordered_triple_set(&vars, set->member);
14185         }
14186
14187         /* Lookup the current indicies of the live varialbe */
14188         used_indicies = 0;
14189         max_index = -1;
14190         for(set = vars; set ; set = set->next) {
14191                 struct triple *ins;
14192                 int index;
14193                 ins = set->member;
14194                 index  = lookup_closure_index(state, me, ins);
14195                 info[ID_BITS(ins->id)].index = index;
14196                 if (index < 0) {
14197                         continue;
14198                 }
14199                 if (index >= MAX_INDICIES) {
14200                         internal_error(state, ins, "index unexpectedly large");
14201                 }
14202                 if (used_indicies & (1 << index)) {
14203                         internal_error(state, ins, "index previously used?");
14204                 }
14205                 /* Remember which indicies have been used */
14206                 used_indicies |= (1 << index);
14207                 if (index > max_index) {
14208                         max_index = index;
14209                 }
14210         }
14211
14212         /* Walk through the live variables and make certain
14213          * everything is assigned an index.
14214          */
14215         for(set = vars; set; set = set->next) {
14216                 struct triple *ins;
14217                 int index;
14218                 ins = set->member;
14219                 index = info[ID_BITS(ins->id)].index;
14220                 if (index >= 0) {
14221                         continue;
14222                 }
14223                 /* Find the lowest unused index value */
14224                 for(index = 0; index < MAX_INDICIES; index++) {
14225                         if (!(used_indicies & (1 << index))) {
14226                                 break;
14227                         }
14228                 }
14229                 if (index == MAX_INDICIES) {
14230                         internal_error(state, ins, "no free indicies?");
14231                 }
14232                 info[ID_BITS(ins->id)].index = index;
14233                 /* Remember which indicies have been used */
14234                 used_indicies |= (1 << index);
14235                 if (index > max_index) {
14236                         max_index = index;
14237                 }
14238         }
14239
14240         /* Build the return list of variables with positions matching
14241          * their indicies.
14242          */
14243         *enclose = 0;
14244         last_var = enclose;
14245         for(i = 0; i <= max_index; i++) {
14246                 struct triple *var;
14247                 var = 0;
14248                 if (used_indicies & (1 << i)) {
14249                         for(set = vars; set; set = set->next) {
14250                                 int index;
14251                                 index = info[ID_BITS(set->member->id)].index;
14252                                 if (index == i) {
14253                                         var = set->member;
14254                                         break;
14255                                 }
14256                         }
14257                         if (!var) {
14258                                 internal_error(state, me, "missing variable");
14259                         }
14260                 }
14261                 insert_triple_set(last_var, var);
14262                 last_var = &(*last_var)->next;
14263         }
14264
14265 #if DEBUG_EXPLICIT_CLOSURES
14266         /* Print out the variables to be enclosed */
14267         loc(state->dbgout, state, fcall);
14268         fprintf(state->dbgout, "Alive: \n");
14269         for(set = *enclose; set; set = set->next) {
14270                 display_triple(state->dbgout, set->member);
14271         }
14272         fflush(state->dbgout);
14273 #endif
14274
14275         /* Clear the marks */
14276         ins = first;
14277         do {
14278                 ins->id = info[ID_BITS(ins->id)].id;
14279                 ins = ins->next;
14280         } while(ins != first);
14281
14282         /* Release the ordered list of live variables */
14283         free_closure_variables(state, &vars);
14284
14285         /* Release the storage of the old ids */
14286         xfree(info);
14287
14288         /* Release the variable lifetime information */
14289         free_variable_lifetimes(state, &bb, rb);
14290
14291         /* Release the basic blocks of this function */
14292         free_basic_blocks(state, &bb);
14293 }
14294
14295 static void expand_function_call(
14296         struct compile_state *state, struct triple *me, struct triple *fcall)
14297 {
14298         /* Generate an ordinary function call */
14299         struct type *closure_type, **closure_next;
14300         struct triple *func, *func_first, *func_last, *retvar;
14301         struct triple *first;
14302         struct type *ptype, *rtype;
14303         struct triple *jmp;
14304         struct triple *ret_addr, *ret_loc, *ret_set;
14305         struct triple_reg_set *enclose, *set;
14306         int closure_idx, pvals, i;
14307
14308 #if DEBUG_EXPLICIT_CLOSURES
14309         FILE *fp = state->dbgout;
14310         fprintf(fp, "\ndisplay_func(me) ptr: %p\n", fcall);
14311         display_func(state, fp, MISC(fcall, 0));
14312         display_func(state, fp, me);
14313         fprintf(fp, "__________ %s _________ done\n\n", __FUNCTION__);
14314 #endif
14315
14316         /* Find the triples */
14317         func = MISC(fcall, 0);
14318         func_first = RHS(func, 0);
14319         retvar = fretaddr(state, func);
14320         func_last  = func_first->prev;
14321         first = fcall->next;
14322
14323         /* Find what I need to enclose */
14324         compute_closure_variables(state, me, fcall, &enclose);
14325
14326         /* Compute the closure type */
14327         closure_type = new_type(TYPE_TUPLE, 0, 0);
14328         closure_type->elements = 0;
14329         closure_next = &closure_type->left;
14330         for(set = enclose; set ; set = set->next) {
14331                 struct type *type;
14332                 type = &void_type;
14333                 if (set->member) {
14334                         type = set->member->type;
14335                 }
14336                 if (!*closure_next) {
14337                         *closure_next = type;
14338                 } else {
14339                         *closure_next = new_type(TYPE_PRODUCT, *closure_next, 
14340                                 type);
14341                         closure_next = &(*closure_next)->right;
14342                 }
14343                 closure_type->elements += 1;
14344         }
14345         if (closure_type->elements == 0) {
14346                 closure_type->type = TYPE_VOID;
14347         }
14348
14349
14350 #if DEBUG_EXPLICIT_CLOSURES
14351         fprintf(state->dbgout, "closure type: ");
14352         name_of(state->dbgout, closure_type);
14353         fprintf(state->dbgout, "\n");
14354 #endif
14355
14356         /* Update the called functions closure variable */
14357         closure_idx = add_closure_type(state, func, closure_type);
14358
14359         /* Generate some needed triples */
14360         ret_loc = label(state);
14361         ret_addr = triple(state, OP_ADDRCONST, &void_ptr_type, ret_loc, 0);
14362
14363         /* Pass the parameters to the new function */
14364         ptype = func->type->right;
14365         pvals = fcall->rhs;
14366         for(i = 0; i < pvals; i++) {
14367                 struct type *atype;
14368                 struct triple *arg, *param;
14369                 atype = ptype;
14370                 if ((ptype->type & TYPE_MASK) == TYPE_PRODUCT) {
14371                         atype = ptype->left;
14372                 }
14373                 param = farg(state, func, i);
14374                 if ((param->type->type & TYPE_MASK) != (atype->type & TYPE_MASK)) {
14375                         internal_error(state, fcall, "param type mismatch");
14376                 }
14377                 arg = RHS(fcall, i);
14378                 flatten(state, first, write_expr(state, param, arg));
14379                 ptype = ptype->right;
14380         }
14381         rtype = func->type->left;
14382
14383         /* Thread the triples together */
14384         ret_loc       = flatten(state, first, ret_loc);
14385
14386         /* Save the active variables in the result variable */
14387         for(i = 0, set = enclose; set ; set = set->next, i++) {
14388                 if (!set->member) {
14389                         continue;
14390                 }
14391                 flatten(state, ret_loc,
14392                         write_expr(state,
14393                                 closure_expr(state, func, closure_idx, i),
14394                                 read_expr(state, set->member)));
14395         }
14396
14397         /* Initialize the return value */
14398         if ((rtype->type & TYPE_MASK) != TYPE_VOID) {
14399                 flatten(state, ret_loc, 
14400                         write_expr(state, 
14401                                 deref_index(state, fresult(state, func), 1),
14402                                 new_triple(state, OP_UNKNOWNVAL, rtype,  0, 0)));
14403         }
14404
14405         ret_addr      = flatten(state, ret_loc, ret_addr);
14406         ret_set       = flatten(state, ret_loc, write_expr(state, retvar, ret_addr));
14407         jmp           = flatten(state, ret_loc, 
14408                 call(state, retvar, ret_addr, func_first, func_last));
14409
14410         /* Find the result */
14411         if ((rtype->type & TYPE_MASK) != TYPE_VOID) {
14412                 struct triple * result;
14413                 result = flatten(state, first, 
14414                         read_expr(state, 
14415                                 deref_index(state, fresult(state, func), 1)));
14416
14417                 propogate_use(state, fcall, result);
14418         }
14419
14420         /* Release the original fcall instruction */
14421         release_triple(state, fcall);
14422
14423         /* Restore the active variables from the result variable */
14424         for(i = 0, set = enclose; set ; set = set->next, i++) {
14425                 struct triple_set *use, *next;
14426                 struct triple *new;
14427                 struct basic_blocks bb;
14428                 if (!set->member || (set->member == fcall)) {
14429                         continue;
14430                 }
14431                 /* Generate an expression for the value */
14432                 new = flatten(state, first,
14433                         read_expr(state, 
14434                                 closure_expr(state, func, closure_idx, i)));
14435
14436
14437                 /* If the original is an lvalue restore the preserved value */
14438                 if (is_lvalue(state, set->member)) {
14439                         flatten(state, first,
14440                                 write_expr(state, set->member, new));
14441                         continue;
14442                 }
14443                 /*
14444                  * If the original is a value update the dominated uses.
14445                  */
14446                 
14447                 /* Analyze the basic blocks so I can see who dominates whom */
14448                 bb.func = me;
14449                 bb.first = RHS(me, 0);
14450                 if (!triple_is_ret(state, bb.first->prev)) {
14451                         bb.func = 0;
14452                 }
14453                 analyze_basic_blocks(state, &bb);
14454                 
14455
14456 #if DEBUG_EXPLICIT_CLOSURES
14457                 fprintf(state->errout, "Updating domindated uses: %p -> %p\n",
14458                         set->member, new);
14459 #endif
14460                 /* If fcall dominates the use update the expression */
14461                 for(use = set->member->use; use; use = next) {
14462                         /* Replace use modifies the use chain and 
14463                          * removes use, so I must take a copy of the
14464                          * next entry early.
14465                          */
14466                         next = use->next;
14467                         if (!tdominates(state, fcall, use->member)) {
14468                                 continue;
14469                         }
14470                         replace_use(state, set->member, new, use->member);
14471                 }
14472
14473                 /* Release the basic blocks, the instructions will be
14474                  * different next time, and flatten/insert_triple does
14475                  * not update the block values so I can't cache the analysis.
14476                  */
14477                 free_basic_blocks(state, &bb);
14478         }
14479
14480         /* Release the closure variable list */
14481         free_closure_variables(state, &enclose);
14482
14483         if (state->compiler->debug & DEBUG_INLINE) {
14484                 FILE *fp = state->dbgout;
14485                 fprintf(fp, "\n");
14486                 loc(fp, state, 0);
14487                 fprintf(fp, "\n__________ %s _________\n", __FUNCTION__);
14488                 display_func(state, fp, func);
14489                 display_func(state, fp, me);
14490                 fprintf(fp, "__________ %s _________ done\n\n", __FUNCTION__);
14491         }
14492
14493         return;
14494 }
14495
14496 static int do_inline(struct compile_state *state, struct triple *func)
14497 {
14498         int do_inline;
14499         int policy;
14500
14501         policy = state->compiler->flags & COMPILER_INLINE_MASK;
14502         switch(policy) {
14503         case COMPILER_INLINE_ALWAYS:
14504                 do_inline = 1;
14505                 if (func->type->type & ATTRIB_NOINLINE) {
14506                         error(state, func, "noinline with always_inline compiler option");
14507                 }
14508                 break;
14509         case COMPILER_INLINE_NEVER:
14510                 do_inline = 0;
14511                 if (func->type->type & ATTRIB_ALWAYS_INLINE) {
14512                         error(state, func, "always_inline with noinline compiler option");
14513                 }
14514                 break;
14515         case COMPILER_INLINE_DEFAULTON:
14516                 switch(func->type->type & STOR_MASK) {
14517                 case STOR_STATIC | STOR_INLINE:
14518                 case STOR_LOCAL  | STOR_INLINE:
14519                 case STOR_EXTERN | STOR_INLINE:
14520                         do_inline = 1;
14521                         break;
14522                 default:
14523                         do_inline = 1;
14524                         break;
14525                 }
14526                 break;
14527         case COMPILER_INLINE_DEFAULTOFF:
14528                 switch(func->type->type & STOR_MASK) {
14529                 case STOR_STATIC | STOR_INLINE:
14530                 case STOR_LOCAL  | STOR_INLINE:
14531                 case STOR_EXTERN | STOR_INLINE:
14532                         do_inline = 1;
14533                         break;
14534                 default:
14535                         do_inline = 0;
14536                         break;
14537                 }
14538                 break;
14539         case COMPILER_INLINE_NOPENALTY:
14540                 switch(func->type->type & STOR_MASK) {
14541                 case STOR_STATIC | STOR_INLINE:
14542                 case STOR_LOCAL  | STOR_INLINE:
14543                 case STOR_EXTERN | STOR_INLINE:
14544                         do_inline = 1;
14545                         break;
14546                 default:
14547                         do_inline = (func->u.cval == 1);
14548                         break;
14549                 }
14550                 break;
14551         default:
14552                 do_inline = 0;
14553                 internal_error(state, 0, "Unimplemented inline policy");
14554                 break;
14555         }
14556         /* Force inlining */
14557         if (func->type->type & ATTRIB_NOINLINE) {
14558                 do_inline = 0;
14559         }
14560         if (func->type->type & ATTRIB_ALWAYS_INLINE) {
14561                 do_inline = 1;
14562         }
14563         return do_inline;
14564 }
14565
14566 static void inline_function(struct compile_state *state, struct triple *me, void *arg)
14567 {
14568         struct triple *first, *ptr, *next;
14569         /* If the function is not used don't bother */
14570         if (me->u.cval <= 0) {
14571                 return;
14572         }
14573         if (state->compiler->debug & DEBUG_CALLS2) {
14574                 FILE *fp = state->dbgout;
14575                 fprintf(fp, "in: %s\n",
14576                         me->type->type_ident->name);
14577         }
14578
14579         first = RHS(me, 0);
14580         ptr = next = first;
14581         do {
14582                 struct triple *func, *prev;
14583                 ptr = next;
14584                 prev = ptr->prev;
14585                 next = ptr->next;
14586                 if (ptr->op != OP_FCALL) {
14587                         continue;
14588                 }
14589                 func = MISC(ptr, 0);
14590                 /* See if the function should be inlined */
14591                 if (!do_inline(state, func)) {
14592                         /* Put a label after the fcall */
14593                         post_triple(state, ptr, OP_LABEL, &void_type, 0, 0);
14594                         continue;
14595                 }
14596                 if (state->compiler->debug & DEBUG_CALLS) {
14597                         FILE *fp = state->dbgout;
14598                         if (state->compiler->debug & DEBUG_CALLS2) {
14599                                 loc(fp, state, ptr);
14600                         }
14601                         fprintf(fp, "inlining %s\n",
14602                                 func->type->type_ident->name);
14603                         fflush(fp);
14604                 }
14605
14606                 /* Update the function use counts */
14607                 func->u.cval -= 1;
14608
14609                 /* Replace the fcall with the called function */
14610                 expand_inline_call(state, me, ptr);
14611
14612                 next = prev->next;
14613         } while (next != first);
14614
14615         ptr = next = first;
14616         do {
14617                 struct triple *prev, *func;
14618                 ptr = next;
14619                 prev = ptr->prev;
14620                 next = ptr->next;
14621                 if (ptr->op != OP_FCALL) {
14622                         continue;
14623                 }
14624                 func = MISC(ptr, 0);
14625                 if (state->compiler->debug & DEBUG_CALLS) {
14626                         FILE *fp = state->dbgout;
14627                         if (state->compiler->debug & DEBUG_CALLS2) {
14628                                 loc(fp, state, ptr);
14629                         }
14630                         fprintf(fp, "calling %s\n",
14631                                 func->type->type_ident->name);
14632                         fflush(fp);
14633                 }
14634                 /* Replace the fcall with the instruction sequence
14635                  * needed to make the call.
14636                  */
14637                 expand_function_call(state, me, ptr);
14638                 next = prev->next;
14639         } while(next != first);
14640 }
14641
14642 static void inline_functions(struct compile_state *state, struct triple *func)
14643 {
14644         inline_function(state, func, 0);
14645         reverse_walk_functions(state, inline_function, 0);
14646 }
14647
14648 static void insert_function(struct compile_state *state,
14649         struct triple *func, void *arg)
14650 {
14651         struct triple *first, *end, *ffirst, *fend;
14652
14653         if (state->compiler->debug & DEBUG_INLINE) {
14654                 FILE *fp = state->errout;
14655                 fprintf(fp, "%s func count: %d\n", 
14656                         func->type->type_ident->name, func->u.cval);
14657         }
14658         if (func->u.cval == 0) {
14659                 return;
14660         }
14661
14662         /* Find the end points of the lists */
14663         first  = arg;
14664         end    = first->prev;
14665         ffirst = RHS(func, 0);
14666         fend   = ffirst->prev;
14667
14668         /* splice the lists together */
14669         end->next    = ffirst;
14670         ffirst->prev = end;
14671         fend->next   = first;
14672         first->prev  = fend;
14673 }
14674
14675 struct triple *input_asm(struct compile_state *state)
14676 {
14677         struct asm_info *info;
14678         struct triple *def;
14679         int i, out;
14680         
14681         info = xcmalloc(sizeof(*info), "asm_info");
14682         info->str = "";
14683
14684         out = sizeof(arch_input_regs)/sizeof(arch_input_regs[0]);
14685         memcpy(&info->tmpl.lhs, arch_input_regs, sizeof(arch_input_regs));
14686
14687         def = new_triple(state, OP_ASM, &void_type, out, 0);
14688         def->u.ainfo = info;
14689         def->id |= TRIPLE_FLAG_VOLATILE;
14690         
14691         for(i = 0; i < out; i++) {
14692                 struct triple *piece;
14693                 piece = triple(state, OP_PIECE, &int_type, def, 0);
14694                 piece->u.cval = i;
14695                 LHS(def, i) = piece;
14696         }
14697
14698         return def;
14699 }
14700
14701 struct triple *output_asm(struct compile_state *state)
14702 {
14703         struct asm_info *info;
14704         struct triple *def;
14705         int in;
14706         
14707         info = xcmalloc(sizeof(*info), "asm_info");
14708         info->str = "";
14709
14710         in = sizeof(arch_output_regs)/sizeof(arch_output_regs[0]);
14711         memcpy(&info->tmpl.rhs, arch_output_regs, sizeof(arch_output_regs));
14712
14713         def = new_triple(state, OP_ASM, &void_type, 0, in);
14714         def->u.ainfo = info;
14715         def->id |= TRIPLE_FLAG_VOLATILE;
14716         
14717         return def;
14718 }
14719
14720 static void join_functions(struct compile_state *state)
14721 {
14722         struct triple *jmp, *start, *end, *call, *in, *out, *func;
14723         struct file_state file;
14724         struct type *pnext, *param;
14725         struct type *result_type, *args_type;
14726         int idx;
14727
14728         /* Be clear the functions have not been joined yet */
14729         state->functions_joined = 0;
14730
14731         /* Dummy file state to get debug handing right */
14732         memset(&file, 0, sizeof(file));
14733         file.basename = "";
14734         file.line = 0;
14735         file.report_line = 0;
14736         file.report_name = file.basename;
14737         file.prev = state->file;
14738         state->file = &file;
14739         state->function = "";
14740
14741         if (!state->main_function) {
14742                 error(state, 0, "No functions to compile\n");
14743         }
14744
14745         /* The type of arguments */
14746         args_type   = state->main_function->type->right;
14747         /* The return type without any specifiers */
14748         result_type = clone_type(0, state->main_function->type->left);
14749
14750
14751         /* Verify the external arguments */
14752         if (registers_of(state, args_type) > ARCH_INPUT_REGS) {
14753                 error(state, state->main_function, 
14754                         "Too many external input arguments");
14755         }
14756         if (registers_of(state, result_type) > ARCH_OUTPUT_REGS) {
14757                 error(state, state->main_function, 
14758                         "Too many external output arguments");
14759         }
14760
14761         /* Lay down the basic program structure */
14762         end           = label(state);
14763         start         = label(state);
14764         start         = flatten(state, state->first, start);
14765         end           = flatten(state, state->first, end);
14766         in            = input_asm(state);
14767         out           = output_asm(state);
14768         call          = new_triple(state, OP_FCALL, result_type, -1, registers_of(state, args_type));
14769         MISC(call, 0) = state->main_function;
14770         in            = flatten(state, state->first, in);
14771         call          = flatten(state, state->first, call);
14772         out           = flatten(state, state->first, out);
14773
14774
14775         /* Read the external input arguments */
14776         pnext = args_type;
14777         idx = 0;
14778         while(pnext && ((pnext->type & TYPE_MASK) != TYPE_VOID)) {
14779                 struct triple *expr;
14780                 param = pnext;
14781                 pnext = 0;
14782                 if ((param->type & TYPE_MASK) == TYPE_PRODUCT) {
14783                         pnext = param->right;
14784                         param = param->left;
14785                 }
14786                 if (registers_of(state, param) != 1) {
14787                         error(state, state->main_function, 
14788                                 "Arg: %d %s requires multiple registers", 
14789                                 idx + 1, param->field_ident->name);
14790                 }
14791                 expr = read_expr(state, LHS(in, idx));
14792                 RHS(call, idx) = expr;
14793                 expr = flatten(state, call, expr);
14794                 use_triple(expr, call);
14795
14796                 idx++;  
14797         }
14798
14799
14800         /* Write the external output arguments */
14801         pnext = result_type;
14802         if ((pnext->type & TYPE_MASK) == TYPE_STRUCT) {
14803                 pnext = result_type->left;
14804         }
14805         for(idx = 0; idx < out->rhs; idx++) {
14806                 struct triple *expr;
14807                 param = pnext;
14808                 pnext = 0;
14809                 if (param && ((param->type & TYPE_MASK) == TYPE_PRODUCT)) {
14810                         pnext = param->right;
14811                         param = param->left;
14812                 }
14813                 if (param && ((param->type & TYPE_MASK) == TYPE_VOID)) {
14814                         param = 0;
14815                 }
14816                 if (param) {
14817                         if (registers_of(state, param) != 1) {
14818                                 error(state, state->main_function,
14819                                         "Result: %d %s requires multiple registers",
14820                                         idx, param->field_ident->name);
14821                         }
14822                         expr = read_expr(state, call);
14823                         if ((result_type->type & TYPE_MASK) == TYPE_STRUCT) {
14824                                 expr = deref_field(state, expr, param->field_ident);
14825                         }
14826                 } else {
14827                         expr = triple(state, OP_UNKNOWNVAL, &int_type, 0, 0);
14828                 }
14829                 flatten(state, out, expr);
14830                 RHS(out, idx) = expr;
14831                 use_triple(expr, out);
14832         }
14833
14834         /* Allocate a dummy containing function */
14835         func = triple(state, OP_LIST, 
14836                 new_type(TYPE_FUNCTION, &void_type, &void_type), 0, 0);
14837         func->type->type_ident = lookup(state, "", 0);
14838         RHS(func, 0) = state->first;
14839         func->u.cval = 1;
14840
14841         /* See which functions are called, and how often */
14842         mark_live_functions(state);
14843         inline_functions(state, func);
14844         walk_functions(state, insert_function, end);
14845
14846         if (start->next != end) {
14847                 jmp = flatten(state, start, branch(state, end, 0));
14848         }
14849
14850         /* OK now the functions have been joined. */
14851         state->functions_joined = 1;
14852
14853         /* Done now cleanup */
14854         state->file = file.prev;
14855         state->function = 0;
14856 }
14857
14858 /*
14859  * Data structurs for optimation.
14860  */
14861
14862
14863 static int do_use_block(
14864         struct block *used, struct block_set **head, struct block *user, 
14865         int front)
14866 {
14867         struct block_set **ptr, *new;
14868         if (!used)
14869                 return 0;
14870         if (!user)
14871                 return 0;
14872         ptr = head;
14873         while(*ptr) {
14874                 if ((*ptr)->member == user) {
14875                         return 0;
14876                 }
14877                 ptr = &(*ptr)->next;
14878         }
14879         new = xcmalloc(sizeof(*new), "block_set");
14880         new->member = user;
14881         if (front) {
14882                 new->next = *head;
14883                 *head = new;
14884         }
14885         else {
14886                 new->next = 0;
14887                 *ptr = new;
14888         }
14889         return 1;
14890 }
14891 static int do_unuse_block(
14892         struct block *used, struct block_set **head, struct block *unuser)
14893 {
14894         struct block_set *use, **ptr;
14895         int count;
14896         count = 0;
14897         ptr = head;
14898         while(*ptr) {
14899                 use = *ptr;
14900                 if (use->member == unuser) {
14901                         *ptr = use->next;
14902                         memset(use, -1, sizeof(*use));
14903                         xfree(use);
14904                         count += 1;
14905                 }
14906                 else {
14907                         ptr = &use->next;
14908                 }
14909         }
14910         return count;
14911 }
14912
14913 static void use_block(struct block *used, struct block *user)
14914 {
14915         int count;
14916         /* Append new to the head of the list, print_block
14917          * depends on this.
14918          */
14919         count = do_use_block(used, &used->use, user, 1); 
14920         used->users += count;
14921 }
14922 static void unuse_block(struct block *used, struct block *unuser)
14923 {
14924         int count;
14925         count = do_unuse_block(used, &used->use, unuser); 
14926         used->users -= count;
14927 }
14928
14929 static void add_block_edge(struct block *block, struct block *edge, int front)
14930 {
14931         int count;
14932         count = do_use_block(block, &block->edges, edge, front);
14933         block->edge_count += count;
14934 }
14935
14936 static void remove_block_edge(struct block *block, struct block *edge)
14937 {
14938         int count;
14939         count = do_unuse_block(block, &block->edges, edge);
14940         block->edge_count -= count;
14941 }
14942
14943 static void idom_block(struct block *idom, struct block *user)
14944 {
14945         do_use_block(idom, &idom->idominates, user, 0);
14946 }
14947
14948 static void unidom_block(struct block *idom, struct block *unuser)
14949 {
14950         do_unuse_block(idom, &idom->idominates, unuser);
14951 }
14952
14953 static void domf_block(struct block *block, struct block *domf)
14954 {
14955         do_use_block(block, &block->domfrontier, domf, 0);
14956 }
14957
14958 static void undomf_block(struct block *block, struct block *undomf)
14959 {
14960         do_unuse_block(block, &block->domfrontier, undomf);
14961 }
14962
14963 static void ipdom_block(struct block *ipdom, struct block *user)
14964 {
14965         do_use_block(ipdom, &ipdom->ipdominates, user, 0);
14966 }
14967
14968 static void unipdom_block(struct block *ipdom, struct block *unuser)
14969 {
14970         do_unuse_block(ipdom, &ipdom->ipdominates, unuser);
14971 }
14972
14973 static void ipdomf_block(struct block *block, struct block *ipdomf)
14974 {
14975         do_use_block(block, &block->ipdomfrontier, ipdomf, 0);
14976 }
14977
14978 static void unipdomf_block(struct block *block, struct block *unipdomf)
14979 {
14980         do_unuse_block(block, &block->ipdomfrontier, unipdomf);
14981 }
14982
14983 static int walk_triples(
14984         struct compile_state *state, 
14985         int (*cb)(struct compile_state *state, struct triple *ptr, void *arg),
14986         void *arg)
14987 {
14988         struct triple *ptr;
14989         int result;
14990         ptr = state->first;
14991         do {
14992                 result = cb(state, ptr, arg);
14993                 if (ptr->next->prev != ptr) {
14994                         internal_error(state, ptr->next, "bad prev");
14995                 }
14996                 ptr = ptr->next;
14997         } while((result == 0) && (ptr != state->first));
14998         return result;
14999 }
15000
15001 #define PRINT_LIST 1
15002 static int do_print_triple(struct compile_state *state, struct triple *ins, void *arg)
15003 {
15004         FILE *fp = arg;
15005         int op;
15006         op = ins->op;
15007         if (op == OP_LIST) {
15008 #if !PRINT_LIST
15009                 return 0;
15010 #endif
15011         }
15012         if ((op == OP_LABEL) && (ins->use)) {
15013                 fprintf(fp, "\n%p:\n", ins);
15014         }
15015         display_triple(fp, ins);
15016
15017         if (triple_is_branch(state, ins) && ins->use && 
15018                 (ins->op != OP_RET) && (ins->op != OP_FCALL)) {
15019                 internal_error(state, ins, "branch used?");
15020         }
15021         if (triple_is_branch(state, ins)) {
15022                 fprintf(fp, "\n");
15023         }
15024         return 0;
15025 }
15026
15027 static void print_triples(struct compile_state *state)
15028 {
15029         if (state->compiler->debug & DEBUG_TRIPLES) {
15030                 FILE *fp = state->dbgout;
15031                 fprintf(fp, "--------------- triples ---------------\n");
15032                 walk_triples(state, do_print_triple, fp);
15033                 fprintf(fp, "\n");
15034         }
15035 }
15036
15037 struct cf_block {
15038         struct block *block;
15039 };
15040 static void find_cf_blocks(struct cf_block *cf, struct block *block)
15041 {
15042         struct block_set *edge;
15043         if (!block || (cf[block->vertex].block == block)) {
15044                 return;
15045         }
15046         cf[block->vertex].block = block;
15047         for(edge = block->edges; edge; edge = edge->next) {
15048                 find_cf_blocks(cf, edge->member);
15049         }
15050 }
15051
15052 static void print_control_flow(struct compile_state *state,
15053         FILE *fp, struct basic_blocks *bb)
15054 {
15055         struct cf_block *cf;
15056         int i;
15057         fprintf(fp, "\ncontrol flow\n");
15058         cf = xcmalloc(sizeof(*cf) * (bb->last_vertex + 1), "cf_block");
15059         find_cf_blocks(cf, bb->first_block);
15060
15061         for(i = 1; i <= bb->last_vertex; i++) {
15062                 struct block *block;
15063                 struct block_set *edge;
15064                 block = cf[i].block;
15065                 if (!block)
15066                         continue;
15067                 fprintf(fp, "(%p) %d:", block, block->vertex);
15068                 for(edge = block->edges; edge; edge = edge->next) {
15069                         fprintf(fp, " %d", edge->member->vertex);
15070                 }
15071                 fprintf(fp, "\n");
15072         }
15073
15074         xfree(cf);
15075 }
15076
15077 static void free_basic_block(struct compile_state *state, struct block *block)
15078 {
15079         struct block_set *edge, *entry;
15080         struct block *child;
15081         if (!block) {
15082                 return;
15083         }
15084         if (block->vertex == -1) {
15085                 return;
15086         }
15087         block->vertex = -1;
15088         for(edge = block->edges; edge; edge = edge->next) {
15089                 if (edge->member) {
15090                         unuse_block(edge->member, block);
15091                 }
15092         }
15093         if (block->idom) {
15094                 unidom_block(block->idom, block);
15095         }
15096         block->idom = 0;
15097         if (block->ipdom) {
15098                 unipdom_block(block->ipdom, block);
15099         }
15100         block->ipdom = 0;
15101         while((entry = block->use)) {
15102                 child = entry->member;
15103                 unuse_block(block, child);
15104                 if (child && (child->vertex != -1)) {
15105                         for(edge = child->edges; edge; edge = edge->next) {
15106                                 edge->member = 0;
15107                         }
15108                 }
15109         }
15110         while((entry = block->idominates)) {
15111                 child = entry->member;
15112                 unidom_block(block, child);
15113                 if (child && (child->vertex != -1)) {
15114                         child->idom = 0;
15115                 }
15116         }
15117         while((entry = block->domfrontier)) {
15118                 child = entry->member;
15119                 undomf_block(block, child);
15120         }
15121         while((entry = block->ipdominates)) {
15122                 child = entry->member;
15123                 unipdom_block(block, child);
15124                 if (child && (child->vertex != -1)) {
15125                         child->ipdom = 0;
15126                 }
15127         }
15128         while((entry = block->ipdomfrontier)) {
15129                 child = entry->member;
15130                 unipdomf_block(block, child);
15131         }
15132         if (block->users != 0) {
15133                 internal_error(state, 0, "block still has users");
15134         }
15135         while((edge = block->edges)) {
15136                 child = edge->member;
15137                 remove_block_edge(block, child);
15138                 
15139                 if (child && (child->vertex != -1)) {
15140                         free_basic_block(state, child);
15141                 }
15142         }
15143         memset(block, -1, sizeof(*block));
15144 #ifndef WIN32
15145         xfree(block);
15146 #endif
15147 }
15148
15149 static void free_basic_blocks(struct compile_state *state, 
15150         struct basic_blocks *bb)
15151 {
15152         struct triple *first, *ins;
15153         free_basic_block(state, bb->first_block);
15154         bb->last_vertex = 0;
15155         bb->first_block = bb->last_block = 0;
15156         first = bb->first;
15157         ins = first;
15158         do {
15159                 if (triple_stores_block(state, ins)) {
15160                         ins->u.block = 0;
15161                 }
15162                 ins = ins->next;
15163         } while(ins != first);
15164         
15165 }
15166
15167 static struct block *basic_block(struct compile_state *state, 
15168         struct basic_blocks *bb, struct triple *first)
15169 {
15170         struct block *block;
15171         struct triple *ptr;
15172         if (!triple_is_label(state, first)) {
15173                 internal_error(state, first, "block does not start with a label");
15174         }
15175         /* See if this basic block has already been setup */
15176         if (first->u.block != 0) {
15177                 return first->u.block;
15178         }
15179         /* Allocate another basic block structure */
15180         bb->last_vertex += 1;
15181         block = xcmalloc(sizeof(*block), "block");
15182         block->first = block->last = first;
15183         block->vertex = bb->last_vertex;
15184         ptr = first;
15185         do {
15186                 if ((ptr != first) && triple_is_label(state, ptr) && (ptr->use)) { 
15187                         break;
15188                 }
15189                 block->last = ptr;
15190                 /* If ptr->u is not used remember where the baic block is */
15191                 if (triple_stores_block(state, ptr)) {
15192                         ptr->u.block = block;
15193                 }
15194                 if (triple_is_branch(state, ptr)) {
15195                         break;
15196                 }
15197                 ptr = ptr->next;
15198         } while (ptr != bb->first);
15199         if ((ptr == bb->first) ||
15200                 ((ptr->next == bb->first) && (
15201                         triple_is_end(state, ptr) || 
15202                         triple_is_ret(state, ptr))))
15203         {
15204                 /* The block has no outflowing edges */
15205         }
15206         else if (triple_is_label(state, ptr)) {
15207                 struct block *next;
15208                 next = basic_block(state, bb, ptr);
15209                 add_block_edge(block, next, 0);
15210                 use_block(next, block);
15211         }
15212         else if (triple_is_branch(state, ptr)) {
15213                 struct triple **expr, *first;
15214                 struct block *child;
15215                 /* Find the branch targets.
15216                  * I special case the first branch as that magically
15217                  * avoids some difficult cases for the register allocator.
15218                  */
15219                 expr = triple_edge_targ(state, ptr, 0);
15220                 if (!expr) {
15221                         internal_error(state, ptr, "branch without targets");
15222                 }
15223                 first = *expr;
15224                 expr = triple_edge_targ(state, ptr, expr);
15225                 for(; expr; expr = triple_edge_targ(state, ptr, expr)) {
15226                         if (!*expr) continue;
15227                         child = basic_block(state, bb, *expr);
15228                         use_block(child, block);
15229                         add_block_edge(block, child, 0);
15230                 }
15231                 if (first) {
15232                         child = basic_block(state, bb, first);
15233                         use_block(child, block);
15234                         add_block_edge(block, child, 1);
15235
15236                         /* Be certain the return block of a call is
15237                          * in a basic block.  When it is not find
15238                          * start of the block, insert a label if
15239                          * necessary and build the basic block.
15240                          * Then add a fake edge from the start block
15241                          * to the return block of the function.
15242                          */
15243                         if (state->functions_joined && triple_is_call(state, ptr)
15244                                 && !block_of_triple(state, MISC(ptr, 0))) {
15245                                 struct block *tail;
15246                                 struct triple *start;
15247                                 start = triple_to_block_start(state, MISC(ptr, 0));
15248                                 if (!triple_is_label(state, start)) {
15249                                         start = pre_triple(state,
15250                                                 start, OP_LABEL, &void_type, 0, 0);
15251                                 }
15252                                 tail = basic_block(state, bb, start);
15253                                 add_block_edge(child, tail, 0);
15254                                 use_block(tail, child);
15255                         }
15256                 }
15257         }
15258         else {
15259                 internal_error(state, 0, "Bad basic block split");
15260         }
15261 #if 0
15262 {
15263         struct block_set *edge;
15264         FILE *fp = state->errout;
15265         fprintf(fp, "basic_block: %10p [%2d] ( %10p - %10p )",
15266                 block, block->vertex, 
15267                 block->first, block->last);
15268         for(edge = block->edges; edge; edge = edge->next) {
15269                 fprintf(fp, " %10p [%2d]",
15270                         edge->member ? edge->member->first : 0,
15271                         edge->member ? edge->member->vertex : -1);
15272         }
15273         fprintf(fp, "\n");
15274 }
15275 #endif
15276         return block;
15277 }
15278
15279
15280 static void walk_blocks(struct compile_state *state, struct basic_blocks *bb,
15281         void (*cb)(struct compile_state *state, struct block *block, void *arg),
15282         void *arg)
15283 {
15284         struct triple *ptr, *first;
15285         struct block *last_block;
15286         last_block = 0;
15287         first = bb->first;
15288         ptr = first;
15289         do {
15290                 if (triple_stores_block(state, ptr)) {
15291                         struct block *block;
15292                         block = ptr->u.block;
15293                         if (block && (block != last_block)) {
15294                                 cb(state, block, arg);
15295                         }
15296                         last_block = block;
15297                 }
15298                 ptr = ptr->next;
15299         } while(ptr != first);
15300 }
15301
15302 static void print_block(
15303         struct compile_state *state, struct block *block, void *arg)
15304 {
15305         struct block_set *user, *edge;
15306         struct triple *ptr;
15307         FILE *fp = arg;
15308
15309         fprintf(fp, "\nblock: %p (%d) ",
15310                 block, 
15311                 block->vertex);
15312
15313         for(edge = block->edges; edge; edge = edge->next) {
15314                 fprintf(fp, " %p<-%p",
15315                         edge->member,
15316                         (edge->member && edge->member->use)?
15317                         edge->member->use->member : 0);
15318         }
15319         fprintf(fp, "\n");
15320         if (block->first->op == OP_LABEL) {
15321                 fprintf(fp, "%p:\n", block->first);
15322         }
15323         for(ptr = block->first; ; ) {
15324                 display_triple(fp, ptr);
15325                 if (ptr == block->last)
15326                         break;
15327                 ptr = ptr->next;
15328                 if (ptr == block->first) {
15329                         internal_error(state, 0, "missing block last?");
15330                 }
15331         }
15332         fprintf(fp, "users %d: ", block->users);
15333         for(user = block->use; user; user = user->next) {
15334                 fprintf(fp, "%p (%d) ", 
15335                         user->member,
15336                         user->member->vertex);
15337         }
15338         fprintf(fp,"\n\n");
15339 }
15340
15341
15342 static void romcc_print_blocks(struct compile_state *state, FILE *fp)
15343 {
15344         fprintf(fp, "--------------- blocks ---------------\n");
15345         walk_blocks(state, &state->bb, print_block, fp);
15346 }
15347 static void print_blocks(struct compile_state *state, const char *func, FILE *fp)
15348 {
15349         if (state->compiler->debug & DEBUG_BASIC_BLOCKS) {
15350                 fprintf(fp, "After %s\n", func);
15351                 romcc_print_blocks(state, fp);
15352                 if (state->compiler->debug & DEBUG_FDOMINATORS) {
15353                         print_dominators(state, fp, &state->bb);
15354                         print_dominance_frontiers(state, fp, &state->bb);
15355                 }
15356                 print_control_flow(state, fp, &state->bb);
15357         }
15358 }
15359
15360 static void prune_nonblock_triples(struct compile_state *state, 
15361         struct basic_blocks *bb)
15362 {
15363         struct block *block;
15364         struct triple *first, *ins, *next;
15365         /* Delete the triples not in a basic block */
15366         block = 0;
15367         first = bb->first;
15368         ins = first;
15369         do {
15370                 next = ins->next;
15371                 if (ins->op == OP_LABEL) {
15372                         block = ins->u.block;
15373                 }
15374                 if (!block) {
15375                         struct triple_set *use;
15376                         for(use = ins->use; use; use = use->next) {
15377                                 struct block *block;
15378                                 block = block_of_triple(state, use->member);
15379                                 if (block != 0) {
15380                                         internal_error(state, ins, "pruning used ins?");
15381                                 }
15382                         }
15383                         release_triple(state, ins);
15384                 }
15385                 if (block && block->last == ins) {
15386                         block = 0;
15387                 }
15388                 ins = next;
15389         } while(ins != first);
15390 }
15391
15392 static void setup_basic_blocks(struct compile_state *state, 
15393         struct basic_blocks *bb)
15394 {
15395         if (!triple_stores_block(state, bb->first)) {
15396                 internal_error(state, 0, "ins will not store block?");
15397         }
15398         /* Initialize the state */
15399         bb->first_block = bb->last_block = 0;
15400         bb->last_vertex = 0;
15401         free_basic_blocks(state, bb);
15402
15403         /* Find the basic blocks */
15404         bb->first_block = basic_block(state, bb, bb->first);
15405
15406         /* Be certain the last instruction of a function, or the
15407          * entire program is in a basic block.  When it is not find 
15408          * the start of the block, insert a label if necessary and build 
15409          * basic block.  Then add a fake edge from the start block
15410          * to the final block.
15411          */
15412         if (!block_of_triple(state, bb->first->prev)) {
15413                 struct triple *start;
15414                 struct block *tail;
15415                 start = triple_to_block_start(state, bb->first->prev);
15416                 if (!triple_is_label(state, start)) {
15417                         start = pre_triple(state,
15418                                 start, OP_LABEL, &void_type, 0, 0);
15419                 }
15420                 tail = basic_block(state, bb, start);
15421                 add_block_edge(bb->first_block, tail, 0);
15422                 use_block(tail, bb->first_block);
15423         }
15424         
15425         /* Find the last basic block.
15426          */
15427         bb->last_block = block_of_triple(state, bb->first->prev);
15428
15429         /* Delete the triples not in a basic block */
15430         prune_nonblock_triples(state, bb);
15431
15432 #if 0
15433         /* If we are debugging print what I have just done */
15434         if (state->compiler->debug & DEBUG_BASIC_BLOCKS) {
15435                 print_blocks(state, state->dbgout);
15436                 print_control_flow(state, bb);
15437         }
15438 #endif
15439 }
15440
15441
15442 struct sdom_block {
15443         struct block *block;
15444         struct sdom_block *sdominates;
15445         struct sdom_block *sdom_next;
15446         struct sdom_block *sdom;
15447         struct sdom_block *label;
15448         struct sdom_block *parent;
15449         struct sdom_block *ancestor;
15450         int vertex;
15451 };
15452
15453
15454 static void unsdom_block(struct sdom_block *block)
15455 {
15456         struct sdom_block **ptr;
15457         if (!block->sdom_next) {
15458                 return;
15459         }
15460         ptr = &block->sdom->sdominates;
15461         while(*ptr) {
15462                 if ((*ptr) == block) {
15463                         *ptr = block->sdom_next;
15464                         return;
15465                 }
15466                 ptr = &(*ptr)->sdom_next;
15467         }
15468 }
15469
15470 static void sdom_block(struct sdom_block *sdom, struct sdom_block *block)
15471 {
15472         unsdom_block(block);
15473         block->sdom = sdom;
15474         block->sdom_next = sdom->sdominates;
15475         sdom->sdominates = block;
15476 }
15477
15478
15479
15480 static int initialize_sdblock(struct sdom_block *sd,
15481         struct block *parent, struct block *block, int vertex)
15482 {
15483         struct block_set *edge;
15484         if (!block || (sd[block->vertex].block == block)) {
15485                 return vertex;
15486         }
15487         vertex += 1;
15488         /* Renumber the blocks in a convinient fashion */
15489         block->vertex = vertex;
15490         sd[vertex].block    = block;
15491         sd[vertex].sdom     = &sd[vertex];
15492         sd[vertex].label    = &sd[vertex];
15493         sd[vertex].parent   = parent? &sd[parent->vertex] : 0;
15494         sd[vertex].ancestor = 0;
15495         sd[vertex].vertex   = vertex;
15496         for(edge = block->edges; edge; edge = edge->next) {
15497                 vertex = initialize_sdblock(sd, block, edge->member, vertex);
15498         }
15499         return vertex;
15500 }
15501
15502 static int initialize_spdblock(
15503         struct compile_state *state, struct sdom_block *sd,
15504         struct block *parent, struct block *block, int vertex)
15505 {
15506         struct block_set *user;
15507         if (!block || (sd[block->vertex].block == block)) {
15508                 return vertex;
15509         }
15510         vertex += 1;
15511         /* Renumber the blocks in a convinient fashion */
15512         block->vertex = vertex;
15513         sd[vertex].block    = block;
15514         sd[vertex].sdom     = &sd[vertex];
15515         sd[vertex].label    = &sd[vertex];
15516         sd[vertex].parent   = parent? &sd[parent->vertex] : 0;
15517         sd[vertex].ancestor = 0;
15518         sd[vertex].vertex   = vertex;
15519         for(user = block->use; user; user = user->next) {
15520                 vertex = initialize_spdblock(state, sd, block, user->member, vertex);
15521         }
15522         return vertex;
15523 }
15524
15525 static int setup_spdblocks(struct compile_state *state, 
15526         struct basic_blocks *bb, struct sdom_block *sd)
15527 {
15528         struct block *block;
15529         int vertex;
15530         /* Setup as many sdpblocks as possible without using fake edges */
15531         vertex = initialize_spdblock(state, sd, 0, bb->last_block, 0);
15532
15533         /* Walk through the graph and find unconnected blocks.  Add a
15534          * fake edge from the unconnected blocks to the end of the
15535          * graph. 
15536          */
15537         block = bb->first_block->last->next->u.block;
15538         for(; block && block != bb->first_block; block = block->last->next->u.block) {
15539                 if (sd[block->vertex].block == block) {
15540                         continue;
15541                 }
15542 #if DEBUG_SDP_BLOCKS
15543                 {
15544                         FILE *fp = state->errout;
15545                         fprintf(fp, "Adding %d\n", vertex +1);
15546                 }
15547 #endif
15548                 add_block_edge(block, bb->last_block, 0);
15549                 use_block(bb->last_block, block);
15550
15551                 vertex = initialize_spdblock(state, sd, bb->last_block, block, vertex);
15552         }
15553         return vertex;
15554 }
15555
15556 static void compress_ancestors(struct sdom_block *v)
15557 {
15558         /* This procedure assumes ancestor(v) != 0 */
15559         /* if (ancestor(ancestor(v)) != 0) {
15560          *      compress(ancestor(ancestor(v)));
15561          *      if (semi(label(ancestor(v))) < semi(label(v))) {
15562          *              label(v) = label(ancestor(v));
15563          *      }
15564          *      ancestor(v) = ancestor(ancestor(v));
15565          * }
15566          */
15567         if (!v->ancestor) {
15568                 return;
15569         }
15570         if (v->ancestor->ancestor) {
15571                 compress_ancestors(v->ancestor->ancestor);
15572                 if (v->ancestor->label->sdom->vertex < v->label->sdom->vertex) {
15573                         v->label = v->ancestor->label;
15574                 }
15575                 v->ancestor = v->ancestor->ancestor;
15576         }
15577 }
15578
15579 static void compute_sdom(struct compile_state *state, 
15580         struct basic_blocks *bb, struct sdom_block *sd)
15581 {
15582         int i;
15583         /* // step 2 
15584          *  for each v <= pred(w) {
15585          *      u = EVAL(v);
15586          *      if (semi[u] < semi[w] { 
15587          *              semi[w] = semi[u]; 
15588          *      } 
15589          * }
15590          * add w to bucket(vertex(semi[w]));
15591          * LINK(parent(w), w);
15592          *
15593          * // step 3
15594          * for each v <= bucket(parent(w)) {
15595          *      delete v from bucket(parent(w));
15596          *      u = EVAL(v);
15597          *      dom(v) = (semi[u] < semi[v]) ? u : parent(w);
15598          * }
15599          */
15600         for(i = bb->last_vertex; i >= 2; i--) {
15601                 struct sdom_block *v, *parent, *next;
15602                 struct block_set *user;
15603                 struct block *block;
15604                 block = sd[i].block;
15605                 parent = sd[i].parent;
15606                 /* Step 2 */
15607                 for(user = block->use; user; user = user->next) {
15608                         struct sdom_block *v, *u;
15609                         v = &sd[user->member->vertex];
15610                         u = !(v->ancestor)? v : (compress_ancestors(v), v->label);
15611                         if (u->sdom->vertex < sd[i].sdom->vertex) {
15612                                 sd[i].sdom = u->sdom;
15613                         }
15614                 }
15615                 sdom_block(sd[i].sdom, &sd[i]);
15616                 sd[i].ancestor = parent;
15617                 /* Step 3 */
15618                 for(v = parent->sdominates; v; v = next) {
15619                         struct sdom_block *u;
15620                         next = v->sdom_next;
15621                         unsdom_block(v);
15622                         u = (!v->ancestor) ? v : (compress_ancestors(v), v->label);
15623                         v->block->idom = (u->sdom->vertex < v->sdom->vertex)? 
15624                                 u->block : parent->block;
15625                 }
15626         }
15627 }
15628
15629 static void compute_spdom(struct compile_state *state, 
15630         struct basic_blocks *bb, struct sdom_block *sd)
15631 {
15632         int i;
15633         /* // step 2 
15634          *  for each v <= pred(w) {
15635          *      u = EVAL(v);
15636          *      if (semi[u] < semi[w] { 
15637          *              semi[w] = semi[u]; 
15638          *      } 
15639          * }
15640          * add w to bucket(vertex(semi[w]));
15641          * LINK(parent(w), w);
15642          *
15643          * // step 3
15644          * for each v <= bucket(parent(w)) {
15645          *      delete v from bucket(parent(w));
15646          *      u = EVAL(v);
15647          *      dom(v) = (semi[u] < semi[v]) ? u : parent(w);
15648          * }
15649          */
15650         for(i = bb->last_vertex; i >= 2; i--) {
15651                 struct sdom_block *u, *v, *parent, *next;
15652                 struct block_set *edge;
15653                 struct block *block;
15654                 block = sd[i].block;
15655                 parent = sd[i].parent;
15656                 /* Step 2 */
15657                 for(edge = block->edges; edge; edge = edge->next) {
15658                         v = &sd[edge->member->vertex];
15659                         u = !(v->ancestor)? v : (compress_ancestors(v), v->label);
15660                         if (u->sdom->vertex < sd[i].sdom->vertex) {
15661                                 sd[i].sdom = u->sdom;
15662                         }
15663                 }
15664                 sdom_block(sd[i].sdom, &sd[i]);
15665                 sd[i].ancestor = parent;
15666                 /* Step 3 */
15667                 for(v = parent->sdominates; v; v = next) {
15668                         struct sdom_block *u;
15669                         next = v->sdom_next;
15670                         unsdom_block(v);
15671                         u = (!v->ancestor) ? v : (compress_ancestors(v), v->label);
15672                         v->block->ipdom = (u->sdom->vertex < v->sdom->vertex)? 
15673                                 u->block : parent->block;
15674                 }
15675         }
15676 }
15677
15678 static void compute_idom(struct compile_state *state, 
15679         struct basic_blocks *bb, struct sdom_block *sd)
15680 {
15681         int i;
15682         for(i = 2; i <= bb->last_vertex; i++) {
15683                 struct block *block;
15684                 block = sd[i].block;
15685                 if (block->idom->vertex != sd[i].sdom->vertex) {
15686                         block->idom = block->idom->idom;
15687                 }
15688                 idom_block(block->idom, block);
15689         }
15690         sd[1].block->idom = 0;
15691 }
15692
15693 static void compute_ipdom(struct compile_state *state, 
15694         struct basic_blocks *bb, struct sdom_block *sd)
15695 {
15696         int i;
15697         for(i = 2; i <= bb->last_vertex; i++) {
15698                 struct block *block;
15699                 block = sd[i].block;
15700                 if (block->ipdom->vertex != sd[i].sdom->vertex) {
15701                         block->ipdom = block->ipdom->ipdom;
15702                 }
15703                 ipdom_block(block->ipdom, block);
15704         }
15705         sd[1].block->ipdom = 0;
15706 }
15707
15708         /* Theorem 1:
15709          *   Every vertex of a flowgraph G = (V, E, r) except r has
15710          *   a unique immediate dominator.  
15711          *   The edges {(idom(w), w) |w <= V - {r}} form a directed tree
15712          *   rooted at r, called the dominator tree of G, such that 
15713          *   v dominates w if and only if v is a proper ancestor of w in
15714          *   the dominator tree.
15715          */
15716         /* Lemma 1:  
15717          *   If v and w are vertices of G such that v <= w,
15718          *   than any path from v to w must contain a common ancestor
15719          *   of v and w in T.
15720          */
15721         /* Lemma 2:  For any vertex w != r, idom(w) -> w */
15722         /* Lemma 3:  For any vertex w != r, sdom(w) -> w */
15723         /* Lemma 4:  For any vertex w != r, idom(w) -> sdom(w) */
15724         /* Theorem 2:
15725          *   Let w != r.  Suppose every u for which sdom(w) -> u -> w satisfies
15726          *   sdom(u) >= sdom(w).  Then idom(w) = sdom(w).
15727          */
15728         /* Theorem 3:
15729          *   Let w != r and let u be a vertex for which sdom(u) is 
15730          *   minimum amoung vertices u satisfying sdom(w) -> u -> w.
15731          *   Then sdom(u) <= sdom(w) and idom(u) = idom(w).
15732          */
15733         /* Lemma 5:  Let vertices v,w satisfy v -> w.
15734          *           Then v -> idom(w) or idom(w) -> idom(v)
15735          */
15736
15737 static void find_immediate_dominators(struct compile_state *state,
15738         struct basic_blocks *bb)
15739 {
15740         struct sdom_block *sd;
15741         /* w->sdom = min{v| there is a path v = v0,v1,...,vk = w such that:
15742          *           vi > w for (1 <= i <= k - 1}
15743          */
15744         /* Theorem 4:
15745          *   For any vertex w != r.
15746          *   sdom(w) = min(
15747          *                 {v|(v,w) <= E  and v < w } U 
15748          *                 {sdom(u) | u > w and there is an edge (v, w) such that u -> v})
15749          */
15750         /* Corollary 1:
15751          *   Let w != r and let u be a vertex for which sdom(u) is 
15752          *   minimum amoung vertices u satisfying sdom(w) -> u -> w.
15753          *   Then:
15754          *                   { sdom(w) if sdom(w) = sdom(u),
15755          *        idom(w) = {
15756          *                   { idom(u) otherwise
15757          */
15758         /* The algorithm consists of the following 4 steps.
15759          * Step 1.  Carry out a depth-first search of the problem graph.  
15760          *    Number the vertices from 1 to N as they are reached during
15761          *    the search.  Initialize the variables used in succeeding steps.
15762          * Step 2.  Compute the semidominators of all vertices by applying
15763          *    theorem 4.   Carry out the computation vertex by vertex in
15764          *    decreasing order by number.
15765          * Step 3.  Implicitly define the immediate dominator of each vertex
15766          *    by applying Corollary 1.
15767          * Step 4.  Explicitly define the immediate dominator of each vertex,
15768          *    carrying out the computation vertex by vertex in increasing order
15769          *    by number.
15770          */
15771         /* Step 1 initialize the basic block information */
15772         sd = xcmalloc(sizeof(*sd) * (bb->last_vertex + 1), "sdom_state");
15773         initialize_sdblock(sd, 0, bb->first_block, 0);
15774 #if 0
15775         sd[1].size  = 0;
15776         sd[1].label = 0;
15777         sd[1].sdom  = 0;
15778 #endif
15779         /* Step 2 compute the semidominators */
15780         /* Step 3 implicitly define the immediate dominator of each vertex */
15781         compute_sdom(state, bb, sd);
15782         /* Step 4 explicitly define the immediate dominator of each vertex */
15783         compute_idom(state, bb, sd);
15784         xfree(sd);
15785 }
15786
15787 static void find_post_dominators(struct compile_state *state,
15788         struct basic_blocks *bb)
15789 {
15790         struct sdom_block *sd;
15791         int vertex;
15792         /* Step 1 initialize the basic block information */
15793         sd = xcmalloc(sizeof(*sd) * (bb->last_vertex + 1), "sdom_state");
15794
15795         vertex = setup_spdblocks(state, bb, sd);
15796         if (vertex != bb->last_vertex) {
15797                 internal_error(state, 0, "missing %d blocks",
15798                         bb->last_vertex - vertex);
15799         }
15800
15801         /* Step 2 compute the semidominators */
15802         /* Step 3 implicitly define the immediate dominator of each vertex */
15803         compute_spdom(state, bb, sd);
15804         /* Step 4 explicitly define the immediate dominator of each vertex */
15805         compute_ipdom(state, bb, sd);
15806         xfree(sd);
15807 }
15808
15809
15810
15811 static void find_block_domf(struct compile_state *state, struct block *block)
15812 {
15813         struct block *child;
15814         struct block_set *user, *edge;
15815         if (block->domfrontier != 0) {
15816                 internal_error(state, block->first, "domfrontier present?");
15817         }
15818         for(user = block->idominates; user; user = user->next) {
15819                 child = user->member;
15820                 if (child->idom != block) {
15821                         internal_error(state, block->first, "bad idom");
15822                 }
15823                 find_block_domf(state, child);
15824         }
15825         for(edge = block->edges; edge; edge = edge->next) {
15826                 if (edge->member->idom != block) {
15827                         domf_block(block, edge->member);
15828                 }
15829         }
15830         for(user = block->idominates; user; user = user->next) {
15831                 struct block_set *frontier;
15832                 child = user->member;
15833                 for(frontier = child->domfrontier; frontier; frontier = frontier->next) {
15834                         if (frontier->member->idom != block) {
15835                                 domf_block(block, frontier->member);
15836                         }
15837                 }
15838         }
15839 }
15840
15841 static void find_block_ipdomf(struct compile_state *state, struct block *block)
15842 {
15843         struct block *child;
15844         struct block_set *user;
15845         if (block->ipdomfrontier != 0) {
15846                 internal_error(state, block->first, "ipdomfrontier present?");
15847         }
15848         for(user = block->ipdominates; user; user = user->next) {
15849                 child = user->member;
15850                 if (child->ipdom != block) {
15851                         internal_error(state, block->first, "bad ipdom");
15852                 }
15853                 find_block_ipdomf(state, child);
15854         }
15855         for(user = block->use; user; user = user->next) {
15856                 if (user->member->ipdom != block) {
15857                         ipdomf_block(block, user->member);
15858                 }
15859         }
15860         for(user = block->ipdominates; user; user = user->next) {
15861                 struct block_set *frontier;
15862                 child = user->member;
15863                 for(frontier = child->ipdomfrontier; frontier; frontier = frontier->next) {
15864                         if (frontier->member->ipdom != block) {
15865                                 ipdomf_block(block, frontier->member);
15866                         }
15867                 }
15868         }
15869 }
15870
15871 static void print_dominated(
15872         struct compile_state *state, struct block *block, void *arg)
15873 {
15874         struct block_set *user;
15875         FILE *fp = arg;
15876
15877         fprintf(fp, "%d:", block->vertex);
15878         for(user = block->idominates; user; user = user->next) {
15879                 fprintf(fp, " %d", user->member->vertex);
15880                 if (user->member->idom != block) {
15881                         internal_error(state, user->member->first, "bad idom");
15882                 }
15883         }
15884         fprintf(fp,"\n");
15885 }
15886
15887 static void print_dominated2(
15888         struct compile_state *state, FILE *fp, int depth, struct block *block)
15889 {
15890         struct block_set *user;
15891         struct triple *ins;
15892         struct occurance *ptr, *ptr2;
15893         const char *filename1, *filename2;
15894         int equal_filenames;
15895         int i;
15896         for(i = 0; i < depth; i++) {
15897                 fprintf(fp, "   ");
15898         }
15899         fprintf(fp, "%3d: %p (%p - %p) @", 
15900                 block->vertex, block, block->first, block->last);
15901         ins = block->first;
15902         while(ins != block->last && (ins->occurance->line == 0)) {
15903                 ins = ins->next;
15904         }
15905         ptr = ins->occurance;
15906         ptr2 = block->last->occurance;
15907         filename1 = ptr->filename? ptr->filename : "";
15908         filename2 = ptr2->filename? ptr2->filename : "";
15909         equal_filenames = (strcmp(filename1, filename2) == 0);
15910         if ((ptr == ptr2) || (equal_filenames && ptr->line == ptr2->line)) {
15911                 fprintf(fp, " %s:%d", ptr->filename, ptr->line);
15912         } else if (equal_filenames) {
15913                 fprintf(fp, " %s:(%d - %d)",
15914                         ptr->filename, ptr->line, ptr2->line);
15915         } else {
15916                 fprintf(fp, " (%s:%d - %s:%d)",
15917                         ptr->filename, ptr->line,
15918                         ptr2->filename, ptr2->line);
15919         }
15920         fprintf(fp, "\n");
15921         for(user = block->idominates; user; user = user->next) {
15922                 print_dominated2(state, fp, depth + 1, user->member);
15923         }
15924 }
15925
15926 static void print_dominators(struct compile_state *state, FILE *fp, struct basic_blocks *bb)
15927 {
15928         fprintf(fp, "\ndominates\n");
15929         walk_blocks(state, bb, print_dominated, fp);
15930         fprintf(fp, "dominates\n");
15931         print_dominated2(state, fp, 0, bb->first_block);
15932 }
15933
15934
15935 static int print_frontiers(
15936         struct compile_state *state, FILE *fp, struct block *block, int vertex)
15937 {
15938         struct block_set *user, *edge;
15939
15940         if (!block || (block->vertex != vertex + 1)) {
15941                 return vertex;
15942         }
15943         vertex += 1;
15944
15945         fprintf(fp, "%d:", block->vertex);
15946         for(user = block->domfrontier; user; user = user->next) {
15947                 fprintf(fp, " %d", user->member->vertex);
15948         }
15949         fprintf(fp, "\n");
15950         
15951         for(edge = block->edges; edge; edge = edge->next) {
15952                 vertex = print_frontiers(state, fp, edge->member, vertex);
15953         }
15954         return vertex;
15955 }
15956 static void print_dominance_frontiers(struct compile_state *state,
15957         FILE *fp, struct basic_blocks *bb)
15958 {
15959         fprintf(fp, "\ndominance frontiers\n");
15960         print_frontiers(state, fp, bb->first_block, 0);
15961         
15962 }
15963
15964 static void analyze_idominators(struct compile_state *state, struct basic_blocks *bb)
15965 {
15966         /* Find the immediate dominators */
15967         find_immediate_dominators(state, bb);
15968         /* Find the dominance frontiers */
15969         find_block_domf(state, bb->first_block);
15970         /* If debuging print the print what I have just found */
15971         if (state->compiler->debug & DEBUG_FDOMINATORS) {
15972                 print_dominators(state, state->dbgout, bb);
15973                 print_dominance_frontiers(state, state->dbgout, bb);
15974                 print_control_flow(state, state->dbgout, bb);
15975         }
15976 }
15977
15978
15979 static void print_ipdominated(
15980         struct compile_state *state, struct block *block, void *arg)
15981 {
15982         struct block_set *user;
15983         FILE *fp = arg;
15984
15985         fprintf(fp, "%d:", block->vertex);
15986         for(user = block->ipdominates; user; user = user->next) {
15987                 fprintf(fp, " %d", user->member->vertex);
15988                 if (user->member->ipdom != block) {
15989                         internal_error(state, user->member->first, "bad ipdom");
15990                 }
15991         }
15992         fprintf(fp, "\n");
15993 }
15994
15995 static void print_ipdominators(struct compile_state *state, FILE *fp,
15996         struct basic_blocks *bb)
15997 {
15998         fprintf(fp, "\nipdominates\n");
15999         walk_blocks(state, bb, print_ipdominated, fp);
16000 }
16001
16002 static int print_pfrontiers(
16003         struct compile_state *state, FILE *fp, struct block *block, int vertex)
16004 {
16005         struct block_set *user;
16006
16007         if (!block || (block->vertex != vertex + 1)) {
16008                 return vertex;
16009         }
16010         vertex += 1;
16011
16012         fprintf(fp, "%d:", block->vertex);
16013         for(user = block->ipdomfrontier; user; user = user->next) {
16014                 fprintf(fp, " %d", user->member->vertex);
16015         }
16016         fprintf(fp, "\n");
16017         for(user = block->use; user; user = user->next) {
16018                 vertex = print_pfrontiers(state, fp, user->member, vertex);
16019         }
16020         return vertex;
16021 }
16022 static void print_ipdominance_frontiers(struct compile_state *state,
16023         FILE *fp, struct basic_blocks *bb)
16024 {
16025         fprintf(fp, "\nipdominance frontiers\n");
16026         print_pfrontiers(state, fp, bb->last_block, 0);
16027         
16028 }
16029
16030 static void analyze_ipdominators(struct compile_state *state,
16031         struct basic_blocks *bb)
16032 {
16033         /* Find the post dominators */
16034         find_post_dominators(state, bb);
16035         /* Find the control dependencies (post dominance frontiers) */
16036         find_block_ipdomf(state, bb->last_block);
16037         /* If debuging print the print what I have just found */
16038         if (state->compiler->debug & DEBUG_RDOMINATORS) {
16039                 print_ipdominators(state, state->dbgout, bb);
16040                 print_ipdominance_frontiers(state, state->dbgout, bb);
16041                 print_control_flow(state, state->dbgout, bb);
16042         }
16043 }
16044
16045 static int bdominates(struct compile_state *state,
16046         struct block *dom, struct block *sub)
16047 {
16048         while(sub && (sub != dom)) {
16049                 sub = sub->idom;
16050         }
16051         return sub == dom;
16052 }
16053
16054 static int tdominates(struct compile_state *state,
16055         struct triple *dom, struct triple *sub)
16056 {
16057         struct block *bdom, *bsub;
16058         int result;
16059         bdom = block_of_triple(state, dom);
16060         bsub = block_of_triple(state, sub);
16061         if (bdom != bsub) {
16062                 result = bdominates(state, bdom, bsub);
16063         } 
16064         else {
16065                 struct triple *ins;
16066                 if (!bdom || !bsub) {
16067                         internal_error(state, dom, "huh?");
16068                 }
16069                 ins = sub;
16070                 while((ins != bsub->first) && (ins != dom)) {
16071                         ins = ins->prev;
16072                 }
16073                 result = (ins == dom);
16074         }
16075         return result;
16076 }
16077
16078 static void analyze_basic_blocks(
16079         struct compile_state *state, struct basic_blocks *bb)
16080 {
16081         setup_basic_blocks(state, bb);
16082         analyze_idominators(state, bb);
16083         analyze_ipdominators(state, bb);
16084 }
16085
16086 static void insert_phi_operations(struct compile_state *state)
16087 {
16088         size_t size;
16089         struct triple *first;
16090         int *has_already, *work;
16091         struct block *work_list, **work_list_tail;
16092         int iter;
16093         struct triple *var, *vnext;
16094
16095         size = sizeof(int) * (state->bb.last_vertex + 1);
16096         has_already = xcmalloc(size, "has_already");
16097         work =        xcmalloc(size, "work");
16098         iter = 0;
16099
16100         first = state->first;
16101         for(var = first->next; var != first ; var = vnext) {
16102                 struct block *block;
16103                 struct triple_set *user, *unext;
16104                 vnext = var->next;
16105
16106                 if (!triple_is_auto_var(state, var) || !var->use) {
16107                         continue;
16108                 }
16109                         
16110                 iter += 1;
16111                 work_list = 0;
16112                 work_list_tail = &work_list;
16113                 for(user = var->use; user; user = unext) {
16114                         unext = user->next;
16115                         if (MISC(var, 0) == user->member) {
16116                                 continue;
16117                         }
16118                         if (user->member->op == OP_READ) {
16119                                 continue;
16120                         }
16121                         if (user->member->op != OP_WRITE) {
16122                                 internal_error(state, user->member, 
16123                                         "bad variable access");
16124                         }
16125                         block = user->member->u.block;
16126                         if (!block) {
16127                                 warning(state, user->member, "dead code");
16128                                 release_triple(state, user->member);
16129                                 continue;
16130                         }
16131                         if (work[block->vertex] >= iter) {
16132                                 continue;
16133                         }
16134                         work[block->vertex] = iter;
16135                         *work_list_tail = block;
16136                         block->work_next = 0;
16137                         work_list_tail = &block->work_next;
16138                 }
16139                 for(block = work_list; block; block = block->work_next) {
16140                         struct block_set *df;
16141                         for(df = block->domfrontier; df; df = df->next) {
16142                                 struct triple *phi;
16143                                 struct block *front;
16144                                 int in_edges;
16145                                 front = df->member;
16146
16147                                 if (has_already[front->vertex] >= iter) {
16148                                         continue;
16149                                 }
16150                                 /* Count how many edges flow into this block */
16151                                 in_edges = front->users;
16152                                 /* Insert a phi function for this variable */
16153                                 get_occurance(var->occurance);
16154                                 phi = alloc_triple(
16155                                         state, OP_PHI, var->type, -1, in_edges, 
16156                                         var->occurance);
16157                                 phi->u.block = front;
16158                                 MISC(phi, 0) = var;
16159                                 use_triple(var, phi);
16160 #if 1
16161                                 if (phi->rhs != in_edges) {
16162                                         internal_error(state, phi, "phi->rhs: %d != in_edges: %d",
16163                                                 phi->rhs, in_edges);
16164                                 }
16165 #endif
16166                                 /* Insert the phi functions immediately after the label */
16167                                 insert_triple(state, front->first->next, phi);
16168                                 if (front->first == front->last) {
16169                                         front->last = front->first->next;
16170                                 }
16171                                 has_already[front->vertex] = iter;
16172                                 transform_to_arch_instruction(state, phi);
16173
16174                                 /* If necessary plan to visit the basic block */
16175                                 if (work[front->vertex] >= iter) {
16176                                         continue;
16177                                 }
16178                                 work[front->vertex] = iter;
16179                                 *work_list_tail = front;
16180                                 front->work_next = 0;
16181                                 work_list_tail = &front->work_next;
16182                         }
16183                 }
16184         }
16185         xfree(has_already);
16186         xfree(work);
16187 }
16188
16189
16190 struct stack {
16191         struct triple_set *top;
16192         unsigned orig_id;
16193 };
16194
16195 static int count_auto_vars(struct compile_state *state)
16196 {
16197         struct triple *first, *ins;
16198         int auto_vars = 0;
16199         first = state->first;
16200         ins = first;
16201         do {
16202                 if (triple_is_auto_var(state, ins)) {
16203                         auto_vars += 1;
16204                 }
16205                 ins = ins->next;
16206         } while(ins != first);
16207         return auto_vars;
16208 }
16209
16210 static void number_auto_vars(struct compile_state *state, struct stack *stacks)
16211 {
16212         struct triple *first, *ins;
16213         int auto_vars = 0;
16214         first = state->first;
16215         ins = first;
16216         do {
16217                 if (triple_is_auto_var(state, ins)) {
16218                         auto_vars += 1;
16219                         stacks[auto_vars].orig_id = ins->id;
16220                         ins->id = auto_vars;
16221                 }
16222                 ins = ins->next;
16223         } while(ins != first);
16224 }
16225
16226 static void restore_auto_vars(struct compile_state *state, struct stack *stacks)
16227 {
16228         struct triple *first, *ins;
16229         first = state->first;
16230         ins = first;
16231         do {
16232                 if (triple_is_auto_var(state, ins)) {
16233                         ins->id = stacks[ins->id].orig_id;
16234                 }
16235                 ins = ins->next;
16236         } while(ins != first);
16237 }
16238
16239 static struct triple *peek_triple(struct stack *stacks, struct triple *var)
16240 {
16241         struct triple_set *head;
16242         struct triple *top_val;
16243         top_val = 0;
16244         head = stacks[var->id].top;
16245         if (head) {
16246                 top_val = head->member;
16247         }
16248         return top_val;
16249 }
16250
16251 static void push_triple(struct stack *stacks, struct triple *var, struct triple *val)
16252 {
16253         struct triple_set *new;
16254         /* Append new to the head of the list,
16255          * it's the only sensible behavoir for a stack.
16256          */
16257         new = xcmalloc(sizeof(*new), "triple_set");
16258         new->member = val;
16259         new->next   = stacks[var->id].top;
16260         stacks[var->id].top = new;
16261 }
16262
16263 static void pop_triple(struct stack *stacks, struct triple *var, struct triple *oldval)
16264 {
16265         struct triple_set *set, **ptr;
16266         ptr = &stacks[var->id].top;
16267         while(*ptr) {
16268                 set = *ptr;
16269                 if (set->member == oldval) {
16270                         *ptr = set->next;
16271                         xfree(set);
16272                         /* Only free one occurance from the stack */
16273                         return;
16274                 }
16275                 else {
16276                         ptr = &set->next;
16277                 }
16278         }
16279 }
16280
16281 /*
16282  * C(V)
16283  * S(V)
16284  */
16285 static void fixup_block_phi_variables(
16286         struct compile_state *state, struct stack *stacks, struct block *parent, struct block *block)
16287 {
16288         struct block_set *set;
16289         struct triple *ptr;
16290         int edge;
16291         if (!parent || !block)
16292                 return;
16293         /* Find the edge I am coming in on */
16294         edge = 0;
16295         for(set = block->use; set; set = set->next, edge++) {
16296                 if (set->member == parent) {
16297                         break;
16298                 }
16299         }
16300         if (!set) {
16301                 internal_error(state, 0, "phi input is not on a control predecessor");
16302         }
16303         for(ptr = block->first; ; ptr = ptr->next) {
16304                 if (ptr->op == OP_PHI) {
16305                         struct triple *var, *val, **slot;
16306                         var = MISC(ptr, 0);
16307                         if (!var) {
16308                                 internal_error(state, ptr, "no var???");
16309                         }
16310                         /* Find the current value of the variable */
16311                         val = peek_triple(stacks, var);
16312                         if (val && ((val->op == OP_WRITE) || (val->op == OP_READ))) {
16313                                 internal_error(state, val, "bad value in phi");
16314                         }
16315                         if (edge >= ptr->rhs) {
16316                                 internal_error(state, ptr, "edges > phi rhs");
16317                         }
16318                         slot = &RHS(ptr, edge);
16319                         if ((*slot != 0) && (*slot != val)) {
16320                                 internal_error(state, ptr, "phi already bound on this edge");
16321                         }
16322                         *slot = val;
16323                         use_triple(val, ptr);
16324                 }
16325                 if (ptr == block->last) {
16326                         break;
16327                 }
16328         }
16329 }
16330
16331
16332 static void rename_block_variables(
16333         struct compile_state *state, struct stack *stacks, struct block *block)
16334 {
16335         struct block_set *user, *edge;
16336         struct triple *ptr, *next, *last;
16337         int done;
16338         if (!block)
16339                 return;
16340         last = block->first;
16341         done = 0;
16342         for(ptr = block->first; !done; ptr = next) {
16343                 next = ptr->next;
16344                 if (ptr == block->last) {
16345                         done = 1;
16346                 }
16347                 /* RHS(A) */
16348                 if (ptr->op == OP_READ) {
16349                         struct triple *var, *val;
16350                         var = RHS(ptr, 0);
16351                         if (!triple_is_auto_var(state, var)) {
16352                                 internal_error(state, ptr, "read of non auto var!");
16353                         }
16354                         unuse_triple(var, ptr);
16355                         /* Find the current value of the variable */
16356                         val = peek_triple(stacks, var);
16357                         if (!val) {
16358                                 /* Let the optimizer at variables that are not initially
16359                                  * set.  But give it a bogus value so things seem to
16360                                  * work by accident.  This is useful for bitfields because
16361                                  * setting them always involves a read-modify-write.
16362                                  */
16363                                 if (TYPE_ARITHMETIC(ptr->type->type)) {
16364                                         val = pre_triple(state, ptr, OP_INTCONST, ptr->type, 0, 0);
16365                                         val->u.cval = 0xdeadbeaf;
16366                                 } else {
16367                                         val = pre_triple(state, ptr, OP_UNKNOWNVAL, ptr->type, 0, 0);
16368                                 }
16369                         }
16370                         if (!val) {
16371                                 error(state, ptr, "variable used without being set");
16372                         }
16373                         if ((val->op == OP_WRITE) || (val->op == OP_READ)) {
16374                                 internal_error(state, val, "bad value in read");
16375                         }
16376                         propogate_use(state, ptr, val);
16377                         release_triple(state, ptr);
16378                         continue;
16379                 }
16380                 /* LHS(A) */
16381                 if (ptr->op == OP_WRITE) {
16382                         struct triple *var, *val, *tval;
16383                         var = MISC(ptr, 0);
16384                         if (!triple_is_auto_var(state, var)) {
16385                                 internal_error(state, ptr, "write to non auto var!");
16386                         }
16387                         tval = val = RHS(ptr, 0);
16388                         if ((val->op == OP_WRITE) || (val->op == OP_READ) ||
16389                                 triple_is_auto_var(state, val)) {
16390                                 internal_error(state, ptr, "bad value in write");
16391                         }
16392                         /* Insert a cast if the types differ */
16393                         if (!is_subset_type(ptr->type, val->type)) {
16394                                 if (val->op == OP_INTCONST) {
16395                                         tval = pre_triple(state, ptr, OP_INTCONST, ptr->type, 0, 0);
16396                                         tval->u.cval = val->u.cval;
16397                                 }
16398                                 else {
16399                                         tval = pre_triple(state, ptr, OP_CONVERT, ptr->type, val, 0);
16400                                         use_triple(val, tval);
16401                                 }
16402                                 transform_to_arch_instruction(state, tval);
16403                                 unuse_triple(val, ptr);
16404                                 RHS(ptr, 0) = tval;
16405                                 use_triple(tval, ptr);
16406                         }
16407                         propogate_use(state, ptr, tval);
16408                         unuse_triple(var, ptr);
16409                         /* Push OP_WRITE ptr->right onto a stack of variable uses */
16410                         push_triple(stacks, var, tval);
16411                 }
16412                 if (ptr->op == OP_PHI) {
16413                         struct triple *var;
16414                         var = MISC(ptr, 0);
16415                         if (!triple_is_auto_var(state, var)) {
16416                                 internal_error(state, ptr, "phi references non auto var!");
16417                         }
16418                         /* Push OP_PHI onto a stack of variable uses */
16419                         push_triple(stacks, var, ptr);
16420                 }
16421                 last = ptr;
16422         }
16423         block->last = last;
16424
16425         /* Fixup PHI functions in the cf successors */
16426         for(edge = block->edges; edge; edge = edge->next) {
16427                 fixup_block_phi_variables(state, stacks, block, edge->member);
16428         }
16429         /* rename variables in the dominated nodes */
16430         for(user = block->idominates; user; user = user->next) {
16431                 rename_block_variables(state, stacks, user->member);
16432         }
16433         /* pop the renamed variable stack */
16434         last = block->first;
16435         done = 0;
16436         for(ptr = block->first; !done ; ptr = next) {
16437                 next = ptr->next;
16438                 if (ptr == block->last) {
16439                         done = 1;
16440                 }
16441                 if (ptr->op == OP_WRITE) {
16442                         struct triple *var;
16443                         var = MISC(ptr, 0);
16444                         /* Pop OP_WRITE ptr->right from the stack of variable uses */
16445                         pop_triple(stacks, var, RHS(ptr, 0));
16446                         release_triple(state, ptr);
16447                         continue;
16448                 }
16449                 if (ptr->op == OP_PHI) {
16450                         struct triple *var;
16451                         var = MISC(ptr, 0);
16452                         /* Pop OP_WRITE ptr->right from the stack of variable uses */
16453                         pop_triple(stacks, var, ptr);
16454                 }
16455                 last = ptr;
16456         }
16457         block->last = last;
16458 }
16459
16460 static void rename_variables(struct compile_state *state)
16461 {
16462         struct stack *stacks;
16463         int auto_vars;
16464
16465         /* Allocate stacks for the Variables */
16466         auto_vars = count_auto_vars(state);
16467         stacks = xcmalloc(sizeof(stacks[0])*(auto_vars + 1), "auto var stacks");
16468
16469         /* Give each auto_var a stack */
16470         number_auto_vars(state, stacks);
16471
16472         /* Rename the variables */
16473         rename_block_variables(state, stacks, state->bb.first_block);
16474
16475         /* Remove the stacks from the auto_vars */
16476         restore_auto_vars(state, stacks);
16477         xfree(stacks);
16478 }
16479
16480 static void prune_block_variables(struct compile_state *state,
16481         struct block *block)
16482 {
16483         struct block_set *user;
16484         struct triple *next, *ptr;
16485         int done;
16486
16487         done = 0;
16488         for(ptr = block->first; !done; ptr = next) {
16489                 /* Be extremely careful I am deleting the list
16490                  * as I walk trhough it.
16491                  */
16492                 next = ptr->next;
16493                 if (ptr == block->last) {
16494                         done = 1;
16495                 }
16496                 if (triple_is_auto_var(state, ptr)) {
16497                         struct triple_set *user, *next;
16498                         for(user = ptr->use; user; user = next) {
16499                                 struct triple *use;
16500                                 next = user->next;
16501                                 use = user->member;
16502                                 if (MISC(ptr, 0) == user->member) {
16503                                         continue;
16504                                 }
16505                                 if (use->op != OP_PHI) {
16506                                         internal_error(state, use, "decl still used");
16507                                 }
16508                                 if (MISC(use, 0) != ptr) {
16509                                         internal_error(state, use, "bad phi use of decl");
16510                                 }
16511                                 unuse_triple(ptr, use);
16512                                 MISC(use, 0) = 0;
16513                         }
16514                         if ((ptr->u.cval == 0) && (MISC(ptr, 0)->lhs == 1)) {
16515                                 /* Delete the adecl */
16516                                 release_triple(state, MISC(ptr, 0));
16517                                 /* And the piece */
16518                                 release_triple(state, ptr);
16519                         }
16520                         continue;
16521                 }
16522         }
16523         for(user = block->idominates; user; user = user->next) {
16524                 prune_block_variables(state, user->member);
16525         }
16526 }
16527
16528 struct phi_triple {
16529         struct triple *phi;
16530         unsigned orig_id;
16531         int alive;
16532 };
16533
16534 static void keep_phi(struct compile_state *state, struct phi_triple *live, struct triple *phi)
16535 {
16536         struct triple **slot;
16537         int zrhs, i;
16538         if (live[phi->id].alive) {
16539                 return;
16540         }
16541         live[phi->id].alive = 1;
16542         zrhs = phi->rhs;
16543         slot = &RHS(phi, 0);
16544         for(i = 0; i < zrhs; i++) {
16545                 struct triple *used;
16546                 used = slot[i];
16547                 if (used && (used->op == OP_PHI)) {
16548                         keep_phi(state, live, used);
16549                 }
16550         }
16551 }
16552
16553 static void prune_unused_phis(struct compile_state *state)
16554 {
16555         struct triple *first, *phi;
16556         struct phi_triple *live;
16557         int phis, i;
16558         
16559         /* Find the first instruction */
16560         first = state->first;
16561
16562         /* Count how many phi functions I need to process */
16563         phis = 0;
16564         for(phi = first->next; phi != first; phi = phi->next) {
16565                 if (phi->op == OP_PHI) {
16566                         phis += 1;
16567                 }
16568         }
16569         
16570         /* Mark them all dead */
16571         live = xcmalloc(sizeof(*live) * (phis + 1), "phi_triple");
16572         phis = 0;
16573         for(phi = first->next; phi != first; phi = phi->next) {
16574                 if (phi->op != OP_PHI) {
16575                         continue;
16576                 }
16577                 live[phis].alive   = 0;
16578                 live[phis].orig_id = phi->id;
16579                 live[phis].phi     = phi;
16580                 phi->id = phis;
16581                 phis += 1;
16582         }
16583         
16584         /* Mark phis alive that are used by non phis */
16585         for(i = 0; i < phis; i++) {
16586                 struct triple_set *set;
16587                 for(set = live[i].phi->use; !live[i].alive && set; set = set->next) {
16588                         if (set->member->op != OP_PHI) {
16589                                 keep_phi(state, live, live[i].phi);
16590                                 break;
16591                         }
16592                 }
16593         }
16594
16595         /* Delete the extraneous phis */
16596         for(i = 0; i < phis; i++) {
16597                 struct triple **slot;
16598                 int zrhs, j;
16599                 if (!live[i].alive) {
16600                         release_triple(state, live[i].phi);
16601                         continue;
16602                 }
16603                 phi = live[i].phi;
16604                 slot = &RHS(phi, 0);
16605                 zrhs = phi->rhs;
16606                 for(j = 0; j < zrhs; j++) {
16607                         if(!slot[j]) {
16608                                 struct triple *unknown;
16609                                 get_occurance(phi->occurance);
16610                                 unknown = flatten(state, state->global_pool,
16611                                         alloc_triple(state, OP_UNKNOWNVAL,
16612                                                 phi->type, 0, 0, phi->occurance));
16613                                 slot[j] = unknown;
16614                                 use_triple(unknown, phi);
16615                                 transform_to_arch_instruction(state, unknown);
16616 #if 0                           
16617                                 warning(state, phi, "variable not set at index %d on all paths to use", j);
16618 #endif
16619                         }
16620                 }
16621         }
16622         xfree(live);
16623 }
16624
16625 static void transform_to_ssa_form(struct compile_state *state)
16626 {
16627         insert_phi_operations(state);
16628         rename_variables(state);
16629
16630         prune_block_variables(state, state->bb.first_block);
16631         prune_unused_phis(state);
16632
16633         print_blocks(state, __func__, state->dbgout);
16634 }
16635
16636
16637 static void clear_vertex(
16638         struct compile_state *state, struct block *block, void *arg)
16639 {
16640         /* Clear the current blocks vertex and the vertex of all
16641          * of the current blocks neighbors in case there are malformed
16642          * blocks with now instructions at this point.
16643          */
16644         struct block_set *user, *edge;
16645         block->vertex = 0;
16646         for(edge = block->edges; edge; edge = edge->next) {
16647                 edge->member->vertex = 0;
16648         }
16649         for(user = block->use; user; user = user->next) {
16650                 user->member->vertex = 0;
16651         }
16652 }
16653
16654 static void mark_live_block(
16655         struct compile_state *state, struct block *block, int *next_vertex)
16656 {
16657         /* See if this is a block that has not been marked */
16658         if (block->vertex != 0) {
16659                 return;
16660         }
16661         block->vertex = *next_vertex;
16662         *next_vertex += 1;
16663         if (triple_is_branch(state, block->last)) {
16664                 struct triple **targ;
16665                 targ = triple_edge_targ(state, block->last, 0);
16666                 for(; targ; targ = triple_edge_targ(state, block->last, targ)) {
16667                         if (!*targ) {
16668                                 continue;
16669                         }
16670                         if (!triple_stores_block(state, *targ)) {
16671                                 internal_error(state, 0, "bad targ");
16672                         }
16673                         mark_live_block(state, (*targ)->u.block, next_vertex);
16674                 }
16675                 /* Ensure the last block of a function remains alive */
16676                 if (triple_is_call(state, block->last)) {
16677                         mark_live_block(state, MISC(block->last, 0)->u.block, next_vertex);
16678                 }
16679         }
16680         else if (block->last->next != state->first) {
16681                 struct triple *ins;
16682                 ins = block->last->next;
16683                 if (!triple_stores_block(state, ins)) {
16684                         internal_error(state, 0, "bad block start");
16685                 }
16686                 mark_live_block(state, ins->u.block, next_vertex);
16687         }
16688 }
16689
16690 static void transform_from_ssa_form(struct compile_state *state)
16691 {
16692         /* To get out of ssa form we insert moves on the incoming
16693          * edges to blocks containting phi functions.
16694          */
16695         struct triple *first;
16696         struct triple *phi, *var, *next;
16697         int next_vertex;
16698
16699         /* Walk the control flow to see which blocks remain alive */
16700         walk_blocks(state, &state->bb, clear_vertex, 0);
16701         next_vertex = 1;
16702         mark_live_block(state, state->bb.first_block, &next_vertex);
16703
16704         /* Walk all of the operations to find the phi functions */
16705         first = state->first;
16706         for(phi = first->next; phi != first ; phi = next) {
16707                 struct block_set *set;
16708                 struct block *block;
16709                 struct triple **slot;
16710                 struct triple *var;
16711                 struct triple_set *use, *use_next;
16712                 int edge, writers, readers;
16713                 next = phi->next;
16714                 if (phi->op != OP_PHI) {
16715                         continue;
16716                 }
16717
16718                 block = phi->u.block;
16719                 slot  = &RHS(phi, 0);
16720
16721                 /* If this phi is in a dead block just forget it */
16722                 if (block->vertex == 0) {
16723                         release_triple(state, phi);
16724                         continue;
16725                 }
16726
16727                 /* Forget uses from code in dead blocks */
16728                 for(use = phi->use; use; use = use_next) {
16729                         struct block *ublock;
16730                         struct triple **expr;
16731                         use_next = use->next;
16732                         ublock = block_of_triple(state, use->member);
16733                         if ((use->member == phi) || (ublock->vertex != 0)) {
16734                                 continue;
16735                         }
16736                         expr = triple_rhs(state, use->member, 0);
16737                         for(; expr; expr = triple_rhs(state, use->member, expr)) {
16738                                 if (*expr == phi) {
16739                                         *expr = 0;
16740                                 }
16741                         }
16742                         unuse_triple(phi, use->member);
16743                 }
16744                 /* A variable to replace the phi function */
16745                 if (registers_of(state, phi->type) != 1) {
16746                         internal_error(state, phi, "phi->type does not fit in a single register!");
16747                 }
16748                 var = post_triple(state, phi, OP_ADECL, phi->type, 0, 0);
16749                 var = var->next; /* point at the var */
16750                         
16751                 /* Replaces use of phi with var */
16752                 propogate_use(state, phi, var);
16753
16754                 /* Count the readers */
16755                 readers = 0;
16756                 for(use = var->use; use; use = use->next) {
16757                         if (use->member != MISC(var, 0)) {
16758                                 readers++;
16759                         }
16760                 }
16761
16762                 /* Walk all of the incoming edges/blocks and insert moves.
16763                  */
16764                 writers = 0;
16765                 for(edge = 0, set = block->use; set; set = set->next, edge++) {
16766                         struct block *eblock, *vblock;
16767                         struct triple *move;
16768                         struct triple *val, *base;
16769                         eblock = set->member;
16770                         val = slot[edge];
16771                         slot[edge] = 0;
16772                         unuse_triple(val, phi);
16773                         vblock = block_of_triple(state, val);
16774
16775                         /* If we don't have a value that belongs in an OP_WRITE
16776                          * continue on.
16777                          */
16778                         if (!val || (val == &unknown_triple) || (val == phi)
16779                                 || (vblock && (vblock->vertex == 0))) {
16780                                 continue;
16781                         }
16782                         /* If the value should never occur error */
16783                         if (!vblock) {
16784                                 internal_error(state, val, "no vblock?");
16785                                 continue;
16786                         }
16787
16788                         /* If the value occurs in a dead block see if a replacement
16789                          * block can be found.
16790                          */
16791                         while(eblock && (eblock->vertex == 0)) {
16792                                 eblock = eblock->idom;
16793                         }
16794                         /* If not continue on with the next value. */
16795                         if (!eblock || (eblock->vertex == 0)) {
16796                                 continue;
16797                         }
16798
16799                         /* If we have an empty incoming block ignore it. */
16800                         if (!eblock->first) {
16801                                 internal_error(state, 0, "empty block?");
16802                         }
16803                         
16804                         /* Make certain the write is placed in the edge block... */
16805                         /* Walk through the edge block backwards to find an
16806                          * appropriate location for the OP_WRITE.
16807                          */
16808                         for(base = eblock->last; base != eblock->first; base = base->prev) {
16809                                 struct triple **expr;
16810                                 if (base->op == OP_PIECE) {
16811                                         base = MISC(base, 0);
16812                                 }
16813                                 if ((base == var) || (base == val)) {
16814                                         goto out;
16815                                 }
16816                                 expr = triple_lhs(state, base, 0);
16817                                 for(; expr; expr = triple_lhs(state, base, expr)) {
16818                                         if ((*expr) == val) {
16819                                                 goto out;
16820                                         }
16821                                 }
16822                                 expr = triple_rhs(state, base, 0);
16823                                 for(; expr; expr = triple_rhs(state, base, expr)) {
16824                                         if ((*expr) == var) {
16825                                                 goto out;
16826                                         }
16827                                 }
16828                         }
16829                 out:
16830                         if (triple_is_branch(state, base)) {
16831                                 internal_error(state, base,
16832                                         "Could not insert write to phi");
16833                         }
16834                         move = post_triple(state, base, OP_WRITE, var->type, val, var);
16835                         use_triple(val, move);
16836                         use_triple(var, move);
16837                         writers++;
16838                 }
16839                 if (!writers && readers) {
16840                         internal_error(state, var, "no value written to in use phi?");
16841                 }
16842                 /* If var is not used free it */
16843                 if (!writers) {
16844                         release_triple(state, MISC(var, 0));
16845                         release_triple(state, var);
16846                 }
16847                 /* Release the phi function */
16848                 release_triple(state, phi);
16849         }
16850         
16851         /* Walk all of the operations to find the adecls */
16852         for(var = first->next; var != first ; var = var->next) {
16853                 struct triple_set *use, *use_next;
16854                 if (!triple_is_auto_var(state, var)) {
16855                         continue;
16856                 }
16857
16858                 /* Walk through all of the rhs uses of var and
16859                  * replace them with read of var.
16860                  */
16861                 for(use = var->use; use; use = use_next) {
16862                         struct triple *read, *user;
16863                         struct triple **slot;
16864                         int zrhs, i, used;
16865                         use_next = use->next;
16866                         user = use->member;
16867                         
16868                         /* Generate a read of var */
16869                         read = pre_triple(state, user, OP_READ, var->type, var, 0);
16870                         use_triple(var, read);
16871
16872                         /* Find the rhs uses and see if they need to be replaced */
16873                         used = 0;
16874                         zrhs = user->rhs;
16875                         slot = &RHS(user, 0);
16876                         for(i = 0; i < zrhs; i++) {
16877                                 if (slot[i] == var) {
16878                                         slot[i] = read;
16879                                         used = 1;
16880                                 }
16881                         }
16882                         /* If we did use it cleanup the uses */
16883                         if (used) {
16884                                 unuse_triple(var, user);
16885                                 use_triple(read, user);
16886                         } 
16887                         /* If we didn't use it release the extra triple */
16888                         else {
16889                                 release_triple(state, read);
16890                         }
16891                 }
16892         }
16893 }
16894
16895 #define HI() if (state->compiler->debug & DEBUG_REBUILD_SSA_FORM) { \
16896         FILE *fp = state->dbgout; \
16897         fprintf(fp, "@ %s:%d\n", __FILE__, __LINE__); romcc_print_blocks(state, fp); \
16898         } 
16899
16900 static void rebuild_ssa_form(struct compile_state *state)
16901 {
16902 HI();
16903         transform_from_ssa_form(state);
16904 HI();
16905         state->bb.first = state->first;
16906         free_basic_blocks(state, &state->bb);
16907         analyze_basic_blocks(state, &state->bb);
16908 HI();
16909         insert_phi_operations(state);
16910 HI();
16911         rename_variables(state);
16912 HI();
16913         
16914         prune_block_variables(state, state->bb.first_block);
16915 HI();
16916         prune_unused_phis(state);
16917 HI();
16918 }
16919 #undef HI
16920
16921 /* 
16922  * Register conflict resolution
16923  * =========================================================
16924  */
16925
16926 static struct reg_info find_def_color(
16927         struct compile_state *state, struct triple *def)
16928 {
16929         struct triple_set *set;
16930         struct reg_info info;
16931         info.reg = REG_UNSET;
16932         info.regcm = 0;
16933         if (!triple_is_def(state, def)) {
16934                 return info;
16935         }
16936         info = arch_reg_lhs(state, def, 0);
16937         if (info.reg >= MAX_REGISTERS) {
16938                 info.reg = REG_UNSET;
16939         }
16940         for(set = def->use; set; set = set->next) {
16941                 struct reg_info tinfo;
16942                 int i;
16943                 i = find_rhs_use(state, set->member, def);
16944                 if (i < 0) {
16945                         continue;
16946                 }
16947                 tinfo = arch_reg_rhs(state, set->member, i);
16948                 if (tinfo.reg >= MAX_REGISTERS) {
16949                         tinfo.reg = REG_UNSET;
16950                 }
16951                 if ((tinfo.reg != REG_UNSET) && 
16952                         (info.reg != REG_UNSET) &&
16953                         (tinfo.reg != info.reg)) {
16954                         internal_error(state, def, "register conflict");
16955                 }
16956                 if ((info.regcm & tinfo.regcm) == 0) {
16957                         internal_error(state, def, "regcm conflict %x & %x == 0",
16958                                 info.regcm, tinfo.regcm);
16959                 }
16960                 if (info.reg == REG_UNSET) {
16961                         info.reg = tinfo.reg;
16962                 }
16963                 info.regcm &= tinfo.regcm;
16964         }
16965         if (info.reg >= MAX_REGISTERS) {
16966                 internal_error(state, def, "register out of range");
16967         }
16968         return info;
16969 }
16970
16971 static struct reg_info find_lhs_pre_color(
16972         struct compile_state *state, struct triple *ins, int index)
16973 {
16974         struct reg_info info;
16975         int zlhs, zrhs, i;
16976         zrhs = ins->rhs;
16977         zlhs = ins->lhs;
16978         if (!zlhs && triple_is_def(state, ins)) {
16979                 zlhs = 1;
16980         }
16981         if (index >= zlhs) {
16982                 internal_error(state, ins, "Bad lhs %d", index);
16983         }
16984         info = arch_reg_lhs(state, ins, index);
16985         for(i = 0; i < zrhs; i++) {
16986                 struct reg_info rinfo;
16987                 rinfo = arch_reg_rhs(state, ins, i);
16988                 if ((info.reg == rinfo.reg) &&
16989                         (rinfo.reg >= MAX_REGISTERS)) {
16990                         struct reg_info tinfo;
16991                         tinfo = find_lhs_pre_color(state, RHS(ins, index), 0);
16992                         info.reg = tinfo.reg;
16993                         info.regcm &= tinfo.regcm;
16994                         break;
16995                 }
16996         }
16997         if (info.reg >= MAX_REGISTERS) {
16998                 info.reg = REG_UNSET;
16999         }
17000         return info;
17001 }
17002
17003 static struct reg_info find_rhs_post_color(
17004         struct compile_state *state, struct triple *ins, int index);
17005
17006 static struct reg_info find_lhs_post_color(
17007         struct compile_state *state, struct triple *ins, int index)
17008 {
17009         struct triple_set *set;
17010         struct reg_info info;
17011         struct triple *lhs;
17012 #if DEBUG_TRIPLE_COLOR
17013         fprintf(state->errout, "find_lhs_post_color(%p, %d)\n",
17014                 ins, index);
17015 #endif
17016         if ((index == 0) && triple_is_def(state, ins)) {
17017                 lhs = ins;
17018         }
17019         else if (index < ins->lhs) {
17020                 lhs = LHS(ins, index);
17021         }
17022         else {
17023                 internal_error(state, ins, "Bad lhs %d", index);
17024                 lhs = 0;
17025         }
17026         info = arch_reg_lhs(state, ins, index);
17027         if (info.reg >= MAX_REGISTERS) {
17028                 info.reg = REG_UNSET;
17029         }
17030         for(set = lhs->use; set; set = set->next) {
17031                 struct reg_info rinfo;
17032                 struct triple *user;
17033                 int zrhs, i;
17034                 user = set->member;
17035                 zrhs = user->rhs;
17036                 for(i = 0; i < zrhs; i++) {
17037                         if (RHS(user, i) != lhs) {
17038                                 continue;
17039                         }
17040                         rinfo = find_rhs_post_color(state, user, i);
17041                         if ((info.reg != REG_UNSET) &&
17042                                 (rinfo.reg != REG_UNSET) &&
17043                                 (info.reg != rinfo.reg)) {
17044                                 internal_error(state, ins, "register conflict");
17045                         }
17046                         if ((info.regcm & rinfo.regcm) == 0) {
17047                                 internal_error(state, ins, "regcm conflict %x & %x == 0",
17048                                         info.regcm, rinfo.regcm);
17049                         }
17050                         if (info.reg == REG_UNSET) {
17051                                 info.reg = rinfo.reg;
17052                         }
17053                         info.regcm &= rinfo.regcm;
17054                 }
17055         }
17056 #if DEBUG_TRIPLE_COLOR
17057         fprintf(state->errout, "find_lhs_post_color(%p, %d) -> ( %d, %x)\n",
17058                 ins, index, info.reg, info.regcm);
17059 #endif
17060         return info;
17061 }
17062
17063 static struct reg_info find_rhs_post_color(
17064         struct compile_state *state, struct triple *ins, int index)
17065 {
17066         struct reg_info info, rinfo;
17067         int zlhs, i;
17068 #if DEBUG_TRIPLE_COLOR
17069         fprintf(state->errout, "find_rhs_post_color(%p, %d)\n",
17070                 ins, index);
17071 #endif
17072         rinfo = arch_reg_rhs(state, ins, index);
17073         zlhs = ins->lhs;
17074         if (!zlhs && triple_is_def(state, ins)) {
17075                 zlhs = 1;
17076         }
17077         info = rinfo;
17078         if (info.reg >= MAX_REGISTERS) {
17079                 info.reg = REG_UNSET;
17080         }
17081         for(i = 0; i < zlhs; i++) {
17082                 struct reg_info linfo;
17083                 linfo = arch_reg_lhs(state, ins, i);
17084                 if ((linfo.reg == rinfo.reg) &&
17085                         (linfo.reg >= MAX_REGISTERS)) {
17086                         struct reg_info tinfo;
17087                         tinfo = find_lhs_post_color(state, ins, i);
17088                         if (tinfo.reg >= MAX_REGISTERS) {
17089                                 tinfo.reg = REG_UNSET;
17090                         }
17091                         info.regcm &= linfo.regcm;
17092                         info.regcm &= tinfo.regcm;
17093                         if (info.reg != REG_UNSET) {
17094                                 internal_error(state, ins, "register conflict");
17095                         }
17096                         if (info.regcm == 0) {
17097                                 internal_error(state, ins, "regcm conflict");
17098                         }
17099                         info.reg = tinfo.reg;
17100                 }
17101         }
17102 #if DEBUG_TRIPLE_COLOR
17103         fprintf(state->errout, "find_rhs_post_color(%p, %d) -> ( %d, %x)\n",
17104                 ins, index, info.reg, info.regcm);
17105 #endif
17106         return info;
17107 }
17108
17109 static struct reg_info find_lhs_color(
17110         struct compile_state *state, struct triple *ins, int index)
17111 {
17112         struct reg_info pre, post, info;
17113 #if DEBUG_TRIPLE_COLOR
17114         fprintf(state->errout, "find_lhs_color(%p, %d)\n",
17115                 ins, index);
17116 #endif
17117         pre = find_lhs_pre_color(state, ins, index);
17118         post = find_lhs_post_color(state, ins, index);
17119         if ((pre.reg != post.reg) &&
17120                 (pre.reg != REG_UNSET) &&
17121                 (post.reg != REG_UNSET)) {
17122                 internal_error(state, ins, "register conflict");
17123         }
17124         info.regcm = pre.regcm & post.regcm;
17125         info.reg = pre.reg;
17126         if (info.reg == REG_UNSET) {
17127                 info.reg = post.reg;
17128         }
17129 #if DEBUG_TRIPLE_COLOR
17130         fprintf(state->errout, "find_lhs_color(%p, %d) -> ( %d, %x) ... (%d, %x) (%d, %x)\n",
17131                 ins, index, info.reg, info.regcm,
17132                 pre.reg, pre.regcm, post.reg, post.regcm);
17133 #endif
17134         return info;
17135 }
17136
17137 static struct triple *post_copy(struct compile_state *state, struct triple *ins)
17138 {
17139         struct triple_set *entry, *next;
17140         struct triple *out;
17141         struct reg_info info, rinfo;
17142
17143         info = arch_reg_lhs(state, ins, 0);
17144         out = post_triple(state, ins, OP_COPY, ins->type, ins, 0);
17145         use_triple(RHS(out, 0), out);
17146         /* Get the users of ins to use out instead */
17147         for(entry = ins->use; entry; entry = next) {
17148                 int i;
17149                 next = entry->next;
17150                 if (entry->member == out) {
17151                         continue;
17152                 }
17153                 i = find_rhs_use(state, entry->member, ins);
17154                 if (i < 0) {
17155                         continue;
17156                 }
17157                 rinfo = arch_reg_rhs(state, entry->member, i);
17158                 if ((info.reg == REG_UNNEEDED) && (rinfo.reg == REG_UNNEEDED)) {
17159                         continue;
17160                 }
17161                 replace_rhs_use(state, ins, out, entry->member);
17162         }
17163         transform_to_arch_instruction(state, out);
17164         return out;
17165 }
17166
17167 static struct triple *typed_pre_copy(
17168         struct compile_state *state, struct type *type, struct triple *ins, int index)
17169 {
17170         /* Carefully insert enough operations so that I can
17171          * enter any operation with a GPR32.
17172          */
17173         struct triple *in;
17174         struct triple **expr;
17175         unsigned classes;
17176         struct reg_info info;
17177         int op;
17178         if (ins->op == OP_PHI) {
17179                 internal_error(state, ins, "pre_copy on a phi?");
17180         }
17181         classes = arch_type_to_regcm(state, type);
17182         info = arch_reg_rhs(state, ins, index);
17183         expr = &RHS(ins, index);
17184         if ((info.regcm & classes) == 0) {
17185                 FILE *fp = state->errout;
17186                 fprintf(fp, "src_type: ");
17187                 name_of(fp, ins->type);
17188                 fprintf(fp, "\ndst_type: ");
17189                 name_of(fp, type);
17190                 fprintf(fp, "\n");
17191                 internal_error(state, ins, "pre_copy with no register classes");
17192         }
17193         op = OP_COPY;
17194         if (!equiv_types(type, (*expr)->type)) {
17195                 op = OP_CONVERT;
17196         }
17197         in = pre_triple(state, ins, op, type, *expr, 0);
17198         unuse_triple(*expr, ins);
17199         *expr = in;
17200         use_triple(RHS(in, 0), in);
17201         use_triple(in, ins);
17202         transform_to_arch_instruction(state, in);
17203         return in;
17204         
17205 }
17206 static struct triple *pre_copy(
17207         struct compile_state *state, struct triple *ins, int index)
17208 {
17209         return typed_pre_copy(state, RHS(ins, index)->type, ins, index);
17210 }
17211
17212
17213 static void insert_copies_to_phi(struct compile_state *state)
17214 {
17215         /* To get out of ssa form we insert moves on the incoming
17216          * edges to blocks containting phi functions.
17217          */
17218         struct triple *first;
17219         struct triple *phi;
17220
17221         /* Walk all of the operations to find the phi functions */
17222         first = state->first;
17223         for(phi = first->next; phi != first ; phi = phi->next) {
17224                 struct block_set *set;
17225                 struct block *block;
17226                 struct triple **slot, *copy;
17227                 int edge;
17228                 if (phi->op != OP_PHI) {
17229                         continue;
17230                 }
17231                 phi->id |= TRIPLE_FLAG_POST_SPLIT;
17232                 block = phi->u.block;
17233                 slot  = &RHS(phi, 0);
17234                 /* Phi's that feed into mandatory live range joins
17235                  * cause nasty complications.  Insert a copy of
17236                  * the phi value so I never have to deal with
17237                  * that in the rest of the code.
17238                  */
17239                 copy = post_copy(state, phi);
17240                 copy->id |= TRIPLE_FLAG_PRE_SPLIT;
17241                 /* Walk all of the incoming edges/blocks and insert moves.
17242                  */
17243                 for(edge = 0, set = block->use; set; set = set->next, edge++) {
17244                         struct block *eblock;
17245                         struct triple *move;
17246                         struct triple *val;
17247                         struct triple *ptr;
17248                         eblock = set->member;
17249                         val = slot[edge];
17250
17251                         if (val == phi) {
17252                                 continue;
17253                         }
17254
17255                         get_occurance(val->occurance);
17256                         move = build_triple(state, OP_COPY, val->type, val, 0,
17257                                 val->occurance);
17258                         move->u.block = eblock;
17259                         move->id |= TRIPLE_FLAG_PRE_SPLIT;
17260                         use_triple(val, move);
17261                         
17262                         slot[edge] = move;
17263                         unuse_triple(val, phi);
17264                         use_triple(move, phi);
17265
17266                         /* Walk up the dominator tree until I have found the appropriate block */
17267                         while(eblock && !tdominates(state, val, eblock->last)) {
17268                                 eblock = eblock->idom;
17269                         }
17270                         if (!eblock) {
17271                                 internal_error(state, phi, "Cannot find block dominated by %p",
17272                                         val);
17273                         }
17274
17275                         /* Walk through the block backwards to find
17276                          * an appropriate location for the OP_COPY.
17277                          */
17278                         for(ptr = eblock->last; ptr != eblock->first; ptr = ptr->prev) {
17279                                 struct triple **expr;
17280                                 if (ptr->op == OP_PIECE) {
17281                                         ptr = MISC(ptr, 0);
17282                                 }
17283                                 if ((ptr == phi) || (ptr == val)) {
17284                                         goto out;
17285                                 }
17286                                 expr = triple_lhs(state, ptr, 0);
17287                                 for(;expr; expr = triple_lhs(state, ptr, expr)) {
17288                                         if ((*expr) == val) {
17289                                                 goto out;
17290                                         }
17291                                 }
17292                                 expr = triple_rhs(state, ptr, 0);
17293                                 for(;expr; expr = triple_rhs(state, ptr, expr)) {
17294                                         if ((*expr) == phi) {
17295                                                 goto out;
17296                                         }
17297                                 }
17298                         }
17299                 out:
17300                         if (triple_is_branch(state, ptr)) {
17301                                 internal_error(state, ptr,
17302                                         "Could not insert write to phi");
17303                         }
17304                         insert_triple(state, after_lhs(state, ptr), move);
17305                         if (eblock->last == after_lhs(state, ptr)->prev) {
17306                                 eblock->last = move;
17307                         }
17308                         transform_to_arch_instruction(state, move);
17309                 }
17310         }
17311         print_blocks(state, __func__, state->dbgout);
17312 }
17313
17314 struct triple_reg_set;
17315 struct reg_block;
17316
17317
17318 static int do_triple_set(struct triple_reg_set **head, 
17319         struct triple *member, struct triple *new_member)
17320 {
17321         struct triple_reg_set **ptr, *new;
17322         if (!member)
17323                 return 0;
17324         ptr = head;
17325         while(*ptr) {
17326                 if ((*ptr)->member == member) {
17327                         return 0;
17328                 }
17329                 ptr = &(*ptr)->next;
17330         }
17331         new = xcmalloc(sizeof(*new), "triple_set");
17332         new->member = member;
17333         new->new    = new_member;
17334         new->next   = *head;
17335         *head       = new;
17336         return 1;
17337 }
17338
17339 static void do_triple_unset(struct triple_reg_set **head, struct triple *member)
17340 {
17341         struct triple_reg_set *entry, **ptr;
17342         ptr = head;
17343         while(*ptr) {
17344                 entry = *ptr;
17345                 if (entry->member == member) {
17346                         *ptr = entry->next;
17347                         xfree(entry);
17348                         return;
17349                 }
17350                 else {
17351                         ptr = &entry->next;
17352                 }
17353         }
17354 }
17355
17356 static int in_triple(struct reg_block *rb, struct triple *in)
17357 {
17358         return do_triple_set(&rb->in, in, 0);
17359 }
17360
17361 #if DEBUG_ROMCC_WARNING
17362 static void unin_triple(struct reg_block *rb, struct triple *unin)
17363 {
17364         do_triple_unset(&rb->in, unin);
17365 }
17366 #endif
17367
17368 static int out_triple(struct reg_block *rb, struct triple *out)
17369 {
17370         return do_triple_set(&rb->out, out, 0);
17371 }
17372 #if DEBUG_ROMCC_WARNING
17373 static void unout_triple(struct reg_block *rb, struct triple *unout)
17374 {
17375         do_triple_unset(&rb->out, unout);
17376 }
17377 #endif
17378
17379 static int initialize_regblock(struct reg_block *blocks,
17380         struct block *block, int vertex)
17381 {
17382         struct block_set *user;
17383         if (!block || (blocks[block->vertex].block == block)) {
17384                 return vertex;
17385         }
17386         vertex += 1;
17387         /* Renumber the blocks in a convinient fashion */
17388         block->vertex = vertex;
17389         blocks[vertex].block    = block;
17390         blocks[vertex].vertex   = vertex;
17391         for(user = block->use; user; user = user->next) {
17392                 vertex = initialize_regblock(blocks, user->member, vertex);
17393         }
17394         return vertex;
17395 }
17396
17397 static struct triple *part_to_piece(struct compile_state *state, struct triple *ins)
17398 {
17399 /* Part to piece is a best attempt and it cannot be correct all by
17400  * itself.  If various values are read as different sizes in different
17401  * parts of the code this function cannot work.  Or rather it cannot
17402  * work in conjunction with compute_variable_liftimes.  As the
17403  * analysis will get confused.
17404  */
17405         struct triple *base;
17406         unsigned reg;
17407         if (!is_lvalue(state, ins)) {
17408                 return ins;
17409         }
17410         base = 0;
17411         reg = 0;
17412         while(ins && triple_is_part(state, ins) && (ins->op != OP_PIECE)) {
17413                 base = MISC(ins, 0);
17414                 switch(ins->op) {
17415                 case OP_INDEX:
17416                         reg += index_reg_offset(state, base->type, ins->u.cval)/REG_SIZEOF_REG;
17417                         break;
17418                 case OP_DOT:
17419                         reg += field_reg_offset(state, base->type, ins->u.field)/REG_SIZEOF_REG;
17420                         break;
17421                 default:
17422                         internal_error(state, ins, "unhandled part");
17423                         break;
17424                 }
17425                 ins = base;
17426         }
17427         if (base) {
17428                 if (reg > base->lhs) {
17429                         internal_error(state, base, "part out of range?");
17430                 }
17431                 ins = LHS(base, reg);
17432         }
17433         return ins;
17434 }
17435
17436 static int this_def(struct compile_state *state, 
17437         struct triple *ins, struct triple *other)
17438 {
17439         if (ins == other) {
17440                 return 1;
17441         }
17442         if (ins->op == OP_WRITE) {
17443                 ins = part_to_piece(state, MISC(ins, 0));
17444         }
17445         return ins == other;
17446 }
17447
17448 static int phi_in(struct compile_state *state, struct reg_block *blocks,
17449         struct reg_block *rb, struct block *suc)
17450 {
17451         /* Read the conditional input set of a successor block
17452          * (i.e. the input to the phi nodes) and place it in the
17453          * current blocks output set.
17454          */
17455         struct block_set *set;
17456         struct triple *ptr;
17457         int edge;
17458         int done, change;
17459         change = 0;
17460         /* Find the edge I am coming in on */
17461         for(edge = 0, set = suc->use; set; set = set->next, edge++) {
17462                 if (set->member == rb->block) {
17463                         break;
17464                 }
17465         }
17466         if (!set) {
17467                 internal_error(state, 0, "Not coming on a control edge?");
17468         }
17469         for(done = 0, ptr = suc->first; !done; ptr = ptr->next) {
17470                 struct triple **slot, *expr, *ptr2;
17471                 int out_change, done2;
17472                 done = (ptr == suc->last);
17473                 if (ptr->op != OP_PHI) {
17474                         continue;
17475                 }
17476                 slot = &RHS(ptr, 0);
17477                 expr = slot[edge];
17478                 out_change = out_triple(rb, expr);
17479                 if (!out_change) {
17480                         continue;
17481                 }
17482                 /* If we don't define the variable also plast it
17483                  * in the current blocks input set.
17484                  */
17485                 ptr2 = rb->block->first;
17486                 for(done2 = 0; !done2; ptr2 = ptr2->next) {
17487                         if (this_def(state, ptr2, expr)) {
17488                                 break;
17489                         }
17490                         done2 = (ptr2 == rb->block->last);
17491                 }
17492                 if (!done2) {
17493                         continue;
17494                 }
17495                 change |= in_triple(rb, expr);
17496         }
17497         return change;
17498 }
17499
17500 static int reg_in(struct compile_state *state, struct reg_block *blocks,
17501         struct reg_block *rb, struct block *suc)
17502 {
17503         struct triple_reg_set *in_set;
17504         int change;
17505         change = 0;
17506         /* Read the input set of a successor block
17507          * and place it in the current blocks output set.
17508          */
17509         in_set = blocks[suc->vertex].in;
17510         for(; in_set; in_set = in_set->next) {
17511                 int out_change, done;
17512                 struct triple *first, *last, *ptr;
17513                 out_change = out_triple(rb, in_set->member);
17514                 if (!out_change) {
17515                         continue;
17516                 }
17517                 /* If we don't define the variable also place it
17518                  * in the current blocks input set.
17519                  */
17520                 first = rb->block->first;
17521                 last = rb->block->last;
17522                 done = 0;
17523                 for(ptr = first; !done; ptr = ptr->next) {
17524                         if (this_def(state, ptr, in_set->member)) {
17525                                 break;
17526                         }
17527                         done = (ptr == last);
17528                 }
17529                 if (!done) {
17530                         continue;
17531                 }
17532                 change |= in_triple(rb, in_set->member);
17533         }
17534         change |= phi_in(state, blocks, rb, suc);
17535         return change;
17536 }
17537
17538 static int use_in(struct compile_state *state, struct reg_block *rb)
17539 {
17540         /* Find the variables we use but don't define and add
17541          * it to the current blocks input set.
17542          */
17543 #if DEBUG_ROMCC_WARNINGS
17544 #warning "FIXME is this O(N^2) algorithm bad?"
17545 #endif
17546         struct block *block;
17547         struct triple *ptr;
17548         int done;
17549         int change;
17550         block = rb->block;
17551         change = 0;
17552         for(done = 0, ptr = block->last; !done; ptr = ptr->prev) {
17553                 struct triple **expr;
17554                 done = (ptr == block->first);
17555                 /* The variable a phi function uses depends on the
17556                  * control flow, and is handled in phi_in, not
17557                  * here.
17558                  */
17559                 if (ptr->op == OP_PHI) {
17560                         continue;
17561                 }
17562                 expr = triple_rhs(state, ptr, 0);
17563                 for(;expr; expr = triple_rhs(state, ptr, expr)) {
17564                         struct triple *rhs, *test;
17565                         int tdone;
17566                         rhs = part_to_piece(state, *expr);
17567                         if (!rhs) {
17568                                 continue;
17569                         }
17570
17571                         /* See if rhs is defined in this block.
17572                          * A write counts as a definition.
17573                          */
17574                         for(tdone = 0, test = ptr; !tdone; test = test->prev) {
17575                                 tdone = (test == block->first);
17576                                 if (this_def(state, test, rhs)) {
17577                                         rhs = 0;
17578                                         break;
17579                                 }
17580                         }
17581                         /* If I still have a valid rhs add it to in */
17582                         change |= in_triple(rb, rhs);
17583                 }
17584         }
17585         return change;
17586 }
17587
17588 static struct reg_block *compute_variable_lifetimes(
17589         struct compile_state *state, struct basic_blocks *bb)
17590 {
17591         struct reg_block *blocks;
17592         int change;
17593         blocks = xcmalloc(
17594                 sizeof(*blocks)*(bb->last_vertex + 1), "reg_block");
17595         initialize_regblock(blocks, bb->last_block, 0);
17596         do {
17597                 int i;
17598                 change = 0;
17599                 for(i = 1; i <= bb->last_vertex; i++) {
17600                         struct block_set *edge;
17601                         struct reg_block *rb;
17602                         rb = &blocks[i];
17603                         /* Add the all successor's input set to in */
17604                         for(edge = rb->block->edges; edge; edge = edge->next) {
17605                                 change |= reg_in(state, blocks, rb, edge->member);
17606                         }
17607                         /* Add use to in... */
17608                         change |= use_in(state, rb);
17609                 }
17610         } while(change);
17611         return blocks;
17612 }
17613
17614 static void free_variable_lifetimes(struct compile_state *state, 
17615         struct basic_blocks *bb, struct reg_block *blocks)
17616 {
17617         int i;
17618         /* free in_set && out_set on each block */
17619         for(i = 1; i <= bb->last_vertex; i++) {
17620                 struct triple_reg_set *entry, *next;
17621                 struct reg_block *rb;
17622                 rb = &blocks[i];
17623                 for(entry = rb->in; entry ; entry = next) {
17624                         next = entry->next;
17625                         do_triple_unset(&rb->in, entry->member);
17626                 }
17627                 for(entry = rb->out; entry; entry = next) {
17628                         next = entry->next;
17629                         do_triple_unset(&rb->out, entry->member);
17630                 }
17631         }
17632         xfree(blocks);
17633
17634 }
17635
17636 typedef void (*wvl_cb_t)(
17637         struct compile_state *state, 
17638         struct reg_block *blocks, struct triple_reg_set *live, 
17639         struct reg_block *rb, struct triple *ins, void *arg);
17640
17641 static void walk_variable_lifetimes(struct compile_state *state,
17642         struct basic_blocks *bb, struct reg_block *blocks, 
17643         wvl_cb_t cb, void *arg)
17644 {
17645         int i;
17646         
17647         for(i = 1; i <= state->bb.last_vertex; i++) {
17648                 struct triple_reg_set *live;
17649                 struct triple_reg_set *entry, *next;
17650                 struct triple *ptr, *prev;
17651                 struct reg_block *rb;
17652                 struct block *block;
17653                 int done;
17654
17655                 /* Get the blocks */
17656                 rb = &blocks[i];
17657                 block = rb->block;
17658
17659                 /* Copy out into live */
17660                 live = 0;
17661                 for(entry = rb->out; entry; entry = next) {
17662                         next = entry->next;
17663                         do_triple_set(&live, entry->member, entry->new);
17664                 }
17665                 /* Walk through the basic block calculating live */
17666                 for(done = 0, ptr = block->last; !done; ptr = prev) {
17667                         struct triple **expr;
17668
17669                         prev = ptr->prev;
17670                         done = (ptr == block->first);
17671
17672                         /* Ensure the current definition is in live */
17673                         if (triple_is_def(state, ptr)) {
17674                                 do_triple_set(&live, ptr, 0);
17675                         }
17676
17677                         /* Inform the callback function of what is
17678                          * going on.
17679                          */
17680                          cb(state, blocks, live, rb, ptr, arg);
17681                         
17682                         /* Remove the current definition from live */
17683                         do_triple_unset(&live, ptr);
17684
17685                         /* Add the current uses to live.
17686                          *
17687                          * It is safe to skip phi functions because they do
17688                          * not have any block local uses, and the block
17689                          * output sets already properly account for what
17690                          * control flow depedent uses phi functions do have.
17691                          */
17692                         if (ptr->op == OP_PHI) {
17693                                 continue;
17694                         }
17695                         expr = triple_rhs(state, ptr, 0);
17696                         for(;expr; expr = triple_rhs(state, ptr, expr)) {
17697                                 /* If the triple is not a definition skip it. */
17698                                 if (!*expr || !triple_is_def(state, *expr)) {
17699                                         continue;
17700                                 }
17701                                 do_triple_set(&live, *expr, 0);
17702                         }
17703                 }
17704                 /* Free live */
17705                 for(entry = live; entry; entry = next) {
17706                         next = entry->next;
17707                         do_triple_unset(&live, entry->member);
17708                 }
17709         }
17710 }
17711
17712 struct print_live_variable_info {
17713         struct reg_block *rb;
17714         FILE *fp;
17715 };
17716 #if DEBUG_EXPLICIT_CLOSURES
17717 static void print_live_variables_block(
17718         struct compile_state *state, struct block *block, void *arg)
17719
17720 {
17721         struct print_live_variable_info *info = arg;
17722         struct block_set *edge;
17723         FILE *fp = info->fp;
17724         struct reg_block *rb;
17725         struct triple *ptr;
17726         int phi_present;
17727         int done;
17728         rb = &info->rb[block->vertex];
17729
17730         fprintf(fp, "\nblock: %p (%d),",
17731                 block,  block->vertex);
17732         for(edge = block->edges; edge; edge = edge->next) {
17733                 fprintf(fp, " %p<-%p",
17734                         edge->member, 
17735                         edge->member && edge->member->use?edge->member->use->member : 0);
17736         }
17737         fprintf(fp, "\n");
17738         if (rb->in) {
17739                 struct triple_reg_set *in_set;
17740                 fprintf(fp, "        in:");
17741                 for(in_set = rb->in; in_set; in_set = in_set->next) {
17742                         fprintf(fp, " %-10p", in_set->member);
17743                 }
17744                 fprintf(fp, "\n");
17745         }
17746         phi_present = 0;
17747         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
17748                 done = (ptr == block->last);
17749                 if (ptr->op == OP_PHI) {
17750                         phi_present = 1;
17751                         break;
17752                 }
17753         }
17754         if (phi_present) {
17755                 int edge;
17756                 for(edge = 0; edge < block->users; edge++) {
17757                         fprintf(fp, "     in(%d):", edge);
17758                         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
17759                                 struct triple **slot;
17760                                 done = (ptr == block->last);
17761                                 if (ptr->op != OP_PHI) {
17762                                         continue;
17763                                 }
17764                                 slot = &RHS(ptr, 0);
17765                                 fprintf(fp, " %-10p", slot[edge]);
17766                         }
17767                         fprintf(fp, "\n");
17768                 }
17769         }
17770         if (block->first->op == OP_LABEL) {
17771                 fprintf(fp, "%p:\n", block->first);
17772         }
17773         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
17774                 done = (ptr == block->last);
17775                 display_triple(fp, ptr);
17776         }
17777         if (rb->out) {
17778                 struct triple_reg_set *out_set;
17779                 fprintf(fp, "       out:");
17780                 for(out_set = rb->out; out_set; out_set = out_set->next) {
17781                         fprintf(fp, " %-10p", out_set->member);
17782                 }
17783                 fprintf(fp, "\n");
17784         }
17785         fprintf(fp, "\n");
17786 }
17787
17788 static void print_live_variables(struct compile_state *state, 
17789         struct basic_blocks *bb, struct reg_block *rb, FILE *fp)
17790 {
17791         struct print_live_variable_info info;
17792         info.rb = rb;
17793         info.fp = fp;
17794         fprintf(fp, "\nlive variables by block\n");
17795         walk_blocks(state, bb, print_live_variables_block, &info);
17796
17797 }
17798 #endif
17799
17800 static int count_triples(struct compile_state *state)
17801 {
17802         struct triple *first, *ins;
17803         int triples = 0;
17804         first = state->first;
17805         ins = first;
17806         do {
17807                 triples++;
17808                 ins = ins->next;
17809         } while (ins != first);
17810         return triples;
17811 }
17812
17813
17814 struct dead_triple {
17815         struct triple *triple;
17816         struct dead_triple *work_next;
17817         struct block *block;
17818         int old_id;
17819         int flags;
17820 #define TRIPLE_FLAG_ALIVE 1
17821 #define TRIPLE_FLAG_FREE  1
17822 };
17823
17824 static void print_dead_triples(struct compile_state *state, 
17825         struct dead_triple *dtriple)
17826 {
17827         struct triple *first, *ins;
17828         struct dead_triple *dt;
17829         FILE *fp;
17830         if (!(state->compiler->debug & DEBUG_TRIPLES)) {
17831                 return;
17832         }
17833         fp = state->dbgout;
17834         fprintf(fp, "--------------- dtriples ---------------\n");
17835         first = state->first;
17836         ins = first;
17837         do {
17838                 dt = &dtriple[ins->id];
17839                 if ((ins->op == OP_LABEL) && (ins->use)) {
17840                         fprintf(fp, "\n%p:\n", ins);
17841                 }
17842                 fprintf(fp, "%c", 
17843                         (dt->flags & TRIPLE_FLAG_ALIVE)?' ': '-');
17844                 display_triple(fp, ins);
17845                 if (triple_is_branch(state, ins)) {
17846                         fprintf(fp, "\n");
17847                 }
17848                 ins = ins->next;
17849         } while(ins != first);
17850         fprintf(fp, "\n");
17851 }
17852
17853
17854 static void awaken(
17855         struct compile_state *state,
17856         struct dead_triple *dtriple, struct triple **expr,
17857         struct dead_triple ***work_list_tail)
17858 {
17859         struct triple *triple;
17860         struct dead_triple *dt;
17861         if (!expr) {
17862                 return;
17863         }
17864         triple = *expr;
17865         if (!triple) {
17866                 return;
17867         }
17868         if (triple->id <= 0)  {
17869                 internal_error(state, triple, "bad triple id: %d",
17870                         triple->id);
17871         }
17872         if (triple->op == OP_NOOP) {
17873                 internal_error(state, triple, "awakening noop?");
17874                 return;
17875         }
17876         dt = &dtriple[triple->id];
17877         if (!(dt->flags & TRIPLE_FLAG_ALIVE)) {
17878                 dt->flags |= TRIPLE_FLAG_ALIVE;
17879                 if (!dt->work_next) {
17880                         **work_list_tail = dt;
17881                         *work_list_tail = &dt->work_next;
17882                 }
17883         }
17884 }
17885
17886 static void eliminate_inefectual_code(struct compile_state *state)
17887 {
17888         struct block *block;
17889         struct dead_triple *dtriple, *work_list, **work_list_tail, *dt;
17890         int triples, i;
17891         struct triple *first, *final, *ins;
17892
17893         if (!(state->compiler->flags & COMPILER_ELIMINATE_INEFECTUAL_CODE)) {
17894                 return;
17895         }
17896
17897         /* Setup the work list */
17898         work_list = 0;
17899         work_list_tail = &work_list;
17900
17901         first = state->first;
17902         final = state->first->prev;
17903
17904         /* Count how many triples I have */
17905         triples = count_triples(state);
17906
17907         /* Now put then in an array and mark all of the triples dead */
17908         dtriple = xcmalloc(sizeof(*dtriple) * (triples + 1), "dtriples");
17909         
17910         ins = first;
17911         i = 1;
17912         block = 0;
17913         do {
17914                 dtriple[i].triple = ins;
17915                 dtriple[i].block  = block_of_triple(state, ins);
17916                 dtriple[i].flags  = 0;
17917                 dtriple[i].old_id = ins->id;
17918                 ins->id = i;
17919                 /* See if it is an operation we always keep */
17920                 if (!triple_is_pure(state, ins, dtriple[i].old_id)) {
17921                         awaken(state, dtriple, &ins, &work_list_tail);
17922                 }
17923                 i++;
17924                 ins = ins->next;
17925         } while(ins != first);
17926         while(work_list) {
17927                 struct block *block;
17928                 struct dead_triple *dt;
17929                 struct block_set *user;
17930                 struct triple **expr;
17931                 dt = work_list;
17932                 work_list = dt->work_next;
17933                 if (!work_list) {
17934                         work_list_tail = &work_list;
17935                 }
17936                 /* Make certain the block the current instruction is in lives */
17937                 block = block_of_triple(state, dt->triple);
17938                 awaken(state, dtriple, &block->first, &work_list_tail);
17939                 if (triple_is_branch(state, block->last)) {
17940                         awaken(state, dtriple, &block->last, &work_list_tail);
17941                 } else {
17942                         awaken(state, dtriple, &block->last->next, &work_list_tail);
17943                 }
17944
17945                 /* Wake up the data depencencies of this triple */
17946                 expr = 0;
17947                 do {
17948                         expr = triple_rhs(state, dt->triple, expr);
17949                         awaken(state, dtriple, expr, &work_list_tail);
17950                 } while(expr);
17951                 do {
17952                         expr = triple_lhs(state, dt->triple, expr);
17953                         awaken(state, dtriple, expr, &work_list_tail);
17954                 } while(expr);
17955                 do {
17956                         expr = triple_misc(state, dt->triple, expr);
17957                         awaken(state, dtriple, expr, &work_list_tail);
17958                 } while(expr);
17959                 /* Wake up the forward control dependencies */
17960                 do {
17961                         expr = triple_targ(state, dt->triple, expr);
17962                         awaken(state, dtriple, expr, &work_list_tail);
17963                 } while(expr);
17964                 /* Wake up the reverse control dependencies of this triple */
17965                 for(user = dt->block->ipdomfrontier; user; user = user->next) {
17966                         struct triple *last;
17967                         last = user->member->last;
17968                         while((last->op == OP_NOOP) && (last != user->member->first)) {
17969 #if DEBUG_ROMCC_WARNINGS
17970 #warning "Should we bring the awakening noops back?"
17971 #endif
17972                                 // internal_warning(state, last, "awakening noop?");
17973                                 last = last->prev;
17974                         }
17975                         awaken(state, dtriple, &last, &work_list_tail);
17976                 }
17977         }
17978         print_dead_triples(state, dtriple);
17979         for(dt = &dtriple[1]; dt <= &dtriple[triples]; dt++) {
17980                 if ((dt->triple->op == OP_NOOP) && 
17981                         (dt->flags & TRIPLE_FLAG_ALIVE)) {
17982                         internal_error(state, dt->triple, "noop effective?");
17983                 }
17984                 dt->triple->id = dt->old_id;    /* Restore the color */
17985                 if (!(dt->flags & TRIPLE_FLAG_ALIVE)) {
17986                         release_triple(state, dt->triple);
17987                 }
17988         }
17989         xfree(dtriple);
17990
17991         rebuild_ssa_form(state);
17992
17993         print_blocks(state, __func__, state->dbgout);
17994 }
17995
17996
17997 static void insert_mandatory_copies(struct compile_state *state)
17998 {
17999         struct triple *ins, *first;
18000
18001         /* The object is with a minimum of inserted copies,
18002          * to resolve in fundamental register conflicts between
18003          * register value producers and consumers.
18004          * Theoretically we may be greater than minimal when we
18005          * are inserting copies before instructions but that
18006          * case should be rare.
18007          */
18008         first = state->first;
18009         ins = first;
18010         do {
18011                 struct triple_set *entry, *next;
18012                 struct triple *tmp;
18013                 struct reg_info info;
18014                 unsigned reg, regcm;
18015                 int do_post_copy, do_pre_copy;
18016                 tmp = 0;
18017                 if (!triple_is_def(state, ins)) {
18018                         goto next;
18019                 }
18020                 /* Find the architecture specific color information */
18021                 info = find_lhs_pre_color(state, ins, 0);
18022                 if (info.reg >= MAX_REGISTERS) {
18023                         info.reg = REG_UNSET;
18024                 }
18025
18026                 reg = REG_UNSET;
18027                 regcm = arch_type_to_regcm(state, ins->type);
18028                 do_post_copy = do_pre_copy = 0;
18029
18030                 /* Walk through the uses of ins and check for conflicts */
18031                 for(entry = ins->use; entry; entry = next) {
18032                         struct reg_info rinfo;
18033                         int i;
18034                         next = entry->next;
18035                         i = find_rhs_use(state, entry->member, ins);
18036                         if (i < 0) {
18037                                 continue;
18038                         }
18039                         
18040                         /* Find the users color requirements */
18041                         rinfo = arch_reg_rhs(state, entry->member, i);
18042                         if (rinfo.reg >= MAX_REGISTERS) {
18043                                 rinfo.reg = REG_UNSET;
18044                         }
18045                         
18046                         /* See if I need a pre_copy */
18047                         if (rinfo.reg != REG_UNSET) {
18048                                 if ((reg != REG_UNSET) && (reg != rinfo.reg)) {
18049                                         do_pre_copy = 1;
18050                                 }
18051                                 reg = rinfo.reg;
18052                         }
18053                         regcm &= rinfo.regcm;
18054                         regcm = arch_regcm_normalize(state, regcm);
18055                         if (regcm == 0) {
18056                                 do_pre_copy = 1;
18057                         }
18058                         /* Always use pre_copies for constants.
18059                          * They do not take up any registers until a
18060                          * copy places them in one.
18061                          */
18062                         if ((info.reg == REG_UNNEEDED) && 
18063                                 (rinfo.reg != REG_UNNEEDED)) {
18064                                 do_pre_copy = 1;
18065                         }
18066                 }
18067                 do_post_copy =
18068                         !do_pre_copy &&
18069                         (((info.reg != REG_UNSET) && 
18070                                 (reg != REG_UNSET) &&
18071                                 (info.reg != reg)) ||
18072                         ((info.regcm & regcm) == 0));
18073
18074                 reg = info.reg;
18075                 regcm = info.regcm;
18076                 /* Walk through the uses of ins and do a pre_copy or see if a post_copy is warranted */
18077                 for(entry = ins->use; entry; entry = next) {
18078                         struct reg_info rinfo;
18079                         int i;
18080                         next = entry->next;
18081                         i = find_rhs_use(state, entry->member, ins);
18082                         if (i < 0) {
18083                                 continue;
18084                         }
18085                         
18086                         /* Find the users color requirements */
18087                         rinfo = arch_reg_rhs(state, entry->member, i);
18088                         if (rinfo.reg >= MAX_REGISTERS) {
18089                                 rinfo.reg = REG_UNSET;
18090                         }
18091
18092                         /* Now see if it is time to do the pre_copy */
18093                         if (rinfo.reg != REG_UNSET) {
18094                                 if (((reg != REG_UNSET) && (reg != rinfo.reg)) ||
18095                                         ((regcm & rinfo.regcm) == 0) ||
18096                                         /* Don't let a mandatory coalesce sneak
18097                                          * into a operation that is marked to prevent
18098                                          * coalescing.
18099                                          */
18100                                         ((reg != REG_UNNEEDED) &&
18101                                         ((ins->id & TRIPLE_FLAG_POST_SPLIT) ||
18102                                         (entry->member->id & TRIPLE_FLAG_PRE_SPLIT)))
18103                                         ) {
18104                                         if (do_pre_copy) {
18105                                                 struct triple *user;
18106                                                 user = entry->member;
18107                                                 if (RHS(user, i) != ins) {
18108                                                         internal_error(state, user, "bad rhs");
18109                                                 }
18110                                                 tmp = pre_copy(state, user, i);
18111                                                 tmp->id |= TRIPLE_FLAG_PRE_SPLIT;
18112                                                 continue;
18113                                         } else {
18114                                                 do_post_copy = 1;
18115                                         }
18116                                 }
18117                                 reg = rinfo.reg;
18118                         }
18119                         if ((regcm & rinfo.regcm) == 0) {
18120                                 if (do_pre_copy) {
18121                                         struct triple *user;
18122                                         user = entry->member;
18123                                         if (RHS(user, i) != ins) {
18124                                                 internal_error(state, user, "bad rhs");
18125                                         }
18126                                         tmp = pre_copy(state, user, i);
18127                                         tmp->id |= TRIPLE_FLAG_PRE_SPLIT;
18128                                         continue;
18129                                 } else {
18130                                         do_post_copy = 1;
18131                                 }
18132                         }
18133                         regcm &= rinfo.regcm;
18134                         
18135                 }
18136                 if (do_post_copy) {
18137                         struct reg_info pre, post;
18138                         tmp = post_copy(state, ins);
18139                         tmp->id |= TRIPLE_FLAG_PRE_SPLIT;
18140                         pre = arch_reg_lhs(state, ins, 0);
18141                         post = arch_reg_lhs(state, tmp, 0);
18142                         if ((pre.reg == post.reg) && (pre.regcm == post.regcm)) {
18143                                 internal_error(state, tmp, "useless copy");
18144                         }
18145                 }
18146         next:
18147                 ins = ins->next;
18148         } while(ins != first);
18149
18150         print_blocks(state, __func__, state->dbgout);
18151 }
18152
18153
18154 struct live_range_edge;
18155 struct live_range_def;
18156 struct live_range {
18157         struct live_range_edge *edges;
18158         struct live_range_def *defs;
18159 /* Note. The list pointed to by defs is kept in order.
18160  * That is baring splits in the flow control
18161  * defs dominates defs->next wich dominates defs->next->next
18162  * etc.
18163  */
18164         unsigned color;
18165         unsigned classes;
18166         unsigned degree;
18167         unsigned length;
18168         struct live_range *group_next, **group_prev;
18169 };
18170
18171 struct live_range_edge {
18172         struct live_range_edge *next;
18173         struct live_range *node;
18174 };
18175
18176 struct live_range_def {
18177         struct live_range_def *next;
18178         struct live_range_def *prev;
18179         struct live_range *lr;
18180         struct triple *def;
18181         unsigned orig_id;
18182 };
18183
18184 #define LRE_HASH_SIZE 2048
18185 struct lre_hash {
18186         struct lre_hash *next;
18187         struct live_range *left;
18188         struct live_range *right;
18189 };
18190
18191
18192 struct reg_state {
18193         struct lre_hash *hash[LRE_HASH_SIZE];
18194         struct reg_block *blocks;
18195         struct live_range_def *lrd;
18196         struct live_range *lr;
18197         struct live_range *low, **low_tail;
18198         struct live_range *high, **high_tail;
18199         unsigned defs;
18200         unsigned ranges;
18201         int passes, max_passes;
18202 };
18203
18204
18205 struct print_interference_block_info {
18206         struct reg_state *rstate;
18207         FILE *fp;
18208         int need_edges;
18209 };
18210 static void print_interference_block(
18211         struct compile_state *state, struct block *block, void *arg)
18212
18213 {
18214         struct print_interference_block_info *info = arg;
18215         struct reg_state *rstate = info->rstate;
18216         struct block_set *edge;
18217         FILE *fp = info->fp;
18218         struct reg_block *rb;
18219         struct triple *ptr;
18220         int phi_present;
18221         int done;
18222         rb = &rstate->blocks[block->vertex];
18223
18224         fprintf(fp, "\nblock: %p (%d),",
18225                 block,  block->vertex);
18226         for(edge = block->edges; edge; edge = edge->next) {
18227                 fprintf(fp, " %p<-%p",
18228                         edge->member, 
18229                         edge->member && edge->member->use?edge->member->use->member : 0);
18230         }
18231         fprintf(fp, "\n");
18232         if (rb->in) {
18233                 struct triple_reg_set *in_set;
18234                 fprintf(fp, "        in:");
18235                 for(in_set = rb->in; in_set; in_set = in_set->next) {
18236                         fprintf(fp, " %-10p", in_set->member);
18237                 }
18238                 fprintf(fp, "\n");
18239         }
18240         phi_present = 0;
18241         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
18242                 done = (ptr == block->last);
18243                 if (ptr->op == OP_PHI) {
18244                         phi_present = 1;
18245                         break;
18246                 }
18247         }
18248         if (phi_present) {
18249                 int edge;
18250                 for(edge = 0; edge < block->users; edge++) {
18251                         fprintf(fp, "     in(%d):", edge);
18252                         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
18253                                 struct triple **slot;
18254                                 done = (ptr == block->last);
18255                                 if (ptr->op != OP_PHI) {
18256                                         continue;
18257                                 }
18258                                 slot = &RHS(ptr, 0);
18259                                 fprintf(fp, " %-10p", slot[edge]);
18260                         }
18261                         fprintf(fp, "\n");
18262                 }
18263         }
18264         if (block->first->op == OP_LABEL) {
18265                 fprintf(fp, "%p:\n", block->first);
18266         }
18267         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
18268                 struct live_range *lr;
18269                 unsigned id;
18270                 int op;
18271                 op = ptr->op;
18272                 done = (ptr == block->last);
18273                 lr = rstate->lrd[ptr->id].lr;
18274                 
18275                 id = ptr->id;
18276                 ptr->id = rstate->lrd[id].orig_id;
18277                 SET_REG(ptr->id, lr->color);
18278                 display_triple(fp, ptr);
18279                 ptr->id = id;
18280
18281                 if (triple_is_def(state, ptr) && (lr->defs == 0)) {
18282                         internal_error(state, ptr, "lr has no defs!");
18283                 }
18284                 if (info->need_edges) {
18285                         if (lr->defs) {
18286                                 struct live_range_def *lrd;
18287                                 fprintf(fp, "       range:");
18288                                 lrd = lr->defs;
18289                                 do {
18290                                         fprintf(fp, " %-10p", lrd->def);
18291                                         lrd = lrd->next;
18292                                 } while(lrd != lr->defs);
18293                                 fprintf(fp, "\n");
18294                         }
18295                         if (lr->edges > 0) {
18296                                 struct live_range_edge *edge;
18297                                 fprintf(fp, "       edges:");
18298                                 for(edge = lr->edges; edge; edge = edge->next) {
18299                                         struct live_range_def *lrd;
18300                                         lrd = edge->node->defs;
18301                                         do {
18302                                                 fprintf(fp, " %-10p", lrd->def);
18303                                                 lrd = lrd->next;
18304                                         } while(lrd != edge->node->defs);
18305                                         fprintf(fp, "|");
18306                                 }
18307                                 fprintf(fp, "\n");
18308                         }
18309                 }
18310                 /* Do a bunch of sanity checks */
18311                 valid_ins(state, ptr);
18312                 if ((ptr->id < 0) || (ptr->id > rstate->defs)) {
18313                         internal_error(state, ptr, "Invalid triple id: %d",
18314                                 ptr->id);
18315                 }
18316         }
18317         if (rb->out) {
18318                 struct triple_reg_set *out_set;
18319                 fprintf(fp, "       out:");
18320                 for(out_set = rb->out; out_set; out_set = out_set->next) {
18321                         fprintf(fp, " %-10p", out_set->member);
18322                 }
18323                 fprintf(fp, "\n");
18324         }
18325         fprintf(fp, "\n");
18326 }
18327
18328 static void print_interference_blocks(
18329         struct compile_state *state, struct reg_state *rstate, FILE *fp, int need_edges)
18330 {
18331         struct print_interference_block_info info;
18332         info.rstate = rstate;
18333         info.fp = fp;
18334         info.need_edges = need_edges;
18335         fprintf(fp, "\nlive variables by block\n");
18336         walk_blocks(state, &state->bb, print_interference_block, &info);
18337
18338 }
18339
18340 static unsigned regc_max_size(struct compile_state *state, int classes)
18341 {
18342         unsigned max_size;
18343         int i;
18344         max_size = 0;
18345         for(i = 0; i < MAX_REGC; i++) {
18346                 if (classes & (1 << i)) {
18347                         unsigned size;
18348                         size = arch_regc_size(state, i);
18349                         if (size > max_size) {
18350                                 max_size = size;
18351                         }
18352                 }
18353         }
18354         return max_size;
18355 }
18356
18357 static int reg_is_reg(struct compile_state *state, int reg1, int reg2)
18358 {
18359         unsigned equivs[MAX_REG_EQUIVS];
18360         int i;
18361         if ((reg1 < 0) || (reg1 >= MAX_REGISTERS)) {
18362                 internal_error(state, 0, "invalid register");
18363         }
18364         if ((reg2 < 0) || (reg2 >= MAX_REGISTERS)) {
18365                 internal_error(state, 0, "invalid register");
18366         }
18367         arch_reg_equivs(state, equivs, reg1);
18368         for(i = 0; (i < MAX_REG_EQUIVS) && equivs[i] != REG_UNSET; i++) {
18369                 if (equivs[i] == reg2) {
18370                         return 1;
18371                 }
18372         }
18373         return 0;
18374 }
18375
18376 static void reg_fill_used(struct compile_state *state, char *used, int reg)
18377 {
18378         unsigned equivs[MAX_REG_EQUIVS];
18379         int i;
18380         if (reg == REG_UNNEEDED) {
18381                 return;
18382         }
18383         arch_reg_equivs(state, equivs, reg);
18384         for(i = 0; (i < MAX_REG_EQUIVS) && equivs[i] != REG_UNSET; i++) {
18385                 used[equivs[i]] = 1;
18386         }
18387         return;
18388 }
18389
18390 static void reg_inc_used(struct compile_state *state, char *used, int reg)
18391 {
18392         unsigned equivs[MAX_REG_EQUIVS];
18393         int i;
18394         if (reg == REG_UNNEEDED) {
18395                 return;
18396         }
18397         arch_reg_equivs(state, equivs, reg);
18398         for(i = 0; (i < MAX_REG_EQUIVS) && equivs[i] != REG_UNSET; i++) {
18399                 used[equivs[i]] += 1;
18400         }
18401         return;
18402 }
18403
18404 static unsigned int hash_live_edge(
18405         struct live_range *left, struct live_range *right)
18406 {
18407         unsigned int hash, val;
18408         unsigned long lval, rval;
18409         lval = ((unsigned long)left)/sizeof(struct live_range);
18410         rval = ((unsigned long)right)/sizeof(struct live_range);
18411         hash = 0;
18412         while(lval) {
18413                 val = lval & 0xff;
18414                 lval >>= 8;
18415                 hash = (hash *263) + val;
18416         }
18417         while(rval) {
18418                 val = rval & 0xff;
18419                 rval >>= 8;
18420                 hash = (hash *263) + val;
18421         }
18422         hash = hash & (LRE_HASH_SIZE - 1);
18423         return hash;
18424 }
18425
18426 static struct lre_hash **lre_probe(struct reg_state *rstate,
18427         struct live_range *left, struct live_range *right)
18428 {
18429         struct lre_hash **ptr;
18430         unsigned int index;
18431         /* Ensure left <= right */
18432         if (left > right) {
18433                 struct live_range *tmp;
18434                 tmp = left;
18435                 left = right;
18436                 right = tmp;
18437         }
18438         index = hash_live_edge(left, right);
18439         
18440         ptr = &rstate->hash[index];
18441         while(*ptr) {
18442                 if (((*ptr)->left == left) && ((*ptr)->right == right)) {
18443                         break;
18444                 }
18445                 ptr = &(*ptr)->next;
18446         }
18447         return ptr;
18448 }
18449
18450 static int interfere(struct reg_state *rstate,
18451         struct live_range *left, struct live_range *right)
18452 {
18453         struct lre_hash **ptr;
18454         ptr = lre_probe(rstate, left, right);
18455         return ptr && *ptr;
18456 }
18457
18458 static void add_live_edge(struct reg_state *rstate, 
18459         struct live_range *left, struct live_range *right)
18460 {
18461         /* FIXME the memory allocation overhead is noticeable here... */
18462         struct lre_hash **ptr, *new_hash;
18463         struct live_range_edge *edge;
18464
18465         if (left == right) {
18466                 return;
18467         }
18468         if ((left == &rstate->lr[0]) || (right == &rstate->lr[0])) {
18469                 return;
18470         }
18471         /* Ensure left <= right */
18472         if (left > right) {
18473                 struct live_range *tmp;
18474                 tmp = left;
18475                 left = right;
18476                 right = tmp;
18477         }
18478         ptr = lre_probe(rstate, left, right);
18479         if (*ptr) {
18480                 return;
18481         }
18482 #if 0
18483         fprintf(state->errout, "new_live_edge(%p, %p)\n",
18484                 left, right);
18485 #endif
18486         new_hash = xmalloc(sizeof(*new_hash), "lre_hash");
18487         new_hash->next  = *ptr;
18488         new_hash->left  = left;
18489         new_hash->right = right;
18490         *ptr = new_hash;
18491
18492         edge = xmalloc(sizeof(*edge), "live_range_edge");
18493         edge->next   = left->edges;
18494         edge->node   = right;
18495         left->edges  = edge;
18496         left->degree += 1;
18497         
18498         edge = xmalloc(sizeof(*edge), "live_range_edge");
18499         edge->next    = right->edges;
18500         edge->node    = left;
18501         right->edges  = edge;
18502         right->degree += 1;
18503 }
18504
18505 static void remove_live_edge(struct reg_state *rstate,
18506         struct live_range *left, struct live_range *right)
18507 {
18508         struct live_range_edge *edge, **ptr;
18509         struct lre_hash **hptr, *entry;
18510         hptr = lre_probe(rstate, left, right);
18511         if (!hptr || !*hptr) {
18512                 return;
18513         }
18514         entry = *hptr;
18515         *hptr = entry->next;
18516         xfree(entry);
18517
18518         for(ptr = &left->edges; *ptr; ptr = &(*ptr)->next) {
18519                 edge = *ptr;
18520                 if (edge->node == right) {
18521                         *ptr = edge->next;
18522                         memset(edge, 0, sizeof(*edge));
18523                         xfree(edge);
18524                         right->degree--;
18525                         break;
18526                 }
18527         }
18528         for(ptr = &right->edges; *ptr; ptr = &(*ptr)->next) {
18529                 edge = *ptr;
18530                 if (edge->node == left) {
18531                         *ptr = edge->next;
18532                         memset(edge, 0, sizeof(*edge));
18533                         xfree(edge);
18534                         left->degree--;
18535                         break;
18536                 }
18537         }
18538 }
18539
18540 static void remove_live_edges(struct reg_state *rstate, struct live_range *range)
18541 {
18542         struct live_range_edge *edge, *next;
18543         for(edge = range->edges; edge; edge = next) {
18544                 next = edge->next;
18545                 remove_live_edge(rstate, range, edge->node);
18546         }
18547 }
18548
18549 static void transfer_live_edges(struct reg_state *rstate, 
18550         struct live_range *dest, struct live_range *src)
18551 {
18552         struct live_range_edge *edge, *next;
18553         for(edge = src->edges; edge; edge = next) {
18554                 struct live_range *other;
18555                 next = edge->next;
18556                 other = edge->node;
18557                 remove_live_edge(rstate, src, other);
18558                 add_live_edge(rstate, dest, other);
18559         }
18560 }
18561
18562
18563 /* Interference graph...
18564  * 
18565  * new(n) --- Return a graph with n nodes but no edges.
18566  * add(g,x,y) --- Return a graph including g with an between x and y
18567  * interfere(g, x, y) --- Return true if there exists an edge between the nodes
18568  *                x and y in the graph g
18569  * degree(g, x) --- Return the degree of the node x in the graph g
18570  * neighbors(g, x, f) --- Apply function f to each neighbor of node x in the graph g
18571  *
18572  * Implement with a hash table && a set of adjcency vectors.
18573  * The hash table supports constant time implementations of add and interfere.
18574  * The adjacency vectors support an efficient implementation of neighbors.
18575  */
18576
18577 /* 
18578  *     +---------------------------------------------------+
18579  *     |         +--------------+                          |
18580  *     v         v              |                          |
18581  * renumber -> build graph -> colalesce -> spill_costs -> simplify -> select 
18582  *
18583  * -- In simplify implment optimistic coloring... (No backtracking)
18584  * -- Implement Rematerialization it is the only form of spilling we can perform
18585  *    Essentially this means dropping a constant from a register because
18586  *    we can regenerate it later.
18587  *
18588  * --- Very conservative colalescing (don't colalesce just mark the opportunities)
18589  *     coalesce at phi points...
18590  * --- Bias coloring if at all possible do the coalesing a compile time.
18591  *
18592  *
18593  */
18594
18595 #if DEBUG_ROMCC_WARNING
18596 static void different_colored(
18597         struct compile_state *state, struct reg_state *rstate, 
18598         struct triple *parent, struct triple *ins)
18599 {
18600         struct live_range *lr;
18601         struct triple **expr;
18602         lr = rstate->lrd[ins->id].lr;
18603         expr = triple_rhs(state, ins, 0);
18604         for(;expr; expr = triple_rhs(state, ins, expr)) {
18605                 struct live_range *lr2;
18606                 if (!*expr || (*expr == parent) || (*expr == ins)) {
18607                         continue;
18608                 }
18609                 lr2 = rstate->lrd[(*expr)->id].lr;
18610                 if (lr->color == lr2->color) {
18611                         internal_error(state, ins, "live range too big");
18612                 }
18613         }
18614 }
18615 #endif
18616
18617 static struct live_range *coalesce_ranges(
18618         struct compile_state *state, struct reg_state *rstate,
18619         struct live_range *lr1, struct live_range *lr2)
18620 {
18621         struct live_range_def *head, *mid1, *mid2, *end, *lrd;
18622         unsigned color;
18623         unsigned classes;
18624         if (lr1 == lr2) {
18625                 return lr1;
18626         }
18627         if (!lr1->defs || !lr2->defs) {
18628                 internal_error(state, 0,
18629                         "cannot coalese dead live ranges");
18630         }
18631         if ((lr1->color == REG_UNNEEDED) ||
18632                 (lr2->color == REG_UNNEEDED)) {
18633                 internal_error(state, 0, 
18634                         "cannot coalesce live ranges without a possible color");
18635         }
18636         if ((lr1->color != lr2->color) &&
18637                 (lr1->color != REG_UNSET) &&
18638                 (lr2->color != REG_UNSET)) {
18639                 internal_error(state, lr1->defs->def, 
18640                         "cannot coalesce live ranges of different colors");
18641         }
18642         color = lr1->color;
18643         if (color == REG_UNSET) {
18644                 color = lr2->color;
18645         }
18646         classes = lr1->classes & lr2->classes;
18647         if (!classes) {
18648                 internal_error(state, lr1->defs->def,
18649                         "cannot coalesce live ranges with dissimilar register classes");
18650         }
18651         if (state->compiler->debug & DEBUG_COALESCING) {
18652                 FILE *fp = state->errout;
18653                 fprintf(fp, "coalescing:");
18654                 lrd = lr1->defs;
18655                 do {
18656                         fprintf(fp, " %p", lrd->def);
18657                         lrd = lrd->next;
18658                 } while(lrd != lr1->defs);
18659                 fprintf(fp, " |");
18660                 lrd = lr2->defs;
18661                 do {
18662                         fprintf(fp, " %p", lrd->def);
18663                         lrd = lrd->next;
18664                 } while(lrd != lr2->defs);
18665                 fprintf(fp, "\n");
18666         }
18667         /* If there is a clear dominate live range put it in lr1,
18668          * For purposes of this test phi functions are
18669          * considered dominated by the definitions that feed into
18670          * them. 
18671          */
18672         if ((lr1->defs->prev->def->op == OP_PHI) ||
18673                 ((lr2->defs->prev->def->op != OP_PHI) &&
18674                 tdominates(state, lr2->defs->def, lr1->defs->def))) {
18675                 struct live_range *tmp;
18676                 tmp = lr1;
18677                 lr1 = lr2;
18678                 lr2 = tmp;
18679         }
18680 #if 0
18681         if (lr1->defs->orig_id  & TRIPLE_FLAG_POST_SPLIT) {
18682                 fprintf(state->errout, "lr1 post\n");
18683         }
18684         if (lr1->defs->orig_id & TRIPLE_FLAG_PRE_SPLIT) {
18685                 fprintf(state->errout, "lr1 pre\n");
18686         }
18687         if (lr2->defs->orig_id  & TRIPLE_FLAG_POST_SPLIT) {
18688                 fprintf(state->errout, "lr2 post\n");
18689         }
18690         if (lr2->defs->orig_id & TRIPLE_FLAG_PRE_SPLIT) {
18691                 fprintf(state->errout, "lr2 pre\n");
18692         }
18693 #endif
18694 #if 0
18695         fprintf(state->errout, "coalesce color1(%p): %3d color2(%p) %3d\n",
18696                 lr1->defs->def,
18697                 lr1->color,
18698                 lr2->defs->def,
18699                 lr2->color);
18700 #endif
18701         
18702         /* Append lr2 onto lr1 */
18703 #if DEBUG_ROMCC_WARNINGS
18704 #warning "FIXME should this be a merge instead of a splice?"
18705 #endif
18706         /* This FIXME item applies to the correctness of live_range_end 
18707          * and to the necessity of making multiple passes of coalesce_live_ranges.
18708          * A failure to find some coalesce opportunities in coaleace_live_ranges
18709          * does not impact the correct of the compiler just the efficiency with
18710          * which registers are allocated.
18711          */
18712         head = lr1->defs;
18713         mid1 = lr1->defs->prev;
18714         mid2 = lr2->defs;
18715         end  = lr2->defs->prev;
18716         
18717         head->prev = end;
18718         end->next  = head;
18719
18720         mid1->next = mid2;
18721         mid2->prev = mid1;
18722
18723         /* Fixup the live range in the added live range defs */
18724         lrd = head;
18725         do {
18726                 lrd->lr = lr1;
18727                 lrd = lrd->next;
18728         } while(lrd != head);
18729
18730         /* Mark lr2 as free. */
18731         lr2->defs = 0;
18732         lr2->color = REG_UNNEEDED;
18733         lr2->classes = 0;
18734
18735         if (!lr1->defs) {
18736                 internal_error(state, 0, "lr1->defs == 0 ?");
18737         }
18738
18739         lr1->color   = color;
18740         lr1->classes = classes;
18741
18742         /* Keep the graph in sync by transfering the edges from lr2 to lr1 */
18743         transfer_live_edges(rstate, lr1, lr2);
18744
18745         return lr1;
18746 }
18747
18748 static struct live_range_def *live_range_head(
18749         struct compile_state *state, struct live_range *lr,
18750         struct live_range_def *last)
18751 {
18752         struct live_range_def *result;
18753         result = 0;
18754         if (last == 0) {
18755                 result = lr->defs;
18756         }
18757         else if (!tdominates(state, lr->defs->def, last->next->def)) {
18758                 result = last->next;
18759         }
18760         return result;
18761 }
18762
18763 static struct live_range_def *live_range_end(
18764         struct compile_state *state, struct live_range *lr,
18765         struct live_range_def *last)
18766 {
18767         struct live_range_def *result;
18768         result = 0;
18769         if (last == 0) {
18770                 result = lr->defs->prev;
18771         }
18772         else if (!tdominates(state, last->prev->def, lr->defs->prev->def)) {
18773                 result = last->prev;
18774         }
18775         return result;
18776 }
18777
18778
18779 static void initialize_live_ranges(
18780         struct compile_state *state, struct reg_state *rstate)
18781 {
18782         struct triple *ins, *first;
18783         size_t count, size;
18784         int i, j;
18785
18786         first = state->first;
18787         /* First count how many instructions I have.
18788          */
18789         count = count_triples(state);
18790         /* Potentially I need one live range definitions for each
18791          * instruction.
18792          */
18793         rstate->defs = count;
18794         /* Potentially I need one live range for each instruction
18795          * plus an extra for the dummy live range.
18796          */
18797         rstate->ranges = count + 1;
18798         size = sizeof(rstate->lrd[0]) * rstate->defs;
18799         rstate->lrd = xcmalloc(size, "live_range_def");
18800         size = sizeof(rstate->lr[0]) * rstate->ranges;
18801         rstate->lr  = xcmalloc(size, "live_range");
18802
18803         /* Setup the dummy live range */
18804         rstate->lr[0].classes = 0;
18805         rstate->lr[0].color = REG_UNSET;
18806         rstate->lr[0].defs = 0;
18807         i = j = 0;
18808         ins = first;
18809         do {
18810                 /* If the triple is a variable give it a live range */
18811                 if (triple_is_def(state, ins)) {
18812                         struct reg_info info;
18813                         /* Find the architecture specific color information */
18814                         info = find_def_color(state, ins);
18815                         i++;
18816                         rstate->lr[i].defs    = &rstate->lrd[j];
18817                         rstate->lr[i].color   = info.reg;
18818                         rstate->lr[i].classes = info.regcm;
18819                         rstate->lr[i].degree  = 0;
18820                         rstate->lrd[j].lr = &rstate->lr[i];
18821                 } 
18822                 /* Otherwise give the triple the dummy live range. */
18823                 else {
18824                         rstate->lrd[j].lr = &rstate->lr[0];
18825                 }
18826
18827                 /* Initalize the live_range_def */
18828                 rstate->lrd[j].next    = &rstate->lrd[j];
18829                 rstate->lrd[j].prev    = &rstate->lrd[j];
18830                 rstate->lrd[j].def     = ins;
18831                 rstate->lrd[j].orig_id = ins->id;
18832                 ins->id = j;
18833
18834                 j++;
18835                 ins = ins->next;
18836         } while(ins != first);
18837         rstate->ranges = i;
18838
18839         /* Make a second pass to handle achitecture specific register
18840          * constraints.
18841          */
18842         ins = first;
18843         do {
18844                 int zlhs, zrhs, i, j;
18845                 if (ins->id > rstate->defs) {
18846                         internal_error(state, ins, "bad id");
18847                 }
18848                 
18849                 /* Walk through the template of ins and coalesce live ranges */
18850                 zlhs = ins->lhs;
18851                 if ((zlhs == 0) && triple_is_def(state, ins)) {
18852                         zlhs = 1;
18853                 }
18854                 zrhs = ins->rhs;
18855
18856                 if (state->compiler->debug & DEBUG_COALESCING2) {
18857                         fprintf(state->errout, "mandatory coalesce: %p %d %d\n",
18858                                 ins, zlhs, zrhs);
18859                 }
18860
18861                 for(i = 0; i < zlhs; i++) {
18862                         struct reg_info linfo;
18863                         struct live_range_def *lhs;
18864                         linfo = arch_reg_lhs(state, ins, i);
18865                         if (linfo.reg < MAX_REGISTERS) {
18866                                 continue;
18867                         }
18868                         if (triple_is_def(state, ins)) {
18869                                 lhs = &rstate->lrd[ins->id];
18870                         } else {
18871                                 lhs = &rstate->lrd[LHS(ins, i)->id];
18872                         }
18873
18874                         if (state->compiler->debug & DEBUG_COALESCING2) {
18875                                 fprintf(state->errout, "coalesce lhs(%d): %p %d\n",
18876                                         i, lhs, linfo.reg);
18877                         }
18878
18879                         for(j = 0; j < zrhs; j++) {
18880                                 struct reg_info rinfo;
18881                                 struct live_range_def *rhs;
18882                                 rinfo = arch_reg_rhs(state, ins, j);
18883                                 if (rinfo.reg < MAX_REGISTERS) {
18884                                         continue;
18885                                 }
18886                                 rhs = &rstate->lrd[RHS(ins, j)->id];
18887
18888                                 if (state->compiler->debug & DEBUG_COALESCING2) {
18889                                         fprintf(state->errout, "coalesce rhs(%d): %p %d\n",
18890                                                 j, rhs, rinfo.reg);
18891                                 }
18892
18893                                 if (rinfo.reg == linfo.reg) {
18894                                         coalesce_ranges(state, rstate, 
18895                                                 lhs->lr, rhs->lr);
18896                                 }
18897                         }
18898                 }
18899                 ins = ins->next;
18900         } while(ins != first);
18901 }
18902
18903 static void graph_ins(
18904         struct compile_state *state, 
18905         struct reg_block *blocks, struct triple_reg_set *live, 
18906         struct reg_block *rb, struct triple *ins, void *arg)
18907 {
18908         struct reg_state *rstate = arg;
18909         struct live_range *def;
18910         struct triple_reg_set *entry;
18911
18912         /* If the triple is not a definition
18913          * we do not have a definition to add to
18914          * the interference graph.
18915          */
18916         if (!triple_is_def(state, ins)) {
18917                 return;
18918         }
18919         def = rstate->lrd[ins->id].lr;
18920         
18921         /* Create an edge between ins and everything that is
18922          * alive, unless the live_range cannot share
18923          * a physical register with ins.
18924          */
18925         for(entry = live; entry; entry = entry->next) {
18926                 struct live_range *lr;
18927                 if ((entry->member->id < 0) || (entry->member->id > rstate->defs)) {
18928                         internal_error(state, 0, "bad entry?");
18929                 }
18930                 lr = rstate->lrd[entry->member->id].lr;
18931                 if (def == lr) {
18932                         continue;
18933                 }
18934                 if (!arch_regcm_intersect(def->classes, lr->classes)) {
18935                         continue;
18936                 }
18937                 add_live_edge(rstate, def, lr);
18938         }
18939         return;
18940 }
18941
18942 #if DEBUG_CONSISTENCY > 1
18943 static struct live_range *get_verify_live_range(
18944         struct compile_state *state, struct reg_state *rstate, struct triple *ins)
18945 {
18946         struct live_range *lr;
18947         struct live_range_def *lrd;
18948         int ins_found;
18949         if ((ins->id < 0) || (ins->id > rstate->defs)) {
18950                 internal_error(state, ins, "bad ins?");
18951         }
18952         lr = rstate->lrd[ins->id].lr;
18953         ins_found = 0;
18954         lrd = lr->defs;
18955         do {
18956                 if (lrd->def == ins) {
18957                         ins_found = 1;
18958                 }
18959                 lrd = lrd->next;
18960         } while(lrd != lr->defs);
18961         if (!ins_found) {
18962                 internal_error(state, ins, "ins not in live range");
18963         }
18964         return lr;
18965 }
18966
18967 static void verify_graph_ins(
18968         struct compile_state *state, 
18969         struct reg_block *blocks, struct triple_reg_set *live, 
18970         struct reg_block *rb, struct triple *ins, void *arg)
18971 {
18972         struct reg_state *rstate = arg;
18973         struct triple_reg_set *entry1, *entry2;
18974
18975
18976         /* Compare live against edges and make certain the code is working */
18977         for(entry1 = live; entry1; entry1 = entry1->next) {
18978                 struct live_range *lr1;
18979                 lr1 = get_verify_live_range(state, rstate, entry1->member);
18980                 for(entry2 = live; entry2; entry2 = entry2->next) {
18981                         struct live_range *lr2;
18982                         struct live_range_edge *edge2;
18983                         int lr1_found;
18984                         int lr2_degree;
18985                         if (entry2 == entry1) {
18986                                 continue;
18987                         }
18988                         lr2 = get_verify_live_range(state, rstate, entry2->member);
18989                         if (lr1 == lr2) {
18990                                 internal_error(state, entry2->member, 
18991                                         "live range with 2 values simultaneously alive");
18992                         }
18993                         if (!arch_regcm_intersect(lr1->classes, lr2->classes)) {
18994                                 continue;
18995                         }
18996                         if (!interfere(rstate, lr1, lr2)) {
18997                                 internal_error(state, entry2->member, 
18998                                         "edges don't interfere?");
18999                         }
19000                                 
19001                         lr1_found = 0;
19002                         lr2_degree = 0;
19003                         for(edge2 = lr2->edges; edge2; edge2 = edge2->next) {
19004                                 lr2_degree++;
19005                                 if (edge2->node == lr1) {
19006                                         lr1_found = 1;
19007                                 }
19008                         }
19009                         if (lr2_degree != lr2->degree) {
19010                                 internal_error(state, entry2->member,
19011                                         "computed degree: %d does not match reported degree: %d\n",
19012                                         lr2_degree, lr2->degree);
19013                         }
19014                         if (!lr1_found) {
19015                                 internal_error(state, entry2->member, "missing edge");
19016                         }
19017                 }
19018         }
19019         return;
19020 }
19021 #endif
19022
19023 static void print_interference_ins(
19024         struct compile_state *state, 
19025         struct reg_block *blocks, struct triple_reg_set *live, 
19026         struct reg_block *rb, struct triple *ins, void *arg)
19027 {
19028         struct reg_state *rstate = arg;
19029         struct live_range *lr;
19030         unsigned id;
19031         FILE *fp = state->dbgout;
19032
19033         lr = rstate->lrd[ins->id].lr;
19034         id = ins->id;
19035         ins->id = rstate->lrd[id].orig_id;
19036         SET_REG(ins->id, lr->color);
19037         display_triple(state->dbgout, ins);
19038         ins->id = id;
19039
19040         if (lr->defs) {
19041                 struct live_range_def *lrd;
19042                 fprintf(fp, "       range:");
19043                 lrd = lr->defs;
19044                 do {
19045                         fprintf(fp, " %-10p", lrd->def);
19046                         lrd = lrd->next;
19047                 } while(lrd != lr->defs);
19048                 fprintf(fp, "\n");
19049         }
19050         if (live) {
19051                 struct triple_reg_set *entry;
19052                 fprintf(fp, "        live:");
19053                 for(entry = live; entry; entry = entry->next) {
19054                         fprintf(fp, " %-10p", entry->member);
19055                 }
19056                 fprintf(fp, "\n");
19057         }
19058         if (lr->edges) {
19059                 struct live_range_edge *entry;
19060                 fprintf(fp, "       edges:");
19061                 for(entry = lr->edges; entry; entry = entry->next) {
19062                         struct live_range_def *lrd;
19063                         lrd = entry->node->defs;
19064                         do {
19065                                 fprintf(fp, " %-10p", lrd->def);
19066                                 lrd = lrd->next;
19067                         } while(lrd != entry->node->defs);
19068                         fprintf(fp, "|");
19069                 }
19070                 fprintf(fp, "\n");
19071         }
19072         if (triple_is_branch(state, ins)) {
19073                 fprintf(fp, "\n");
19074         }
19075         return;
19076 }
19077
19078 static int coalesce_live_ranges(
19079         struct compile_state *state, struct reg_state *rstate)
19080 {
19081         /* At the point where a value is moved from one
19082          * register to another that value requires two
19083          * registers, thus increasing register pressure.
19084          * Live range coaleescing reduces the register
19085          * pressure by keeping a value in one register
19086          * longer.
19087          *
19088          * In the case of a phi function all paths leading
19089          * into it must be allocated to the same register
19090          * otherwise the phi function may not be removed.
19091          *
19092          * Forcing a value to stay in a single register
19093          * for an extended period of time does have
19094          * limitations when applied to non homogenous
19095          * register pool.  
19096          *
19097          * The two cases I have identified are:
19098          * 1) Two forced register assignments may
19099          *    collide.
19100          * 2) Registers may go unused because they
19101          *    are only good for storing the value
19102          *    and not manipulating it.
19103          *
19104          * Because of this I need to split live ranges,
19105          * even outside of the context of coalesced live
19106          * ranges.  The need to split live ranges does
19107          * impose some constraints on live range coalescing.
19108          *
19109          * - Live ranges may not be coalesced across phi
19110          *   functions.  This creates a 2 headed live
19111          *   range that cannot be sanely split.
19112          *
19113          * - phi functions (coalesced in initialize_live_ranges) 
19114          *   are handled as pre split live ranges so we will
19115          *   never attempt to split them.
19116          */
19117         int coalesced;
19118         int i;
19119
19120         coalesced = 0;
19121         for(i = 0; i <= rstate->ranges; i++) {
19122                 struct live_range *lr1;
19123                 struct live_range_def *lrd1;
19124                 lr1 = &rstate->lr[i];
19125                 if (!lr1->defs) {
19126                         continue;
19127                 }
19128                 lrd1 = live_range_end(state, lr1, 0);
19129                 for(; lrd1; lrd1 = live_range_end(state, lr1, lrd1)) {
19130                         struct triple_set *set;
19131                         if (lrd1->def->op != OP_COPY) {
19132                                 continue;
19133                         }
19134                         /* Skip copies that are the result of a live range split. */
19135                         if (lrd1->orig_id & TRIPLE_FLAG_POST_SPLIT) {
19136                                 continue;
19137                         }
19138                         for(set = lrd1->def->use; set; set = set->next) {
19139                                 struct live_range_def *lrd2;
19140                                 struct live_range *lr2, *res;
19141
19142                                 lrd2 = &rstate->lrd[set->member->id];
19143
19144                                 /* Don't coalesce with instructions
19145                                  * that are the result of a live range
19146                                  * split.
19147                                  */
19148                                 if (lrd2->orig_id & TRIPLE_FLAG_PRE_SPLIT) {
19149                                         continue;
19150                                 }
19151                                 lr2 = rstate->lrd[set->member->id].lr;
19152                                 if (lr1 == lr2) {
19153                                         continue;
19154                                 }
19155                                 if ((lr1->color != lr2->color) &&
19156                                         (lr1->color != REG_UNSET) &&
19157                                         (lr2->color != REG_UNSET)) {
19158                                         continue;
19159                                 }
19160                                 if ((lr1->classes & lr2->classes) == 0) {
19161                                         continue;
19162                                 }
19163                                 
19164                                 if (interfere(rstate, lr1, lr2)) {
19165                                         continue;
19166                                 }
19167
19168                                 res = coalesce_ranges(state, rstate, lr1, lr2);
19169                                 coalesced += 1;
19170                                 if (res != lr1) {
19171                                         goto next;
19172                                 }
19173                         }
19174                 }
19175         next:
19176                 ;
19177         }
19178         return coalesced;
19179 }
19180
19181
19182 static void fix_coalesce_conflicts(struct compile_state *state,
19183         struct reg_block *blocks, struct triple_reg_set *live,
19184         struct reg_block *rb, struct triple *ins, void *arg)
19185 {
19186         int *conflicts = arg;
19187         int zlhs, zrhs, i, j;
19188
19189         /* See if we have a mandatory coalesce operation between
19190          * a lhs and a rhs value.  If so and the rhs value is also
19191          * alive then this triple needs to be pre copied.  Otherwise
19192          * we would have two definitions in the same live range simultaneously
19193          * alive.
19194          */
19195         zlhs = ins->lhs;
19196         if ((zlhs == 0) && triple_is_def(state, ins)) {
19197                 zlhs = 1;
19198         }
19199         zrhs = ins->rhs;
19200         for(i = 0; i < zlhs; i++) {
19201                 struct reg_info linfo;
19202                 linfo = arch_reg_lhs(state, ins, i);
19203                 if (linfo.reg < MAX_REGISTERS) {
19204                         continue;
19205                 }
19206                 for(j = 0; j < zrhs; j++) {
19207                         struct reg_info rinfo;
19208                         struct triple *rhs;
19209                         struct triple_reg_set *set;
19210                         int found;
19211                         found = 0;
19212                         rinfo = arch_reg_rhs(state, ins, j);
19213                         if (rinfo.reg != linfo.reg) {
19214                                 continue;
19215                         }
19216                         rhs = RHS(ins, j);
19217                         for(set = live; set && !found; set = set->next) {
19218                                 if (set->member == rhs) {
19219                                         found = 1;
19220                                 }
19221                         }
19222                         if (found) {
19223                                 struct triple *copy;
19224                                 copy = pre_copy(state, ins, j);
19225                                 copy->id |= TRIPLE_FLAG_PRE_SPLIT;
19226                                 (*conflicts)++;
19227                         }
19228                 }
19229         }
19230         return;
19231 }
19232
19233 static int correct_coalesce_conflicts(
19234         struct compile_state *state, struct reg_block *blocks)
19235 {
19236         int conflicts;
19237         conflicts = 0;
19238         walk_variable_lifetimes(state, &state->bb, blocks, 
19239                 fix_coalesce_conflicts, &conflicts);
19240         return conflicts;
19241 }
19242
19243 static void replace_set_use(struct compile_state *state,
19244         struct triple_reg_set *head, struct triple *orig, struct triple *new)
19245 {
19246         struct triple_reg_set *set;
19247         for(set = head; set; set = set->next) {
19248                 if (set->member == orig) {
19249                         set->member = new;
19250                 }
19251         }
19252 }
19253
19254 static void replace_block_use(struct compile_state *state, 
19255         struct reg_block *blocks, struct triple *orig, struct triple *new)
19256 {
19257         int i;
19258 #if DEBUG_ROMCC_WARNINGS
19259 #warning "WISHLIST visit just those blocks that need it *"
19260 #endif
19261         for(i = 1; i <= state->bb.last_vertex; i++) {
19262                 struct reg_block *rb;
19263                 rb = &blocks[i];
19264                 replace_set_use(state, rb->in, orig, new);
19265                 replace_set_use(state, rb->out, orig, new);
19266         }
19267 }
19268
19269 static void color_instructions(struct compile_state *state)
19270 {
19271         struct triple *ins, *first;
19272         first = state->first;
19273         ins = first;
19274         do {
19275                 if (triple_is_def(state, ins)) {
19276                         struct reg_info info;
19277                         info = find_lhs_color(state, ins, 0);
19278                         if (info.reg >= MAX_REGISTERS) {
19279                                 info.reg = REG_UNSET;
19280                         }
19281                         SET_INFO(ins->id, info);
19282                 }
19283                 ins = ins->next;
19284         } while(ins != first);
19285 }
19286
19287 static struct reg_info read_lhs_color(
19288         struct compile_state *state, struct triple *ins, int index)
19289 {
19290         struct reg_info info;
19291         if ((index == 0) && triple_is_def(state, ins)) {
19292                 info.reg   = ID_REG(ins->id);
19293                 info.regcm = ID_REGCM(ins->id);
19294         }
19295         else if (index < ins->lhs) {
19296                 info = read_lhs_color(state, LHS(ins, index), 0);
19297         }
19298         else {
19299                 internal_error(state, ins, "Bad lhs %d", index);
19300                 info.reg = REG_UNSET;
19301                 info.regcm = 0;
19302         }
19303         return info;
19304 }
19305
19306 static struct triple *resolve_tangle(
19307         struct compile_state *state, struct triple *tangle)
19308 {
19309         struct reg_info info, uinfo;
19310         struct triple_set *set, *next;
19311         struct triple *copy;
19312
19313 #if DEBUG_ROMCC_WARNINGS
19314 #warning "WISHLIST recalculate all affected instructions colors"
19315 #endif
19316         info = find_lhs_color(state, tangle, 0);
19317         for(set = tangle->use; set; set = next) {
19318                 struct triple *user;
19319                 int i, zrhs;
19320                 next = set->next;
19321                 user = set->member;
19322                 zrhs = user->rhs;
19323                 for(i = 0; i < zrhs; i++) {
19324                         if (RHS(user, i) != tangle) {
19325                                 continue;
19326                         }
19327                         uinfo = find_rhs_post_color(state, user, i);
19328                         if (uinfo.reg == info.reg) {
19329                                 copy = pre_copy(state, user, i);
19330                                 copy->id |= TRIPLE_FLAG_PRE_SPLIT;
19331                                 SET_INFO(copy->id, uinfo);
19332                         }
19333                 }
19334         }
19335         copy = 0;
19336         uinfo = find_lhs_pre_color(state, tangle, 0);
19337         if (uinfo.reg == info.reg) {
19338                 struct reg_info linfo;
19339                 copy = post_copy(state, tangle);
19340                 copy->id |= TRIPLE_FLAG_PRE_SPLIT;
19341                 linfo = find_lhs_color(state, copy, 0);
19342                 SET_INFO(copy->id, linfo);
19343         }
19344         info = find_lhs_color(state, tangle, 0);
19345         SET_INFO(tangle->id, info);
19346         
19347         return copy;
19348 }
19349
19350
19351 static void fix_tangles(struct compile_state *state,
19352         struct reg_block *blocks, struct triple_reg_set *live,
19353         struct reg_block *rb, struct triple *ins, void *arg)
19354 {
19355         int *tangles = arg;
19356         struct triple *tangle;
19357         do {
19358                 char used[MAX_REGISTERS];
19359                 struct triple_reg_set *set;
19360                 tangle = 0;
19361
19362                 /* Find out which registers have multiple uses at this point */
19363                 memset(used, 0, sizeof(used));
19364                 for(set = live; set; set = set->next) {
19365                         struct reg_info info;
19366                         info = read_lhs_color(state, set->member, 0);
19367                         if (info.reg == REG_UNSET) {
19368                                 continue;
19369                         }
19370                         reg_inc_used(state, used, info.reg);
19371                 }
19372                 
19373                 /* Now find the least dominated definition of a register in
19374                  * conflict I have seen so far.
19375                  */
19376                 for(set = live; set; set = set->next) {
19377                         struct reg_info info;
19378                         info = read_lhs_color(state, set->member, 0);
19379                         if (used[info.reg] < 2) {
19380                                 continue;
19381                         }
19382                         /* Changing copies that feed into phi functions
19383                          * is incorrect.
19384                          */
19385                         if (set->member->use && 
19386                                 (set->member->use->member->op == OP_PHI)) {
19387                                 continue;
19388                         }
19389                         if (!tangle || tdominates(state, set->member, tangle)) {
19390                                 tangle = set->member;
19391                         }
19392                 }
19393                 /* If I have found a tangle resolve it */
19394                 if (tangle) {
19395                         struct triple *post_copy;
19396                         (*tangles)++;
19397                         post_copy = resolve_tangle(state, tangle);
19398                         if (post_copy) {
19399                                 replace_block_use(state, blocks, tangle, post_copy);
19400                         }
19401                         if (post_copy && (tangle != ins)) {
19402                                 replace_set_use(state, live, tangle, post_copy);
19403                         }
19404                 }
19405         } while(tangle);
19406         return;
19407 }
19408
19409 static int correct_tangles(
19410         struct compile_state *state, struct reg_block *blocks)
19411 {
19412         int tangles;
19413         tangles = 0;
19414         color_instructions(state);
19415         walk_variable_lifetimes(state, &state->bb, blocks, 
19416                 fix_tangles, &tangles);
19417         return tangles;
19418 }
19419
19420
19421 static void ids_from_rstate(struct compile_state *state, struct reg_state *rstate);
19422 static void cleanup_rstate(struct compile_state *state, struct reg_state *rstate);
19423
19424 struct triple *find_constrained_def(
19425         struct compile_state *state, struct live_range *range, struct triple *constrained)
19426 {
19427         struct live_range_def *lrd, *lrd_next;
19428         lrd_next = range->defs;
19429         do {
19430                 struct reg_info info;
19431                 unsigned regcm;
19432
19433                 lrd = lrd_next;
19434                 lrd_next = lrd->next;
19435
19436                 regcm = arch_type_to_regcm(state, lrd->def->type);
19437                 info = find_lhs_color(state, lrd->def, 0);
19438                 regcm      = arch_regcm_reg_normalize(state, regcm);
19439                 info.regcm = arch_regcm_reg_normalize(state, info.regcm);
19440                 /* If the 2 register class masks are equal then
19441                  * the current register class is not constrained.
19442                  */
19443                 if (regcm == info.regcm) {
19444                         continue;
19445                 }
19446                 
19447                 /* If there is just one use.
19448                  * That use cannot accept a larger register class.
19449                  * There are no intervening definitions except
19450                  * definitions that feed into that use.
19451                  * Then a triple is not constrained.
19452                  * FIXME handle this case!
19453                  */
19454 #if DEBUG_ROMCC_WARNINGS
19455 #warning "FIXME ignore cases that cannot be fixed (a definition followed by a use)"
19456 #endif
19457                 
19458
19459                 /* Of the constrained live ranges deal with the
19460                  * least dominated one first.
19461                  */
19462                 if (state->compiler->debug & DEBUG_RANGE_CONFLICTS) {
19463                         fprintf(state->errout, "canidate: %p %-8s regcm: %x %x\n",
19464                                 lrd->def, tops(lrd->def->op), regcm, info.regcm);
19465                 }
19466                 if (!constrained || 
19467                         tdominates(state, lrd->def, constrained))
19468                 {
19469                         constrained = lrd->def;
19470                 }
19471         } while(lrd_next != range->defs);
19472         return constrained;
19473 }
19474
19475 static int split_constrained_ranges(
19476         struct compile_state *state, struct reg_state *rstate, 
19477         struct live_range *range)
19478 {
19479         /* Walk through the edges in conflict and our current live
19480          * range, and find definitions that are more severly constrained
19481          * than they type of data they contain require.
19482          * 
19483          * Then pick one of those ranges and relax the constraints.
19484          */
19485         struct live_range_edge *edge;
19486         struct triple *constrained;
19487
19488         constrained = 0;
19489         for(edge = range->edges; edge; edge = edge->next) {
19490                 constrained = find_constrained_def(state, edge->node, constrained);
19491         }
19492 #if DEBUG_ROMCC_WARNINGS
19493 #warning "FIXME should I call find_constrained_def here only if no previous constrained def was found?"
19494 #endif
19495         if (!constrained) {
19496                 constrained = find_constrained_def(state, range, constrained);
19497         }
19498
19499         if (state->compiler->debug & DEBUG_RANGE_CONFLICTS) {
19500                 fprintf(state->errout, "constrained: ");
19501                 display_triple(state->errout, constrained);
19502         }
19503         if (constrained) {
19504                 ids_from_rstate(state, rstate);
19505                 cleanup_rstate(state, rstate);
19506                 resolve_tangle(state, constrained);
19507         }
19508         return !!constrained;
19509 }
19510         
19511 static int split_ranges(
19512         struct compile_state *state, struct reg_state *rstate,
19513         char *used, struct live_range *range)
19514 {
19515         int split;
19516         if (state->compiler->debug & DEBUG_RANGE_CONFLICTS) {
19517                 fprintf(state->errout, "split_ranges %d %s %p\n", 
19518                         rstate->passes, tops(range->defs->def->op), range->defs->def);
19519         }
19520         if ((range->color == REG_UNNEEDED) ||
19521                 (rstate->passes >= rstate->max_passes)) {
19522                 return 0;
19523         }
19524         split = split_constrained_ranges(state, rstate, range);
19525
19526         /* Ideally I would split the live range that will not be used
19527          * for the longest period of time in hopes that this will 
19528          * (a) allow me to spill a register or
19529          * (b) allow me to place a value in another register.
19530          *
19531          * So far I don't have a test case for this, the resolving
19532          * of mandatory constraints has solved all of my
19533          * know issues.  So I have choosen not to write any
19534          * code until I cat get a better feel for cases where
19535          * it would be useful to have.
19536          *
19537          */
19538 #if DEBUG_ROMCC_WARNINGS
19539 #warning "WISHLIST implement live range splitting..."
19540 #endif
19541         
19542         if (!split && (state->compiler->debug & DEBUG_RANGE_CONFLICTS2)) {
19543                 FILE *fp = state->errout;
19544                 print_interference_blocks(state, rstate, fp, 0);
19545                 print_dominators(state, fp, &state->bb);
19546         }
19547         return split;
19548 }
19549
19550 static FILE *cgdebug_fp(struct compile_state *state)
19551 {
19552         FILE *fp;
19553         fp = 0;
19554         if (!fp && (state->compiler->debug & DEBUG_COLOR_GRAPH2)) {
19555                 fp = state->errout;
19556         }
19557         if (!fp && (state->compiler->debug & DEBUG_COLOR_GRAPH)) {
19558                 fp = state->dbgout;
19559         }
19560         return fp;
19561 }
19562
19563 static void cgdebug_printf(struct compile_state *state, const char *fmt, ...)
19564 {
19565         FILE *fp;
19566         fp = cgdebug_fp(state);
19567         if (fp) {
19568                 va_list args;
19569                 va_start(args, fmt);
19570                 vfprintf(fp, fmt, args);
19571                 va_end(args);
19572         }
19573 }
19574
19575 static void cgdebug_flush(struct compile_state *state)
19576 {
19577         FILE *fp;
19578         fp = cgdebug_fp(state);
19579         if (fp) {
19580                 fflush(fp);
19581         }
19582 }
19583
19584 static void cgdebug_loc(struct compile_state *state, struct triple *ins)
19585 {
19586         FILE *fp;
19587         fp = cgdebug_fp(state);
19588         if (fp) {
19589                 loc(fp, state, ins);
19590         }
19591 }
19592
19593 static int select_free_color(struct compile_state *state, 
19594         struct reg_state *rstate, struct live_range *range)
19595 {
19596         struct triple_set *entry;
19597         struct live_range_def *lrd;
19598         struct live_range_def *phi;
19599         struct live_range_edge *edge;
19600         char used[MAX_REGISTERS];
19601         struct triple **expr;
19602
19603         /* Instead of doing just the trivial color select here I try
19604          * a few extra things because a good color selection will help reduce
19605          * copies.
19606          */
19607
19608         /* Find the registers currently in use */
19609         memset(used, 0, sizeof(used));
19610         for(edge = range->edges; edge; edge = edge->next) {
19611                 if (edge->node->color == REG_UNSET) {
19612                         continue;
19613                 }
19614                 reg_fill_used(state, used, edge->node->color);
19615         }
19616
19617         if (state->compiler->debug & DEBUG_COLOR_GRAPH2) {
19618                 int i;
19619                 i = 0;
19620                 for(edge = range->edges; edge; edge = edge->next) {
19621                         i++;
19622                 }
19623                 cgdebug_printf(state, "\n%s edges: %d", 
19624                         tops(range->defs->def->op), i);
19625                 cgdebug_loc(state, range->defs->def);
19626                 cgdebug_printf(state, "\n");
19627                 for(i = 0; i < MAX_REGISTERS; i++) {
19628                         if (used[i]) {
19629                                 cgdebug_printf(state, "used: %s\n",
19630                                         arch_reg_str(i));
19631                         }
19632                 }
19633         }       
19634
19635         /* If a color is already assigned see if it will work */
19636         if (range->color != REG_UNSET) {
19637                 struct live_range_def *lrd;
19638                 if (!used[range->color]) {
19639                         return 1;
19640                 }
19641                 for(edge = range->edges; edge; edge = edge->next) {
19642                         if (edge->node->color != range->color) {
19643                                 continue;
19644                         }
19645                         warning(state, edge->node->defs->def, "edge: ");
19646                         lrd = edge->node->defs;
19647                         do {
19648                                 warning(state, lrd->def, " %p %s",
19649                                         lrd->def, tops(lrd->def->op));
19650                                 lrd = lrd->next;
19651                         } while(lrd != edge->node->defs);
19652                 }
19653                 lrd = range->defs;
19654                 warning(state, range->defs->def, "def: ");
19655                 do {
19656                         warning(state, lrd->def, " %p %s",
19657                                 lrd->def, tops(lrd->def->op));
19658                         lrd = lrd->next;
19659                 } while(lrd != range->defs);
19660                 internal_error(state, range->defs->def,
19661                         "live range with already used color %s",
19662                         arch_reg_str(range->color));
19663         }
19664
19665         /* If I feed into an expression reuse it's color.
19666          * This should help remove copies in the case of 2 register instructions
19667          * and phi functions.
19668          */
19669         phi = 0;
19670         lrd = live_range_end(state, range, 0);
19671         for(; (range->color == REG_UNSET) && lrd ; lrd = live_range_end(state, range, lrd)) {
19672                 entry = lrd->def->use;
19673                 for(;(range->color == REG_UNSET) && entry; entry = entry->next) {
19674                         struct live_range_def *insd;
19675                         unsigned regcm;
19676                         insd = &rstate->lrd[entry->member->id];
19677                         if (insd->lr->defs == 0) {
19678                                 continue;
19679                         }
19680                         if (!phi && (insd->def->op == OP_PHI) &&
19681                                 !interfere(rstate, range, insd->lr)) {
19682                                 phi = insd;
19683                         }
19684                         if (insd->lr->color == REG_UNSET) {
19685                                 continue;
19686                         }
19687                         regcm = insd->lr->classes;
19688                         if (((regcm & range->classes) == 0) ||
19689                                 (used[insd->lr->color])) {
19690                                 continue;
19691                         }
19692                         if (interfere(rstate, range, insd->lr)) {
19693                                 continue;
19694                         }
19695                         range->color = insd->lr->color;
19696                 }
19697         }
19698         /* If I feed into a phi function reuse it's color or the color
19699          * of something else that feeds into the phi function.
19700          */
19701         if (phi) {
19702                 if (phi->lr->color != REG_UNSET) {
19703                         if (used[phi->lr->color]) {
19704                                 range->color = phi->lr->color;
19705                         }
19706                 }
19707                 else {
19708                         expr = triple_rhs(state, phi->def, 0);
19709                         for(; expr; expr = triple_rhs(state, phi->def, expr)) {
19710                                 struct live_range *lr;
19711                                 unsigned regcm;
19712                                 if (!*expr) {
19713                                         continue;
19714                                 }
19715                                 lr = rstate->lrd[(*expr)->id].lr;
19716                                 if (lr->color == REG_UNSET) {
19717                                         continue;
19718                                 }
19719                                 regcm = lr->classes;
19720                                 if (((regcm & range->classes) == 0) ||
19721                                         (used[lr->color])) {
19722                                         continue;
19723                                 }
19724                                 if (interfere(rstate, range, lr)) {
19725                                         continue;
19726                                 }
19727                                 range->color = lr->color;
19728                         }
19729                 }
19730         }
19731         /* If I don't interfere with a rhs node reuse it's color */
19732         lrd = live_range_head(state, range, 0);
19733         for(; (range->color == REG_UNSET) && lrd ; lrd = live_range_head(state, range, lrd)) {
19734                 expr = triple_rhs(state, lrd->def, 0);
19735                 for(; expr; expr = triple_rhs(state, lrd->def, expr)) {
19736                         struct live_range *lr;
19737                         unsigned regcm;
19738                         if (!*expr) {
19739                                 continue;
19740                         }
19741                         lr = rstate->lrd[(*expr)->id].lr;
19742                         if (lr->color == REG_UNSET) {
19743                                 continue;
19744                         }
19745                         regcm = lr->classes;
19746                         if (((regcm & range->classes) == 0) ||
19747                                 (used[lr->color])) {
19748                                 continue;
19749                         }
19750                         if (interfere(rstate, range, lr)) {
19751                                 continue;
19752                         }
19753                         range->color = lr->color;
19754                         break;
19755                 }
19756         }
19757         /* If I have not opportunitically picked a useful color
19758          * pick the first color that is free.
19759          */
19760         if (range->color == REG_UNSET) {
19761                 range->color = 
19762                         arch_select_free_register(state, used, range->classes);
19763         }
19764         if (range->color == REG_UNSET) {
19765                 struct live_range_def *lrd;
19766                 int i;
19767                 if (split_ranges(state, rstate, used, range)) {
19768                         return 0;
19769                 }
19770                 for(edge = range->edges; edge; edge = edge->next) {
19771                         warning(state, edge->node->defs->def, "edge reg %s",
19772                                 arch_reg_str(edge->node->color));
19773                         lrd = edge->node->defs;
19774                         do {
19775                                 warning(state, lrd->def, " %s %p",
19776                                         tops(lrd->def->op), lrd->def);
19777                                 lrd = lrd->next;
19778                         } while(lrd != edge->node->defs);
19779                 }
19780                 warning(state, range->defs->def, "range: ");
19781                 lrd = range->defs;
19782                 do {
19783                         warning(state, lrd->def, " %s %p",
19784                                 tops(lrd->def->op), lrd->def);
19785                         lrd = lrd->next;
19786                 } while(lrd != range->defs);
19787                         
19788                 warning(state, range->defs->def, "classes: %x",
19789                         range->classes);
19790                 for(i = 0; i < MAX_REGISTERS; i++) {
19791                         if (used[i]) {
19792                                 warning(state, range->defs->def, "used: %s",
19793                                         arch_reg_str(i));
19794                         }
19795                 }
19796                 error(state, range->defs->def, "too few registers");
19797         }
19798         range->classes &= arch_reg_regcm(state, range->color);
19799         if ((range->color == REG_UNSET) || (range->classes == 0)) {
19800                 internal_error(state, range->defs->def, "select_free_color did not?");
19801         }
19802         return 1;
19803 }
19804
19805 static int color_graph(struct compile_state *state, struct reg_state *rstate)
19806 {
19807         int colored;
19808         struct live_range_edge *edge;
19809         struct live_range *range;
19810         if (rstate->low) {
19811                 cgdebug_printf(state, "Lo: ");
19812                 range = rstate->low;
19813                 if (*range->group_prev != range) {
19814                         internal_error(state, 0, "lo: *prev != range?");
19815                 }
19816                 *range->group_prev = range->group_next;
19817                 if (range->group_next) {
19818                         range->group_next->group_prev = range->group_prev;
19819                 }
19820                 if (&range->group_next == rstate->low_tail) {
19821                         rstate->low_tail = range->group_prev;
19822                 }
19823                 if (rstate->low == range) {
19824                         internal_error(state, 0, "low: next != prev?");
19825                 }
19826         }
19827         else if (rstate->high) {
19828                 cgdebug_printf(state, "Hi: ");
19829                 range = rstate->high;
19830                 if (*range->group_prev != range) {
19831                         internal_error(state, 0, "hi: *prev != range?");
19832                 }
19833                 *range->group_prev = range->group_next;
19834                 if (range->group_next) {
19835                         range->group_next->group_prev = range->group_prev;
19836                 }
19837                 if (&range->group_next == rstate->high_tail) {
19838                         rstate->high_tail = range->group_prev;
19839                 }
19840                 if (rstate->high == range) {
19841                         internal_error(state, 0, "high: next != prev?");
19842                 }
19843         }
19844         else {
19845                 return 1;
19846         }
19847         cgdebug_printf(state, " %d\n", range - rstate->lr);
19848         range->group_prev = 0;
19849         for(edge = range->edges; edge; edge = edge->next) {
19850                 struct live_range *node;
19851                 node = edge->node;
19852                 /* Move nodes from the high to the low list */
19853                 if (node->group_prev && (node->color == REG_UNSET) &&
19854                         (node->degree == regc_max_size(state, node->classes))) {
19855                         if (*node->group_prev != node) {
19856                                 internal_error(state, 0, "move: *prev != node?");
19857                         }
19858                         *node->group_prev = node->group_next;
19859                         if (node->group_next) {
19860                                 node->group_next->group_prev = node->group_prev;
19861                         }
19862                         if (&node->group_next == rstate->high_tail) {
19863                                 rstate->high_tail = node->group_prev;
19864                         }
19865                         cgdebug_printf(state, "Moving...%d to low\n", node - rstate->lr);
19866                         node->group_prev  = rstate->low_tail;
19867                         node->group_next  = 0;
19868                         *rstate->low_tail = node;
19869                         rstate->low_tail  = &node->group_next;
19870                         if (*node->group_prev != node) {
19871                                 internal_error(state, 0, "move2: *prev != node?");
19872                         }
19873                 }
19874                 node->degree -= 1;
19875         }
19876         colored = color_graph(state, rstate);
19877         if (colored) {
19878                 cgdebug_printf(state, "Coloring %d @", range - rstate->lr);
19879                 cgdebug_loc(state, range->defs->def);
19880                 cgdebug_flush(state);
19881                 colored = select_free_color(state, rstate, range);
19882                 if (colored) {
19883                         cgdebug_printf(state, " %s\n", arch_reg_str(range->color));
19884                 }
19885         }
19886         return colored;
19887 }
19888
19889 static void verify_colors(struct compile_state *state, struct reg_state *rstate)
19890 {
19891         struct live_range *lr;
19892         struct live_range_edge *edge;
19893         struct triple *ins, *first;
19894         char used[MAX_REGISTERS];
19895         first = state->first;
19896         ins = first;
19897         do {
19898                 if (triple_is_def(state, ins)) {
19899                         if ((ins->id < 0) || (ins->id > rstate->defs)) {
19900                                 internal_error(state, ins, 
19901                                         "triple without a live range def");
19902                         }
19903                         lr = rstate->lrd[ins->id].lr;
19904                         if (lr->color == REG_UNSET) {
19905                                 internal_error(state, ins,
19906                                         "triple without a color");
19907                         }
19908                         /* Find the registers used by the edges */
19909                         memset(used, 0, sizeof(used));
19910                         for(edge = lr->edges; edge; edge = edge->next) {
19911                                 if (edge->node->color == REG_UNSET) {
19912                                         internal_error(state, 0,
19913                                                 "live range without a color");
19914                         }
19915                                 reg_fill_used(state, used, edge->node->color);
19916                         }
19917                         if (used[lr->color]) {
19918                                 internal_error(state, ins,
19919                                         "triple with already used color");
19920                         }
19921                 }
19922                 ins = ins->next;
19923         } while(ins != first);
19924 }
19925
19926 static void color_triples(struct compile_state *state, struct reg_state *rstate)
19927 {
19928         struct live_range_def *lrd;
19929         struct live_range *lr;
19930         struct triple *first, *ins;
19931         first = state->first;
19932         ins = first;
19933         do {
19934                 if ((ins->id < 0) || (ins->id > rstate->defs)) {
19935                         internal_error(state, ins, 
19936                                 "triple without a live range");
19937                 }
19938                 lrd = &rstate->lrd[ins->id];
19939                 lr = lrd->lr;
19940                 ins->id = lrd->orig_id;
19941                 SET_REG(ins->id, lr->color);
19942                 ins = ins->next;
19943         } while (ins != first);
19944 }
19945
19946 static struct live_range *merge_sort_lr(
19947         struct live_range *first, struct live_range *last)
19948 {
19949         struct live_range *mid, *join, **join_tail, *pick;
19950         size_t size;
19951         size = (last - first) + 1;
19952         if (size >= 2) {
19953                 mid = first + size/2;
19954                 first = merge_sort_lr(first, mid -1);
19955                 mid   = merge_sort_lr(mid, last);
19956                 
19957                 join = 0;
19958                 join_tail = &join;
19959                 /* merge the two lists */
19960                 while(first && mid) {
19961                         if ((first->degree < mid->degree) ||
19962                                 ((first->degree == mid->degree) &&
19963                                         (first->length < mid->length))) {
19964                                 pick = first;
19965                                 first = first->group_next;
19966                                 if (first) {
19967                                         first->group_prev = 0;
19968                                 }
19969                         }
19970                         else {
19971                                 pick = mid;
19972                                 mid = mid->group_next;
19973                                 if (mid) {
19974                                         mid->group_prev = 0;
19975                                 }
19976                         }
19977                         pick->group_next = 0;
19978                         pick->group_prev = join_tail;
19979                         *join_tail = pick;
19980                         join_tail = &pick->group_next;
19981                 }
19982                 /* Splice the remaining list */
19983                 pick = (first)? first : mid;
19984                 *join_tail = pick;
19985                 if (pick) { 
19986                         pick->group_prev = join_tail;
19987                 }
19988         }
19989         else {
19990                 if (!first->defs) {
19991                         first = 0;
19992                 }
19993                 join = first;
19994         }
19995         return join;
19996 }
19997
19998 static void ids_from_rstate(struct compile_state *state, 
19999         struct reg_state *rstate)
20000 {
20001         struct triple *ins, *first;
20002         if (!rstate->defs) {
20003                 return;
20004         }
20005         /* Display the graph if desired */
20006         if (state->compiler->debug & DEBUG_INTERFERENCE) {
20007                 FILE *fp = state->dbgout;
20008                 print_interference_blocks(state, rstate, fp, 0);
20009                 print_control_flow(state, fp, &state->bb);
20010                 fflush(fp);
20011         }
20012         first = state->first;
20013         ins = first;
20014         do {
20015                 if (ins->id) {
20016                         struct live_range_def *lrd;
20017                         lrd = &rstate->lrd[ins->id];
20018                         ins->id = lrd->orig_id;
20019                 }
20020                 ins = ins->next;
20021         } while(ins != first);
20022 }
20023
20024 static void cleanup_live_edges(struct reg_state *rstate)
20025 {
20026         int i;
20027         /* Free the edges on each node */
20028         for(i = 1; i <= rstate->ranges; i++) {
20029                 remove_live_edges(rstate, &rstate->lr[i]);
20030         }
20031 }
20032
20033 static void cleanup_rstate(struct compile_state *state, struct reg_state *rstate)
20034 {
20035         cleanup_live_edges(rstate);
20036         xfree(rstate->lrd);
20037         xfree(rstate->lr);
20038
20039         /* Free the variable lifetime information */
20040         if (rstate->blocks) {
20041                 free_variable_lifetimes(state, &state->bb, rstate->blocks);
20042         }
20043         rstate->defs = 0;
20044         rstate->ranges = 0;
20045         rstate->lrd = 0;
20046         rstate->lr = 0;
20047         rstate->blocks = 0;
20048 }
20049
20050 static void verify_consistency(struct compile_state *state);
20051 static void allocate_registers(struct compile_state *state)
20052 {
20053         struct reg_state rstate;
20054         int colored;
20055
20056         /* Clear out the reg_state */
20057         memset(&rstate, 0, sizeof(rstate));
20058         rstate.max_passes = state->compiler->max_allocation_passes;
20059
20060         do {
20061                 struct live_range **point, **next;
20062                 int conflicts;
20063                 int tangles;
20064                 int coalesced;
20065
20066                 if (state->compiler->debug & DEBUG_RANGE_CONFLICTS) {
20067                         FILE *fp = state->errout;
20068                         fprintf(fp, "pass: %d\n", rstate.passes);
20069                         fflush(fp);
20070                 }
20071
20072                 /* Restore ids */
20073                 ids_from_rstate(state, &rstate);
20074
20075                 /* Cleanup the temporary data structures */
20076                 cleanup_rstate(state, &rstate);
20077
20078                 /* Compute the variable lifetimes */
20079                 rstate.blocks = compute_variable_lifetimes(state, &state->bb);
20080
20081                 /* Fix invalid mandatory live range coalesce conflicts */
20082                 conflicts = correct_coalesce_conflicts(state, rstate.blocks);
20083
20084                 /* Fix two simultaneous uses of the same register.
20085                  * In a few pathlogical cases a partial untangle moves
20086                  * the tangle to a part of the graph we won't revisit.
20087                  * So we keep looping until we have no more tangle fixes
20088                  * to apply.
20089                  */
20090                 do {
20091                         tangles = correct_tangles(state, rstate.blocks);
20092                 } while(tangles);
20093
20094                 
20095                 print_blocks(state, "resolve_tangles", state->dbgout);
20096                 verify_consistency(state);
20097                 
20098                 /* Allocate and initialize the live ranges */
20099                 initialize_live_ranges(state, &rstate);
20100
20101                 /* Note currently doing coalescing in a loop appears to 
20102                  * buys me nothing.  The code is left this way in case
20103                  * there is some value in it.  Or if a future bugfix
20104                  * yields some benefit.
20105                  */
20106                 do {
20107                         if (state->compiler->debug & DEBUG_COALESCING) {
20108                                 fprintf(state->errout, "coalescing\n");
20109                         }
20110
20111                         /* Remove any previous live edge calculations */
20112                         cleanup_live_edges(&rstate);
20113
20114                         /* Compute the interference graph */
20115                         walk_variable_lifetimes(
20116                                 state, &state->bb, rstate.blocks, 
20117                                 graph_ins, &rstate);
20118                         
20119                         /* Display the interference graph if desired */
20120                         if (state->compiler->debug & DEBUG_INTERFERENCE) {
20121                                 print_interference_blocks(state, &rstate, state->dbgout, 1);
20122                                 fprintf(state->dbgout, "\nlive variables by instruction\n");
20123                                 walk_variable_lifetimes(
20124                                         state, &state->bb, rstate.blocks, 
20125                                         print_interference_ins, &rstate);
20126                         }
20127                         
20128                         coalesced = coalesce_live_ranges(state, &rstate);
20129
20130                         if (state->compiler->debug & DEBUG_COALESCING) {
20131                                 fprintf(state->errout, "coalesced: %d\n", coalesced);
20132                         }
20133                 } while(coalesced);
20134
20135 #if DEBUG_CONSISTENCY > 1
20136 # if 0
20137                 fprintf(state->errout, "verify_graph_ins...\n");
20138 # endif
20139                 /* Verify the interference graph */
20140                 walk_variable_lifetimes(
20141                         state, &state->bb, rstate.blocks, 
20142                         verify_graph_ins, &rstate);
20143 # if 0
20144                 fprintf(state->errout, "verify_graph_ins done\n");
20145 #endif
20146 #endif
20147                         
20148                 /* Build the groups low and high.  But with the nodes
20149                  * first sorted by degree order.
20150                  */
20151                 rstate.low_tail  = &rstate.low;
20152                 rstate.high_tail = &rstate.high;
20153                 rstate.high = merge_sort_lr(&rstate.lr[1], &rstate.lr[rstate.ranges]);
20154                 if (rstate.high) {
20155                         rstate.high->group_prev = &rstate.high;
20156                 }
20157                 for(point = &rstate.high; *point; point = &(*point)->group_next)
20158                         ;
20159                 rstate.high_tail = point;
20160                 /* Walk through the high list and move everything that needs
20161                  * to be onto low.
20162                  */
20163                 for(point = &rstate.high; *point; point = next) {
20164                         struct live_range *range;
20165                         next = &(*point)->group_next;
20166                         range = *point;
20167                         
20168                         /* If it has a low degree or it already has a color
20169                          * place the node in low.
20170                          */
20171                         if ((range->degree < regc_max_size(state, range->classes)) ||
20172                                 (range->color != REG_UNSET)) {
20173                                 cgdebug_printf(state, "Lo: %5d degree %5d%s\n", 
20174                                         range - rstate.lr, range->degree,
20175                                         (range->color != REG_UNSET) ? " (colored)": "");
20176                                 *range->group_prev = range->group_next;
20177                                 if (range->group_next) {
20178                                         range->group_next->group_prev = range->group_prev;
20179                                 }
20180                                 if (&range->group_next == rstate.high_tail) {
20181                                         rstate.high_tail = range->group_prev;
20182                                 }
20183                                 range->group_prev  = rstate.low_tail;
20184                                 range->group_next  = 0;
20185                                 *rstate.low_tail   = range;
20186                                 rstate.low_tail    = &range->group_next;
20187                                 next = point;
20188                         }
20189                         else {
20190                                 cgdebug_printf(state, "hi: %5d degree %5d%s\n", 
20191                                         range - rstate.lr, range->degree,
20192                                         (range->color != REG_UNSET) ? " (colored)": "");
20193                         }
20194                 }
20195                 /* Color the live_ranges */
20196                 colored = color_graph(state, &rstate);
20197                 rstate.passes++;
20198         } while (!colored);
20199
20200         /* Verify the graph was properly colored */
20201         verify_colors(state, &rstate);
20202
20203         /* Move the colors from the graph to the triples */
20204         color_triples(state, &rstate);
20205
20206         /* Cleanup the temporary data structures */
20207         cleanup_rstate(state, &rstate);
20208
20209         /* Display the new graph */
20210         print_blocks(state, __func__, state->dbgout);
20211 }
20212
20213 /* Sparce Conditional Constant Propogation
20214  * =========================================
20215  */
20216 struct ssa_edge;
20217 struct flow_block;
20218 struct lattice_node {
20219         unsigned old_id;
20220         struct triple *def;
20221         struct ssa_edge *out;
20222         struct flow_block *fblock;
20223         struct triple *val;
20224         /* lattice high   val == def
20225          * lattice const  is_const(val)
20226          * lattice low    other
20227          */
20228 };
20229 struct ssa_edge {
20230         struct lattice_node *src;
20231         struct lattice_node *dst;
20232         struct ssa_edge *work_next;
20233         struct ssa_edge *work_prev;
20234         struct ssa_edge *out_next;
20235 };
20236 struct flow_edge {
20237         struct flow_block *src;
20238         struct flow_block *dst;
20239         struct flow_edge *work_next;
20240         struct flow_edge *work_prev;
20241         struct flow_edge *in_next;
20242         struct flow_edge *out_next;
20243         int executable;
20244 };
20245 #define MAX_FLOW_BLOCK_EDGES 3
20246 struct flow_block {
20247         struct block *block;
20248         struct flow_edge *in;
20249         struct flow_edge *out;
20250         struct flow_edge *edges;
20251 };
20252
20253 struct scc_state {
20254         int ins_count;
20255         struct lattice_node *lattice;
20256         struct ssa_edge     *ssa_edges;
20257         struct flow_block   *flow_blocks;
20258         struct flow_edge    *flow_work_list;
20259         struct ssa_edge     *ssa_work_list;
20260 };
20261
20262
20263 static int is_scc_const(struct compile_state *state, struct triple *ins)
20264 {
20265         return ins && (triple_is_ubranch(state, ins) || is_const(ins));
20266 }
20267
20268 static int is_lattice_hi(struct compile_state *state, struct lattice_node *lnode)
20269 {
20270         return !is_scc_const(state, lnode->val) && (lnode->val == lnode->def);
20271 }
20272
20273 static int is_lattice_const(struct compile_state *state, struct lattice_node *lnode)
20274 {
20275         return is_scc_const(state, lnode->val);
20276 }
20277
20278 static int is_lattice_lo(struct compile_state *state, struct lattice_node *lnode)
20279 {
20280         return (lnode->val != lnode->def) && !is_scc_const(state, lnode->val);
20281 }
20282
20283 static void scc_add_fedge(struct compile_state *state, struct scc_state *scc, 
20284         struct flow_edge *fedge)
20285 {
20286         if (state->compiler->debug & DEBUG_SCC_TRANSFORM2) {
20287                 fprintf(state->errout, "adding fedge: %p (%4d -> %5d)\n",
20288                         fedge,
20289                         fedge->src->block?fedge->src->block->last->id: 0,
20290                         fedge->dst->block?fedge->dst->block->first->id: 0);
20291         }
20292         if ((fedge == scc->flow_work_list) ||
20293                 (fedge->work_next != fedge) ||
20294                 (fedge->work_prev != fedge)) {
20295
20296                 if (state->compiler->debug & DEBUG_SCC_TRANSFORM2) {
20297                         fprintf(state->errout, "dupped fedge: %p\n",
20298                                 fedge);
20299                 }
20300                 return;
20301         }
20302         if (!scc->flow_work_list) {
20303                 scc->flow_work_list = fedge;
20304                 fedge->work_next = fedge->work_prev = fedge;
20305         }
20306         else {
20307                 struct flow_edge *ftail;
20308                 ftail = scc->flow_work_list->work_prev;
20309                 fedge->work_next = ftail->work_next;
20310                 fedge->work_prev = ftail;
20311                 fedge->work_next->work_prev = fedge;
20312                 fedge->work_prev->work_next = fedge;
20313         }
20314 }
20315
20316 static struct flow_edge *scc_next_fedge(
20317         struct compile_state *state, struct scc_state *scc)
20318 {
20319         struct flow_edge *fedge;
20320         fedge = scc->flow_work_list;
20321         if (fedge) {
20322                 fedge->work_next->work_prev = fedge->work_prev;
20323                 fedge->work_prev->work_next = fedge->work_next;
20324                 if (fedge->work_next != fedge) {
20325                         scc->flow_work_list = fedge->work_next;
20326                 } else {
20327                         scc->flow_work_list = 0;
20328                 }
20329                 fedge->work_next = fedge->work_prev = fedge;
20330         }
20331         return fedge;
20332 }
20333
20334 static void scc_add_sedge(struct compile_state *state, struct scc_state *scc,
20335         struct ssa_edge *sedge)
20336 {
20337         if (state->compiler->debug & DEBUG_SCC_TRANSFORM2) {
20338                 fprintf(state->errout, "adding sedge: %5ld (%4d -> %5d)\n",
20339                         (long)(sedge - scc->ssa_edges),
20340                         sedge->src->def->id,
20341                         sedge->dst->def->id);
20342         }
20343         if ((sedge == scc->ssa_work_list) ||
20344                 (sedge->work_next != sedge) ||
20345                 (sedge->work_prev != sedge)) {
20346
20347                 if (state->compiler->debug & DEBUG_SCC_TRANSFORM2) {
20348                         fprintf(state->errout, "dupped sedge: %5ld\n",
20349                                 (long)(sedge - scc->ssa_edges));
20350                 }
20351                 return;
20352         }
20353         if (!scc->ssa_work_list) {
20354                 scc->ssa_work_list = sedge;
20355                 sedge->work_next = sedge->work_prev = sedge;
20356         }
20357         else {
20358                 struct ssa_edge *stail;
20359                 stail = scc->ssa_work_list->work_prev;
20360                 sedge->work_next = stail->work_next;
20361                 sedge->work_prev = stail;
20362                 sedge->work_next->work_prev = sedge;
20363                 sedge->work_prev->work_next = sedge;
20364         }
20365 }
20366
20367 static struct ssa_edge *scc_next_sedge(
20368         struct compile_state *state, struct scc_state *scc)
20369 {
20370         struct ssa_edge *sedge;
20371         sedge = scc->ssa_work_list;
20372         if (sedge) {
20373                 sedge->work_next->work_prev = sedge->work_prev;
20374                 sedge->work_prev->work_next = sedge->work_next;
20375                 if (sedge->work_next != sedge) {
20376                         scc->ssa_work_list = sedge->work_next;
20377                 } else {
20378                         scc->ssa_work_list = 0;
20379                 }
20380                 sedge->work_next = sedge->work_prev = sedge;
20381         }
20382         return sedge;
20383 }
20384
20385 static void initialize_scc_state(
20386         struct compile_state *state, struct scc_state *scc)
20387 {
20388         int ins_count, ssa_edge_count;
20389         int ins_index, ssa_edge_index, fblock_index;
20390         struct triple *first, *ins;
20391         struct block *block;
20392         struct flow_block *fblock;
20393
20394         memset(scc, 0, sizeof(*scc));
20395
20396         /* Inialize pass zero find out how much memory we need */
20397         first = state->first;
20398         ins = first;
20399         ins_count = ssa_edge_count = 0;
20400         do {
20401                 struct triple_set *edge;
20402                 ins_count += 1;
20403                 for(edge = ins->use; edge; edge = edge->next) {
20404                         ssa_edge_count++;
20405                 }
20406                 ins = ins->next;
20407         } while(ins != first);
20408         if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
20409                 fprintf(state->errout, "ins_count: %d ssa_edge_count: %d vertex_count: %d\n",
20410                         ins_count, ssa_edge_count, state->bb.last_vertex);
20411         }
20412         scc->ins_count   = ins_count;
20413         scc->lattice     = 
20414                 xcmalloc(sizeof(*scc->lattice)*(ins_count + 1), "lattice");
20415         scc->ssa_edges   = 
20416                 xcmalloc(sizeof(*scc->ssa_edges)*(ssa_edge_count + 1), "ssa_edges");
20417         scc->flow_blocks = 
20418                 xcmalloc(sizeof(*scc->flow_blocks)*(state->bb.last_vertex + 1), 
20419                         "flow_blocks");
20420
20421         /* Initialize pass one collect up the nodes */
20422         fblock = 0;
20423         block = 0;
20424         ins_index = ssa_edge_index = fblock_index = 0;
20425         ins = first;
20426         do {
20427                 if ((ins->op == OP_LABEL) && (block != ins->u.block)) {
20428                         block = ins->u.block;
20429                         if (!block) {
20430                                 internal_error(state, ins, "label without block");
20431                         }
20432                         fblock_index += 1;
20433                         block->vertex = fblock_index;
20434                         fblock = &scc->flow_blocks[fblock_index];
20435                         fblock->block = block;
20436                         fblock->edges = xcmalloc(sizeof(*fblock->edges)*block->edge_count,
20437                                 "flow_edges");
20438                 }
20439                 {
20440                         struct lattice_node *lnode;
20441                         ins_index += 1;
20442                         lnode = &scc->lattice[ins_index];
20443                         lnode->def = ins;
20444                         lnode->out = 0;
20445                         lnode->fblock = fblock;
20446                         lnode->val = ins; /* LATTICE HIGH */
20447                         if (lnode->val->op == OP_UNKNOWNVAL) {
20448                                 lnode->val = 0; /* LATTICE LOW by definition */
20449                         }
20450                         lnode->old_id = ins->id;
20451                         ins->id = ins_index;
20452                 }
20453                 ins = ins->next;
20454         } while(ins != first);
20455         /* Initialize pass two collect up the edges */
20456         block = 0;
20457         fblock = 0;
20458         ins = first;
20459         do {
20460                 {
20461                         struct triple_set *edge;
20462                         struct ssa_edge **stail;
20463                         struct lattice_node *lnode;
20464                         lnode = &scc->lattice[ins->id];
20465                         lnode->out = 0;
20466                         stail = &lnode->out;
20467                         for(edge = ins->use; edge; edge = edge->next) {
20468                                 struct ssa_edge *sedge;
20469                                 ssa_edge_index += 1;
20470                                 sedge = &scc->ssa_edges[ssa_edge_index];
20471                                 *stail = sedge;
20472                                 stail = &sedge->out_next;
20473                                 sedge->src = lnode;
20474                                 sedge->dst = &scc->lattice[edge->member->id];
20475                                 sedge->work_next = sedge->work_prev = sedge;
20476                                 sedge->out_next = 0;
20477                         }
20478                 }
20479                 if ((ins->op == OP_LABEL) && (block != ins->u.block)) {
20480                         struct flow_edge *fedge, **ftail;
20481                         struct block_set *bedge;
20482                         block = ins->u.block;
20483                         fblock = &scc->flow_blocks[block->vertex];
20484                         fblock->in = 0;
20485                         fblock->out = 0;
20486                         ftail = &fblock->out;
20487
20488                         fedge = fblock->edges;
20489                         bedge = block->edges;
20490                         for(; bedge; bedge = bedge->next, fedge++) {
20491                                 fedge->dst = &scc->flow_blocks[bedge->member->vertex];
20492                                 if (fedge->dst->block != bedge->member) {
20493                                         internal_error(state, 0, "block mismatch");
20494                                 }
20495                                 *ftail = fedge;
20496                                 ftail = &fedge->out_next;
20497                                 fedge->out_next = 0;
20498                         }
20499                         for(fedge = fblock->out; fedge; fedge = fedge->out_next) {
20500                                 fedge->src = fblock;
20501                                 fedge->work_next = fedge->work_prev = fedge;
20502                                 fedge->executable = 0;
20503                         }
20504                 }
20505                 ins = ins->next;
20506         } while (ins != first);
20507         block = 0;
20508         fblock = 0;
20509         ins = first;
20510         do {
20511                 if ((ins->op  == OP_LABEL) && (block != ins->u.block)) {
20512                         struct flow_edge **ftail;
20513                         struct block_set *bedge;
20514                         block = ins->u.block;
20515                         fblock = &scc->flow_blocks[block->vertex];
20516                         ftail = &fblock->in;
20517                         for(bedge = block->use; bedge; bedge = bedge->next) {
20518                                 struct block *src_block;
20519                                 struct flow_block *sfblock;
20520                                 struct flow_edge *sfedge;
20521                                 src_block = bedge->member;
20522                                 sfblock = &scc->flow_blocks[src_block->vertex];
20523                                 for(sfedge = sfblock->out; sfedge; sfedge = sfedge->out_next) {
20524                                         if (sfedge->dst == fblock) {
20525                                                 break;
20526                                         }
20527                                 }
20528                                 if (!sfedge) {
20529                                         internal_error(state, 0, "edge mismatch");
20530                                 }
20531                                 *ftail = sfedge;
20532                                 ftail = &sfedge->in_next;
20533                                 sfedge->in_next = 0;
20534                         }
20535                 }
20536                 ins = ins->next;
20537         } while(ins != first);
20538         /* Setup a dummy block 0 as a node above the start node */
20539         {
20540                 struct flow_block *fblock, *dst;
20541                 struct flow_edge *fedge;
20542                 fblock = &scc->flow_blocks[0];
20543                 fblock->block = 0;
20544                 fblock->edges = xcmalloc(sizeof(*fblock->edges)*1, "flow_edges");
20545                 fblock->in = 0;
20546                 fblock->out = fblock->edges;
20547                 dst = &scc->flow_blocks[state->bb.first_block->vertex];
20548                 fedge = fblock->edges;
20549                 fedge->src        = fblock;
20550                 fedge->dst        = dst;
20551                 fedge->work_next  = fedge;
20552                 fedge->work_prev  = fedge;
20553                 fedge->in_next    = fedge->dst->in;
20554                 fedge->out_next   = 0;
20555                 fedge->executable = 0;
20556                 fedge->dst->in = fedge;
20557                 
20558                 /* Initialize the work lists */
20559                 scc->flow_work_list = 0;
20560                 scc->ssa_work_list  = 0;
20561                 scc_add_fedge(state, scc, fedge);
20562         }
20563         if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
20564                 fprintf(state->errout, "ins_index: %d ssa_edge_index: %d fblock_index: %d\n",
20565                         ins_index, ssa_edge_index, fblock_index);
20566         }
20567 }
20568
20569         
20570 static void free_scc_state(
20571         struct compile_state *state, struct scc_state *scc)
20572 {
20573         int i;
20574         for(i = 0; i < state->bb.last_vertex + 1; i++) {
20575                 struct flow_block *fblock;
20576                 fblock = &scc->flow_blocks[i];
20577                 if (fblock->edges) {
20578                         xfree(fblock->edges);
20579                         fblock->edges = 0;
20580                 }
20581         }
20582         xfree(scc->flow_blocks);
20583         xfree(scc->ssa_edges);
20584         xfree(scc->lattice);
20585         
20586 }
20587
20588 static struct lattice_node *triple_to_lattice(
20589         struct compile_state *state, struct scc_state *scc, struct triple *ins)
20590 {
20591         if (ins->id <= 0) {
20592                 internal_error(state, ins, "bad id");
20593         }
20594         return &scc->lattice[ins->id];
20595 }
20596
20597 static struct triple *preserve_lval(
20598         struct compile_state *state, struct lattice_node *lnode)
20599 {
20600         struct triple *old;
20601         /* Preserve the original value */
20602         if (lnode->val) {
20603                 old = dup_triple(state, lnode->val);
20604                 if (lnode->val != lnode->def) {
20605                         xfree(lnode->val);
20606                 }
20607                 lnode->val = 0;
20608         } else {
20609                 old = 0;
20610         }
20611         return old;
20612 }
20613
20614 static int lval_changed(struct compile_state *state, 
20615         struct triple *old, struct lattice_node *lnode)
20616 {
20617         int changed;
20618         /* See if the lattice value has changed */
20619         changed = 1;
20620         if (!old && !lnode->val) {
20621                 changed = 0;
20622         }
20623         if (changed &&
20624                 lnode->val && old &&
20625                 (memcmp(lnode->val->param, old->param,
20626                         TRIPLE_SIZE(lnode->val) * sizeof(lnode->val->param[0])) == 0) &&
20627                 (memcmp(&lnode->val->u, &old->u, sizeof(old->u)) == 0)) {
20628                 changed = 0;
20629         }
20630         if (old) {
20631                 xfree(old);
20632         }
20633         return changed;
20634
20635 }
20636
20637 static void scc_debug_lnode(
20638         struct compile_state *state, struct scc_state *scc,
20639         struct lattice_node *lnode, int changed)
20640 {
20641         if ((state->compiler->debug & DEBUG_SCC_TRANSFORM2) && lnode->val) {
20642                 display_triple_changes(state->errout, lnode->val, lnode->def);
20643         }
20644         if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
20645                 FILE *fp = state->errout;
20646                 struct triple *val, **expr;
20647                 val = lnode->val? lnode->val : lnode->def;
20648                 fprintf(fp, "%p %s %3d %10s (",
20649                         lnode->def, 
20650                         ((lnode->def->op == OP_PHI)? "phi: ": "expr:"),
20651                         lnode->def->id,
20652                         tops(lnode->def->op));
20653                 expr = triple_rhs(state, lnode->def, 0);
20654                 for(;expr;expr = triple_rhs(state, lnode->def, expr)) {
20655                         if (*expr) {
20656                                 fprintf(fp, " %d", (*expr)->id);
20657                         }
20658                 }
20659                 if (val->op == OP_INTCONST) {
20660                         fprintf(fp, " <0x%08lx>", (unsigned long)(val->u.cval));
20661                 }
20662                 fprintf(fp, " ) -> %s %s\n",
20663                         (is_lattice_hi(state, lnode)? "hi":
20664                                 is_lattice_const(state, lnode)? "const" : "lo"),
20665                         changed? "changed" : ""
20666                         );
20667         }
20668 }
20669
20670 static int compute_lnode_val(struct compile_state *state, struct scc_state *scc,
20671         struct lattice_node *lnode)
20672 {
20673         int changed;
20674         struct triple *old, *scratch;
20675         struct triple **dexpr, **vexpr;
20676         int count, i;
20677         
20678         /* Store the original value */
20679         old = preserve_lval(state, lnode);
20680
20681         /* Reinitialize the value */
20682         lnode->val = scratch = dup_triple(state, lnode->def);
20683         scratch->id = lnode->old_id;
20684         scratch->next     = scratch;
20685         scratch->prev     = scratch;
20686         scratch->use      = 0;
20687
20688         count = TRIPLE_SIZE(scratch);
20689         for(i = 0; i < count; i++) {
20690                 dexpr = &lnode->def->param[i];
20691                 vexpr = &scratch->param[i];
20692                 *vexpr = *dexpr;
20693                 if (((i < TRIPLE_MISC_OFF(scratch)) ||
20694                         (i >= TRIPLE_TARG_OFF(scratch))) &&
20695                         *dexpr) {
20696                         struct lattice_node *tmp;
20697                         tmp = triple_to_lattice(state, scc, *dexpr);
20698                         *vexpr = (tmp->val)? tmp->val : tmp->def;
20699                 }
20700         }
20701         if (triple_is_branch(state, scratch)) {
20702                 scratch->next = lnode->def->next;
20703         }
20704         /* Recompute the value */
20705 #if DEBUG_ROMCC_WARNINGS
20706 #warning "FIXME see if simplify does anything bad"
20707 #endif
20708         /* So far it looks like only the strength reduction
20709          * optimization are things I need to worry about.
20710          */
20711         simplify(state, scratch);
20712         /* Cleanup my value */
20713         if (scratch->use) {
20714                 internal_error(state, lnode->def, "scratch used?");
20715         }
20716         if ((scratch->prev != scratch) ||
20717                 ((scratch->next != scratch) &&
20718                         (!triple_is_branch(state, lnode->def) ||
20719                                 (scratch->next != lnode->def->next)))) {
20720                 internal_error(state, lnode->def, "scratch in list?");
20721         }
20722         /* undo any uses... */
20723         count = TRIPLE_SIZE(scratch);
20724         for(i = 0; i < count; i++) {
20725                 vexpr = &scratch->param[i];
20726                 if (*vexpr) {
20727                         unuse_triple(*vexpr, scratch);
20728                 }
20729         }
20730         if (lnode->val->op == OP_UNKNOWNVAL) {
20731                 lnode->val = 0; /* Lattice low by definition */
20732         }
20733         /* Find the case when I am lattice high */
20734         if (lnode->val && 
20735                 (lnode->val->op == lnode->def->op) &&
20736                 (memcmp(lnode->val->param, lnode->def->param, 
20737                         count * sizeof(lnode->val->param[0])) == 0) &&
20738                 (memcmp(&lnode->val->u, &lnode->def->u, sizeof(lnode->def->u)) == 0)) {
20739                 lnode->val = lnode->def;
20740         }
20741         /* Only allow lattice high when all of my inputs
20742          * are also lattice high.  Occassionally I can
20743          * have constants with a lattice low input, so
20744          * I do not need to check that case.
20745          */
20746         if (is_lattice_hi(state, lnode)) {
20747                 struct lattice_node *tmp;
20748                 int rhs;
20749                 rhs = lnode->val->rhs;
20750                 for(i = 0; i < rhs; i++) {
20751                         tmp = triple_to_lattice(state, scc, RHS(lnode->val, i));
20752                         if (!is_lattice_hi(state, tmp)) {
20753                                 lnode->val = 0;
20754                                 break;
20755                         }
20756                 }
20757         }
20758         /* Find the cases that are always lattice lo */
20759         if (lnode->val && 
20760                 triple_is_def(state, lnode->val) &&
20761                 !triple_is_pure(state, lnode->val, lnode->old_id)) {
20762                 lnode->val = 0;
20763         }
20764         /* See if the lattice value has changed */
20765         changed = lval_changed(state, old, lnode);
20766         /* See if this value should not change */
20767         if ((lnode->val != lnode->def) && 
20768                 ((      !triple_is_def(state, lnode->def)  &&
20769                         !triple_is_cbranch(state, lnode->def)) ||
20770                         (lnode->def->op == OP_PIECE))) {
20771 #if DEBUG_ROMCC_WARNINGS
20772 #warning "FIXME constant propogate through expressions with multiple left hand sides"
20773 #endif
20774                 if (changed) {
20775                         internal_warning(state, lnode->def, "non def changes value?");
20776                 }
20777                 lnode->val = 0;
20778         }
20779
20780         /* See if we need to free the scratch value */
20781         if (lnode->val != scratch) {
20782                 xfree(scratch);
20783         }
20784         
20785         return changed;
20786 }
20787
20788
20789 static void scc_visit_cbranch(struct compile_state *state, struct scc_state *scc,
20790         struct lattice_node *lnode)
20791 {
20792         struct lattice_node *cond;
20793         struct flow_edge *left, *right;
20794         int changed;
20795
20796         /* Update the branch value */
20797         changed = compute_lnode_val(state, scc, lnode);
20798         scc_debug_lnode(state, scc, lnode, changed);
20799
20800         /* This only applies to conditional branches */
20801         if (!triple_is_cbranch(state, lnode->def)) {
20802                 internal_error(state, lnode->def, "not a conditional branch");
20803         }
20804
20805         if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
20806                 struct flow_edge *fedge;
20807                 FILE *fp = state->errout;
20808                 fprintf(fp, "%s: %d (",
20809                         tops(lnode->def->op),
20810                         lnode->def->id);
20811                 
20812                 for(fedge = lnode->fblock->out; fedge; fedge = fedge->out_next) {
20813                         fprintf(fp, " %d", fedge->dst->block->vertex);
20814                 }
20815                 fprintf(fp, " )");
20816                 if (lnode->def->rhs > 0) {
20817                         fprintf(fp, " <- %d",
20818                                 RHS(lnode->def, 0)->id);
20819                 }
20820                 fprintf(fp, "\n");
20821         }
20822         cond = triple_to_lattice(state, scc, RHS(lnode->def,0));
20823         for(left = cond->fblock->out; left; left = left->out_next) {
20824                 if (left->dst->block->first == lnode->def->next) {
20825                         break;
20826                 }
20827         }
20828         if (!left) {
20829                 internal_error(state, lnode->def, "Cannot find left branch edge");
20830         }
20831         for(right = cond->fblock->out; right; right = right->out_next) {
20832                 if (right->dst->block->first == TARG(lnode->def, 0)) {
20833                         break;
20834                 }
20835         }
20836         if (!right) {
20837                 internal_error(state, lnode->def, "Cannot find right branch edge");
20838         }
20839         /* I should only come here if the controlling expressions value
20840          * has changed, which means it must be either a constant or lo.
20841          */
20842         if (is_lattice_hi(state, cond)) {
20843                 internal_error(state, cond->def, "condition high?");
20844                 return;
20845         }
20846         if (is_lattice_lo(state, cond)) {
20847                 scc_add_fedge(state, scc, left);
20848                 scc_add_fedge(state, scc, right);
20849         }
20850         else if (cond->val->u.cval) {
20851                 scc_add_fedge(state, scc, right);
20852         } else {
20853                 scc_add_fedge(state, scc, left);
20854         }
20855
20856 }
20857
20858
20859 static void scc_add_sedge_dst(struct compile_state *state, 
20860         struct scc_state *scc, struct ssa_edge *sedge)
20861 {
20862         if (triple_is_cbranch(state, sedge->dst->def)) {
20863                 scc_visit_cbranch(state, scc, sedge->dst);
20864         }
20865         else if (triple_is_def(state, sedge->dst->def)) {
20866                 scc_add_sedge(state, scc, sedge);
20867         }
20868 }
20869
20870 static void scc_visit_phi(struct compile_state *state, struct scc_state *scc, 
20871         struct lattice_node *lnode)
20872 {
20873         struct lattice_node *tmp;
20874         struct triple **slot, *old;
20875         struct flow_edge *fedge;
20876         int changed;
20877         int index;
20878         if (lnode->def->op != OP_PHI) {
20879                 internal_error(state, lnode->def, "not phi");
20880         }
20881         /* Store the original value */
20882         old = preserve_lval(state, lnode);
20883
20884         /* default to lattice high */
20885         lnode->val = lnode->def;
20886         slot = &RHS(lnode->def, 0);
20887         index = 0;
20888         for(fedge = lnode->fblock->in; fedge; index++, fedge = fedge->in_next) {
20889                 if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
20890                         fprintf(state->errout, "Examining edge: %d vertex: %d executable: %d\n", 
20891                                 index,
20892                                 fedge->dst->block->vertex,
20893                                 fedge->executable
20894                                 );
20895                 }
20896                 if (!fedge->executable) {
20897                         continue;
20898                 }
20899                 if (!slot[index]) {
20900                         internal_error(state, lnode->def, "no phi value");
20901                 }
20902                 tmp = triple_to_lattice(state, scc, slot[index]);
20903                 /* meet(X, lattice low) = lattice low */
20904                 if (is_lattice_lo(state, tmp)) {
20905                         lnode->val = 0;
20906                 }
20907                 /* meet(X, lattice high) = X */
20908                 else if (is_lattice_hi(state, tmp)) {
20909                         lnode->val = lnode->val;
20910                 }
20911                 /* meet(lattice high, X) = X */
20912                 else if (is_lattice_hi(state, lnode)) {
20913                         lnode->val = dup_triple(state, tmp->val);
20914                         /* Only change the type if necessary */
20915                         if (!is_subset_type(lnode->def->type, tmp->val->type)) {
20916                                 lnode->val->type = lnode->def->type;
20917                         }
20918                 }
20919                 /* meet(const, const) = const or lattice low */
20920                 else if (!constants_equal(state, lnode->val, tmp->val)) {
20921                         lnode->val = 0;
20922                 }
20923
20924                 /* meet(lattice low, X) = lattice low */
20925                 if (is_lattice_lo(state, lnode)) {
20926                         lnode->val = 0;
20927                         break;
20928                 }
20929         }
20930         changed = lval_changed(state, old, lnode);
20931         scc_debug_lnode(state, scc, lnode, changed);
20932
20933         /* If the lattice value has changed update the work lists. */
20934         if (changed) {
20935                 struct ssa_edge *sedge;
20936                 for(sedge = lnode->out; sedge; sedge = sedge->out_next) {
20937                         scc_add_sedge_dst(state, scc, sedge);
20938                 }
20939         }
20940 }
20941
20942
20943 static void scc_visit_expr(struct compile_state *state, struct scc_state *scc,
20944         struct lattice_node *lnode)
20945 {
20946         int changed;
20947
20948         if (!triple_is_def(state, lnode->def)) {
20949                 internal_warning(state, lnode->def, "not visiting an expression?");
20950         }
20951         changed = compute_lnode_val(state, scc, lnode);
20952         scc_debug_lnode(state, scc, lnode, changed);
20953
20954         if (changed) {
20955                 struct ssa_edge *sedge;
20956                 for(sedge = lnode->out; sedge; sedge = sedge->out_next) {
20957                         scc_add_sedge_dst(state, scc, sedge);
20958                 }
20959         }
20960 }
20961
20962 static void scc_writeback_values(
20963         struct compile_state *state, struct scc_state *scc)
20964 {
20965         struct triple *first, *ins;
20966         first = state->first;
20967         ins = first;
20968         do {
20969                 struct lattice_node *lnode;
20970                 lnode = triple_to_lattice(state, scc, ins);
20971                 if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
20972                         if (is_lattice_hi(state, lnode) &&
20973                                 (lnode->val->op != OP_NOOP))
20974                         {
20975                                 struct flow_edge *fedge;
20976                                 int executable;
20977                                 executable = 0;
20978                                 for(fedge = lnode->fblock->in; 
20979                                     !executable && fedge; fedge = fedge->in_next) {
20980                                         executable |= fedge->executable;
20981                                 }
20982                                 if (executable) {
20983                                         internal_warning(state, lnode->def,
20984                                                 "lattice node %d %s->%s still high?",
20985                                                 ins->id, 
20986                                                 tops(lnode->def->op),
20987                                                 tops(lnode->val->op));
20988                                 }
20989                         }
20990                 }
20991
20992                 /* Restore id */
20993                 ins->id = lnode->old_id;
20994                 if (lnode->val && (lnode->val != ins)) {
20995                         /* See if it something I know how to write back */
20996                         switch(lnode->val->op) {
20997                         case OP_INTCONST:
20998                                 mkconst(state, ins, lnode->val->u.cval);
20999                                 break;
21000                         case OP_ADDRCONST:
21001                                 mkaddr_const(state, ins, 
21002                                         MISC(lnode->val, 0), lnode->val->u.cval);
21003                                 break;
21004                         default:
21005                                 /* By default don't copy the changes,
21006                                  * recompute them in place instead.
21007                                  */
21008                                 simplify(state, ins);
21009                                 break;
21010                         }
21011                         if (is_const(lnode->val) &&
21012                                 !constants_equal(state, lnode->val, ins)) {
21013                                 internal_error(state, 0, "constants not equal");
21014                         }
21015                         /* Free the lattice nodes */
21016                         xfree(lnode->val);
21017                         lnode->val = 0;
21018                 }
21019                 ins = ins->next;
21020         } while(ins != first);
21021 }
21022
21023 static void scc_transform(struct compile_state *state)
21024 {
21025         struct scc_state scc;
21026         if (!(state->compiler->flags & COMPILER_SCC_TRANSFORM)) {
21027                 return;
21028         }
21029
21030         initialize_scc_state(state, &scc);
21031
21032         while(scc.flow_work_list || scc.ssa_work_list) {
21033                 struct flow_edge *fedge;
21034                 struct ssa_edge *sedge;
21035                 struct flow_edge *fptr;
21036                 while((fedge = scc_next_fedge(state, &scc))) {
21037                         struct block *block;
21038                         struct triple *ptr;
21039                         struct flow_block *fblock;
21040                         int reps;
21041                         int done;
21042                         if (fedge->executable) {
21043                                 continue;
21044                         }
21045                         if (!fedge->dst) {
21046                                 internal_error(state, 0, "fedge without dst");
21047                         }
21048                         if (!fedge->src) {
21049                                 internal_error(state, 0, "fedge without src");
21050                         }
21051                         fedge->executable = 1;
21052                         fblock = fedge->dst;
21053                         block = fblock->block;
21054                         reps = 0;
21055                         for(fptr = fblock->in; fptr; fptr = fptr->in_next) {
21056                                 if (fptr->executable) {
21057                                         reps++;
21058                                 }
21059                         }
21060                         
21061                         if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
21062                                 fprintf(state->errout, "vertex: %d reps: %d\n", 
21063                                         block->vertex, reps);
21064                         }
21065
21066                         done = 0;
21067                         for(ptr = block->first; !done; ptr = ptr->next) {
21068                                 struct lattice_node *lnode;
21069                                 done = (ptr == block->last);
21070                                 lnode = &scc.lattice[ptr->id];
21071                                 if (ptr->op == OP_PHI) {
21072                                         scc_visit_phi(state, &scc, lnode);
21073                                 }
21074                                 else if ((reps == 1) && triple_is_def(state, ptr))
21075                                 {
21076                                         scc_visit_expr(state, &scc, lnode);
21077                                 }
21078                         }
21079                         /* Add unconditional branch edges */
21080                         if (!triple_is_cbranch(state, fblock->block->last)) {
21081                                 struct flow_edge *out;
21082                                 for(out = fblock->out; out; out = out->out_next) {
21083                                         scc_add_fedge(state, &scc, out);
21084                                 }
21085                         }
21086                 }
21087                 while((sedge = scc_next_sedge(state, &scc))) {
21088                         struct lattice_node *lnode;
21089                         struct flow_block *fblock;
21090                         lnode = sedge->dst;
21091                         fblock = lnode->fblock;
21092
21093                         if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
21094                                 fprintf(state->errout, "sedge: %5ld (%5d -> %5d)\n",
21095                                         sedge - scc.ssa_edges,
21096                                         sedge->src->def->id,
21097                                         sedge->dst->def->id);
21098                         }
21099
21100                         if (lnode->def->op == OP_PHI) {
21101                                 scc_visit_phi(state, &scc, lnode);
21102                         }
21103                         else {
21104                                 for(fptr = fblock->in; fptr; fptr = fptr->in_next) {
21105                                         if (fptr->executable) {
21106                                                 break;
21107                                         }
21108                                 }
21109                                 if (fptr) {
21110                                         scc_visit_expr(state, &scc, lnode);
21111                                 }
21112                         }
21113                 }
21114         }
21115         
21116         scc_writeback_values(state, &scc);
21117         free_scc_state(state, &scc);
21118         rebuild_ssa_form(state);
21119         
21120         print_blocks(state, __func__, state->dbgout);
21121 }
21122
21123
21124 static void transform_to_arch_instructions(struct compile_state *state)
21125 {
21126         struct triple *ins, *first;
21127         first = state->first;
21128         ins = first;
21129         do {
21130                 ins = transform_to_arch_instruction(state, ins);
21131         } while(ins != first);
21132         
21133         print_blocks(state, __func__, state->dbgout);
21134 }
21135
21136 #if DEBUG_CONSISTENCY
21137 static void verify_uses(struct compile_state *state)
21138 {
21139         struct triple *first, *ins;
21140         struct triple_set *set;
21141         first = state->first;
21142         ins = first;
21143         do {
21144                 struct triple **expr;
21145                 expr = triple_rhs(state, ins, 0);
21146                 for(; expr; expr = triple_rhs(state, ins, expr)) {
21147                         struct triple *rhs;
21148                         rhs = *expr;
21149                         for(set = rhs?rhs->use:0; set; set = set->next) {
21150                                 if (set->member == ins) {
21151                                         break;
21152                                 }
21153                         }
21154                         if (!set) {
21155                                 internal_error(state, ins, "rhs not used");
21156                         }
21157                 }
21158                 expr = triple_lhs(state, ins, 0);
21159                 for(; expr; expr = triple_lhs(state, ins, expr)) {
21160                         struct triple *lhs;
21161                         lhs = *expr;
21162                         for(set =  lhs?lhs->use:0; set; set = set->next) {
21163                                 if (set->member == ins) {
21164                                         break;
21165                                 }
21166                         }
21167                         if (!set) {
21168                                 internal_error(state, ins, "lhs not used");
21169                         }
21170                 }
21171                 expr = triple_misc(state, ins, 0);
21172                 if (ins->op != OP_PHI) {
21173                         for(; expr; expr = triple_targ(state, ins, expr)) {
21174                                 struct triple *misc;
21175                                 misc = *expr;
21176                                 for(set = misc?misc->use:0; set; set = set->next) {
21177                                         if (set->member == ins) {
21178                                                 break;
21179                                         }
21180                                 }
21181                                 if (!set) {
21182                                         internal_error(state, ins, "misc not used");
21183                                 }
21184                         }
21185                 }
21186                 if (!triple_is_ret(state, ins)) {
21187                         expr = triple_targ(state, ins, 0);
21188                         for(; expr; expr = triple_targ(state, ins, expr)) {
21189                                 struct triple *targ;
21190                                 targ = *expr;
21191                                 for(set = targ?targ->use:0; set; set = set->next) {
21192                                         if (set->member == ins) {
21193                                                 break;
21194                                         }
21195                                 }
21196                                 if (!set) {
21197                                         internal_error(state, ins, "targ not used");
21198                                 }
21199                         }
21200                 }
21201                 ins = ins->next;
21202         } while(ins != first);
21203         
21204 }
21205 static void verify_blocks_present(struct compile_state *state)
21206 {
21207         struct triple *first, *ins;
21208         if (!state->bb.first_block) {
21209                 return;
21210         }
21211         first = state->first;
21212         ins = first;
21213         do {
21214                 valid_ins(state, ins);
21215                 if (triple_stores_block(state, ins)) {
21216                         if (!ins->u.block) {
21217                                 internal_error(state, ins, 
21218                                         "%p not in a block?", ins);
21219                         }
21220                 }
21221                 ins = ins->next;
21222         } while(ins != first);
21223         
21224         
21225 }
21226
21227 static int edge_present(struct compile_state *state, struct block *block, struct triple *edge)
21228 {
21229         struct block_set *bedge;
21230         struct block *targ;
21231         targ = block_of_triple(state, edge);
21232         for(bedge = block->edges; bedge; bedge = bedge->next) {
21233                 if (bedge->member == targ) {
21234                         return 1;
21235                 }
21236         }
21237         return 0;
21238 }
21239
21240 static void verify_blocks(struct compile_state *state)
21241 {
21242         struct triple *ins;
21243         struct block *block;
21244         int blocks;
21245         block = state->bb.first_block;
21246         if (!block) {
21247                 return;
21248         }
21249         blocks = 0;
21250         do {
21251                 int users;
21252                 struct block_set *user, *edge;
21253                 blocks++;
21254                 for(ins = block->first; ins != block->last->next; ins = ins->next) {
21255                         if (triple_stores_block(state, ins) && (ins->u.block != block)) {
21256                                 internal_error(state, ins, "inconsitent block specified");
21257                         }
21258                         valid_ins(state, ins);
21259                 }
21260                 users = 0;
21261                 for(user = block->use; user; user = user->next) {
21262                         users++;
21263                         if (!user->member->first) {
21264                                 internal_error(state, block->first, "user is empty");
21265                         }
21266                         if ((block == state->bb.last_block) &&
21267                                 (user->member == state->bb.first_block)) {
21268                                 continue;
21269                         }
21270                         for(edge = user->member->edges; edge; edge = edge->next) {
21271                                 if (edge->member == block) {
21272                                         break;
21273                                 }
21274                         }
21275                         if (!edge) {
21276                                 internal_error(state, user->member->first,
21277                                         "user does not use block");
21278                         }
21279                 }
21280                 if (triple_is_branch(state, block->last)) {
21281                         struct triple **expr;
21282                         expr = triple_edge_targ(state, block->last, 0);
21283                         for(;expr; expr = triple_edge_targ(state, block->last, expr)) {
21284                                 if (*expr && !edge_present(state, block, *expr)) {
21285                                         internal_error(state, block->last, "no edge to targ");
21286                                 }
21287                         }
21288                 }
21289                 if (!triple_is_ubranch(state, block->last) &&
21290                         (block != state->bb.last_block) &&
21291                         !edge_present(state, block, block->last->next)) {
21292                         internal_error(state, block->last, "no edge to block->last->next");
21293                 }
21294                 for(edge = block->edges; edge; edge = edge->next) {
21295                         for(user = edge->member->use; user; user = user->next) {
21296                                 if (user->member == block) {
21297                                         break;
21298                                 }
21299                         }
21300                         if (!user || user->member != block) {
21301                                 internal_error(state, block->first,
21302                                         "block does not use edge");
21303                         }
21304                         if (!edge->member->first) {
21305                                 internal_error(state, block->first, "edge block is empty");
21306                         }
21307                 }
21308                 if (block->users != users) {
21309                         internal_error(state, block->first, 
21310                                 "computed users %d != stored users %d",
21311                                 users, block->users);
21312                 }
21313                 if (!triple_stores_block(state, block->last->next)) {
21314                         internal_error(state, block->last->next, 
21315                                 "cannot find next block");
21316                 }
21317                 block = block->last->next->u.block;
21318                 if (!block) {
21319                         internal_error(state, block->last->next,
21320                                 "bad next block");
21321                 }
21322         } while(block != state->bb.first_block);
21323         if (blocks != state->bb.last_vertex) {
21324                 internal_error(state, 0, "computed blocks: %d != stored blocks %d",
21325                         blocks, state->bb.last_vertex);
21326         }
21327 }
21328
21329 static void verify_domination(struct compile_state *state)
21330 {
21331         struct triple *first, *ins;
21332         struct triple_set *set;
21333         if (!state->bb.first_block) {
21334                 return;
21335         }
21336         
21337         first = state->first;
21338         ins = first;
21339         do {
21340                 for(set = ins->use; set; set = set->next) {
21341                         struct triple **slot;
21342                         struct triple *use_point;
21343                         int i, zrhs;
21344                         use_point = 0;
21345                         zrhs = set->member->rhs;
21346                         slot = &RHS(set->member, 0);
21347                         /* See if the use is on the right hand side */
21348                         for(i = 0; i < zrhs; i++) {
21349                                 if (slot[i] == ins) {
21350                                         break;
21351                                 }
21352                         }
21353                         if (i < zrhs) {
21354                                 use_point = set->member;
21355                                 if (set->member->op == OP_PHI) {
21356                                         struct block_set *bset;
21357                                         int edge;
21358                                         bset = set->member->u.block->use;
21359                                         for(edge = 0; bset && (edge < i); edge++) {
21360                                                 bset = bset->next;
21361                                         }
21362                                         if (!bset) {
21363                                                 internal_error(state, set->member, 
21364                                                         "no edge for phi rhs %d", i);
21365                                         }
21366                                         use_point = bset->member->last;
21367                                 }
21368                         }
21369                         if (use_point &&
21370                                 !tdominates(state, ins, use_point)) {
21371                                 if (is_const(ins)) {
21372                                         internal_warning(state, ins, 
21373                                         "non dominated rhs use point %p?", use_point);
21374                                 }
21375                                 else {
21376                                         internal_error(state, ins, 
21377                                                 "non dominated rhs use point %p?", use_point);
21378                                 }
21379                         }
21380                 }
21381                 ins = ins->next;
21382         } while(ins != first);
21383 }
21384
21385 static void verify_rhs(struct compile_state *state)
21386 {
21387         struct triple *first, *ins;
21388         first = state->first;
21389         ins = first;
21390         do {
21391                 struct triple **slot;
21392                 int zrhs, i;
21393                 zrhs = ins->rhs;
21394                 slot = &RHS(ins, 0);
21395                 for(i = 0; i < zrhs; i++) {
21396                         if (slot[i] == 0) {
21397                                 internal_error(state, ins,
21398                                         "missing rhs %d on %s",
21399                                         i, tops(ins->op));
21400                         }
21401                         if ((ins->op != OP_PHI) && (slot[i] == ins)) {
21402                                 internal_error(state, ins,
21403                                         "ins == rhs[%d] on %s",
21404                                         i, tops(ins->op));
21405                         }
21406                 }
21407                 ins = ins->next;
21408         } while(ins != first);
21409 }
21410
21411 static void verify_piece(struct compile_state *state)
21412 {
21413         struct triple *first, *ins;
21414         first = state->first;
21415         ins = first;
21416         do {
21417                 struct triple *ptr;
21418                 int lhs, i;
21419                 lhs = ins->lhs;
21420                 for(ptr = ins->next, i = 0; i < lhs; i++, ptr = ptr->next) {
21421                         if (ptr != LHS(ins, i)) {
21422                                 internal_error(state, ins, "malformed lhs on %s",
21423                                         tops(ins->op));
21424                         }
21425                         if (ptr->op != OP_PIECE) {
21426                                 internal_error(state, ins, "bad lhs op %s at %d on %s",
21427                                         tops(ptr->op), i, tops(ins->op));
21428                         }
21429                         if (ptr->u.cval != i) {
21430                                 internal_error(state, ins, "bad u.cval of %d %d expected",
21431                                         ptr->u.cval, i);
21432                         }
21433                 }
21434                 ins = ins->next;
21435         } while(ins != first);
21436 }
21437
21438 static void verify_ins_colors(struct compile_state *state)
21439 {
21440         struct triple *first, *ins;
21441         
21442         first = state->first;
21443         ins = first;
21444         do {
21445                 ins = ins->next;
21446         } while(ins != first);
21447 }
21448
21449 static void verify_unknown(struct compile_state *state)
21450 {
21451         struct triple *first, *ins;
21452         if (    (unknown_triple.next != &unknown_triple) ||
21453                 (unknown_triple.prev != &unknown_triple) ||
21454 #if 0
21455                 (unknown_triple.use != 0) ||
21456 #endif
21457                 (unknown_triple.op != OP_UNKNOWNVAL) ||
21458                 (unknown_triple.lhs != 0) ||
21459                 (unknown_triple.rhs != 0) ||
21460                 (unknown_triple.misc != 0) ||
21461                 (unknown_triple.targ != 0) ||
21462                 (unknown_triple.template_id != 0) ||
21463                 (unknown_triple.id != -1) ||
21464                 (unknown_triple.type != &unknown_type) ||
21465                 (unknown_triple.occurance != &dummy_occurance) ||
21466                 (unknown_triple.param[0] != 0) ||
21467                 (unknown_triple.param[1] != 0)) {
21468                 internal_error(state, &unknown_triple, "unknown_triple corrupted!");
21469         }
21470         if (    (dummy_occurance.count != 2) ||
21471                 (strcmp(dummy_occurance.filename, __FILE__) != 0) ||
21472                 (strcmp(dummy_occurance.function, "") != 0) ||
21473                 (dummy_occurance.col != 0) ||
21474                 (dummy_occurance.parent != 0)) {
21475                 internal_error(state, &unknown_triple, "dummy_occurance corrupted!");
21476         }
21477         if (    (unknown_type.type != TYPE_UNKNOWN)) {
21478                 internal_error(state, &unknown_triple, "unknown_type corrupted!");
21479         }
21480         first = state->first;
21481         ins = first;
21482         do {
21483                 int params, i;
21484                 if (ins == &unknown_triple) {
21485                         internal_error(state, ins, "unknown triple in list");
21486                 }
21487                 params = TRIPLE_SIZE(ins);
21488                 for(i = 0; i < params; i++) {
21489                         if (ins->param[i] == &unknown_triple) {
21490                                 internal_error(state, ins, "unknown triple used!");
21491                         }
21492                 }
21493                 ins = ins->next;
21494         } while(ins != first);
21495 }
21496
21497 static void verify_types(struct compile_state *state)
21498 {
21499         struct triple *first, *ins;
21500         first = state->first;
21501         ins = first;
21502         do {
21503                 struct type *invalid;
21504                 invalid = invalid_type(state, ins->type);
21505                 if (invalid) {
21506                         FILE *fp = state->errout;
21507                         fprintf(fp, "type: ");
21508                         name_of(fp, ins->type);
21509                         fprintf(fp, "\n");
21510                         fprintf(fp, "invalid type: ");
21511                         name_of(fp, invalid);
21512                         fprintf(fp, "\n");
21513                         internal_error(state, ins, "invalid ins type");
21514                 }
21515         } while(ins != first);
21516 }
21517
21518 static void verify_copy(struct compile_state *state)
21519 {
21520         struct triple *first, *ins, *next;
21521         first = state->first;
21522         next = ins = first;
21523         do {
21524                 ins = next;
21525                 next = ins->next;
21526                 if (ins->op != OP_COPY) {
21527                         continue;
21528                 }
21529                 if (!equiv_types(ins->type, RHS(ins, 0)->type)) {
21530                         FILE *fp = state->errout;
21531                         fprintf(fp, "src type: ");
21532                         name_of(fp, RHS(ins, 0)->type);
21533                         fprintf(fp, "\n");
21534                         fprintf(fp, "dst type: ");
21535                         name_of(fp, ins->type);
21536                         fprintf(fp, "\n");
21537                         internal_error(state, ins, "type mismatch in copy");
21538                 }
21539         } while(next != first);
21540 }
21541
21542 static void verify_consistency(struct compile_state *state)
21543 {
21544         verify_unknown(state);
21545         verify_uses(state);
21546         verify_blocks_present(state);
21547         verify_blocks(state);
21548         verify_domination(state);
21549         verify_rhs(state);
21550         verify_piece(state);
21551         verify_ins_colors(state);
21552         verify_types(state);
21553         verify_copy(state);
21554         if (state->compiler->debug & DEBUG_VERIFICATION) {
21555                 fprintf(state->dbgout, "consistency verified\n");
21556         }
21557 }
21558 #else 
21559 static void verify_consistency(struct compile_state *state) {}
21560 #endif /* DEBUG_CONSISTENCY */
21561
21562 static void optimize(struct compile_state *state)
21563 {
21564         /* Join all of the functions into one giant function */
21565         join_functions(state);
21566
21567         /* Dump what the instruction graph intially looks like */
21568         print_triples(state);
21569
21570         /* Replace structures with simpler data types */
21571         decompose_compound_types(state);
21572         print_triples(state);
21573
21574         verify_consistency(state);
21575         /* Analyze the intermediate code */
21576         state->bb.first = state->first;
21577         analyze_basic_blocks(state, &state->bb);
21578
21579         /* Transform the code to ssa form. */
21580         /*
21581          * The transformation to ssa form puts a phi function
21582          * on each of edge of a dominance frontier where that
21583          * phi function might be needed.  At -O2 if we don't
21584          * eleminate the excess phi functions we can get an
21585          * exponential code size growth.  So I kill the extra
21586          * phi functions early and I kill them often.
21587          */
21588         transform_to_ssa_form(state);
21589         verify_consistency(state);
21590
21591         /* Remove dead code */
21592         eliminate_inefectual_code(state);
21593         verify_consistency(state);
21594
21595         /* Do strength reduction and simple constant optimizations */
21596         simplify_all(state);
21597         verify_consistency(state);
21598         /* Propogate constants throughout the code */
21599         scc_transform(state);
21600         verify_consistency(state);
21601 #if DEBUG_ROMCC_WARNINGS
21602 #warning "WISHLIST implement single use constants (least possible register pressure)"
21603 #warning "WISHLIST implement induction variable elimination"
21604 #endif
21605         /* Select architecture instructions and an initial partial
21606          * coloring based on architecture constraints.
21607          */
21608         transform_to_arch_instructions(state);
21609         verify_consistency(state);
21610
21611         /* Remove dead code */
21612         eliminate_inefectual_code(state);
21613         verify_consistency(state);
21614
21615         /* Color all of the variables to see if they will fit in registers */
21616         insert_copies_to_phi(state);
21617         verify_consistency(state);
21618
21619         insert_mandatory_copies(state);
21620         verify_consistency(state);
21621
21622         allocate_registers(state);
21623         verify_consistency(state);
21624
21625         /* Remove the optimization information.
21626          * This is more to check for memory consistency than to free memory.
21627          */
21628         free_basic_blocks(state, &state->bb);
21629 }
21630
21631 static void print_op_asm(struct compile_state *state,
21632         struct triple *ins, FILE *fp)
21633 {
21634         struct asm_info *info;
21635         const char *ptr;
21636         unsigned lhs, rhs, i;
21637         info = ins->u.ainfo;
21638         lhs = ins->lhs;
21639         rhs = ins->rhs;
21640         /* Don't count the clobbers in lhs */
21641         for(i = 0; i < lhs; i++) {
21642                 if (LHS(ins, i)->type == &void_type) {
21643                         break;
21644                 }
21645         }
21646         lhs = i;
21647         fprintf(fp, "#ASM\n");
21648         fputc('\t', fp);
21649         for(ptr = info->str; *ptr; ptr++) {
21650                 char *next;
21651                 unsigned long param;
21652                 struct triple *piece;
21653                 if (*ptr != '%') {
21654                         fputc(*ptr, fp);
21655                         continue;
21656                 }
21657                 ptr++;
21658                 if (*ptr == '%') {
21659                         fputc('%', fp);
21660                         continue;
21661                 }
21662                 param = strtoul(ptr, &next, 10);
21663                 if (ptr == next) {
21664                         error(state, ins, "Invalid asm template");
21665                 }
21666                 if (param >= (lhs + rhs)) {
21667                         error(state, ins, "Invalid param %%%u in asm template",
21668                                 param);
21669                 }
21670                 piece = (param < lhs)? LHS(ins, param) : RHS(ins, param - lhs);
21671                 fprintf(fp, "%s", 
21672                         arch_reg_str(ID_REG(piece->id)));
21673                 ptr = next -1;
21674         }
21675         fprintf(fp, "\n#NOT ASM\n");
21676 }
21677
21678
21679 /* Only use the low x86 byte registers.  This allows me
21680  * allocate the entire register when a byte register is used.
21681  */
21682 #define X86_4_8BIT_GPRS 1
21683
21684 /* x86 featrues */
21685 #define X86_MMX_REGS  (1<<0)
21686 #define X86_XMM_REGS  (1<<1)
21687 #define X86_NOOP_COPY (1<<2)
21688
21689 /* The x86 register classes */
21690 #define REGC_FLAGS       0
21691 #define REGC_GPR8        1
21692 #define REGC_GPR16       2
21693 #define REGC_GPR32       3
21694 #define REGC_DIVIDEND64  4
21695 #define REGC_DIVIDEND32  5
21696 #define REGC_MMX         6
21697 #define REGC_XMM         7
21698 #define REGC_GPR32_8     8
21699 #define REGC_GPR16_8     9
21700 #define REGC_GPR8_LO    10
21701 #define REGC_IMM32      11
21702 #define REGC_IMM16      12
21703 #define REGC_IMM8       13
21704 #define LAST_REGC  REGC_IMM8
21705 #if LAST_REGC >= MAX_REGC
21706 #error "MAX_REGC is to low"
21707 #endif
21708
21709 /* Register class masks */
21710 #define REGCM_FLAGS      (1 << REGC_FLAGS)
21711 #define REGCM_GPR8       (1 << REGC_GPR8)
21712 #define REGCM_GPR16      (1 << REGC_GPR16)
21713 #define REGCM_GPR32      (1 << REGC_GPR32)
21714 #define REGCM_DIVIDEND64 (1 << REGC_DIVIDEND64)
21715 #define REGCM_DIVIDEND32 (1 << REGC_DIVIDEND32)
21716 #define REGCM_MMX        (1 << REGC_MMX)
21717 #define REGCM_XMM        (1 << REGC_XMM)
21718 #define REGCM_GPR32_8    (1 << REGC_GPR32_8)
21719 #define REGCM_GPR16_8    (1 << REGC_GPR16_8)
21720 #define REGCM_GPR8_LO    (1 << REGC_GPR8_LO)
21721 #define REGCM_IMM32      (1 << REGC_IMM32)
21722 #define REGCM_IMM16      (1 << REGC_IMM16)
21723 #define REGCM_IMM8       (1 << REGC_IMM8)
21724 #define REGCM_ALL        ((1 << (LAST_REGC + 1)) - 1)
21725 #define REGCM_IMMALL    (REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8)
21726
21727 /* The x86 registers */
21728 #define REG_EFLAGS  2
21729 #define REGC_FLAGS_FIRST REG_EFLAGS
21730 #define REGC_FLAGS_LAST  REG_EFLAGS
21731 #define REG_AL      3
21732 #define REG_BL      4
21733 #define REG_CL      5
21734 #define REG_DL      6
21735 #define REG_AH      7
21736 #define REG_BH      8
21737 #define REG_CH      9
21738 #define REG_DH      10
21739 #define REGC_GPR8_LO_FIRST REG_AL
21740 #define REGC_GPR8_LO_LAST  REG_DL
21741 #define REGC_GPR8_FIRST  REG_AL
21742 #define REGC_GPR8_LAST   REG_DH
21743 #define REG_AX     11
21744 #define REG_BX     12
21745 #define REG_CX     13
21746 #define REG_DX     14
21747 #define REG_SI     15
21748 #define REG_DI     16
21749 #define REG_BP     17
21750 #define REG_SP     18
21751 #define REGC_GPR16_FIRST REG_AX
21752 #define REGC_GPR16_LAST  REG_SP
21753 #define REG_EAX    19
21754 #define REG_EBX    20
21755 #define REG_ECX    21
21756 #define REG_EDX    22
21757 #define REG_ESI    23
21758 #define REG_EDI    24
21759 #define REG_EBP    25
21760 #define REG_ESP    26
21761 #define REGC_GPR32_FIRST REG_EAX
21762 #define REGC_GPR32_LAST  REG_ESP
21763 #define REG_EDXEAX 27
21764 #define REGC_DIVIDEND64_FIRST REG_EDXEAX
21765 #define REGC_DIVIDEND64_LAST  REG_EDXEAX
21766 #define REG_DXAX   28
21767 #define REGC_DIVIDEND32_FIRST REG_DXAX
21768 #define REGC_DIVIDEND32_LAST  REG_DXAX
21769 #define REG_MMX0   29
21770 #define REG_MMX1   30
21771 #define REG_MMX2   31
21772 #define REG_MMX3   32
21773 #define REG_MMX4   33
21774 #define REG_MMX5   34
21775 #define REG_MMX6   35
21776 #define REG_MMX7   36
21777 #define REGC_MMX_FIRST REG_MMX0
21778 #define REGC_MMX_LAST  REG_MMX7
21779 #define REG_XMM0   37
21780 #define REG_XMM1   38
21781 #define REG_XMM2   39
21782 #define REG_XMM3   40
21783 #define REG_XMM4   41
21784 #define REG_XMM5   42
21785 #define REG_XMM6   43
21786 #define REG_XMM7   44
21787 #define REGC_XMM_FIRST REG_XMM0
21788 #define REGC_XMM_LAST  REG_XMM7
21789
21790 #if DEBUG_ROMCC_WARNINGS
21791 #warning "WISHLIST figure out how to use pinsrw and pextrw to better use extended regs"
21792 #endif
21793
21794 #define LAST_REG   REG_XMM7
21795
21796 #define REGC_GPR32_8_FIRST REG_EAX
21797 #define REGC_GPR32_8_LAST  REG_EDX
21798 #define REGC_GPR16_8_FIRST REG_AX
21799 #define REGC_GPR16_8_LAST  REG_DX
21800
21801 #define REGC_IMM8_FIRST    -1
21802 #define REGC_IMM8_LAST     -1
21803 #define REGC_IMM16_FIRST   -2
21804 #define REGC_IMM16_LAST    -1
21805 #define REGC_IMM32_FIRST   -4
21806 #define REGC_IMM32_LAST    -1
21807
21808 #if LAST_REG >= MAX_REGISTERS
21809 #error "MAX_REGISTERS to low"
21810 #endif
21811
21812
21813 static unsigned regc_size[LAST_REGC +1] = {
21814         [REGC_FLAGS]      = REGC_FLAGS_LAST      - REGC_FLAGS_FIRST + 1,
21815         [REGC_GPR8]       = REGC_GPR8_LAST       - REGC_GPR8_FIRST + 1,
21816         [REGC_GPR16]      = REGC_GPR16_LAST      - REGC_GPR16_FIRST + 1,
21817         [REGC_GPR32]      = REGC_GPR32_LAST      - REGC_GPR32_FIRST + 1,
21818         [REGC_DIVIDEND64] = REGC_DIVIDEND64_LAST - REGC_DIVIDEND64_FIRST + 1,
21819         [REGC_DIVIDEND32] = REGC_DIVIDEND32_LAST - REGC_DIVIDEND32_FIRST + 1,
21820         [REGC_MMX]        = REGC_MMX_LAST        - REGC_MMX_FIRST + 1,
21821         [REGC_XMM]        = REGC_XMM_LAST        - REGC_XMM_FIRST + 1,
21822         [REGC_GPR32_8]    = REGC_GPR32_8_LAST    - REGC_GPR32_8_FIRST + 1,
21823         [REGC_GPR16_8]    = REGC_GPR16_8_LAST    - REGC_GPR16_8_FIRST + 1,
21824         [REGC_GPR8_LO]    = REGC_GPR8_LO_LAST    - REGC_GPR8_LO_FIRST + 1,
21825         [REGC_IMM32]      = 0,
21826         [REGC_IMM16]      = 0,
21827         [REGC_IMM8]       = 0,
21828 };
21829
21830 static const struct {
21831         int first, last;
21832 } regcm_bound[LAST_REGC + 1] = {
21833         [REGC_FLAGS]      = { REGC_FLAGS_FIRST,      REGC_FLAGS_LAST },
21834         [REGC_GPR8]       = { REGC_GPR8_FIRST,       REGC_GPR8_LAST },
21835         [REGC_GPR16]      = { REGC_GPR16_FIRST,      REGC_GPR16_LAST },
21836         [REGC_GPR32]      = { REGC_GPR32_FIRST,      REGC_GPR32_LAST },
21837         [REGC_DIVIDEND64] = { REGC_DIVIDEND64_FIRST, REGC_DIVIDEND64_LAST },
21838         [REGC_DIVIDEND32] = { REGC_DIVIDEND32_FIRST, REGC_DIVIDEND32_LAST },
21839         [REGC_MMX]        = { REGC_MMX_FIRST,        REGC_MMX_LAST },
21840         [REGC_XMM]        = { REGC_XMM_FIRST,        REGC_XMM_LAST },
21841         [REGC_GPR32_8]    = { REGC_GPR32_8_FIRST,    REGC_GPR32_8_LAST },
21842         [REGC_GPR16_8]    = { REGC_GPR16_8_FIRST,    REGC_GPR16_8_LAST },
21843         [REGC_GPR8_LO]    = { REGC_GPR8_LO_FIRST,    REGC_GPR8_LO_LAST },
21844         [REGC_IMM32]      = { REGC_IMM32_FIRST,      REGC_IMM32_LAST },
21845         [REGC_IMM16]      = { REGC_IMM16_FIRST,      REGC_IMM16_LAST },
21846         [REGC_IMM8]       = { REGC_IMM8_FIRST,       REGC_IMM8_LAST },
21847 };
21848
21849 #if ARCH_INPUT_REGS != 4
21850 #error ARCH_INPUT_REGS size mismatch
21851 #endif
21852 static const struct reg_info arch_input_regs[ARCH_INPUT_REGS] = {
21853         { .reg = REG_EAX, .regcm = REGCM_GPR32 },
21854         { .reg = REG_EBX, .regcm = REGCM_GPR32 },
21855         { .reg = REG_ECX, .regcm = REGCM_GPR32 },
21856         { .reg = REG_EDX, .regcm = REGCM_GPR32 },
21857 };
21858
21859 #if ARCH_OUTPUT_REGS != 4
21860 #error ARCH_INPUT_REGS size mismatch
21861 #endif
21862 static const struct reg_info arch_output_regs[ARCH_OUTPUT_REGS] = {
21863         { .reg = REG_EAX, .regcm = REGCM_GPR32 },
21864         { .reg = REG_EBX, .regcm = REGCM_GPR32 },
21865         { .reg = REG_ECX, .regcm = REGCM_GPR32 },
21866         { .reg = REG_EDX, .regcm = REGCM_GPR32 },
21867 };
21868
21869 static void init_arch_state(struct arch_state *arch)
21870 {
21871         memset(arch, 0, sizeof(*arch));
21872         arch->features = 0;
21873 }
21874
21875 static const struct compiler_flag arch_flags[] = {
21876         { "mmx",       X86_MMX_REGS },
21877         { "sse",       X86_XMM_REGS },
21878         { "noop-copy", X86_NOOP_COPY },
21879         { 0,     0 },
21880 };
21881 static const struct compiler_flag arch_cpus[] = {
21882         { "i386", 0 },
21883         { "p2",   X86_MMX_REGS },
21884         { "p3",   X86_MMX_REGS | X86_XMM_REGS },
21885         { "p4",   X86_MMX_REGS | X86_XMM_REGS },
21886         { "k7",   X86_MMX_REGS },
21887         { "k8",   X86_MMX_REGS | X86_XMM_REGS },
21888         { "c3",   X86_MMX_REGS },
21889         { "c3-2", X86_MMX_REGS | X86_XMM_REGS }, /* Nehemiah */
21890         {  0,     0 }
21891 };
21892 static int arch_encode_flag(struct arch_state *arch, const char *flag)
21893 {
21894         int result;
21895         int act;
21896
21897         act = 1;
21898         result = -1;
21899         if (strncmp(flag, "no-", 3) == 0) {
21900                 flag += 3;
21901                 act = 0;
21902         }
21903         if (act && strncmp(flag, "cpu=", 4) == 0) {
21904                 flag += 4;
21905                 result = set_flag(arch_cpus, &arch->features, 1, flag);
21906         }
21907         else {
21908                 result = set_flag(arch_flags, &arch->features, act, flag);
21909         }
21910         return result;
21911 }
21912
21913 static void arch_usage(FILE *fp)
21914 {
21915         flag_usage(fp, arch_flags, "-m", "-mno-");
21916         flag_usage(fp, arch_cpus, "-mcpu=", 0);
21917 }
21918
21919 static unsigned arch_regc_size(struct compile_state *state, int class)
21920 {
21921         if ((class < 0) || (class > LAST_REGC)) {
21922                 return 0;
21923         }
21924         return regc_size[class];
21925 }
21926
21927 static int arch_regcm_intersect(unsigned regcm1, unsigned regcm2)
21928 {
21929         /* See if two register classes may have overlapping registers */
21930         unsigned gpr_mask = REGCM_GPR8 | REGCM_GPR8_LO | REGCM_GPR16_8 | REGCM_GPR16 |
21931                 REGCM_GPR32_8 | REGCM_GPR32 | 
21932                 REGCM_DIVIDEND32 | REGCM_DIVIDEND64;
21933
21934         /* Special case for the immediates */
21935         if ((regcm1 & (REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8)) &&
21936                 ((regcm1 & ~(REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8)) == 0) &&
21937                 (regcm2 & (REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8)) &&
21938                 ((regcm2 & ~(REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8)) == 0)) { 
21939                 return 0;
21940         }
21941         return (regcm1 & regcm2) ||
21942                 ((regcm1 & gpr_mask) && (regcm2 & gpr_mask));
21943 }
21944
21945 static void arch_reg_equivs(
21946         struct compile_state *state, unsigned *equiv, int reg)
21947 {
21948         if ((reg < 0) || (reg > LAST_REG)) {
21949                 internal_error(state, 0, "invalid register");
21950         }
21951         *equiv++ = reg;
21952         switch(reg) {
21953         case REG_AL:
21954 #if X86_4_8BIT_GPRS
21955                 *equiv++ = REG_AH;
21956 #endif
21957                 *equiv++ = REG_AX;
21958                 *equiv++ = REG_EAX;
21959                 *equiv++ = REG_DXAX;
21960                 *equiv++ = REG_EDXEAX;
21961                 break;
21962         case REG_AH:
21963 #if X86_4_8BIT_GPRS
21964                 *equiv++ = REG_AL;
21965 #endif
21966                 *equiv++ = REG_AX;
21967                 *equiv++ = REG_EAX;
21968                 *equiv++ = REG_DXAX;
21969                 *equiv++ = REG_EDXEAX;
21970                 break;
21971         case REG_BL:  
21972 #if X86_4_8BIT_GPRS
21973                 *equiv++ = REG_BH;
21974 #endif
21975                 *equiv++ = REG_BX;
21976                 *equiv++ = REG_EBX;
21977                 break;
21978
21979         case REG_BH:
21980 #if X86_4_8BIT_GPRS
21981                 *equiv++ = REG_BL;
21982 #endif
21983                 *equiv++ = REG_BX;
21984                 *equiv++ = REG_EBX;
21985                 break;
21986         case REG_CL:
21987 #if X86_4_8BIT_GPRS
21988                 *equiv++ = REG_CH;
21989 #endif
21990                 *equiv++ = REG_CX;
21991                 *equiv++ = REG_ECX;
21992                 break;
21993
21994         case REG_CH:
21995 #if X86_4_8BIT_GPRS
21996                 *equiv++ = REG_CL;
21997 #endif
21998                 *equiv++ = REG_CX;
21999                 *equiv++ = REG_ECX;
22000                 break;
22001         case REG_DL:
22002 #if X86_4_8BIT_GPRS
22003                 *equiv++ = REG_DH;
22004 #endif
22005                 *equiv++ = REG_DX;
22006                 *equiv++ = REG_EDX;
22007                 *equiv++ = REG_DXAX;
22008                 *equiv++ = REG_EDXEAX;
22009                 break;
22010         case REG_DH:
22011 #if X86_4_8BIT_GPRS
22012                 *equiv++ = REG_DL;
22013 #endif
22014                 *equiv++ = REG_DX;
22015                 *equiv++ = REG_EDX;
22016                 *equiv++ = REG_DXAX;
22017                 *equiv++ = REG_EDXEAX;
22018                 break;
22019         case REG_AX:
22020                 *equiv++ = REG_AL;
22021                 *equiv++ = REG_AH;
22022                 *equiv++ = REG_EAX;
22023                 *equiv++ = REG_DXAX;
22024                 *equiv++ = REG_EDXEAX;
22025                 break;
22026         case REG_BX:
22027                 *equiv++ = REG_BL;
22028                 *equiv++ = REG_BH;
22029                 *equiv++ = REG_EBX;
22030                 break;
22031         case REG_CX:  
22032                 *equiv++ = REG_CL;
22033                 *equiv++ = REG_CH;
22034                 *equiv++ = REG_ECX;
22035                 break;
22036         case REG_DX:  
22037                 *equiv++ = REG_DL;
22038                 *equiv++ = REG_DH;
22039                 *equiv++ = REG_EDX;
22040                 *equiv++ = REG_DXAX;
22041                 *equiv++ = REG_EDXEAX;
22042                 break;
22043         case REG_SI:  
22044                 *equiv++ = REG_ESI;
22045                 break;
22046         case REG_DI:
22047                 *equiv++ = REG_EDI;
22048                 break;
22049         case REG_BP:
22050                 *equiv++ = REG_EBP;
22051                 break;
22052         case REG_SP:
22053                 *equiv++ = REG_ESP;
22054                 break;
22055         case REG_EAX:
22056                 *equiv++ = REG_AL;
22057                 *equiv++ = REG_AH;
22058                 *equiv++ = REG_AX;
22059                 *equiv++ = REG_DXAX;
22060                 *equiv++ = REG_EDXEAX;
22061                 break;
22062         case REG_EBX:
22063                 *equiv++ = REG_BL;
22064                 *equiv++ = REG_BH;
22065                 *equiv++ = REG_BX;
22066                 break;
22067         case REG_ECX:
22068                 *equiv++ = REG_CL;
22069                 *equiv++ = REG_CH;
22070                 *equiv++ = REG_CX;
22071                 break;
22072         case REG_EDX:
22073                 *equiv++ = REG_DL;
22074                 *equiv++ = REG_DH;
22075                 *equiv++ = REG_DX;
22076                 *equiv++ = REG_DXAX;
22077                 *equiv++ = REG_EDXEAX;
22078                 break;
22079         case REG_ESI: 
22080                 *equiv++ = REG_SI;
22081                 break;
22082         case REG_EDI: 
22083                 *equiv++ = REG_DI;
22084                 break;
22085         case REG_EBP: 
22086                 *equiv++ = REG_BP;
22087                 break;
22088         case REG_ESP: 
22089                 *equiv++ = REG_SP;
22090                 break;
22091         case REG_DXAX: 
22092                 *equiv++ = REG_AL;
22093                 *equiv++ = REG_AH;
22094                 *equiv++ = REG_DL;
22095                 *equiv++ = REG_DH;
22096                 *equiv++ = REG_AX;
22097                 *equiv++ = REG_DX;
22098                 *equiv++ = REG_EAX;
22099                 *equiv++ = REG_EDX;
22100                 *equiv++ = REG_EDXEAX;
22101                 break;
22102         case REG_EDXEAX: 
22103                 *equiv++ = REG_AL;
22104                 *equiv++ = REG_AH;
22105                 *equiv++ = REG_DL;
22106                 *equiv++ = REG_DH;
22107                 *equiv++ = REG_AX;
22108                 *equiv++ = REG_DX;
22109                 *equiv++ = REG_EAX;
22110                 *equiv++ = REG_EDX;
22111                 *equiv++ = REG_DXAX;
22112                 break;
22113         }
22114         *equiv++ = REG_UNSET; 
22115 }
22116
22117 static unsigned arch_avail_mask(struct compile_state *state)
22118 {
22119         unsigned avail_mask;
22120         /* REGCM_GPR8 is not available */
22121         avail_mask = REGCM_GPR8_LO | REGCM_GPR16_8 | REGCM_GPR16 | 
22122                 REGCM_GPR32 | REGCM_GPR32_8 | 
22123                 REGCM_DIVIDEND32 | REGCM_DIVIDEND64 |
22124                 REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8 | REGCM_FLAGS;
22125         if (state->arch->features & X86_MMX_REGS) {
22126                 avail_mask |= REGCM_MMX;
22127         }
22128         if (state->arch->features & X86_XMM_REGS) {
22129                 avail_mask |= REGCM_XMM;
22130         }
22131         return avail_mask;
22132 }
22133
22134 static unsigned arch_regcm_normalize(struct compile_state *state, unsigned regcm)
22135 {
22136         unsigned mask, result;
22137         int class, class2;
22138         result = regcm;
22139
22140         for(class = 0, mask = 1; mask; mask <<= 1, class++) {
22141                 if ((result & mask) == 0) {
22142                         continue;
22143                 }
22144                 if (class > LAST_REGC) {
22145                         result &= ~mask;
22146                 }
22147                 for(class2 = 0; class2 <= LAST_REGC; class2++) {
22148                         if ((regcm_bound[class2].first >= regcm_bound[class].first) &&
22149                                 (regcm_bound[class2].last <= regcm_bound[class].last)) {
22150                                 result |= (1 << class2);
22151                         }
22152                 }
22153         }
22154         result &= arch_avail_mask(state);
22155         return result;
22156 }
22157
22158 static unsigned arch_regcm_reg_normalize(struct compile_state *state, unsigned regcm)
22159 {
22160         /* Like arch_regcm_normalize except immediate register classes are excluded */
22161         regcm = arch_regcm_normalize(state, regcm);
22162         /* Remove the immediate register classes */
22163         regcm &= ~(REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8);
22164         return regcm;
22165         
22166 }
22167
22168 static unsigned arch_reg_regcm(struct compile_state *state, int reg)
22169 {
22170         unsigned mask;
22171         int class;
22172         mask = 0;
22173         for(class = 0; class <= LAST_REGC; class++) {
22174                 if ((reg >= regcm_bound[class].first) &&
22175                         (reg <= regcm_bound[class].last)) {
22176                         mask |= (1 << class);
22177                 }
22178         }
22179         if (!mask) {
22180                 internal_error(state, 0, "reg %d not in any class", reg);
22181         }
22182         return mask;
22183 }
22184
22185 static struct reg_info arch_reg_constraint(
22186         struct compile_state *state, struct type *type, const char *constraint)
22187 {
22188         static const struct {
22189                 char class;
22190                 unsigned int mask;
22191                 unsigned int reg;
22192         } constraints[] = {
22193                 { 'r', REGCM_GPR32,   REG_UNSET },
22194                 { 'g', REGCM_GPR32,   REG_UNSET },
22195                 { 'p', REGCM_GPR32,   REG_UNSET },
22196                 { 'q', REGCM_GPR8_LO, REG_UNSET },
22197                 { 'Q', REGCM_GPR32_8, REG_UNSET },
22198                 { 'x', REGCM_XMM,     REG_UNSET },
22199                 { 'y', REGCM_MMX,     REG_UNSET },
22200                 { 'a', REGCM_GPR32,   REG_EAX },
22201                 { 'b', REGCM_GPR32,   REG_EBX },
22202                 { 'c', REGCM_GPR32,   REG_ECX },
22203                 { 'd', REGCM_GPR32,   REG_EDX },
22204                 { 'D', REGCM_GPR32,   REG_EDI },
22205                 { 'S', REGCM_GPR32,   REG_ESI },
22206                 { '\0', 0, REG_UNSET },
22207         };
22208         unsigned int regcm;
22209         unsigned int mask, reg;
22210         struct reg_info result;
22211         const char *ptr;
22212         regcm = arch_type_to_regcm(state, type);
22213         reg = REG_UNSET;
22214         mask = 0;
22215         for(ptr = constraint; *ptr; ptr++) {
22216                 int i;
22217                 if (*ptr ==  ' ') {
22218                         continue;
22219                 }
22220                 for(i = 0; constraints[i].class != '\0'; i++) {
22221                         if (constraints[i].class == *ptr) {
22222                                 break;
22223                         }
22224                 }
22225                 if (constraints[i].class == '\0') {
22226                         error(state, 0, "invalid register constraint ``%c''", *ptr);
22227                         break;
22228                 }
22229                 if ((constraints[i].mask & regcm) == 0) {
22230                         error(state, 0, "invalid register class %c specified",
22231                                 *ptr);
22232                 }
22233                 mask |= constraints[i].mask;
22234                 if (constraints[i].reg != REG_UNSET) {
22235                         if ((reg != REG_UNSET) && (reg != constraints[i].reg)) {
22236                                 error(state, 0, "Only one register may be specified");
22237                         }
22238                         reg = constraints[i].reg;
22239                 }
22240         }
22241         result.reg = reg;
22242         result.regcm = mask;
22243         return result;
22244 }
22245
22246 static struct reg_info arch_reg_clobber(
22247         struct compile_state *state, const char *clobber)
22248 {
22249         struct reg_info result;
22250         if (strcmp(clobber, "memory") == 0) {
22251                 result.reg = REG_UNSET;
22252                 result.regcm = 0;
22253         }
22254         else if (strcmp(clobber, "eax") == 0) {
22255                 result.reg = REG_EAX;
22256                 result.regcm = REGCM_GPR32;
22257         }
22258         else if (strcmp(clobber, "ebx") == 0) {
22259                 result.reg = REG_EBX;
22260                 result.regcm = REGCM_GPR32;
22261         }
22262         else if (strcmp(clobber, "ecx") == 0) {
22263                 result.reg = REG_ECX;
22264                 result.regcm = REGCM_GPR32;
22265         }
22266         else if (strcmp(clobber, "edx") == 0) {
22267                 result.reg = REG_EDX;
22268                 result.regcm = REGCM_GPR32;
22269         }
22270         else if (strcmp(clobber, "esi") == 0) {
22271                 result.reg = REG_ESI;
22272                 result.regcm = REGCM_GPR32;
22273         }
22274         else if (strcmp(clobber, "edi") == 0) {
22275                 result.reg = REG_EDI;
22276                 result.regcm = REGCM_GPR32;
22277         }
22278         else if (strcmp(clobber, "ebp") == 0) {
22279                 result.reg = REG_EBP;
22280                 result.regcm = REGCM_GPR32;
22281         }
22282         else if (strcmp(clobber, "esp") == 0) {
22283                 result.reg = REG_ESP;
22284                 result.regcm = REGCM_GPR32;
22285         }
22286         else if (strcmp(clobber, "cc") == 0) {
22287                 result.reg = REG_EFLAGS;
22288                 result.regcm = REGCM_FLAGS;
22289         }
22290         else if ((strncmp(clobber, "xmm", 3) == 0)  &&
22291                 octdigitp(clobber[3]) && (clobber[4] == '\0')) {
22292                 result.reg = REG_XMM0 + octdigval(clobber[3]);
22293                 result.regcm = REGCM_XMM;
22294         }
22295         else if ((strncmp(clobber, "mm", 2) == 0) &&
22296                 octdigitp(clobber[3]) && (clobber[4] == '\0')) {
22297                 result.reg = REG_MMX0 + octdigval(clobber[3]);
22298                 result.regcm = REGCM_MMX;
22299         }
22300         else {
22301                 error(state, 0, "unknown register name `%s' in asm",
22302                         clobber);
22303                 result.reg = REG_UNSET;
22304                 result.regcm = 0;
22305         }
22306         return result;
22307 }
22308
22309 static int do_select_reg(struct compile_state *state, 
22310         char *used, int reg, unsigned classes)
22311 {
22312         unsigned mask;
22313         if (used[reg]) {
22314                 return REG_UNSET;
22315         }
22316         mask = arch_reg_regcm(state, reg);
22317         return (classes & mask) ? reg : REG_UNSET;
22318 }
22319
22320 static int arch_select_free_register(
22321         struct compile_state *state, char *used, int classes)
22322 {
22323         /* Live ranges with the most neighbors are colored first.
22324          *
22325          * Generally it does not matter which colors are given
22326          * as the register allocator attempts to color live ranges
22327          * in an order where you are guaranteed not to run out of colors.
22328          *
22329          * Occasionally the register allocator cannot find an order
22330          * of register selection that will find a free color.  To
22331          * increase the odds the register allocator will work when
22332          * it guesses first give out registers from register classes
22333          * least likely to run out of registers.
22334          * 
22335          */
22336         int i, reg;
22337         reg = REG_UNSET;
22338         for(i = REGC_XMM_FIRST; (reg == REG_UNSET) && (i <= REGC_XMM_LAST); i++) {
22339                 reg = do_select_reg(state, used, i, classes);
22340         }
22341         for(i = REGC_MMX_FIRST; (reg == REG_UNSET) && (i <= REGC_MMX_LAST); i++) {
22342                 reg = do_select_reg(state, used, i, classes);
22343         }
22344         for(i = REGC_GPR32_LAST; (reg == REG_UNSET) && (i >= REGC_GPR32_FIRST); i--) {
22345                 reg = do_select_reg(state, used, i, classes);
22346         }
22347         for(i = REGC_GPR16_FIRST; (reg == REG_UNSET) && (i <= REGC_GPR16_LAST); i++) {
22348                 reg = do_select_reg(state, used, i, classes);
22349         }
22350         for(i = REGC_GPR8_FIRST; (reg == REG_UNSET) && (i <= REGC_GPR8_LAST); i++) {
22351                 reg = do_select_reg(state, used, i, classes);
22352         }
22353         for(i = REGC_GPR8_LO_FIRST; (reg == REG_UNSET) && (i <= REGC_GPR8_LO_LAST); i++) {
22354                 reg = do_select_reg(state, used, i, classes);
22355         }
22356         for(i = REGC_DIVIDEND32_FIRST; (reg == REG_UNSET) && (i <= REGC_DIVIDEND32_LAST); i++) {
22357                 reg = do_select_reg(state, used, i, classes);
22358         }
22359         for(i = REGC_DIVIDEND64_FIRST; (reg == REG_UNSET) && (i <= REGC_DIVIDEND64_LAST); i++) {
22360                 reg = do_select_reg(state, used, i, classes);
22361         }
22362         for(i = REGC_FLAGS_FIRST; (reg == REG_UNSET) && (i <= REGC_FLAGS_LAST); i++) {
22363                 reg = do_select_reg(state, used, i, classes);
22364         }
22365         return reg;
22366 }
22367
22368
22369 static unsigned arch_type_to_regcm(struct compile_state *state, struct type *type) 
22370 {
22371
22372 #if DEBUG_ROMCC_WARNINGS
22373 #warning "FIXME force types smaller (if legal) before I get here"
22374 #endif
22375         unsigned mask;
22376         mask = 0;
22377         switch(type->type & TYPE_MASK) {
22378         case TYPE_ARRAY:
22379         case TYPE_VOID: 
22380                 mask = 0; 
22381                 break;
22382         case TYPE_CHAR:
22383         case TYPE_UCHAR:
22384                 mask = REGCM_GPR8 | REGCM_GPR8_LO |
22385                         REGCM_GPR16 | REGCM_GPR16_8 | 
22386                         REGCM_GPR32 | REGCM_GPR32_8 |
22387                         REGCM_DIVIDEND32 | REGCM_DIVIDEND64 |
22388                         REGCM_MMX | REGCM_XMM |
22389                         REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8;
22390                 break;
22391         case TYPE_SHORT:
22392         case TYPE_USHORT:
22393                 mask =  REGCM_GPR16 | REGCM_GPR16_8 |
22394                         REGCM_GPR32 | REGCM_GPR32_8 |
22395                         REGCM_DIVIDEND32 | REGCM_DIVIDEND64 |
22396                         REGCM_MMX | REGCM_XMM |
22397                         REGCM_IMM32 | REGCM_IMM16;
22398                 break;
22399         case TYPE_ENUM:
22400         case TYPE_INT:
22401         case TYPE_UINT:
22402         case TYPE_LONG:
22403         case TYPE_ULONG:
22404         case TYPE_POINTER:
22405                 mask =  REGCM_GPR32 | REGCM_GPR32_8 |
22406                         REGCM_DIVIDEND32 | REGCM_DIVIDEND64 |
22407                         REGCM_MMX | REGCM_XMM |
22408                         REGCM_IMM32;
22409                 break;
22410         case TYPE_JOIN:
22411         case TYPE_UNION:
22412                 mask = arch_type_to_regcm(state, type->left);
22413                 break;
22414         case TYPE_OVERLAP:
22415                 mask = arch_type_to_regcm(state, type->left) &
22416                         arch_type_to_regcm(state, type->right);
22417                 break;
22418         case TYPE_BITFIELD:
22419                 mask = arch_type_to_regcm(state, type->left);
22420                 break;
22421         default:
22422                 fprintf(state->errout, "type: ");
22423                 name_of(state->errout, type);
22424                 fprintf(state->errout, "\n");
22425                 internal_error(state, 0, "no register class for type");
22426                 break;
22427         }
22428         mask = arch_regcm_normalize(state, mask);
22429         return mask;
22430 }
22431
22432 static int is_imm32(struct triple *imm)
22433 {
22434         return ((imm->op == OP_INTCONST) && (imm->u.cval <= 0xffffffffUL)) ||
22435                 (imm->op == OP_ADDRCONST);
22436         
22437 }
22438 static int is_imm16(struct triple *imm)
22439 {
22440         return ((imm->op == OP_INTCONST) && (imm->u.cval <= 0xffff));
22441 }
22442 static int is_imm8(struct triple *imm)
22443 {
22444         return ((imm->op == OP_INTCONST) && (imm->u.cval <= 0xff));
22445 }
22446
22447 static int get_imm32(struct triple *ins, struct triple **expr)
22448 {
22449         struct triple *imm;
22450         imm = *expr;
22451         while(imm->op == OP_COPY) {
22452                 imm = RHS(imm, 0);
22453         }
22454         if (!is_imm32(imm)) {
22455                 return 0;
22456         }
22457         unuse_triple(*expr, ins);
22458         use_triple(imm, ins);
22459         *expr = imm;
22460         return 1;
22461 }
22462
22463 static int get_imm8(struct triple *ins, struct triple **expr)
22464 {
22465         struct triple *imm;
22466         imm = *expr;
22467         while(imm->op == OP_COPY) {
22468                 imm = RHS(imm, 0);
22469         }
22470         if (!is_imm8(imm)) {
22471                 return 0;
22472         }
22473         unuse_triple(*expr, ins);
22474         use_triple(imm, ins);
22475         *expr = imm;
22476         return 1;
22477 }
22478
22479 #define TEMPLATE_NOP           0
22480 #define TEMPLATE_INTCONST8     1
22481 #define TEMPLATE_INTCONST32    2
22482 #define TEMPLATE_UNKNOWNVAL    3
22483 #define TEMPLATE_COPY8_REG     5
22484 #define TEMPLATE_COPY16_REG    6
22485 #define TEMPLATE_COPY32_REG    7
22486 #define TEMPLATE_COPY_IMM8     8
22487 #define TEMPLATE_COPY_IMM16    9
22488 #define TEMPLATE_COPY_IMM32   10
22489 #define TEMPLATE_PHI8         11
22490 #define TEMPLATE_PHI16        12
22491 #define TEMPLATE_PHI32        13
22492 #define TEMPLATE_STORE8       14
22493 #define TEMPLATE_STORE16      15
22494 #define TEMPLATE_STORE32      16
22495 #define TEMPLATE_LOAD8        17
22496 #define TEMPLATE_LOAD16       18
22497 #define TEMPLATE_LOAD32       19
22498 #define TEMPLATE_BINARY8_REG  20
22499 #define TEMPLATE_BINARY16_REG 21
22500 #define TEMPLATE_BINARY32_REG 22
22501 #define TEMPLATE_BINARY8_IMM  23
22502 #define TEMPLATE_BINARY16_IMM 24
22503 #define TEMPLATE_BINARY32_IMM 25
22504 #define TEMPLATE_SL8_CL       26
22505 #define TEMPLATE_SL16_CL      27
22506 #define TEMPLATE_SL32_CL      28
22507 #define TEMPLATE_SL8_IMM      29
22508 #define TEMPLATE_SL16_IMM     30
22509 #define TEMPLATE_SL32_IMM     31
22510 #define TEMPLATE_UNARY8       32
22511 #define TEMPLATE_UNARY16      33
22512 #define TEMPLATE_UNARY32      34
22513 #define TEMPLATE_CMP8_REG     35
22514 #define TEMPLATE_CMP16_REG    36
22515 #define TEMPLATE_CMP32_REG    37
22516 #define TEMPLATE_CMP8_IMM     38
22517 #define TEMPLATE_CMP16_IMM    39
22518 #define TEMPLATE_CMP32_IMM    40
22519 #define TEMPLATE_TEST8        41
22520 #define TEMPLATE_TEST16       42
22521 #define TEMPLATE_TEST32       43
22522 #define TEMPLATE_SET          44
22523 #define TEMPLATE_JMP          45
22524 #define TEMPLATE_RET          46
22525 #define TEMPLATE_INB_DX       47
22526 #define TEMPLATE_INB_IMM      48
22527 #define TEMPLATE_INW_DX       49
22528 #define TEMPLATE_INW_IMM      50
22529 #define TEMPLATE_INL_DX       51
22530 #define TEMPLATE_INL_IMM      52
22531 #define TEMPLATE_OUTB_DX      53
22532 #define TEMPLATE_OUTB_IMM     54
22533 #define TEMPLATE_OUTW_DX      55
22534 #define TEMPLATE_OUTW_IMM     56
22535 #define TEMPLATE_OUTL_DX      57
22536 #define TEMPLATE_OUTL_IMM     58
22537 #define TEMPLATE_BSF          59
22538 #define TEMPLATE_RDMSR        60
22539 #define TEMPLATE_WRMSR        61
22540 #define TEMPLATE_UMUL8        62
22541 #define TEMPLATE_UMUL16       63
22542 #define TEMPLATE_UMUL32       64
22543 #define TEMPLATE_DIV8         65
22544 #define TEMPLATE_DIV16        66
22545 #define TEMPLATE_DIV32        67
22546 #define LAST_TEMPLATE       TEMPLATE_DIV32
22547 #if LAST_TEMPLATE >= MAX_TEMPLATES
22548 #error "MAX_TEMPLATES to low"
22549 #endif
22550
22551 #define COPY8_REGCM     (REGCM_DIVIDEND64 | REGCM_DIVIDEND32 | REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO | REGCM_MMX | REGCM_XMM)
22552 #define COPY16_REGCM    (REGCM_DIVIDEND64 | REGCM_DIVIDEND32 | REGCM_GPR32 | REGCM_GPR16 | REGCM_MMX | REGCM_XMM)  
22553 #define COPY32_REGCM    (REGCM_DIVIDEND64 | REGCM_DIVIDEND32 | REGCM_GPR32 | REGCM_MMX | REGCM_XMM)
22554
22555
22556 static struct ins_template templates[] = {
22557         [TEMPLATE_NOP]      = {
22558                 .lhs = { 
22559                         [ 0] = { REG_UNNEEDED, REGCM_IMMALL },
22560                         [ 1] = { REG_UNNEEDED, REGCM_IMMALL },
22561                         [ 2] = { REG_UNNEEDED, REGCM_IMMALL },
22562                         [ 3] = { REG_UNNEEDED, REGCM_IMMALL },
22563                         [ 4] = { REG_UNNEEDED, REGCM_IMMALL },
22564                         [ 5] = { REG_UNNEEDED, REGCM_IMMALL },
22565                         [ 6] = { REG_UNNEEDED, REGCM_IMMALL },
22566                         [ 7] = { REG_UNNEEDED, REGCM_IMMALL },
22567                         [ 8] = { REG_UNNEEDED, REGCM_IMMALL },
22568                         [ 9] = { REG_UNNEEDED, REGCM_IMMALL },
22569                         [10] = { REG_UNNEEDED, REGCM_IMMALL },
22570                         [11] = { REG_UNNEEDED, REGCM_IMMALL },
22571                         [12] = { REG_UNNEEDED, REGCM_IMMALL },
22572                         [13] = { REG_UNNEEDED, REGCM_IMMALL },
22573                         [14] = { REG_UNNEEDED, REGCM_IMMALL },
22574                         [15] = { REG_UNNEEDED, REGCM_IMMALL },
22575                         [16] = { REG_UNNEEDED, REGCM_IMMALL },
22576                         [17] = { REG_UNNEEDED, REGCM_IMMALL },
22577                         [18] = { REG_UNNEEDED, REGCM_IMMALL },
22578                         [19] = { REG_UNNEEDED, REGCM_IMMALL },
22579                         [20] = { REG_UNNEEDED, REGCM_IMMALL },
22580                         [21] = { REG_UNNEEDED, REGCM_IMMALL },
22581                         [22] = { REG_UNNEEDED, REGCM_IMMALL },
22582                         [23] = { REG_UNNEEDED, REGCM_IMMALL },
22583                         [24] = { REG_UNNEEDED, REGCM_IMMALL },
22584                         [25] = { REG_UNNEEDED, REGCM_IMMALL },
22585                         [26] = { REG_UNNEEDED, REGCM_IMMALL },
22586                         [27] = { REG_UNNEEDED, REGCM_IMMALL },
22587                         [28] = { REG_UNNEEDED, REGCM_IMMALL },
22588                         [29] = { REG_UNNEEDED, REGCM_IMMALL },
22589                         [30] = { REG_UNNEEDED, REGCM_IMMALL },
22590                         [31] = { REG_UNNEEDED, REGCM_IMMALL },
22591                         [32] = { REG_UNNEEDED, REGCM_IMMALL },
22592                         [33] = { REG_UNNEEDED, REGCM_IMMALL },
22593                         [34] = { REG_UNNEEDED, REGCM_IMMALL },
22594                         [35] = { REG_UNNEEDED, REGCM_IMMALL },
22595                         [36] = { REG_UNNEEDED, REGCM_IMMALL },
22596                         [37] = { REG_UNNEEDED, REGCM_IMMALL },
22597                         [38] = { REG_UNNEEDED, REGCM_IMMALL },
22598                         [39] = { REG_UNNEEDED, REGCM_IMMALL },
22599                         [40] = { REG_UNNEEDED, REGCM_IMMALL },
22600                         [41] = { REG_UNNEEDED, REGCM_IMMALL },
22601                         [42] = { REG_UNNEEDED, REGCM_IMMALL },
22602                         [43] = { REG_UNNEEDED, REGCM_IMMALL },
22603                         [44] = { REG_UNNEEDED, REGCM_IMMALL },
22604                         [45] = { REG_UNNEEDED, REGCM_IMMALL },
22605                         [46] = { REG_UNNEEDED, REGCM_IMMALL },
22606                         [47] = { REG_UNNEEDED, REGCM_IMMALL },
22607                         [48] = { REG_UNNEEDED, REGCM_IMMALL },
22608                         [49] = { REG_UNNEEDED, REGCM_IMMALL },
22609                         [50] = { REG_UNNEEDED, REGCM_IMMALL },
22610                         [51] = { REG_UNNEEDED, REGCM_IMMALL },
22611                         [52] = { REG_UNNEEDED, REGCM_IMMALL },
22612                         [53] = { REG_UNNEEDED, REGCM_IMMALL },
22613                         [54] = { REG_UNNEEDED, REGCM_IMMALL },
22614                         [55] = { REG_UNNEEDED, REGCM_IMMALL },
22615                         [56] = { REG_UNNEEDED, REGCM_IMMALL },
22616                         [57] = { REG_UNNEEDED, REGCM_IMMALL },
22617                         [58] = { REG_UNNEEDED, REGCM_IMMALL },
22618                         [59] = { REG_UNNEEDED, REGCM_IMMALL },
22619                         [60] = { REG_UNNEEDED, REGCM_IMMALL },
22620                         [61] = { REG_UNNEEDED, REGCM_IMMALL },
22621                         [62] = { REG_UNNEEDED, REGCM_IMMALL },
22622                         [63] = { REG_UNNEEDED, REGCM_IMMALL },
22623                 },
22624         },
22625         [TEMPLATE_INTCONST8] = { 
22626                 .lhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
22627         },
22628         [TEMPLATE_INTCONST32] = { 
22629                 .lhs = { [0] = { REG_UNNEEDED, REGCM_IMM32 } },
22630         },
22631         [TEMPLATE_UNKNOWNVAL] = {
22632                 .lhs = { [0] = { REG_UNSET, COPY32_REGCM } },
22633         },
22634         [TEMPLATE_COPY8_REG] = {
22635                 .lhs = { [0] = { REG_UNSET, COPY8_REGCM } },
22636                 .rhs = { [0] = { REG_UNSET, COPY8_REGCM }  },
22637         },
22638         [TEMPLATE_COPY16_REG] = {
22639                 .lhs = { [0] = { REG_UNSET, COPY16_REGCM } },
22640                 .rhs = { [0] = { REG_UNSET, COPY16_REGCM }  },
22641         },
22642         [TEMPLATE_COPY32_REG] = {
22643                 .lhs = { [0] = { REG_UNSET, COPY32_REGCM } },
22644                 .rhs = { [0] = { REG_UNSET, COPY32_REGCM }  },
22645         },
22646         [TEMPLATE_COPY_IMM8] = {
22647                 .lhs = { [0] = { REG_UNSET, COPY8_REGCM } },
22648                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
22649         },
22650         [TEMPLATE_COPY_IMM16] = {
22651                 .lhs = { [0] = { REG_UNSET, COPY16_REGCM } },
22652                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM16 | REGCM_IMM8 } },
22653         },
22654         [TEMPLATE_COPY_IMM32] = {
22655                 .lhs = { [0] = { REG_UNSET, COPY32_REGCM } },
22656                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8 } },
22657         },
22658         [TEMPLATE_PHI8] = { 
22659                 .lhs = { [0] = { REG_VIRT0, COPY8_REGCM } },
22660                 .rhs = { [0] = { REG_VIRT0, COPY8_REGCM } },
22661         },
22662         [TEMPLATE_PHI16] = { 
22663                 .lhs = { [0] = { REG_VIRT0, COPY16_REGCM } },
22664                 .rhs = { [0] = { REG_VIRT0, COPY16_REGCM } }, 
22665         },
22666         [TEMPLATE_PHI32] = { 
22667                 .lhs = { [0] = { REG_VIRT0, COPY32_REGCM } },
22668                 .rhs = { [0] = { REG_VIRT0, COPY32_REGCM } }, 
22669         },
22670         [TEMPLATE_STORE8] = {
22671                 .rhs = { 
22672                         [0] = { REG_UNSET, REGCM_GPR32 },
22673                         [1] = { REG_UNSET, REGCM_GPR8_LO },
22674                 },
22675         },
22676         [TEMPLATE_STORE16] = {
22677                 .rhs = { 
22678                         [0] = { REG_UNSET, REGCM_GPR32 },
22679                         [1] = { REG_UNSET, REGCM_GPR16 },
22680                 },
22681         },
22682         [TEMPLATE_STORE32] = {
22683                 .rhs = { 
22684                         [0] = { REG_UNSET, REGCM_GPR32 },
22685                         [1] = { REG_UNSET, REGCM_GPR32 },
22686                 },
22687         },
22688         [TEMPLATE_LOAD8] = {
22689                 .lhs = { [0] = { REG_UNSET, REGCM_GPR8_LO } },
22690                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
22691         },
22692         [TEMPLATE_LOAD16] = {
22693                 .lhs = { [0] = { REG_UNSET, REGCM_GPR16 } },
22694                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
22695         },
22696         [TEMPLATE_LOAD32] = {
22697                 .lhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
22698                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
22699         },
22700         [TEMPLATE_BINARY8_REG] = {
22701                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
22702                 .rhs = { 
22703                         [0] = { REG_VIRT0, REGCM_GPR8_LO },
22704                         [1] = { REG_UNSET, REGCM_GPR8_LO },
22705                 },
22706         },
22707         [TEMPLATE_BINARY16_REG] = {
22708                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
22709                 .rhs = { 
22710                         [0] = { REG_VIRT0, REGCM_GPR16 },
22711                         [1] = { REG_UNSET, REGCM_GPR16 },
22712                 },
22713         },
22714         [TEMPLATE_BINARY32_REG] = {
22715                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
22716                 .rhs = { 
22717                         [0] = { REG_VIRT0, REGCM_GPR32 },
22718                         [1] = { REG_UNSET, REGCM_GPR32 },
22719                 },
22720         },
22721         [TEMPLATE_BINARY8_IMM] = {
22722                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
22723                 .rhs = { 
22724                         [0] = { REG_VIRT0,    REGCM_GPR8_LO },
22725                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
22726                 },
22727         },
22728         [TEMPLATE_BINARY16_IMM] = {
22729                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
22730                 .rhs = { 
22731                         [0] = { REG_VIRT0,    REGCM_GPR16 },
22732                         [1] = { REG_UNNEEDED, REGCM_IMM16 },
22733                 },
22734         },
22735         [TEMPLATE_BINARY32_IMM] = {
22736                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
22737                 .rhs = { 
22738                         [0] = { REG_VIRT0,    REGCM_GPR32 },
22739                         [1] = { REG_UNNEEDED, REGCM_IMM32 },
22740                 },
22741         },
22742         [TEMPLATE_SL8_CL] = {
22743                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
22744                 .rhs = { 
22745                         [0] = { REG_VIRT0, REGCM_GPR8_LO },
22746                         [1] = { REG_CL, REGCM_GPR8_LO },
22747                 },
22748         },
22749         [TEMPLATE_SL16_CL] = {
22750                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
22751                 .rhs = { 
22752                         [0] = { REG_VIRT0, REGCM_GPR16 },
22753                         [1] = { REG_CL, REGCM_GPR8_LO },
22754                 },
22755         },
22756         [TEMPLATE_SL32_CL] = {
22757                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
22758                 .rhs = { 
22759                         [0] = { REG_VIRT0, REGCM_GPR32 },
22760                         [1] = { REG_CL, REGCM_GPR8_LO },
22761                 },
22762         },
22763         [TEMPLATE_SL8_IMM] = {
22764                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
22765                 .rhs = { 
22766                         [0] = { REG_VIRT0,    REGCM_GPR8_LO },
22767                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
22768                 },
22769         },
22770         [TEMPLATE_SL16_IMM] = {
22771                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
22772                 .rhs = { 
22773                         [0] = { REG_VIRT0,    REGCM_GPR16 },
22774                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
22775                 },
22776         },
22777         [TEMPLATE_SL32_IMM] = {
22778                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
22779                 .rhs = { 
22780                         [0] = { REG_VIRT0,    REGCM_GPR32 },
22781                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
22782                 },
22783         },
22784         [TEMPLATE_UNARY8] = {
22785                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
22786                 .rhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
22787         },
22788         [TEMPLATE_UNARY16] = {
22789                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
22790                 .rhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
22791         },
22792         [TEMPLATE_UNARY32] = {
22793                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
22794                 .rhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
22795         },
22796         [TEMPLATE_CMP8_REG] = {
22797                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22798                 .rhs = {
22799                         [0] = { REG_UNSET, REGCM_GPR8_LO },
22800                         [1] = { REG_UNSET, REGCM_GPR8_LO },
22801                 },
22802         },
22803         [TEMPLATE_CMP16_REG] = {
22804                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22805                 .rhs = {
22806                         [0] = { REG_UNSET, REGCM_GPR16 },
22807                         [1] = { REG_UNSET, REGCM_GPR16 },
22808                 },
22809         },
22810         [TEMPLATE_CMP32_REG] = {
22811                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22812                 .rhs = {
22813                         [0] = { REG_UNSET, REGCM_GPR32 },
22814                         [1] = { REG_UNSET, REGCM_GPR32 },
22815                 },
22816         },
22817         [TEMPLATE_CMP8_IMM] = {
22818                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22819                 .rhs = {
22820                         [0] = { REG_UNSET, REGCM_GPR8_LO },
22821                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
22822                 },
22823         },
22824         [TEMPLATE_CMP16_IMM] = {
22825                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22826                 .rhs = {
22827                         [0] = { REG_UNSET, REGCM_GPR16 },
22828                         [1] = { REG_UNNEEDED, REGCM_IMM16 },
22829                 },
22830         },
22831         [TEMPLATE_CMP32_IMM] = {
22832                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22833                 .rhs = {
22834                         [0] = { REG_UNSET, REGCM_GPR32 },
22835                         [1] = { REG_UNNEEDED, REGCM_IMM32 },
22836                 },
22837         },
22838         [TEMPLATE_TEST8] = {
22839                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22840                 .rhs = { [0] = { REG_UNSET, REGCM_GPR8_LO } },
22841         },
22842         [TEMPLATE_TEST16] = {
22843                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22844                 .rhs = { [0] = { REG_UNSET, REGCM_GPR16 } },
22845         },
22846         [TEMPLATE_TEST32] = {
22847                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22848                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
22849         },
22850         [TEMPLATE_SET] = {
22851                 .lhs = { [0] = { REG_UNSET, REGCM_GPR8_LO } },
22852                 .rhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22853         },
22854         [TEMPLATE_JMP] = {
22855                 .rhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22856         },
22857         [TEMPLATE_RET] = {
22858                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
22859         },
22860         [TEMPLATE_INB_DX] = {
22861                 .lhs = { [0] = { REG_AL,  REGCM_GPR8_LO } },  
22862                 .rhs = { [0] = { REG_DX, REGCM_GPR16 } },
22863         },
22864         [TEMPLATE_INB_IMM] = {
22865                 .lhs = { [0] = { REG_AL,  REGCM_GPR8_LO } },  
22866                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
22867         },
22868         [TEMPLATE_INW_DX]  = { 
22869                 .lhs = { [0] = { REG_AX,  REGCM_GPR16 } }, 
22870                 .rhs = { [0] = { REG_DX, REGCM_GPR16 } },
22871         },
22872         [TEMPLATE_INW_IMM] = { 
22873                 .lhs = { [0] = { REG_AX,  REGCM_GPR16 } }, 
22874                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
22875         },
22876         [TEMPLATE_INL_DX]  = {
22877                 .lhs = { [0] = { REG_EAX, REGCM_GPR32 } },
22878                 .rhs = { [0] = { REG_DX, REGCM_GPR16 } },
22879         },
22880         [TEMPLATE_INL_IMM] = {
22881                 .lhs = { [0] = { REG_EAX, REGCM_GPR32 } },
22882                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
22883         },
22884         [TEMPLATE_OUTB_DX] = { 
22885                 .rhs = {
22886                         [0] = { REG_AL,  REGCM_GPR8_LO },
22887                         [1] = { REG_DX, REGCM_GPR16 },
22888                 },
22889         },
22890         [TEMPLATE_OUTB_IMM] = { 
22891                 .rhs = {
22892                         [0] = { REG_AL,  REGCM_GPR8_LO },  
22893                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
22894                 },
22895         },
22896         [TEMPLATE_OUTW_DX] = { 
22897                 .rhs = {
22898                         [0] = { REG_AX,  REGCM_GPR16 },
22899                         [1] = { REG_DX, REGCM_GPR16 },
22900                 },
22901         },
22902         [TEMPLATE_OUTW_IMM] = {
22903                 .rhs = {
22904                         [0] = { REG_AX,  REGCM_GPR16 }, 
22905                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
22906                 },
22907         },
22908         [TEMPLATE_OUTL_DX] = { 
22909                 .rhs = {
22910                         [0] = { REG_EAX, REGCM_GPR32 },
22911                         [1] = { REG_DX, REGCM_GPR16 },
22912                 },
22913         },
22914         [TEMPLATE_OUTL_IMM] = { 
22915                 .rhs = {
22916                         [0] = { REG_EAX, REGCM_GPR32 }, 
22917                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
22918                 },
22919         },
22920         [TEMPLATE_BSF] = {
22921                 .lhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
22922                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
22923         },
22924         [TEMPLATE_RDMSR] = {
22925                 .lhs = { 
22926                         [0] = { REG_EAX, REGCM_GPR32 },
22927                         [1] = { REG_EDX, REGCM_GPR32 },
22928                 },
22929                 .rhs = { [0] = { REG_ECX, REGCM_GPR32 } },
22930         },
22931         [TEMPLATE_WRMSR] = {
22932                 .rhs = {
22933                         [0] = { REG_ECX, REGCM_GPR32 },
22934                         [1] = { REG_EAX, REGCM_GPR32 },
22935                         [2] = { REG_EDX, REGCM_GPR32 },
22936                 },
22937         },
22938         [TEMPLATE_UMUL8] = {
22939                 .lhs = { [0] = { REG_AX, REGCM_GPR16 } },
22940                 .rhs = { 
22941                         [0] = { REG_AL, REGCM_GPR8_LO },
22942                         [1] = { REG_UNSET, REGCM_GPR8_LO },
22943                 },
22944         },
22945         [TEMPLATE_UMUL16] = {
22946                 .lhs = { [0] = { REG_DXAX, REGCM_DIVIDEND32 } },
22947                 .rhs = { 
22948                         [0] = { REG_AX, REGCM_GPR16 },
22949                         [1] = { REG_UNSET, REGCM_GPR16 },
22950                 },
22951         },
22952         [TEMPLATE_UMUL32] = {
22953                 .lhs = { [0] = { REG_EDXEAX, REGCM_DIVIDEND64 } },
22954                 .rhs = { 
22955                         [0] = { REG_EAX, REGCM_GPR32 },
22956                         [1] = { REG_UNSET, REGCM_GPR32 },
22957                 },
22958         },
22959         [TEMPLATE_DIV8] = {
22960                 .lhs = { 
22961                         [0] = { REG_AL, REGCM_GPR8_LO },
22962                         [1] = { REG_AH, REGCM_GPR8 },
22963                 },
22964                 .rhs = {
22965                         [0] = { REG_AX, REGCM_GPR16 },
22966                         [1] = { REG_UNSET, REGCM_GPR8_LO },
22967                 },
22968         },
22969         [TEMPLATE_DIV16] = {
22970                 .lhs = { 
22971                         [0] = { REG_AX, REGCM_GPR16 },
22972                         [1] = { REG_DX, REGCM_GPR16 },
22973                 },
22974                 .rhs = {
22975                         [0] = { REG_DXAX, REGCM_DIVIDEND32 },
22976                         [1] = { REG_UNSET, REGCM_GPR16 },
22977                 },
22978         },
22979         [TEMPLATE_DIV32] = {
22980                 .lhs = { 
22981                         [0] = { REG_EAX, REGCM_GPR32 },
22982                         [1] = { REG_EDX, REGCM_GPR32 },
22983                 },
22984                 .rhs = {
22985                         [0] = { REG_EDXEAX, REGCM_DIVIDEND64 },
22986                         [1] = { REG_UNSET, REGCM_GPR32 },
22987                 },
22988         },
22989 };
22990
22991 static void fixup_branch(struct compile_state *state,
22992         struct triple *branch, int jmp_op, int cmp_op, struct type *cmp_type,
22993         struct triple *left, struct triple *right)
22994 {
22995         struct triple *test;
22996         if (!left) {
22997                 internal_error(state, branch, "no branch test?");
22998         }
22999         test = pre_triple(state, branch,
23000                 cmp_op, cmp_type, left, right);
23001         test->template_id = TEMPLATE_TEST32; 
23002         if (cmp_op == OP_CMP) {
23003                 test->template_id = TEMPLATE_CMP32_REG;
23004                 if (get_imm32(test, &RHS(test, 1))) {
23005                         test->template_id = TEMPLATE_CMP32_IMM;
23006                 }
23007         }
23008         use_triple(RHS(test, 0), test);
23009         use_triple(RHS(test, 1), test);
23010         unuse_triple(RHS(branch, 0), branch);
23011         RHS(branch, 0) = test;
23012         branch->op = jmp_op;
23013         branch->template_id = TEMPLATE_JMP;
23014         use_triple(RHS(branch, 0), branch);
23015 }
23016
23017 static void fixup_branches(struct compile_state *state,
23018         struct triple *cmp, struct triple *use, int jmp_op)
23019 {
23020         struct triple_set *entry, *next;
23021         for(entry = use->use; entry; entry = next) {
23022                 next = entry->next;
23023                 if (entry->member->op == OP_COPY) {
23024                         fixup_branches(state, cmp, entry->member, jmp_op);
23025                 }
23026                 else if (entry->member->op == OP_CBRANCH) {
23027                         struct triple *branch;
23028                         struct triple *left, *right;
23029                         left = right = 0;
23030                         left = RHS(cmp, 0);
23031                         if (cmp->rhs > 1) {
23032                                 right = RHS(cmp, 1);
23033                         }
23034                         branch = entry->member;
23035                         fixup_branch(state, branch, jmp_op, 
23036                                 cmp->op, cmp->type, left, right);
23037                 }
23038         }
23039 }
23040
23041 static void bool_cmp(struct compile_state *state, 
23042         struct triple *ins, int cmp_op, int jmp_op, int set_op)
23043 {
23044         struct triple_set *entry, *next;
23045         struct triple *set, *convert;
23046
23047         /* Put a barrier up before the cmp which preceeds the
23048          * copy instruction.  If a set actually occurs this gives
23049          * us a chance to move variables in registers out of the way.
23050          */
23051
23052         /* Modify the comparison operator */
23053         ins->op = cmp_op;
23054         ins->template_id = TEMPLATE_TEST32;
23055         if (cmp_op == OP_CMP) {
23056                 ins->template_id = TEMPLATE_CMP32_REG;
23057                 if (get_imm32(ins, &RHS(ins, 1))) {
23058                         ins->template_id =  TEMPLATE_CMP32_IMM;
23059                 }
23060         }
23061         /* Generate the instruction sequence that will transform the
23062          * result of the comparison into a logical value.
23063          */
23064         set = post_triple(state, ins, set_op, &uchar_type, ins, 0);
23065         use_triple(ins, set);
23066         set->template_id = TEMPLATE_SET;
23067
23068         convert = set;
23069         if (!equiv_types(ins->type, set->type)) {
23070                 convert = post_triple(state, set, OP_CONVERT, ins->type, set, 0);
23071                 use_triple(set, convert);
23072                 convert->template_id = TEMPLATE_COPY32_REG;
23073         }
23074
23075         for(entry = ins->use; entry; entry = next) {
23076                 next = entry->next;
23077                 if (entry->member == set) {
23078                         continue;
23079                 }
23080                 replace_rhs_use(state, ins, convert, entry->member);
23081         }
23082         fixup_branches(state, ins, convert, jmp_op);
23083 }
23084
23085 struct reg_info arch_reg_lhs(struct compile_state *state, struct triple *ins, int index)
23086 {
23087         struct ins_template *template;
23088         struct reg_info result;
23089         int zlhs;
23090         if (ins->op == OP_PIECE) {
23091                 index = ins->u.cval;
23092                 ins = MISC(ins, 0);
23093         }
23094         zlhs = ins->lhs;
23095         if (triple_is_def(state, ins)) {
23096                 zlhs = 1;
23097         }
23098         if (index >= zlhs) {
23099                 internal_error(state, ins, "index %d out of range for %s",
23100                         index, tops(ins->op));
23101         }
23102         switch(ins->op) {
23103         case OP_ASM:
23104                 template = &ins->u.ainfo->tmpl;
23105                 break;
23106         default:
23107                 if (ins->template_id > LAST_TEMPLATE) {
23108                         internal_error(state, ins, "bad template number %d", 
23109                                 ins->template_id);
23110                 }
23111                 template = &templates[ins->template_id];
23112                 break;
23113         }
23114         result = template->lhs[index];
23115         result.regcm = arch_regcm_normalize(state, result.regcm);
23116         if (result.reg != REG_UNNEEDED) {
23117                 result.regcm &= ~(REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8);
23118         }
23119         if (result.regcm == 0) {
23120                 internal_error(state, ins, "lhs %d regcm == 0", index);
23121         }
23122         return result;
23123 }
23124
23125 struct reg_info arch_reg_rhs(struct compile_state *state, struct triple *ins, int index)
23126 {
23127         struct reg_info result;
23128         struct ins_template *template;
23129         if ((index > ins->rhs) ||
23130                 (ins->op == OP_PIECE)) {
23131                 internal_error(state, ins, "index %d out of range for %s\n",
23132                         index, tops(ins->op));
23133         }
23134         switch(ins->op) {
23135         case OP_ASM:
23136                 template = &ins->u.ainfo->tmpl;
23137                 break;
23138         case OP_PHI:
23139                 index = 0;
23140                 /* Fall through */
23141         default:
23142                 if (ins->template_id > LAST_TEMPLATE) {
23143                         internal_error(state, ins, "bad template number %d", 
23144                                 ins->template_id);
23145                 }
23146                 template = &templates[ins->template_id];
23147                 break;
23148         }
23149         result = template->rhs[index];
23150         result.regcm = arch_regcm_normalize(state, result.regcm);
23151         if (result.regcm == 0) {
23152                 internal_error(state, ins, "rhs %d regcm == 0", index);
23153         }
23154         return result;
23155 }
23156
23157 static struct triple *mod_div(struct compile_state *state,
23158         struct triple *ins, int div_op, int index)
23159 {
23160         struct triple *div, *piece0, *piece1;
23161         
23162         /* Generate the appropriate division instruction */
23163         div = post_triple(state, ins, div_op, ins->type, 0, 0);
23164         RHS(div, 0) = RHS(ins, 0);
23165         RHS(div, 1) = RHS(ins, 1);
23166         piece0 = LHS(div, 0);
23167         piece1 = LHS(div, 1);
23168         div->template_id  = TEMPLATE_DIV32;
23169         use_triple(RHS(div, 0), div);
23170         use_triple(RHS(div, 1), div);
23171         use_triple(LHS(div, 0), div);
23172         use_triple(LHS(div, 1), div);
23173
23174         /* Replate uses of ins with the appropriate piece of the div */
23175         propogate_use(state, ins, LHS(div, index));
23176         release_triple(state, ins);
23177
23178         /* Return the address of the next instruction */
23179         return piece1->next;
23180 }
23181
23182 static int noop_adecl(struct triple *adecl)
23183 {
23184         struct triple_set *use;
23185         /* It's a noop if it doesn't specify stoorage */
23186         if (adecl->lhs == 0) {
23187                 return 1;
23188         }
23189         /* Is the adecl used? If not it's a noop */
23190         for(use = adecl->use; use ; use = use->next) {
23191                 if ((use->member->op != OP_PIECE) ||
23192                         (MISC(use->member, 0) != adecl)) {
23193                         return 0;
23194                 }
23195         }
23196         return 1;
23197 }
23198
23199 static struct triple *x86_deposit(struct compile_state *state, struct triple *ins)
23200 {
23201         struct triple *mask, *nmask, *shift;
23202         struct triple *val, *val_mask, *val_shift;
23203         struct triple *targ, *targ_mask;
23204         struct triple *new;
23205         ulong_t the_mask, the_nmask;
23206
23207         targ = RHS(ins, 0);
23208         val = RHS(ins, 1);
23209
23210         /* Get constant for the mask value */
23211         the_mask = 1;
23212         the_mask <<= ins->u.bitfield.size;
23213         the_mask -= 1;
23214         the_mask <<= ins->u.bitfield.offset;
23215         mask = pre_triple(state, ins, OP_INTCONST, &uint_type, 0, 0);
23216         mask->u.cval = the_mask;
23217
23218         /* Get the inverted mask value */
23219         the_nmask = ~the_mask;
23220         nmask = pre_triple(state, ins, OP_INTCONST, &uint_type, 0, 0);
23221         nmask->u.cval = the_nmask;
23222
23223         /* Get constant for the shift value */
23224         shift = pre_triple(state, ins, OP_INTCONST, &uint_type, 0, 0);
23225         shift->u.cval = ins->u.bitfield.offset;
23226
23227         /* Shift and mask the source value */
23228         val_shift = val;
23229         if (shift->u.cval != 0) {
23230                 val_shift = pre_triple(state, ins, OP_SL, val->type, val, shift);
23231                 use_triple(val, val_shift);
23232                 use_triple(shift, val_shift);
23233         }
23234         val_mask = val_shift;
23235         if (is_signed(val->type)) {
23236                 val_mask = pre_triple(state, ins, OP_AND, val->type, val_shift, mask);
23237                 use_triple(val_shift, val_mask);
23238                 use_triple(mask, val_mask);
23239         }
23240
23241         /* Mask the target value */
23242         targ_mask = pre_triple(state, ins, OP_AND, targ->type, targ, nmask);
23243         use_triple(targ, targ_mask);
23244         use_triple(nmask, targ_mask);
23245
23246         /* Now combined them together */
23247         new = pre_triple(state, ins, OP_OR, targ->type, targ_mask, val_mask);
23248         use_triple(targ_mask, new);
23249         use_triple(val_mask, new);
23250
23251         /* Move all of the users over to the new expression */
23252         propogate_use(state, ins, new);
23253
23254         /* Delete the original triple */
23255         release_triple(state, ins);
23256
23257         /* Restart the transformation at mask */
23258         return mask;
23259 }
23260
23261 static struct triple *x86_extract(struct compile_state *state, struct triple *ins)
23262 {
23263         struct triple *mask, *shift;
23264         struct triple *val, *val_mask, *val_shift;
23265         ulong_t the_mask;
23266
23267         val = RHS(ins, 0);
23268
23269         /* Get constant for the mask value */
23270         the_mask = 1;
23271         the_mask <<= ins->u.bitfield.size;
23272         the_mask -= 1;
23273         mask = pre_triple(state, ins, OP_INTCONST, &int_type, 0, 0);
23274         mask->u.cval = the_mask;
23275
23276         /* Get constant for the right shift value */
23277         shift = pre_triple(state, ins, OP_INTCONST, &int_type, 0, 0);
23278         shift->u.cval = ins->u.bitfield.offset;
23279
23280         /* Shift arithmetic right, to correct the sign */
23281         val_shift = val;
23282         if (shift->u.cval != 0) {
23283                 int op;
23284                 if (ins->op == OP_SEXTRACT) {
23285                         op = OP_SSR;
23286                 } else {
23287                         op = OP_USR;
23288                 }
23289                 val_shift = pre_triple(state, ins, op, val->type, val, shift);
23290                 use_triple(val, val_shift);
23291                 use_triple(shift, val_shift);
23292         }
23293
23294         /* Finally mask the value */
23295         val_mask = pre_triple(state, ins, OP_AND, ins->type, val_shift, mask);
23296         use_triple(val_shift, val_mask);
23297         use_triple(mask,      val_mask);
23298
23299         /* Move all of the users over to the new expression */
23300         propogate_use(state, ins, val_mask);
23301
23302         /* Release the original instruction */
23303         release_triple(state, ins);
23304
23305         return mask;
23306
23307 }
23308
23309 static struct triple *transform_to_arch_instruction(
23310         struct compile_state *state, struct triple *ins)
23311 {
23312         /* Transform from generic 3 address instructions
23313          * to archtecture specific instructions.
23314          * And apply architecture specific constraints to instructions.
23315          * Copies are inserted to preserve the register flexibility
23316          * of 3 address instructions.
23317          */
23318         struct triple *next, *value;
23319         size_t size;
23320         next = ins->next;
23321         switch(ins->op) {
23322         case OP_INTCONST:
23323                 ins->template_id = TEMPLATE_INTCONST32;
23324                 if (ins->u.cval < 256) {
23325                         ins->template_id = TEMPLATE_INTCONST8;
23326                 }
23327                 break;
23328         case OP_ADDRCONST:
23329                 ins->template_id = TEMPLATE_INTCONST32;
23330                 break;
23331         case OP_UNKNOWNVAL:
23332                 ins->template_id = TEMPLATE_UNKNOWNVAL;
23333                 break;
23334         case OP_NOOP:
23335         case OP_SDECL:
23336         case OP_BLOBCONST:
23337         case OP_LABEL:
23338                 ins->template_id = TEMPLATE_NOP;
23339                 break;
23340         case OP_COPY:
23341         case OP_CONVERT:
23342                 size = size_of(state, ins->type);
23343                 value = RHS(ins, 0);
23344                 if (is_imm8(value) && (size <= SIZEOF_I8)) {
23345                         ins->template_id = TEMPLATE_COPY_IMM8;
23346                 }
23347                 else if (is_imm16(value) && (size <= SIZEOF_I16)) {
23348                         ins->template_id = TEMPLATE_COPY_IMM16;
23349                 }
23350                 else if (is_imm32(value) && (size <= SIZEOF_I32)) {
23351                         ins->template_id = TEMPLATE_COPY_IMM32;
23352                 }
23353                 else if (is_const(value)) {
23354                         internal_error(state, ins, "bad constant passed to copy");
23355                 }
23356                 else if (size <= SIZEOF_I8) {
23357                         ins->template_id = TEMPLATE_COPY8_REG;
23358                 }
23359                 else if (size <= SIZEOF_I16) {
23360                         ins->template_id = TEMPLATE_COPY16_REG;
23361                 }
23362                 else if (size <= SIZEOF_I32) {
23363                         ins->template_id = TEMPLATE_COPY32_REG;
23364                 }
23365                 else {
23366                         internal_error(state, ins, "bad type passed to copy");
23367                 }
23368                 break;
23369         case OP_PHI:
23370                 size = size_of(state, ins->type);
23371                 if (size <= SIZEOF_I8) {
23372                         ins->template_id = TEMPLATE_PHI8;
23373                 }
23374                 else if (size <= SIZEOF_I16) {
23375                         ins->template_id = TEMPLATE_PHI16;
23376                 }
23377                 else if (size <= SIZEOF_I32) {
23378                         ins->template_id = TEMPLATE_PHI32;
23379                 }
23380                 else {
23381                         internal_error(state, ins, "bad type passed to phi");
23382                 }
23383                 break;
23384         case OP_ADECL:
23385                 /* Adecls should always be treated as dead code and
23386                  * removed.  If we are not optimizing they may linger.
23387                  */
23388                 if (!noop_adecl(ins)) {
23389                         internal_error(state, ins, "adecl remains?");
23390                 }
23391                 ins->template_id = TEMPLATE_NOP;
23392                 next = after_lhs(state, ins);
23393                 break;
23394         case OP_STORE:
23395                 switch(ins->type->type & TYPE_MASK) {
23396                 case TYPE_CHAR:    case TYPE_UCHAR:
23397                         ins->template_id = TEMPLATE_STORE8;
23398                         break;
23399                 case TYPE_SHORT:   case TYPE_USHORT:
23400                         ins->template_id = TEMPLATE_STORE16;
23401                         break;
23402                 case TYPE_INT:     case TYPE_UINT:
23403                 case TYPE_LONG:    case TYPE_ULONG:
23404                 case TYPE_POINTER:
23405                         ins->template_id = TEMPLATE_STORE32;
23406                         break;
23407                 default:
23408                         internal_error(state, ins, "unknown type in store");
23409                         break;
23410                 }
23411                 break;
23412         case OP_LOAD:
23413                 switch(ins->type->type & TYPE_MASK) {
23414                 case TYPE_CHAR:   case TYPE_UCHAR:
23415                 case TYPE_SHORT:  case TYPE_USHORT:
23416                 case TYPE_INT:    case TYPE_UINT:
23417                 case TYPE_LONG:   case TYPE_ULONG:
23418                 case TYPE_POINTER:
23419                         break;
23420                 default:
23421                         internal_error(state, ins, "unknown type in load");
23422                         break;
23423                 }
23424                 ins->template_id = TEMPLATE_LOAD32;
23425                 break;
23426         case OP_ADD:
23427         case OP_SUB:
23428         case OP_AND:
23429         case OP_XOR:
23430         case OP_OR:
23431         case OP_SMUL:
23432                 ins->template_id = TEMPLATE_BINARY32_REG;
23433                 if (get_imm32(ins, &RHS(ins, 1))) {
23434                         ins->template_id = TEMPLATE_BINARY32_IMM;
23435                 }
23436                 break;
23437         case OP_SDIVT:
23438         case OP_UDIVT:
23439                 ins->template_id = TEMPLATE_DIV32;
23440                 next = after_lhs(state, ins);
23441                 break;
23442         case OP_UMUL:
23443                 ins->template_id = TEMPLATE_UMUL32;
23444                 break;
23445         case OP_UDIV:
23446                 next = mod_div(state, ins, OP_UDIVT, 0);
23447                 break;
23448         case OP_SDIV:
23449                 next = mod_div(state, ins, OP_SDIVT, 0);
23450                 break;
23451         case OP_UMOD:
23452                 next = mod_div(state, ins, OP_UDIVT, 1);
23453                 break;
23454         case OP_SMOD:
23455                 next = mod_div(state, ins, OP_SDIVT, 1);
23456                 break;
23457         case OP_SL:
23458         case OP_SSR:
23459         case OP_USR:
23460                 ins->template_id = TEMPLATE_SL32_CL;
23461                 if (get_imm8(ins, &RHS(ins, 1))) {
23462                         ins->template_id = TEMPLATE_SL32_IMM;
23463                 } else if (size_of(state, RHS(ins, 1)->type) > SIZEOF_CHAR) {
23464                         typed_pre_copy(state, &uchar_type, ins, 1);
23465                 }
23466                 break;
23467         case OP_INVERT:
23468         case OP_NEG:
23469                 ins->template_id = TEMPLATE_UNARY32;
23470                 break;
23471         case OP_EQ: 
23472                 bool_cmp(state, ins, OP_CMP, OP_JMP_EQ, OP_SET_EQ); 
23473                 break;
23474         case OP_NOTEQ:
23475                 bool_cmp(state, ins, OP_CMP, OP_JMP_NOTEQ, OP_SET_NOTEQ);
23476                 break;
23477         case OP_SLESS:
23478                 bool_cmp(state, ins, OP_CMP, OP_JMP_SLESS, OP_SET_SLESS);
23479                 break;
23480         case OP_ULESS:
23481                 bool_cmp(state, ins, OP_CMP, OP_JMP_ULESS, OP_SET_ULESS);
23482                 break;
23483         case OP_SMORE:
23484                 bool_cmp(state, ins, OP_CMP, OP_JMP_SMORE, OP_SET_SMORE);
23485                 break;
23486         case OP_UMORE:
23487                 bool_cmp(state, ins, OP_CMP, OP_JMP_UMORE, OP_SET_UMORE);
23488                 break;
23489         case OP_SLESSEQ:
23490                 bool_cmp(state, ins, OP_CMP, OP_JMP_SLESSEQ, OP_SET_SLESSEQ);
23491                 break;
23492         case OP_ULESSEQ:
23493                 bool_cmp(state, ins, OP_CMP, OP_JMP_ULESSEQ, OP_SET_ULESSEQ);
23494                 break;
23495         case OP_SMOREEQ:
23496                 bool_cmp(state, ins, OP_CMP, OP_JMP_SMOREEQ, OP_SET_SMOREEQ);
23497                 break;
23498         case OP_UMOREEQ:
23499                 bool_cmp(state, ins, OP_CMP, OP_JMP_UMOREEQ, OP_SET_UMOREEQ);
23500                 break;
23501         case OP_LTRUE:
23502                 bool_cmp(state, ins, OP_TEST, OP_JMP_NOTEQ, OP_SET_NOTEQ);
23503                 break;
23504         case OP_LFALSE:
23505                 bool_cmp(state, ins, OP_TEST, OP_JMP_EQ, OP_SET_EQ);
23506                 break;
23507         case OP_BRANCH:
23508                 ins->op = OP_JMP;
23509                 ins->template_id = TEMPLATE_NOP;
23510                 break;
23511         case OP_CBRANCH:
23512                 fixup_branch(state, ins, OP_JMP_NOTEQ, OP_TEST, 
23513                         RHS(ins, 0)->type, RHS(ins, 0), 0);
23514                 break;
23515         case OP_CALL:
23516                 ins->template_id = TEMPLATE_NOP;
23517                 break;
23518         case OP_RET:
23519                 ins->template_id = TEMPLATE_RET;
23520                 break;
23521         case OP_INB:
23522         case OP_INW:
23523         case OP_INL:
23524                 switch(ins->op) {
23525                 case OP_INB: ins->template_id = TEMPLATE_INB_DX; break;
23526                 case OP_INW: ins->template_id = TEMPLATE_INW_DX; break;
23527                 case OP_INL: ins->template_id = TEMPLATE_INL_DX; break;
23528                 }
23529                 if (get_imm8(ins, &RHS(ins, 0))) {
23530                         ins->template_id += 1;
23531                 }
23532                 break;
23533         case OP_OUTB:
23534         case OP_OUTW:
23535         case OP_OUTL:
23536                 switch(ins->op) {
23537                 case OP_OUTB: ins->template_id = TEMPLATE_OUTB_DX; break;
23538                 case OP_OUTW: ins->template_id = TEMPLATE_OUTW_DX; break;
23539                 case OP_OUTL: ins->template_id = TEMPLATE_OUTL_DX; break;
23540                 }
23541                 if (get_imm8(ins, &RHS(ins, 1))) {
23542                         ins->template_id += 1;
23543                 }
23544                 break;
23545         case OP_BSF:
23546         case OP_BSR:
23547                 ins->template_id = TEMPLATE_BSF;
23548                 break;
23549         case OP_RDMSR:
23550                 ins->template_id = TEMPLATE_RDMSR;
23551                 next = after_lhs(state, ins);
23552                 break;
23553         case OP_WRMSR:
23554                 ins->template_id = TEMPLATE_WRMSR;
23555                 break;
23556         case OP_HLT:
23557                 ins->template_id = TEMPLATE_NOP;
23558                 break;
23559         case OP_ASM:
23560                 ins->template_id = TEMPLATE_NOP;
23561                 next = after_lhs(state, ins);
23562                 break;
23563                 /* Already transformed instructions */
23564         case OP_TEST:
23565                 ins->template_id = TEMPLATE_TEST32;
23566                 break;
23567         case OP_CMP:
23568                 ins->template_id = TEMPLATE_CMP32_REG;
23569                 if (get_imm32(ins, &RHS(ins, 1))) {
23570                         ins->template_id = TEMPLATE_CMP32_IMM;
23571                 }
23572                 break;
23573         case OP_JMP:
23574                 ins->template_id = TEMPLATE_NOP;
23575                 break;
23576         case OP_JMP_EQ:      case OP_JMP_NOTEQ:
23577         case OP_JMP_SLESS:   case OP_JMP_ULESS:
23578         case OP_JMP_SMORE:   case OP_JMP_UMORE:
23579         case OP_JMP_SLESSEQ: case OP_JMP_ULESSEQ:
23580         case OP_JMP_SMOREEQ: case OP_JMP_UMOREEQ:
23581                 ins->template_id = TEMPLATE_JMP;
23582                 break;
23583         case OP_SET_EQ:      case OP_SET_NOTEQ:
23584         case OP_SET_SLESS:   case OP_SET_ULESS:
23585         case OP_SET_SMORE:   case OP_SET_UMORE:
23586         case OP_SET_SLESSEQ: case OP_SET_ULESSEQ:
23587         case OP_SET_SMOREEQ: case OP_SET_UMOREEQ:
23588                 ins->template_id = TEMPLATE_SET;
23589                 break;
23590         case OP_DEPOSIT:
23591                 next = x86_deposit(state, ins);
23592                 break;
23593         case OP_SEXTRACT:
23594         case OP_UEXTRACT:
23595                 next = x86_extract(state, ins);
23596                 break;
23597                 /* Unhandled instructions */
23598         case OP_PIECE:
23599         default:
23600                 internal_error(state, ins, "unhandled ins: %d %s",
23601                         ins->op, tops(ins->op));
23602                 break;
23603         }
23604         return next;
23605 }
23606
23607 static long next_label(struct compile_state *state)
23608 {
23609         static long label_counter = 1000;
23610         return ++label_counter;
23611 }
23612 static void generate_local_labels(struct compile_state *state)
23613 {
23614         struct triple *first, *label;
23615         first = state->first;
23616         label = first;
23617         do {
23618                 if ((label->op == OP_LABEL) || 
23619                         (label->op == OP_SDECL)) {
23620                         if (label->use) {
23621                                 label->u.cval = next_label(state);
23622                         } else {
23623                                 label->u.cval = 0;
23624                         }
23625                         
23626                 }
23627                 label = label->next;
23628         } while(label != first);
23629 }
23630
23631 static int check_reg(struct compile_state *state, 
23632         struct triple *triple, int classes)
23633 {
23634         unsigned mask;
23635         int reg;
23636         reg = ID_REG(triple->id);
23637         if (reg == REG_UNSET) {
23638                 internal_error(state, triple, "register not set");
23639         }
23640         mask = arch_reg_regcm(state, reg);
23641         if (!(classes & mask)) {
23642                 internal_error(state, triple, "reg %d in wrong class",
23643                         reg);
23644         }
23645         return reg;
23646 }
23647
23648
23649 #if REG_XMM7 != 44
23650 #error "Registers have renumberd fix arch_reg_str"
23651 #endif
23652 static const char *arch_regs[] = {
23653         "%unset",
23654         "%unneeded",
23655         "%eflags",
23656         "%al", "%bl", "%cl", "%dl", "%ah", "%bh", "%ch", "%dh",
23657         "%ax", "%bx", "%cx", "%dx", "%si", "%di", "%bp", "%sp",
23658         "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi", "%ebp", "%esp",
23659         "%edx:%eax",
23660         "%dx:%ax",
23661         "%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7",
23662         "%xmm0", "%xmm1", "%xmm2", "%xmm3", 
23663         "%xmm4", "%xmm5", "%xmm6", "%xmm7",
23664 };
23665 static const char *arch_reg_str(int reg)
23666 {
23667         if (!((reg >= REG_EFLAGS) && (reg <= REG_XMM7))) {
23668                 reg = 0;
23669         }
23670         return arch_regs[reg];
23671 }
23672
23673 static const char *reg(struct compile_state *state, struct triple *triple,
23674         int classes)
23675 {
23676         int reg;
23677         reg = check_reg(state, triple, classes);
23678         return arch_reg_str(reg);
23679 }
23680
23681 static int arch_reg_size(int reg)
23682 {
23683         int size;
23684         size = 0;
23685         if (reg == REG_EFLAGS) {
23686                 size = 32;
23687         }
23688         else if ((reg >= REG_AL) && (reg <= REG_DH)) {
23689                 size = 8;
23690         }
23691         else if ((reg >= REG_AX) && (reg <= REG_SP)) {
23692                 size = 16;
23693         }
23694         else if ((reg >= REG_EAX) && (reg <= REG_ESP)) {
23695                 size = 32;
23696         }
23697         else if (reg == REG_EDXEAX) {
23698                 size = 64;
23699         }
23700         else if (reg == REG_DXAX) {
23701                 size = 32;
23702         }
23703         else if ((reg >= REG_MMX0) && (reg <= REG_MMX7)) {
23704                 size = 64;
23705         }
23706         else if ((reg >= REG_XMM0) && (reg <= REG_XMM7)) {
23707                 size = 128;
23708         }
23709         return size;
23710 }
23711
23712 static int reg_size(struct compile_state *state, struct triple *ins)
23713 {
23714         int reg;
23715         reg = ID_REG(ins->id);
23716         if (reg == REG_UNSET) {
23717                 internal_error(state, ins, "register not set");
23718         }
23719         return arch_reg_size(reg);
23720 }
23721         
23722
23723
23724 const char *type_suffix(struct compile_state *state, struct type *type)
23725 {
23726         const char *suffix;
23727         switch(size_of(state, type)) {
23728         case SIZEOF_I8:  suffix = "b"; break;
23729         case SIZEOF_I16: suffix = "w"; break;
23730         case SIZEOF_I32: suffix = "l"; break;
23731         default:
23732                 internal_error(state, 0, "unknown suffix");
23733                 suffix = 0;
23734                 break;
23735         }
23736         return suffix;
23737 }
23738
23739 static void print_const_val(
23740         struct compile_state *state, struct triple *ins, FILE *fp)
23741 {
23742         switch(ins->op) {
23743         case OP_INTCONST:
23744                 fprintf(fp, " $%ld ", 
23745                         (long)(ins->u.cval));
23746                 break;
23747         case OP_ADDRCONST:
23748                 if ((MISC(ins, 0)->op != OP_SDECL) &&
23749                         (MISC(ins, 0)->op != OP_LABEL))
23750                 {
23751                         internal_error(state, ins, "bad base for addrconst");
23752                 }
23753                 if (MISC(ins, 0)->u.cval <= 0) {
23754                         internal_error(state, ins, "unlabeled constant");
23755                 }
23756                 fprintf(fp, " $L%s%lu+%lu ",
23757                         state->compiler->label_prefix, 
23758                         (unsigned long)(MISC(ins, 0)->u.cval),
23759                         (unsigned long)(ins->u.cval));
23760                 break;
23761         default:
23762                 internal_error(state, ins, "unknown constant type");
23763                 break;
23764         }
23765 }
23766
23767 static void print_const(struct compile_state *state,
23768         struct triple *ins, FILE *fp)
23769 {
23770         switch(ins->op) {
23771         case OP_INTCONST:
23772                 switch(ins->type->type & TYPE_MASK) {
23773                 case TYPE_CHAR:
23774                 case TYPE_UCHAR:
23775                         fprintf(fp, ".byte 0x%02lx\n", 
23776                                 (unsigned long)(ins->u.cval));
23777                         break;
23778                 case TYPE_SHORT:
23779                 case TYPE_USHORT:
23780                         fprintf(fp, ".short 0x%04lx\n", 
23781                                 (unsigned long)(ins->u.cval));
23782                         break;
23783                 case TYPE_INT:
23784                 case TYPE_UINT:
23785                 case TYPE_LONG:
23786                 case TYPE_ULONG:
23787                 case TYPE_POINTER:
23788                         fprintf(fp, ".int %lu\n", 
23789                                 (unsigned long)(ins->u.cval));
23790                         break;
23791                 default:
23792                         fprintf(state->errout, "type: ");
23793                         name_of(state->errout, ins->type);
23794                         fprintf(state->errout, "\n");
23795                         internal_error(state, ins, "Unknown constant type. Val: %lu",
23796                                 (unsigned long)(ins->u.cval));
23797                 }
23798                 
23799                 break;
23800         case OP_ADDRCONST:
23801                 if ((MISC(ins, 0)->op != OP_SDECL) &&
23802                         (MISC(ins, 0)->op != OP_LABEL)) {
23803                         internal_error(state, ins, "bad base for addrconst");
23804                 }
23805                 if (MISC(ins, 0)->u.cval <= 0) {
23806                         internal_error(state, ins, "unlabeled constant");
23807                 }
23808                 fprintf(fp, ".int L%s%lu+%lu\n",
23809                         state->compiler->label_prefix,
23810                         (unsigned long)(MISC(ins, 0)->u.cval),
23811                         (unsigned long)(ins->u.cval));
23812                 break;
23813         case OP_BLOBCONST:
23814         {
23815                 unsigned char *blob;
23816                 size_t size, i;
23817                 size = size_of_in_bytes(state, ins->type);
23818                 blob = ins->u.blob;
23819                 for(i = 0; i < size; i++) {
23820                         fprintf(fp, ".byte 0x%02x\n",
23821                                 blob[i]);
23822                 }
23823                 break;
23824         }
23825         default:
23826                 internal_error(state, ins, "Unknown constant type");
23827                 break;
23828         }
23829 }
23830
23831 #define TEXT_SECTION ".rom.text"
23832 #define DATA_SECTION ".rom.data"
23833
23834 static long get_const_pool_ref(
23835         struct compile_state *state, struct triple *ins, size_t size, FILE *fp)
23836 {
23837         size_t fill_bytes;
23838         long ref;
23839         ref = next_label(state);
23840         fprintf(fp, ".section \"" DATA_SECTION "\"\n");
23841         fprintf(fp, ".balign %ld\n", (long int)align_of_in_bytes(state, ins->type));
23842         fprintf(fp, "L%s%lu:\n", state->compiler->label_prefix, ref);
23843         print_const(state, ins, fp);
23844         fill_bytes = bits_to_bytes(size - size_of(state, ins->type));
23845         if (fill_bytes) {
23846                 fprintf(fp, ".fill %ld, 1, 0\n", (long int)fill_bytes);
23847         }
23848         fprintf(fp, ".section \"" TEXT_SECTION "\"\n");
23849         return ref;
23850 }
23851
23852 static long get_mask_pool_ref(
23853         struct compile_state *state, struct triple *ins, unsigned long mask, FILE *fp)
23854 {
23855         long ref;
23856         if (mask == 0xff) {
23857                 ref = 1;
23858         }
23859         else if (mask == 0xffff) {
23860                 ref = 2;
23861         }
23862         else {
23863                 ref = 0;
23864                 internal_error(state, ins, "unhandled mask value");
23865         }
23866         return ref;
23867 }
23868
23869 static void print_binary_op(struct compile_state *state,
23870         const char *op, struct triple *ins, FILE *fp) 
23871 {
23872         unsigned mask;
23873         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO;
23874         if (ID_REG(RHS(ins, 0)->id) != ID_REG(ins->id)) {
23875                 internal_error(state, ins, "invalid register assignment");
23876         }
23877         if (is_const(RHS(ins, 1))) {
23878                 fprintf(fp, "\t%s ", op);
23879                 print_const_val(state, RHS(ins, 1), fp);
23880                 fprintf(fp, ", %s\n",
23881                         reg(state, RHS(ins, 0), mask));
23882         }
23883         else {
23884                 unsigned lmask, rmask;
23885                 int lreg, rreg;
23886                 lreg = check_reg(state, RHS(ins, 0), mask);
23887                 rreg = check_reg(state, RHS(ins, 1), mask);
23888                 lmask = arch_reg_regcm(state, lreg);
23889                 rmask = arch_reg_regcm(state, rreg);
23890                 mask = lmask & rmask;
23891                 fprintf(fp, "\t%s %s, %s\n",
23892                         op,
23893                         reg(state, RHS(ins, 1), mask),
23894                         reg(state, RHS(ins, 0), mask));
23895         }
23896 }
23897 static void print_unary_op(struct compile_state *state, 
23898         const char *op, struct triple *ins, FILE *fp)
23899 {
23900         unsigned mask;
23901         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO;
23902         fprintf(fp, "\t%s %s\n",
23903                 op,
23904                 reg(state, RHS(ins, 0), mask));
23905 }
23906
23907 static void print_op_shift(struct compile_state *state,
23908         const char *op, struct triple *ins, FILE *fp)
23909 {
23910         unsigned mask;
23911         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO;
23912         if (ID_REG(RHS(ins, 0)->id) != ID_REG(ins->id)) {
23913                 internal_error(state, ins, "invalid register assignment");
23914         }
23915         if (is_const(RHS(ins, 1))) {
23916                 fprintf(fp, "\t%s ", op);
23917                 print_const_val(state, RHS(ins, 1), fp);
23918                 fprintf(fp, ", %s\n",
23919                         reg(state, RHS(ins, 0), mask));
23920         }
23921         else {
23922                 fprintf(fp, "\t%s %s, %s\n",
23923                         op,
23924                         reg(state, RHS(ins, 1), REGCM_GPR8_LO),
23925                         reg(state, RHS(ins, 0), mask));
23926         }
23927 }
23928
23929 static void print_op_in(struct compile_state *state, struct triple *ins, FILE *fp)
23930 {
23931         const char *op;
23932         int mask;
23933         int dreg;
23934         mask = 0;
23935         switch(ins->op) {
23936         case OP_INB: op = "inb", mask = REGCM_GPR8_LO; break;
23937         case OP_INW: op = "inw", mask = REGCM_GPR16; break;
23938         case OP_INL: op = "inl", mask = REGCM_GPR32; break;
23939         default:
23940                 internal_error(state, ins, "not an in operation");
23941                 op = 0;
23942                 break;
23943         }
23944         dreg = check_reg(state, ins, mask);
23945         if (!reg_is_reg(state, dreg, REG_EAX)) {
23946                 internal_error(state, ins, "dst != %%eax");
23947         }
23948         if (is_const(RHS(ins, 0))) {
23949                 fprintf(fp, "\t%s ", op);
23950                 print_const_val(state, RHS(ins, 0), fp);
23951                 fprintf(fp, ", %s\n",
23952                         reg(state, ins, mask));
23953         }
23954         else {
23955                 int addr_reg;
23956                 addr_reg = check_reg(state, RHS(ins, 0), REGCM_GPR16);
23957                 if (!reg_is_reg(state, addr_reg, REG_DX)) {
23958                         internal_error(state, ins, "src != %%dx");
23959                 }
23960                 fprintf(fp, "\t%s %s, %s\n",
23961                         op, 
23962                         reg(state, RHS(ins, 0), REGCM_GPR16),
23963                         reg(state, ins, mask));
23964         }
23965 }
23966
23967 static void print_op_out(struct compile_state *state, struct triple *ins, FILE *fp)
23968 {
23969         const char *op;
23970         int mask;
23971         int lreg;
23972         mask = 0;
23973         switch(ins->op) {
23974         case OP_OUTB: op = "outb", mask = REGCM_GPR8_LO; break;
23975         case OP_OUTW: op = "outw", mask = REGCM_GPR16; break;
23976         case OP_OUTL: op = "outl", mask = REGCM_GPR32; break;
23977         default:
23978                 internal_error(state, ins, "not an out operation");
23979                 op = 0;
23980                 break;
23981         }
23982         lreg = check_reg(state, RHS(ins, 0), mask);
23983         if (!reg_is_reg(state, lreg, REG_EAX)) {
23984                 internal_error(state, ins, "src != %%eax");
23985         }
23986         if (is_const(RHS(ins, 1))) {
23987                 fprintf(fp, "\t%s %s,", 
23988                         op, reg(state, RHS(ins, 0), mask));
23989                 print_const_val(state, RHS(ins, 1), fp);
23990                 fprintf(fp, "\n");
23991         }
23992         else {
23993                 int addr_reg;
23994                 addr_reg = check_reg(state, RHS(ins, 1), REGCM_GPR16);
23995                 if (!reg_is_reg(state, addr_reg, REG_DX)) {
23996                         internal_error(state, ins, "dst != %%dx");
23997                 }
23998                 fprintf(fp, "\t%s %s, %s\n",
23999                         op, 
24000                         reg(state, RHS(ins, 0), mask),
24001                         reg(state, RHS(ins, 1), REGCM_GPR16));
24002         }
24003 }
24004
24005 static void print_op_move(struct compile_state *state,
24006         struct triple *ins, FILE *fp)
24007 {
24008         /* op_move is complex because there are many types
24009          * of registers we can move between.
24010          * Because OP_COPY will be introduced in arbitrary locations
24011          * OP_COPY must not affect flags.
24012          * OP_CONVERT can change the flags and it is the only operation
24013          * where it is expected the types in the registers can change.
24014          */
24015         int omit_copy = 1; /* Is it o.k. to omit a noop copy? */
24016         struct triple *dst, *src;
24017         if (state->arch->features & X86_NOOP_COPY) {
24018                 omit_copy = 0;
24019         }
24020         if ((ins->op == OP_COPY) || (ins->op == OP_CONVERT)) {
24021                 src = RHS(ins, 0);
24022                 dst = ins;
24023         }
24024         else {
24025                 internal_error(state, ins, "unknown move operation");
24026                 src = dst = 0;
24027         }
24028         if (reg_size(state, dst) < size_of(state, dst->type)) {
24029                 internal_error(state, ins, "Invalid destination register");
24030         }
24031         if (!equiv_types(src->type, dst->type) && (dst->op == OP_COPY)) {
24032                 fprintf(state->errout, "src type: ");
24033                 name_of(state->errout, src->type);
24034                 fprintf(state->errout, "\n");
24035                 fprintf(state->errout, "dst type: ");
24036                 name_of(state->errout, dst->type);
24037                 fprintf(state->errout, "\n");
24038                 internal_error(state, ins, "Type mismatch for OP_COPY");
24039         }
24040
24041         if (!is_const(src)) {
24042                 int src_reg, dst_reg;
24043                 int src_regcm, dst_regcm;
24044                 src_reg   = ID_REG(src->id);
24045                 dst_reg   = ID_REG(dst->id);
24046                 src_regcm = arch_reg_regcm(state, src_reg);
24047                 dst_regcm = arch_reg_regcm(state, dst_reg);
24048                 /* If the class is the same just move the register */
24049                 if (src_regcm & dst_regcm & 
24050                         (REGCM_GPR8_LO | REGCM_GPR16 | REGCM_GPR32)) {
24051                         if ((src_reg != dst_reg) || !omit_copy) {
24052                                 fprintf(fp, "\tmov %s, %s\n",
24053                                         reg(state, src, src_regcm),
24054                                         reg(state, dst, dst_regcm));
24055                         }
24056                 }
24057                 /* Move 32bit to 16bit */
24058                 else if ((src_regcm & REGCM_GPR32) &&
24059                         (dst_regcm & REGCM_GPR16)) {
24060                         src_reg = (src_reg - REGC_GPR32_FIRST) + REGC_GPR16_FIRST;
24061                         if ((src_reg != dst_reg) || !omit_copy) {
24062                                 fprintf(fp, "\tmovw %s, %s\n",
24063                                         arch_reg_str(src_reg), 
24064                                         arch_reg_str(dst_reg));
24065                         }
24066                 }
24067                 /* Move from 32bit gprs to 16bit gprs */
24068                 else if ((src_regcm & REGCM_GPR32) &&
24069                         (dst_regcm & REGCM_GPR16)) {
24070                         dst_reg = (dst_reg - REGC_GPR16_FIRST) + REGC_GPR32_FIRST;
24071                         if ((src_reg != dst_reg) || !omit_copy) {
24072                                 fprintf(fp, "\tmov %s, %s\n",
24073                                         arch_reg_str(src_reg),
24074                                         arch_reg_str(dst_reg));
24075                         }
24076                 }
24077                 /* Move 32bit to 8bit */
24078                 else if ((src_regcm & REGCM_GPR32_8) &&
24079                         (dst_regcm & REGCM_GPR8_LO))
24080                 {
24081                         src_reg = (src_reg - REGC_GPR32_8_FIRST) + REGC_GPR8_FIRST;
24082                         if ((src_reg != dst_reg) || !omit_copy) {
24083                                 fprintf(fp, "\tmovb %s, %s\n",
24084                                         arch_reg_str(src_reg),
24085                                         arch_reg_str(dst_reg));
24086                         }
24087                 }
24088                 /* Move 16bit to 8bit */
24089                 else if ((src_regcm & REGCM_GPR16_8) &&
24090                         (dst_regcm & REGCM_GPR8_LO))
24091                 {
24092                         src_reg = (src_reg - REGC_GPR16_8_FIRST) + REGC_GPR8_FIRST;
24093                         if ((src_reg != dst_reg) || !omit_copy) {
24094                                 fprintf(fp, "\tmovb %s, %s\n",
24095                                         arch_reg_str(src_reg),
24096                                         arch_reg_str(dst_reg));
24097                         }
24098                 }
24099                 /* Move 8/16bit to 16/32bit */
24100                 else if ((src_regcm & (REGCM_GPR8_LO | REGCM_GPR16)) && 
24101                         (dst_regcm & (REGCM_GPR16 | REGCM_GPR32))) {
24102                         const char *op;
24103                         op = is_signed(src->type)? "movsx": "movzx";
24104                         fprintf(fp, "\t%s %s, %s\n",
24105                                 op,
24106                                 reg(state, src, src_regcm),
24107                                 reg(state, dst, dst_regcm));
24108                 }
24109                 /* Move between sse registers */
24110                 else if ((src_regcm & dst_regcm & REGCM_XMM)) {
24111                         if ((src_reg != dst_reg) || !omit_copy) {
24112                                 fprintf(fp, "\tmovdqa %s, %s\n",
24113                                         reg(state, src, src_regcm),
24114                                         reg(state, dst, dst_regcm));
24115                         }
24116                 }
24117                 /* Move between mmx registers */
24118                 else if ((src_regcm & dst_regcm & REGCM_MMX)) {
24119                         if ((src_reg != dst_reg) || !omit_copy) {
24120                                 fprintf(fp, "\tmovq %s, %s\n",
24121                                         reg(state, src, src_regcm),
24122                                         reg(state, dst, dst_regcm));
24123                         }
24124                 }
24125                 /* Move from sse to mmx registers */
24126                 else if ((src_regcm & REGCM_XMM) && (dst_regcm & REGCM_MMX)) {
24127                         fprintf(fp, "\tmovdq2q %s, %s\n",
24128                                 reg(state, src, src_regcm),
24129                                 reg(state, dst, dst_regcm));
24130                 }
24131                 /* Move from mmx to sse registers */
24132                 else if ((src_regcm & REGCM_MMX) && (dst_regcm & REGCM_XMM)) {
24133                         fprintf(fp, "\tmovq2dq %s, %s\n",
24134                                 reg(state, src, src_regcm),
24135                                 reg(state, dst, dst_regcm));
24136                 }
24137                 /* Move between 32bit gprs & mmx/sse registers */
24138                 else if ((src_regcm & (REGCM_GPR32 | REGCM_MMX | REGCM_XMM)) &&
24139                         (dst_regcm & (REGCM_GPR32 | REGCM_MMX | REGCM_XMM))) {
24140                         fprintf(fp, "\tmovd %s, %s\n",
24141                                 reg(state, src, src_regcm),
24142                                 reg(state, dst, dst_regcm));
24143                 }
24144                 /* Move from 16bit gprs &  mmx/sse registers */
24145                 else if ((src_regcm & REGCM_GPR16) &&
24146                         (dst_regcm & (REGCM_MMX | REGCM_XMM))) {
24147                         const char *op;
24148                         int mid_reg;
24149                         op = is_signed(src->type)? "movsx":"movzx";
24150                         mid_reg = (src_reg - REGC_GPR16_FIRST) + REGC_GPR32_FIRST;
24151                         fprintf(fp, "\t%s %s, %s\n\tmovd %s, %s\n",
24152                                 op,
24153                                 arch_reg_str(src_reg),
24154                                 arch_reg_str(mid_reg),
24155                                 arch_reg_str(mid_reg),
24156                                 arch_reg_str(dst_reg));
24157                 }
24158                 /* Move from mmx/sse registers to 16bit gprs */
24159                 else if ((src_regcm & (REGCM_MMX | REGCM_XMM)) &&
24160                         (dst_regcm & REGCM_GPR16)) {
24161                         dst_reg = (dst_reg - REGC_GPR16_FIRST) + REGC_GPR32_FIRST;
24162                         fprintf(fp, "\tmovd %s, %s\n",
24163                                 arch_reg_str(src_reg),
24164                                 arch_reg_str(dst_reg));
24165                 }
24166                 /* Move from gpr to 64bit dividend */
24167                 else if ((src_regcm & (REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO))  &&
24168                         (dst_regcm & REGCM_DIVIDEND64)) {
24169                         const char *extend;
24170                         extend = is_signed(src->type)? "cltd":"movl $0, %edx";
24171                         fprintf(fp, "\tmov %s, %%eax\n\t%s\n",
24172                                 arch_reg_str(src_reg), 
24173                                 extend);
24174                 }
24175                 /* Move from 64bit gpr to gpr */
24176                 else if ((src_regcm & REGCM_DIVIDEND64) &&
24177                         (dst_regcm & (REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO))) {
24178                         if (dst_regcm & REGCM_GPR32) {
24179                                 src_reg = REG_EAX;
24180                         } 
24181                         else if (dst_regcm & REGCM_GPR16) {
24182                                 src_reg = REG_AX;
24183                         }
24184                         else if (dst_regcm & REGCM_GPR8_LO) {
24185                                 src_reg = REG_AL;
24186                         }
24187                         fprintf(fp, "\tmov %s, %s\n",
24188                                 arch_reg_str(src_reg),
24189                                 arch_reg_str(dst_reg));
24190                 }
24191                 /* Move from mmx/sse registers to 64bit gpr */
24192                 else if ((src_regcm & (REGCM_MMX | REGCM_XMM)) &&
24193                         (dst_regcm & REGCM_DIVIDEND64)) {
24194                         const char *extend;
24195                         extend = is_signed(src->type)? "cltd": "movl $0, %edx";
24196                         fprintf(fp, "\tmovd %s, %%eax\n\t%s\n",
24197                                 arch_reg_str(src_reg),
24198                                 extend);
24199                 }
24200                 /* Move from 64bit gpr to mmx/sse register */
24201                 else if ((src_regcm & REGCM_DIVIDEND64) &&
24202                         (dst_regcm & (REGCM_XMM | REGCM_MMX))) {
24203                         fprintf(fp, "\tmovd %%eax, %s\n",
24204                                 arch_reg_str(dst_reg));
24205                 }
24206 #if X86_4_8BIT_GPRS
24207                 /* Move from 8bit gprs to  mmx/sse registers */
24208                 else if ((src_regcm & REGCM_GPR8_LO) && (src_reg <= REG_DL) &&
24209                         (dst_regcm & (REGCM_MMX | REGCM_XMM))) {
24210                         const char *op;
24211                         int mid_reg;
24212                         op = is_signed(src->type)? "movsx":"movzx";
24213                         mid_reg = (src_reg - REGC_GPR8_FIRST) + REGC_GPR32_FIRST;
24214                         fprintf(fp, "\t%s %s, %s\n\tmovd %s, %s\n",
24215                                 op,
24216                                 reg(state, src, src_regcm),
24217                                 arch_reg_str(mid_reg),
24218                                 arch_reg_str(mid_reg),
24219                                 reg(state, dst, dst_regcm));
24220                 }
24221                 /* Move from mmx/sse registers and 8bit gprs */
24222                 else if ((src_regcm & (REGCM_MMX | REGCM_XMM)) &&
24223                         (dst_regcm & REGCM_GPR8_LO) && (dst_reg <= REG_DL)) {
24224                         int mid_reg;
24225                         mid_reg = (dst_reg - REGC_GPR8_FIRST) + REGC_GPR32_FIRST;
24226                         fprintf(fp, "\tmovd %s, %s\n",
24227                                 reg(state, src, src_regcm),
24228                                 arch_reg_str(mid_reg));
24229                 }
24230                 /* Move from 32bit gprs to 8bit gprs */
24231                 else if ((src_regcm & REGCM_GPR32) &&
24232                         (dst_regcm & REGCM_GPR8_LO)) {
24233                         dst_reg = (dst_reg - REGC_GPR8_FIRST) + REGC_GPR32_FIRST;
24234                         if ((src_reg != dst_reg) || !omit_copy) {
24235                                 fprintf(fp, "\tmov %s, %s\n",
24236                                         arch_reg_str(src_reg),
24237                                         arch_reg_str(dst_reg));
24238                         }
24239                 }
24240                 /* Move from 16bit gprs to 8bit gprs */
24241                 else if ((src_regcm & REGCM_GPR16) &&
24242                         (dst_regcm & REGCM_GPR8_LO)) {
24243                         dst_reg = (dst_reg - REGC_GPR8_FIRST) + REGC_GPR16_FIRST;
24244                         if ((src_reg != dst_reg) || !omit_copy) {
24245                                 fprintf(fp, "\tmov %s, %s\n",
24246                                         arch_reg_str(src_reg),
24247                                         arch_reg_str(dst_reg));
24248                         }
24249                 }
24250 #endif /* X86_4_8BIT_GPRS */
24251                 /* Move from %eax:%edx to %eax:%edx */
24252                 else if ((src_regcm & REGCM_DIVIDEND64) &&
24253                         (dst_regcm & REGCM_DIVIDEND64) &&
24254                         (src_reg == dst_reg)) {
24255                         if (!omit_copy) {
24256                                 fprintf(fp, "\t/*mov %s, %s*/\n",
24257                                         arch_reg_str(src_reg),
24258                                         arch_reg_str(dst_reg));
24259                         }
24260                 }
24261                 else {
24262                         if ((src_regcm & ~REGCM_FLAGS) == 0) {
24263                                 internal_error(state, ins, "attempt to copy from %%eflags!");
24264                         }
24265                         internal_error(state, ins, "unknown copy type");
24266                 }
24267         }
24268         else {
24269                 size_t dst_size;
24270                 int dst_reg;
24271                 int dst_regcm;
24272                 dst_size = size_of(state, dst->type);
24273                 dst_reg = ID_REG(dst->id);
24274                 dst_regcm = arch_reg_regcm(state, dst_reg);
24275                 if (dst_regcm & (REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO)) {
24276                         fprintf(fp, "\tmov ");
24277                         print_const_val(state, src, fp);
24278                         fprintf(fp, ", %s\n",
24279                                 reg(state, dst, REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO));
24280                 }
24281                 else if (dst_regcm & REGCM_DIVIDEND64) {
24282                         if (dst_size > SIZEOF_I32) {
24283                                 internal_error(state, ins, "%dbit constant...", dst_size);
24284                         }
24285                         fprintf(fp, "\tmov $0, %%edx\n");
24286                         fprintf(fp, "\tmov ");
24287                         print_const_val(state, src, fp);
24288                         fprintf(fp, ", %%eax\n");
24289                 }
24290                 else if (dst_regcm & REGCM_DIVIDEND32) {
24291                         if (dst_size > SIZEOF_I16) {
24292                                 internal_error(state, ins, "%dbit constant...", dst_size);
24293                         }
24294                         fprintf(fp, "\tmov $0, %%dx\n");
24295                         fprintf(fp, "\tmov ");
24296                         print_const_val(state, src, fp);
24297                         fprintf(fp, ", %%ax");
24298                 }
24299                 else if (dst_regcm & (REGCM_XMM | REGCM_MMX)) {
24300                         long ref;
24301                         if (dst_size > SIZEOF_I32) {
24302                                 internal_error(state, ins, "%d bit constant...", dst_size);
24303                         }
24304                         ref = get_const_pool_ref(state, src, SIZEOF_I32, fp);
24305                         fprintf(fp, "\tmovd L%s%lu, %s\n",
24306                                 state->compiler->label_prefix, ref,
24307                                 reg(state, dst, (REGCM_XMM | REGCM_MMX)));
24308                 }
24309                 else {
24310                         internal_error(state, ins, "unknown copy immediate type");
24311                 }
24312         }
24313         /* Leave now if this is not a type conversion */
24314         if (ins->op != OP_CONVERT) {
24315                 return;
24316         }
24317         /* Now make certain I have not logically overflowed the destination */
24318         if ((size_of(state, src->type) > size_of(state, dst->type)) &&
24319                 (size_of(state, dst->type) < reg_size(state, dst)))
24320         {
24321                 unsigned long mask;
24322                 int dst_reg;
24323                 int dst_regcm;
24324                 if (size_of(state, dst->type) >= 32) {
24325                         fprintf(state->errout, "dst type: ");
24326                         name_of(state->errout, dst->type);
24327                         fprintf(state->errout, "\n");
24328                         internal_error(state, dst, "unhandled dst type size");
24329                 }
24330                 mask = 1;
24331                 mask <<= size_of(state, dst->type);
24332                 mask -= 1;
24333
24334                 dst_reg = ID_REG(dst->id);
24335                 dst_regcm = arch_reg_regcm(state, dst_reg);
24336
24337                 if (dst_regcm & (REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO)) {
24338                         fprintf(fp, "\tand $0x%lx, %s\n",
24339                                 mask, reg(state, dst, REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO));
24340                 }
24341                 else if (dst_regcm & REGCM_MMX) {
24342                         long ref;
24343                         ref = get_mask_pool_ref(state, dst, mask, fp);
24344                         fprintf(fp, "\tpand L%s%lu, %s\n",
24345                                 state->compiler->label_prefix, ref,
24346                                 reg(state, dst, REGCM_MMX));
24347                 }
24348                 else if (dst_regcm & REGCM_XMM) {
24349                         long ref;
24350                         ref = get_mask_pool_ref(state, dst, mask, fp);
24351                         fprintf(fp, "\tpand L%s%lu, %s\n",
24352                                 state->compiler->label_prefix, ref,
24353                                 reg(state, dst, REGCM_XMM));
24354                 }
24355                 else {
24356                         fprintf(state->errout, "dst type: ");
24357                         name_of(state->errout, dst->type);
24358                         fprintf(state->errout, "\n");
24359                         fprintf(state->errout, "dst: %s\n", reg(state, dst, REGCM_ALL));
24360                         internal_error(state, dst, "failed to trunc value: mask %lx", mask);
24361                 }
24362         }
24363         /* Make certain I am properly sign extended */
24364         if ((size_of(state, src->type) < size_of(state, dst->type)) &&
24365                 (is_signed(src->type)))
24366         {
24367                 int bits, reg_bits, shift_bits;
24368                 int dst_reg;
24369                 int dst_regcm;
24370
24371                 bits = size_of(state, src->type);
24372                 reg_bits = reg_size(state, dst);
24373                 if (reg_bits > 32) {
24374                         reg_bits = 32;
24375                 }
24376                 shift_bits = reg_bits - size_of(state, src->type);
24377                 dst_reg = ID_REG(dst->id);
24378                 dst_regcm = arch_reg_regcm(state, dst_reg);
24379
24380                 if (shift_bits < 0) {
24381                         internal_error(state, dst, "negative shift?");
24382                 }
24383
24384                 if (dst_regcm & (REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO)) {
24385                         fprintf(fp, "\tshl $%d, %s\n", 
24386                                 shift_bits, 
24387                                 reg(state, dst, REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO));
24388                         fprintf(fp, "\tsar $%d, %s\n", 
24389                                 shift_bits, 
24390                                 reg(state, dst, REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO));
24391                 }
24392                 else if (dst_regcm & (REGCM_MMX | REGCM_XMM)) {
24393                         fprintf(fp, "\tpslld $%d, %s\n",
24394                                 shift_bits, 
24395                                 reg(state, dst, REGCM_MMX | REGCM_XMM));
24396                         fprintf(fp, "\tpsrad $%d, %s\n",
24397                                 shift_bits, 
24398                                 reg(state, dst, REGCM_MMX | REGCM_XMM));
24399                 }
24400                 else {
24401                         fprintf(state->errout, "dst type: ");
24402                         name_of(state->errout, dst->type);
24403                         fprintf(state->errout, "\n");
24404                         fprintf(state->errout, "dst: %s\n", reg(state, dst, REGCM_ALL));
24405                         internal_error(state, dst, "failed to signed extend value");
24406                 }
24407         }
24408 }
24409
24410 static void print_op_load(struct compile_state *state,
24411         struct triple *ins, FILE *fp)
24412 {
24413         struct triple *dst, *src;
24414         const char *op;
24415         dst = ins;
24416         src = RHS(ins, 0);
24417         if (is_const(src) || is_const(dst)) {
24418                 internal_error(state, ins, "unknown load operation");
24419         }
24420         switch(ins->type->type & TYPE_MASK) {
24421         case TYPE_CHAR:   op = "movsbl"; break;
24422         case TYPE_UCHAR:  op = "movzbl"; break;
24423         case TYPE_SHORT:  op = "movswl"; break;
24424         case TYPE_USHORT: op = "movzwl"; break;
24425         case TYPE_INT:    case TYPE_UINT:
24426         case TYPE_LONG:   case TYPE_ULONG:
24427         case TYPE_POINTER:
24428                 op = "movl"; 
24429                 break;
24430         default:
24431                 internal_error(state, ins, "unknown type in load");
24432                 op = "<invalid opcode>";
24433                 break;
24434         }
24435         fprintf(fp, "\t%s (%s), %s\n",
24436                 op, 
24437                 reg(state, src, REGCM_GPR32),
24438                 reg(state, dst, REGCM_GPR32));
24439 }
24440
24441
24442 static void print_op_store(struct compile_state *state,
24443         struct triple *ins, FILE *fp)
24444 {
24445         struct triple *dst, *src;
24446         dst = RHS(ins, 0);
24447         src = RHS(ins, 1);
24448         if (is_const(src) && (src->op == OP_INTCONST)) {
24449                 long_t value;
24450                 value = (long_t)(src->u.cval);
24451                 fprintf(fp, "\tmov%s $%ld, (%s)\n",
24452                         type_suffix(state, src->type),
24453                         (long)(value),
24454                         reg(state, dst, REGCM_GPR32));
24455         }
24456         else if (is_const(dst) && (dst->op == OP_INTCONST)) {
24457                 fprintf(fp, "\tmov%s %s, 0x%08lx\n",
24458                         type_suffix(state, src->type),
24459                         reg(state, src, REGCM_GPR8_LO | REGCM_GPR16 | REGCM_GPR32),
24460                         (unsigned long)(dst->u.cval));
24461         }
24462         else {
24463                 if (is_const(src) || is_const(dst)) {
24464                         internal_error(state, ins, "unknown store operation");
24465                 }
24466                 fprintf(fp, "\tmov%s %s, (%s)\n",
24467                         type_suffix(state, src->type),
24468                         reg(state, src, REGCM_GPR8_LO | REGCM_GPR16 | REGCM_GPR32),
24469                         reg(state, dst, REGCM_GPR32));
24470         }
24471         
24472         
24473 }
24474
24475 static void print_op_smul(struct compile_state *state,
24476         struct triple *ins, FILE *fp)
24477 {
24478         if (!is_const(RHS(ins, 1))) {
24479                 fprintf(fp, "\timul %s, %s\n",
24480                         reg(state, RHS(ins, 1), REGCM_GPR32),
24481                         reg(state, RHS(ins, 0), REGCM_GPR32));
24482         }
24483         else {
24484                 fprintf(fp, "\timul ");
24485                 print_const_val(state, RHS(ins, 1), fp);
24486                 fprintf(fp, ", %s\n", reg(state, RHS(ins, 0), REGCM_GPR32));
24487         }
24488 }
24489
24490 static void print_op_cmp(struct compile_state *state,
24491         struct triple *ins, FILE *fp)
24492 {
24493         unsigned mask;
24494         int dreg;
24495         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO;
24496         dreg = check_reg(state, ins, REGCM_FLAGS);
24497         if (!reg_is_reg(state, dreg, REG_EFLAGS)) {
24498                 internal_error(state, ins, "bad dest register for cmp");
24499         }
24500         if (is_const(RHS(ins, 1))) {
24501                 fprintf(fp, "\tcmp ");
24502                 print_const_val(state, RHS(ins, 1), fp);
24503                 fprintf(fp, ", %s\n", reg(state, RHS(ins, 0), mask));
24504         }
24505         else {
24506                 unsigned lmask, rmask;
24507                 int lreg, rreg;
24508                 lreg = check_reg(state, RHS(ins, 0), mask);
24509                 rreg = check_reg(state, RHS(ins, 1), mask);
24510                 lmask = arch_reg_regcm(state, lreg);
24511                 rmask = arch_reg_regcm(state, rreg);
24512                 mask = lmask & rmask;
24513                 fprintf(fp, "\tcmp %s, %s\n",
24514                         reg(state, RHS(ins, 1), mask),
24515                         reg(state, RHS(ins, 0), mask));
24516         }
24517 }
24518
24519 static void print_op_test(struct compile_state *state,
24520         struct triple *ins, FILE *fp)
24521 {
24522         unsigned mask;
24523         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO;
24524         fprintf(fp, "\ttest %s, %s\n",
24525                 reg(state, RHS(ins, 0), mask),
24526                 reg(state, RHS(ins, 0), mask));
24527 }
24528
24529 static void print_op_branch(struct compile_state *state,
24530         struct triple *branch, FILE *fp)
24531 {
24532         const char *bop = "j";
24533         if ((branch->op == OP_JMP) || (branch->op == OP_CALL)) {
24534                 if (branch->rhs != 0) {
24535                         internal_error(state, branch, "jmp with condition?");
24536                 }
24537                 bop = "jmp";
24538         }
24539         else {
24540                 struct triple *ptr;
24541                 if (branch->rhs != 1) {
24542                         internal_error(state, branch, "jmpcc without condition?");
24543                 }
24544                 check_reg(state, RHS(branch, 0), REGCM_FLAGS);
24545                 if ((RHS(branch, 0)->op != OP_CMP) &&
24546                         (RHS(branch, 0)->op != OP_TEST)) {
24547                         internal_error(state, branch, "bad branch test");
24548                 }
24549 #if DEBUG_ROMCC_WARNINGS
24550 #warning "FIXME I have observed instructions between the test and branch instructions"
24551 #endif
24552                 ptr = RHS(branch, 0);
24553                 for(ptr = RHS(branch, 0)->next; ptr != branch; ptr = ptr->next) {
24554                         if (ptr->op != OP_COPY) {
24555                                 internal_error(state, branch, "branch does not follow test");
24556                         }
24557                 }
24558                 switch(branch->op) {
24559                 case OP_JMP_EQ:       bop = "jz";  break;
24560                 case OP_JMP_NOTEQ:    bop = "jnz"; break;
24561                 case OP_JMP_SLESS:    bop = "jl";  break;
24562                 case OP_JMP_ULESS:    bop = "jb";  break;
24563                 case OP_JMP_SMORE:    bop = "jg";  break;
24564                 case OP_JMP_UMORE:    bop = "ja";  break;
24565                 case OP_JMP_SLESSEQ:  bop = "jle"; break;
24566                 case OP_JMP_ULESSEQ:  bop = "jbe"; break;
24567                 case OP_JMP_SMOREEQ:  bop = "jge"; break;
24568                 case OP_JMP_UMOREEQ:  bop = "jae"; break;
24569                 default:
24570                         internal_error(state, branch, "Invalid branch op");
24571                         break;
24572                 }
24573                 
24574         }
24575 #if 1
24576         if (branch->op == OP_CALL) {
24577                 fprintf(fp, "\t/* call */\n");
24578         }
24579 #endif
24580         fprintf(fp, "\t%s L%s%lu\n",
24581                 bop, 
24582                 state->compiler->label_prefix,
24583                 (unsigned long)(TARG(branch, 0)->u.cval));
24584 }
24585
24586 static void print_op_ret(struct compile_state *state,
24587         struct triple *branch, FILE *fp)
24588 {
24589         fprintf(fp, "\tjmp *%s\n",
24590                 reg(state, RHS(branch, 0), REGCM_GPR32));
24591 }
24592
24593 static void print_op_set(struct compile_state *state,
24594         struct triple *set, FILE *fp)
24595 {
24596         const char *sop = "set";
24597         if (set->rhs != 1) {
24598                 internal_error(state, set, "setcc without condition?");
24599         }
24600         check_reg(state, RHS(set, 0), REGCM_FLAGS);
24601         if ((RHS(set, 0)->op != OP_CMP) &&
24602                 (RHS(set, 0)->op != OP_TEST)) {
24603                 internal_error(state, set, "bad set test");
24604         }
24605         if (RHS(set, 0)->next != set) {
24606                 internal_error(state, set, "set does not follow test");
24607         }
24608         switch(set->op) {
24609         case OP_SET_EQ:       sop = "setz";  break;
24610         case OP_SET_NOTEQ:    sop = "setnz"; break;
24611         case OP_SET_SLESS:    sop = "setl";  break;
24612         case OP_SET_ULESS:    sop = "setb";  break;
24613         case OP_SET_SMORE:    sop = "setg";  break;
24614         case OP_SET_UMORE:    sop = "seta";  break;
24615         case OP_SET_SLESSEQ:  sop = "setle"; break;
24616         case OP_SET_ULESSEQ:  sop = "setbe"; break;
24617         case OP_SET_SMOREEQ:  sop = "setge"; break;
24618         case OP_SET_UMOREEQ:  sop = "setae"; break;
24619         default:
24620                 internal_error(state, set, "Invalid set op");
24621                 break;
24622         }
24623         fprintf(fp, "\t%s %s\n",
24624                 sop, reg(state, set, REGCM_GPR8_LO));
24625 }
24626
24627 static void print_op_bit_scan(struct compile_state *state, 
24628         struct triple *ins, FILE *fp) 
24629 {
24630         const char *op;
24631         switch(ins->op) {
24632         case OP_BSF: op = "bsf"; break;
24633         case OP_BSR: op = "bsr"; break;
24634         default: 
24635                 internal_error(state, ins, "unknown bit scan");
24636                 op = 0;
24637                 break;
24638         }
24639         fprintf(fp, 
24640                 "\t%s %s, %s\n"
24641                 "\tjnz 1f\n"
24642                 "\tmovl $-1, %s\n"
24643                 "1:\n",
24644                 op,
24645                 reg(state, RHS(ins, 0), REGCM_GPR32),
24646                 reg(state, ins, REGCM_GPR32),
24647                 reg(state, ins, REGCM_GPR32));
24648 }
24649
24650
24651 static void print_sdecl(struct compile_state *state,
24652         struct triple *ins, FILE *fp)
24653 {
24654         fprintf(fp, ".section \"" DATA_SECTION "\"\n");
24655         fprintf(fp, ".balign %ld\n", (long int)align_of_in_bytes(state, ins->type));
24656         fprintf(fp, "L%s%lu:\n", 
24657                 state->compiler->label_prefix, (unsigned long)(ins->u.cval));
24658         print_const(state, MISC(ins, 0), fp);
24659         fprintf(fp, ".section \"" TEXT_SECTION "\"\n");
24660                 
24661 }
24662
24663 static void print_instruction(struct compile_state *state,
24664         struct triple *ins, FILE *fp)
24665 {
24666         /* Assumption: after I have exted the register allocator
24667          * everything is in a valid register. 
24668          */
24669         switch(ins->op) {
24670         case OP_ASM:
24671                 print_op_asm(state, ins, fp);
24672                 break;
24673         case OP_ADD:    print_binary_op(state, "add", ins, fp); break;
24674         case OP_SUB:    print_binary_op(state, "sub", ins, fp); break;
24675         case OP_AND:    print_binary_op(state, "and", ins, fp); break;
24676         case OP_XOR:    print_binary_op(state, "xor", ins, fp); break;
24677         case OP_OR:     print_binary_op(state, "or",  ins, fp); break;
24678         case OP_SL:     print_op_shift(state, "shl", ins, fp); break;
24679         case OP_USR:    print_op_shift(state, "shr", ins, fp); break;
24680         case OP_SSR:    print_op_shift(state, "sar", ins, fp); break;
24681         case OP_POS:    break;
24682         case OP_NEG:    print_unary_op(state, "neg", ins, fp); break;
24683         case OP_INVERT: print_unary_op(state, "not", ins, fp); break;
24684         case OP_NOOP:
24685         case OP_INTCONST:
24686         case OP_ADDRCONST:
24687         case OP_BLOBCONST:
24688                 /* Don't generate anything here for constants */
24689         case OP_PHI:
24690                 /* Don't generate anything for variable declarations. */
24691                 break;
24692         case OP_UNKNOWNVAL:
24693                 fprintf(fp, " /* unknown %s */\n",
24694                         reg(state, ins, REGCM_ALL));
24695                 break;
24696         case OP_SDECL:
24697                 print_sdecl(state, ins, fp);
24698                 break;
24699         case OP_COPY:   
24700         case OP_CONVERT:
24701                 print_op_move(state, ins, fp);
24702                 break;
24703         case OP_LOAD:
24704                 print_op_load(state, ins, fp);
24705                 break;
24706         case OP_STORE:
24707                 print_op_store(state, ins, fp);
24708                 break;
24709         case OP_SMUL:
24710                 print_op_smul(state, ins, fp);
24711                 break;
24712         case OP_CMP:    print_op_cmp(state, ins, fp); break;
24713         case OP_TEST:   print_op_test(state, ins, fp); break;
24714         case OP_JMP:
24715         case OP_JMP_EQ:      case OP_JMP_NOTEQ:
24716         case OP_JMP_SLESS:   case OP_JMP_ULESS:
24717         case OP_JMP_SMORE:   case OP_JMP_UMORE:
24718         case OP_JMP_SLESSEQ: case OP_JMP_ULESSEQ:
24719         case OP_JMP_SMOREEQ: case OP_JMP_UMOREEQ:
24720         case OP_CALL:
24721                 print_op_branch(state, ins, fp);
24722                 break;
24723         case OP_RET:
24724                 print_op_ret(state, ins, fp);
24725                 break;
24726         case OP_SET_EQ:      case OP_SET_NOTEQ:
24727         case OP_SET_SLESS:   case OP_SET_ULESS:
24728         case OP_SET_SMORE:   case OP_SET_UMORE:
24729         case OP_SET_SLESSEQ: case OP_SET_ULESSEQ:
24730         case OP_SET_SMOREEQ: case OP_SET_UMOREEQ:
24731                 print_op_set(state, ins, fp);
24732                 break;
24733         case OP_INB:  case OP_INW:  case OP_INL:
24734                 print_op_in(state, ins, fp); 
24735                 break;
24736         case OP_OUTB: case OP_OUTW: case OP_OUTL:
24737                 print_op_out(state, ins, fp); 
24738                 break;
24739         case OP_BSF:
24740         case OP_BSR:
24741                 print_op_bit_scan(state, ins, fp);
24742                 break;
24743         case OP_RDMSR:
24744                 after_lhs(state, ins);
24745                 fprintf(fp, "\trdmsr\n");
24746                 break;
24747         case OP_WRMSR:
24748                 fprintf(fp, "\twrmsr\n");
24749                 break;
24750         case OP_HLT:
24751                 fprintf(fp, "\thlt\n");
24752                 break;
24753         case OP_SDIVT:
24754                 fprintf(fp, "\tidiv %s\n", reg(state, RHS(ins, 1), REGCM_GPR32));
24755                 break;
24756         case OP_UDIVT:
24757                 fprintf(fp, "\tdiv %s\n", reg(state, RHS(ins, 1), REGCM_GPR32));
24758                 break;
24759         case OP_UMUL:
24760                 fprintf(fp, "\tmul %s\n", reg(state, RHS(ins, 1), REGCM_GPR32));
24761                 break;
24762         case OP_LABEL:
24763                 if (!ins->use) {
24764                         return;
24765                 }
24766                 fprintf(fp, "L%s%lu:\n", 
24767                         state->compiler->label_prefix, (unsigned long)(ins->u.cval));
24768                 break;
24769         case OP_ADECL:
24770                 /* Ignore adecls with no registers error otherwise */
24771                 if (!noop_adecl(ins)) {
24772                         internal_error(state, ins, "adecl remains?");
24773                 }
24774                 break;
24775                 /* Ignore OP_PIECE */
24776         case OP_PIECE:
24777                 break;
24778                 /* Operations that should never get here */
24779         case OP_SDIV: case OP_UDIV:
24780         case OP_SMOD: case OP_UMOD:
24781         case OP_LTRUE:   case OP_LFALSE:  case OP_EQ:      case OP_NOTEQ:
24782         case OP_SLESS:   case OP_ULESS:   case OP_SMORE:   case OP_UMORE:
24783         case OP_SLESSEQ: case OP_ULESSEQ: case OP_SMOREEQ: case OP_UMOREEQ:
24784         default:
24785                 internal_error(state, ins, "unknown op: %d %s",
24786                         ins->op, tops(ins->op));
24787                 break;
24788         }
24789 }
24790
24791 static void print_instructions(struct compile_state *state)
24792 {
24793         struct triple *first, *ins;
24794         int print_location;
24795         struct occurance *last_occurance;
24796         FILE *fp;
24797         int max_inline_depth;
24798         max_inline_depth = 0;
24799         print_location = 1;
24800         last_occurance = 0;
24801         fp = state->output;
24802         /* Masks for common sizes */
24803         fprintf(fp, ".section \"" DATA_SECTION "\"\n");
24804         fprintf(fp, ".balign 16\n");
24805         fprintf(fp, "L%s1:\n", state->compiler->label_prefix);
24806         fprintf(fp, ".int 0xff, 0, 0, 0\n");
24807         fprintf(fp, "L%s2:\n", state->compiler->label_prefix);
24808         fprintf(fp, ".int 0xffff, 0, 0, 0\n");
24809         fprintf(fp, ".section \"" TEXT_SECTION "\"\n");
24810         first = state->first;
24811         ins = first;
24812         do {
24813                 if (print_location && 
24814                         last_occurance != ins->occurance) {
24815                         if (!ins->occurance->parent) {
24816                                 fprintf(fp, "\t/* %s,%s:%d.%d */\n",
24817                                         ins->occurance->function?ins->occurance->function:"(null)",
24818                                         ins->occurance->filename?ins->occurance->filename:"(null)",
24819                                         ins->occurance->line,
24820                                         ins->occurance->col);
24821                         }
24822                         else {
24823                                 struct occurance *ptr;
24824                                 int inline_depth;
24825                                 fprintf(fp, "\t/*\n");
24826                                 inline_depth = 0;
24827                                 for(ptr = ins->occurance; ptr; ptr = ptr->parent) {
24828                                         inline_depth++;
24829                                         fprintf(fp, "\t * %s,%s:%d.%d\n",
24830                                                 ptr->function,
24831                                                 ptr->filename,
24832                                                 ptr->line,
24833                                                 ptr->col);
24834                                 }
24835                                 fprintf(fp, "\t */\n");
24836                                 if (inline_depth > max_inline_depth) {
24837                                         max_inline_depth = inline_depth;
24838                                 }
24839                         }
24840                         if (last_occurance) {
24841                                 put_occurance(last_occurance);
24842                         }
24843                         get_occurance(ins->occurance);
24844                         last_occurance = ins->occurance;
24845                 }
24846
24847                 print_instruction(state, ins, fp);
24848                 ins = ins->next;
24849         } while(ins != first);
24850         if (print_location) {
24851                 fprintf(fp, "/* max inline depth %d */\n",
24852                         max_inline_depth);
24853         }
24854 }
24855
24856 static void generate_code(struct compile_state *state)
24857 {
24858         generate_local_labels(state);
24859         print_instructions(state);
24860         
24861 }
24862
24863 static void print_preprocessed_tokens(struct compile_state *state)
24864 {
24865         int tok;
24866         FILE *fp;
24867         int line;
24868         const char *filename;
24869         fp = state->output;
24870         filename = 0;
24871         line = 0;
24872         for(;;) {
24873                 struct file_state *file;
24874                 struct token *tk;
24875                 const char *token_str;
24876                 tok = peek(state);
24877                 if (tok == TOK_EOF) {
24878                         break;
24879                 }
24880                 tk = eat(state, tok);
24881                 token_str = 
24882                         tk->ident ? tk->ident->name :
24883                         tk->str_len ? tk->val.str :
24884                         tokens[tk->tok];
24885
24886                 file = state->file;
24887                 while(file->macro && file->prev) {
24888                         file = file->prev;
24889                 }
24890                 if (!file->macro && 
24891                         ((file->line != line) || (file->basename != filename))) 
24892                 {
24893                         int i, col;
24894                         if ((file->basename == filename) &&
24895                                 (line < file->line)) {
24896                                 while(line < file->line) {
24897                                         fprintf(fp, "\n");
24898                                         line++;
24899                                 }
24900                         }
24901                         else {
24902                                 fprintf(fp, "\n#line %d \"%s\"\n",
24903                                         file->line, file->basename);
24904                         }
24905                         line = file->line;
24906                         filename = file->basename;
24907                         col = get_col(file) - strlen(token_str);
24908                         for(i = 0; i < col; i++) {
24909                                 fprintf(fp, " ");
24910                         }
24911                 }
24912                 
24913                 fprintf(fp, "%s ", token_str);
24914                 
24915                 if (state->compiler->debug & DEBUG_TOKENS) {
24916                         loc(state->dbgout, state, 0);
24917                         fprintf(state->dbgout, "%s <- `%s'\n",
24918                                 tokens[tok], token_str);
24919                 }
24920         }
24921 }
24922
24923 static void compile(const char *filename, const char *includefile,
24924         struct compiler_state *compiler, struct arch_state *arch)
24925 {
24926         int i;
24927         struct compile_state state;
24928         struct triple *ptr;
24929         memset(&state, 0, sizeof(state));
24930         state.compiler = compiler;
24931         state.arch     = arch;
24932         state.file = 0;
24933         for(i = 0; i < sizeof(state.token)/sizeof(state.token[0]); i++) {
24934                 memset(&state.token[i], 0, sizeof(state.token[i]));
24935                 state.token[i].tok = -1;
24936         }
24937         /* Remember the output descriptors */
24938         state.errout = stderr;
24939         state.dbgout = stdout;
24940         /* Remember the output filename */
24941         state.output    = fopen(state.compiler->ofilename, "w");
24942         if (!state.output) {
24943                 error(&state, 0, "Cannot open output file %s\n",
24944                         state.compiler->ofilename);
24945         }
24946         /* Make certain a good cleanup happens */
24947         exit_state = &state;
24948         atexit(exit_cleanup);
24949
24950         /* Prep the preprocessor */
24951         state.if_depth = 0;
24952         memset(state.if_bytes, 0, sizeof(state.if_bytes));
24953         /* register the C keywords */
24954         register_keywords(&state);
24955         /* register the keywords the macro preprocessor knows */
24956         register_macro_keywords(&state);
24957         /* generate some builtin macros */
24958         register_builtin_macros(&state);
24959         /* Memorize where some special keywords are. */
24960         state.i_switch        = lookup(&state, "switch", 6);
24961         state.i_case          = lookup(&state, "case", 4);
24962         state.i_continue      = lookup(&state, "continue", 8);
24963         state.i_break         = lookup(&state, "break", 5);
24964         state.i_default       = lookup(&state, "default", 7);
24965         state.i_return        = lookup(&state, "return", 6);
24966         /* Memorize where predefined macros are. */
24967         state.i___VA_ARGS__   = lookup(&state, "__VA_ARGS__", 11);
24968         state.i___FILE__      = lookup(&state, "__FILE__", 8);
24969         state.i___LINE__      = lookup(&state, "__LINE__", 8);
24970         /* Memorize where predefined identifiers are. */
24971         state.i___func__      = lookup(&state, "__func__", 8);
24972         /* Memorize where some attribute keywords are. */
24973         state.i_noinline      = lookup(&state, "noinline", 8);
24974         state.i_always_inline = lookup(&state, "always_inline", 13);
24975
24976         /* Process the command line macros */
24977         process_cmdline_macros(&state);
24978
24979         /* Allocate beginning bounding labels for the function list */
24980         state.first = label(&state);
24981         state.first->id |= TRIPLE_FLAG_VOLATILE;
24982         use_triple(state.first, state.first);
24983         ptr = label(&state);
24984         ptr->id |= TRIPLE_FLAG_VOLATILE;
24985         use_triple(ptr, ptr);
24986         flatten(&state, state.first, ptr);
24987
24988         /* Allocate a label for the pool of global variables */
24989         state.global_pool = label(&state);
24990         state.global_pool->id |= TRIPLE_FLAG_VOLATILE;
24991         flatten(&state, state.first, state.global_pool);
24992
24993         /* Enter the globl definition scope */
24994         start_scope(&state);
24995         register_builtins(&state);
24996
24997         compile_file(&state, filename, 1);
24998         if (includefile)
24999                 compile_file(&state, includefile, 1);
25000
25001         /* Stop if all we want is preprocessor output */
25002         if (state.compiler->flags & COMPILER_PP_ONLY) {
25003                 print_preprocessed_tokens(&state);
25004                 return;
25005         }
25006
25007         decls(&state);
25008
25009         /* Exit the global definition scope */
25010         end_scope(&state);
25011
25012         /* Now that basic compilation has happened 
25013          * optimize the intermediate code 
25014          */
25015         optimize(&state);
25016
25017         generate_code(&state);
25018         if (state.compiler->debug) {
25019                 fprintf(state.errout, "done\n");
25020         }
25021         exit_state = 0;
25022 }
25023
25024 static void version(FILE *fp)
25025 {
25026         fprintf(fp, "romcc " VERSION " released " RELEASE_DATE "\n");
25027 }
25028
25029 static void usage(void)
25030 {
25031         FILE *fp = stdout;
25032         version(fp);
25033         fprintf(fp,
25034                 "\nUsage: romcc [options] <source>.c\n"
25035                 "Compile a C source file generating a binary that does not implicilty use RAM\n"
25036                 "Options: \n"
25037                 "-o <output file name>\n"
25038                 "-f<option>            Specify a generic compiler option\n"
25039                 "-m<option>            Specify a arch dependent option\n"
25040                 "--                    Specify this is the last option\n"
25041                 "\nGeneric compiler options:\n"
25042         );
25043         compiler_usage(fp);
25044         fprintf(fp,
25045                 "\nArchitecture compiler options:\n"
25046         );
25047         arch_usage(fp);
25048         fprintf(fp,
25049                 "\n"
25050         );
25051 }
25052
25053 static void arg_error(char *fmt, ...)
25054 {
25055         va_list args;
25056         va_start(args, fmt);
25057         vfprintf(stderr, fmt, args);
25058         va_end(args);
25059         usage();
25060         exit(1);
25061 }
25062
25063 int main(int argc, char **argv)
25064 {
25065         const char *filename;
25066         const char *includefile = NULL;
25067         struct compiler_state compiler;
25068         struct arch_state arch;
25069         int all_opts;
25070         
25071         
25072         /* I don't want any surprises */
25073         setlocale(LC_ALL, "C");
25074
25075         init_compiler_state(&compiler);
25076         init_arch_state(&arch);
25077         filename = 0;
25078         all_opts = 0;
25079         while(argc > 1) {
25080                 if (!all_opts && (strcmp(argv[1], "-o") == 0) && (argc > 2)) {
25081                         compiler.ofilename = argv[2];
25082                         argv += 2;
25083                         argc -= 2;
25084                 }
25085                 else if (!all_opts && argv[1][0] == '-') {
25086                         int result;
25087                         result = -1;
25088                         if (strcmp(argv[1], "--") == 0) {
25089                                 result = 0;
25090                                 all_opts = 1;
25091                         }
25092                         else if (strncmp(argv[1], "-E", 2) == 0) {
25093                                 result = compiler_encode_flag(&compiler, argv[1]);
25094                         }
25095                         else if (strncmp(argv[1], "-O", 2) == 0) {
25096                                 result = compiler_encode_flag(&compiler, argv[1]);
25097                         }
25098                         else if (strncmp(argv[1], "-I", 2) == 0) {
25099                                 result = compiler_encode_flag(&compiler, argv[1]);
25100                         }
25101                         else if (strncmp(argv[1], "-D", 2) == 0) {
25102                                 result = compiler_encode_flag(&compiler, argv[1]);
25103                         }
25104                         else if (strncmp(argv[1], "-U", 2) == 0) {
25105                                 result = compiler_encode_flag(&compiler, argv[1]);
25106                         }
25107                         else if (strncmp(argv[1], "--label-prefix=", 15) == 0) {
25108                                 result = compiler_encode_flag(&compiler, argv[1]+2);
25109                         }
25110                         else if (strncmp(argv[1], "-f", 2) == 0) {
25111                                 result = compiler_encode_flag(&compiler, argv[1]+2);
25112                         }
25113                         else if (strncmp(argv[1], "-m", 2) == 0) {
25114                                 result = arch_encode_flag(&arch, argv[1]+2);
25115                         }
25116                         else if (strncmp(argv[1], "-include", 10) == 0) {
25117                                 if (includefile) {
25118                                         arg_error("Only one -include option may be specified.\n");
25119                                 } else {
25120                                         argv++;
25121                                         argc--;
25122                                         includefile = argv[1];
25123                                         result = 0;
25124                                 }
25125                         }
25126                         if (result < 0) {
25127                                 arg_error("Invalid option specified: %s\n",
25128                                         argv[1]);
25129                         }
25130                         argv++;
25131                         argc--;
25132                 }
25133                 else {
25134                         if (filename) {
25135                                 arg_error("Only one filename may be specified\n");
25136                         }
25137                         filename = argv[1];
25138                         argv++;
25139                         argc--;
25140                 }
25141         }
25142         if (!filename) {
25143                 arg_error("No filename specified\n");
25144         }
25145         compile(filename, includefile, &compiler, &arch);
25146
25147         return 0;
25148 }