- Fix silly thinkos in that caused parsing problems in romcc.
[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 "66"
7 #define RELEASE_DATE "8 November 2004"
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 #define DEBUG_CONSISTENCY 1
29 #define DEBUG_SDP_BLOCKS 0
30 #define DEBUG_TRIPLE_COLOR 0
31
32 #define DEBUG_DISPLAY_USES 1
33 #define DEBUG_DISPLAY_TYPES 1
34 #define DEBUG_REPLACE_CLOSURE_TYPE_HIRES 0
35 #define DEBUG_DECOMPOSE_PRINT_TUPLES 0
36 #define DEBUG_DECOMPOSE_HIRES  0
37 #define DEBUG_INITIALIZER 0
38 #define DEBUG_UPDATE_CLOSURE_TYPE 0
39 #define DEBUG_LOCAL_TRIPLE 0
40 #define DEBUG_BASIC_BLOCKS_VERBOSE 0
41 #define DEBUG_CPS_RENAME_VARIABLES_HIRES 0
42 #define DEBUG_SIMPLIFY_HIRES 0
43 #define DEBUG_SHRINKING 0
44 #define DEBUG_COALESCE_HITCHES 0
45 #define DEBUG_CODE_ELIMINATION 0
46
47 #define DEBUG_EXPLICIT_CLOSURES 0
48
49 #warning "FIXME give clear error messages about unused variables"
50 #warning "FIXME properly handle multi dimensional arrays"
51 #warning "FIXME handle multiple register sizes"
52
53 /*  Control flow graph of a loop without goto.
54  * 
55  *        AAA
56  *   +---/
57  *  /
58  * / +--->CCC
59  * | |    / \
60  * | |  DDD EEE    break;
61  * | |    \    \
62  * | |    FFF   \
63  *  \|    / \    \
64  *   |\ GGG HHH   |   continue;
65  *   | \  \   |   |
66  *   |  \ III |  /
67  *   |   \ | /  / 
68  *   |    vvv  /  
69  *   +----BBB /   
70  *         | /
71  *         vv
72  *        JJJ
73  *
74  * 
75  *             AAA
76  *     +-----+  |  +----+
77  *     |      \ | /     |
78  *     |       BBB  +-+ |
79  *     |       / \ /  | |
80  *     |     CCC JJJ / /
81  *     |     / \    / / 
82  *     |   DDD EEE / /  
83  *     |    |   +-/ /
84  *     |   FFF     /    
85  *     |   / \    /     
86  *     | GGG HHH /      
87  *     |  |   +-/
88  *     | III
89  *     +--+ 
90  *
91  * 
92  * DFlocal(X) = { Y <- Succ(X) | idom(Y) != X }
93  * DFup(Z)    = { Y <- DF(Z) | idom(Y) != X }
94  *
95  *
96  * [] == DFlocal(X) U DF(X)
97  * () == DFup(X)
98  *
99  * Dominator graph of the same nodes.
100  *
101  *           AAA     AAA: [ ] ()
102  *          /   \
103  *        BBB    JJJ BBB: [ JJJ ] ( JJJ )  JJJ: [ ] ()
104  *         |
105  *        CCC        CCC: [ ] ( BBB, JJJ )
106  *        / \
107  *     DDD   EEE     DDD: [ ] ( BBB ) EEE: [ JJJ ] ()
108  *      |
109  *     FFF           FFF: [ ] ( BBB )
110  *     / \         
111  *  GGG   HHH        GGG: [ ] ( BBB ) HHH: [ BBB ] ()
112  *   |
113  *  III              III: [ BBB ] ()
114  *
115  *
116  * BBB and JJJ are definitely the dominance frontier.
117  * Where do I place phi functions and how do I make that decision.
118  *   
119  */
120 static void die(char *fmt, ...)
121 {
122         va_list args;
123
124         va_start(args, fmt);
125         vfprintf(stderr, fmt, args);
126         va_end(args);
127         fflush(stdout);
128         fflush(stderr);
129         exit(1);
130 }
131
132 static void *xmalloc(size_t size, const char *name)
133 {
134         void *buf;
135         buf = malloc(size);
136         if (!buf) {
137                 die("Cannot malloc %ld bytes to hold %s: %s\n",
138                         size + 0UL, name, strerror(errno));
139         }
140         return buf;
141 }
142
143 static void *xcmalloc(size_t size, const char *name)
144 {
145         void *buf;
146         buf = xmalloc(size, name);
147         memset(buf, 0, size);
148         return buf;
149 }
150
151 static void *xrealloc(void *ptr, size_t size, const char *name)
152 {
153         void *buf;
154         buf = realloc(ptr, size);
155         if (!buf) {
156                 die("Cannot realloc %ld bytes to hold %s: %s\n",
157                         size + 0UL, name, strerror(errno));
158         }
159         return buf;
160 }
161
162 static void xfree(const void *ptr)
163 {
164         free((void *)ptr);
165 }
166
167 static char *xstrdup(const char *str)
168 {
169         char *new;
170         int len;
171         len = strlen(str);
172         new = xmalloc(len + 1, "xstrdup string");
173         memcpy(new, str, len);
174         new[len] = '\0';
175         return new;
176 }
177
178 static void xchdir(const char *path)
179 {
180         if (chdir(path) != 0) {
181                 die("chdir to `%s' failed: %s\n",
182                         path, strerror(errno));
183         }
184 }
185
186 static int exists(const char *dirname, const char *filename)
187 {
188         char cwd[MAX_CWD_SIZE];
189         int does_exist;
190
191         if (getcwd(cwd, sizeof(cwd)) == 0) {
192                 die("cwd buffer to small");
193         }
194
195         does_exist = 1;
196         if (chdir(dirname) != 0) {
197                 does_exist = 0;
198         }
199         if (does_exist && (access(filename, O_RDONLY) < 0)) {
200                 if ((errno != EACCES) && (errno != EROFS)) {
201                         does_exist = 0;
202                 }
203         }
204         xchdir(cwd);
205         return does_exist;
206 }
207
208
209 static char *slurp_file(const char *dirname, const char *filename, off_t *r_size)
210 {
211         char cwd[MAX_CWD_SIZE];
212         int fd;
213         char *buf;
214         off_t size, progress;
215         ssize_t result;
216         struct stat stats;
217         
218         if (!filename) {
219                 *r_size = 0;
220                 return 0;
221         }
222         if (getcwd(cwd, sizeof(cwd)) == 0) {
223                 die("cwd buffer to small");
224         }
225         xchdir(dirname);
226         fd = open(filename, O_RDONLY);
227         xchdir(cwd);
228         if (fd < 0) {
229                 die("Cannot open '%s' : %s\n",
230                         filename, strerror(errno));
231         }
232         result = fstat(fd, &stats);
233         if (result < 0) {
234                 die("Cannot stat: %s: %s\n",
235                         filename, strerror(errno));
236         }
237         size = stats.st_size;
238         *r_size = size +1;
239         buf = xmalloc(size +2, filename);
240         buf[size] = '\n'; /* Make certain the file is newline terminated */
241         buf[size+1] = '\0'; /* Null terminate the file for good measure */
242         progress = 0;
243         while(progress < size) {
244                 result = read(fd, buf + progress, size - progress);
245                 if (result < 0) {
246                         if ((errno == EINTR) || (errno == EAGAIN))
247                                 continue;
248                         die("read on %s of %ld bytes failed: %s\n",
249                                 filename, (size - progress)+ 0UL, strerror(errno));
250                 }
251                 progress += result;
252         }
253         result = close(fd);
254         if (result < 0) {
255                 die("Close of %s failed: %s\n",
256                         filename, strerror(errno));
257         }
258         return buf;
259 }
260
261 /* Types on the destination platform */
262 #warning "FIXME this assumes 32bit x86 is the destination"
263 typedef int8_t   schar_t;
264 typedef uint8_t  uchar_t;
265 typedef int8_t   char_t;
266 typedef int16_t  short_t;
267 typedef uint16_t ushort_t;
268 typedef int32_t  int_t;
269 typedef uint32_t uint_t;
270 typedef int32_t  long_t;
271 typedef uint32_t ulong_t;
272
273 #define SCHAR_T_MIN (-128)
274 #define SCHAR_T_MAX 127
275 #define UCHAR_T_MAX 255
276 #define CHAR_T_MIN  SCHAR_T_MIN
277 #define CHAR_T_MAX  SCHAR_T_MAX
278 #define SHRT_T_MIN  (-32768)
279 #define SHRT_T_MAX  32767
280 #define USHRT_T_MAX 65535
281 #define INT_T_MIN   (-LONG_T_MAX - 1)
282 #define INT_T_MAX   2147483647
283 #define UINT_T_MAX  4294967295U
284 #define LONG_T_MIN  (-LONG_T_MAX - 1)
285 #define LONG_T_MAX  2147483647
286 #define ULONG_T_MAX 4294967295U
287
288 #define SIZEOF_I8    8
289 #define SIZEOF_I16   16
290 #define SIZEOF_I32   32
291 #define SIZEOF_I64   64
292
293 #define SIZEOF_CHAR    8
294 #define SIZEOF_SHORT   16
295 #define SIZEOF_INT     32
296 #define SIZEOF_LONG    (sizeof(long_t)*SIZEOF_CHAR)
297
298
299 #define ALIGNOF_CHAR    8
300 #define ALIGNOF_SHORT   16
301 #define ALIGNOF_INT     32
302 #define ALIGNOF_LONG    (sizeof(long_t)*SIZEOF_CHAR)
303
304 #define REG_SIZEOF_REG     32
305 #define REG_SIZEOF_CHAR    REG_SIZEOF_REG
306 #define REG_SIZEOF_SHORT   REG_SIZEOF_REG
307 #define REG_SIZEOF_INT     REG_SIZEOF_REG
308 #define REG_SIZEOF_LONG    REG_SIZEOF_REG
309
310 #define REG_ALIGNOF_REG     REG_SIZEOF_REG
311 #define REG_ALIGNOF_CHAR    REG_SIZEOF_REG
312 #define REG_ALIGNOF_SHORT   REG_SIZEOF_REG
313 #define REG_ALIGNOF_INT     REG_SIZEOF_REG
314 #define REG_ALIGNOF_LONG    REG_SIZEOF_REG
315
316 /* Additional definitions for clarity.
317  * I currently assume a long is the largest native
318  * machine word and that a pointer fits into it.
319  */
320 #define SIZEOF_WORD     SIZEOF_LONG
321 #define SIZEOF_POINTER  SIZEOF_LONG
322 #define ALIGNOF_WORD    ALIGNOF_LONG
323 #define ALIGNOF_POINTER ALIGNOF_LONG
324 #define REG_SIZEOF_POINTER  REG_SIZEOF_LONG
325 #define REG_ALIGNOF_POINTER REG_ALIGNOF_LONG
326
327 struct file_state {
328         struct file_state *prev;
329         const char *basename;
330         char *dirname;
331         char *buf;
332         off_t size;
333         const char *pos;
334         int line;
335         const char *line_start;
336         int report_line;
337         const char *report_name;
338         const char *report_dir;
339 };
340 struct hash_entry;
341 struct token {
342         int tok;
343         struct hash_entry *ident;
344         int str_len;
345         union {
346                 ulong_t integer;
347                 const char *str;
348                 int notmacro;
349         } val;
350 };
351
352 /* I have two classes of types:
353  * Operational types.
354  * Logical types.  (The type the C standard says the operation is of)
355  *
356  * The operational types are:
357  * chars
358  * shorts
359  * ints
360  * longs
361  *
362  * floats
363  * doubles
364  * long doubles
365  *
366  * pointer
367  */
368
369
370 /* Machine model.
371  * No memory is useable by the compiler.
372  * There is no floating point support.
373  * All operations take place in general purpose registers.
374  * There is one type of general purpose register.
375  * Unsigned longs are stored in that general purpose register.
376  */
377
378 /* Operations on general purpose registers.
379  */
380
381 #define OP_SDIVT      0
382 #define OP_UDIVT      1
383 #define OP_SMUL       2
384 #define OP_UMUL       3
385 #define OP_SDIV       4
386 #define OP_UDIV       5
387 #define OP_SMOD       6
388 #define OP_UMOD       7
389 #define OP_ADD        8
390 #define OP_SUB        9
391 #define OP_SL        10
392 #define OP_USR       11
393 #define OP_SSR       12 
394 #define OP_AND       13 
395 #define OP_XOR       14
396 #define OP_OR        15
397 #define OP_POS       16 /* Dummy positive operator don't use it */
398 #define OP_NEG       17
399 #define OP_INVERT    18
400                      
401 #define OP_EQ        20
402 #define OP_NOTEQ     21
403 #define OP_SLESS     22
404 #define OP_ULESS     23
405 #define OP_SMORE     24
406 #define OP_UMORE     25
407 #define OP_SLESSEQ   26
408 #define OP_ULESSEQ   27
409 #define OP_SMOREEQ   28
410 #define OP_UMOREEQ   29
411                      
412 #define OP_LFALSE    30  /* Test if the expression is logically false */
413 #define OP_LTRUE     31  /* Test if the expression is logcially true */
414
415 #define OP_LOAD      32
416 #define OP_STORE     33
417 /* For OP_STORE ->type holds the type
418  * RHS(0) holds the destination address
419  * RHS(1) holds the value to store.
420  */
421
422 #define OP_UEXTRACT  34
423 /* OP_UEXTRACT extracts an unsigned bitfield from a pseudo register
424  * RHS(0) holds the psuedo register to extract from
425  * ->type holds the size of the bitfield.
426  * ->u.bitfield.size holds the size of the bitfield.
427  * ->u.bitfield.offset holds the offset to extract from
428  */
429 #define OP_SEXTRACT  35
430 /* OP_SEXTRACT extracts a signed bitfield from a pseudo register
431  * RHS(0) holds the psuedo register to extract from
432  * ->type holds the size of the bitfield.
433  * ->u.bitfield.size holds the size of the bitfield.
434  * ->u.bitfield.offset holds the offset to extract from
435  */
436 #define OP_DEPOSIT   36
437 /* OP_DEPOSIT replaces a bitfield with a new value.
438  * RHS(0) holds the value to replace a bitifield in.
439  * RHS(1) holds the replacement value
440  * ->u.bitfield.size holds the size of the bitfield.
441  * ->u.bitfield.offset holds the deposit into
442  */
443
444 #define OP_NOOP      37
445
446 #define OP_MIN_CONST 50
447 #define OP_MAX_CONST 58
448 #define IS_CONST_OP(X) (((X) >= OP_MIN_CONST) && ((X) <= OP_MAX_CONST))
449 #define OP_INTCONST  50
450 /* For OP_INTCONST ->type holds the type.
451  * ->u.cval holds the constant value.
452  */
453 #define OP_BLOBCONST 51
454 /* For OP_BLOBCONST ->type holds the layout and size
455  * information.  u.blob holds a pointer to the raw binary
456  * data for the constant initializer.
457  */
458 #define OP_ADDRCONST 52
459 /* For OP_ADDRCONST ->type holds the type.
460  * MISC(0) holds the reference to the static variable.
461  * ->u.cval holds an offset from that value.
462  */
463 #define OP_UNKNOWNVAL 59
464 /* For OP_UNKNOWNAL ->type holds the type.
465  * For some reason we don't know what value this type has.
466  * This allows for variables that have don't have values
467  * assigned yet, or variables whose value we simply do not know.
468  */
469
470 #define OP_WRITE     60 
471 /* OP_WRITE moves one pseudo register to another.
472  * MISC(0) holds the destination pseudo register, which must be an OP_DECL.
473  * RHS(0) holds the psuedo to move.
474  */
475
476 #define OP_READ      61
477 /* OP_READ reads the value of a variable and makes
478  * it available for the pseudo operation.
479  * Useful for things like def-use chains.
480  * RHS(0) holds points to the triple to read from.
481  */
482 #define OP_COPY      62
483 /* OP_COPY makes a copy of the pseudo register or constant in RHS(0).
484  */
485 #define OP_CONVERT   63
486 /* OP_CONVERT makes a copy of the pseudo register or constant in RHS(0).
487  * And then the type is converted appropriately.
488  */
489 #define OP_PIECE     64
490 /* OP_PIECE returns one piece of a instruction that returns a structure.
491  * MISC(0) is the instruction
492  * u.cval is the LHS piece of the instruction to return.
493  */
494 #define OP_ASM       65
495 /* OP_ASM holds a sequence of assembly instructions, the result
496  * of a C asm directive.
497  * RHS(x) holds input value x to the assembly sequence.
498  * LHS(x) holds the output value x from the assembly sequence.
499  * u.blob holds the string of assembly instructions.
500  */
501
502 #define OP_DEREF     66
503 /* OP_DEREF generates an lvalue from a pointer.
504  * RHS(0) holds the pointer value.
505  * OP_DEREF serves as a place holder to indicate all necessary
506  * checks have been done to indicate a value is an lvalue.
507  */
508 #define OP_DOT       67
509 /* OP_DOT references a submember of a structure lvalue.
510  * MISC(0) holds the lvalue.
511  * ->u.field holds the name of the field we want.
512  *
513  * Not seen after structures are flattened.
514  */
515 #define OP_INDEX     68
516 /* OP_INDEX references a submember of a tuple or array lvalue.
517  * MISC(0) holds the lvalue.
518  * ->u.cval holds the index into the lvalue.
519  *
520  * Not seen after structures are flattened.
521  */
522 #define OP_VAL       69
523 /* OP_VAL returns the value of a subexpression of the current expression.
524  * Useful for operators that have side effects.
525  * RHS(0) holds the expression.
526  * MISC(0) holds the subexpression of RHS(0) that is the
527  * value of the expression.
528  *
529  * Not seen outside of expressions.
530  */
531
532 #define OP_TUPLE     70
533 /* OP_TUPLE is an array of triples that are either variable
534  * or values for a structure or an array.  It is used as
535  * a place holder when flattening compound types.
536  * The value represented by an OP_TUPLE is held in N registers.
537  * LHS(0..N-1) refer to those registers.
538  * ->use is a list of statements that use the value.
539  * 
540  * Although OP_TUPLE always has register sized pieces they are not
541  * used until structures are flattened/decomposed into their register
542  * components. 
543  * ???? registers ????
544  */
545
546 #define OP_BITREF    71
547 /* OP_BITREF describes a bitfield as an lvalue.
548  * RHS(0) holds the register value.
549  * ->type holds the type of the bitfield.
550  * ->u.bitfield.size holds the size of the bitfield.
551  * ->u.bitfield.offset holds the offset of the bitfield in the register
552  */
553
554
555 #define OP_FCALL     72
556 /* OP_FCALL performs a procedure call. 
557  * MISC(0) holds a pointer to the OP_LIST of a function
558  * RHS(x) holds argument x of a function
559  * 
560  * Currently not seen outside of expressions.
561  */
562 #define OP_PROG      73
563 /* OP_PROG is an expression that holds a list of statements, or
564  * expressions.  The final expression is the value of the expression.
565  * RHS(0) holds the start of the list.
566  */
567
568 /* statements */
569 #define OP_LIST      80
570 /* OP_LIST Holds a list of statements that compose a function, and a result value.
571  * RHS(0) holds the list of statements.
572  * A list of all functions is maintained.
573  */
574
575 #define OP_BRANCH    81 /* an unconditional branch */
576 /* For branch instructions
577  * TARG(0) holds the branch target.
578  * ->next holds where to branch to if the branch is not taken.
579  * The branch target can only be a label
580  */
581
582 #define OP_CBRANCH   82 /* a conditional branch */
583 /* For conditional branch instructions
584  * RHS(0) holds the branch condition.
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_CALL      83 /* an uncontional branch that will return */
591 /* For call instructions
592  * MISC(0) holds the OP_RET that returns from the branch
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_RET       84 /* an uncontinonal branch through a variable back to an OP_CALL */
599 /* For call instructions
600  * RHS(0) holds the variable with the return address
601  * The branch target can only be a label
602  */
603
604 #define OP_LABEL     86
605 /* OP_LABEL is a triple that establishes an target for branches.
606  * ->use is the list of all branches that use this label.
607  */
608
609 #define OP_ADECL     87 
610 /* OP_ADECL is a triple that establishes an lvalue for assignments.
611  * A variable takes N registers to contain.
612  * LHS(0..N-1) refer to an OP_PIECE triple that represents
613  * the Xth register that the variable is stored in.
614  * ->use is a list of statements that use the variable.
615  * 
616  * Although OP_ADECL always has register sized pieces they are not
617  * used until structures are flattened/decomposed into their register
618  * components. 
619  */
620
621 #define OP_SDECL     88
622 /* OP_SDECL is a triple that establishes a variable of static
623  * storage duration.
624  * ->use is a list of statements that use the variable.
625  * MISC(0) holds the initializer expression.
626  */
627
628
629 #define OP_PHI       89
630 /* OP_PHI is a triple used in SSA form code.  
631  * It is used when multiple code paths merge and a variable needs
632  * a single assignment from any of those code paths.
633  * The operation is a cross between OP_DECL and OP_WRITE, which
634  * is what OP_PHI is generated from.
635  * 
636  * RHS(x) points to the value from code path x
637  * The number of RHS entries is the number of control paths into the block
638  * in which OP_PHI resides.  The elements of the array point to point
639  * to the variables OP_PHI is derived from.
640  *
641  * MISC(0) holds a pointer to the orginal OP_DECL node.
642  */
643
644 #if 0
645 /* continuation helpers
646  */
647 #define OP_CPS_BRANCH    90 /* an unconditional branch */
648 /* OP_CPS_BRANCH calls a continuation 
649  * RHS(x) holds argument x of the function
650  * TARG(0) holds OP_CPS_START target
651  */
652 #define OP_CPS_CBRANCH   91  /* a conditional branch */
653 /* OP_CPS_CBRANCH conditionally calls one of two continuations 
654  * RHS(0) holds the branch condition
655  * RHS(x + 1) holds argument x of the function
656  * TARG(0) holds the OP_CPS_START to jump to when true
657  * ->next holds the OP_CPS_START to jump to when false
658  */
659 #define OP_CPS_CALL      92  /* an uncontional branch that will return */
660 /* For OP_CPS_CALL instructions
661  * RHS(x) holds argument x of the function
662  * MISC(0) holds the OP_CPS_RET that returns from the branch
663  * TARG(0) holds the branch target.
664  * ->next holds where the OP_CPS_RET will return to.
665  */
666 #define OP_CPS_RET       93
667 /* OP_CPS_RET conditionally calls one of two continuations 
668  * RHS(0) holds the variable with the return function address
669  * RHS(x + 1) holds argument x of the function
670  * The branch target may be any OP_CPS_START
671  */
672 #define OP_CPS_END       94
673 /* OP_CPS_END is the triple at the end of the program.
674  * For most practical purposes it is a branch.
675  */
676 #define OP_CPS_START     95
677 /* OP_CPS_START is a triple at the start of a continuation
678  * The arguments variables takes N registers to contain.
679  * LHS(0..N-1) refer to an OP_PIECE triple that represents
680  * the Xth register that the arguments are stored in.
681  */
682 #endif
683
684 /* Architecture specific instructions */
685 #define OP_CMP         100
686 #define OP_TEST        101
687 #define OP_SET_EQ      102
688 #define OP_SET_NOTEQ   103
689 #define OP_SET_SLESS   104
690 #define OP_SET_ULESS   105
691 #define OP_SET_SMORE   106
692 #define OP_SET_UMORE   107
693 #define OP_SET_SLESSEQ 108
694 #define OP_SET_ULESSEQ 109
695 #define OP_SET_SMOREEQ 110
696 #define OP_SET_UMOREEQ 111
697
698 #define OP_JMP         112
699 #define OP_JMP_EQ      113
700 #define OP_JMP_NOTEQ   114
701 #define OP_JMP_SLESS   115
702 #define OP_JMP_ULESS   116
703 #define OP_JMP_SMORE   117
704 #define OP_JMP_UMORE   118
705 #define OP_JMP_SLESSEQ 119
706 #define OP_JMP_ULESSEQ 120
707 #define OP_JMP_SMOREEQ 121
708 #define OP_JMP_UMOREEQ 122
709
710 /* Builtin operators that it is just simpler to use the compiler for */
711 #define OP_INB         130
712 #define OP_INW         131
713 #define OP_INL         132
714 #define OP_OUTB        133
715 #define OP_OUTW        134
716 #define OP_OUTL        135
717 #define OP_BSF         136
718 #define OP_BSR         137
719 #define OP_RDMSR       138
720 #define OP_WRMSR       139
721 #define OP_HLT         140
722
723 struct op_info {
724         const char *name;
725         unsigned flags;
726 #define PURE       0x001 /* Triple has no side effects */
727 #define IMPURE     0x002 /* Triple has side effects */
728 #define PURE_BITS(FLAGS) ((FLAGS) & 0x3)
729 #define DEF        0x004 /* Triple is a variable definition */
730 #define BLOCK      0x008 /* Triple stores the current block */
731 #define STRUCTURAL 0x010 /* Triple does not generate a machine instruction */
732 #define BRANCH_BITS(FLAGS) ((FLAGS) & 0xe0 )
733 #define UBRANCH    0x020 /* Triple is an unconditional branch instruction */
734 #define CBRANCH    0x040 /* Triple is a conditional branch instruction */
735 #define RETBRANCH  0x060 /* Triple is a return instruction */
736 #define CALLBRANCH 0x080 /* Triple is a call instruction */
737 #define ENDBRANCH  0x0a0 /* Triple is an end instruction */
738 #define PART       0x100 /* Triple is really part of another triple */
739 #define BITFIELD   0x200 /* Triple manipulates a bitfield */
740         signed char lhs, rhs, misc, targ;
741 };
742
743 #define OP(LHS, RHS, MISC, TARG, FLAGS, NAME) { \
744         .name = (NAME), \
745         .flags = (FLAGS), \
746         .lhs = (LHS), \
747         .rhs = (RHS), \
748         .misc = (MISC), \
749         .targ = (TARG), \
750          }
751 static const struct op_info table_ops[] = {
752 [OP_SDIVT      ] = OP( 2,  2, 0, 0, PURE | BLOCK , "sdivt"),
753 [OP_UDIVT      ] = OP( 2,  2, 0, 0, PURE | BLOCK , "udivt"),
754 [OP_SMUL       ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "smul"),
755 [OP_UMUL       ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "umul"),
756 [OP_SDIV       ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "sdiv"),
757 [OP_UDIV       ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "udiv"),
758 [OP_SMOD       ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "smod"),
759 [OP_UMOD       ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "umod"),
760 [OP_ADD        ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "add"),
761 [OP_SUB        ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "sub"),
762 [OP_SL         ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "sl"),
763 [OP_USR        ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "usr"),
764 [OP_SSR        ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "ssr"),
765 [OP_AND        ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "and"),
766 [OP_XOR        ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "xor"),
767 [OP_OR         ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "or"),
768 [OP_POS        ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK , "pos"),
769 [OP_NEG        ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK , "neg"),
770 [OP_INVERT     ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK , "invert"),
771
772 [OP_EQ         ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "eq"),
773 [OP_NOTEQ      ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "noteq"),
774 [OP_SLESS      ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "sless"),
775 [OP_ULESS      ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "uless"),
776 [OP_SMORE      ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "smore"),
777 [OP_UMORE      ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "umore"),
778 [OP_SLESSEQ    ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "slesseq"),
779 [OP_ULESSEQ    ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "ulesseq"),
780 [OP_SMOREEQ    ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "smoreeq"),
781 [OP_UMOREEQ    ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "umoreeq"),
782 [OP_LFALSE     ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK , "lfalse"),
783 [OP_LTRUE      ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK , "ltrue"),
784
785 [OP_LOAD       ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "load"),
786 [OP_STORE      ] = OP( 0,  2, 0, 0, PURE | BLOCK , "store"),
787
788 [OP_UEXTRACT   ] = OP( 0,  1, 0, 0, PURE | DEF | BITFIELD, "uextract"),
789 [OP_SEXTRACT   ] = OP( 0,  1, 0, 0, PURE | DEF | BITFIELD, "sextract"),
790 [OP_DEPOSIT    ] = OP( 0,  2, 0, 0, PURE | DEF | BITFIELD, "deposit"),
791
792 [OP_NOOP       ] = OP( 0,  0, 0, 0, PURE | BLOCK | STRUCTURAL, "noop"),
793
794 [OP_INTCONST   ] = OP( 0,  0, 0, 0, PURE | DEF, "intconst"),
795 [OP_BLOBCONST  ] = OP( 0,  0, 0, 0, PURE , "blobconst"),
796 [OP_ADDRCONST  ] = OP( 0,  0, 1, 0, PURE | DEF, "addrconst"),
797 [OP_UNKNOWNVAL ] = OP( 0,  0, 0, 0, PURE | DEF, "unknown"),
798
799 #warning "FIXME is it correct for OP_WRITE to be a def?  I currently use it as one..."
800 [OP_WRITE      ] = OP( 0,  1, 1, 0, PURE | DEF | BLOCK, "write"),
801 [OP_READ       ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "read"),
802 [OP_COPY       ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "copy"),
803 [OP_CONVERT    ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "convert"),
804 [OP_PIECE      ] = OP( 0,  0, 1, 0, PURE | DEF | STRUCTURAL | PART, "piece"),
805 [OP_ASM        ] = OP(-1, -1, 0, 0, PURE, "asm"),
806 [OP_DEREF      ] = OP( 0,  1, 0, 0, 0 | DEF | BLOCK, "deref"), 
807 [OP_DOT        ] = OP( 0,  0, 1, 0, PURE | DEF | PART, "dot"),
808 [OP_INDEX      ] = OP( 0,  0, 1, 0, PURE | DEF | PART, "index"),
809
810 [OP_VAL        ] = OP( 0,  1, 1, 0, 0 | DEF | BLOCK, "val"),
811 [OP_TUPLE      ] = OP(-1,  0, 0, 0, 0 | PURE | BLOCK | STRUCTURAL, "tuple"),
812 [OP_BITREF     ] = OP( 0,  1, 0, 0, 0 | DEF | PURE | STRUCTURAL | BITFIELD, "bitref"),
813 /* Call is special most it can stand in for anything so it depends on context */
814 [OP_FCALL      ] = OP( 0, -1, 1, 0, 0 | BLOCK | CALLBRANCH, "fcall"),
815 [OP_PROG       ] = OP( 0,  1, 0, 0, 0 | IMPURE | BLOCK | STRUCTURAL, "prog"),
816 /* The sizes of OP_FCALL depends upon context */
817
818 [OP_LIST       ] = OP( 0,  1, 1, 0, 0 | DEF | STRUCTURAL, "list"),
819 [OP_BRANCH     ] = OP( 0,  0, 0, 1, PURE | BLOCK | UBRANCH, "branch"),
820 [OP_CBRANCH    ] = OP( 0,  1, 0, 1, PURE | BLOCK | CBRANCH, "cbranch"),
821 [OP_CALL       ] = OP( 0,  0, 1, 1, PURE | BLOCK | CALLBRANCH, "call"),
822 [OP_RET        ] = OP( 0,  1, 0, 0, PURE | BLOCK | RETBRANCH, "ret"),
823 [OP_LABEL      ] = OP( 0,  0, 0, 0, PURE | BLOCK | STRUCTURAL, "label"),
824 [OP_ADECL      ] = OP( 0,  0, 0, 0, PURE | BLOCK | STRUCTURAL, "adecl"),
825 [OP_SDECL      ] = OP( 0,  0, 1, 0, PURE | BLOCK | STRUCTURAL, "sdecl"),
826 /* The number of RHS elements of OP_PHI depend upon context */
827 [OP_PHI        ] = OP( 0, -1, 1, 0, PURE | DEF | BLOCK, "phi"),
828
829 #if 0
830 [OP_CPS_BRANCH ] = OP( 0, -1, 0, 1, PURE | BLOCK | UBRANCH,     "cps_branch"),
831 [OP_CPS_CBRANCH] = OP( 0, -1, 0, 1, PURE | BLOCK | CBRANCH,     "cps_cbranch"),
832 [OP_CPS_CALL   ] = OP( 0, -1, 1, 1, PURE | BLOCK | CALLBRANCH,  "cps_call"),
833 [OP_CPS_RET    ] = OP( 0, -1, 0, 0, PURE | BLOCK | RETBRANCH,   "cps_ret"),
834 [OP_CPS_END    ] = OP( 0, -1, 0, 0, IMPURE | BLOCK | ENDBRANCH, "cps_end"),
835 [OP_CPS_START  ] = OP( -1, 0, 0, 0, PURE | BLOCK | STRUCTURAL,  "cps_start"),
836 #endif
837
838 [OP_CMP        ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK, "cmp"),
839 [OP_TEST       ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "test"),
840 [OP_SET_EQ     ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_eq"),
841 [OP_SET_NOTEQ  ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_noteq"),
842 [OP_SET_SLESS  ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_sless"),
843 [OP_SET_ULESS  ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_uless"),
844 [OP_SET_SMORE  ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_smore"),
845 [OP_SET_UMORE  ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_umore"),
846 [OP_SET_SLESSEQ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_slesseq"),
847 [OP_SET_ULESSEQ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_ulesseq"),
848 [OP_SET_SMOREEQ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_smoreq"),
849 [OP_SET_UMOREEQ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_umoreq"),
850 [OP_JMP        ] = OP( 0,  0, 0, 1, PURE | BLOCK | UBRANCH, "jmp"),
851 [OP_JMP_EQ     ] = OP( 0,  1, 0, 1, PURE | BLOCK | CBRANCH, "jmp_eq"),
852 [OP_JMP_NOTEQ  ] = OP( 0,  1, 0, 1, PURE | BLOCK | CBRANCH, "jmp_noteq"),
853 [OP_JMP_SLESS  ] = OP( 0,  1, 0, 1, PURE | BLOCK | CBRANCH, "jmp_sless"),
854 [OP_JMP_ULESS  ] = OP( 0,  1, 0, 1, PURE | BLOCK | CBRANCH, "jmp_uless"),
855 [OP_JMP_SMORE  ] = OP( 0,  1, 0, 1, PURE | BLOCK | CBRANCH, "jmp_smore"),
856 [OP_JMP_UMORE  ] = OP( 0,  1, 0, 1, PURE | BLOCK | CBRANCH, "jmp_umore"),
857 [OP_JMP_SLESSEQ] = OP( 0,  1, 0, 1, PURE | BLOCK | CBRANCH, "jmp_slesseq"),
858 [OP_JMP_ULESSEQ] = OP( 0,  1, 0, 1, PURE | BLOCK | CBRANCH, "jmp_ulesseq"),
859 [OP_JMP_SMOREEQ] = OP( 0,  1, 0, 1, PURE | BLOCK | CBRANCH, "jmp_smoreq"),
860 [OP_JMP_UMOREEQ] = OP( 0,  1, 0, 1, PURE | BLOCK | CBRANCH, "jmp_umoreq"),
861
862 [OP_INB        ] = OP( 0,  1, 0, 0, IMPURE | DEF | BLOCK, "__inb"),
863 [OP_INW        ] = OP( 0,  1, 0, 0, IMPURE | DEF | BLOCK, "__inw"),
864 [OP_INL        ] = OP( 0,  1, 0, 0, IMPURE | DEF | BLOCK, "__inl"),
865 [OP_OUTB       ] = OP( 0,  2, 0, 0, IMPURE| BLOCK, "__outb"),
866 [OP_OUTW       ] = OP( 0,  2, 0, 0, IMPURE| BLOCK, "__outw"),
867 [OP_OUTL       ] = OP( 0,  2, 0, 0, IMPURE| BLOCK, "__outl"),
868 [OP_BSF        ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "__bsf"),
869 [OP_BSR        ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "__bsr"),
870 [OP_RDMSR      ] = OP( 2,  1, 0, 0, IMPURE | BLOCK, "__rdmsr"),
871 [OP_WRMSR      ] = OP( 0,  3, 0, 0, IMPURE | BLOCK, "__wrmsr"),
872 [OP_HLT        ] = OP( 0,  0, 0, 0, IMPURE | BLOCK, "__hlt"),
873 };
874 #undef OP
875 #define OP_MAX      (sizeof(table_ops)/sizeof(table_ops[0]))
876
877 static const char *tops(int index) 
878 {
879         static const char unknown[] = "unknown op";
880         if (index < 0) {
881                 return unknown;
882         }
883         if (index > OP_MAX) {
884                 return unknown;
885         }
886         return table_ops[index].name;
887 }
888
889 struct asm_info;
890 struct triple;
891 struct block;
892 struct triple_set {
893         struct triple_set *next;
894         struct triple *member;
895 };
896
897 #define MAX_LHS  63
898 #define MAX_RHS  127
899 #define MAX_MISC 3
900 #define MAX_TARG 1
901
902 struct occurance {
903         int count;
904         const char *filename;
905         const char *function;
906         int line;
907         int col;
908         struct occurance *parent;
909 };
910 struct bitfield {
911         ulong_t size : 8;
912         ulong_t offset : 24;
913 };
914 struct triple {
915         struct triple *next, *prev;
916         struct triple_set *use;
917         struct type *type;
918         unsigned int op : 8;
919         unsigned int template_id : 7;
920         unsigned int lhs  : 6;
921         unsigned int rhs  : 7;
922         unsigned int misc : 2;
923         unsigned int targ : 1;
924 #define TRIPLE_SIZE(TRIPLE) \
925         ((TRIPLE)->lhs + (TRIPLE)->rhs + (TRIPLE)->misc + (TRIPLE)->targ)
926 #define TRIPLE_LHS_OFF(PTR)  (0)
927 #define TRIPLE_RHS_OFF(PTR)  (TRIPLE_LHS_OFF(PTR) + (PTR)->lhs)
928 #define TRIPLE_MISC_OFF(PTR) (TRIPLE_RHS_OFF(PTR) + (PTR)->rhs)
929 #define TRIPLE_TARG_OFF(PTR) (TRIPLE_MISC_OFF(PTR) + (PTR)->misc)
930 #define LHS(PTR,INDEX) ((PTR)->param[TRIPLE_LHS_OFF(PTR) + (INDEX)])
931 #define RHS(PTR,INDEX) ((PTR)->param[TRIPLE_RHS_OFF(PTR) + (INDEX)])
932 #define TARG(PTR,INDEX) ((PTR)->param[TRIPLE_TARG_OFF(PTR) + (INDEX)])
933 #define MISC(PTR,INDEX) ((PTR)->param[TRIPLE_MISC_OFF(PTR) + (INDEX)])
934         unsigned id; /* A scratch value and finally the register */
935 #define TRIPLE_FLAG_FLATTENED   (1 << 31)
936 #define TRIPLE_FLAG_PRE_SPLIT   (1 << 30)
937 #define TRIPLE_FLAG_POST_SPLIT  (1 << 29)
938 #define TRIPLE_FLAG_VOLATILE    (1 << 28)
939 #define TRIPLE_FLAG_INLINE      (1 << 27) /* ???? */
940 #define TRIPLE_FLAG_LOCAL       (1 << 26)
941
942 #define TRIPLE_FLAG_COPY TRIPLE_FLAG_VOLATILE
943         struct occurance *occurance;
944         union {
945                 ulong_t cval;
946                 struct bitfield bitfield;
947                 struct block  *block;
948                 void *blob;
949                 struct hash_entry *field;
950                 struct asm_info *ainfo;
951                 struct triple *func;
952                 struct symbol *symbol;
953         } u;
954         struct triple *param[2];
955 };
956
957 struct reg_info {
958         unsigned reg;
959         unsigned regcm;
960 };
961 struct ins_template {
962         struct reg_info lhs[MAX_LHS + 1], rhs[MAX_RHS + 1];
963 };
964
965 struct asm_info {
966         struct ins_template tmpl;
967         char *str;
968 };
969
970 struct block_set {
971         struct block_set *next;
972         struct block *member;
973 };
974 struct block {
975         struct block *work_next;
976         struct triple *first, *last;
977         int edge_count;
978         struct block_set *edges;
979         int users;
980         struct block_set *use;
981         struct block_set *idominates;
982         struct block_set *domfrontier;
983         struct block *idom;
984         struct block_set *ipdominates;
985         struct block_set *ipdomfrontier;
986         struct block *ipdom;
987         int vertex;
988         
989 };
990
991 struct symbol {
992         struct symbol *next;
993         struct hash_entry *ident;
994         struct triple *def;
995         struct type *type;
996         int scope_depth;
997 };
998
999 struct macro_arg {
1000         struct macro_arg *next;
1001         struct hash_entry *ident;
1002 };
1003 struct macro {
1004         struct hash_entry *ident;
1005         char *buf;
1006         int buf_len;
1007         int buf_off;
1008         struct macro_arg *args;
1009         int argc;
1010 };
1011
1012 struct hash_entry {
1013         struct hash_entry *next;
1014         const char *name;
1015         int name_len;
1016         int tok;
1017         struct macro *sym_define;
1018         struct symbol *sym_label;
1019         struct symbol *sym_tag;
1020         struct symbol *sym_ident;
1021 };
1022
1023 #define HASH_TABLE_SIZE 2048
1024
1025 struct compiler_state {
1026         const char *label_prefix;
1027         const char *ofilename;
1028         unsigned long flags;
1029         unsigned long debug;
1030         unsigned long max_allocation_passes;
1031
1032         size_t include_path_count;
1033         const char **include_paths;
1034
1035         size_t define_count;
1036         const char **defines;
1037
1038         size_t undef_count;
1039         const char **undefs;
1040 };
1041 struct arch_state {
1042         unsigned long features;
1043 };
1044 struct basic_blocks {
1045         struct triple *func;
1046         struct triple *first;
1047         struct block *first_block, *last_block;
1048         int last_vertex;
1049 };
1050 #define MAX_CPP_IF_DEPTH 63
1051 struct compile_state {
1052         struct compiler_state *compiler;
1053         struct arch_state *arch;
1054         FILE *output;
1055         FILE *errout;
1056         FILE *dbgout;
1057         struct file_state *file;
1058         struct occurance *last_occurance;
1059         const char *function;
1060         int    token_base;
1061         struct token token[6];
1062         struct hash_entry *hash_table[HASH_TABLE_SIZE];
1063         struct hash_entry *i_switch;
1064         struct hash_entry *i_case;
1065         struct hash_entry *i_continue;
1066         struct hash_entry *i_break;
1067         struct hash_entry *i_default;
1068         struct hash_entry *i_return;
1069         /* Additional hash entries for predefined macros */
1070         struct hash_entry *i_defined;
1071         struct hash_entry *i___VA_ARGS__;
1072         struct hash_entry *i___FILE__;
1073         struct hash_entry *i___LINE__;
1074         /* Additional hash entries for predefined identifiers */
1075         struct hash_entry *i___func__;
1076         /* Additional hash entries for attributes */
1077         struct hash_entry *i_noinline;
1078         struct hash_entry *i_always_inline;
1079         int scope_depth;
1080         unsigned char if_bytes[(MAX_CPP_IF_DEPTH + CHAR_BIT -1)/CHAR_BIT];
1081         int if_depth;
1082         int eat_depth, eat_targ;
1083         int macro_line;
1084         struct file_state *macro_file;
1085         struct triple *functions;
1086         struct triple *main_function;
1087         struct triple *first;
1088         struct triple *global_pool;
1089         struct basic_blocks bb;
1090         int functions_joined;
1091 };
1092
1093 /* visibility global/local */
1094 /* static/auto duration */
1095 /* typedef, register, inline */
1096 #define STOR_SHIFT         0
1097 #define STOR_MASK     0x001f
1098 /* Visibility */
1099 #define STOR_GLOBAL   0x0001
1100 /* Duration */
1101 #define STOR_PERM     0x0002
1102 /* Definition locality */
1103 #define STOR_NONLOCAL 0x0004  /* The definition is not in this translation unit */
1104 /* Storage specifiers */
1105 #define STOR_AUTO     0x0000
1106 #define STOR_STATIC   0x0002
1107 #define STOR_LOCAL    0x0003
1108 #define STOR_EXTERN   0x0007
1109 #define STOR_INLINE   0x0008
1110 #define STOR_REGISTER 0x0010
1111 #define STOR_TYPEDEF  0x0018
1112
1113 #define QUAL_SHIFT         5
1114 #define QUAL_MASK     0x00e0
1115 #define QUAL_NONE     0x0000
1116 #define QUAL_CONST    0x0020
1117 #define QUAL_VOLATILE 0x0040
1118 #define QUAL_RESTRICT 0x0080
1119
1120 #define TYPE_SHIFT         8
1121 #define TYPE_MASK     0x1f00
1122 #define TYPE_INTEGER(TYPE)    ((((TYPE) >= TYPE_CHAR) && ((TYPE) <= TYPE_ULLONG)) || ((TYPE) == TYPE_ENUM) || ((TYPE) == TYPE_BITFIELD))
1123 #define TYPE_ARITHMETIC(TYPE) ((((TYPE) >= TYPE_CHAR) && ((TYPE) <= TYPE_LDOUBLE)) || ((TYPE) == TYPE_ENUM) || ((TYPE) == TYPE_BITFIELD))
1124 #define TYPE_UNSIGNED(TYPE)   ((TYPE) & 0x0100)
1125 #define TYPE_SIGNED(TYPE)     (!TYPE_UNSIGNED(TYPE))
1126 #define TYPE_MKUNSIGNED(TYPE) (((TYPE) & ~0xF000) | 0x0100)
1127 #define TYPE_RANK(TYPE)       ((TYPE) & ~0xF1FF)
1128 #define TYPE_PTR(TYPE)        (((TYPE) & TYPE_MASK) == TYPE_POINTER)
1129 #define TYPE_DEFAULT  0x0000
1130 #define TYPE_VOID     0x0100
1131 #define TYPE_CHAR     0x0200
1132 #define TYPE_UCHAR    0x0300
1133 #define TYPE_SHORT    0x0400
1134 #define TYPE_USHORT   0x0500
1135 #define TYPE_INT      0x0600
1136 #define TYPE_UINT     0x0700
1137 #define TYPE_LONG     0x0800
1138 #define TYPE_ULONG    0x0900
1139 #define TYPE_LLONG    0x0a00 /* long long */
1140 #define TYPE_ULLONG   0x0b00
1141 #define TYPE_FLOAT    0x0c00
1142 #define TYPE_DOUBLE   0x0d00
1143 #define TYPE_LDOUBLE  0x0e00 /* long double */
1144
1145 /* Note: TYPE_ENUM is chosen very carefully so TYPE_RANK works */
1146 #define TYPE_ENUM     0x1600
1147 #define TYPE_LIST     0x1700
1148 /* TYPE_LIST is a basic building block when defining enumerations
1149  * type->field_ident holds the name of this enumeration entry.
1150  * type->right holds the entry in the list.
1151  */
1152
1153 #define TYPE_STRUCT   0x1000
1154 /* For TYPE_STRUCT
1155  * type->left holds the link list of TYPE_PRODUCT entries that
1156  * make up the structure.
1157  * type->elements hold the length of the linked list
1158  */
1159 #define TYPE_UNION    0x1100
1160 /* For TYPE_UNION
1161  * type->left holds the link list of TYPE_OVERLAP entries that
1162  * make up the union.
1163  * type->elements hold the length of the linked list
1164  */
1165 #define TYPE_POINTER  0x1200 
1166 /* For TYPE_POINTER:
1167  * type->left holds the type pointed to.
1168  */
1169 #define TYPE_FUNCTION 0x1300 
1170 /* For TYPE_FUNCTION:
1171  * type->left holds the return type.
1172  * type->right holds the type of the arguments
1173  * type->elements holds the count of the arguments
1174  */
1175 #define TYPE_PRODUCT  0x1400
1176 /* TYPE_PRODUCT is a basic building block when defining structures
1177  * type->left holds the type that appears first in memory.
1178  * type->right holds the type that appears next in memory.
1179  */
1180 #define TYPE_OVERLAP  0x1500
1181 /* TYPE_OVERLAP is a basic building block when defining unions
1182  * type->left and type->right holds to types that overlap
1183  * each other in memory.
1184  */
1185 #define TYPE_ARRAY    0x1800
1186 /* TYPE_ARRAY is a basic building block when definitng arrays.
1187  * type->left holds the type we are an array of.
1188  * type->elements holds the number of elements.
1189  */
1190 #define TYPE_TUPLE    0x1900
1191 /* TYPE_TUPLE is a basic building block when defining 
1192  * positionally reference type conglomerations. (i.e. closures)
1193  * In essence it is a wrapper for TYPE_PRODUCT, like TYPE_STRUCT
1194  * except it has no field names.
1195  * type->left holds the liked list of TYPE_PRODUCT entries that
1196  * make up the closure type.
1197  * type->elements hold the number of elements in the closure.
1198  */
1199 #define TYPE_JOIN     0x1a00
1200 /* TYPE_JOIN is a basic building block when defining 
1201  * positionally reference type conglomerations. (i.e. closures)
1202  * In essence it is a wrapper for TYPE_OVERLAP, like TYPE_UNION
1203  * except it has no field names.
1204  * type->left holds the liked list of TYPE_OVERLAP entries that
1205  * make up the closure type.
1206  * type->elements hold the number of elements in the closure.
1207  */
1208 #define TYPE_BITFIELD 0x1b00
1209 /* TYPE_BITFIED is the type of a bitfield.
1210  * type->left holds the type basic type TYPE_BITFIELD is derived from.
1211  * type->elements holds the number of bits in the bitfield.
1212  */
1213 #define TYPE_UNKNOWN  0x1c00
1214 /* TYPE_UNKNOWN is the type of an unknown value.
1215  * Used on unknown consts and other places where I don't know the type.
1216  */
1217
1218 #define ATTRIB_SHIFT                 16
1219 #define ATTRIB_MASK          0xffff0000
1220 #define ATTRIB_NOINLINE      0x00010000
1221 #define ATTRIB_ALWAYS_INLINE 0x00020000
1222
1223 #define ELEMENT_COUNT_UNSPECIFIED ULONG_T_MAX
1224
1225 struct type {
1226         unsigned int type;
1227         struct type *left, *right;
1228         ulong_t elements;
1229         struct hash_entry *field_ident;
1230         struct hash_entry *type_ident;
1231 };
1232
1233 #define TEMPLATE_BITS      7
1234 #define MAX_TEMPLATES      (1<<TEMPLATE_BITS)
1235 #define MAX_REG_EQUIVS     16
1236 #define MAX_REGC           14
1237 #define MAX_REGISTERS      75
1238 #define REGISTER_BITS      7
1239 #define MAX_VIRT_REGISTERS (1<<REGISTER_BITS)
1240 #define REG_ERROR          0
1241 #define REG_UNSET          1
1242 #define REG_UNNEEDED       2
1243 #define REG_VIRT0          (MAX_REGISTERS + 0)
1244 #define REG_VIRT1          (MAX_REGISTERS + 1)
1245 #define REG_VIRT2          (MAX_REGISTERS + 2)
1246 #define REG_VIRT3          (MAX_REGISTERS + 3)
1247 #define REG_VIRT4          (MAX_REGISTERS + 4)
1248 #define REG_VIRT5          (MAX_REGISTERS + 5)
1249 #define REG_VIRT6          (MAX_REGISTERS + 6)
1250 #define REG_VIRT7          (MAX_REGISTERS + 7)
1251 #define REG_VIRT8          (MAX_REGISTERS + 8)
1252 #define REG_VIRT9          (MAX_REGISTERS + 9)
1253
1254 #if (MAX_REGISTERS + 9) > MAX_VIRT_REGISTERS
1255 #error "MAX_VIRT_REGISTERS to small"
1256 #endif
1257 #if (MAX_REGC + REGISTER_BITS) >= 26
1258 #error "Too many id bits used"
1259 #endif
1260
1261 /* Provision for 8 register classes */
1262 #define REG_SHIFT  0
1263 #define REGC_SHIFT REGISTER_BITS
1264 #define REGC_MASK (((1 << MAX_REGC) - 1) << REGISTER_BITS)
1265 #define REG_MASK (MAX_VIRT_REGISTERS -1)
1266 #define ID_REG(ID)              ((ID) & REG_MASK)
1267 #define SET_REG(ID, REG)        ((ID) = (((ID) & ~REG_MASK) | ((REG) & REG_MASK)))
1268 #define ID_REGCM(ID)            (((ID) & REGC_MASK) >> REGC_SHIFT)
1269 #define SET_REGCM(ID, REGCM)    ((ID) = (((ID) & ~REGC_MASK) | (((REGCM) << REGC_SHIFT) & REGC_MASK)))
1270 #define SET_INFO(ID, INFO)      ((ID) = (((ID) & ~(REG_MASK | REGC_MASK)) | \
1271                 (((INFO).reg) & REG_MASK) | ((((INFO).regcm) << REGC_SHIFT) & REGC_MASK)))
1272
1273 #define ARCH_INPUT_REGS 4
1274 #define ARCH_OUTPUT_REGS 4
1275
1276 static const struct reg_info arch_input_regs[ARCH_INPUT_REGS];
1277 static const struct reg_info arch_output_regs[ARCH_OUTPUT_REGS];
1278 static unsigned arch_reg_regcm(struct compile_state *state, int reg);
1279 static unsigned arch_regcm_normalize(struct compile_state *state, unsigned regcm);
1280 static unsigned arch_regcm_reg_normalize(struct compile_state *state, unsigned regcm);
1281 static void arch_reg_equivs(
1282         struct compile_state *state, unsigned *equiv, int reg);
1283 static int arch_select_free_register(
1284         struct compile_state *state, char *used, int classes);
1285 static unsigned arch_regc_size(struct compile_state *state, int class);
1286 static int arch_regcm_intersect(unsigned regcm1, unsigned regcm2);
1287 static unsigned arch_type_to_regcm(struct compile_state *state, struct type *type);
1288 static const char *arch_reg_str(int reg);
1289 static struct reg_info arch_reg_constraint(
1290         struct compile_state *state, struct type *type, const char *constraint);
1291 static struct reg_info arch_reg_clobber(
1292         struct compile_state *state, const char *clobber);
1293 static struct reg_info arch_reg_lhs(struct compile_state *state, 
1294         struct triple *ins, int index);
1295 static struct reg_info arch_reg_rhs(struct compile_state *state, 
1296         struct triple *ins, int index);
1297 static int arch_reg_size(int reg);
1298 static struct triple *transform_to_arch_instruction(
1299         struct compile_state *state, struct triple *ins);
1300 static struct triple *flatten(
1301         struct compile_state *state, struct triple *first, struct triple *ptr);
1302
1303
1304
1305
1306 #define DEBUG_ABORT_ON_ERROR    0x00000001
1307 #define DEBUG_BASIC_BLOCKS      0x00000002
1308 #define DEBUG_FDOMINATORS       0x00000004
1309 #define DEBUG_RDOMINATORS       0x00000008
1310 #define DEBUG_TRIPLES           0x00000010
1311 #define DEBUG_INTERFERENCE      0x00000020
1312 #define DEBUG_SCC_TRANSFORM     0x00000040
1313 #define DEBUG_SCC_TRANSFORM2    0x00000080
1314 #define DEBUG_REBUILD_SSA_FORM  0x00000100
1315 #define DEBUG_INLINE            0x00000200
1316 #define DEBUG_RANGE_CONFLICTS   0x00000400
1317 #define DEBUG_RANGE_CONFLICTS2  0x00000800
1318 #define DEBUG_COLOR_GRAPH       0x00001000
1319 #define DEBUG_COLOR_GRAPH2      0x00002000
1320 #define DEBUG_COALESCING        0x00004000
1321 #define DEBUG_COALESCING2       0x00008000
1322 #define DEBUG_VERIFICATION      0x00010000
1323 #define DEBUG_CALLS             0x00020000
1324 #define DEBUG_CALLS2            0x00040000
1325 #define DEBUG_TOKENS            0x80000000
1326
1327 #define DEBUG_DEFAULT ( \
1328         DEBUG_ABORT_ON_ERROR | \
1329         DEBUG_BASIC_BLOCKS | \
1330         DEBUG_FDOMINATORS | \
1331         DEBUG_RDOMINATORS | \
1332         DEBUG_TRIPLES | \
1333         0 )
1334
1335 #define DEBUG_ALL ( \
1336         DEBUG_ABORT_ON_ERROR   | \
1337         DEBUG_BASIC_BLOCKS     | \
1338         DEBUG_FDOMINATORS      | \
1339         DEBUG_RDOMINATORS      | \
1340         DEBUG_TRIPLES          | \
1341         DEBUG_INTERFERENCE     | \
1342         DEBUG_SCC_TRANSFORM    | \
1343         DEBUG_SCC_TRANSFORM2   | \
1344         DEBUG_REBUILD_SSA_FORM | \
1345         DEBUG_INLINE           | \
1346         DEBUG_RANGE_CONFLICTS  | \
1347         DEBUG_RANGE_CONFLICTS2 | \
1348         DEBUG_COLOR_GRAPH      | \
1349         DEBUG_COLOR_GRAPH2     | \
1350         DEBUG_COALESCING       | \
1351         DEBUG_COALESCING2      | \
1352         DEBUG_VERIFICATION     | \
1353         DEBUG_CALLS            | \
1354         DEBUG_CALLS2           | \
1355         DEBUG_TOKENS           | \
1356         0 )
1357
1358 #define COMPILER_INLINE_MASK               0x00000007
1359 #define COMPILER_INLINE_ALWAYS             0x00000000
1360 #define COMPILER_INLINE_NEVER              0x00000001
1361 #define COMPILER_INLINE_DEFAULTON          0x00000002
1362 #define COMPILER_INLINE_DEFAULTOFF         0x00000003
1363 #define COMPILER_INLINE_NOPENALTY          0x00000004
1364 #define COMPILER_ELIMINATE_INEFECTUAL_CODE 0x00000008
1365 #define COMPILER_SIMPLIFY                  0x00000010
1366 #define COMPILER_SCC_TRANSFORM             0x00000020
1367 #define COMPILER_SIMPLIFY_OP               0x00000040
1368 #define COMPILER_SIMPLIFY_PHI              0x00000080
1369 #define COMPILER_SIMPLIFY_LABEL            0x00000100
1370 #define COMPILER_SIMPLIFY_BRANCH           0x00000200
1371 #define COMPILER_SIMPLIFY_COPY             0x00000400
1372 #define COMPILER_SIMPLIFY_ARITH            0x00000800
1373 #define COMPILER_SIMPLIFY_SHIFT            0x00001000
1374 #define COMPILER_SIMPLIFY_BITWISE          0x00002000
1375 #define COMPILER_SIMPLIFY_LOGICAL          0x00004000
1376 #define COMPILER_SIMPLIFY_BITFIELD         0x00008000
1377
1378 #define COMPILER_CPP_ONLY                  0x80000000
1379
1380 #define COMPILER_DEFAULT_FLAGS ( \
1381         COMPILER_ELIMINATE_INEFECTUAL_CODE | \
1382         COMPILER_INLINE_DEFAULTON | \
1383         COMPILER_SIMPLIFY_OP | \
1384         COMPILER_SIMPLIFY_PHI | \
1385         COMPILER_SIMPLIFY_LABEL | \
1386         COMPILER_SIMPLIFY_BRANCH | \
1387         COMPILER_SIMPLIFY_COPY | \
1388         COMPILER_SIMPLIFY_ARITH | \
1389         COMPILER_SIMPLIFY_SHIFT | \
1390         COMPILER_SIMPLIFY_BITWISE | \
1391         COMPILER_SIMPLIFY_LOGICAL | \
1392         COMPILER_SIMPLIFY_BITFIELD | \
1393         0 )
1394
1395 #define GLOBAL_SCOPE_DEPTH   1
1396 #define FUNCTION_SCOPE_DEPTH (GLOBAL_SCOPE_DEPTH + 1)
1397
1398 static void compile_file(struct compile_state *old_state, const char *filename, int local);
1399
1400
1401
1402 static void init_compiler_state(struct compiler_state *compiler)
1403 {
1404         memset(compiler, 0, sizeof(*compiler));
1405         compiler->label_prefix = "";
1406         compiler->ofilename = "auto.inc";
1407         compiler->flags = COMPILER_DEFAULT_FLAGS;
1408         compiler->debug = 0;
1409         compiler->max_allocation_passes = MAX_ALLOCATION_PASSES;
1410         compiler->include_path_count = 1;
1411         compiler->include_paths      = xcmalloc(sizeof(char *), "include_paths");
1412         compiler->define_count       = 1;
1413         compiler->defines            = xcmalloc(sizeof(char *), "defines");
1414         compiler->undef_count        = 1;
1415         compiler->undefs             = xcmalloc(sizeof(char *), "undefs");
1416 }
1417
1418 struct compiler_flag {
1419         const char *name;
1420         unsigned long flag;
1421 };
1422
1423 struct compiler_arg {
1424         const char *name;
1425         unsigned long mask;
1426         struct compiler_flag flags[16];
1427 };
1428
1429 static int set_flag(
1430         const struct compiler_flag *ptr, unsigned long *flags,
1431         int act, const char *flag)
1432 {
1433         int result = -1;
1434         for(; ptr->name; ptr++) {
1435                 if (strcmp(ptr->name, flag) == 0) {
1436                         break;
1437                 }
1438         }
1439         if (ptr->name) {
1440                 result = 0;
1441                 *flags &= ~(ptr->flag);
1442                 if (act) {
1443                         *flags |= ptr->flag;
1444                 }
1445         }
1446         return result;
1447 }
1448
1449 static int set_arg(
1450         const struct compiler_arg *ptr, unsigned long *flags, const char *arg)
1451 {
1452         const char *val;
1453         int result = -1;
1454         int len;
1455         val = strchr(arg, '=');
1456         if (val) {
1457                 len = val - arg;
1458                 val++;
1459                 for(; ptr->name; ptr++) {
1460                         if (strncmp(ptr->name, arg, len) == 0) {
1461                                 break;
1462                         }
1463                 }
1464                 if (ptr->name) {
1465                         *flags &= ~ptr->mask;
1466                         result = set_flag(&ptr->flags[0], flags, 1, val);
1467                 }
1468         }
1469         return result;
1470 }
1471         
1472
1473 static void flag_usage(FILE *fp, const struct compiler_flag *ptr, 
1474         const char *prefix, const char *invert_prefix)
1475 {
1476         for(;ptr->name; ptr++) {
1477                 fprintf(fp, "%s%s\n", prefix, ptr->name);
1478                 if (invert_prefix) {
1479                         fprintf(fp, "%s%s\n", invert_prefix, ptr->name);
1480                 }
1481         }
1482 }
1483
1484 static void arg_usage(FILE *fp, const struct compiler_arg *ptr,
1485         const char *prefix)
1486 {
1487         for(;ptr->name; ptr++) {
1488                 const struct compiler_flag *flag;
1489                 for(flag = &ptr->flags[0]; flag->name; flag++) {
1490                         fprintf(fp, "%s%s=%s\n", 
1491                                 prefix, ptr->name, flag->name);
1492                 }
1493         }
1494 }
1495
1496 static int append_string(size_t *max, const char ***vec, const char *str,
1497         const char *name)
1498 {
1499         size_t count;
1500         count = ++(*max);
1501         *vec = xrealloc(*vec, sizeof(char *)*count, "name");
1502         (*vec)[count -1] = 0;
1503         (*vec)[count -2] = str; 
1504         return 0;
1505 }
1506
1507 static void arg_error(char *fmt, ...);
1508 static const char *identifier(const char *str, const char *end);
1509
1510 static int append_include_path(struct compiler_state *compiler, const char *str)
1511 {
1512         int result;
1513         if (!exists(str, ".")) {
1514                 arg_error("Nonexistent include path: `%s'\n",
1515                         str);
1516         }
1517         result = append_string(&compiler->include_path_count,
1518                 &compiler->include_paths, str, "include_paths");
1519         return result;
1520 }
1521
1522 static int append_define(struct compiler_state *compiler, const char *str)
1523 {
1524         const char *end, *rest;
1525         int result;
1526
1527         end = strchr(str, '=');
1528         if (!end) {
1529                 end = str + strlen(str);
1530         }
1531         rest = identifier(str, end);
1532         if (rest != end) {
1533                 int len = end - str - 1;
1534                 arg_error("Invalid name cannot define macro: `%*.*s'\n", 
1535                         len, len, str);
1536         }
1537         result = append_string(&compiler->define_count,
1538                 &compiler->defines, str, "defines");
1539         return result;
1540 }
1541
1542 static int append_undef(struct compiler_state *compiler, const char *str)
1543 {
1544         const char *end, *rest;
1545         int result;
1546
1547         end = str + strlen(str);
1548         rest = identifier(str, end);
1549         if (rest != end) {
1550                 int len = end - str - 1;
1551                 arg_error("Invalid name cannot undefine macro: `%*.*s'\n", 
1552                         len, len, str);
1553         }
1554         result = append_string(&compiler->undef_count,
1555                 &compiler->undefs, str, "undefs");
1556         return result;
1557 }
1558
1559 static const struct compiler_flag romcc_flags[] = {
1560         { "cpp-only",                  COMPILER_CPP_ONLY },
1561         { "eliminate-inefectual-code", COMPILER_ELIMINATE_INEFECTUAL_CODE },
1562         { "simplify",                  COMPILER_SIMPLIFY },
1563         { "scc-transform",             COMPILER_SCC_TRANSFORM },
1564         { "simplify-op",               COMPILER_SIMPLIFY_OP },
1565         { "simplify-phi",              COMPILER_SIMPLIFY_PHI },
1566         { "simplify-label",            COMPILER_SIMPLIFY_LABEL },
1567         { "simplify-branch",           COMPILER_SIMPLIFY_BRANCH },
1568         { "simplify-copy",             COMPILER_SIMPLIFY_COPY },
1569         { "simplify-arith",            COMPILER_SIMPLIFY_ARITH },
1570         { "simplify-shift",            COMPILER_SIMPLIFY_SHIFT },
1571         { "simplify-bitwise",          COMPILER_SIMPLIFY_BITWISE },
1572         { "simplify-logical",          COMPILER_SIMPLIFY_LOGICAL },
1573         { "simplify-bitfield",         COMPILER_SIMPLIFY_BITFIELD },
1574         { 0, 0 },
1575 };
1576 static const struct compiler_arg romcc_args[] = {
1577         { "inline-policy",             COMPILER_INLINE_MASK,
1578                 {
1579                         { "always",      COMPILER_INLINE_ALWAYS, },
1580                         { "never",       COMPILER_INLINE_NEVER, },
1581                         { "defaulton",   COMPILER_INLINE_DEFAULTON, },
1582                         { "defaultoff",  COMPILER_INLINE_DEFAULTOFF, },
1583                         { "nopenalty",   COMPILER_INLINE_NOPENALTY, },
1584                         { 0, 0 },
1585                 },
1586         },
1587         { 0, 0 },
1588 };
1589 static const struct compiler_flag romcc_opt_flags[] = {
1590         { "-O",  COMPILER_SIMPLIFY },
1591         { "-O2", COMPILER_SIMPLIFY | COMPILER_SCC_TRANSFORM },
1592         { "-E",  COMPILER_CPP_ONLY },
1593         { 0, 0, },
1594 };
1595 static const struct compiler_flag romcc_debug_flags[] = {
1596         { "all",                   DEBUG_ALL },
1597         { "abort-on-error",        DEBUG_ABORT_ON_ERROR },
1598         { "basic-blocks",          DEBUG_BASIC_BLOCKS },
1599         { "fdominators",           DEBUG_FDOMINATORS },
1600         { "rdominators",           DEBUG_RDOMINATORS },
1601         { "triples",               DEBUG_TRIPLES },
1602         { "interference",          DEBUG_INTERFERENCE },
1603         { "scc-transform",         DEBUG_SCC_TRANSFORM },
1604         { "scc-transform2",        DEBUG_SCC_TRANSFORM2 },
1605         { "rebuild-ssa-form",      DEBUG_REBUILD_SSA_FORM },
1606         { "inline",                DEBUG_INLINE },
1607         { "live-range-conflicts",  DEBUG_RANGE_CONFLICTS },
1608         { "live-range-conflicts2", DEBUG_RANGE_CONFLICTS2 },
1609         { "color-graph",           DEBUG_COLOR_GRAPH },
1610         { "color-graph2",          DEBUG_COLOR_GRAPH2 },
1611         { "coalescing",            DEBUG_COALESCING },
1612         { "coalescing2",           DEBUG_COALESCING2 },
1613         { "verification",          DEBUG_VERIFICATION },
1614         { "calls",                 DEBUG_CALLS },
1615         { "calls2",                DEBUG_CALLS2 },
1616         { "tokens",                DEBUG_TOKENS },
1617         { 0, 0 },
1618 };
1619
1620 static int compiler_encode_flag(
1621         struct compiler_state *compiler, const char *flag)
1622 {
1623         int act;
1624         int result;
1625
1626         act = 1;
1627         result = -1;
1628         if (strncmp(flag, "no-", 3) == 0) {
1629                 flag += 3;
1630                 act = 0;
1631         }
1632         if (strncmp(flag, "-O", 2) == 0) {
1633                 result = set_flag(romcc_opt_flags, &compiler->flags, act, flag);
1634         }
1635         else if (strncmp(flag, "-E", 2) == 0) {
1636                 result = set_flag(romcc_opt_flags, &compiler->flags, act, flag);
1637         }
1638         else if (strncmp(flag, "-I", 2) == 0) {
1639                 result = append_include_path(compiler, flag + 2);
1640         }
1641         else if (strncmp(flag, "-D", 2) == 0) {
1642                 result = append_define(compiler, flag + 2);
1643         }
1644         else if (strncmp(flag, "-U", 2) == 0) {
1645                 result = append_undef(compiler, flag + 2);
1646         }
1647         else if (act && strncmp(flag, "label-prefix=", 13) == 0) {
1648                 result = 0;
1649                 compiler->label_prefix = flag + 13;
1650         }
1651         else if (act && strncmp(flag, "max-allocation-passes=", 22) == 0) {
1652                 unsigned long max_passes;
1653                 char *end;
1654                 max_passes = strtoul(flag + 22, &end, 10);
1655                 if (end[0] == '\0') {
1656                         result = 0;
1657                         compiler->max_allocation_passes = max_passes;
1658                 }
1659         }
1660         else if (act && strcmp(flag, "debug") == 0) {
1661                 result = 0;
1662                 compiler->debug |= DEBUG_DEFAULT;
1663         }
1664         else if (strncmp(flag, "debug-", 6) == 0) {
1665                 flag += 6;
1666                 result = set_flag(romcc_debug_flags, &compiler->debug, act, flag);
1667         }
1668         else {
1669                 result = set_flag(romcc_flags, &compiler->flags, act, flag);
1670                 if (result < 0) {
1671                         result = set_arg(romcc_args, &compiler->flags, flag);
1672                 }
1673         }
1674         return result;
1675 }
1676
1677 static void compiler_usage(FILE *fp)
1678 {
1679         flag_usage(fp, romcc_opt_flags, "", 0);
1680         flag_usage(fp, romcc_flags, "-f", "-fno-");
1681         arg_usage(fp,  romcc_args, "-f");
1682         flag_usage(fp, romcc_debug_flags, "-fdebug-", "-fno-debug-");
1683         fprintf(fp, "-flabel-prefix=<prefix for assembly language labels>\n");
1684         fprintf(fp, "--label-prefix=<prefix for assembly language labels>\n");
1685         fprintf(fp, "-I<include path>\n");
1686         fprintf(fp, "-D<macro>[=defn]\n");
1687         fprintf(fp, "-U<macro>\n");
1688 }
1689
1690 static void do_cleanup(struct compile_state *state)
1691 {
1692         if (state->output) {
1693                 fclose(state->output);
1694                 unlink(state->compiler->ofilename);
1695                 state->output = 0;
1696         }
1697         if (state->dbgout) {
1698                 fflush(state->dbgout);
1699         }
1700         if (state->errout) {
1701                 fflush(state->errout);
1702         }
1703 }
1704
1705 static struct compile_state *exit_state;
1706 static void exit_cleanup(void)
1707 {
1708         if (exit_state) {
1709                 do_cleanup(exit_state);
1710         }
1711 }
1712
1713 static int get_col(struct file_state *file)
1714 {
1715         int col;
1716         const char *ptr, *end;
1717         ptr = file->line_start;
1718         end = file->pos;
1719         for(col = 0; ptr < end; ptr++) {
1720                 if (*ptr != '\t') {
1721                         col++;
1722                 } 
1723                 else {
1724                         col = (col & ~7) + 8;
1725                 }
1726         }
1727         return col;
1728 }
1729
1730 static void loc(FILE *fp, struct compile_state *state, struct triple *triple)
1731 {
1732         int col;
1733         if (triple && triple->occurance) {
1734                 struct occurance *spot;
1735                 for(spot = triple->occurance; spot; spot = spot->parent) {
1736                         fprintf(fp, "%s:%d.%d: ", 
1737                                 spot->filename, spot->line, spot->col);
1738                 }
1739                 return;
1740         }
1741         if (!state->file) {
1742                 return;
1743         }
1744         col = get_col(state->file);
1745         fprintf(fp, "%s:%d.%d: ", 
1746                 state->file->report_name, state->file->report_line, col);
1747 }
1748
1749 static void internal_error(struct compile_state *state, struct triple *ptr, 
1750         const char *fmt, ...)
1751 {
1752         FILE *fp = state->errout;
1753         va_list args;
1754         va_start(args, fmt);
1755         loc(fp, state, ptr);
1756         fputc('\n', fp);
1757         if (ptr) {
1758                 fprintf(fp, "%p %-10s ", ptr, tops(ptr->op));
1759         }
1760         fprintf(fp, "Internal compiler error: ");
1761         vfprintf(fp, fmt, args);
1762         fprintf(fp, "\n");
1763         va_end(args);
1764         do_cleanup(state);
1765         abort();
1766 }
1767
1768
1769 static void internal_warning(struct compile_state *state, struct triple *ptr, 
1770         const char *fmt, ...)
1771 {
1772         FILE *fp = state->errout;
1773         va_list args;
1774         va_start(args, fmt);
1775         loc(fp, state, ptr);
1776         if (ptr) {
1777                 fprintf(fp, "%p %-10s ", ptr, tops(ptr->op));
1778         }
1779         fprintf(fp, "Internal compiler warning: ");
1780         vfprintf(fp, fmt, args);
1781         fprintf(fp, "\n");
1782         va_end(args);
1783 }
1784
1785
1786
1787 static void error(struct compile_state *state, struct triple *ptr, 
1788         const char *fmt, ...)
1789 {
1790         FILE *fp = state->errout;
1791         va_list args;
1792         va_start(args, fmt);
1793         loc(fp, state, ptr);
1794         fputc('\n', fp);
1795         if (ptr && (state->compiler->debug & DEBUG_ABORT_ON_ERROR)) {
1796                 fprintf(fp, "%p %-10s ", ptr, tops(ptr->op));
1797         }
1798         vfprintf(fp, fmt, args);
1799         va_end(args);
1800         fprintf(fp, "\n");
1801         do_cleanup(state);
1802         if (state->compiler->debug & DEBUG_ABORT_ON_ERROR) {
1803                 abort();
1804         }
1805         exit(1);
1806 }
1807
1808 static void warning(struct compile_state *state, struct triple *ptr, 
1809         const char *fmt, ...)
1810 {
1811         FILE *fp = state->errout;
1812         va_list args;
1813         va_start(args, fmt);
1814         loc(fp, state, ptr);
1815         fprintf(fp, "warning: "); 
1816         if (ptr && (state->compiler->debug & DEBUG_ABORT_ON_ERROR)) {
1817                 fprintf(fp, "%p %-10s ", ptr, tops(ptr->op));
1818         }
1819         vfprintf(fp, fmt, args);
1820         fprintf(fp, "\n");
1821         va_end(args);
1822 }
1823
1824 #define FINISHME() warning(state, 0, "FINISHME @ %s.%s:%d", __FILE__, __func__, __LINE__)
1825
1826 static void valid_op(struct compile_state *state, int op)
1827 {
1828         char *fmt = "invalid op: %d";
1829         if (op >= OP_MAX) {
1830                 internal_error(state, 0, fmt, op);
1831         }
1832         if (op < 0) {
1833                 internal_error(state, 0, fmt, op);
1834         }
1835 }
1836
1837 static void valid_ins(struct compile_state *state, struct triple *ptr)
1838 {
1839         valid_op(state, ptr->op);
1840 }
1841
1842 static void valid_param_count(struct compile_state *state, struct triple *ins)
1843 {
1844         int lhs, rhs, misc, targ;
1845         valid_ins(state, ins);
1846         lhs  = table_ops[ins->op].lhs;
1847         rhs  = table_ops[ins->op].rhs;
1848         misc = table_ops[ins->op].misc;
1849         targ = table_ops[ins->op].targ;
1850
1851         if ((lhs >= 0) && (ins->lhs != lhs)) {
1852                 internal_error(state, ins, "Bad lhs count");
1853         }
1854         if ((rhs >= 0) && (ins->rhs != rhs)) {
1855                 internal_error(state, ins, "Bad rhs count");
1856         }
1857         if ((misc >= 0) && (ins->misc != misc)) {
1858                 internal_error(state, ins, "Bad misc count");
1859         }
1860         if ((targ >= 0) && (ins->targ != targ)) {
1861                 internal_error(state, ins, "Bad targ count");
1862         }
1863 }
1864
1865 static void process_trigraphs(struct compile_state *state)
1866 {
1867         char *src, *dest, *end;
1868         struct file_state *file;
1869         file = state->file;
1870         src = dest = file->buf;
1871         end = file->buf + file->size;
1872         while((end - src) >= 3) {
1873                 if ((src[0] == '?') && (src[1] == '?')) {
1874                         int c = -1;
1875                         switch(src[2]) {
1876                         case '=': c = '#'; break;
1877                         case '/': c = '\\'; break;
1878                         case '\'': c = '^'; break;
1879                         case '(': c = '['; break;
1880                         case ')': c = ']'; break;
1881                         case '!': c = '!'; break;
1882                         case '<': c = '{'; break;
1883                         case '>': c = '}'; break;
1884                         case '-': c = '~'; break;
1885                         }
1886                         if (c != -1) {
1887                                 *dest++ = c;
1888                                 src += 3;
1889                         }
1890                         else {
1891                                 *dest++ = *src++;
1892                         }
1893                 }
1894                 else {
1895                         *dest++ = *src++;
1896                 }
1897         }
1898         while(src != end) {
1899                 *dest++ = *src++;
1900         }
1901         file->size = dest - file->buf;
1902 }
1903
1904 static void splice_lines(struct compile_state *state)
1905 {
1906         char *src, *dest, *end;
1907         struct file_state *file;
1908         file = state->file;
1909         src = dest = file->buf;
1910         end = file->buf + file->size;
1911         while((end - src) >= 2) {
1912                 if ((src[0] == '\\') && (src[1] == '\n')) {
1913                         src += 2;
1914                 }
1915                 else {
1916                         *dest++ = *src++;
1917                 }
1918         }
1919         while(src != end) {
1920                 *dest++ = *src++;
1921         }
1922         file->size = dest - file->buf;
1923 }
1924
1925 static struct type void_type;
1926 static struct type unknown_type;
1927 static void use_triple(struct triple *used, struct triple *user)
1928 {
1929         struct triple_set **ptr, *new;
1930         if (!used)
1931                 return;
1932         if (!user)
1933                 return;
1934         ptr = &used->use;
1935         while(*ptr) {
1936                 if ((*ptr)->member == user) {
1937                         return;
1938                 }
1939                 ptr = &(*ptr)->next;
1940         }
1941         /* Append new to the head of the list, 
1942          * copy_func and rename_block_variables
1943          * depends on this.
1944          */
1945         new = xcmalloc(sizeof(*new), "triple_set");
1946         new->member = user;
1947         new->next   = used->use;
1948         used->use   = new;
1949 }
1950
1951 static void unuse_triple(struct triple *used, struct triple *unuser)
1952 {
1953         struct triple_set *use, **ptr;
1954         if (!used) {
1955                 return;
1956         }
1957         ptr = &used->use;
1958         while(*ptr) {
1959                 use = *ptr;
1960                 if (use->member == unuser) {
1961                         *ptr = use->next;
1962                         xfree(use);
1963                 }
1964                 else {
1965                         ptr = &use->next;
1966                 }
1967         }
1968 }
1969
1970 static void put_occurance(struct occurance *occurance)
1971 {
1972         if (occurance) {
1973                 occurance->count -= 1;
1974                 if (occurance->count <= 0) {
1975                         if (occurance->parent) {
1976                                 put_occurance(occurance->parent);
1977                         }
1978                         xfree(occurance);
1979                 }
1980         }
1981 }
1982
1983 static void get_occurance(struct occurance *occurance)
1984 {
1985         if (occurance) {
1986                 occurance->count += 1;
1987         }
1988 }
1989
1990
1991 static struct occurance *new_occurance(struct compile_state *state)
1992 {
1993         struct occurance *result, *last;
1994         const char *filename;
1995         const char *function;
1996         int line, col;
1997
1998         function = "";
1999         filename = 0;
2000         line = 0;
2001         col  = 0;
2002         if (state->file) {
2003                 filename = state->file->report_name;
2004                 line     = state->file->report_line;
2005                 col      = get_col(state->file);
2006         }
2007         if (state->function) {
2008                 function = state->function;
2009         }
2010         last = state->last_occurance;
2011         if (last &&
2012                 (last->col == col) &&
2013                 (last->line == line) &&
2014                 (last->function == function) &&
2015                 ((last->filename == filename) ||
2016                         (strcmp(last->filename, filename) == 0))) 
2017         {
2018                 get_occurance(last);
2019                 return last;
2020         }
2021         if (last) {
2022                 state->last_occurance = 0;
2023                 put_occurance(last);
2024         }
2025         result = xmalloc(sizeof(*result), "occurance");
2026         result->count    = 2;
2027         result->filename = filename;
2028         result->function = function;
2029         result->line     = line;
2030         result->col      = col;
2031         result->parent   = 0;
2032         state->last_occurance = result;
2033         return result;
2034 }
2035
2036 static struct occurance *inline_occurance(struct compile_state *state,
2037         struct occurance *base, struct occurance *top)
2038 {
2039         struct occurance *result, *last;
2040         if (top->parent) {
2041                 internal_error(state, 0, "inlining an already inlined function?");
2042         }
2043         /* If I have a null base treat it that way */
2044         if ((base->parent == 0) &&
2045                 (base->col == 0) &&
2046                 (base->line == 0) &&
2047                 (base->function[0] == '\0') &&
2048                 (base->filename[0] == '\0')) {
2049                 base = 0;
2050         }
2051         /* See if I can reuse the last occurance I had */
2052         last = state->last_occurance;
2053         if (last &&
2054                 (last->parent   == base) &&
2055                 (last->col      == top->col) &&
2056                 (last->line     == top->line) &&
2057                 (last->function == top->function) &&
2058                 (last->filename == top->filename)) {
2059                 get_occurance(last);
2060                 return last;
2061         }
2062         /* I can't reuse the last occurance so free it */
2063         if (last) {
2064                 state->last_occurance = 0;
2065                 put_occurance(last);
2066         }
2067         /* Generate a new occurance structure */
2068         get_occurance(base);
2069         result = xmalloc(sizeof(*result), "occurance");
2070         result->count    = 2;
2071         result->filename = top->filename;
2072         result->function = top->function;
2073         result->line     = top->line;
2074         result->col      = top->col;
2075         result->parent   = base;
2076         state->last_occurance = result;
2077         return result;
2078 }
2079
2080 static struct occurance dummy_occurance = {
2081         .count    = 2,
2082         .filename = __FILE__,
2083         .function = "",
2084         .line     = __LINE__,
2085         .col      = 0,
2086         .parent   = 0,
2087 };
2088
2089 /* The undef triple is used as a place holder when we are removing pointers
2090  * from a triple.  Having allows certain sanity checks to pass even
2091  * when the original triple that was pointed to is gone.
2092  */
2093 static struct triple unknown_triple = {
2094         .next      = &unknown_triple,
2095         .prev      = &unknown_triple,
2096         .use       = 0,
2097         .op        = OP_UNKNOWNVAL,
2098         .lhs       = 0,
2099         .rhs       = 0,
2100         .misc      = 0,
2101         .targ      = 0,
2102         .type      = &unknown_type,
2103         .id        = -1, /* An invalid id */
2104         .u = { .cval = 0, },
2105         .occurance = &dummy_occurance,
2106         .param = { [0] = 0, [1] = 0, },
2107 };
2108
2109
2110 static size_t registers_of(struct compile_state *state, struct type *type);
2111
2112 static struct triple *alloc_triple(struct compile_state *state, 
2113         int op, struct type *type, int lhs_wanted, int rhs_wanted,
2114         struct occurance *occurance)
2115 {
2116         size_t size, extra_count, min_count;
2117         int lhs, rhs, misc, targ;
2118         struct triple *ret, dummy;
2119         dummy.op = op;
2120         dummy.occurance = occurance;
2121         valid_op(state, op);
2122         lhs = table_ops[op].lhs;
2123         rhs = table_ops[op].rhs;
2124         misc = table_ops[op].misc;
2125         targ = table_ops[op].targ;
2126
2127         switch(op) {
2128         case OP_FCALL:
2129                 rhs = rhs_wanted;
2130                 break;
2131         case OP_PHI:
2132                 rhs = rhs_wanted;
2133                 break;
2134         case OP_ADECL:
2135                 lhs = registers_of(state, type);
2136                 break;
2137         case OP_TUPLE:
2138                 lhs = registers_of(state, type);
2139                 break;
2140         case OP_ASM:
2141                 rhs = rhs_wanted;
2142                 lhs = lhs_wanted;
2143                 break;
2144         }
2145         if ((rhs < 0) || (rhs > MAX_RHS)) {
2146                 internal_error(state, &dummy, "bad rhs count %d", rhs);
2147         }
2148         if ((lhs < 0) || (lhs > MAX_LHS)) {
2149                 internal_error(state, &dummy, "bad lhs count %d", lhs);
2150         }
2151         if ((misc < 0) || (misc > MAX_MISC)) {
2152                 internal_error(state, &dummy, "bad misc count %d", misc);
2153         }
2154         if ((targ < 0) || (targ > MAX_TARG)) {
2155                 internal_error(state, &dummy, "bad targs count %d", targ);
2156         }
2157
2158         min_count = sizeof(ret->param)/sizeof(ret->param[0]);
2159         extra_count = lhs + rhs + misc + targ;
2160         extra_count = (extra_count < min_count)? 0 : extra_count - min_count;
2161
2162         size = sizeof(*ret) + sizeof(ret->param[0]) * extra_count;
2163         ret = xcmalloc(size, "tripple");
2164         ret->op        = op;
2165         ret->lhs       = lhs;
2166         ret->rhs       = rhs;
2167         ret->misc      = misc;
2168         ret->targ      = targ;
2169         ret->type      = type;
2170         ret->next      = ret;
2171         ret->prev      = ret;
2172         ret->occurance = occurance;
2173         /* A simple sanity check */
2174         if ((ret->op != op) ||
2175                 (ret->lhs != lhs) ||
2176                 (ret->rhs != rhs) ||
2177                 (ret->misc != misc) ||
2178                 (ret->targ != targ) ||
2179                 (ret->type != type) ||
2180                 (ret->next != ret) ||
2181                 (ret->prev != ret) ||
2182                 (ret->occurance != occurance)) {
2183                 internal_error(state, ret, "huh?");
2184         }
2185         return ret;
2186 }
2187
2188 struct triple *dup_triple(struct compile_state *state, struct triple *src)
2189 {
2190         struct triple *dup;
2191         int src_lhs, src_rhs, src_size;
2192         src_lhs = src->lhs;
2193         src_rhs = src->rhs;
2194         src_size = TRIPLE_SIZE(src);
2195         get_occurance(src->occurance);
2196         dup = alloc_triple(state, src->op, src->type, src_lhs, src_rhs,
2197                 src->occurance);
2198         memcpy(dup, src, sizeof(*src));
2199         memcpy(dup->param, src->param, src_size * sizeof(src->param[0]));
2200         return dup;
2201 }
2202
2203 static struct triple *copy_triple(struct compile_state *state, struct triple *src)
2204 {
2205         struct triple *copy;
2206         copy = dup_triple(state, src);
2207         copy->use = 0;
2208         copy->next = copy->prev = copy;
2209         return copy;
2210 }
2211
2212 static struct triple *new_triple(struct compile_state *state, 
2213         int op, struct type *type, int lhs, int rhs)
2214 {
2215         struct triple *ret;
2216         struct occurance *occurance;
2217         occurance = new_occurance(state);
2218         ret = alloc_triple(state, op, type, lhs, rhs, occurance);
2219         return ret;
2220 }
2221
2222 static struct triple *build_triple(struct compile_state *state, 
2223         int op, struct type *type, struct triple *left, struct triple *right,
2224         struct occurance *occurance)
2225 {
2226         struct triple *ret;
2227         size_t count;
2228         ret = alloc_triple(state, op, type, -1, -1, occurance);
2229         count = TRIPLE_SIZE(ret);
2230         if (count > 0) {
2231                 ret->param[0] = left;
2232         }
2233         if (count > 1) {
2234                 ret->param[1] = right;
2235         }
2236         return ret;
2237 }
2238
2239 static struct triple *triple(struct compile_state *state, 
2240         int op, struct type *type, struct triple *left, struct triple *right)
2241 {
2242         struct triple *ret;
2243         size_t count;
2244         ret = new_triple(state, op, type, -1, -1);
2245         count = TRIPLE_SIZE(ret);
2246         if (count >= 1) {
2247                 ret->param[0] = left;
2248         }
2249         if (count >= 2) {
2250                 ret->param[1] = right;
2251         }
2252         return ret;
2253 }
2254
2255 static struct triple *branch(struct compile_state *state, 
2256         struct triple *targ, struct triple *test)
2257 {
2258         struct triple *ret;
2259         if (test) {
2260                 ret = new_triple(state, OP_CBRANCH, &void_type, -1, 1);
2261                 RHS(ret, 0) = test;
2262         } else {
2263                 ret = new_triple(state, OP_BRANCH, &void_type, -1, 0);
2264         }
2265         TARG(ret, 0) = targ;
2266         /* record the branch target was used */
2267         if (!targ || (targ->op != OP_LABEL)) {
2268                 internal_error(state, 0, "branch not to label");
2269         }
2270         return ret;
2271 }
2272
2273 static int triple_is_label(struct compile_state *state, struct triple *ins);
2274 static int triple_is_call(struct compile_state *state, struct triple *ins);
2275 static int triple_is_cbranch(struct compile_state *state, struct triple *ins);
2276 static void insert_triple(struct compile_state *state,
2277         struct triple *first, struct triple *ptr)
2278 {
2279         if (ptr) {
2280                 if ((ptr->id & TRIPLE_FLAG_FLATTENED) || (ptr->next != ptr)) {
2281                         internal_error(state, ptr, "expression already used");
2282                 }
2283                 ptr->next       = first;
2284                 ptr->prev       = first->prev;
2285                 ptr->prev->next = ptr;
2286                 ptr->next->prev = ptr;
2287
2288                 if (triple_is_cbranch(state, ptr->prev) ||
2289                         triple_is_call(state, ptr->prev)) {
2290                         unuse_triple(first, ptr->prev);
2291                         use_triple(ptr, ptr->prev);
2292                 }
2293         }
2294 }
2295
2296 static int triple_stores_block(struct compile_state *state, struct triple *ins)
2297 {
2298         /* This function is used to determine if u.block 
2299          * is utilized to store the current block number.
2300          */
2301         int stores_block;
2302         valid_ins(state, ins);
2303         stores_block = (table_ops[ins->op].flags & BLOCK) == BLOCK;
2304         return stores_block;
2305 }
2306
2307 static int triple_is_branch(struct compile_state *state, struct triple *ins);
2308 static struct block *block_of_triple(struct compile_state *state, 
2309         struct triple *ins)
2310 {
2311         struct triple *first;
2312         if (!ins || ins == &unknown_triple) {
2313                 return 0;
2314         }
2315         first = state->first;
2316         while(ins != first && !triple_is_branch(state, ins->prev) &&
2317                 !triple_stores_block(state, ins)) 
2318         { 
2319                 if (ins == ins->prev) {
2320                         internal_error(state, ins, "ins == ins->prev?");
2321                 }
2322                 ins = ins->prev;
2323         }
2324         return triple_stores_block(state, ins)? ins->u.block: 0;
2325 }
2326
2327 static void generate_lhs_pieces(struct compile_state *state, struct triple *ins);
2328 static struct triple *pre_triple(struct compile_state *state,
2329         struct triple *base,
2330         int op, struct type *type, struct triple *left, struct triple *right)
2331 {
2332         struct block *block;
2333         struct triple *ret;
2334         int i;
2335         /* If I am an OP_PIECE jump to the real instruction */
2336         if (base->op == OP_PIECE) {
2337                 base = MISC(base, 0);
2338         }
2339         block = block_of_triple(state, base);
2340         get_occurance(base->occurance);
2341         ret = build_triple(state, op, type, left, right, base->occurance);
2342         generate_lhs_pieces(state, ret);
2343         if (triple_stores_block(state, ret)) {
2344                 ret->u.block = block;
2345         }
2346         insert_triple(state, base, ret);
2347         for(i = 0; i < ret->lhs; i++) {
2348                 struct triple *piece;
2349                 piece = LHS(ret, i);
2350                 insert_triple(state, base, piece);
2351                 use_triple(ret, piece);
2352                 use_triple(piece, ret);
2353         }
2354         if (block && (block->first == base)) {
2355                 block->first = ret;
2356         }
2357         return ret;
2358 }
2359
2360 static struct triple *post_triple(struct compile_state *state,
2361         struct triple *base,
2362         int op, struct type *type, struct triple *left, struct triple *right)
2363 {
2364         struct block *block;
2365         struct triple *ret, *next;
2366         int zlhs, i;
2367         /* If I am an OP_PIECE jump to the real instruction */
2368         if (base->op == OP_PIECE) {
2369                 base = MISC(base, 0);
2370         }
2371         /* If I have a left hand side skip over it */
2372         zlhs = base->lhs;
2373         if (zlhs) {
2374                 base = LHS(base, zlhs - 1);
2375         }
2376
2377         block = block_of_triple(state, base);
2378         get_occurance(base->occurance);
2379         ret = build_triple(state, op, type, left, right, base->occurance);
2380         generate_lhs_pieces(state, ret);
2381         if (triple_stores_block(state, ret)) {
2382                 ret->u.block = block;
2383         }
2384         next = base->next;
2385         insert_triple(state, next, ret);
2386         zlhs = ret->lhs;
2387         for(i = 0; i < zlhs; i++) {
2388                 struct triple *piece;
2389                 piece = LHS(ret, i);
2390                 insert_triple(state, next, piece);
2391                 use_triple(ret, piece);
2392                 use_triple(piece, ret);
2393         }
2394         if (block && (block->last == base)) {
2395                 block->last = ret;
2396                 if (zlhs) {
2397                         block->last = LHS(ret, zlhs - 1);
2398                 }
2399         }
2400         return ret;
2401 }
2402
2403 static struct type *reg_type(
2404         struct compile_state *state, struct type *type, int reg);
2405
2406 static void generate_lhs_piece(
2407         struct compile_state *state, struct triple *ins, int index)
2408 {
2409         struct type *piece_type;
2410         struct triple *piece;
2411         get_occurance(ins->occurance);
2412         piece_type = reg_type(state, ins->type, index * REG_SIZEOF_REG);
2413
2414         if ((piece_type->type & TYPE_MASK) == TYPE_BITFIELD) {
2415                 piece_type = piece_type->left;
2416         }
2417 #if 0
2418 {
2419         static void name_of(FILE *fp, struct type *type);
2420         FILE * fp = state->errout;
2421         fprintf(fp, "piece_type(%d): ", index);
2422         name_of(fp, piece_type);
2423         fprintf(fp, "\n");
2424 }
2425 #endif
2426         piece = alloc_triple(state, OP_PIECE, piece_type, -1, -1, ins->occurance);
2427         piece->u.cval  = index;
2428         LHS(ins, piece->u.cval) = piece;
2429         MISC(piece, 0) = ins;
2430 }
2431
2432 static void generate_lhs_pieces(struct compile_state *state, struct triple *ins)
2433 {
2434         int i, zlhs;
2435         zlhs = ins->lhs;
2436         for(i = 0; i < zlhs; i++) {
2437                 generate_lhs_piece(state, ins, i);
2438         }
2439 }
2440
2441 static struct triple *label(struct compile_state *state)
2442 {
2443         /* Labels don't get a type */
2444         struct triple *result;
2445         result = triple(state, OP_LABEL, &void_type, 0, 0);
2446         return result;
2447 }
2448
2449 static struct triple *mkprog(struct compile_state *state, ...)
2450 {
2451         struct triple *prog, *head, *arg;
2452         va_list args;
2453         int i;
2454
2455         head = label(state);
2456         prog = new_triple(state, OP_PROG, &void_type, -1, -1);
2457         RHS(prog, 0) = head;
2458         va_start(args, state);
2459         i = 0;
2460         while((arg = va_arg(args, struct triple *)) != 0) {
2461                 if (++i >= 100) {
2462                         internal_error(state, 0, "too many arguments to mkprog");
2463                 }
2464                 flatten(state, head, arg);
2465         }
2466         va_end(args);
2467         prog->type = head->prev->type;
2468         return prog;
2469 }
2470 static void name_of(FILE *fp, struct type *type);
2471 static void display_triple(FILE *fp, struct triple *ins)
2472 {
2473         struct occurance *ptr;
2474         const char *reg;
2475         char pre, post, vol;
2476         pre = post = vol = ' ';
2477         if (ins) {
2478                 if (ins->id & TRIPLE_FLAG_PRE_SPLIT) {
2479                         pre = '^';
2480                 }
2481                 if (ins->id & TRIPLE_FLAG_POST_SPLIT) {
2482                         post = ',';
2483                 }
2484                 if (ins->id & TRIPLE_FLAG_VOLATILE) {
2485                         vol = 'v';
2486                 }
2487                 reg = arch_reg_str(ID_REG(ins->id));
2488         }
2489         if (ins == 0) {
2490                 fprintf(fp, "(%p) <nothing> ", ins);
2491         }
2492         else if (ins->op == OP_INTCONST) {
2493                 fprintf(fp, "(%p) %c%c%c %-7s %-2d %-10s <0x%08lx>         ",
2494                         ins, pre, post, vol, reg, ins->template_id, tops(ins->op), 
2495                         (unsigned long)(ins->u.cval));
2496         }
2497         else if (ins->op == OP_ADDRCONST) {
2498                 fprintf(fp, "(%p) %c%c%c %-7s %-2d %-10s %-10p <0x%08lx>",
2499                         ins, pre, post, vol, reg, ins->template_id, tops(ins->op), 
2500                         MISC(ins, 0), (unsigned long)(ins->u.cval));
2501         }
2502         else if (ins->op == OP_INDEX) {
2503                 fprintf(fp, "(%p) %c%c%c %-7s %-2d %-10s %-10p <0x%08lx>",
2504                         ins, pre, post, vol, reg, ins->template_id, tops(ins->op), 
2505                         RHS(ins, 0), (unsigned long)(ins->u.cval));
2506         }
2507         else if (ins->op == OP_PIECE) {
2508                 fprintf(fp, "(%p) %c%c%c %-7s %-2d %-10s %-10p <0x%08lx>",
2509                         ins, pre, post, vol, reg, ins->template_id, tops(ins->op), 
2510                         MISC(ins, 0), (unsigned long)(ins->u.cval));
2511         }
2512         else {
2513                 int i, count;
2514                 fprintf(fp, "(%p) %c%c%c %-7s %-2d %-10s", 
2515                         ins, pre, post, vol, reg, ins->template_id, tops(ins->op));
2516                 if (table_ops[ins->op].flags & BITFIELD) {
2517                         fprintf(fp, " <%2d-%2d:%2d>", 
2518                                 ins->u.bitfield.offset,
2519                                 ins->u.bitfield.offset + ins->u.bitfield.size,
2520                                 ins->u.bitfield.size);
2521                 }
2522                 count = TRIPLE_SIZE(ins);
2523                 for(i = 0; i < count; i++) {
2524                         fprintf(fp, " %-10p", ins->param[i]);
2525                 }
2526                 for(; i < 2; i++) {
2527                         fprintf(fp, "           ");
2528                 }
2529         }
2530         if (ins) {
2531                 struct triple_set *user;
2532 #if DEBUG_DISPLAY_TYPES
2533                 fprintf(fp, " <");
2534                 name_of(fp, ins->type);
2535                 fprintf(fp, "> ");
2536 #endif
2537 #if DEBUG_DISPLAY_USES
2538                 fprintf(fp, " [");
2539                 for(user = ins->use; user; user = user->next) {
2540                         fprintf(fp, " %-10p", user->member);
2541                 }
2542                 fprintf(fp, " ]");
2543 #endif
2544                 fprintf(fp, " @");
2545                 for(ptr = ins->occurance; ptr; ptr = ptr->parent) {
2546                         fprintf(fp, " %s,%s:%d.%d",
2547                                 ptr->function, 
2548                                 ptr->filename,
2549                                 ptr->line, 
2550                                 ptr->col);
2551                 }
2552                 if (ins->op == OP_ASM) {
2553                         fprintf(fp, "\n\t%s", ins->u.ainfo->str);
2554                 }
2555         }
2556         fprintf(fp, "\n");
2557         fflush(fp);
2558 }
2559
2560 static int equiv_types(struct type *left, struct type *right);
2561 static void display_triple_changes(
2562         FILE *fp, const struct triple *new, const struct triple *orig)
2563 {
2564
2565         int new_count, orig_count;
2566         new_count = TRIPLE_SIZE(new);
2567         orig_count = TRIPLE_SIZE(orig);
2568         if ((new->op != orig->op) ||
2569                 (new_count != orig_count) ||
2570                 (memcmp(orig->param, new->param,        
2571                         orig_count * sizeof(orig->param[0])) != 0) ||
2572                 (memcmp(&orig->u, &new->u, sizeof(orig->u)) != 0)) 
2573         {
2574                 struct occurance *ptr;
2575                 int i, min_count, indent;
2576                 fprintf(fp, "(%p %p)", new, orig);
2577                 if (orig->op == new->op) {
2578                         fprintf(fp, " %-11s", tops(orig->op));
2579                 } else {
2580                         fprintf(fp, " [%-10s %-10s]", 
2581                                 tops(new->op), tops(orig->op));
2582                 }
2583                 min_count = new_count;
2584                 if (min_count > orig_count) {
2585                         min_count = orig_count;
2586                 }
2587                 for(indent = i = 0; i < min_count; i++) {
2588                         if (orig->param[i] == new->param[i]) {
2589                                 fprintf(fp, " %-11p", 
2590                                         orig->param[i]);
2591                                 indent += 12;
2592                         } else {
2593                                 fprintf(fp, " [%-10p %-10p]",
2594                                         new->param[i], 
2595                                         orig->param[i]);
2596                                 indent += 24;
2597                         }
2598                 }
2599                 for(; i < orig_count; i++) {
2600                         fprintf(fp, " [%-9p]", orig->param[i]);
2601                         indent += 12;
2602                 }
2603                 for(; i < new_count; i++) {
2604                         fprintf(fp, " [%-9p]", new->param[i]);
2605                         indent += 12;
2606                 }
2607                 if ((new->op == OP_INTCONST)||
2608                         (new->op == OP_ADDRCONST)) {
2609                         fprintf(fp, " <0x%08lx>", 
2610                                 (unsigned long)(new->u.cval));
2611                         indent += 13;
2612                 }
2613                 for(;indent < 36; indent++) {
2614                         putc(' ', fp);
2615                 }
2616
2617 #if DEBUG_DISPLAY_TYPES
2618                 fprintf(fp, " <");
2619                 name_of(fp, new->type);
2620                 if (!equiv_types(new->type, orig->type)) {
2621                         fprintf(fp, " -- ");
2622                         name_of(fp, orig->type);
2623                 }
2624                 fprintf(fp, "> ");
2625 #endif
2626
2627                 fprintf(fp, " @");
2628                 for(ptr = orig->occurance; ptr; ptr = ptr->parent) {
2629                         fprintf(fp, " %s,%s:%d.%d",
2630                                 ptr->function, 
2631                                 ptr->filename,
2632                                 ptr->line, 
2633                                 ptr->col);
2634                         
2635                 }
2636                 fprintf(fp, "\n");
2637                 fflush(fp);
2638         }
2639 }
2640
2641 static int triple_is_pure(struct compile_state *state, struct triple *ins, unsigned id)
2642 {
2643         /* Does the triple have no side effects.
2644          * I.e. Rexecuting the triple with the same arguments 
2645          * gives the same value.
2646          */
2647         unsigned pure;
2648         valid_ins(state, ins);
2649         pure = PURE_BITS(table_ops[ins->op].flags);
2650         if ((pure != PURE) && (pure != IMPURE)) {
2651                 internal_error(state, 0, "Purity of %s not known",
2652                         tops(ins->op));
2653         }
2654         return (pure == PURE) && !(id & TRIPLE_FLAG_VOLATILE);
2655 }
2656
2657 static int triple_is_branch_type(struct compile_state *state, 
2658         struct triple *ins, unsigned type)
2659 {
2660         /* Is this one of the passed branch types? */
2661         valid_ins(state, ins);
2662         return (BRANCH_BITS(table_ops[ins->op].flags) == type);
2663 }
2664
2665 static int triple_is_branch(struct compile_state *state, struct triple *ins)
2666 {
2667         /* Is this triple a branch instruction? */
2668         valid_ins(state, ins);
2669         return (BRANCH_BITS(table_ops[ins->op].flags) != 0);
2670 }
2671
2672 static int triple_is_cbranch(struct compile_state *state, struct triple *ins)
2673 {
2674         /* Is this triple a conditional branch instruction? */
2675         return triple_is_branch_type(state, ins, CBRANCH);
2676 }
2677
2678 static int triple_is_ubranch(struct compile_state *state, struct triple *ins)
2679 {
2680         /* Is this triple a unconditional branch instruction? */
2681         unsigned type;
2682         valid_ins(state, ins);
2683         type = BRANCH_BITS(table_ops[ins->op].flags);
2684         return (type != 0) && (type != CBRANCH);
2685 }
2686
2687 static int triple_is_call(struct compile_state *state, struct triple *ins)
2688 {
2689         /* Is this triple a call instruction? */
2690         return triple_is_branch_type(state, ins, CALLBRANCH);
2691 }
2692
2693 static int triple_is_ret(struct compile_state *state, struct triple *ins)
2694 {
2695         /* Is this triple a return instruction? */
2696         return triple_is_branch_type(state, ins, RETBRANCH);
2697 }
2698
2699 static int triple_is_simple_ubranch(struct compile_state *state, struct triple *ins)
2700 {
2701         /* Is this triple an unconditional branch and not a call or a
2702          * return? */
2703         return triple_is_branch_type(state, ins, UBRANCH);
2704 }
2705
2706 static int triple_is_end(struct compile_state *state, struct triple *ins)
2707 {
2708         return triple_is_branch_type(state, ins, ENDBRANCH);
2709 }
2710
2711 static int triple_is_label(struct compile_state *state, struct triple *ins)
2712 {
2713         valid_ins(state, ins);
2714         return (ins->op == OP_LABEL);
2715 }
2716
2717 static struct triple *triple_to_block_start(
2718         struct compile_state *state, struct triple *start)
2719 {
2720         while(!triple_is_branch(state, start->prev) &&
2721                 (!triple_is_label(state, start) || !start->use)) {
2722                 start = start->prev;
2723         }
2724         return start;
2725 }
2726
2727 static int triple_is_def(struct compile_state *state, struct triple *ins)
2728 {
2729         /* This function is used to determine which triples need
2730          * a register.
2731          */
2732         int is_def;
2733         valid_ins(state, ins);
2734         is_def = (table_ops[ins->op].flags & DEF) == DEF;
2735         if (ins->lhs >= 1) {
2736                 is_def = 0;
2737         }
2738         return is_def;
2739 }
2740
2741 static int triple_is_structural(struct compile_state *state, struct triple *ins)
2742 {
2743         int is_structural;
2744         valid_ins(state, ins);
2745         is_structural = (table_ops[ins->op].flags & STRUCTURAL) == STRUCTURAL;
2746         return is_structural;
2747 }
2748
2749 static int triple_is_part(struct compile_state *state, struct triple *ins)
2750 {
2751         int is_part;
2752         valid_ins(state, ins);
2753         is_part = (table_ops[ins->op].flags & PART) == PART;
2754         return is_part;
2755 }
2756
2757 static int triple_is_auto_var(struct compile_state *state, struct triple *ins)
2758 {
2759         return (ins->op == OP_PIECE) && (MISC(ins, 0)->op == OP_ADECL);
2760 }
2761
2762 static struct triple **triple_iter(struct compile_state *state,
2763         size_t count, struct triple **vector,
2764         struct triple *ins, struct triple **last)
2765 {
2766         struct triple **ret;
2767         ret = 0;
2768         if (count) {
2769                 if (!last) {
2770                         ret = vector;
2771                 }
2772                 else if ((last >= vector) && (last < (vector + count - 1))) {
2773                         ret = last + 1;
2774                 }
2775         }
2776         return ret;
2777         
2778 }
2779
2780 static struct triple **triple_lhs(struct compile_state *state,
2781         struct triple *ins, struct triple **last)
2782 {
2783         return triple_iter(state, ins->lhs, &LHS(ins,0), 
2784                 ins, last);
2785 }
2786
2787 static struct triple **triple_rhs(struct compile_state *state,
2788         struct triple *ins, struct triple **last)
2789 {
2790         return triple_iter(state, ins->rhs, &RHS(ins,0), 
2791                 ins, last);
2792 }
2793
2794 static struct triple **triple_misc(struct compile_state *state,
2795         struct triple *ins, struct triple **last)
2796 {
2797         return triple_iter(state, ins->misc, &MISC(ins,0), 
2798                 ins, last);
2799 }
2800
2801 static struct triple **do_triple_targ(struct compile_state *state,
2802         struct triple *ins, struct triple **last, int call_edges, int next_edges)
2803 {
2804         size_t count;
2805         struct triple **ret, **vector;
2806         int next_is_targ;
2807         ret = 0;
2808         count = ins->targ;
2809         next_is_targ = 0;
2810         if (triple_is_cbranch(state, ins)) {
2811                 next_is_targ = 1;
2812         }
2813         if (!call_edges && triple_is_call(state, ins)) {
2814                 count = 0;
2815         }
2816         if (next_edges && triple_is_call(state, ins)) {
2817                 next_is_targ = 1;
2818         }
2819         vector = &TARG(ins, 0);
2820         if (!ret && next_is_targ) {
2821                 if (!last) {
2822                         ret = &ins->next;
2823                 } else if (last == &ins->next) {
2824                         last = 0;
2825                 }
2826         }
2827         if (!ret && count) {
2828                 if (!last) {
2829                         ret = vector;
2830                 }
2831                 else if ((last >= vector) && (last < (vector + count - 1))) {
2832                         ret = last + 1;
2833                 }
2834                 else if (last == vector + count - 1) {
2835                         last = 0;
2836                 }
2837         }
2838         if (!ret && triple_is_ret(state, ins) && call_edges) {
2839                 struct triple_set *use;
2840                 for(use = ins->use; use; use = use->next) {
2841                         if (!triple_is_call(state, use->member)) {
2842                                 continue;
2843                         }
2844                         if (!last) {
2845                                 ret = &use->member->next;
2846                                 break;
2847                         }
2848                         else if (last == &use->member->next) {
2849                                 last = 0;
2850                         }
2851                 }
2852         }
2853         return ret;
2854 }
2855
2856 static struct triple **triple_targ(struct compile_state *state,
2857         struct triple *ins, struct triple **last)
2858 {
2859         return do_triple_targ(state, ins, last, 1, 1);
2860 }
2861
2862 static struct triple **triple_edge_targ(struct compile_state *state,
2863         struct triple *ins, struct triple **last)
2864 {
2865         return do_triple_targ(state, ins, last, 
2866                 state->functions_joined, !state->functions_joined);
2867 }
2868
2869 static struct triple *after_lhs(struct compile_state *state, struct triple *ins)
2870 {
2871         struct triple *next;
2872         int lhs, i;
2873         lhs = ins->lhs;
2874         next = ins->next;
2875         for(i = 0; i < lhs; i++) {
2876                 struct triple *piece;
2877                 piece = LHS(ins, i);
2878                 if (next != piece) {
2879                         internal_error(state, ins, "malformed lhs on %s",
2880                                 tops(ins->op));
2881                 }
2882                 if (next->op != OP_PIECE) {
2883                         internal_error(state, ins, "bad lhs op %s at %d on %s",
2884                                 tops(next->op), i, tops(ins->op));
2885                 }
2886                 if (next->u.cval != i) {
2887                         internal_error(state, ins, "bad u.cval of %d %d expected",
2888                                 next->u.cval, i);
2889                 }
2890                 next = next->next;
2891         }
2892         return next;
2893 }
2894
2895 /* Function piece accessor functions */
2896 static struct triple *do_farg(struct compile_state *state, 
2897         struct triple *func, unsigned index)
2898 {
2899         struct type *ftype;
2900         struct triple *first, *arg;
2901         unsigned i;
2902
2903         ftype = func->type;
2904         if((index < 0) || (index >= (ftype->elements + 2))) {
2905                 internal_error(state, func, "bad argument index: %d", index);
2906         }
2907         first = RHS(func, 0);
2908         arg = first->next;
2909         for(i = 0; i < index; i++, arg = after_lhs(state, arg)) {
2910                 /* do nothing */
2911         }
2912         if (arg->op != OP_ADECL) {
2913                 internal_error(state, 0, "arg not adecl?");
2914         }
2915         return arg;
2916 }
2917 static struct triple *fresult(struct compile_state *state, struct triple *func)
2918 {
2919         return do_farg(state, func, 0);
2920 }
2921 static struct triple *fretaddr(struct compile_state *state, struct triple *func)
2922 {
2923         return do_farg(state, func, 1);
2924 }
2925 static struct triple *farg(struct compile_state *state, 
2926         struct triple *func, unsigned index)
2927 {
2928         return do_farg(state, func, index + 2);
2929 }
2930
2931
2932 static void display_func(struct compile_state *state, FILE *fp, struct triple *func)
2933 {
2934         struct triple *first, *ins;
2935         fprintf(fp, "display_func %s\n", func->type->type_ident->name);
2936         first = ins = RHS(func, 0);
2937         do {
2938                 if (triple_is_label(state, ins) && ins->use) {
2939                         fprintf(fp, "%p:\n", ins);
2940                 }
2941                 display_triple(fp, ins);
2942
2943                 if (triple_is_branch(state, ins)) {
2944                         fprintf(fp, "\n");
2945                 }
2946                 if (ins->next->prev != ins) {
2947                         internal_error(state, ins->next, "bad prev");
2948                 }
2949                 ins = ins->next;
2950         } while(ins != first);
2951 }
2952
2953 static void verify_use(struct compile_state *state,
2954         struct triple *user, struct triple *used)
2955 {
2956         int size, i;
2957         size = TRIPLE_SIZE(user);
2958         for(i = 0; i < size; i++) {
2959                 if (user->param[i] == used) {
2960                         break;
2961                 }
2962         }
2963         if (triple_is_branch(state, user)) {
2964                 if (user->next == used) {
2965                         i = -1;
2966                 }
2967         }
2968         if (i == size) {
2969                 internal_error(state, user, "%s(%p) does not use %s(%p)",
2970                         tops(user->op), user, tops(used->op), used);
2971         }
2972 }
2973
2974 static int find_rhs_use(struct compile_state *state, 
2975         struct triple *user, struct triple *used)
2976 {
2977         struct triple **param;
2978         int size, i;
2979         verify_use(state, user, used);
2980 #warning "AUDIT ME ->rhs"
2981         size = user->rhs;
2982         param = &RHS(user, 0);
2983         for(i = 0; i < size; i++) {
2984                 if (param[i] == used) {
2985                         return i;
2986                 }
2987         }
2988         return -1;
2989 }
2990
2991 static void free_triple(struct compile_state *state, struct triple *ptr)
2992 {
2993         size_t size;
2994         size = sizeof(*ptr) - sizeof(ptr->param) +
2995                 (sizeof(ptr->param[0])*TRIPLE_SIZE(ptr));
2996         ptr->prev->next = ptr->next;
2997         ptr->next->prev = ptr->prev;
2998         if (ptr->use) {
2999                 internal_error(state, ptr, "ptr->use != 0");
3000         }
3001         put_occurance(ptr->occurance);
3002         memset(ptr, -1, size);
3003         xfree(ptr);
3004 }
3005
3006 static void release_triple(struct compile_state *state, struct triple *ptr)
3007 {
3008         struct triple_set *set, *next;
3009         struct triple **expr;
3010         struct block *block;
3011         if (ptr == &unknown_triple) {
3012                 return;
3013         }
3014         valid_ins(state, ptr);
3015         /* Make certain the we are not the first or last element of a block */
3016         block = block_of_triple(state, ptr);
3017         if (block) {
3018                 if ((block->last == ptr) && (block->first == ptr)) {
3019                         block->last = block->first = 0;
3020                 }
3021                 else if (block->last == ptr) {
3022                         block->last = ptr->prev;
3023                 }
3024                 else if (block->first == ptr) {
3025                         block->first = ptr->next;
3026                 }
3027         }
3028         /* Remove ptr from use chains where it is the user */
3029         expr = triple_rhs(state, ptr, 0);
3030         for(; expr; expr = triple_rhs(state, ptr, expr)) {
3031                 if (*expr) {
3032                         unuse_triple(*expr, ptr);
3033                 }
3034         }
3035         expr = triple_lhs(state, ptr, 0);
3036         for(; expr; expr = triple_lhs(state, ptr, expr)) {
3037                 if (*expr) {
3038                         unuse_triple(*expr, ptr);
3039                 }
3040         }
3041         expr = triple_misc(state, ptr, 0);
3042         for(; expr; expr = triple_misc(state, ptr, expr)) {
3043                 if (*expr) {
3044                         unuse_triple(*expr, ptr);
3045                 }
3046         }
3047         expr = triple_targ(state, ptr, 0);
3048         for(; expr; expr = triple_targ(state, ptr, expr)) {
3049                 if (*expr){
3050                         unuse_triple(*expr, ptr);
3051                 }
3052         }
3053         /* Reomve ptr from use chains where it is used */
3054         for(set = ptr->use; set; set = next) {
3055                 next = set->next;
3056                 valid_ins(state, set->member);
3057                 expr = triple_rhs(state, set->member, 0);
3058                 for(; expr; expr = triple_rhs(state, set->member, expr)) {
3059                         if (*expr == ptr) {
3060                                 *expr = &unknown_triple;
3061                         }
3062                 }
3063                 expr = triple_lhs(state, set->member, 0);
3064                 for(; expr; expr = triple_lhs(state, set->member, expr)) {
3065                         if (*expr == ptr) {
3066                                 *expr = &unknown_triple;
3067                         }
3068                 }
3069                 expr = triple_misc(state, set->member, 0);
3070                 for(; expr; expr = triple_misc(state, set->member, expr)) {
3071                         if (*expr == ptr) {
3072                                 *expr = &unknown_triple;
3073                         }
3074                 }
3075                 expr = triple_targ(state, set->member, 0);
3076                 for(; expr; expr = triple_targ(state, set->member, expr)) {
3077                         if (*expr == ptr) {
3078                                 *expr = &unknown_triple;
3079                         }
3080                 }
3081                 unuse_triple(ptr, set->member);
3082         }
3083         free_triple(state, ptr);
3084 }
3085
3086 static void print_triples(struct compile_state *state);
3087 static void print_blocks(struct compile_state *state, const char *func, FILE *fp);
3088
3089 #define TOK_UNKNOWN     0
3090 #define TOK_SPACE       1
3091 #define TOK_SEMI        2
3092 #define TOK_LBRACE      3
3093 #define TOK_RBRACE      4
3094 #define TOK_COMMA       5
3095 #define TOK_EQ          6
3096 #define TOK_COLON       7
3097 #define TOK_LBRACKET    8
3098 #define TOK_RBRACKET    9
3099 #define TOK_LPAREN      10
3100 #define TOK_RPAREN      11
3101 #define TOK_STAR        12
3102 #define TOK_DOTS        13
3103 #define TOK_MORE        14
3104 #define TOK_LESS        15
3105 #define TOK_TIMESEQ     16
3106 #define TOK_DIVEQ       17
3107 #define TOK_MODEQ       18
3108 #define TOK_PLUSEQ      19
3109 #define TOK_MINUSEQ     20
3110 #define TOK_SLEQ        21
3111 #define TOK_SREQ        22
3112 #define TOK_ANDEQ       23
3113 #define TOK_XOREQ       24
3114 #define TOK_OREQ        25
3115 #define TOK_EQEQ        26
3116 #define TOK_NOTEQ       27
3117 #define TOK_QUEST       28
3118 #define TOK_LOGOR       29
3119 #define TOK_LOGAND      30
3120 #define TOK_OR          31
3121 #define TOK_AND         32
3122 #define TOK_XOR         33
3123 #define TOK_LESSEQ      34
3124 #define TOK_MOREEQ      35
3125 #define TOK_SL          36
3126 #define TOK_SR          37
3127 #define TOK_PLUS        38
3128 #define TOK_MINUS       39
3129 #define TOK_DIV         40
3130 #define TOK_MOD         41
3131 #define TOK_PLUSPLUS    42
3132 #define TOK_MINUSMINUS  43
3133 #define TOK_BANG        44
3134 #define TOK_ARROW       45
3135 #define TOK_DOT         46
3136 #define TOK_TILDE       47
3137 #define TOK_LIT_STRING  48
3138 #define TOK_LIT_CHAR    49
3139 #define TOK_LIT_INT     50
3140 #define TOK_LIT_FLOAT   51
3141 #define TOK_MACRO       52
3142 #define TOK_CONCATENATE 53
3143
3144 #define TOK_IDENT       54
3145 #define TOK_STRUCT_NAME 55
3146 #define TOK_ENUM_CONST  56
3147 #define TOK_TYPE_NAME   57
3148
3149 #define TOK_AUTO        58
3150 #define TOK_BREAK       59
3151 #define TOK_CASE        60
3152 #define TOK_CHAR        61
3153 #define TOK_CONST       62
3154 #define TOK_CONTINUE    63
3155 #define TOK_DEFAULT     64
3156 #define TOK_DO          65
3157 #define TOK_DOUBLE      66
3158 #define TOK_ELSE        67
3159 #define TOK_ENUM        68
3160 #define TOK_EXTERN      69
3161 #define TOK_FLOAT       70
3162 #define TOK_FOR         71
3163 #define TOK_GOTO        72
3164 #define TOK_IF          73
3165 #define TOK_INLINE      74
3166 #define TOK_INT         75
3167 #define TOK_LONG        76
3168 #define TOK_REGISTER    77
3169 #define TOK_RESTRICT    78
3170 #define TOK_RETURN      79
3171 #define TOK_SHORT       80
3172 #define TOK_SIGNED      81
3173 #define TOK_SIZEOF      82
3174 #define TOK_STATIC      83
3175 #define TOK_STRUCT      84
3176 #define TOK_SWITCH      85
3177 #define TOK_TYPEDEF     86
3178 #define TOK_UNION       87
3179 #define TOK_UNSIGNED    88
3180 #define TOK_VOID        89
3181 #define TOK_VOLATILE    90
3182 #define TOK_WHILE       91
3183 #define TOK_ASM         92
3184 #define TOK_ATTRIBUTE   93
3185 #define TOK_ALIGNOF     94
3186 #define TOK_FIRST_KEYWORD TOK_AUTO
3187 #define TOK_LAST_KEYWORD  TOK_ALIGNOF
3188
3189 #define TOK_MDEFINE     100
3190 #define TOK_MDEFINED    101
3191 #define TOK_MUNDEF      102
3192 #define TOK_MINCLUDE    103
3193 #define TOK_MLINE       104
3194 #define TOK_MERROR      105
3195 #define TOK_MWARNING    106
3196 #define TOK_MPRAGMA     107
3197 #define TOK_MIFDEF      108
3198 #define TOK_MIFNDEF     109
3199 #define TOK_MELIF       110
3200 #define TOK_MENDIF      111
3201
3202 #define TOK_FIRST_MACRO TOK_MDEFINE
3203 #define TOK_LAST_MACRO  TOK_MENDIF
3204          
3205 #define TOK_MIF         112
3206 #define TOK_MELSE       113
3207 #define TOK_MIDENT      114
3208
3209 #define TOK_EOL         115
3210 #define TOK_EOF         116
3211
3212 static const char *tokens[] = {
3213 [TOK_UNKNOWN     ] = ":unknown:",
3214 [TOK_SPACE       ] = ":space:",
3215 [TOK_SEMI        ] = ";",
3216 [TOK_LBRACE      ] = "{",
3217 [TOK_RBRACE      ] = "}",
3218 [TOK_COMMA       ] = ",",
3219 [TOK_EQ          ] = "=",
3220 [TOK_COLON       ] = ":",
3221 [TOK_LBRACKET    ] = "[",
3222 [TOK_RBRACKET    ] = "]",
3223 [TOK_LPAREN      ] = "(",
3224 [TOK_RPAREN      ] = ")",
3225 [TOK_STAR        ] = "*",
3226 [TOK_DOTS        ] = "...",
3227 [TOK_MORE        ] = ">",
3228 [TOK_LESS        ] = "<",
3229 [TOK_TIMESEQ     ] = "*=",
3230 [TOK_DIVEQ       ] = "/=",
3231 [TOK_MODEQ       ] = "%=",
3232 [TOK_PLUSEQ      ] = "+=",
3233 [TOK_MINUSEQ     ] = "-=",
3234 [TOK_SLEQ        ] = "<<=",
3235 [TOK_SREQ        ] = ">>=",
3236 [TOK_ANDEQ       ] = "&=",
3237 [TOK_XOREQ       ] = "^=",
3238 [TOK_OREQ        ] = "|=",
3239 [TOK_EQEQ        ] = "==",
3240 [TOK_NOTEQ       ] = "!=",
3241 [TOK_QUEST       ] = "?",
3242 [TOK_LOGOR       ] = "||",
3243 [TOK_LOGAND      ] = "&&",
3244 [TOK_OR          ] = "|",
3245 [TOK_AND         ] = "&",
3246 [TOK_XOR         ] = "^",
3247 [TOK_LESSEQ      ] = "<=",
3248 [TOK_MOREEQ      ] = ">=",
3249 [TOK_SL          ] = "<<",
3250 [TOK_SR          ] = ">>",
3251 [TOK_PLUS        ] = "+",
3252 [TOK_MINUS       ] = "-",
3253 [TOK_DIV         ] = "/",
3254 [TOK_MOD         ] = "%",
3255 [TOK_PLUSPLUS    ] = "++",
3256 [TOK_MINUSMINUS  ] = "--",
3257 [TOK_BANG        ] = "!",
3258 [TOK_ARROW       ] = "->",
3259 [TOK_DOT         ] = ".",
3260 [TOK_TILDE       ] = "~",
3261 [TOK_LIT_STRING  ] = ":string:",
3262 [TOK_IDENT       ] = ":ident:",
3263 [TOK_TYPE_NAME   ] = ":typename:",
3264 [TOK_LIT_CHAR    ] = ":char:",
3265 [TOK_LIT_INT     ] = ":integer:",
3266 [TOK_LIT_FLOAT   ] = ":float:",
3267 [TOK_MACRO       ] = "#",
3268 [TOK_CONCATENATE ] = "##",
3269
3270 [TOK_AUTO        ] = "auto",
3271 [TOK_BREAK       ] = "break",
3272 [TOK_CASE        ] = "case",
3273 [TOK_CHAR        ] = "char",
3274 [TOK_CONST       ] = "const",
3275 [TOK_CONTINUE    ] = "continue",
3276 [TOK_DEFAULT     ] = "default",
3277 [TOK_DO          ] = "do",
3278 [TOK_DOUBLE      ] = "double",
3279 [TOK_ELSE        ] = "else",
3280 [TOK_ENUM        ] = "enum",
3281 [TOK_EXTERN      ] = "extern",
3282 [TOK_FLOAT       ] = "float",
3283 [TOK_FOR         ] = "for",
3284 [TOK_GOTO        ] = "goto",
3285 [TOK_IF          ] = "if",
3286 [TOK_INLINE      ] = "inline",
3287 [TOK_INT         ] = "int",
3288 [TOK_LONG        ] = "long",
3289 [TOK_REGISTER    ] = "register",
3290 [TOK_RESTRICT    ] = "restrict",
3291 [TOK_RETURN      ] = "return",
3292 [TOK_SHORT       ] = "short",
3293 [TOK_SIGNED      ] = "signed",
3294 [TOK_SIZEOF      ] = "sizeof",
3295 [TOK_STATIC      ] = "static",
3296 [TOK_STRUCT      ] = "struct",
3297 [TOK_SWITCH      ] = "switch",
3298 [TOK_TYPEDEF     ] = "typedef",
3299 [TOK_UNION       ] = "union",
3300 [TOK_UNSIGNED    ] = "unsigned",
3301 [TOK_VOID        ] = "void",
3302 [TOK_VOLATILE    ] = "volatile",
3303 [TOK_WHILE       ] = "while",
3304 [TOK_ASM         ] = "asm",
3305 [TOK_ATTRIBUTE   ] = "__attribute__",
3306 [TOK_ALIGNOF     ] = "__alignof__",
3307
3308 [TOK_MDEFINE     ] = "#define",
3309 [TOK_MDEFINED    ] = "#defined",
3310 [TOK_MUNDEF      ] = "#undef",
3311 [TOK_MINCLUDE    ] = "#include",
3312 [TOK_MLINE       ] = "#line",
3313 [TOK_MERROR      ] = "#error",
3314 [TOK_MWARNING    ] = "#warning",
3315 [TOK_MPRAGMA     ] = "#pragma",
3316 [TOK_MIFDEF      ] = "#ifdef",
3317 [TOK_MIFNDEF     ] = "#ifndef",
3318 [TOK_MELIF       ] = "#elif",
3319 [TOK_MENDIF      ] = "#endif",
3320
3321 [TOK_MIF         ] = "#if",
3322 [TOK_MELSE       ] = "#else",
3323 [TOK_MIDENT      ] = "#:ident:",
3324 [TOK_EOL         ] = "EOL", 
3325 [TOK_EOF         ] = "EOF",
3326 };
3327
3328 static unsigned int hash(const char *str, int str_len)
3329 {
3330         unsigned int hash;
3331         const char *end;
3332         end = str + str_len;
3333         hash = 0;
3334         for(; str < end; str++) {
3335                 hash = (hash *263) + *str;
3336         }
3337         hash = hash & (HASH_TABLE_SIZE -1);
3338         return hash;
3339 }
3340
3341 static struct hash_entry *lookup(
3342         struct compile_state *state, const char *name, int name_len)
3343 {
3344         struct hash_entry *entry;
3345         unsigned int index;
3346         index = hash(name, name_len);
3347         entry = state->hash_table[index];
3348         while(entry && 
3349                 ((entry->name_len != name_len) ||
3350                         (memcmp(entry->name, name, name_len) != 0))) {
3351                 entry = entry->next;
3352         }
3353         if (!entry) {
3354                 char *new_name;
3355                 /* Get a private copy of the name */
3356                 new_name = xmalloc(name_len + 1, "hash_name");
3357                 memcpy(new_name, name, name_len);
3358                 new_name[name_len] = '\0';
3359
3360                 /* Create a new hash entry */
3361                 entry = xcmalloc(sizeof(*entry), "hash_entry");
3362                 entry->next = state->hash_table[index];
3363                 entry->name = new_name;
3364                 entry->name_len = name_len;
3365
3366                 /* Place the new entry in the hash table */
3367                 state->hash_table[index] = entry;
3368         }
3369         return entry;
3370 }
3371
3372 static void ident_to_keyword(struct compile_state *state, struct token *tk)
3373 {
3374         struct hash_entry *entry;
3375         entry = tk->ident;
3376         if (entry && ((entry->tok == TOK_TYPE_NAME) ||
3377                 (entry->tok == TOK_ENUM_CONST) ||
3378                 ((entry->tok >= TOK_FIRST_KEYWORD) && 
3379                         (entry->tok <= TOK_LAST_KEYWORD)))) {
3380                 tk->tok = entry->tok;
3381         }
3382 }
3383
3384 static void ident_to_macro(struct compile_state *state, struct token *tk)
3385 {
3386         struct hash_entry *entry;
3387         entry = tk->ident;
3388         if (!entry)
3389                 return;
3390         if ((entry->tok >= TOK_FIRST_MACRO) && (entry->tok <= TOK_LAST_MACRO)) {
3391                 tk->tok = entry->tok;
3392         }
3393         else if (entry->tok == TOK_IF) {
3394                 tk->tok = TOK_MIF;
3395         }
3396         else if (entry->tok == TOK_ELSE) {
3397                 tk->tok = TOK_MELSE;
3398         }
3399         else {
3400                 tk->tok = TOK_MIDENT;
3401         }
3402 }
3403
3404 static void hash_keyword(
3405         struct compile_state *state, const char *keyword, int tok)
3406 {
3407         struct hash_entry *entry;
3408         entry = lookup(state, keyword, strlen(keyword));
3409         if (entry && entry->tok != TOK_UNKNOWN) {
3410                 die("keyword %s already hashed", keyword);
3411         }
3412         entry->tok  = tok;
3413 }
3414
3415 static void romcc_symbol(
3416         struct compile_state *state, struct hash_entry *ident,
3417         struct symbol **chain, struct triple *def, struct type *type, int depth)
3418 {
3419         struct symbol *sym;
3420         if (*chain && ((*chain)->scope_depth >= depth)) {
3421                 error(state, 0, "%s already defined", ident->name);
3422         }
3423         sym = xcmalloc(sizeof(*sym), "symbol");
3424         sym->ident = ident;
3425         sym->def   = def;
3426         sym->type  = type;
3427         sym->scope_depth = depth;
3428         sym->next = *chain;
3429         *chain    = sym;
3430 }
3431
3432 static void symbol(
3433         struct compile_state *state, struct hash_entry *ident,
3434         struct symbol **chain, struct triple *def, struct type *type)
3435 {
3436         romcc_symbol(state, ident, chain, def, type, state->scope_depth);
3437 }
3438
3439 static void var_symbol(struct compile_state *state, 
3440         struct hash_entry *ident, struct triple *def)
3441 {
3442         if ((def->type->type & TYPE_MASK) == TYPE_PRODUCT) {
3443                 internal_error(state, 0, "bad var type");
3444         }
3445         symbol(state, ident, &ident->sym_ident, def, def->type);
3446 }
3447
3448 static void label_symbol(struct compile_state *state, 
3449         struct hash_entry *ident, struct triple *label, int depth)
3450 {
3451         romcc_symbol(state, ident, &ident->sym_label, label, &void_type, depth);
3452 }
3453
3454 static void start_scope(struct compile_state *state)
3455 {
3456         state->scope_depth++;
3457 }
3458
3459 static void end_scope_syms(struct compile_state *state,
3460         struct symbol **chain, int depth)
3461 {
3462         struct symbol *sym, *next;
3463         sym = *chain;
3464         while(sym && (sym->scope_depth == depth)) {
3465                 next = sym->next;
3466                 xfree(sym);
3467                 sym = next;
3468         }
3469         *chain = sym;
3470 }
3471
3472 static void end_scope(struct compile_state *state)
3473 {
3474         int i;
3475         int depth;
3476         /* Walk through the hash table and remove all symbols
3477          * in the current scope. 
3478          */
3479         depth = state->scope_depth;
3480         for(i = 0; i < HASH_TABLE_SIZE; i++) {
3481                 struct hash_entry *entry;
3482                 entry = state->hash_table[i];
3483                 while(entry) {
3484                         end_scope_syms(state, &entry->sym_label, depth);
3485                         end_scope_syms(state, &entry->sym_tag,   depth);
3486                         end_scope_syms(state, &entry->sym_ident, depth);
3487                         entry = entry->next;
3488                 }
3489         }
3490         state->scope_depth = depth - 1;
3491 }
3492
3493 static void register_keywords(struct compile_state *state)
3494 {
3495         hash_keyword(state, "auto",          TOK_AUTO);
3496         hash_keyword(state, "break",         TOK_BREAK);
3497         hash_keyword(state, "case",          TOK_CASE);
3498         hash_keyword(state, "char",          TOK_CHAR);
3499         hash_keyword(state, "const",         TOK_CONST);
3500         hash_keyword(state, "continue",      TOK_CONTINUE);
3501         hash_keyword(state, "default",       TOK_DEFAULT);
3502         hash_keyword(state, "do",            TOK_DO);
3503         hash_keyword(state, "double",        TOK_DOUBLE);
3504         hash_keyword(state, "else",          TOK_ELSE);
3505         hash_keyword(state, "enum",          TOK_ENUM);
3506         hash_keyword(state, "extern",        TOK_EXTERN);
3507         hash_keyword(state, "float",         TOK_FLOAT);
3508         hash_keyword(state, "for",           TOK_FOR);
3509         hash_keyword(state, "goto",          TOK_GOTO);
3510         hash_keyword(state, "if",            TOK_IF);
3511         hash_keyword(state, "inline",        TOK_INLINE);
3512         hash_keyword(state, "int",           TOK_INT);
3513         hash_keyword(state, "long",          TOK_LONG);
3514         hash_keyword(state, "register",      TOK_REGISTER);
3515         hash_keyword(state, "restrict",      TOK_RESTRICT);
3516         hash_keyword(state, "return",        TOK_RETURN);
3517         hash_keyword(state, "short",         TOK_SHORT);
3518         hash_keyword(state, "signed",        TOK_SIGNED);
3519         hash_keyword(state, "sizeof",        TOK_SIZEOF);
3520         hash_keyword(state, "static",        TOK_STATIC);
3521         hash_keyword(state, "struct",        TOK_STRUCT);
3522         hash_keyword(state, "switch",        TOK_SWITCH);
3523         hash_keyword(state, "typedef",       TOK_TYPEDEF);
3524         hash_keyword(state, "union",         TOK_UNION);
3525         hash_keyword(state, "unsigned",      TOK_UNSIGNED);
3526         hash_keyword(state, "void",          TOK_VOID);
3527         hash_keyword(state, "volatile",      TOK_VOLATILE);
3528         hash_keyword(state, "__volatile__",  TOK_VOLATILE);
3529         hash_keyword(state, "while",         TOK_WHILE);
3530         hash_keyword(state, "asm",           TOK_ASM);
3531         hash_keyword(state, "__asm__",       TOK_ASM);
3532         hash_keyword(state, "__attribute__", TOK_ATTRIBUTE);
3533         hash_keyword(state, "__alignof__",   TOK_ALIGNOF);
3534 }
3535
3536 static void register_macro_keywords(struct compile_state *state)
3537 {
3538         hash_keyword(state, "define",        TOK_MDEFINE);
3539         hash_keyword(state, "defined",       TOK_MDEFINED);
3540         hash_keyword(state, "undef",         TOK_MUNDEF);
3541         hash_keyword(state, "include",       TOK_MINCLUDE);
3542         hash_keyword(state, "line",          TOK_MLINE);
3543         hash_keyword(state, "error",         TOK_MERROR);
3544         hash_keyword(state, "warning",       TOK_MWARNING);
3545         hash_keyword(state, "pragma",        TOK_MPRAGMA);
3546         hash_keyword(state, "ifdef",         TOK_MIFDEF);
3547         hash_keyword(state, "ifndef",        TOK_MIFNDEF);
3548         hash_keyword(state, "elif",          TOK_MELIF);
3549         hash_keyword(state, "endif",         TOK_MENDIF);
3550 }
3551
3552
3553 static void undef_macro(struct compile_state *state, struct hash_entry *ident)
3554 {
3555         if (ident->sym_define != 0) {
3556                 struct macro *macro;
3557                 struct macro_arg *arg, *anext;
3558                 macro = ident->sym_define;
3559                 ident->sym_define = 0;
3560                 
3561                 /* Free the macro arguments... */
3562                 anext = macro->args;
3563                 while(anext) {
3564                         arg = anext;
3565                         anext = arg->next;
3566                         xfree(arg);
3567                 }
3568
3569                 /* Free the macro buffer */
3570                 xfree(macro->buf);
3571
3572                 /* Now free the macro itself */
3573                 xfree(macro);
3574         }
3575 }
3576
3577 static void define_macro(
3578         struct compile_state *state,
3579         struct hash_entry *ident, 
3580         const char *value, int value_len, int value_off, 
3581         struct macro_arg *args)
3582 {
3583         struct macro *macro;
3584         struct macro_arg *arg;
3585         macro = ident->sym_define;
3586         if (macro != 0) {
3587                 /* Explicitly allow identical redefinitions of the same macro */
3588                 if ((macro->buf_len == value_len) &&
3589                         (memcmp(macro->buf, value, value_len) == 0)) {
3590                         return;
3591                 }
3592                 error(state, 0, "macro %s already defined\n", ident->name);
3593         }
3594 #if 0
3595         fprintf(state->errout, "%s: `%*.*s'\n",
3596                 ident->name,
3597                 value_len - value_off,
3598                 value_len - value_off,
3599                 value + value_off);
3600 #endif
3601         macro = xmalloc(sizeof(*macro), "macro");
3602         macro->ident = ident;
3603         macro->buf_len = value_len;
3604         macro->buf_off = value_off;
3605         macro->args    = args;
3606         macro->buf = xmalloc(macro->buf_len + 1, "macro buf");
3607
3608         macro->argc = 0;
3609         for(arg = args; arg; arg = arg->next) {
3610                 macro->argc += 1;
3611         }      
3612
3613         memcpy(macro->buf, value, macro->buf_len);
3614         macro->buf[macro->buf_len] = '\0';
3615
3616         ident->sym_define = macro;
3617 }
3618
3619 static void register_builtin_macro(struct compile_state *state,
3620         const char *name, const char *value)
3621 {
3622         struct hash_entry *ident;
3623
3624         if (value[0] == '(') {
3625                 internal_error(state, 0, "Builtin macros with arguments not supported");
3626         }
3627         ident = lookup(state, name, strlen(name));
3628         define_macro(state, ident, value, strlen(value), 0, 0);
3629 }
3630
3631 static void register_builtin_macros(struct compile_state *state)
3632 {
3633         char buf[30];
3634         char scratch[30];
3635         time_t now;
3636         struct tm *tm;
3637         now = time(NULL);
3638         tm = localtime(&now);
3639
3640         register_builtin_macro(state, "__ROMCC__", VERSION_MAJOR);
3641         register_builtin_macro(state, "__ROMCC_MINOR__", VERSION_MINOR);
3642         register_builtin_macro(state, "__FILE__", "\"This should be the filename\"");
3643         register_builtin_macro(state, "__LINE__", "54321");
3644
3645         strftime(scratch, sizeof(scratch), "%b %e %Y", tm);
3646         sprintf(buf, "\"%s\"", scratch);
3647         register_builtin_macro(state, "__DATE__", buf);
3648
3649         strftime(scratch, sizeof(scratch), "%H:%M:%S", tm);
3650         sprintf(buf, "\"%s\"", scratch);
3651         register_builtin_macro(state, "__TIME__", buf);
3652
3653         /* I can't be a conforming implementation of C :( */
3654         register_builtin_macro(state, "__STDC__", "0");
3655         /* In particular I don't conform to C99 */
3656         register_builtin_macro(state, "__STDC_VERSION__", "199901L");
3657         
3658 }
3659
3660 static void process_cmdline_macros(struct compile_state *state)
3661 {
3662         const char **macro, *name;
3663         struct hash_entry *ident;
3664         for(macro = state->compiler->defines; (name = *macro); macro++) {
3665                 const char *body;
3666                 size_t name_len;
3667
3668                 name_len = strlen(name);
3669                 body = strchr(name, '=');
3670                 if (!body) {
3671                         body = "\0";
3672                 } else {
3673                         name_len = body - name;
3674                         body++;
3675                 }
3676                 ident = lookup(state, name, name_len);
3677                 define_macro(state, ident, body, strlen(body), 0, 0);
3678         }
3679         for(macro = state->compiler->undefs; (name = *macro); macro++) {
3680                 ident = lookup(state, name, strlen(name));
3681                 undef_macro(state, ident);
3682         }
3683 }
3684
3685 static int spacep(int c)
3686 {
3687         int ret = 0;
3688         switch(c) {
3689         case ' ':
3690         case '\t':
3691         case '\f':
3692         case '\v':
3693         case '\r':
3694                 ret = 1;
3695                 break;
3696         }
3697         return ret;
3698 }
3699
3700 static int eolp(int c)
3701 {
3702         int ret = 0;
3703         switch(c) {
3704         case '\n':
3705                 ret = 1;
3706                 break;
3707         }
3708         return ret;
3709 }
3710
3711 static int digitp(int c)
3712 {
3713         int ret = 0;
3714         switch(c) {
3715         case '0': case '1': case '2': case '3': case '4': 
3716         case '5': case '6': case '7': case '8': case '9':
3717                 ret = 1;
3718                 break;
3719         }
3720         return ret;
3721 }
3722 static int digval(int c)
3723 {
3724         int val = -1;
3725         if ((c >= '0') && (c <= '9')) {
3726                 val = c - '0';
3727         }
3728         return val;
3729 }
3730
3731 static int hexdigitp(int c)
3732 {
3733         int ret = 0;
3734         switch(c) {
3735         case '0': case '1': case '2': case '3': case '4': 
3736         case '5': case '6': case '7': case '8': case '9':
3737         case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
3738         case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
3739                 ret = 1;
3740                 break;
3741         }
3742         return ret;
3743 }
3744 static int hexdigval(int c) 
3745 {
3746         int val = -1;
3747         if ((c >= '0') && (c <= '9')) {
3748                 val = c - '0';
3749         }
3750         else if ((c >= 'A') && (c <= 'F')) {
3751                 val = 10 + (c - 'A');
3752         }
3753         else if ((c >= 'a') && (c <= 'f')) {
3754                 val = 10 + (c - 'a');
3755         }
3756         return val;
3757 }
3758
3759 static int octdigitp(int c)
3760 {
3761         int ret = 0;
3762         switch(c) {
3763         case '0': case '1': case '2': case '3': 
3764         case '4': case '5': case '6': case '7':
3765                 ret = 1;
3766                 break;
3767         }
3768         return ret;
3769 }
3770 static int octdigval(int c)
3771 {
3772         int val = -1;
3773         if ((c >= '0') && (c <= '7')) {
3774                 val = c - '0';
3775         }
3776         return val;
3777 }
3778
3779 static int letterp(int c)
3780 {
3781         int ret = 0;
3782         switch(c) {
3783         case 'a': case 'b': case 'c': case 'd': case 'e':
3784         case 'f': case 'g': case 'h': case 'i': case 'j':
3785         case 'k': case 'l': case 'm': case 'n': case 'o':
3786         case 'p': case 'q': case 'r': case 's': case 't':
3787         case 'u': case 'v': case 'w': case 'x': case 'y':
3788         case 'z':
3789         case 'A': case 'B': case 'C': case 'D': case 'E':
3790         case 'F': case 'G': case 'H': case 'I': case 'J':
3791         case 'K': case 'L': case 'M': case 'N': case 'O':
3792         case 'P': case 'Q': case 'R': case 'S': case 'T':
3793         case 'U': case 'V': case 'W': case 'X': case 'Y':
3794         case 'Z':
3795         case '_':
3796                 ret = 1;
3797                 break;
3798         }
3799         return ret;
3800 }
3801
3802 static const char *identifier(const char *str, const char *end)
3803 {
3804         if (letterp(*str)) {
3805                 for(; str < end; str++) {
3806                         int c;
3807                         c = *str;
3808                         if (!letterp(c) && !digitp(c)) {
3809                                 break;
3810                         }
3811                 }
3812         }
3813         return str;
3814 }
3815
3816 static int char_value(struct compile_state *state,
3817         const signed char **strp, const signed char *end)
3818 {
3819         const signed char *str;
3820         int c;
3821         str = *strp;
3822         c = *str++;
3823         if ((c == '\\') && (str < end)) {
3824                 switch(*str) {
3825                 case 'n':  c = '\n'; str++; break;
3826                 case 't':  c = '\t'; str++; break;
3827                 case 'v':  c = '\v'; str++; break;
3828                 case 'b':  c = '\b'; str++; break;
3829                 case 'r':  c = '\r'; str++; break;
3830                 case 'f':  c = '\f'; str++; break;
3831                 case 'a':  c = '\a'; str++; break;
3832                 case '\\': c = '\\'; str++; break;
3833                 case '?':  c = '?';  str++; break;
3834                 case '\'': c = '\''; str++; break;
3835                 case '"':  c = '"';  str++; break;
3836                 case 'x': 
3837                         c = 0;
3838                         str++;
3839                         while((str < end) && hexdigitp(*str)) {
3840                                 c <<= 4;
3841                                 c += hexdigval(*str);
3842                                 str++;
3843                         }
3844                         break;
3845                 case '0': case '1': case '2': case '3': 
3846                 case '4': case '5': case '6': case '7':
3847                         c = 0;
3848                         while((str < end) && octdigitp(*str)) {
3849                                 c <<= 3;
3850                                 c += octdigval(*str);
3851                                 str++;
3852                         }
3853                         break;
3854                 default:
3855                         error(state, 0, "Invalid character constant");
3856                         break;
3857                 }
3858         }
3859         *strp = str;
3860         return c;
3861 }
3862
3863 static const char *after_digits(const char *ptr, const char *end)
3864 {
3865         while((ptr < end) && digitp(*ptr)) {
3866                 ptr++;
3867         }
3868         return ptr;
3869 }
3870
3871 static const char *after_octdigits(const char *ptr, const char *end)
3872 {
3873         while((ptr < end) && octdigitp(*ptr)) {
3874                 ptr++;
3875         }
3876         return ptr;
3877 }
3878
3879 static const char *after_hexdigits(const char *ptr, const char *end)
3880 {
3881         while((ptr < end) && hexdigitp(*ptr)) {
3882                 ptr++;
3883         }
3884         return ptr;
3885 }
3886
3887 static void save_string(struct compile_state *state, 
3888         struct token *tk, const char *start, const char *end, const char *id)
3889 {
3890         char *str;
3891         int str_len;
3892         /* Create a private copy of the string */
3893         str_len = end - start + 1;
3894         str = xmalloc(str_len + 1, id);
3895         memcpy(str, start, str_len);
3896         str[str_len] = '\0';
3897
3898         /* Store the copy in the token */
3899         tk->val.str = str;
3900         tk->str_len = str_len;
3901 }
3902
3903 static int lparen_peek(struct compile_state *state, struct file_state *file)
3904 {
3905         const char *tokp, *end;
3906         /* Is the next token going to be an lparen? 
3907          * Whitespace tokens are significant for seeing if a macro
3908          * should be expanded.
3909          */
3910         tokp = file->pos;
3911         end = file->buf + file->size;
3912         return (tokp < end) && (*tokp == '(');
3913 }
3914
3915 static void raw_next_token(struct compile_state *state, 
3916         struct file_state *file, struct token *tk)
3917 {
3918         const char *token;
3919         int c, c1, c2, c3;
3920         const char *tokp, *end;
3921         int tok;
3922
3923         tk->str_len = 0;
3924         tk->ident = 0;
3925         token = tokp = file->pos;
3926         end = file->buf + file->size;
3927         tok = TOK_UNKNOWN;
3928         c = -1;
3929         if (tokp < end) {
3930                 c = *tokp;
3931         }
3932         c1 = -1;
3933         if ((tokp + 1) < end) {
3934                 c1 = tokp[1];
3935         }
3936         c2 = -1;
3937         if ((tokp + 2) < end) {
3938                 c2 = tokp[2];
3939         }
3940         c3 = -1;
3941         if ((tokp + 3) < end) {
3942                 c3 = tokp[3];
3943         }
3944         if (tokp >= end) {
3945                 tok = TOK_EOF;
3946                 tokp = end;
3947         }
3948         /* End of Line */
3949         else if (eolp(c)) {
3950                 tok = TOK_EOL;
3951                 file->line++;
3952                 file->report_line++;
3953                 file->line_start = tokp + 1;
3954         }
3955         /* Whitespace */
3956         else if (spacep(c)) {
3957                 tok = TOK_SPACE;
3958                 while ((tokp < end) && spacep(c)) {
3959                         c = *(++tokp);
3960                 }
3961                 if (!spacep(c)) {
3962                         tokp--;
3963                 }
3964         }
3965         /* EOL Comments */
3966         else if ((c == '/') && (c1 == '/')) {
3967                 tok = TOK_SPACE;
3968                 for(tokp += 2; tokp < end; tokp++) {
3969                         c = *tokp;
3970                         if (c == '\n') {
3971                                 tokp--;
3972                                 break;
3973                         }
3974                 }
3975         }
3976         /* Comments */
3977         else if ((c == '/') && (c1 == '*')) {
3978                 int line;
3979                 const char *line_start;
3980                 line = file->line;
3981                 line_start = file->line_start;
3982                 for(tokp += 2; (end - tokp) >= 2; tokp++) {
3983                         c = *tokp;
3984                         if (c == '\n') {
3985                                 line++;
3986                                 line_start = tokp +1;
3987                         }
3988                         else if ((c == '*') && (tokp[1] == '/')) {
3989                                 tok = TOK_SPACE;
3990                                 tokp += 1;
3991                                 break;
3992                         }
3993                 }
3994                 if (tok == TOK_UNKNOWN) {
3995                         error(state, 0, "unterminated comment");
3996                 }
3997                 file->report_line += line - file->line;
3998                 file->line = line;
3999                 file->line_start = line_start;
4000         }
4001         /* string constants */
4002         else if ((c == '"') ||
4003                 ((c == 'L') && (c1 == '"'))) {
4004                 int line;
4005                 const char *line_start;
4006                 int wchar;
4007                 line = file->line;
4008                 line_start = file->line_start;
4009                 wchar = 0;
4010                 if (c == 'L') {
4011                         wchar = 1;
4012                         tokp++;
4013                 }
4014                 for(tokp += 1; tokp < end; tokp++) {
4015                         c = *tokp;
4016                         if (c == '\n') {
4017                                 line++;
4018                                 line_start = tokp + 1;
4019                         }
4020                         else if ((c == '\\') && (tokp +1 < end)) {
4021                                 tokp++;
4022                         }
4023                         else if (c == '"') {
4024                                 tok = TOK_LIT_STRING;
4025                                 break;
4026                         }
4027                 }
4028                 if (tok == TOK_UNKNOWN) {
4029                         error(state, 0, "unterminated string constant");
4030                 }
4031                 if (line != file->line) {
4032                         warning(state, 0, "multiline string constant");
4033                 }
4034                 file->report_line += line - file->line;
4035                 file->line = line;
4036                 file->line_start = line_start;
4037
4038                 /* Save the string value */
4039                 save_string(state, tk, token, tokp, "literal string");
4040         }
4041         /* character constants */
4042         else if ((c == '\'') ||
4043                 ((c == 'L') && (c1 == '\''))) {
4044                 int line;
4045                 const char *line_start;
4046                 int wchar;
4047                 line = file->line;
4048                 line_start = file->line_start;
4049                 wchar = 0;
4050                 if (c == 'L') {
4051                         wchar = 1;
4052                         tokp++;
4053                 }
4054                 for(tokp += 1; tokp < end; tokp++) {
4055                         c = *tokp;
4056                         if (c == '\n') {
4057                                 line++;
4058                                 line_start = tokp + 1;
4059                         }
4060                         else if ((c == '\\') && (tokp +1 < end)) {
4061                                 tokp++;
4062                         }
4063                         else if (c == '\'') {
4064                                 tok = TOK_LIT_CHAR;
4065                                 break;
4066                         }
4067                 }
4068                 if (tok == TOK_UNKNOWN) {
4069                         error(state, 0, "unterminated character constant");
4070                 }
4071                 if (line != file->line) {
4072                         warning(state, 0, "multiline character constant");
4073                 }
4074                 file->report_line += line - file->line;
4075                 file->line = line;
4076                 file->line_start = line_start;
4077
4078                 /* Save the character value */
4079                 save_string(state, tk, token, tokp, "literal character");
4080         }
4081         /* integer and floating constants 
4082          * Integer Constants
4083          * {digits}
4084          * 0[Xx]{hexdigits}
4085          * 0{octdigit}+
4086          * 
4087          * Floating constants
4088          * {digits}.{digits}[Ee][+-]?{digits}
4089          * {digits}.{digits}
4090          * {digits}[Ee][+-]?{digits}
4091          * .{digits}[Ee][+-]?{digits}
4092          * .{digits}
4093          */
4094         
4095         else if (digitp(c) || ((c == '.') && (digitp(c1)))) {
4096                 const char *next, *new;
4097                 int is_float;
4098                 is_float = 0;
4099                 if (c != '.') {
4100                         next = after_digits(tokp, end);
4101                 }
4102                 else {
4103                         next = tokp;
4104                 }
4105                 if (next[0] == '.') {
4106                         new = after_digits(next, end);
4107                         is_float = (new != next);
4108                         next = new;
4109                 }
4110                 if ((next[0] == 'e') || (next[0] == 'E')) {
4111                         if (((next + 1) < end) && 
4112                                 ((next[1] == '+') || (next[1] == '-'))) {
4113                                 next++;
4114                         }
4115                         new = after_digits(next, end);
4116                         is_float = (new != next);
4117                         next = new;
4118                 }
4119                 if (is_float) {
4120                         tok = TOK_LIT_FLOAT;
4121                         if ((next < end) && (
4122                                 (next[0] == 'f') ||
4123                                 (next[0] == 'F') ||
4124                                 (next[0] == 'l') ||
4125                                 (next[0] == 'L'))
4126                                 ) {
4127                                 next++;
4128                         }
4129                 }
4130                 if (!is_float && digitp(c)) {
4131                         tok = TOK_LIT_INT;
4132                         if ((c == '0') && ((c1 == 'x') || (c1 == 'X'))) {
4133                                 next = after_hexdigits(tokp + 2, end);
4134                         }
4135                         else if (c == '0') {
4136                                 next = after_octdigits(tokp, end);
4137                         }
4138                         else {
4139                                 next = after_digits(tokp, end);
4140                         }
4141                         /* crazy integer suffixes */
4142                         if ((next < end) && 
4143                                 ((next[0] == 'u') || (next[0] == 'U'))) { 
4144                                 next++;
4145                                 if ((next < end) &&
4146                                         ((next[0] == 'l') || (next[0] == 'L'))) {
4147                                         next++;
4148                                 }
4149                         }
4150                         else if ((next < end) &&
4151                                 ((next[0] == 'l') || (next[0] == 'L'))) {
4152                                 next++;
4153                                 if ((next < end) && 
4154                                         ((next[0] == 'u') || (next[0] == 'U'))) { 
4155                                         next++;
4156                                 }
4157                         }
4158                 }
4159                 tokp = next - 1;
4160
4161                 /* Save the integer/floating point value */
4162                 save_string(state, tk, token, tokp, "literal number");
4163         }
4164         /* identifiers */
4165         else if (letterp(c)) {
4166                 tok = TOK_IDENT;
4167                 tokp = identifier(tokp, end);
4168                 tokp -= 1;
4169                 tk->ident = lookup(state, token, tokp +1 - token);
4170                 /* See if this identifier can be macro expanded */
4171                 tk->val.notmacro = 0;
4172                 if ((tokp < end) && (tokp[1] == '$')) {
4173                         tokp++;
4174                         tk->val.notmacro = 1;
4175                 }
4176         }
4177         /* C99 alternate macro characters */
4178         else if ((c == '%') && (c1 == ':') && (c2 == '%') && (c3 == ':')) { 
4179                 tokp += 3; 
4180                 tok = TOK_CONCATENATE; 
4181         }
4182         else if ((c == '.') && (c1 == '.') && (c2 == '.')) { tokp += 2; tok = TOK_DOTS; }
4183         else if ((c == '<') && (c1 == '<') && (c2 == '=')) { tokp += 2; tok = TOK_SLEQ; }
4184         else if ((c == '>') && (c1 == '>') && (c2 == '=')) { tokp += 2; tok = TOK_SREQ; }
4185         else if ((c == '*') && (c1 == '=')) { tokp += 1; tok = TOK_TIMESEQ; }
4186         else if ((c == '/') && (c1 == '=')) { tokp += 1; tok = TOK_DIVEQ; }
4187         else if ((c == '%') && (c1 == '=')) { tokp += 1; tok = TOK_MODEQ; }
4188         else if ((c == '+') && (c1 == '=')) { tokp += 1; tok = TOK_PLUSEQ; }
4189         else if ((c == '-') && (c1 == '=')) { tokp += 1; tok = TOK_MINUSEQ; }
4190         else if ((c == '&') && (c1 == '=')) { tokp += 1; tok = TOK_ANDEQ; }
4191         else if ((c == '^') && (c1 == '=')) { tokp += 1; tok = TOK_XOREQ; }
4192         else if ((c == '|') && (c1 == '=')) { tokp += 1; tok = TOK_OREQ; }
4193         else if ((c == '=') && (c1 == '=')) { tokp += 1; tok = TOK_EQEQ; }
4194         else if ((c == '!') && (c1 == '=')) { tokp += 1; tok = TOK_NOTEQ; }
4195         else if ((c == '|') && (c1 == '|')) { tokp += 1; tok = TOK_LOGOR; }
4196         else if ((c == '&') && (c1 == '&')) { tokp += 1; tok = TOK_LOGAND; }
4197         else if ((c == '<') && (c1 == '=')) { tokp += 1; tok = TOK_LESSEQ; }
4198         else if ((c == '>') && (c1 == '=')) { tokp += 1; tok = TOK_MOREEQ; }
4199         else if ((c == '<') && (c1 == '<')) { tokp += 1; tok = TOK_SL; }
4200         else if ((c == '>') && (c1 == '>')) { tokp += 1; tok = TOK_SR; }
4201         else if ((c == '+') && (c1 == '+')) { tokp += 1; tok = TOK_PLUSPLUS; }
4202         else if ((c == '-') && (c1 == '-')) { tokp += 1; tok = TOK_MINUSMINUS; }
4203         else if ((c == '-') && (c1 == '>')) { tokp += 1; tok = TOK_ARROW; }
4204         else if ((c == '<') && (c1 == ':')) { tokp += 1; tok = TOK_LBRACKET; }
4205         else if ((c == ':') && (c1 == '>')) { tokp += 1; tok = TOK_RBRACKET; }
4206         else if ((c == '<') && (c1 == '%')) { tokp += 1; tok = TOK_LBRACE; }
4207         else if ((c == '%') && (c1 == '>')) { tokp += 1; tok = TOK_RBRACE; }
4208         else if ((c == '%') && (c1 == ':')) { tokp += 1; tok = TOK_MACRO; }
4209         else if ((c == '#') && (c1 == '#')) { tokp += 1; tok = TOK_CONCATENATE; }
4210         else if (c == ';') { tok = TOK_SEMI; }
4211         else if (c == '{') { tok = TOK_LBRACE; }
4212         else if (c == '}') { tok = TOK_RBRACE; }
4213         else if (c == ',') { tok = TOK_COMMA; }
4214         else if (c == '=') { tok = TOK_EQ; }
4215         else if (c == ':') { tok = TOK_COLON; }
4216         else if (c == '[') { tok = TOK_LBRACKET; }
4217         else if (c == ']') { tok = TOK_RBRACKET; }
4218         else if (c == '(') { tok = TOK_LPAREN; }
4219         else if (c == ')') { tok = TOK_RPAREN; }
4220         else if (c == '*') { tok = TOK_STAR; }
4221         else if (c == '>') { tok = TOK_MORE; }
4222         else if (c == '<') { tok = TOK_LESS; }
4223         else if (c == '?') { tok = TOK_QUEST; }
4224         else if (c == '|') { tok = TOK_OR; }
4225         else if (c == '&') { tok = TOK_AND; }
4226         else if (c == '^') { tok = TOK_XOR; }
4227         else if (c == '+') { tok = TOK_PLUS; }
4228         else if (c == '-') { tok = TOK_MINUS; }
4229         else if (c == '/') { tok = TOK_DIV; }
4230         else if (c == '%') { tok = TOK_MOD; }
4231         else if (c == '!') { tok = TOK_BANG; }
4232         else if (c == '.') { tok = TOK_DOT; }
4233         else if (c == '~') { tok = TOK_TILDE; }
4234         else if (c == '#') { tok = TOK_MACRO; }
4235
4236         file->pos = tokp + 1;
4237         tk->tok = tok;
4238         if (tok == TOK_IDENT) {
4239                 if (state->token_base == 0) {
4240                         ident_to_keyword(state, tk);
4241                 } else {
4242                         ident_to_macro(state, tk);
4243                 }
4244         }
4245 }
4246
4247 static void next_token(struct compile_state *state, struct token *tk)
4248 {
4249         struct file_state *file;
4250         file = state->file;
4251         /* Don't return space tokens. */
4252         do {
4253                 raw_next_token(state, file, tk);
4254                 if (tk->tok == TOK_MACRO) {
4255                         /* Only match preprocessor directives at the start of a line */
4256                         const char *ptr;
4257                         for(ptr = file->line_start; spacep(*ptr); ptr++)
4258                                 ;
4259                         if (ptr != file->pos - 1) {
4260                                 tk->tok = TOK_UNKNOWN;
4261                         }
4262                 }
4263                 if (tk->tok == TOK_UNKNOWN) {
4264                         error(state, 0, "unknown token");
4265                 }
4266         } while(tk->tok == TOK_SPACE);
4267 }
4268
4269 static void check_tok(struct compile_state *state, struct token *tk, int tok)
4270 {
4271         if (tk->tok != tok) {
4272                 const char *name1, *name2;
4273                 name1 = tokens[tk->tok];
4274                 name2 = "";
4275                 if ((tk->tok == TOK_IDENT) || (tk->tok == TOK_MIDENT)) {
4276                         name2 = tk->ident->name;
4277                 }
4278                 error(state, 0, "\tfound %s %s expected %s",
4279                         name1, name2, tokens[tok]);
4280         }
4281 }
4282
4283 struct macro_arg_value {
4284         struct hash_entry *ident;
4285         unsigned char *value;
4286         size_t len;
4287 };
4288 static struct macro_arg_value *read_macro_args(
4289         struct compile_state *state, struct macro *macro, 
4290         struct file_state *file, struct token *tk)
4291 {
4292         struct macro_arg_value *argv;
4293         struct macro_arg *arg;
4294         int paren_depth;
4295         int i;
4296
4297         if (macro->argc == 0) {
4298                 do {
4299                         raw_next_token(state, file, tk);
4300                 } while(tk->tok == TOK_SPACE);
4301                 return 0;
4302         }
4303         argv = xcmalloc(sizeof(*argv) * macro->argc, "macro args");
4304         for(i = 0, arg = macro->args; arg; arg = arg->next, i++) {
4305                 argv[i].value = 0;
4306                 argv[i].len   = 0;
4307                 argv[i].ident = arg->ident;
4308         }
4309         paren_depth = 0;
4310         i = 0;
4311         
4312         for(;;) {
4313                 const char *start;
4314                 size_t len;
4315                 start = file->pos;
4316                 raw_next_token(state, file, tk);
4317                 
4318                 if (!paren_depth && (tk->tok == TOK_COMMA) &&
4319                         (argv[i].ident != state->i___VA_ARGS__)) 
4320                 {
4321                         i++;
4322                         if (i >= macro->argc) {
4323                                 error(state, 0, "too many args to %s\n",
4324                                         macro->ident->name);
4325                         }
4326                         continue;
4327                 }
4328                 
4329                 if (tk->tok == TOK_LPAREN) {
4330                         paren_depth++;
4331                 }
4332                 
4333                 if (tk->tok == TOK_RPAREN) {
4334                         if (paren_depth == 0) {
4335                                 break;
4336                         }
4337                         paren_depth--;
4338                 }
4339                 if (tk->tok == TOK_EOF) {
4340                         error(state, 0, "End of file encountered while parsing macro arguments");
4341                 }
4342                 
4343                 len = file->pos - start;
4344                 argv[i].value = xrealloc(
4345                         argv[i].value, argv[i].len + len, "macro args");
4346                 memcpy(argv[i].value + argv[i].len, start, len);
4347                 argv[i].len += len;
4348         }
4349         if (i != macro->argc -1) {
4350                 error(state, 0, "missing %s arg %d\n", 
4351                         macro->ident->name, i +2);
4352         }
4353         return argv;
4354 }
4355
4356
4357 static void free_macro_args(struct macro *macro, struct macro_arg_value *argv)
4358 {
4359         int i;
4360         for(i = 0; i < macro->argc; i++) {
4361                 xfree(argv[i].value);
4362         }
4363         xfree(argv);
4364 }
4365
4366 struct macro_buf {
4367         char *str;
4368         size_t len, pos;
4369 };
4370
4371 static void append_macro_text(struct compile_state *state,
4372         struct macro *macro, struct macro_buf *buf, 
4373         const char *fstart, size_t flen)
4374 {
4375 #if 0
4376         fprintf(state->errout, "append: `%*.*s' `%*.*s'\n",
4377                 buf->pos, buf->pos, buf->str,
4378                 flen, flen, fstart);
4379 #endif
4380         if ((buf->pos + flen) < buf->len) {
4381                 memcpy(buf->str + buf->pos, fstart, flen);
4382         } else {
4383                 buf->str = xrealloc(buf->str, buf->len + flen, macro->ident->name);
4384                 memcpy(buf->str + buf->pos, fstart, flen);
4385                 buf->len += flen;
4386         }
4387         buf->pos += flen;
4388 }
4389
4390 static int compile_macro(struct compile_state *state, 
4391         struct file_state **filep, struct token *tk);
4392
4393 static void macro_expand_args(struct compile_state *state, 
4394         struct macro *macro, struct macro_arg_value *argv, struct token *tk)
4395 {
4396         size_t i;
4397         
4398         for(i = 0; i < macro->argc; i++) {
4399                 struct file_state fmacro, *file;
4400                 struct macro_buf buf;
4401                 const char *fstart;
4402                 size_t flen;
4403
4404                 fmacro.basename    = argv[i].ident->name;
4405                 fmacro.dirname     = "";
4406                 fmacro.size        = argv[i].len;
4407                 fmacro.buf         = argv[i].value;
4408                 fmacro.pos         = fmacro.buf;
4409                 fmacro.line_start  = fmacro.buf;
4410                 fmacro.line        = 1;
4411                 fmacro.report_line = 1;
4412                 fmacro.report_name = fmacro.basename;
4413                 fmacro.report_dir  = fmacro.dirname;
4414                 fmacro.prev        = 0;
4415
4416                 buf.len = argv[i].len;
4417                 buf.str = xmalloc(buf.len, argv[i].ident->name);
4418                 buf.pos = 0;
4419
4420                 file = &fmacro;
4421                 for(;;) {
4422                         fstart = file->pos;
4423                         raw_next_token(state, file, tk);
4424                         flen = file->pos - fstart;
4425                         
4426                         if (tk->tok == TOK_EOF) {
4427                                 struct file_state *old;
4428                                 old = file;
4429                                 file = file->prev;
4430                                 if (!file) {
4431                                         break;
4432                                 }
4433                                 /* old->basename is used keep it */
4434                                 xfree(old->dirname);
4435                                 xfree(old->buf);
4436                                 xfree(old);
4437                                 continue;
4438                         }
4439                         else if (tk->ident && tk->ident->sym_define) {
4440                                 if (compile_macro(state, &file, tk)) {
4441                                         continue;
4442                                 }
4443                         }
4444
4445                         append_macro_text(state, macro, &buf,
4446                                 fstart, flen);
4447                 }
4448                         
4449                 xfree(argv[i].value);
4450                 argv[i].value = buf.str;
4451                 argv[i].len   = buf.pos;
4452         }
4453         return;
4454 }
4455
4456 static void expand_macro(struct compile_state *state,
4457         struct macro *macro, struct macro_buf *buf,
4458         struct macro_arg_value *argv, struct token *tk)
4459 {
4460         struct file_state fmacro;
4461         const char space[] = " ";
4462         const char *fstart;
4463         size_t flen;
4464         size_t i, j;
4465         fmacro.basename = macro->ident->name;
4466         fmacro.dirname  = "";
4467         fmacro.size = macro->buf_len - macro->buf_off;;
4468         fmacro.buf  = macro->buf + macro->buf_off;
4469         fmacro.pos  = fmacro.buf;
4470         fmacro.line_start = fmacro.buf;
4471         fmacro.line = 1;
4472         fmacro.report_line = 1;
4473         fmacro.report_name = fmacro.basename;
4474         fmacro.report_dir  = fmacro.dirname;
4475         fmacro.prev = 0;
4476         
4477         buf->len = macro->buf_len + 3;
4478         buf->str = xmalloc(buf->len, macro->ident->name);
4479         buf->pos = 0;
4480         
4481         fstart = fmacro.pos;
4482         raw_next_token(state, &fmacro, tk);
4483         while(tk->tok != TOK_EOF) {
4484                 flen = fmacro.pos - fstart;
4485                 switch(tk->tok) {
4486                 case TOK_IDENT:
4487                         for(i = 0; i < macro->argc; i++) {
4488                                 if (argv[i].ident == tk->ident) {
4489                                         break;
4490                                 }
4491                         }
4492                         if (i >= macro->argc) {
4493                                 break;
4494                         }
4495                         /* Substitute macro parameter */
4496                         fstart = argv[i].value;
4497                         flen   = argv[i].len;
4498                         break;
4499                 case TOK_MACRO:
4500                         if (!macro->buf_off) {
4501                                 break;
4502                         }
4503                         do {
4504                                 raw_next_token(state, &fmacro, tk);
4505                         } while(tk->tok == TOK_SPACE);
4506                         check_tok(state, tk, TOK_IDENT);
4507                         for(i = 0; i < macro->argc; i++) {
4508                                 if (argv[i].ident == tk->ident) {
4509                                         break;
4510                                 }
4511                         }
4512                         if (i >= macro->argc) {
4513                                 error(state, 0, "parameter `%s' not found",
4514                                         tk->ident->name);
4515                         }
4516                         /* Stringize token */
4517                         append_macro_text(state, macro, buf, "\"", 1);
4518                         for(j = 0; j < argv[i].len; j++) {
4519                                 char *str = argv[i].value + j;
4520                                 size_t len = 1;
4521                                 if (*str == '\\') {
4522                                         str = "\\";
4523                                         len = 2;
4524                                 } 
4525                                 else if (*str == '"') {
4526                                         str = "\\\"";
4527                                         len = 2;
4528                                 }
4529                                 append_macro_text(state, macro, buf, str, len);
4530                         }
4531                         append_macro_text(state, macro, buf, "\"", 1);
4532                         fstart = 0;
4533                         flen   = 0;
4534                         break;
4535                 case TOK_CONCATENATE:
4536                         /* Concatenate tokens */
4537                         /* Delete the previous whitespace token */
4538                         if (buf->str[buf->pos - 1] == ' ') {
4539                                 buf->pos -= 1;
4540                         }
4541                         /* Skip the next sequence of whitspace tokens */
4542                         do {
4543                                 fstart = fmacro.pos;
4544                                 raw_next_token(state, &fmacro, tk);
4545                         } while(tk->tok == TOK_SPACE);
4546                         /* Restart at the top of the loop.
4547                          * I need to process the non white space token.
4548                          */
4549                         continue;
4550                         break;
4551                 case TOK_SPACE:
4552                         /* Collapse multiple spaces into one */
4553                         if (buf->str[buf->pos - 1] != ' ') {
4554                                 fstart = space;
4555                                 flen   = 1;
4556                         } else {
4557                                 fstart = 0;
4558                                 flen   = 0;
4559                         }
4560                         break;
4561                 default:
4562                         break;
4563                 }
4564
4565                 append_macro_text(state, macro, buf, fstart, flen);
4566                 
4567                 fstart = fmacro.pos;
4568                 raw_next_token(state, &fmacro, tk);
4569         }
4570 }
4571
4572 static void tag_macro_name(struct compile_state *state,
4573         struct macro *macro, struct macro_buf *buf,
4574         struct token *tk)
4575 {
4576         /* Guard all instances of the macro name in the replacement
4577          * text from further macro expansion.
4578          */
4579         struct file_state fmacro;
4580         const char *fstart;
4581         size_t flen;
4582         fmacro.basename = macro->ident->name;
4583         fmacro.dirname  = "";
4584         fmacro.size = buf->pos;
4585         fmacro.buf  = buf->str;
4586         fmacro.pos  = fmacro.buf;
4587         fmacro.line_start = fmacro.buf;
4588         fmacro.line = 1;
4589         fmacro.report_line = 1;
4590         fmacro.report_name = fmacro.basename;
4591         fmacro.report_dir  = fmacro.dirname;
4592         fmacro.prev = 0;
4593         
4594         buf->len = macro->buf_len + 3;
4595         buf->str = xmalloc(buf->len, macro->ident->name);
4596         buf->pos = 0;
4597         
4598         fstart = fmacro.pos;
4599         raw_next_token(state, &fmacro, tk);
4600         while(tk->tok != TOK_EOF) {
4601                 flen = fmacro.pos - fstart;
4602                 if ((tk->tok == TOK_IDENT) &&
4603                         (tk->ident == macro->ident) &&
4604                         (tk->val.notmacro == 0)) {
4605                         append_macro_text(state, macro, buf, fstart, flen);
4606                         fstart = "$";
4607                         flen   = 1;
4608                 }
4609
4610                 append_macro_text(state, macro, buf, fstart, flen);
4611                 
4612                 fstart = fmacro.pos;
4613                 raw_next_token(state, &fmacro, tk);
4614         }
4615         xfree(fmacro.buf);
4616 }
4617         
4618 static int compile_macro(struct compile_state *state, 
4619         struct file_state **filep, struct token *tk)
4620 {
4621         struct file_state *file;
4622         struct hash_entry *ident;
4623         struct macro *macro;
4624         struct macro_arg_value *argv;
4625         struct macro_buf buf;
4626
4627 #if 0
4628         fprintf(state->errout, "macro: %s\n", tk->ident->name);
4629 #endif
4630         ident = tk->ident;
4631         macro = ident->sym_define;
4632
4633         /* If this token comes from a macro expansion ignore it */
4634         if (tk->val.notmacro) {
4635                 return 0;
4636         }
4637         /* If I am a function like macro and the identifier is not followed
4638          * by a left parenthesis, do nothing.
4639          */
4640         if ((macro->buf_off != 0) && !lparen_peek(state, *filep)) {
4641                 return 0;
4642         }
4643
4644         /* Read in the macro arguments */
4645         argv = 0;
4646         if (macro->buf_off) {
4647                 raw_next_token(state, *filep, tk);
4648                 check_tok(state, tk, TOK_LPAREN);
4649
4650                 argv = read_macro_args(state, macro, *filep, tk);
4651
4652                 check_tok(state, tk, TOK_RPAREN);
4653         }
4654         /* Macro expand the macro arguments */
4655         macro_expand_args(state, macro, argv, tk);
4656
4657         buf.str = 0;
4658         buf.len = 0;
4659         buf.pos = 0;
4660         if (ident == state->i___FILE__) {
4661                 buf.len = strlen(state->file->basename) + 1 + 2 + 3;
4662                 buf.str = xmalloc(buf.len, ident->name);
4663                 sprintf(buf.str, "\"%s\"", state->file->basename);
4664                 buf.pos = strlen(buf.str);
4665         }
4666         else if (ident == state->i___LINE__) {
4667                 buf.len = 30;
4668                 buf.str = xmalloc(buf.len, ident->name);
4669                 sprintf(buf.str, "%d", state->file->line);
4670                 buf.pos = strlen(buf.str);
4671         }
4672         else {
4673                 expand_macro(state, macro, &buf, argv, tk);
4674         }
4675         /* Tag the macro name with a $ so it will no longer
4676          * be regonized as a canidate for macro expansion.
4677          */
4678         tag_macro_name(state, macro, &buf, tk);
4679         append_macro_text(state, macro, &buf, "\n\0", 2);
4680
4681 #if 0
4682         fprintf(state->errout, "%s: %d -> `%*.*s'\n",
4683                 ident->name, buf.pos, buf.pos, (int)(buf.pos), buf.str);
4684 #endif
4685
4686         free_macro_args(macro, argv);
4687
4688         file = xmalloc(sizeof(*file), "file_state");
4689         file->basename = xstrdup(ident->name);
4690         file->dirname = xstrdup("");
4691         file->buf = buf.str;
4692         file->size = buf.pos - 2;
4693         file->pos = file->buf;
4694         file->line_start = file->pos;
4695         file->line = 1;
4696         file->report_line = 1;
4697         file->report_name = file->basename;
4698         file->report_dir  = file->dirname;
4699         file->prev = *filep;
4700         *filep = file;
4701         return 1;
4702 }
4703
4704 static void eat_tokens(struct compile_state *state, int targ_tok)
4705 {
4706         if (state->eat_depth > 0) {
4707                 internal_error(state, 0, "Already eating...");
4708         }
4709         state->eat_depth = state->if_depth;
4710         state->eat_targ = targ_tok;
4711 }
4712 static int if_eat(struct compile_state *state)
4713 {
4714         return state->eat_depth > 0;
4715 }
4716 static int if_value(struct compile_state *state)
4717 {
4718         int index, offset;
4719         index = state->if_depth / CHAR_BIT;
4720         offset = state->if_depth % CHAR_BIT;
4721         return !!(state->if_bytes[index] & (1 << (offset)));
4722 }
4723 static void set_if_value(struct compile_state *state, int value) 
4724 {
4725         int index, offset;
4726         index = state->if_depth / CHAR_BIT;
4727         offset = state->if_depth % CHAR_BIT;
4728
4729         state->if_bytes[index] &= ~(1 << offset);
4730         if (value) {
4731                 state->if_bytes[index] |= (1 << offset);
4732         }
4733 }
4734 static void in_if(struct compile_state *state, const char *name)
4735 {
4736         if (state->if_depth <= 0) {
4737                 error(state, 0, "%s without #if", name);
4738         }
4739 }
4740 static void enter_if(struct compile_state *state)
4741 {
4742         state->if_depth += 1;
4743         if (state->if_depth > MAX_CPP_IF_DEPTH) {
4744                 error(state, 0, "#if depth too great");
4745         }
4746 }
4747 static void reenter_if(struct compile_state *state, const char *name)
4748 {
4749         in_if(state, name);
4750         if ((state->eat_depth == state->if_depth) &&
4751                 (state->eat_targ == TOK_MELSE)) {
4752                 state->eat_depth = 0;
4753                 state->eat_targ = 0;
4754         }
4755 }
4756 static void enter_else(struct compile_state *state, const char *name)
4757 {
4758         in_if(state, name);
4759         if ((state->eat_depth == state->if_depth) &&
4760                 (state->eat_targ == TOK_MELSE)) {
4761                 state->eat_depth = 0;
4762                 state->eat_targ = 0;
4763         }
4764 }
4765 static void exit_if(struct compile_state *state, const char *name)
4766 {
4767         in_if(state, name);
4768         if (state->eat_depth == state->if_depth) {
4769                 state->eat_depth = 0;
4770                 state->eat_targ = 0;
4771         }
4772         state->if_depth -= 1;
4773 }
4774
4775 static void cpp_token(struct compile_state *state, struct token *tk)
4776 {
4777         struct file_state *file;
4778         int rescan;
4779
4780         next_token(state, tk);
4781         do {
4782                 rescan = 0;
4783                 file = state->file;
4784                 /* Exit out of an include directive or macro call */
4785                 if ((tk->tok == TOK_EOF) && 
4786                         (state->file && state->macro_file) &&
4787                         file->prev) 
4788                 {
4789                         state->file = file->prev;
4790                         /* file->basename is used keep it */
4791                         xfree(file->dirname);
4792                         xfree(file->buf);
4793                         xfree(file);
4794                         next_token(state, tk);
4795                         rescan = 1;
4796                 }
4797         } while(rescan);
4798 }
4799
4800 static void preprocess(struct compile_state *state, struct token *tk);
4801
4802 static void token(struct compile_state *state, struct token *tk)
4803 {
4804         int rescan;
4805         cpp_token(state, tk);
4806         do {
4807                 rescan = 0;
4808                 /* Process a macro directive */
4809                 if (tk->tok == TOK_MACRO) {
4810                         preprocess(state, tk);
4811                         rescan = 1;
4812                 }
4813                 /* Expand a macro call */
4814                 else if (tk->ident && tk->ident->sym_define) {
4815                         rescan = compile_macro(state, &state->file, tk);
4816                         if (rescan) {
4817                                 cpp_token(state, tk);
4818                         }
4819                 }
4820                 /* Eat tokens disabled by the preprocessor (Unless we are parsing a preprocessor directive */
4821                 else if (if_eat(state) && (state->token_base == 0)) {
4822                         cpp_token(state, tk);
4823                         rescan = 1;
4824                 }
4825                 /* Make certain EOL only shows up in preprocessor directives */
4826                 else if ((tk->tok == TOK_EOL) && (state->token_base == 0)) {
4827                         cpp_token(state, tk);
4828                         rescan = 1;
4829                 }
4830         } while(rescan);
4831 }
4832
4833
4834 static inline struct token *get_token(struct compile_state *state, int offset)
4835 {
4836         int index;
4837         index = state->token_base + offset;
4838         if (index >= sizeof(state->token)/sizeof(state->token[0])) {
4839                 internal_error(state, 0, "token array to small");
4840         }
4841         return &state->token[index];
4842 }
4843
4844 static struct token *do_eat_token(struct compile_state *state, int tok)
4845 {
4846         struct token *tk;
4847         int i;
4848         check_tok(state, get_token(state, 1), tok);
4849         
4850         /* Free the old token value */
4851         tk = get_token(state, 0);
4852         if (tk->str_len) {
4853                 memset((void *)tk->val.str, -1, tk->str_len);
4854                 xfree(tk->val.str);
4855         }
4856         /* Overwrite the old token with newer tokens */
4857         for(i = state->token_base; i < sizeof(state->token)/sizeof(state->token[0]) - 1; i++) {
4858                 state->token[i] = state->token[i + 1];
4859         }
4860         /* Clear the last token */
4861         memset(&state->token[i], 0, sizeof(state->token[i]));
4862         state->token[i].tok = -1;
4863
4864         /* Return the token */
4865         return tk;
4866 }
4867
4868 static int cpp_peek(struct compile_state *state)
4869 {
4870         struct token *tk1;
4871         tk1 = get_token(state, 1);
4872         if (tk1->tok == -1) {
4873                 cpp_token(state, tk1);
4874         }
4875         return tk1->tok;
4876 }
4877
4878 static struct token *cpp_eat(struct compile_state *state, int tok)
4879 {
4880         cpp_peek(state);
4881         return do_eat_token(state, tok);
4882 }
4883
4884 static int peek(struct compile_state *state)
4885 {
4886         struct token *tk1;
4887         tk1 = get_token(state, 1);
4888         if (tk1->tok == -1) {
4889                 token(state, tk1);
4890         }
4891         return tk1->tok;
4892 }
4893
4894 static int peek2(struct compile_state *state)
4895 {
4896         struct token *tk1, *tk2;
4897         tk1 = get_token(state, 1);
4898         tk2 = get_token(state, 2);
4899         if (tk1->tok == -1) {
4900                 token(state, tk1);
4901         }
4902         if (tk2->tok == -1) {
4903                 token(state, tk2);
4904         }
4905         return tk2->tok;
4906 }
4907
4908 static struct token *eat(struct compile_state *state, int tok)
4909 {
4910         peek(state);
4911         return do_eat_token(state, tok);
4912 }
4913
4914 static void compile_file(struct compile_state *state, const char *filename, int local)
4915 {
4916         char cwd[MAX_CWD_SIZE];
4917         const char *subdir, *base;
4918         int subdir_len;
4919         struct file_state *file;
4920         char *basename;
4921         file = xmalloc(sizeof(*file), "file_state");
4922
4923         base = strrchr(filename, '/');
4924         subdir = filename;
4925         if (base != 0) {
4926                 subdir_len = base - filename;
4927                 base++;
4928         }
4929         else {
4930                 base = filename;
4931                 subdir_len = 0;
4932         }
4933         basename = xmalloc(strlen(base) +1, "basename");
4934         strcpy(basename, base);
4935         file->basename = basename;
4936
4937         if (getcwd(cwd, sizeof(cwd)) == 0) {
4938                 die("cwd buffer to small");
4939         }
4940         if (subdir[0] == '/') {
4941                 file->dirname = xmalloc(subdir_len + 1, "dirname");
4942                 memcpy(file->dirname, subdir, subdir_len);
4943                 file->dirname[subdir_len] = '\0';
4944         }
4945         else {
4946                 const char *dir;
4947                 int dirlen;
4948                 const char **path;
4949                 /* Find the appropriate directory... */
4950                 dir = 0;
4951                 if (!state->file && exists(cwd, filename)) {
4952                         dir = cwd;
4953                 }
4954                 if (local && state->file && exists(state->file->dirname, filename)) {
4955                         dir = state->file->dirname;
4956                 }
4957                 for(path = state->compiler->include_paths; !dir && *path; path++) {
4958                         if (exists(*path, filename)) {
4959                                 dir = *path;
4960                         }
4961                 }
4962                 if (!dir) {
4963                         error(state, 0, "Cannot find `%s'\n", filename);
4964                 }
4965                 dirlen = strlen(dir);
4966                 file->dirname = xmalloc(dirlen + 1 + subdir_len + 1, "dirname");
4967                 memcpy(file->dirname, dir, dirlen);
4968                 file->dirname[dirlen] = '/';
4969                 memcpy(file->dirname + dirlen + 1, subdir, subdir_len);
4970                 file->dirname[dirlen + 1 + subdir_len] = '\0';
4971         }
4972         file->buf = slurp_file(file->dirname, file->basename, &file->size);
4973
4974         file->pos = file->buf;
4975         file->line_start = file->pos;
4976         file->line = 1;
4977
4978         file->report_line = 1;
4979         file->report_name = file->basename;
4980         file->report_dir  = file->dirname;
4981
4982         file->prev = state->file;
4983         state->file = file;
4984         
4985         process_trigraphs(state);
4986         splice_lines(state);
4987 }
4988
4989 static struct triple *constant_expr(struct compile_state *state);
4990 static void integral(struct compile_state *state, struct triple *def);
4991
4992 static int mcexpr(struct compile_state *state)
4993 {
4994         struct triple *cvalue;
4995         cvalue = constant_expr(state);
4996         integral(state, cvalue);
4997         if (cvalue->op != OP_INTCONST) {
4998                 error(state, 0, "integer constant expected");
4999         }
5000         return cvalue->u.cval != 0;
5001 }
5002
5003 static void preprocess(struct compile_state *state, struct token *current_token)
5004 {
5005         /* Doing much more with the preprocessor would require
5006          * a parser and a major restructuring.
5007          * Postpone that for later.
5008          */
5009         struct file_state *file;
5010         int old_token_base;
5011         int line;
5012         int tok;
5013         
5014         file = state->file;
5015         state->macro_line = line = file->line;
5016         state->macro_file = file;
5017
5018         old_token_base = state->token_base;
5019         state->token_base = current_token - state->token;
5020
5021         tok = cpp_peek(state);
5022         switch(tok) {
5023         case TOK_LIT_INT:
5024         {
5025                 struct token *tk;
5026                 int override_line;
5027                 tk = cpp_eat(state, TOK_LIT_INT);
5028                 override_line = strtoul(tk->val.str, 0, 10);
5029                 /* I have a cpp line marker parse it */
5030                 if (cpp_peek(state) == TOK_LIT_STRING) {
5031                         const char *token, *base;
5032                         char *name, *dir;
5033                         int name_len, dir_len;
5034                         tk = cpp_eat(state, TOK_LIT_STRING);
5035                         name = xmalloc(tk->str_len, "report_name");
5036                         token = tk->val.str + 1;
5037                         base = strrchr(token, '/');
5038                         name_len = tk->str_len -2;
5039                         if (base != 0) {
5040                                 dir_len = base - token;
5041                                 base++;
5042                                 name_len -= base - token;
5043                         } else {
5044                                 dir_len = 0;
5045                                 base = token;
5046                         }
5047                         memcpy(name, base, name_len);
5048                         name[name_len] = '\0';
5049                         dir = xmalloc(dir_len + 1, "report_dir");
5050                         memcpy(dir, token, dir_len);
5051                         dir[dir_len] = '\0';
5052                         file->report_line = override_line - 1;
5053                         file->report_name = name;
5054                         file->report_dir = dir;
5055                 }
5056                 break;
5057         }
5058         case TOK_MLINE:
5059         {
5060                 struct token *tk;
5061                 cpp_eat(state, TOK_MLINE);
5062                 tk = eat(state, TOK_LIT_INT);
5063                 file->report_line = strtoul(tk->val.str, 0, 10) -1;
5064                 if (cpp_peek(state) == TOK_LIT_STRING) {
5065                         const char *token, *base;
5066                         char *name, *dir;
5067                         int name_len, dir_len;
5068                         tk = cpp_eat(state, TOK_LIT_STRING);
5069                         name = xmalloc(tk->str_len, "report_name");
5070                         token = tk->val.str + 1;
5071                         base = strrchr(token, '/');
5072                         name_len = tk->str_len - 2;
5073                         if (base != 0) {
5074                                 dir_len = base - token;
5075                                 base++;
5076                                 name_len -= base - token;
5077                         } else {
5078                                 dir_len = 0;
5079                                 base = token;
5080                         }
5081                         memcpy(name, base, name_len);
5082                         name[name_len] = '\0';
5083                         dir = xmalloc(dir_len + 1, "report_dir");
5084                         memcpy(dir, token, dir_len);
5085                         dir[dir_len] = '\0';
5086                         file->report_name = name;
5087                         file->report_dir = dir;
5088                 }
5089                 break;
5090         }
5091         case TOK_MUNDEF:
5092         {
5093                 struct hash_entry *ident;
5094                 cpp_eat(state, TOK_MUNDEF);
5095                 if (if_eat(state))  /* quit early when #if'd out */
5096                         break;
5097                 
5098                 ident = cpp_eat(state, TOK_MIDENT)->ident;
5099
5100                 undef_macro(state, ident);
5101                 break;
5102         }
5103         case TOK_MPRAGMA:
5104                 cpp_eat(state, TOK_MPRAGMA);
5105                 if (if_eat(state))  /* quit early when #if'd out */
5106                         break;
5107                 warning(state, 0, "Ignoring pragma"); 
5108                 break;
5109         case TOK_MELIF:
5110                 cpp_eat(state, TOK_MELIF);
5111                 reenter_if(state, "#elif");
5112                 if (if_eat(state))   /* quit early when #if'd out */
5113                         break;
5114                 /* If the #if was taken the #elif just disables the following code */
5115                 if (if_value(state)) {
5116                         eat_tokens(state, TOK_MENDIF);
5117                 }
5118                 /* If the previous #if was not taken see if the #elif enables the 
5119                  * trailing code.
5120                  */
5121                 else {
5122                         set_if_value(state, mcexpr(state));
5123                         if (!if_value(state)) {
5124                                 eat_tokens(state, TOK_MELSE);
5125                         }
5126                 }
5127                 break;
5128         case TOK_MIF:
5129                 cpp_eat(state, TOK_MIF);
5130                 enter_if(state);
5131                 if (if_eat(state))  /* quit early when #if'd out */
5132                         break;
5133                 set_if_value(state, mcexpr(state));
5134                 if (!if_value(state)) {
5135                         eat_tokens(state, TOK_MELSE);
5136                 }
5137                 break;
5138         case TOK_MIFNDEF:
5139         {
5140                 struct hash_entry *ident;
5141
5142                 cpp_eat(state, TOK_MIFNDEF);
5143                 enter_if(state);
5144                 if (if_eat(state))  /* quit early when #if'd out */
5145                         break;
5146                 ident = cpp_eat(state, TOK_MIDENT)->ident;
5147                 set_if_value(state, ident->sym_define == 0);
5148                 if (!if_value(state)) {
5149                         eat_tokens(state, TOK_MELSE);
5150                 }
5151                 break;
5152         }
5153         case TOK_MIFDEF:
5154         {
5155                 struct hash_entry *ident;
5156                 cpp_eat(state, TOK_MIFDEF);
5157                 enter_if(state);
5158                 if (if_eat(state))  /* quit early when #if'd out */
5159                         break;
5160                 ident = cpp_eat(state, TOK_MIDENT)->ident;
5161                 set_if_value(state, ident->sym_define != 0);
5162                 if (!if_value(state)) {
5163                         eat_tokens(state, TOK_MELSE);
5164                 }
5165                 break;
5166         }
5167         case TOK_MELSE:
5168                 cpp_eat(state, TOK_MELSE);
5169                 enter_else(state, "#else");
5170                 if (!if_eat(state) && if_value(state)) {
5171                         eat_tokens(state, TOK_MENDIF);
5172                 }
5173                 break;
5174         case TOK_MENDIF:
5175                 cpp_eat(state, TOK_MENDIF);
5176                 exit_if(state, "#endif");
5177                 break;
5178         case TOK_MDEFINE:
5179         {
5180                 struct hash_entry *ident;
5181                 struct macro_arg *args, **larg;
5182                 const char *start, *mstart, *ptr;
5183
5184                 cpp_eat(state, TOK_MDEFINE);
5185                 if (if_eat(state))  /* quit early when #if'd out */
5186                         break;
5187
5188                 ident = cpp_eat(state, TOK_MIDENT)->ident;
5189                 args = 0;
5190                 larg = &args;
5191
5192                 /* Remember the start of the macro */
5193                 start = file->pos;
5194
5195                 /* Find the end of the line. */
5196                 for(ptr = start; *ptr != '\n'; ptr++)  
5197                         ;
5198
5199                 /* remove the trailing whitespace */
5200                 ptr-=1;
5201                 while(spacep(*ptr)) {
5202                         ptr--;
5203                 }
5204
5205                 /* Remove leading whitespace */
5206                 while(spacep(*start) && (start < ptr)) {
5207                         start++;
5208                 }
5209                 /* Remember where the macro starts */
5210                 mstart = start;
5211
5212                 /* Parse macro parameters */
5213                 if (lparen_peek(state, state->file)) {
5214                         cpp_eat(state, TOK_LPAREN);
5215                         
5216                         for(;;) {
5217                                 struct macro_arg *narg, *arg;
5218                                 struct hash_entry *aident;
5219                                 int tok;
5220
5221                                 tok = cpp_peek(state);
5222                                 if (!args && (tok == TOK_RPAREN)) {
5223                                         break;
5224                                 }
5225                                 else if (tok == TOK_DOTS) {
5226                                         cpp_eat(state, TOK_DOTS);
5227                                         aident = state->i___VA_ARGS__;
5228                                 } 
5229                                 else {
5230                                         aident = cpp_eat(state, TOK_MIDENT)->ident;
5231                                 }
5232                                 
5233                                 narg = xcmalloc(sizeof(*arg), "macro arg");
5234                                 narg->ident = aident;
5235
5236                                 /* Verify I don't have a duplicate identifier */
5237                                 for(arg = args; arg; arg = arg->next) {
5238                                         if (arg->ident == narg->ident) {
5239                                                 error(state, 0, "Duplicate macro arg `%s'",
5240                                                         narg->ident->name);
5241                                         }
5242                                 }
5243                                 /* Add the new argument to the end of the list */
5244                                 *larg = narg;
5245                                 larg = &narg->next;
5246
5247                                 if ((aident == state->i___VA_ARGS__) ||
5248                                         (cpp_peek(state) != TOK_COMMA)) {
5249                                         break;
5250                                 }
5251                                 cpp_eat(state, TOK_COMMA);
5252                         }
5253                         cpp_eat(state, TOK_RPAREN);
5254
5255                         /* Get the start of the macro body */
5256                         mstart = file->pos;
5257
5258                         /* Remove leading whitespace */
5259                         while(spacep(*mstart) && (mstart < ptr)) {
5260                                 mstart++;
5261                         }
5262                 }
5263                 define_macro(state, ident, start, ptr - start + 1, 
5264                         mstart - start, args);
5265                 break;
5266         }
5267         case TOK_MERROR:
5268         {
5269                 const char *end;
5270                 int len;
5271                 
5272                 cpp_eat(state, TOK_MERROR);
5273                 /* Find the end of the line */
5274                 for(end = file->pos; *end != '\n'; end++)
5275                         ;
5276                 len = (end - file->pos);
5277                 if (!if_eat(state)) {
5278                         error(state, 0, "%*.*s", len, len, file->pos);
5279                 }
5280                 file->pos = end;
5281                 break;
5282         }
5283         case TOK_MWARNING:
5284         {
5285                 const char *end;
5286                 int len;
5287                 
5288                 cpp_eat(state, TOK_MWARNING);
5289                 /* Find the end of the line */
5290                 for(end = file->pos; *end != '\n'; end++)
5291                         ;
5292                 len = (end - file->pos);
5293                 if (!if_eat(state)) {
5294                         warning(state, 0, "%*.*s", len, len, file->pos);
5295                 }
5296                 file->pos = end;
5297                 break;
5298         }
5299         case TOK_MINCLUDE:
5300         {
5301                 char *name;
5302                 int local;
5303                 local = 0;
5304                 name = 0;
5305
5306                 cpp_eat(state, TOK_MINCLUDE);
5307                 tok = peek(state);
5308                 if (tok == TOK_LIT_STRING) {
5309                         struct token *tk;
5310                         const char *token;
5311                         int name_len;
5312                         tk = eat(state, TOK_LIT_STRING);
5313                         name = xmalloc(tk->str_len, "include");
5314                         token = tk->val.str +1;
5315                         name_len = tk->str_len -2;
5316                         if (*token == '"') {
5317                                 token++;
5318                                 name_len--;
5319                         }
5320                         memcpy(name, token, name_len);
5321                         name[name_len] = '\0';
5322                         local = 1;
5323                 }
5324                 else if (tok == TOK_LESS) {
5325                         const char *start, *end;
5326                         eat(state, TOK_LESS);
5327                         start = file->pos;
5328                         for(end = start; *end != '\n'; end++) {
5329                                 if (*end == '>') {
5330                                         break;
5331                                 }
5332                         }
5333                         if (*end == '\n') {
5334                                 error(state, 0, "Unterminated include directive");
5335                         }
5336                         name = xmalloc(end - start + 1, "include");
5337                         memcpy(name, start, end - start);
5338                         name[end - start] = '\0';
5339                         file->pos = end;
5340                         local = 0;
5341                         eat(state, TOK_MORE);
5342                 }
5343                 else {
5344                         error(state, 0, "Invalid include directive");
5345                 }
5346                 /* Error if there are any tokens after the include */
5347                 if (cpp_peek(state) != TOK_EOL) {
5348                         error(state, 0, "garbage after include directive");
5349                 }
5350                 if (!if_eat(state)) {
5351                         compile_file(state, name, local);
5352                 }
5353                 xfree(name);
5354                 break;
5355         }
5356         case TOK_EOL:
5357                 /* Ignore # without a follwing ident */
5358                 break;
5359         default:
5360         {
5361                 const char *name1, *name2;
5362                 name1 = tokens[tok];
5363                 name2 = "";
5364                 if (tok == TOK_MIDENT) {
5365                         name2 = get_token(state, 1)->ident->name;
5366                 }
5367                 error(state, 0, "Invalid preprocessor directive: %s %s", 
5368                         name1, name2);
5369                 break;
5370         }
5371         }
5372         /* Consume the rest of the macro line */
5373         do {
5374                 tok = cpp_peek(state);
5375                 cpp_eat(state, tok);
5376         } while((tok != TOK_EOF) && (tok != TOK_EOL));
5377         state->token_base = old_token_base;
5378         return;
5379 }
5380
5381 /* Type helper functions */
5382
5383 static struct type *new_type(
5384         unsigned int type, struct type *left, struct type *right)
5385 {
5386         struct type *result;
5387         result = xmalloc(sizeof(*result), "type");
5388         result->type = type;
5389         result->left = left;
5390         result->right = right;
5391         result->field_ident = 0;
5392         result->type_ident = 0;
5393         result->elements = 0;
5394         return result;
5395 }
5396
5397 static struct type *clone_type(unsigned int specifiers, struct type *old)
5398 {
5399         struct type *result;
5400         result = xmalloc(sizeof(*result), "type");
5401         memcpy(result, old, sizeof(*result));
5402         result->type &= TYPE_MASK;
5403         result->type |= specifiers;
5404         return result;
5405 }
5406
5407 static struct type *dup_type(struct compile_state *state, struct type *orig)
5408 {
5409         struct type *new;
5410         new = xcmalloc(sizeof(*new), "type");
5411         new->type = orig->type;
5412         new->field_ident = orig->field_ident;
5413         new->type_ident  = orig->type_ident;
5414         new->elements    = orig->elements;
5415         if (orig->left) {
5416                 new->left = dup_type(state, orig->left);
5417         }
5418         if (orig->right) {
5419                 new->right = dup_type(state, orig->right);
5420         }
5421         return new;
5422 }
5423
5424
5425 static struct type *invalid_type(struct compile_state *state, struct type *type)
5426 {
5427         struct type *invalid, *member;
5428         invalid = 0;
5429         if (!type) {
5430                 internal_error(state, 0, "type missing?");
5431         }
5432         switch(type->type & TYPE_MASK) {
5433         case TYPE_VOID:
5434         case TYPE_CHAR:         case TYPE_UCHAR:
5435         case TYPE_SHORT:        case TYPE_USHORT:
5436         case TYPE_INT:          case TYPE_UINT:
5437         case TYPE_LONG:         case TYPE_ULONG:
5438         case TYPE_LLONG:        case TYPE_ULLONG:
5439         case TYPE_POINTER:
5440         case TYPE_ENUM:
5441                 break;
5442         case TYPE_BITFIELD:
5443                 invalid = invalid_type(state, type->left);
5444                 break;
5445         case TYPE_ARRAY:
5446                 invalid = invalid_type(state, type->left);
5447                 break;
5448         case TYPE_STRUCT:
5449         case TYPE_TUPLE:
5450                 member = type->left;
5451                 while(member && (invalid == 0) && 
5452                         ((member->type & TYPE_MASK) == TYPE_PRODUCT)) {
5453                         invalid = invalid_type(state, member->left);
5454                         member = member->right;
5455                 }
5456                 if (!invalid) {
5457                         invalid = invalid_type(state, member);
5458                 }
5459                 break;
5460         case TYPE_UNION:
5461         case TYPE_JOIN:
5462                 member = type->left;
5463                 while(member && (invalid == 0) &&
5464                         ((member->type & TYPE_MASK) == TYPE_OVERLAP)) {
5465                         invalid = invalid_type(state, member->left);
5466                         member = member->right;
5467                 }
5468                 if (!invalid) {
5469                         invalid = invalid_type(state, member);
5470                 }
5471                 break;
5472         default:
5473                 invalid = type;
5474                 break;
5475         }
5476         return invalid;
5477         
5478 }
5479
5480 #define MASK_UCHAR(X)    ((X) & ((ulong_t)0xff))
5481 #define MASK_USHORT(X)   ((X) & (((ulong_t)1 << (SIZEOF_SHORT)) - 1))
5482 static inline ulong_t mask_uint(ulong_t x)
5483 {
5484         if (SIZEOF_INT < SIZEOF_LONG) {
5485                 ulong_t mask = (((ulong_t)1) << ((ulong_t)(SIZEOF_INT))) -1;
5486                 x &= mask;
5487         }
5488         return x;
5489 }
5490 #define MASK_UINT(X)      (mask_uint(X))
5491 #define MASK_ULONG(X)    (X)
5492
5493 static struct type void_type    = { .type  = TYPE_VOID };
5494 static struct type char_type    = { .type  = TYPE_CHAR };
5495 static struct type uchar_type   = { .type  = TYPE_UCHAR };
5496 static struct type short_type   = { .type  = TYPE_SHORT };
5497 static struct type ushort_type  = { .type  = TYPE_USHORT };
5498 static struct type int_type     = { .type  = TYPE_INT };
5499 static struct type uint_type    = { .type  = TYPE_UINT };
5500 static struct type long_type    = { .type  = TYPE_LONG };
5501 static struct type ulong_type   = { .type  = TYPE_ULONG };
5502 static struct type unknown_type = { .type  = TYPE_UNKNOWN };
5503
5504 static struct type void_ptr_type  = {
5505         .type = TYPE_POINTER,
5506         .left = &void_type,
5507 };
5508
5509 static struct type void_func_type = { 
5510         .type  = TYPE_FUNCTION,
5511         .left  = &void_type,
5512         .right = &void_type,
5513 };
5514
5515 static size_t bits_to_bytes(size_t size)
5516 {
5517         return (size + SIZEOF_CHAR - 1)/SIZEOF_CHAR;
5518 }
5519
5520 static struct triple *variable(struct compile_state *state, struct type *type)
5521 {
5522         struct triple *result;
5523         if ((type->type & STOR_MASK) != STOR_PERM) {
5524                 result = triple(state, OP_ADECL, type, 0, 0);
5525                 generate_lhs_pieces(state, result);
5526         }
5527         else {
5528                 result = triple(state, OP_SDECL, type, 0, 0);
5529         }
5530         return result;
5531 }
5532
5533 static void stor_of(FILE *fp, struct type *type)
5534 {
5535         switch(type->type & STOR_MASK) {
5536         case STOR_AUTO:
5537                 fprintf(fp, "auto ");
5538                 break;
5539         case STOR_STATIC:
5540                 fprintf(fp, "static ");
5541                 break;
5542         case STOR_LOCAL:
5543                 fprintf(fp, "local ");
5544                 break;
5545         case STOR_EXTERN:
5546                 fprintf(fp, "extern ");
5547                 break;
5548         case STOR_REGISTER:
5549                 fprintf(fp, "register ");
5550                 break;
5551         case STOR_TYPEDEF:
5552                 fprintf(fp, "typedef ");
5553                 break;
5554         case STOR_INLINE | STOR_LOCAL:
5555                 fprintf(fp, "inline ");
5556                 break;
5557         case STOR_INLINE | STOR_STATIC:
5558                 fprintf(fp, "static inline");
5559                 break;
5560         case STOR_INLINE | STOR_EXTERN:
5561                 fprintf(fp, "extern inline");
5562                 break;
5563         default:
5564                 fprintf(fp, "stor:%x", type->type & STOR_MASK);
5565                 break;
5566         }
5567 }
5568 static void qual_of(FILE *fp, struct type *type)
5569 {
5570         if (type->type & QUAL_CONST) {
5571                 fprintf(fp, " const");
5572         }
5573         if (type->type & QUAL_VOLATILE) {
5574                 fprintf(fp, " volatile");
5575         }
5576         if (type->type & QUAL_RESTRICT) {
5577                 fprintf(fp, " restrict");
5578         }
5579 }
5580
5581 static void name_of(FILE *fp, struct type *type)
5582 {
5583         unsigned int base_type;
5584         base_type = type->type & TYPE_MASK;
5585         if ((base_type != TYPE_PRODUCT) && (base_type != TYPE_OVERLAP)) {
5586                 stor_of(fp, type);
5587         }
5588         switch(base_type) {
5589         case TYPE_VOID:
5590                 fprintf(fp, "void");
5591                 qual_of(fp, type);
5592                 break;
5593         case TYPE_CHAR:
5594                 fprintf(fp, "signed char");
5595                 qual_of(fp, type);
5596                 break;
5597         case TYPE_UCHAR:
5598                 fprintf(fp, "unsigned char");
5599                 qual_of(fp, type);
5600                 break;
5601         case TYPE_SHORT:
5602                 fprintf(fp, "signed short");
5603                 qual_of(fp, type);
5604                 break;
5605         case TYPE_USHORT:
5606                 fprintf(fp, "unsigned short");
5607                 qual_of(fp, type);
5608                 break;
5609         case TYPE_INT:
5610                 fprintf(fp, "signed int");
5611                 qual_of(fp, type);
5612                 break;
5613         case TYPE_UINT:
5614                 fprintf(fp, "unsigned int");
5615                 qual_of(fp, type);
5616                 break;
5617         case TYPE_LONG:
5618                 fprintf(fp, "signed long");
5619                 qual_of(fp, type);
5620                 break;
5621         case TYPE_ULONG:
5622                 fprintf(fp, "unsigned long");
5623                 qual_of(fp, type);
5624                 break;
5625         case TYPE_POINTER:
5626                 name_of(fp, type->left);
5627                 fprintf(fp, " * ");
5628                 qual_of(fp, type);
5629                 break;
5630         case TYPE_PRODUCT:
5631                 name_of(fp, type->left);
5632                 fprintf(fp, ", ");
5633                 name_of(fp, type->right);
5634                 break;
5635         case TYPE_OVERLAP:
5636                 name_of(fp, type->left);
5637                 fprintf(fp, ",| ");
5638                 name_of(fp, type->right);
5639                 break;
5640         case TYPE_ENUM:
5641                 fprintf(fp, "enum %s", 
5642                         (type->type_ident)? type->type_ident->name : "");
5643                 qual_of(fp, type);
5644                 break;
5645         case TYPE_STRUCT:
5646                 fprintf(fp, "struct %s { ", 
5647                         (type->type_ident)? type->type_ident->name : "");
5648                 name_of(fp, type->left);
5649                 fprintf(fp, " } ");
5650                 qual_of(fp, type);
5651                 break;
5652         case TYPE_UNION:
5653                 fprintf(fp, "union %s { ", 
5654                         (type->type_ident)? type->type_ident->name : "");
5655                 name_of(fp, type->left);
5656                 fprintf(fp, " } ");
5657                 qual_of(fp, type);
5658                 break;
5659         case TYPE_FUNCTION:
5660                 name_of(fp, type->left);
5661                 fprintf(fp, " (*)(");
5662                 name_of(fp, type->right);
5663                 fprintf(fp, ")");
5664                 break;
5665         case TYPE_ARRAY:
5666                 name_of(fp, type->left);
5667                 fprintf(fp, " [%ld]", (long)(type->elements));
5668                 break;
5669         case TYPE_TUPLE:
5670                 fprintf(fp, "tuple { "); 
5671                 name_of(fp, type->left);
5672                 fprintf(fp, " } ");
5673                 qual_of(fp, type);
5674                 break;
5675         case TYPE_JOIN:
5676                 fprintf(fp, "join { ");
5677                 name_of(fp, type->left);
5678                 fprintf(fp, " } ");
5679                 qual_of(fp, type);
5680                 break;
5681         case TYPE_BITFIELD:
5682                 name_of(fp, type->left);
5683                 fprintf(fp, " : %d ", type->elements);
5684                 qual_of(fp, type);
5685                 break;
5686         case TYPE_UNKNOWN:
5687                 fprintf(fp, "unknown_t");
5688                 break;
5689         default:
5690                 fprintf(fp, "????: %x", base_type);
5691                 break;
5692         }
5693         if (type->field_ident && type->field_ident->name) {
5694                 fprintf(fp, " .%s", type->field_ident->name);
5695         }
5696 }
5697
5698 static size_t align_of(struct compile_state *state, struct type *type)
5699 {
5700         size_t align;
5701         align = 0;
5702         switch(type->type & TYPE_MASK) {
5703         case TYPE_VOID:
5704                 align = 1;
5705                 break;
5706         case TYPE_BITFIELD:
5707                 align = 1;
5708                 break;
5709         case TYPE_CHAR:
5710         case TYPE_UCHAR:
5711                 align = ALIGNOF_CHAR;
5712                 break;
5713         case TYPE_SHORT:
5714         case TYPE_USHORT:
5715                 align = ALIGNOF_SHORT;
5716                 break;
5717         case TYPE_INT:
5718         case TYPE_UINT:
5719         case TYPE_ENUM:
5720                 align = ALIGNOF_INT;
5721                 break;
5722         case TYPE_LONG:
5723         case TYPE_ULONG:
5724                 align = ALIGNOF_LONG;
5725                 break;
5726         case TYPE_POINTER:
5727                 align = ALIGNOF_POINTER;
5728                 break;
5729         case TYPE_PRODUCT:
5730         case TYPE_OVERLAP:
5731         {
5732                 size_t left_align, right_align;
5733                 left_align  = align_of(state, type->left);
5734                 right_align = align_of(state, type->right);
5735                 align = (left_align >= right_align) ? left_align : right_align;
5736                 break;
5737         }
5738         case TYPE_ARRAY:
5739                 align = align_of(state, type->left);
5740                 break;
5741         case TYPE_STRUCT:
5742         case TYPE_TUPLE:
5743         case TYPE_UNION:
5744         case TYPE_JOIN:
5745                 align = align_of(state, type->left);
5746                 break;
5747         default:
5748                 error(state, 0, "alignof not yet defined for type\n");
5749                 break;
5750         }
5751         return align;
5752 }
5753
5754 static size_t reg_align_of(struct compile_state *state, struct type *type)
5755 {
5756         size_t align;
5757         align = 0;
5758         switch(type->type & TYPE_MASK) {
5759         case TYPE_VOID:
5760                 align = 1;
5761                 break;
5762         case TYPE_BITFIELD:
5763                 align = 1;
5764                 break;
5765         case TYPE_CHAR:
5766         case TYPE_UCHAR:
5767                 align = REG_ALIGNOF_CHAR;
5768                 break;
5769         case TYPE_SHORT:
5770         case TYPE_USHORT:
5771                 align = REG_ALIGNOF_SHORT;
5772                 break;
5773         case TYPE_INT:
5774         case TYPE_UINT:
5775         case TYPE_ENUM:
5776                 align = REG_ALIGNOF_INT;
5777                 break;
5778         case TYPE_LONG:
5779         case TYPE_ULONG:
5780                 align = REG_ALIGNOF_LONG;
5781                 break;
5782         case TYPE_POINTER:
5783                 align = REG_ALIGNOF_POINTER;
5784                 break;
5785         case TYPE_PRODUCT:
5786         case TYPE_OVERLAP:
5787         {
5788                 size_t left_align, right_align;
5789                 left_align  = reg_align_of(state, type->left);
5790                 right_align = reg_align_of(state, type->right);
5791                 align = (left_align >= right_align) ? left_align : right_align;
5792                 break;
5793         }
5794         case TYPE_ARRAY:
5795                 align = reg_align_of(state, type->left);
5796                 break;
5797         case TYPE_STRUCT:
5798         case TYPE_UNION:
5799         case TYPE_TUPLE:
5800         case TYPE_JOIN:
5801                 align = reg_align_of(state, type->left);
5802                 break;
5803         default:
5804                 error(state, 0, "alignof not yet defined for type\n");
5805                 break;
5806         }
5807         return align;
5808 }
5809
5810 static size_t align_of_in_bytes(struct compile_state *state, struct type *type)
5811 {
5812         return bits_to_bytes(align_of(state, type));
5813 }
5814 static size_t size_of(struct compile_state *state, struct type *type);
5815 static size_t reg_size_of(struct compile_state *state, struct type *type);
5816
5817 static size_t needed_padding(struct compile_state *state, 
5818         struct type *type, size_t offset)
5819 {
5820         size_t padding, align;
5821         align = align_of(state, type);
5822         /* Align to the next machine word if the bitfield does completely
5823          * fit into the current word.
5824          */
5825         if ((type->type & TYPE_MASK) == TYPE_BITFIELD) {
5826                 size_t size;
5827                 size = size_of(state, type);
5828                 if ((offset + type->elements)/size != offset/size) {
5829                         align = size;
5830                 }
5831         }
5832         padding = 0;
5833         if (offset % align) {
5834                 padding = align - (offset % align);
5835         }
5836         return padding;
5837 }
5838
5839 static size_t reg_needed_padding(struct compile_state *state, 
5840         struct type *type, size_t offset)
5841 {
5842         size_t padding, align;
5843         align = reg_align_of(state, type);
5844         /* Align to the next register word if the bitfield does completely
5845          * fit into the current register.
5846          */
5847         if (((type->type & TYPE_MASK) == TYPE_BITFIELD) &&
5848                 (((offset + type->elements)/REG_SIZEOF_REG) != (offset/REG_SIZEOF_REG))) 
5849         {
5850                 align = REG_SIZEOF_REG;
5851         }
5852         padding = 0;
5853         if (offset % align) {
5854                 padding = align - (offset % align);
5855         }
5856         return padding;
5857 }
5858
5859 static size_t size_of(struct compile_state *state, struct type *type)
5860 {
5861         size_t size;
5862         size = 0;
5863         switch(type->type & TYPE_MASK) {
5864         case TYPE_VOID:
5865                 size = 0;
5866                 break;
5867         case TYPE_BITFIELD:
5868                 size = type->elements;
5869                 break;
5870         case TYPE_CHAR:
5871         case TYPE_UCHAR:
5872                 size = SIZEOF_CHAR;
5873                 break;
5874         case TYPE_SHORT:
5875         case TYPE_USHORT:
5876                 size = SIZEOF_SHORT;
5877                 break;
5878         case TYPE_INT:
5879         case TYPE_UINT:
5880         case TYPE_ENUM:
5881                 size = SIZEOF_INT;
5882                 break;
5883         case TYPE_LONG:
5884         case TYPE_ULONG:
5885                 size = SIZEOF_LONG;
5886                 break;
5887         case TYPE_POINTER:
5888                 size = SIZEOF_POINTER;
5889                 break;
5890         case TYPE_PRODUCT:
5891         {
5892                 size_t pad;
5893                 size = 0;
5894                 while((type->type & TYPE_MASK) == TYPE_PRODUCT) {
5895                         pad = needed_padding(state, type->left, size);
5896                         size = size + pad + size_of(state, type->left);
5897                         type = type->right;
5898                 }
5899                 pad = needed_padding(state, type, size);
5900                 size = size + pad + size_of(state, type);
5901                 break;
5902         }
5903         case TYPE_OVERLAP:
5904         {
5905                 size_t size_left, size_right;
5906                 size_left = size_of(state, type->left);
5907                 size_right = size_of(state, type->right);
5908                 size = (size_left >= size_right)? size_left : size_right;
5909                 break;
5910         }
5911         case TYPE_ARRAY:
5912                 if (type->elements == ELEMENT_COUNT_UNSPECIFIED) {
5913                         internal_error(state, 0, "Invalid array type");
5914                 } else {
5915                         size = size_of(state, type->left) * type->elements;
5916                 }
5917                 break;
5918         case TYPE_STRUCT:
5919         case TYPE_TUPLE:
5920         {
5921                 size_t pad;
5922                 size = size_of(state, type->left);
5923                 /* Pad structures so their size is a multiples of their alignment */
5924                 pad = needed_padding(state, type, size);
5925                 size = size + pad;
5926                 break;
5927         }
5928         case TYPE_UNION:
5929         case TYPE_JOIN:
5930         {
5931                 size_t pad;
5932                 size = size_of(state, type->left);
5933                 /* Pad unions so their size is a multiple of their alignment */
5934                 pad = needed_padding(state, type, size);
5935                 size = size + pad;
5936                 break;
5937         }
5938         default:
5939                 internal_error(state, 0, "sizeof not yet defined for type");
5940                 break;
5941         }
5942         return size;
5943 }
5944
5945 static size_t reg_size_of(struct compile_state *state, struct type *type)
5946 {
5947         size_t size;
5948         size = 0;
5949         switch(type->type & TYPE_MASK) {
5950         case TYPE_VOID:
5951                 size = 0;
5952                 break;
5953         case TYPE_BITFIELD:
5954                 size = type->elements;
5955                 break;
5956         case TYPE_CHAR:
5957         case TYPE_UCHAR:
5958                 size = REG_SIZEOF_CHAR;
5959                 break;
5960         case TYPE_SHORT:
5961         case TYPE_USHORT:
5962                 size = REG_SIZEOF_SHORT;
5963                 break;
5964         case TYPE_INT:
5965         case TYPE_UINT:
5966         case TYPE_ENUM:
5967                 size = REG_SIZEOF_INT;
5968                 break;
5969         case TYPE_LONG:
5970         case TYPE_ULONG:
5971                 size = REG_SIZEOF_LONG;
5972                 break;
5973         case TYPE_POINTER:
5974                 size = REG_SIZEOF_POINTER;
5975                 break;
5976         case TYPE_PRODUCT:
5977         {
5978                 size_t pad;
5979                 size = 0;
5980                 while((type->type & TYPE_MASK) == TYPE_PRODUCT) {
5981                         pad = reg_needed_padding(state, type->left, size);
5982                         size = size + pad + reg_size_of(state, type->left);
5983                         type = type->right;
5984                 }
5985                 pad = reg_needed_padding(state, type, size);
5986                 size = size + pad + reg_size_of(state, type);
5987                 break;
5988         }
5989         case TYPE_OVERLAP:
5990         {
5991                 size_t size_left, size_right;
5992                 size_left  = reg_size_of(state, type->left);
5993                 size_right = reg_size_of(state, type->right);
5994                 size = (size_left >= size_right)? size_left : size_right;
5995                 break;
5996         }
5997         case TYPE_ARRAY:
5998                 if (type->elements == ELEMENT_COUNT_UNSPECIFIED) {
5999                         internal_error(state, 0, "Invalid array type");
6000                 } else {
6001                         size = reg_size_of(state, type->left) * type->elements;
6002                 }
6003                 break;
6004         case TYPE_STRUCT:
6005         case TYPE_TUPLE:
6006         {
6007                 size_t pad;
6008                 size = reg_size_of(state, type->left);
6009                 /* Pad structures so their size is a multiples of their alignment */
6010                 pad = reg_needed_padding(state, type, size);
6011                 size = size + pad;
6012                 break;
6013         }
6014         case TYPE_UNION:
6015         case TYPE_JOIN:
6016         {
6017                 size_t pad;
6018                 size = reg_size_of(state, type->left);
6019                 /* Pad unions so their size is a multiple of their alignment */
6020                 pad = reg_needed_padding(state, type, size);
6021                 size = size + pad;
6022                 break;
6023         }
6024         default:
6025                 internal_error(state, 0, "sizeof not yet defined for type");
6026                 break;
6027         }
6028         return size;
6029 }
6030
6031 static size_t registers_of(struct compile_state *state, struct type *type)
6032 {
6033         size_t registers;
6034         registers = reg_size_of(state, type);
6035         registers += REG_SIZEOF_REG - 1;
6036         registers /= REG_SIZEOF_REG;
6037         return registers;
6038 }
6039
6040 static size_t size_of_in_bytes(struct compile_state *state, struct type *type)
6041 {
6042         return bits_to_bytes(size_of(state, type));
6043 }
6044
6045 static size_t field_offset(struct compile_state *state, 
6046         struct type *type, struct hash_entry *field)
6047 {
6048         struct type *member;
6049         size_t size;
6050
6051         size = 0;
6052         member = 0;
6053         if ((type->type & TYPE_MASK) == TYPE_STRUCT) {
6054                 member = type->left;
6055                 while(member && ((member->type & TYPE_MASK) == TYPE_PRODUCT)) {
6056                         size += needed_padding(state, member->left, size);
6057                         if (member->left->field_ident == field) {
6058                                 member = member->left;
6059                                 break;
6060                         }
6061                         size += size_of(state, member->left);
6062                         member = member->right;
6063                 }
6064                 size += needed_padding(state, member, size);
6065         }
6066         else if ((type->type & TYPE_MASK) == TYPE_UNION) {
6067                 member = type->left;
6068                 while(member && ((member->type & TYPE_MASK) == TYPE_OVERLAP)) {
6069                         if (member->left->field_ident == field) {
6070                                 member = member->left;
6071                                 break;
6072                         }
6073                         member = member->right;
6074                 }
6075         }
6076         else {
6077                 internal_error(state, 0, "field_offset only works on structures and unions");
6078         }
6079
6080         if (!member || (member->field_ident != field)) {
6081                 error(state, 0, "member %s not present", field->name);
6082         }
6083         return size;
6084 }
6085
6086 static size_t field_reg_offset(struct compile_state *state, 
6087         struct type *type, struct hash_entry *field)
6088 {
6089         struct type *member;
6090         size_t size;
6091
6092         size = 0;
6093         member = 0;
6094         if ((type->type & TYPE_MASK) == TYPE_STRUCT) {
6095                 member = type->left;
6096                 while(member && ((member->type & TYPE_MASK) == TYPE_PRODUCT)) {
6097                         size += reg_needed_padding(state, member->left, size);
6098                         if (member->left->field_ident == field) {
6099                                 member = member->left;
6100                                 break;
6101                         }
6102                         size += reg_size_of(state, member->left);
6103                         member = member->right;
6104                 }
6105         }
6106         else if ((type->type & TYPE_MASK) == TYPE_UNION) {
6107                 member = type->left;
6108                 while(member && ((member->type & TYPE_MASK) == TYPE_OVERLAP)) {
6109                         if (member->left->field_ident == field) {
6110                                 member = member->left;
6111                                 break;
6112                         }
6113                         member = member->right;
6114                 }
6115         }
6116         else {
6117                 internal_error(state, 0, "field_reg_offset only works on structures and unions");
6118         }
6119
6120         size += reg_needed_padding(state, member, size);
6121         if (!member || (member->field_ident != field)) {
6122                 error(state, 0, "member %s not present", field->name);
6123         }
6124         return size;
6125 }
6126
6127 static struct type *field_type(struct compile_state *state, 
6128         struct type *type, struct hash_entry *field)
6129 {
6130         struct type *member;
6131
6132         member = 0;
6133         if ((type->type & TYPE_MASK) == TYPE_STRUCT) {
6134                 member = type->left;
6135                 while(member && ((member->type & TYPE_MASK) == TYPE_PRODUCT)) {
6136                         if (member->left->field_ident == field) {
6137                                 member = member->left;
6138                                 break;
6139                         }
6140                         member = member->right;
6141                 }
6142         }
6143         else if ((type->type & TYPE_MASK) == TYPE_UNION) {
6144                 member = type->left;
6145                 while(member && ((member->type & TYPE_MASK) == TYPE_OVERLAP)) {
6146                         if (member->left->field_ident == field) {
6147                                 member = member->left;
6148                                 break;
6149                         }
6150                         member = member->right;
6151                 }
6152         }
6153         else {
6154                 internal_error(state, 0, "field_type only works on structures and unions");
6155         }
6156         
6157         if (!member || (member->field_ident != field)) {
6158                 error(state, 0, "member %s not present", field->name);
6159         }
6160         return member;
6161 }
6162
6163 static size_t index_offset(struct compile_state *state, 
6164         struct type *type, ulong_t index)
6165 {
6166         struct type *member;
6167         size_t size;
6168         size = 0;
6169         if ((type->type & TYPE_MASK) == TYPE_ARRAY) {
6170                 size = size_of(state, type->left) * index;
6171         }
6172         else if ((type->type & TYPE_MASK) == TYPE_TUPLE) {
6173                 ulong_t i;
6174                 member = type->left;
6175                 i = 0;
6176                 while(member && ((member->type & TYPE_MASK) == TYPE_PRODUCT)) {
6177                         size += needed_padding(state, member->left, size);
6178                         if (i == index) {
6179                                 member = member->left;
6180                                 break;
6181                         }
6182                         size += size_of(state, member->left);
6183                         i++;
6184                         member = member->right;
6185                 }
6186                 size += needed_padding(state, member, size);
6187                 if (i != index) {
6188                         internal_error(state, 0, "Missing member index: %u", index);
6189                 }
6190         }
6191         else if ((type->type & TYPE_MASK) == TYPE_JOIN) {
6192                 ulong_t i;
6193                 size = 0;
6194                 member = type->left;
6195                 i = 0;
6196                 while(member && ((member->type & TYPE_MASK) == TYPE_OVERLAP)) {
6197                         if (i == index) {
6198                                 member = member->left;
6199                                 break;
6200                         }
6201                         i++;
6202                         member = member->right;
6203                 }
6204                 if (i != index) {
6205                         internal_error(state, 0, "Missing member index: %u", index);
6206                 }
6207         }
6208         else {
6209                 internal_error(state, 0, 
6210                         "request for index %u in something not an array, tuple or join",
6211                         index);
6212         }
6213         return size;
6214 }
6215
6216 static size_t index_reg_offset(struct compile_state *state, 
6217         struct type *type, ulong_t index)
6218 {
6219         struct type *member;
6220         size_t size;
6221         size = 0;
6222         if ((type->type & TYPE_MASK) == TYPE_ARRAY) {
6223                 size = reg_size_of(state, type->left) * index;
6224         }
6225         else if ((type->type & TYPE_MASK) == TYPE_TUPLE) {
6226                 ulong_t i;
6227                 member = type->left;
6228                 i = 0;
6229                 while(member && ((member->type & TYPE_MASK) == TYPE_PRODUCT)) {
6230                         size += reg_needed_padding(state, member->left, size);
6231                         if (i == index) {
6232                                 member = member->left;
6233                                 break;
6234                         }
6235                         size += reg_size_of(state, member->left);
6236                         i++;
6237                         member = member->right;
6238                 }
6239                 size += reg_needed_padding(state, member, size);
6240                 if (i != index) {
6241                         internal_error(state, 0, "Missing member index: %u", index);
6242                 }
6243                 
6244         }
6245         else if ((type->type & TYPE_MASK) == TYPE_JOIN) {
6246                 ulong_t i;
6247                 size = 0;
6248                 member = type->left;
6249                 i = 0;
6250                 while(member && ((member->type & TYPE_MASK) == TYPE_OVERLAP)) {
6251                         if (i == index) {
6252                                 member = member->left;
6253                                 break;
6254                         }
6255                         i++;
6256                         member = member->right;
6257                 }
6258                 if (i != index) {
6259                         internal_error(state, 0, "Missing member index: %u", index);
6260                 }
6261         }
6262         else {
6263                 internal_error(state, 0, 
6264                         "request for index %u in something not an array, tuple or join",
6265                         index);
6266         }
6267         return size;
6268 }
6269
6270 static struct type *index_type(struct compile_state *state,
6271         struct type *type, ulong_t index)
6272 {
6273         struct type *member;
6274         if (index >= type->elements) {
6275                 internal_error(state, 0, "Invalid element %u requested", index);
6276         }
6277         if ((type->type & TYPE_MASK) == TYPE_ARRAY) {
6278                 member = type->left;
6279         }
6280         else if ((type->type & TYPE_MASK) == TYPE_TUPLE) {
6281                 ulong_t i;
6282                 member = type->left;
6283                 i = 0;
6284                 while(member && ((member->type & TYPE_MASK) == TYPE_PRODUCT)) {
6285                         if (i == index) {
6286                                 member = member->left;
6287                                 break;
6288                         }
6289                         i++;
6290                         member = member->right;
6291                 }
6292                 if (i != index) {
6293                         internal_error(state, 0, "Missing member index: %u", index);
6294                 }
6295         }
6296         else if ((type->type & TYPE_MASK) == TYPE_JOIN) {
6297                 ulong_t i;
6298                 member = type->left;
6299                 i = 0;
6300                 while(member && ((member->type & TYPE_MASK) == TYPE_OVERLAP)) {
6301                         if (i == index) {
6302                                 member = member->left;
6303                                 break;
6304                         }
6305                         i++;
6306                         member = member->right;
6307                 }
6308                 if (i != index) {
6309                         internal_error(state, 0, "Missing member index: %u", index);
6310                 }
6311         }
6312         else {
6313                 member = 0;
6314                 internal_error(state, 0, 
6315                         "request for index %u in something not an array, tuple or join",
6316                         index);
6317         }
6318         return member;
6319 }
6320
6321 static struct type *unpack_type(struct compile_state *state, struct type *type)
6322 {
6323         /* If I have a single register compound type not a bit-field
6324          * find the real type.
6325          */
6326         struct type *start_type;
6327         size_t size;
6328         /* Get out early if I need multiple registers for this type */
6329         size = reg_size_of(state, type);
6330         if (size > REG_SIZEOF_REG) {
6331                 return type;
6332         }
6333         /* Get out early if I don't need any registers for this type */
6334         if (size == 0) {
6335                 return &void_type;
6336         }
6337         /* Loop until I have no more layers I can remove */
6338         do {
6339                 start_type = type;
6340                 switch(type->type & TYPE_MASK) {
6341                 case TYPE_ARRAY:
6342                         /* If I have a single element the unpacked type
6343                          * is that element.
6344                          */
6345                         if (type->elements == 1) {
6346                                 type = type->left;
6347                         }
6348                         break;
6349                 case TYPE_STRUCT:
6350                 case TYPE_TUPLE:
6351                         /* If I have a single element the unpacked type
6352                          * is that element.
6353                          */
6354                         if (type->elements == 1) {
6355                                 type = type->left;
6356                         }
6357                         /* If I have multiple elements the unpacked
6358                          * type is the non-void element.
6359                          */
6360                         else {
6361                                 struct type *next, *member;
6362                                 struct type *sub_type;
6363                                 sub_type = 0;
6364                                 next = type->left;
6365                                 while(next) {
6366                                         member = next;
6367                                         next = 0;
6368                                         if ((member->type & TYPE_MASK) == TYPE_PRODUCT) {
6369                                                 next = member->right;
6370                                                 member = member->left;
6371                                         }
6372                                         if (reg_size_of(state, member) > 0) {
6373                                                 if (sub_type) {
6374                                                         internal_error(state, 0, "true compound type in a register");
6375                                                 }
6376                                                 sub_type = member;
6377                                         }
6378                                 }
6379                                 if (sub_type) {
6380                                         type = sub_type;
6381                                 }
6382                         }
6383                         break;
6384
6385                 case TYPE_UNION:
6386                 case TYPE_JOIN:
6387                         /* If I have a single element the unpacked type
6388                          * is that element.
6389                          */
6390                         if (type->elements == 1) {
6391                                 type = type->left;
6392                         }
6393                         /* I can't in general unpack union types */
6394                         break;
6395                 default:
6396                         /* If I'm not a compound type I can't unpack it */
6397                         break;
6398                 }
6399         } while(start_type != type);
6400         switch(type->type & TYPE_MASK) {
6401         case TYPE_STRUCT:
6402         case TYPE_ARRAY:
6403         case TYPE_TUPLE:
6404                 internal_error(state, 0, "irredicible type?");
6405                 break;
6406         }
6407         return type;
6408 }
6409
6410 static int equiv_types(struct type *left, struct type *right);
6411 static int is_compound_type(struct type *type);
6412
6413 static struct type *reg_type(
6414         struct compile_state *state, struct type *type, int reg_offset)
6415 {
6416         struct type *member;
6417         size_t size;
6418 #if 1
6419         struct type *invalid;
6420         invalid = invalid_type(state, type);
6421         if (invalid) {
6422                 fprintf(state->errout, "type: ");
6423                 name_of(state->errout, type);
6424                 fprintf(state->errout, "\n");
6425                 fprintf(state->errout, "invalid: ");
6426                 name_of(state->errout, invalid);
6427                 fprintf(state->errout, "\n");
6428                 internal_error(state, 0, "bad input type?");
6429         }
6430 #endif
6431
6432         size = reg_size_of(state, type);
6433         if (reg_offset > size) {
6434                 member = 0;
6435                 fprintf(state->errout, "type: ");
6436                 name_of(state->errout, type);
6437                 fprintf(state->errout, "\n");
6438                 internal_error(state, 0, "offset outside of type");
6439         }
6440         else {
6441                 switch(type->type & TYPE_MASK) {
6442                         /* Don't do anything with the basic types */
6443                 case TYPE_VOID:
6444                 case TYPE_CHAR:         case TYPE_UCHAR:
6445                 case TYPE_SHORT:        case TYPE_USHORT:
6446                 case TYPE_INT:          case TYPE_UINT:
6447                 case TYPE_LONG:         case TYPE_ULONG:
6448                 case TYPE_LLONG:        case TYPE_ULLONG:
6449                 case TYPE_FLOAT:        case TYPE_DOUBLE:
6450                 case TYPE_LDOUBLE:
6451                 case TYPE_POINTER:
6452                 case TYPE_ENUM:
6453                 case TYPE_BITFIELD:
6454                         member = type;
6455                         break;
6456                 case TYPE_ARRAY:
6457                         member = type->left;
6458                         size = reg_size_of(state, member);
6459                         if (size > REG_SIZEOF_REG) {
6460                                 member = reg_type(state, member, reg_offset % size);
6461                         }
6462                         break;
6463                 case TYPE_STRUCT:
6464                 case TYPE_TUPLE:
6465                 {
6466                         size_t offset;
6467                         offset = 0;
6468                         member = type->left;
6469                         while(member && ((member->type & TYPE_MASK) == TYPE_PRODUCT)) {
6470                                 size = reg_size_of(state, member->left);
6471                                 offset += reg_needed_padding(state, member->left, offset);
6472                                 if ((offset + size) > reg_offset) {
6473                                         member = member->left;
6474                                         break;
6475                                 }
6476                                 offset += size;
6477                                 member = member->right;
6478                         }
6479                         offset += reg_needed_padding(state, member, offset);
6480                         member = reg_type(state, member, reg_offset - offset);
6481                         break;
6482                 }
6483                 case TYPE_UNION:
6484                 case TYPE_JOIN:
6485                 {
6486                         struct type *join, **jnext, *mnext;
6487                         join = new_type(TYPE_JOIN, 0, 0);
6488                         jnext = &join->left;
6489                         mnext = type->left;
6490                         while(mnext) {
6491                                 size_t size;
6492                                 member = mnext;
6493                                 mnext = 0;
6494                                 if ((member->type & TYPE_MASK) == TYPE_OVERLAP) {
6495                                         mnext = member->right;
6496                                         member = member->left;
6497                                 }
6498                                 size = reg_size_of(state, member);
6499                                 if (size > reg_offset) {
6500                                         struct type *part, *hunt;
6501                                         part = reg_type(state, member, reg_offset);
6502                                         /* See if this type is already in the union */
6503                                         hunt = join->left;
6504                                         while(hunt) {
6505                                                 struct type *test = hunt;
6506                                                 hunt = 0;
6507                                                 if ((test->type & TYPE_MASK) == TYPE_OVERLAP) {
6508                                                         hunt = test->right;
6509                                                         test = test->left;
6510                                                 }
6511                                                 if (equiv_types(part, test)) {
6512                                                         goto next;
6513                                                 }
6514                                         }
6515                                         /* Nope add it */
6516                                         if (!*jnext) {
6517                                                 *jnext = part;
6518                                         } else {
6519                                                 *jnext = new_type(TYPE_OVERLAP, *jnext, part);
6520                                                 jnext = &(*jnext)->right;
6521                                         }
6522                                         join->elements++;
6523                                 }
6524                         next:
6525                                 ;
6526                         }
6527                         if (join->elements == 0) {
6528                                 internal_error(state, 0, "No elements?");
6529                         }
6530                         member = join;
6531                         break;
6532                 }
6533                 default:
6534                         member = 0;
6535                         fprintf(state->errout, "type: ");
6536                         name_of(state->errout, type);
6537                         fprintf(state->errout, "\n");
6538                         internal_error(state, 0, "reg_type not yet defined for type");
6539                         
6540                 }
6541         }
6542         /* If I have a single register compound type not a bit-field
6543          * find the real type.
6544          */
6545         member = unpack_type(state, member);
6546                 ;
6547         size  = reg_size_of(state, member);
6548         if (size > REG_SIZEOF_REG) {
6549                 internal_error(state, 0, "Cannot find type of single register");
6550         }
6551 #if 1
6552         invalid = invalid_type(state, member);
6553         if (invalid) {
6554                 fprintf(state->errout, "type: ");
6555                 name_of(state->errout, member);
6556                 fprintf(state->errout, "\n");
6557                 fprintf(state->errout, "invalid: ");
6558                 name_of(state->errout, invalid);
6559                 fprintf(state->errout, "\n");
6560                 internal_error(state, 0, "returning bad type?");
6561         }
6562 #endif
6563         return member;
6564 }
6565
6566 static struct type *next_field(struct compile_state *state,
6567         struct type *type, struct type *prev_member) 
6568 {
6569         struct type *member;
6570         if ((type->type & TYPE_MASK) != TYPE_STRUCT) {
6571                 internal_error(state, 0, "next_field only works on structures");
6572         }
6573         member = type->left;
6574         while((member->type & TYPE_MASK) == TYPE_PRODUCT) {
6575                 if (!prev_member) {
6576                         member = member->left;
6577                         break;
6578                 }
6579                 if (member->left == prev_member) {
6580                         prev_member = 0;
6581                 }
6582                 member = member->right;
6583         }
6584         if (member == prev_member) {
6585                 prev_member = 0;
6586         }
6587         if (prev_member) {
6588                 internal_error(state, 0, "prev_member %s not present", 
6589                         prev_member->field_ident->name);
6590         }
6591         return member;
6592 }
6593
6594 typedef void (*walk_type_fields_cb_t)(struct compile_state *state, struct type *type, 
6595         size_t ret_offset, size_t mem_offset, void *arg);
6596
6597 static void walk_type_fields(struct compile_state *state,
6598         struct type *type, size_t reg_offset, size_t mem_offset,
6599         walk_type_fields_cb_t cb, void *arg);
6600
6601 static void walk_struct_fields(struct compile_state *state,
6602         struct type *type, size_t reg_offset, size_t mem_offset,
6603         walk_type_fields_cb_t cb, void *arg)
6604 {
6605         struct type *tptr;
6606         ulong_t i;
6607         if ((type->type & TYPE_MASK) != TYPE_STRUCT) {
6608                 internal_error(state, 0, "walk_struct_fields only works on structures");
6609         }
6610         tptr = type->left;
6611         for(i = 0; i < type->elements; i++) {
6612                 struct type *mtype;
6613                 mtype = tptr;
6614                 if ((mtype->type & TYPE_MASK) == TYPE_PRODUCT) {
6615                         mtype = mtype->left;
6616                 }
6617                 walk_type_fields(state, mtype, 
6618                         reg_offset + 
6619                         field_reg_offset(state, type, mtype->field_ident),
6620                         mem_offset + 
6621                         field_offset(state, type, mtype->field_ident),
6622                         cb, arg);
6623                 tptr = tptr->right;
6624         }
6625         
6626 }
6627
6628 static void walk_type_fields(struct compile_state *state,
6629         struct type *type, size_t reg_offset, size_t mem_offset,
6630         walk_type_fields_cb_t cb, void *arg)
6631 {
6632         switch(type->type & TYPE_MASK) {
6633         case TYPE_STRUCT:
6634                 walk_struct_fields(state, type, reg_offset, mem_offset, cb, arg);
6635                 break;
6636         case TYPE_CHAR:
6637         case TYPE_UCHAR:
6638         case TYPE_SHORT:
6639         case TYPE_USHORT:
6640         case TYPE_INT:
6641         case TYPE_UINT:
6642         case TYPE_LONG:
6643         case TYPE_ULONG:
6644                 cb(state, type, reg_offset, mem_offset, arg);
6645                 break;
6646         case TYPE_VOID:
6647                 break;
6648         default:
6649                 internal_error(state, 0, "walk_type_fields not yet implemented for type");
6650         }
6651 }
6652
6653 static void arrays_complete(struct compile_state *state, struct type *type)
6654 {
6655         if ((type->type & TYPE_MASK) == TYPE_ARRAY) {
6656                 if (type->elements == ELEMENT_COUNT_UNSPECIFIED) {
6657                         error(state, 0, "array size not specified");
6658                 }
6659                 arrays_complete(state, type->left);
6660         }
6661 }
6662
6663 static unsigned int get_basic_type(struct type *type)
6664 {
6665         unsigned int basic;
6666         basic = type->type & TYPE_MASK;
6667         /* Convert enums to ints */
6668         if (basic == TYPE_ENUM) {
6669                 basic = TYPE_INT;
6670         }
6671         /* Convert bitfields to standard types */
6672         else if (basic == TYPE_BITFIELD) {
6673                 if (type->elements <= SIZEOF_CHAR) {
6674                         basic = TYPE_CHAR;
6675                 }
6676                 else if (type->elements <= SIZEOF_SHORT) {
6677                         basic = TYPE_SHORT;
6678                 }
6679                 else if (type->elements <= SIZEOF_INT) {
6680                         basic = TYPE_INT;
6681                 }
6682                 else if (type->elements <= SIZEOF_LONG) {
6683                         basic = TYPE_LONG;
6684                 }
6685                 if (!TYPE_SIGNED(type->left->type)) {
6686                         basic += 1;
6687                 }
6688         }
6689         return basic;
6690 }
6691
6692 static unsigned int do_integral_promotion(unsigned int type)
6693 {
6694         if (TYPE_INTEGER(type) && (TYPE_RANK(type) < TYPE_RANK(TYPE_INT))) {
6695                 type = TYPE_INT;
6696         }
6697         return type;
6698 }
6699
6700 static unsigned int do_arithmetic_conversion(
6701         unsigned int left, unsigned int right)
6702 {
6703         if ((left == TYPE_LDOUBLE) || (right == TYPE_LDOUBLE)) {
6704                 return TYPE_LDOUBLE;
6705         }
6706         else if ((left == TYPE_DOUBLE) || (right == TYPE_DOUBLE)) {
6707                 return TYPE_DOUBLE;
6708         }
6709         else if ((left == TYPE_FLOAT) || (right == TYPE_FLOAT)) {
6710                 return TYPE_FLOAT;
6711         }
6712         left = do_integral_promotion(left);
6713         right = do_integral_promotion(right);
6714         /* If both operands have the same size done */
6715         if (left == right) {
6716                 return left;
6717         }
6718         /* If both operands have the same signedness pick the larger */
6719         else if (!!TYPE_UNSIGNED(left) == !!TYPE_UNSIGNED(right)) {
6720                 return (TYPE_RANK(left) >= TYPE_RANK(right)) ? left : right;
6721         }
6722         /* If the signed type can hold everything use it */
6723         else if (TYPE_SIGNED(left) && (TYPE_RANK(left) > TYPE_RANK(right))) {
6724                 return left;
6725         }
6726         else if (TYPE_SIGNED(right) && (TYPE_RANK(right) > TYPE_RANK(left))) {
6727                 return right;
6728         }
6729         /* Convert to the unsigned type with the same rank as the signed type */
6730         else if (TYPE_SIGNED(left)) {
6731                 return TYPE_MKUNSIGNED(left);
6732         }
6733         else {
6734                 return TYPE_MKUNSIGNED(right);
6735         }
6736 }
6737
6738 /* see if two types are the same except for qualifiers */
6739 static int equiv_types(struct type *left, struct type *right)
6740 {
6741         unsigned int type;
6742         /* Error if the basic types do not match */
6743         if ((left->type & TYPE_MASK) != (right->type & TYPE_MASK)) {
6744                 return 0;
6745         }
6746         type = left->type & TYPE_MASK;
6747         /* If the basic types match and it is a void type we are done */
6748         if (type == TYPE_VOID) {
6749                 return 1;
6750         }
6751         /* For bitfields we need to compare the sizes */
6752         else if (type == TYPE_BITFIELD) {
6753                 return (left->elements == right->elements) &&
6754                         (TYPE_SIGNED(left->left->type) == TYPE_SIGNED(right->left->type));
6755         }
6756         /* if the basic types match and it is an arithmetic type we are done */
6757         else if (TYPE_ARITHMETIC(type)) {
6758                 return 1;
6759         }
6760         /* If it is a pointer type recurse and keep testing */
6761         else if (type == TYPE_POINTER) {
6762                 return equiv_types(left->left, right->left);
6763         }
6764         else if (type == TYPE_ARRAY) {
6765                 return (left->elements == right->elements) &&
6766                         equiv_types(left->left, right->left);
6767         }
6768         /* test for struct equality */
6769         else if (type == TYPE_STRUCT) {
6770                 return left->type_ident == right->type_ident;
6771         }
6772         /* test for union equality */
6773         else if (type == TYPE_UNION) {
6774                 return left->type_ident == right->type_ident;
6775         }
6776         /* Test for equivalent functions */
6777         else if (type == TYPE_FUNCTION) {
6778                 return equiv_types(left->left, right->left) &&
6779                         equiv_types(left->right, right->right);
6780         }
6781         /* We only see TYPE_PRODUCT as part of function equivalence matching */
6782         /* We also see TYPE_PRODUCT as part of of tuple equivalence matchin */
6783         else if (type == TYPE_PRODUCT) {
6784                 return equiv_types(left->left, right->left) &&
6785                         equiv_types(left->right, right->right);
6786         }
6787         /* We should see TYPE_OVERLAP when comparing joins */
6788         else if (type == TYPE_OVERLAP) {
6789                 return equiv_types(left->left, right->left) &&
6790                         equiv_types(left->right, right->right);
6791         }
6792         /* Test for equivalence of tuples */
6793         else if (type == TYPE_TUPLE) {
6794                 return (left->elements == right->elements) &&
6795                         equiv_types(left->left, right->left);
6796         }
6797         /* Test for equivalence of joins */
6798         else if (type == TYPE_JOIN) {
6799                 return (left->elements == right->elements) &&
6800                         equiv_types(left->left, right->left);
6801         }
6802         else {
6803                 return 0;
6804         }
6805 }
6806
6807 static int equiv_ptrs(struct type *left, struct type *right)
6808 {
6809         if (((left->type & TYPE_MASK) != TYPE_POINTER) ||
6810                 ((right->type & TYPE_MASK) != TYPE_POINTER)) {
6811                 return 0;
6812         }
6813         return equiv_types(left->left, right->left);
6814 }
6815
6816 static struct type *compatible_types(struct type *left, struct type *right)
6817 {
6818         struct type *result;
6819         unsigned int type, qual_type;
6820         /* Error if the basic types do not match */
6821         if ((left->type & TYPE_MASK) != (right->type & TYPE_MASK)) {
6822                 return 0;
6823         }
6824         type = left->type & TYPE_MASK;
6825         qual_type = (left->type & ~STOR_MASK) | (right->type & ~STOR_MASK);
6826         result = 0;
6827         /* if the basic types match and it is an arithmetic type we are done */
6828         if (TYPE_ARITHMETIC(type)) {
6829                 result = new_type(qual_type, 0, 0);
6830         }
6831         /* If it is a pointer type recurse and keep testing */
6832         else if (type == TYPE_POINTER) {
6833                 result = compatible_types(left->left, right->left);
6834                 if (result) {
6835                         result = new_type(qual_type, result, 0);
6836                 }
6837         }
6838         /* test for struct equality */
6839         else if (type == TYPE_STRUCT) {
6840                 if (left->type_ident == right->type_ident) {
6841                         result = left;
6842                 }
6843         }
6844         /* test for union equality */
6845         else if (type == TYPE_UNION) {
6846                 if (left->type_ident == right->type_ident) {
6847                         result = left;
6848                 }
6849         }
6850         /* Test for equivalent functions */
6851         else if (type == TYPE_FUNCTION) {
6852                 struct type *lf, *rf;
6853                 lf = compatible_types(left->left, right->left);
6854                 rf = compatible_types(left->right, right->right);
6855                 if (lf && rf) {
6856                         result = new_type(qual_type, lf, rf);
6857                 }
6858         }
6859         /* We only see TYPE_PRODUCT as part of function equivalence matching */
6860         else if (type == TYPE_PRODUCT) {
6861                 struct type *lf, *rf;
6862                 lf = compatible_types(left->left, right->left);
6863                 rf = compatible_types(left->right, right->right);
6864                 if (lf && rf) {
6865                         result = new_type(qual_type, lf, rf);
6866                 }
6867         }
6868         else {
6869                 /* Nothing else is compatible */
6870         }
6871         return result;
6872 }
6873
6874 /* See if left is a equivalent to right or right is a union member of left */
6875 static int is_subset_type(struct type *left, struct type *right)
6876 {
6877         if (equiv_types(left, right)) {
6878                 return 1;
6879         }
6880         if ((left->type & TYPE_MASK) == TYPE_JOIN) {
6881                 struct type *member, *mnext;
6882                 mnext = left->left;
6883                 while(mnext) {
6884                         member = mnext;
6885                         mnext = 0;
6886                         if ((member->type & TYPE_MASK) == TYPE_OVERLAP) {
6887                                 mnext = member->right;
6888                                 member = member->left;
6889                         }
6890                         if (is_subset_type( member, right)) {
6891                                 return 1;
6892                         }
6893                 }
6894         }
6895         return 0;
6896 }
6897
6898 static struct type *compatible_ptrs(struct type *left, struct type *right)
6899 {
6900         struct type *result;
6901         if (((left->type & TYPE_MASK) != TYPE_POINTER) ||
6902                 ((right->type & TYPE_MASK) != TYPE_POINTER)) {
6903                 return 0;
6904         }
6905         result = compatible_types(left->left, right->left);
6906         if (result) {
6907                 unsigned int qual_type;
6908                 qual_type = (left->type & ~STOR_MASK) | (right->type & ~STOR_MASK);
6909                 result = new_type(qual_type, result, 0);
6910         }
6911         return result;
6912         
6913 }
6914 static struct triple *integral_promotion(
6915         struct compile_state *state, struct triple *def)
6916 {
6917         struct type *type;
6918         type = def->type;
6919         /* As all operations are carried out in registers
6920          * the values are converted on load I just convert
6921          * logical type of the operand.
6922          */
6923         if (TYPE_INTEGER(type->type)) {
6924                 unsigned int int_type;
6925                 int_type = type->type & ~TYPE_MASK;
6926                 int_type |= do_integral_promotion(get_basic_type(type));
6927                 if (int_type != type->type) {
6928                         if (def->op != OP_LOAD) {
6929                                 def->type = new_type(int_type, 0, 0);
6930                         }
6931                         else {
6932                                 def = triple(state, OP_CONVERT, 
6933                                         new_type(int_type, 0, 0), def, 0);
6934                         }
6935                 }
6936         }
6937         return def;
6938 }
6939
6940
6941 static void arithmetic(struct compile_state *state, struct triple *def)
6942 {
6943         if (!TYPE_ARITHMETIC(def->type->type)) {
6944                 error(state, 0, "arithmetic type expexted");
6945         }
6946 }
6947
6948 static void ptr_arithmetic(struct compile_state *state, struct triple *def)
6949 {
6950         if (!TYPE_PTR(def->type->type) && !TYPE_ARITHMETIC(def->type->type)) {
6951                 error(state, def, "pointer or arithmetic type expected");
6952         }
6953 }
6954
6955 static int is_integral(struct triple *ins)
6956 {
6957         return TYPE_INTEGER(ins->type->type);
6958 }
6959
6960 static void integral(struct compile_state *state, struct triple *def)
6961 {
6962         if (!is_integral(def)) {
6963                 error(state, 0, "integral type expected");
6964         }
6965 }
6966
6967
6968 static void bool(struct compile_state *state, struct triple *def)
6969 {
6970         if (!TYPE_ARITHMETIC(def->type->type) &&
6971                 ((def->type->type & TYPE_MASK) != TYPE_POINTER)) {
6972                 error(state, 0, "arithmetic or pointer type expected");
6973         }
6974 }
6975
6976 static int is_signed(struct type *type)
6977 {
6978         if ((type->type & TYPE_MASK) == TYPE_BITFIELD) {
6979                 type = type->left;
6980         }
6981         return !!TYPE_SIGNED(type->type);
6982 }
6983 static int is_compound_type(struct type *type)
6984 {
6985         int is_compound;
6986         switch((type->type & TYPE_MASK)) {
6987         case TYPE_ARRAY:
6988         case TYPE_STRUCT:
6989         case TYPE_TUPLE:
6990         case TYPE_UNION:
6991         case TYPE_JOIN: 
6992                 is_compound = 1;
6993                 break;
6994         default:
6995                 is_compound = 0;
6996                 break;
6997         }
6998         return is_compound;
6999 }
7000
7001 /* Is this value located in a register otherwise it must be in memory */
7002 static int is_in_reg(struct compile_state *state, struct triple *def)
7003 {
7004         int in_reg;
7005         if (def->op == OP_ADECL) {
7006                 in_reg = 1;
7007         }
7008         else if ((def->op == OP_SDECL) || (def->op == OP_DEREF)) {
7009                 in_reg = 0;
7010         }
7011         else if (triple_is_part(state, def)) {
7012                 in_reg = is_in_reg(state, MISC(def, 0));
7013         }
7014         else {
7015                 internal_error(state, def, "unknown expr storage location");
7016                 in_reg = -1;
7017         }
7018         return in_reg;
7019 }
7020
7021 /* Is this an auto or static variable location? Something that can
7022  * be assigned to.  Otherwise it must must be a pure value, a temporary.
7023  */
7024 static int is_lvalue(struct compile_state *state, struct triple *def)
7025 {
7026         int ret;
7027         ret = 0;
7028         if (!def) {
7029                 return 0;
7030         }
7031         if ((def->op == OP_ADECL) || 
7032                 (def->op == OP_SDECL) || 
7033                 (def->op == OP_DEREF) ||
7034                 (def->op == OP_BLOBCONST) ||
7035                 (def->op == OP_LIST)) {
7036                 ret = 1;
7037         }
7038         else if (triple_is_part(state, def)) {
7039                 ret = is_lvalue(state, MISC(def, 0));
7040         }
7041         return ret;
7042 }
7043
7044 static void clvalue(struct compile_state *state, struct triple *def)
7045 {
7046         if (!def) {
7047                 internal_error(state, def, "nothing where lvalue expected?");
7048         }
7049         if (!is_lvalue(state, def)) { 
7050                 error(state, def, "lvalue expected");
7051         }
7052 }
7053 static void lvalue(struct compile_state *state, struct triple *def)
7054 {
7055         clvalue(state, def);
7056         if (def->type->type & QUAL_CONST) {
7057                 error(state, def, "modifable lvalue expected");
7058         }
7059 }
7060
7061 static int is_pointer(struct triple *def)
7062 {
7063         return (def->type->type & TYPE_MASK) == TYPE_POINTER;
7064 }
7065
7066 static void pointer(struct compile_state *state, struct triple *def)
7067 {
7068         if (!is_pointer(def)) {
7069                 error(state, def, "pointer expected");
7070         }
7071 }
7072
7073 static struct triple *int_const(
7074         struct compile_state *state, struct type *type, ulong_t value)
7075 {
7076         struct triple *result;
7077         switch(type->type & TYPE_MASK) {
7078         case TYPE_CHAR:
7079         case TYPE_INT:   case TYPE_UINT:
7080         case TYPE_LONG:  case TYPE_ULONG:
7081                 break;
7082         default:
7083                 internal_error(state, 0, "constant for unknown type");
7084         }
7085         result = triple(state, OP_INTCONST, type, 0, 0);
7086         result->u.cval = value;
7087         return result;
7088 }
7089
7090
7091 static struct triple *read_expr(struct compile_state *state, struct triple *def);
7092
7093 static struct triple *do_mk_addr_expr(struct compile_state *state, 
7094         struct triple *expr, struct type *type, ulong_t offset)
7095 {
7096         struct triple *result;
7097         struct type *ptr_type;
7098         clvalue(state, expr);
7099
7100         ptr_type = new_type(TYPE_POINTER | (type->type & QUAL_MASK), type, 0);
7101
7102         
7103         result = 0;
7104         if (expr->op == OP_ADECL) {
7105                 error(state, expr, "address of auto variables not supported");
7106         }
7107         else if (expr->op == OP_SDECL) {
7108                 result = triple(state, OP_ADDRCONST, ptr_type, 0, 0);
7109                 MISC(result, 0) = expr;
7110                 result->u.cval = offset;
7111         }
7112         else if (expr->op == OP_DEREF) {
7113                 result = triple(state, OP_ADD, ptr_type,
7114                         RHS(expr, 0),
7115                         int_const(state, &ulong_type, offset));
7116         }
7117         else if (expr->op == OP_BLOBCONST) {
7118                 FINISHME();
7119                 internal_error(state, expr, "not yet implemented");
7120         }
7121         else if (expr->op == OP_LIST) {
7122                 error(state, 0, "Function addresses not supported");
7123         }
7124         else if (triple_is_part(state, expr)) {
7125                 struct triple *part;
7126                 part = expr;
7127                 expr = MISC(expr, 0);
7128                 if (part->op == OP_DOT) {
7129                         offset += bits_to_bytes(
7130                                 field_offset(state, expr->type, part->u.field));
7131                 }
7132                 else if (part->op == OP_INDEX) {
7133                         offset += bits_to_bytes(
7134                                 index_offset(state, expr->type, part->u.cval));
7135                 }
7136                 else {
7137                         internal_error(state, part, "unhandled part type");
7138                 }
7139                 result = do_mk_addr_expr(state, expr, type, offset);
7140         }
7141         if (!result) {
7142                 internal_error(state, expr, "cannot take address of expression");
7143         }
7144         return result;
7145 }
7146
7147 static struct triple *mk_addr_expr(
7148         struct compile_state *state, struct triple *expr, ulong_t offset)
7149 {
7150         return do_mk_addr_expr(state, expr, expr->type, offset);
7151 }
7152
7153 static struct triple *mk_deref_expr(
7154         struct compile_state *state, struct triple *expr)
7155 {
7156         struct type *base_type;
7157         pointer(state, expr);
7158         base_type = expr->type->left;
7159         return triple(state, OP_DEREF, base_type, expr, 0);
7160 }
7161
7162 /* lvalue conversions always apply except when certain operators
7163  * are applied.  So I apply apply it when I know no more
7164  * operators will be applied.
7165  */
7166 static struct triple *lvalue_conversion(struct compile_state *state, struct triple *def)
7167 {
7168         /* Tranform an array to a pointer to the first element */
7169         if ((def->type->type & TYPE_MASK) == TYPE_ARRAY) {
7170                 struct type *type;
7171                 type = new_type(
7172                         TYPE_POINTER | (def->type->type & QUAL_MASK),
7173                         def->type->left, 0);
7174                 if ((def->op == OP_SDECL) || IS_CONST_OP(def->op)) {
7175                         struct triple *addrconst;
7176                         if ((def->op != OP_SDECL) && (def->op != OP_BLOBCONST)) {
7177                                 internal_error(state, def, "bad array constant");
7178                         }
7179                         addrconst = triple(state, OP_ADDRCONST, type, 0, 0);
7180                         MISC(addrconst, 0) = def;
7181                         def = addrconst;
7182                 }
7183                 else {
7184                         def = triple(state, OP_CONVERT, type, def, 0);
7185                 }
7186         }
7187         /* Transform a function to a pointer to it */
7188         else if ((def->type->type & TYPE_MASK) == TYPE_FUNCTION) {
7189                 def = mk_addr_expr(state, def, 0);
7190         }
7191         return def;
7192 }
7193
7194 static struct triple *deref_field(
7195         struct compile_state *state, struct triple *expr, struct hash_entry *field)
7196 {
7197         struct triple *result;
7198         struct type *type, *member;
7199         ulong_t offset;
7200         if (!field) {
7201                 internal_error(state, 0, "No field passed to deref_field");
7202         }
7203         result = 0;
7204         type = expr->type;
7205         if (((type->type & TYPE_MASK) != TYPE_STRUCT) &&
7206                 ((type->type & TYPE_MASK) != TYPE_UNION)) {
7207                 error(state, 0, "request for member %s in something not a struct or union",
7208                         field->name);
7209         }
7210         member = field_type(state, type, field);
7211         if ((type->type & STOR_MASK) == STOR_PERM) {
7212                 /* Do the pointer arithmetic to get a deref the field */
7213                 offset = bits_to_bytes(field_offset(state, type, field));
7214                 result = do_mk_addr_expr(state, expr, member, offset);
7215                 result = mk_deref_expr(state, result);
7216         }
7217         else {
7218                 /* Find the variable for the field I want. */
7219                 result = triple(state, OP_DOT, member, expr, 0);
7220                 result->u.field = field;
7221         }
7222         return result;
7223 }
7224
7225 static struct triple *deref_index(
7226         struct compile_state *state, struct triple *expr, size_t index)
7227 {
7228         struct triple *result;
7229         struct type *type, *member;
7230         ulong_t offset;
7231
7232         result = 0;
7233         type = expr->type;
7234         member = index_type(state, type, index);
7235
7236         if ((type->type & STOR_MASK) == STOR_PERM) {
7237                 offset = bits_to_bytes(index_offset(state, type, index));
7238                 result = do_mk_addr_expr(state, expr, member, offset);
7239                 result = mk_deref_expr(state, result);
7240         }
7241         else {
7242                 result = triple(state, OP_INDEX, member, expr, 0);
7243                 result->u.cval = index;
7244         }
7245         return result;
7246 }
7247
7248 static struct triple *read_expr(struct compile_state *state, struct triple *def)
7249 {
7250         int op;
7251         if  (!def) {
7252                 return 0;
7253         }
7254 #warning "CHECK_ME is this the only place I need to do lvalue conversions?"
7255         /* Transform lvalues into something we can read */
7256         def = lvalue_conversion(state, def);
7257         if (!is_lvalue(state, def)) {
7258                 return def;
7259         }
7260         if (is_in_reg(state, def)) {
7261                 op = OP_READ;
7262         } else {
7263                 if (def->op == OP_SDECL) {
7264                         def = mk_addr_expr(state, def, 0);
7265                         def = mk_deref_expr(state, def);
7266                 }
7267                 op = OP_LOAD;
7268         }
7269         def = triple(state, op, def->type, def, 0);
7270         if (def->type->type & QUAL_VOLATILE) {
7271                 def->id |= TRIPLE_FLAG_VOLATILE;
7272         }
7273         return def;
7274 }
7275
7276 int is_write_compatible(struct compile_state *state, 
7277         struct type *dest, struct type *rval)
7278 {
7279         int compatible = 0;
7280         /* Both operands have arithmetic type */
7281         if (TYPE_ARITHMETIC(dest->type) && TYPE_ARITHMETIC(rval->type)) {
7282                 compatible = 1;
7283         }
7284         /* One operand is a pointer and the other is a pointer to void */
7285         else if (((dest->type & TYPE_MASK) == TYPE_POINTER) &&
7286                 ((rval->type & TYPE_MASK) == TYPE_POINTER) &&
7287                 (((dest->left->type & TYPE_MASK) == TYPE_VOID) ||
7288                         ((rval->left->type & TYPE_MASK) == TYPE_VOID))) {
7289                 compatible = 1;
7290         }
7291         /* If both types are the same without qualifiers we are good */
7292         else if (equiv_ptrs(dest, rval)) {
7293                 compatible = 1;
7294         }
7295         /* test for struct/union equality  */
7296         else if (equiv_types(dest, rval)) {
7297                 compatible = 1;
7298         }
7299         return compatible;
7300 }
7301
7302 static void write_compatible(struct compile_state *state,
7303         struct type *dest, struct type *rval)
7304 {
7305         if (!is_write_compatible(state, dest, rval)) {
7306                 FILE *fp = state->errout;
7307                 fprintf(fp, "dest: ");
7308                 name_of(fp, dest);
7309                 fprintf(fp,"\nrval: ");
7310                 name_of(fp, rval);
7311                 fprintf(fp, "\n");
7312                 error(state, 0, "Incompatible types in assignment");
7313         }
7314 }
7315
7316 static int is_init_compatible(struct compile_state *state,
7317         struct type *dest, struct type *rval)
7318 {
7319         int compatible = 0;
7320         if (is_write_compatible(state, dest, rval)) {
7321                 compatible = 1;
7322         }
7323         else if (equiv_types(dest, rval)) {
7324                 compatible = 1;
7325         }
7326         return compatible;
7327 }
7328
7329 static struct triple *write_expr(
7330         struct compile_state *state, struct triple *dest, struct triple *rval)
7331 {
7332         struct triple *def;
7333         int op;
7334
7335         def = 0;
7336         if (!rval) {
7337                 internal_error(state, 0, "missing rval");
7338         }
7339
7340         if (rval->op == OP_LIST) {
7341                 internal_error(state, 0, "expression of type OP_LIST?");
7342         }
7343         if (!is_lvalue(state, dest)) {
7344                 internal_error(state, 0, "writing to a non lvalue?");
7345         }
7346         if (dest->type->type & QUAL_CONST) {
7347                 internal_error(state, 0, "modifable lvalue expexted");
7348         }
7349
7350         write_compatible(state, dest->type, rval->type);
7351         if (!equiv_types(dest->type, rval->type)) {
7352                 rval = triple(state, OP_CONVERT, dest->type, rval, 0);
7353         }
7354
7355         /* Now figure out which assignment operator to use */
7356         op = -1;
7357         if (is_in_reg(state, dest)) {
7358                 def = triple(state, OP_WRITE, dest->type, rval, dest);
7359                 if (MISC(def, 0) != dest) {
7360                         internal_error(state, def, "huh?");
7361                 }
7362                 if (RHS(def, 0) != rval) {
7363                         internal_error(state, def, "huh?");
7364                 }
7365         } else {
7366                 def = triple(state, OP_STORE, dest->type, dest, rval);
7367         }
7368         if (def->type->type & QUAL_VOLATILE) {
7369                 def->id |= TRIPLE_FLAG_VOLATILE;
7370         }
7371         return def;
7372 }
7373
7374 static struct triple *init_expr(
7375         struct compile_state *state, struct triple *dest, struct triple *rval)
7376 {
7377         struct triple *def;
7378
7379         def = 0;
7380         if (!rval) {
7381                 internal_error(state, 0, "missing rval");
7382         }
7383         if ((dest->type->type & STOR_MASK) != STOR_PERM) {
7384                 rval = read_expr(state, rval);
7385                 def = write_expr(state, dest, rval);
7386         }
7387         else {
7388                 /* Fill in the array size if necessary */
7389                 if (((dest->type->type & TYPE_MASK) == TYPE_ARRAY) &&
7390                         ((rval->type->type & TYPE_MASK) == TYPE_ARRAY)) {
7391                         if (dest->type->elements == ELEMENT_COUNT_UNSPECIFIED) {
7392                                 dest->type->elements = rval->type->elements;
7393                         }
7394                 }
7395                 if (!equiv_types(dest->type, rval->type)) {
7396                         error(state, 0, "Incompatible types in inializer");
7397                 }
7398                 MISC(dest, 0) = rval;
7399                 insert_triple(state, dest, rval);
7400                 rval->id |= TRIPLE_FLAG_FLATTENED;
7401                 use_triple(MISC(dest, 0), dest);
7402         }
7403         return def;
7404 }
7405
7406 struct type *arithmetic_result(
7407         struct compile_state *state, struct triple *left, struct triple *right)
7408 {
7409         struct type *type;
7410         /* Sanity checks to ensure I am working with arithmetic types */
7411         arithmetic(state, left);
7412         arithmetic(state, right);
7413         type = new_type(
7414                 do_arithmetic_conversion(
7415                         get_basic_type(left->type),
7416                         get_basic_type(right->type)),
7417                 0, 0);
7418         return type;
7419 }
7420
7421 struct type *ptr_arithmetic_result(
7422         struct compile_state *state, struct triple *left, struct triple *right)
7423 {
7424         struct type *type;
7425         /* Sanity checks to ensure I am working with the proper types */
7426         ptr_arithmetic(state, left);
7427         arithmetic(state, right);
7428         if (TYPE_ARITHMETIC(left->type->type) && 
7429                 TYPE_ARITHMETIC(right->type->type)) {
7430                 type = arithmetic_result(state, left, right);
7431         }
7432         else if (TYPE_PTR(left->type->type)) {
7433                 type = left->type;
7434         }
7435         else {
7436                 internal_error(state, 0, "huh?");
7437                 type = 0;
7438         }
7439         return type;
7440 }
7441
7442 /* boolean helper function */
7443
7444 static struct triple *ltrue_expr(struct compile_state *state, 
7445         struct triple *expr)
7446 {
7447         switch(expr->op) {
7448         case OP_LTRUE:   case OP_LFALSE:  case OP_EQ:      case OP_NOTEQ:
7449         case OP_SLESS:   case OP_ULESS:   case OP_SMORE:   case OP_UMORE:
7450         case OP_SLESSEQ: case OP_ULESSEQ: case OP_SMOREEQ: case OP_UMOREEQ:
7451                 /* If the expression is already boolean do nothing */
7452                 break;
7453         default:
7454                 expr = triple(state, OP_LTRUE, &int_type, expr, 0);
7455                 break;
7456         }
7457         return expr;
7458 }
7459
7460 static struct triple *lfalse_expr(struct compile_state *state, 
7461         struct triple *expr)
7462 {
7463         return triple(state, OP_LFALSE, &int_type, expr, 0);
7464 }
7465
7466 static struct triple *mkland_expr(
7467         struct compile_state *state,
7468         struct triple *left, struct triple *right)
7469 {
7470         struct triple *def, *val, *var, *jmp, *mid, *end;
7471         struct triple *lstore, *rstore;
7472
7473         /* Generate some intermediate triples */
7474         end = label(state);
7475         var = variable(state, &int_type);
7476         
7477         /* Store the left hand side value */
7478         lstore = write_expr(state, var, left);
7479
7480         /* Jump if the value is false */
7481         jmp =  branch(state, end, 
7482                 lfalse_expr(state, read_expr(state, var)));
7483         mid = label(state);
7484         
7485         /* Store the right hand side value */
7486         rstore = write_expr(state, var, right);
7487
7488         /* An expression for the computed value */
7489         val = read_expr(state, var);
7490
7491         /* Generate the prog for a logical and */
7492         def = mkprog(state, var, lstore, jmp, mid, rstore, end, val, 0);
7493         
7494         return def;
7495 }
7496
7497 static struct triple *mklor_expr(
7498         struct compile_state *state,
7499         struct triple *left, struct triple *right)
7500 {
7501         struct triple *def, *val, *var, *jmp, *mid, *end;
7502
7503         /* Generate some intermediate triples */
7504         end = label(state);
7505         var = variable(state, &int_type);
7506         
7507         /* Store the left hand side value */
7508         left = write_expr(state, var, left);
7509         
7510         /* Jump if the value is true */
7511         jmp = branch(state, end, read_expr(state, var));
7512         mid = label(state);
7513         
7514         /* Store the right hand side value */
7515         right = write_expr(state, var, right);
7516                 
7517         /* An expression for the computed value*/
7518         val = read_expr(state, var);
7519
7520         /* Generate the prog for a logical or */
7521         def = mkprog(state, var, left, jmp, mid, right, end, val, 0);
7522
7523         return def;
7524 }
7525
7526 static struct triple *mkcond_expr(
7527         struct compile_state *state, 
7528         struct triple *test, struct triple *left, struct triple *right)
7529 {
7530         struct triple *def, *val, *var, *jmp1, *jmp2, *top, *mid, *end;
7531         struct type *result_type;
7532         unsigned int left_type, right_type;
7533         bool(state, test);
7534         left_type = left->type->type;
7535         right_type = right->type->type;
7536         result_type = 0;
7537         /* Both operands have arithmetic type */
7538         if (TYPE_ARITHMETIC(left_type) && TYPE_ARITHMETIC(right_type)) {
7539                 result_type = arithmetic_result(state, left, right);
7540         }
7541         /* Both operands have void type */
7542         else if (((left_type & TYPE_MASK) == TYPE_VOID) &&
7543                 ((right_type & TYPE_MASK) == TYPE_VOID)) {
7544                 result_type = &void_type;
7545         }
7546         /* pointers to the same type... */
7547         else if ((result_type = compatible_ptrs(left->type, right->type))) {
7548                 ;
7549         }
7550         /* Both operands are pointers and left is a pointer to void */
7551         else if (((left_type & TYPE_MASK) == TYPE_POINTER) &&
7552                 ((right_type & TYPE_MASK) == TYPE_POINTER) &&
7553                 ((left->type->left->type & TYPE_MASK) == TYPE_VOID)) {
7554                 result_type = right->type;
7555         }
7556         /* Both operands are pointers and right is a pointer to void */
7557         else if (((left_type & TYPE_MASK) == TYPE_POINTER) &&
7558                 ((right_type & TYPE_MASK) == TYPE_POINTER) &&
7559                 ((right->type->left->type & TYPE_MASK) == TYPE_VOID)) {
7560                 result_type = left->type;
7561         }
7562         if (!result_type) {
7563                 error(state, 0, "Incompatible types in conditional expression");
7564         }
7565         /* Generate some intermediate triples */
7566         mid = label(state);
7567         end = label(state);
7568         var = variable(state, result_type);
7569
7570         /* Branch if the test is false */
7571         jmp1 = branch(state, mid, lfalse_expr(state, read_expr(state, test)));
7572         top = label(state);
7573
7574         /* Store the left hand side value */
7575         left = write_expr(state, var, left);
7576
7577         /* Branch to the end */
7578         jmp2 = branch(state, end, 0);
7579
7580         /* Store the right hand side value */
7581         right = write_expr(state, var, right);
7582         
7583         /* An expression for the computed value */
7584         val = read_expr(state, var);
7585
7586         /* Generate the prog for a conditional expression */
7587         def = mkprog(state, var, jmp1, top, left, jmp2, mid, right, end, val, 0);
7588
7589         return def;
7590 }
7591
7592
7593 static int expr_depth(struct compile_state *state, struct triple *ins)
7594 {
7595 #warning "FIXME move optimal ordering of subexpressions into the optimizer"
7596         int count;
7597         count = 0;
7598         if (!ins || (ins->id & TRIPLE_FLAG_FLATTENED)) {
7599                 count = 0;
7600         }
7601         else if (ins->op == OP_DEREF) {
7602                 count = expr_depth(state, RHS(ins, 0)) - 1;
7603         }
7604         else if (ins->op == OP_VAL) {
7605                 count = expr_depth(state, RHS(ins, 0)) - 1;
7606         }
7607         else if (ins->op == OP_FCALL) {
7608                 /* Don't figure the depth of a call just guess it is huge */
7609                 count = 1000;
7610         }
7611         else {
7612                 struct triple **expr;
7613                 expr = triple_rhs(state, ins, 0);
7614                 for(;expr; expr = triple_rhs(state, ins, expr)) {
7615                         if (*expr) {
7616                                 int depth;
7617                                 depth = expr_depth(state, *expr);
7618                                 if (depth > count) {
7619                                         count = depth;
7620                                 }
7621                         }
7622                 }
7623         }
7624         return count + 1;
7625 }
7626
7627 static struct triple *flatten_generic(
7628         struct compile_state *state, struct triple *first, struct triple *ptr,
7629         int ignored)
7630 {
7631         struct rhs_vector {
7632                 int depth;
7633                 struct triple **ins;
7634         } vector[MAX_RHS];
7635         int i, rhs, lhs;
7636         /* Only operations with just a rhs and a lhs should come here */
7637         rhs = ptr->rhs;
7638         lhs = ptr->lhs;
7639         if (TRIPLE_SIZE(ptr) != lhs + rhs + ignored) {
7640                 internal_error(state, ptr, "unexpected args for: %d %s",
7641                         ptr->op, tops(ptr->op));
7642         }
7643         /* Find the depth of the rhs elements */
7644         for(i = 0; i < rhs; i++) {
7645                 vector[i].ins = &RHS(ptr, i);
7646                 vector[i].depth = expr_depth(state, *vector[i].ins);
7647         }
7648         /* Selection sort the rhs */
7649         for(i = 0; i < rhs; i++) {
7650                 int j, max = i;
7651                 for(j = i + 1; j < rhs; j++ ) {
7652                         if (vector[j].depth > vector[max].depth) {
7653                                 max = j;
7654                         }
7655                 }
7656                 if (max != i) {
7657                         struct rhs_vector tmp;
7658                         tmp = vector[i];
7659                         vector[i] = vector[max];
7660                         vector[max] = tmp;
7661                 }
7662         }
7663         /* Now flatten the rhs elements */
7664         for(i = 0; i < rhs; i++) {
7665                 *vector[i].ins = flatten(state, first, *vector[i].ins);
7666                 use_triple(*vector[i].ins, ptr);
7667         }
7668         if (lhs) {
7669                 insert_triple(state, first, ptr);
7670                 ptr->id |= TRIPLE_FLAG_FLATTENED;
7671                 ptr->id &= ~TRIPLE_FLAG_LOCAL;
7672                 
7673                 /* Now flatten the lhs elements */
7674                 for(i = 0; i < lhs; i++) {
7675                         struct triple **ins = &LHS(ptr, i);
7676                         *ins = flatten(state, first, *ins);
7677                         use_triple(*ins, ptr);
7678                 }
7679         }
7680         return ptr;
7681 }
7682
7683 static struct triple *flatten_prog(
7684         struct compile_state *state, struct triple *first, struct triple *ptr)
7685 {
7686         struct triple *head, *body, *val;
7687         head = RHS(ptr, 0);
7688         RHS(ptr, 0) = 0;
7689         val  = head->prev;
7690         body = head->next;
7691         release_triple(state, head);
7692         release_triple(state, ptr);
7693         val->next        = first;
7694         body->prev       = first->prev;
7695         body->prev->next = body;
7696         val->next->prev  = val;
7697
7698         if (triple_is_cbranch(state, body->prev) ||
7699                 triple_is_call(state, body->prev)) {
7700                 unuse_triple(first, body->prev);
7701                 use_triple(body, body->prev);
7702         }
7703         
7704         if (!(val->id & TRIPLE_FLAG_FLATTENED)) {
7705                 internal_error(state, val, "val not flattened?");
7706         }
7707
7708         return val;
7709 }
7710
7711
7712 static struct triple *flatten_part(
7713         struct compile_state *state, struct triple *first, struct triple *ptr)
7714 {
7715         if (!triple_is_part(state, ptr)) {
7716                 internal_error(state, ptr,  "not a part");
7717         }
7718         if (ptr->rhs || ptr->lhs || ptr->targ || (ptr->misc != 1)) {
7719                 internal_error(state, ptr, "unexpected args for: %d %s",
7720                         ptr->op, tops(ptr->op));
7721         }
7722         MISC(ptr, 0) = flatten(state, first, MISC(ptr, 0));
7723         use_triple(MISC(ptr, 0), ptr);
7724         return flatten_generic(state, first, ptr, 1);
7725 }
7726
7727 static struct triple *flatten(
7728         struct compile_state *state, struct triple *first, struct triple *ptr)
7729 {
7730         struct triple *orig_ptr;
7731         if (!ptr)
7732                 return 0;
7733         do {
7734                 orig_ptr = ptr;
7735                 /* Only flatten triples once */
7736                 if (ptr->id & TRIPLE_FLAG_FLATTENED) {
7737                         return ptr;
7738                 }
7739                 switch(ptr->op) {
7740                 case OP_VAL:
7741                         RHS(ptr, 0) = flatten(state, first, RHS(ptr, 0));
7742                         return MISC(ptr, 0);
7743                         break;
7744                 case OP_PROG:
7745                         ptr = flatten_prog(state, first, ptr);
7746                         break;
7747                 case OP_FCALL:
7748                         ptr = flatten_generic(state, first, ptr, 1);
7749                         insert_triple(state, first, ptr);
7750                         ptr->id |= TRIPLE_FLAG_FLATTENED;
7751                         ptr->id &= ~TRIPLE_FLAG_LOCAL;
7752                         if (ptr->next != ptr) {
7753                                 use_triple(ptr->next, ptr);
7754                         }
7755                         break;
7756                 case OP_READ:
7757                 case OP_LOAD:
7758                         RHS(ptr, 0) = flatten(state, first, RHS(ptr, 0));
7759                         use_triple(RHS(ptr, 0), ptr);
7760                         break;
7761                 case OP_WRITE:
7762                         ptr = flatten_generic(state, first, ptr, 1);
7763                         MISC(ptr, 0) = flatten(state, first, MISC(ptr, 0));
7764                         use_triple(MISC(ptr, 0), ptr);
7765                         break;
7766                 case OP_BRANCH:
7767                         use_triple(TARG(ptr, 0), ptr);
7768                         break;
7769                 case OP_CBRANCH:
7770                         RHS(ptr, 0) = flatten(state, first, RHS(ptr, 0));
7771                         use_triple(RHS(ptr, 0), ptr);
7772                         use_triple(TARG(ptr, 0), ptr);
7773                         insert_triple(state, first, ptr);
7774                         ptr->id |= TRIPLE_FLAG_FLATTENED;
7775                         ptr->id &= ~TRIPLE_FLAG_LOCAL;
7776                         if (ptr->next != ptr) {
7777                                 use_triple(ptr->next, ptr);
7778                         }
7779                         break;
7780                 case OP_CALL:
7781                         MISC(ptr, 0) = flatten(state, first, MISC(ptr, 0));
7782                         use_triple(MISC(ptr, 0), ptr);
7783                         use_triple(TARG(ptr, 0), ptr);
7784                         insert_triple(state, first, ptr);
7785                         ptr->id |= TRIPLE_FLAG_FLATTENED;
7786                         ptr->id &= ~TRIPLE_FLAG_LOCAL;
7787                         if (ptr->next != ptr) {
7788                                 use_triple(ptr->next, ptr);
7789                         }
7790                         break;
7791                 case OP_RET:
7792                         RHS(ptr, 0) = flatten(state, first, RHS(ptr, 0));
7793                         use_triple(RHS(ptr, 0), ptr);
7794                         break;
7795                 case OP_BLOBCONST:
7796                         insert_triple(state, state->global_pool, ptr);
7797                         ptr->id |= TRIPLE_FLAG_FLATTENED;
7798                         ptr->id &= ~TRIPLE_FLAG_LOCAL;
7799                         ptr = triple(state, OP_SDECL, ptr->type, ptr, 0);
7800                         use_triple(MISC(ptr, 0), ptr);
7801                         break;
7802                 case OP_DEREF:
7803                         /* Since OP_DEREF is just a marker delete it when I flatten it */
7804                         ptr = RHS(ptr, 0);
7805                         RHS(orig_ptr, 0) = 0;
7806                         free_triple(state, orig_ptr);
7807                         break;
7808                 case OP_DOT:
7809                         if (RHS(ptr, 0)->op == OP_DEREF) {
7810                                 struct triple *base, *left;
7811                                 ulong_t offset;
7812                                 base = MISC(ptr, 0);
7813                                 offset = bits_to_bytes(field_offset(state, base->type, ptr->u.field));
7814                                 left = RHS(base, 0);
7815                                 ptr = triple(state, OP_ADD, left->type, 
7816                                         read_expr(state, left),
7817                                         int_const(state, &ulong_type, offset));
7818                                 free_triple(state, base);
7819                         }
7820                         else {
7821                                 ptr = flatten_part(state, first, ptr);
7822                         }
7823                         break;
7824                 case OP_INDEX:
7825                         if (RHS(ptr, 0)->op == OP_DEREF) {
7826                                 struct triple *base, *left;
7827                                 ulong_t offset;
7828                                 base = MISC(ptr, 0);
7829                                 offset = bits_to_bytes(index_offset(state, base->type, ptr->u.cval));
7830                                 left = RHS(base, 0);
7831                                 ptr = triple(state, OP_ADD, left->type,
7832                                         read_expr(state, left),
7833                                         int_const(state, &long_type, offset));
7834                                 free_triple(state, base);
7835                         }
7836                         else {
7837                                 ptr = flatten_part(state, first, ptr);
7838                         }
7839                         break;
7840                 case OP_PIECE:
7841                         ptr = flatten_part(state, first, ptr);
7842                         use_triple(ptr, MISC(ptr, 0));
7843                         break;
7844                 case OP_ADDRCONST:
7845                         MISC(ptr, 0) = flatten(state, first, MISC(ptr, 0));
7846                         use_triple(MISC(ptr, 0), ptr);
7847                         break;
7848                 case OP_SDECL:
7849                         first = state->global_pool;
7850                         MISC(ptr, 0) = flatten(state, first, MISC(ptr, 0));
7851                         use_triple(MISC(ptr, 0), ptr);
7852                         insert_triple(state, first, ptr);
7853                         ptr->id |= TRIPLE_FLAG_FLATTENED;
7854                         ptr->id &= ~TRIPLE_FLAG_LOCAL;
7855                         return ptr;
7856                 case OP_ADECL:
7857                         ptr = flatten_generic(state, first, ptr, 0);
7858                         break;
7859                 default:
7860                         /* Flatten the easy cases we don't override */
7861                         ptr = flatten_generic(state, first, ptr, 0);
7862                         break;
7863                 }
7864         } while(ptr && (ptr != orig_ptr));
7865         if (ptr && !(ptr->id & TRIPLE_FLAG_FLATTENED)) {
7866                 insert_triple(state, first, ptr);
7867                 ptr->id |= TRIPLE_FLAG_FLATTENED;
7868                 ptr->id &= ~TRIPLE_FLAG_LOCAL;
7869         }
7870         return ptr;
7871 }
7872
7873 static void release_expr(struct compile_state *state, struct triple *expr)
7874 {
7875         struct triple *head;
7876         head = label(state);
7877         flatten(state, head, expr);
7878         while(head->next != head) {
7879                 release_triple(state, head->next);
7880         }
7881         free_triple(state, head);
7882 }
7883
7884 static int replace_rhs_use(struct compile_state *state,
7885         struct triple *orig, struct triple *new, struct triple *use)
7886 {
7887         struct triple **expr;
7888         int found;
7889         found = 0;
7890         expr = triple_rhs(state, use, 0);
7891         for(;expr; expr = triple_rhs(state, use, expr)) {
7892                 if (*expr == orig) {
7893                         *expr = new;
7894                         found = 1;
7895                 }
7896         }
7897         if (found) {
7898                 unuse_triple(orig, use);
7899                 use_triple(new, use);
7900         }
7901         return found;
7902 }
7903
7904 static int replace_lhs_use(struct compile_state *state,
7905         struct triple *orig, struct triple *new, struct triple *use)
7906 {
7907         struct triple **expr;
7908         int found;
7909         found = 0;
7910         expr = triple_lhs(state, use, 0);
7911         for(;expr; expr = triple_lhs(state, use, expr)) {
7912                 if (*expr == orig) {
7913                         *expr = new;
7914                         found = 1;
7915                 }
7916         }
7917         if (found) {
7918                 unuse_triple(orig, use);
7919                 use_triple(new, use);
7920         }
7921         return found;
7922 }
7923
7924 static int replace_misc_use(struct compile_state *state,
7925         struct triple *orig, struct triple *new, struct triple *use)
7926 {
7927         struct triple **expr;
7928         int found;
7929         found = 0;
7930         expr = triple_misc(state, use, 0);
7931         for(;expr; expr = triple_misc(state, use, expr)) {
7932                 if (*expr == orig) {
7933                         *expr = new;
7934                         found = 1;
7935                 }
7936         }
7937         if (found) {
7938                 unuse_triple(orig, use);
7939                 use_triple(new, use);
7940         }
7941         return found;
7942 }
7943
7944 static int replace_targ_use(struct compile_state *state,
7945         struct triple *orig, struct triple *new, struct triple *use)
7946 {
7947         struct triple **expr;
7948         int found;
7949         found = 0;
7950         expr = triple_targ(state, use, 0);
7951         for(;expr; expr = triple_targ(state, use, expr)) {
7952                 if (*expr == orig) {
7953                         *expr = new;
7954                         found = 1;
7955                 }
7956         }
7957         if (found) {
7958                 unuse_triple(orig, use);
7959                 use_triple(new, use);
7960         }
7961         return found;
7962 }
7963
7964 static void replace_use(struct compile_state *state,
7965         struct triple *orig, struct triple *new, struct triple *use)
7966 {
7967         int found;
7968         found = 0;
7969         found |= replace_rhs_use(state, orig, new, use);
7970         found |= replace_lhs_use(state, orig, new, use);
7971         found |= replace_misc_use(state, orig, new, use);
7972         found |= replace_targ_use(state, orig, new, use);
7973         if (!found) {
7974                 internal_error(state, use, "use without use");
7975         }
7976 }
7977
7978 static void propogate_use(struct compile_state *state,
7979         struct triple *orig, struct triple *new)
7980 {
7981         struct triple_set *user, *next;
7982         for(user = orig->use; user; user = next) {
7983                 /* Careful replace_use modifies the use chain and
7984                  * removes use.  So we must get a copy of the next
7985                  * entry early.
7986                  */
7987                 next = user->next;
7988                 replace_use(state, orig, new, user->member);
7989         }
7990         if (orig->use) {
7991                 internal_error(state, orig, "used after propogate_use");
7992         }
7993 }
7994
7995 /*
7996  * Code generators
7997  * ===========================
7998  */
7999
8000 static struct triple *mk_cast_expr(
8001         struct compile_state *state, struct type *type, struct triple *expr)
8002 {
8003         struct triple *def;
8004         def = read_expr(state, expr);
8005         def = triple(state, OP_CONVERT, type, def, 0);
8006         return def;
8007 }
8008
8009 static struct triple *mk_add_expr(
8010         struct compile_state *state, struct triple *left, struct triple *right)
8011 {
8012         struct type *result_type;
8013         /* Put pointer operands on the left */
8014         if (is_pointer(right)) {
8015                 struct triple *tmp;
8016                 tmp = left;
8017                 left = right;
8018                 right = tmp;
8019         }
8020         left  = read_expr(state, left);
8021         right = read_expr(state, right);
8022         result_type = ptr_arithmetic_result(state, left, right);
8023         if (is_pointer(left)) {
8024                 struct type *ptr_math;
8025                 int op;
8026                 if (is_signed(right->type)) {
8027                         ptr_math = &long_type;
8028                         op = OP_SMUL;
8029                 } else {
8030                         ptr_math = &ulong_type;
8031                         op = OP_UMUL;
8032                 }
8033                 if (!equiv_types(right->type, ptr_math)) {
8034                         right = mk_cast_expr(state, ptr_math, right);
8035                 }
8036                 right = triple(state, op, ptr_math, right, 
8037                         int_const(state, ptr_math, 
8038                                 size_of_in_bytes(state, left->type->left)));
8039         }
8040         return triple(state, OP_ADD, result_type, left, right);
8041 }
8042
8043 static struct triple *mk_sub_expr(
8044         struct compile_state *state, struct triple *left, struct triple *right)
8045 {
8046         struct type *result_type;
8047         result_type = ptr_arithmetic_result(state, left, right);
8048         left  = read_expr(state, left);
8049         right = read_expr(state, right);
8050         if (is_pointer(left)) {
8051                 struct type *ptr_math;
8052                 int op;
8053                 if (is_signed(right->type)) {
8054                         ptr_math = &long_type;
8055                         op = OP_SMUL;
8056                 } else {
8057                         ptr_math = &ulong_type;
8058                         op = OP_UMUL;
8059                 }
8060                 if (!equiv_types(right->type, ptr_math)) {
8061                         right = mk_cast_expr(state, ptr_math, right);
8062                 }
8063                 right = triple(state, op, ptr_math, right, 
8064                         int_const(state, ptr_math, 
8065                                 size_of_in_bytes(state, left->type->left)));
8066         }
8067         return triple(state, OP_SUB, result_type, left, right);
8068 }
8069
8070 static struct triple *mk_pre_inc_expr(
8071         struct compile_state *state, struct triple *def)
8072 {
8073         struct triple *val;
8074         lvalue(state, def);
8075         val = mk_add_expr(state, def, int_const(state, &int_type, 1));
8076         return triple(state, OP_VAL, def->type,
8077                 write_expr(state, def, val),
8078                 val);
8079 }
8080
8081 static struct triple *mk_pre_dec_expr(
8082         struct compile_state *state, struct triple *def)
8083 {
8084         struct triple *val;
8085         lvalue(state, def);
8086         val = mk_sub_expr(state, def, int_const(state, &int_type, 1));
8087         return triple(state, OP_VAL, def->type,
8088                 write_expr(state, def, val),
8089                 val);
8090 }
8091
8092 static struct triple *mk_post_inc_expr(
8093         struct compile_state *state, struct triple *def)
8094 {
8095         struct triple *val;
8096         lvalue(state, def);
8097         val = read_expr(state, def);
8098         return triple(state, OP_VAL, def->type,
8099                 write_expr(state, def,
8100                         mk_add_expr(state, val, int_const(state, &int_type, 1)))
8101                 , val);
8102 }
8103
8104 static struct triple *mk_post_dec_expr(
8105         struct compile_state *state, struct triple *def)
8106 {
8107         struct triple *val;
8108         lvalue(state, def);
8109         val = read_expr(state, def);
8110         return triple(state, OP_VAL, def->type, 
8111                 write_expr(state, def,
8112                         mk_sub_expr(state, val, int_const(state, &int_type, 1)))
8113                 , val);
8114 }
8115
8116 static struct triple *mk_subscript_expr(
8117         struct compile_state *state, struct triple *left, struct triple *right)
8118 {
8119         left  = read_expr(state, left);
8120         right = read_expr(state, right);
8121         if (!is_pointer(left) && !is_pointer(right)) {
8122                 error(state, left, "subscripted value is not a pointer");
8123         }
8124         return mk_deref_expr(state, mk_add_expr(state, left, right));
8125 }
8126
8127
8128 /*
8129  * Compile time evaluation
8130  * ===========================
8131  */
8132 static int is_const(struct triple *ins)
8133 {
8134         return IS_CONST_OP(ins->op);
8135 }
8136
8137 static int is_simple_const(struct triple *ins)
8138 {
8139         /* Is this a constant that u.cval has the value.
8140          * Or equivalently is this a constant that read_const
8141          * works on.
8142          * So far only OP_INTCONST qualifies.  
8143          */
8144         return (ins->op == OP_INTCONST);
8145 }
8146
8147 static int constants_equal(struct compile_state *state, 
8148         struct triple *left, struct triple *right)
8149 {
8150         int equal;
8151         if ((left->op == OP_UNKNOWNVAL) || (right->op == OP_UNKNOWNVAL)) {
8152                 equal = 0;
8153         }
8154         else if (!is_const(left) || !is_const(right)) {
8155                 equal = 0;
8156         }
8157         else if (left->op != right->op) {
8158                 equal = 0;
8159         }
8160         else if (!equiv_types(left->type, right->type)) {
8161                 equal = 0;
8162         }
8163         else {
8164                 equal = 0;
8165                 switch(left->op) {
8166                 case OP_INTCONST:
8167                         if (left->u.cval == right->u.cval) {
8168                                 equal = 1;
8169                         }
8170                         break;
8171                 case OP_BLOBCONST:
8172                 {
8173                         size_t lsize, rsize, bytes;
8174                         lsize = size_of(state, left->type);
8175                         rsize = size_of(state, right->type);
8176                         if (lsize != rsize) {
8177                                 break;
8178                         }
8179                         bytes = bits_to_bytes(lsize);
8180                         if (memcmp(left->u.blob, right->u.blob, bytes) == 0) {
8181                                 equal = 1;
8182                         }
8183                         break;
8184                 }
8185                 case OP_ADDRCONST:
8186                         if ((MISC(left, 0) == MISC(right, 0)) &&
8187                                 (left->u.cval == right->u.cval)) {
8188                                 equal = 1;
8189                         }
8190                         break;
8191                 default:
8192                         internal_error(state, left, "uknown constant type");
8193                         break;
8194                 }
8195         }
8196         return equal;
8197 }
8198
8199 static int is_zero(struct triple *ins)
8200 {
8201         return is_simple_const(ins) && (ins->u.cval == 0);
8202 }
8203
8204 static int is_one(struct triple *ins)
8205 {
8206         return is_simple_const(ins) && (ins->u.cval == 1);
8207 }
8208
8209 static long_t bit_count(ulong_t value)
8210 {
8211         int count;
8212         int i;
8213         count = 0;
8214         for(i = (sizeof(ulong_t)*8) -1; i >= 0; i--) {
8215                 ulong_t mask;
8216                 mask = 1;
8217                 mask <<= i;
8218                 if (value & mask) {
8219                         count++;
8220                 }
8221         }
8222         return count;
8223         
8224 }
8225 static long_t bsr(ulong_t value)
8226 {
8227         int i;
8228         for(i = (sizeof(ulong_t)*8) -1; i >= 0; i--) {
8229                 ulong_t mask;
8230                 mask = 1;
8231                 mask <<= i;
8232                 if (value & mask) {
8233                         return i;
8234                 }
8235         }
8236         return -1;
8237 }
8238
8239 static long_t bsf(ulong_t value)
8240 {
8241         int i;
8242         for(i = 0; i < (sizeof(ulong_t)*8); i++) {
8243                 ulong_t mask;
8244                 mask = 1;
8245                 mask <<= 1;
8246                 if (value & mask) {
8247                         return i;
8248                 }
8249         }
8250         return -1;
8251 }
8252
8253 static long_t log2(ulong_t value)
8254 {
8255         return bsr(value);
8256 }
8257
8258 static long_t tlog2(struct triple *ins)
8259 {
8260         return log2(ins->u.cval);
8261 }
8262
8263 static int is_pow2(struct triple *ins)
8264 {
8265         ulong_t value, mask;
8266         long_t log;
8267         if (!is_const(ins)) {
8268                 return 0;
8269         }
8270         value = ins->u.cval;
8271         log = log2(value);
8272         if (log == -1) {
8273                 return 0;
8274         }
8275         mask = 1;
8276         mask <<= log;
8277         return  ((value & mask) == value);
8278 }
8279
8280 static ulong_t read_const(struct compile_state *state,
8281         struct triple *ins, struct triple *rhs)
8282 {
8283         switch(rhs->type->type &TYPE_MASK) {
8284         case TYPE_CHAR:   
8285         case TYPE_SHORT:
8286         case TYPE_INT:
8287         case TYPE_LONG:
8288         case TYPE_UCHAR:   
8289         case TYPE_USHORT:  
8290         case TYPE_UINT:
8291         case TYPE_ULONG:
8292         case TYPE_POINTER:
8293         case TYPE_BITFIELD:
8294                 break;
8295         default:
8296                 fprintf(state->errout, "type: ");
8297                 name_of(state->errout, rhs->type);
8298                 fprintf(state->errout, "\n");
8299                 internal_warning(state, rhs, "bad type to read_const");
8300                 break;
8301         }
8302         if (!is_simple_const(rhs)) {
8303                 internal_error(state, rhs, "bad op to read_const");
8304         }
8305         return rhs->u.cval;
8306 }
8307
8308 static long_t read_sconst(struct compile_state *state,
8309         struct triple *ins, struct triple *rhs)
8310 {
8311         return (long_t)(rhs->u.cval);
8312 }
8313
8314 int const_ltrue(struct compile_state *state, struct triple *ins, struct triple *rhs)
8315 {
8316         if (!is_const(rhs)) {
8317                 internal_error(state, 0, "non const passed to const_true");
8318         }
8319         return !is_zero(rhs);
8320 }
8321
8322 int const_eq(struct compile_state *state, struct triple *ins,
8323         struct triple *left, struct triple *right)
8324 {
8325         int result;
8326         if (!is_const(left) || !is_const(right)) {
8327                 internal_warning(state, ins, "non const passed to const_eq");
8328                 result = -1;
8329         }
8330         else if (left == right) {
8331                 result = 1;
8332         }
8333         else if (is_simple_const(left) && is_simple_const(right)) {
8334                 ulong_t lval, rval;
8335                 lval = read_const(state, ins, left);
8336                 rval = read_const(state, ins, right);
8337                 result = (lval == rval);
8338         }
8339         else if ((left->op == OP_ADDRCONST) && 
8340                 (right->op == OP_ADDRCONST)) {
8341                 result = (MISC(left, 0) == MISC(right, 0)) &&
8342                         (left->u.cval == right->u.cval);
8343         }
8344         else {
8345                 internal_warning(state, ins, "incomparable constants passed to const_eq");
8346                 result = -1;
8347         }
8348         return result;
8349         
8350 }
8351
8352 int const_ucmp(struct compile_state *state, struct triple *ins,
8353         struct triple *left, struct triple *right)
8354 {
8355         int result;
8356         if (!is_const(left) || !is_const(right)) {
8357                 internal_warning(state, ins, "non const past to const_ucmp");
8358                 result = -2;
8359         }
8360         else if (left == right) {
8361                 result = 0;
8362         }
8363         else if (is_simple_const(left) && is_simple_const(right)) {
8364                 ulong_t lval, rval;
8365                 lval = read_const(state, ins, left);
8366                 rval = read_const(state, ins, right);
8367                 result = 0;
8368                 if (lval > rval) {
8369                         result = 1;
8370                 } else if (rval > lval) {
8371                         result = -1;
8372                 }
8373         }
8374         else if ((left->op == OP_ADDRCONST) && 
8375                 (right->op == OP_ADDRCONST) &&
8376                 (MISC(left, 0) == MISC(right, 0))) {
8377                 result = 0;
8378                 if (left->u.cval > right->u.cval) {
8379                         result = 1;
8380                 } else if (left->u.cval < right->u.cval) {
8381                         result = -1;
8382                 }
8383         }
8384         else {
8385                 internal_warning(state, ins, "incomparable constants passed to const_ucmp");
8386                 result = -2;
8387         }
8388         return result;
8389 }
8390
8391 int const_scmp(struct compile_state *state, struct triple *ins,
8392         struct triple *left, struct triple *right)
8393 {
8394         int result;
8395         if (!is_const(left) || !is_const(right)) {
8396                 internal_warning(state, ins, "non const past to ucmp_const");
8397                 result = -2;
8398         }
8399         else if (left == right) {
8400                 result = 0;
8401         }
8402         else if (is_simple_const(left) && is_simple_const(right)) {
8403                 long_t lval, rval;
8404                 lval = read_sconst(state, ins, left);
8405                 rval = read_sconst(state, ins, right);
8406                 result = 0;
8407                 if (lval > rval) {
8408                         result = 1;
8409                 } else if (rval > lval) {
8410                         result = -1;
8411                 }
8412         }
8413         else {
8414                 internal_warning(state, ins, "incomparable constants passed to const_scmp");
8415                 result = -2;
8416         }
8417         return result;
8418 }
8419
8420 static void unuse_rhs(struct compile_state *state, struct triple *ins)
8421 {
8422         struct triple **expr;
8423         expr = triple_rhs(state, ins, 0);
8424         for(;expr;expr = triple_rhs(state, ins, expr)) {
8425                 if (*expr) {
8426                         unuse_triple(*expr, ins);
8427                         *expr = 0;
8428                 }
8429         }
8430 }
8431
8432 static void unuse_lhs(struct compile_state *state, struct triple *ins)
8433 {
8434         struct triple **expr;
8435         expr = triple_lhs(state, ins, 0);
8436         for(;expr;expr = triple_lhs(state, ins, expr)) {
8437                 unuse_triple(*expr, ins);
8438                 *expr = 0;
8439         }
8440 }
8441
8442 static void unuse_misc(struct compile_state *state, struct triple *ins)
8443 {
8444         struct triple **expr;
8445         expr = triple_misc(state, ins, 0);
8446         for(;expr;expr = triple_misc(state, ins, expr)) {
8447                 unuse_triple(*expr, ins);
8448                 *expr = 0;
8449         }
8450 }
8451
8452 static void unuse_targ(struct compile_state *state, struct triple *ins)
8453 {
8454         int i;
8455         struct triple **slot;
8456         slot = &TARG(ins, 0);
8457         for(i = 0; i < ins->targ; i++) {
8458                 unuse_triple(slot[i], ins);
8459                 slot[i] = 0;
8460         }
8461 }
8462
8463 static void check_lhs(struct compile_state *state, struct triple *ins)
8464 {
8465         struct triple **expr;
8466         expr = triple_lhs(state, ins, 0);
8467         for(;expr;expr = triple_lhs(state, ins, expr)) {
8468                 internal_error(state, ins, "unexpected lhs");
8469         }
8470         
8471 }
8472
8473 static void check_misc(struct compile_state *state, struct triple *ins)
8474 {
8475         struct triple **expr;
8476         expr = triple_misc(state, ins, 0);
8477         for(;expr;expr = triple_misc(state, ins, expr)) {
8478                 if (*expr) {
8479                         internal_error(state, ins, "unexpected misc");
8480                 }
8481         }
8482 }
8483
8484 static void check_targ(struct compile_state *state, struct triple *ins)
8485 {
8486         struct triple **expr;
8487         expr = triple_targ(state, ins, 0);
8488         for(;expr;expr = triple_targ(state, ins, expr)) {
8489                 internal_error(state, ins, "unexpected targ");
8490         }
8491 }
8492
8493 static void wipe_ins(struct compile_state *state, struct triple *ins)
8494 {
8495         /* Becareful which instructions you replace the wiped
8496          * instruction with, as there are not enough slots
8497          * in all instructions to hold all others.
8498          */
8499         check_targ(state, ins);
8500         check_misc(state, ins);
8501         unuse_rhs(state, ins);
8502         unuse_lhs(state, ins);
8503         ins->lhs  = 0;
8504         ins->rhs  = 0;
8505         ins->misc = 0;
8506         ins->targ = 0;
8507 }
8508
8509 static void wipe_branch(struct compile_state *state, struct triple *ins)
8510 {
8511         /* Becareful which instructions you replace the wiped
8512          * instruction with, as there are not enough slots
8513          * in all instructions to hold all others.
8514          */
8515         unuse_rhs(state, ins);
8516         unuse_lhs(state, ins);
8517         unuse_misc(state, ins);
8518         unuse_targ(state, ins);
8519         ins->lhs  = 0;
8520         ins->rhs  = 0;
8521         ins->misc = 0;
8522         ins->targ = 0;
8523 }
8524
8525 static void mkcopy(struct compile_state *state, 
8526         struct triple *ins, struct triple *rhs)
8527 {
8528         struct block *block;
8529         if (!equiv_types(ins->type, rhs->type)) {
8530                 FILE *fp = state->errout;
8531                 fprintf(fp, "src type: ");
8532                 name_of(fp, rhs->type);
8533                 fprintf(fp, "\ndst type: ");
8534                 name_of(fp, ins->type);
8535                 fprintf(fp, "\n");
8536                 internal_error(state, ins, "mkcopy type mismatch");
8537         }
8538         block = block_of_triple(state, ins);
8539         wipe_ins(state, ins);
8540         ins->op = OP_COPY;
8541         ins->rhs  = 1;
8542         ins->u.block = block;
8543         RHS(ins, 0) = rhs;
8544         use_triple(RHS(ins, 0), ins);
8545 }
8546
8547 static void mkconst(struct compile_state *state, 
8548         struct triple *ins, ulong_t value)
8549 {
8550         if (!is_integral(ins) && !is_pointer(ins)) {
8551                 fprintf(state->errout, "type: ");
8552                 name_of(state->errout, ins->type);
8553                 fprintf(state->errout, "\n");
8554                 internal_error(state, ins, "unknown type to make constant value: %ld",
8555                         value);
8556         }
8557         wipe_ins(state, ins);
8558         ins->op = OP_INTCONST;
8559         ins->u.cval = value;
8560 }
8561
8562 static void mkaddr_const(struct compile_state *state,
8563         struct triple *ins, struct triple *sdecl, ulong_t value)
8564 {
8565         if ((sdecl->op != OP_SDECL) && (sdecl->op != OP_LABEL)) {
8566                 internal_error(state, ins, "bad base for addrconst");
8567         }
8568         wipe_ins(state, ins);
8569         ins->op = OP_ADDRCONST;
8570         ins->misc = 1;
8571         MISC(ins, 0) = sdecl;
8572         ins->u.cval = value;
8573         use_triple(sdecl, ins);
8574 }
8575
8576 #if DEBUG_DECOMPOSE_PRINT_TUPLES
8577 static void print_tuple(struct compile_state *state, 
8578         struct triple *ins, struct triple *tuple)
8579 {
8580         FILE *fp = state->dbgout;
8581         fprintf(fp, "%5s %p tuple: %p ", tops(ins->op), ins, tuple);
8582         name_of(fp, tuple->type);
8583         if (tuple->lhs > 0) {
8584                 fprintf(fp, " lhs: ");
8585                 name_of(fp, LHS(tuple, 0)->type);
8586         }
8587         fprintf(fp, "\n");
8588         
8589 }
8590 #endif
8591
8592 static struct triple *decompose_with_tuple(struct compile_state *state, 
8593         struct triple *ins, struct triple *tuple)
8594 {
8595         struct triple *next;
8596         next = ins->next;
8597         flatten(state, next, tuple);
8598 #if DEBUG_DECOMPOSE_PRINT_TUPLES
8599         print_tuple(state, ins, tuple);
8600 #endif
8601
8602         if (!is_compound_type(tuple->type) && (tuple->lhs > 0)) {
8603                 struct triple *tmp;
8604                 if (tuple->lhs != 1) {
8605                         internal_error(state, tuple, "plain type in multiple registers?");
8606                 }
8607                 tmp = LHS(tuple, 0);
8608                 release_triple(state, tuple);
8609                 tuple = tmp;
8610         }
8611
8612         propogate_use(state, ins, tuple);
8613         release_triple(state, ins);
8614         
8615         return next;
8616 }
8617
8618 static struct triple *decompose_unknownval(struct compile_state *state,
8619         struct triple *ins)
8620 {
8621         struct triple *tuple;
8622         ulong_t i;
8623
8624 #if DEBUG_DECOMPOSE_HIRES
8625         FILE *fp = state->dbgout;
8626         fprintf(fp, "unknown type: ");
8627         name_of(fp, ins->type);
8628         fprintf(fp, "\n");
8629 #endif
8630
8631         get_occurance(ins->occurance);
8632         tuple = alloc_triple(state, OP_TUPLE, ins->type, -1, -1, 
8633                 ins->occurance);
8634
8635         for(i = 0; i < tuple->lhs; i++) {
8636                 struct type *piece_type;
8637                 struct triple *unknown;
8638
8639                 piece_type = reg_type(state, ins->type, i * REG_SIZEOF_REG);
8640                 get_occurance(tuple->occurance);
8641                 unknown = alloc_triple(state, OP_UNKNOWNVAL, piece_type, 0, 0,
8642                         tuple->occurance);
8643                 LHS(tuple, i) = unknown;
8644         }
8645         return decompose_with_tuple(state, ins, tuple);
8646 }
8647
8648
8649 static struct triple *decompose_read(struct compile_state *state, 
8650         struct triple *ins)
8651 {
8652         struct triple *tuple, *lval;
8653         ulong_t i;
8654
8655         lval = RHS(ins, 0);
8656
8657         if (lval->op == OP_PIECE) {
8658                 return ins->next;
8659         }
8660         get_occurance(ins->occurance);
8661         tuple = alloc_triple(state, OP_TUPLE, lval->type, -1, -1,
8662                 ins->occurance);
8663
8664         if ((tuple->lhs != lval->lhs) &&
8665                 (!triple_is_def(state, lval) || (tuple->lhs != 1))) 
8666         {
8667                 internal_error(state, ins, "lhs size inconsistency?");
8668         }
8669         for(i = 0; i < tuple->lhs; i++) {
8670                 struct triple *piece, *read, *bitref;
8671                 if ((i != 0) || !triple_is_def(state, lval)) {
8672                         piece = LHS(lval, i);
8673                 } else {
8674                         piece = lval;
8675                 }
8676
8677                 /* See if the piece is really a bitref */
8678                 bitref = 0;
8679                 if (piece->op == OP_BITREF) {
8680                         bitref = piece;
8681                         piece = RHS(bitref, 0);
8682                 }
8683
8684                 get_occurance(tuple->occurance);
8685                 read = alloc_triple(state, OP_READ, piece->type, -1, -1, 
8686                         tuple->occurance);
8687                 RHS(read, 0) = piece;
8688
8689                 if (bitref) {
8690                         struct triple *extract;
8691                         int op;
8692                         if (is_signed(bitref->type->left)) {
8693                                 op = OP_SEXTRACT;
8694                         } else {
8695                                 op = OP_UEXTRACT;
8696                         }
8697                         get_occurance(tuple->occurance);
8698                         extract = alloc_triple(state, op, bitref->type, -1, -1,
8699                                 tuple->occurance);
8700                         RHS(extract, 0) = read;
8701                         extract->u.bitfield.size   = bitref->u.bitfield.size;
8702                         extract->u.bitfield.offset = bitref->u.bitfield.offset;
8703
8704                         read = extract;
8705                 }
8706
8707                 LHS(tuple, i) = read;
8708         }
8709         return decompose_with_tuple(state, ins, tuple);
8710 }
8711
8712 static struct triple *decompose_write(struct compile_state *state, 
8713         struct triple *ins)
8714 {
8715         struct triple *tuple, *lval, *val;
8716         ulong_t i;
8717         
8718         lval = MISC(ins, 0);
8719         val = RHS(ins, 0);
8720         get_occurance(ins->occurance);
8721         tuple = alloc_triple(state, OP_TUPLE, ins->type, -1, -1,
8722                 ins->occurance);
8723
8724         if ((tuple->lhs != lval->lhs) &&
8725                 (!triple_is_def(state, lval) || tuple->lhs != 1)) 
8726         {
8727                 internal_error(state, ins, "lhs size inconsistency?");
8728         }
8729         for(i = 0; i < tuple->lhs; i++) {
8730                 struct triple *piece, *write, *pval, *bitref;
8731                 if ((i != 0) || !triple_is_def(state, lval)) {
8732                         piece = LHS(lval, i);
8733                 } else {
8734                         piece = lval;
8735                 }
8736                 if ((i == 0) && (tuple->lhs == 1) && (val->lhs == 0)) {
8737                         pval = val;
8738                 }
8739                 else {
8740                         if (i > val->lhs) {
8741                                 internal_error(state, ins, "lhs size inconsistency?");
8742                         }
8743                         pval = LHS(val, i);
8744                 }
8745                 
8746                 /* See if the piece is really a bitref */
8747                 bitref = 0;
8748                 if (piece->op == OP_BITREF) {
8749                         struct triple *read, *deposit;
8750                         bitref = piece;
8751                         piece = RHS(bitref, 0);
8752
8753                         /* Read the destination register */
8754                         get_occurance(tuple->occurance);
8755                         read = alloc_triple(state, OP_READ, piece->type, -1, -1,
8756                                 tuple->occurance);
8757                         RHS(read, 0) = piece;
8758
8759                         /* Deposit the new bitfield value */
8760                         get_occurance(tuple->occurance);
8761                         deposit = alloc_triple(state, OP_DEPOSIT, piece->type, -1, -1,
8762                                 tuple->occurance);
8763                         RHS(deposit, 0) = read;
8764                         RHS(deposit, 1) = pval;
8765                         deposit->u.bitfield.size   = bitref->u.bitfield.size;
8766                         deposit->u.bitfield.offset = bitref->u.bitfield.offset;
8767
8768                         /* Now write the newly generated value */
8769                         pval = deposit;
8770                 }
8771
8772                 get_occurance(tuple->occurance);
8773                 write = alloc_triple(state, OP_WRITE, piece->type, -1, -1, 
8774                         tuple->occurance);
8775                 MISC(write, 0) = piece;
8776                 RHS(write, 0) = pval;
8777                 LHS(tuple, i) = write;
8778         }
8779         return decompose_with_tuple(state, ins, tuple);
8780 }
8781
8782 struct decompose_load_info {
8783         struct occurance *occurance;
8784         struct triple *lval;
8785         struct triple *tuple;
8786 };
8787 static void decompose_load_cb(struct compile_state *state,
8788         struct type *type, size_t reg_offset, size_t mem_offset, void *arg)
8789 {
8790         struct decompose_load_info *info = arg;
8791         struct triple *load;
8792         
8793         if (reg_offset > info->tuple->lhs) {
8794                 internal_error(state, info->tuple, "lhs to small?");
8795         }
8796         get_occurance(info->occurance);
8797         load = alloc_triple(state, OP_LOAD, type, -1, -1, info->occurance);
8798         RHS(load, 0) = mk_addr_expr(state, info->lval, mem_offset);
8799         LHS(info->tuple, reg_offset/REG_SIZEOF_REG) = load;
8800 }
8801
8802 static struct triple *decompose_load(struct compile_state *state, 
8803         struct triple *ins)
8804 {
8805         struct triple *tuple;
8806         struct decompose_load_info info;
8807
8808         if (!is_compound_type(ins->type)) {
8809                 return ins->next;
8810         }
8811         get_occurance(ins->occurance);
8812         tuple = alloc_triple(state, OP_TUPLE, ins->type, -1, -1,
8813                 ins->occurance);
8814
8815         info.occurance = ins->occurance;
8816         info.lval      = RHS(ins, 0);
8817         info.tuple     = tuple;
8818         walk_type_fields(state, ins->type, 0, 0, decompose_load_cb, &info);
8819
8820         return decompose_with_tuple(state, ins, tuple);
8821 }
8822
8823
8824 struct decompose_store_info {
8825         struct occurance *occurance;
8826         struct triple *lval;
8827         struct triple *val;
8828         struct triple *tuple;
8829 };
8830 static void decompose_store_cb(struct compile_state *state,
8831         struct type *type, size_t reg_offset, size_t mem_offset, void *arg)
8832 {
8833         struct decompose_store_info *info = arg;
8834         struct triple *store;
8835         
8836         if (reg_offset > info->tuple->lhs) {
8837                 internal_error(state, info->tuple, "lhs to small?");
8838         }
8839         get_occurance(info->occurance);
8840         store = alloc_triple(state, OP_STORE, type, -1, -1, info->occurance);
8841         RHS(store, 0) = mk_addr_expr(state, info->lval, mem_offset);
8842         RHS(store, 1) = LHS(info->val, reg_offset);
8843         LHS(info->tuple, reg_offset/REG_SIZEOF_REG) = store;
8844 }
8845
8846 static struct triple *decompose_store(struct compile_state *state, 
8847         struct triple *ins)
8848 {
8849         struct triple *tuple;
8850         struct decompose_store_info info;
8851
8852         if (!is_compound_type(ins->type)) {
8853                 return ins->next;
8854         }
8855         get_occurance(ins->occurance);
8856         tuple = alloc_triple(state, OP_TUPLE, ins->type, -1, -1,
8857                 ins->occurance);
8858
8859         info.occurance = ins->occurance;
8860         info.lval      = RHS(ins, 0);
8861         info.val       = RHS(ins, 1);
8862         info.tuple     = tuple;
8863         walk_type_fields(state, ins->type, 0, 0, decompose_store_cb, &info);
8864
8865         return decompose_with_tuple(state, ins, tuple);
8866 }
8867
8868 static struct triple *decompose_dot(struct compile_state *state, 
8869         struct triple *ins)
8870 {
8871         struct triple *tuple, *lval;
8872         struct type *type;
8873         size_t reg_offset;
8874         int i, idx;
8875
8876         lval = MISC(ins, 0);
8877         reg_offset = field_reg_offset(state, lval->type, ins->u.field);
8878         idx  = reg_offset/REG_SIZEOF_REG;
8879         type = field_type(state, lval->type, ins->u.field);
8880 #if DEBUG_DECOMPOSE_HIRES
8881         {
8882                 FILE *fp = state->dbgout;
8883                 fprintf(fp, "field type: ");
8884                 name_of(fp, type);
8885                 fprintf(fp, "\n");
8886         }
8887 #endif
8888
8889         get_occurance(ins->occurance);
8890         tuple = alloc_triple(state, OP_TUPLE, type, -1, -1, 
8891                 ins->occurance);
8892
8893         if (((ins->type->type & TYPE_MASK) == TYPE_BITFIELD) &&
8894                 (tuple->lhs != 1))
8895         {
8896                 internal_error(state, ins, "multi register bitfield?");
8897         }
8898
8899         for(i = 0; i < tuple->lhs; i++, idx++) {
8900                 struct triple *piece;
8901                 if (!triple_is_def(state, lval)) {
8902                         if (idx > lval->lhs) {
8903                                 internal_error(state, ins, "inconsistent lhs count");
8904                         }
8905                         piece = LHS(lval, idx);
8906                 } else {
8907                         if (idx != 0) {
8908                                 internal_error(state, ins, "bad reg_offset into def");
8909                         }
8910                         if (i != 0) {
8911                                 internal_error(state, ins, "bad reg count from def");
8912                         }
8913                         piece = lval;
8914                 }
8915
8916                 /* Remember the offset of the bitfield */
8917                 if ((type->type & TYPE_MASK) == TYPE_BITFIELD) {
8918                         get_occurance(ins->occurance);
8919                         piece = build_triple(state, OP_BITREF, type, piece, 0,
8920                                 ins->occurance);
8921                         piece->u.bitfield.size   = size_of(state, type);
8922                         piece->u.bitfield.offset = reg_offset % REG_SIZEOF_REG;
8923                 }
8924                 else if ((reg_offset % REG_SIZEOF_REG) != 0) {
8925                         internal_error(state, ins, 
8926                                 "request for a nonbitfield sub register?");
8927                 }
8928
8929                 LHS(tuple, i) = piece;
8930         }
8931
8932         return decompose_with_tuple(state, ins, tuple);
8933 }
8934
8935 static struct triple *decompose_index(struct compile_state *state, 
8936         struct triple *ins)
8937 {
8938         struct triple *tuple, *lval;
8939         struct type *type;
8940         int i, idx;
8941
8942         lval = MISC(ins, 0);
8943         idx = index_reg_offset(state, lval->type, ins->u.cval)/REG_SIZEOF_REG;
8944         type = index_type(state, lval->type, ins->u.cval);
8945 #if DEBUG_DECOMPOSE_HIRES
8946 {
8947         FILE *fp = state->dbgout;
8948         fprintf(fp, "index type: ");
8949         name_of(fp, type);
8950         fprintf(fp, "\n");
8951 }
8952 #endif
8953
8954         get_occurance(ins->occurance);
8955         tuple = alloc_triple(state, OP_TUPLE, type, -1, -1, 
8956                 ins->occurance);
8957
8958         for(i = 0; i < tuple->lhs; i++, idx++) {
8959                 struct triple *piece;
8960                 if (!triple_is_def(state, lval)) {
8961                         if (idx > lval->lhs) {
8962                                 internal_error(state, ins, "inconsistent lhs count");
8963                         }
8964                         piece = LHS(lval, idx);
8965                 } else {
8966                         if (idx != 0) {
8967                                 internal_error(state, ins, "bad reg_offset into def");
8968                         }
8969                         if (i != 0) {
8970                                 internal_error(state, ins, "bad reg count from def");
8971                         }
8972                         piece = lval;
8973                 }
8974                 LHS(tuple, i) = piece;
8975         }
8976
8977         return decompose_with_tuple(state, ins, tuple);
8978 }
8979
8980 static void decompose_compound_types(struct compile_state *state)
8981 {
8982         struct triple *ins, *next, *first;
8983         FILE *fp;
8984         fp = state->dbgout;
8985         first = state->first;
8986         ins = first;
8987
8988         /* Pass one expand compound values into pseudo registers.
8989          */
8990         next = first;
8991         do {
8992                 ins = next;
8993                 next = ins->next;
8994                 switch(ins->op) {
8995                 case OP_UNKNOWNVAL:
8996                         next = decompose_unknownval(state, ins);
8997                         break;
8998
8999                 case OP_READ:
9000                         next = decompose_read(state, ins);
9001                         break;
9002
9003                 case OP_WRITE:
9004                         next = decompose_write(state, ins);
9005                         break;
9006
9007
9008                 /* Be very careful with the load/store logic. These
9009                  * operations must convert from the in register layout
9010                  * to the in memory layout, which is nontrivial.
9011                  */
9012                 case OP_LOAD:
9013                         next = decompose_load(state, ins);
9014                         break;
9015                 case OP_STORE:
9016                         next = decompose_store(state, ins);
9017                         break;
9018
9019                 case OP_DOT:
9020                         next = decompose_dot(state, ins);
9021                         break;
9022                 case OP_INDEX:
9023                         next = decompose_index(state, ins);
9024                         break;
9025                         
9026                 }
9027 #if DEBUG_DECOMPOSE_HIRES
9028                 fprintf(fp, "decompose next: %p \n", next);
9029                 fflush(fp);
9030                 fprintf(fp, "next->op: %d %s\n",
9031                         next->op, tops(next->op));
9032                 /* High resolution debugging mode */
9033                 print_triples(state);
9034 #endif
9035         } while (next != first);
9036
9037         /* Pass two remove the tuples.
9038          */
9039         ins = first;
9040         do {
9041                 next = ins->next;
9042                 if (ins->op == OP_TUPLE) {
9043                         if (ins->use) {
9044                                 internal_error(state, ins, "tuple used");
9045                         }
9046                         else {
9047                                 release_triple(state, ins);
9048                         }
9049                 } 
9050                 ins = next;
9051         } while(ins != first);
9052         ins = first;
9053         do {
9054                 next = ins->next;
9055                 if (ins->op == OP_BITREF) {
9056                         if (ins->use) {
9057                                 internal_error(state, ins, "bitref used");
9058                         } 
9059                         else {
9060                                 release_triple(state, ins);
9061                         }
9062                 }
9063                 ins = next;
9064         } while(ins != first);
9065
9066         /* Pass three verify the state and set ->id to 0.
9067          */
9068         next = first;
9069         do {
9070                 ins = next;
9071                 next = ins->next;
9072                 ins->id &= ~TRIPLE_FLAG_FLATTENED;
9073                 if (triple_stores_block(state, ins)) {
9074                         ins->u.block = 0;
9075                 }
9076                 if (triple_is_def(state, ins)) {
9077                         if (reg_size_of(state, ins->type) > REG_SIZEOF_REG) {
9078                                 internal_error(state, ins, "multi register value remains?");
9079                         }
9080                 }
9081                 if (ins->op == OP_DOT) {
9082                         internal_error(state, ins, "OP_DOT remains?");
9083                 }
9084                 if (ins->op == OP_INDEX) {
9085                         internal_error(state, ins, "OP_INDEX remains?");
9086                 }
9087                 if (ins->op == OP_BITREF) {
9088                         internal_error(state, ins, "OP_BITREF remains?");
9089                 }
9090                 if (ins->op == OP_TUPLE) {
9091                         internal_error(state, ins, "OP_TUPLE remains?");
9092                 }
9093         } while(next != first);
9094 }
9095
9096 /* For those operations that cannot be simplified */
9097 static void simplify_noop(struct compile_state *state, struct triple *ins)
9098 {
9099         return;
9100 }
9101
9102 static void simplify_smul(struct compile_state *state, struct triple *ins)
9103 {
9104         if (is_const(RHS(ins, 0)) && !is_const(RHS(ins, 1))) {
9105                 struct triple *tmp;
9106                 tmp = RHS(ins, 0);
9107                 RHS(ins, 0) = RHS(ins, 1);
9108                 RHS(ins, 1) = tmp;
9109         }
9110         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
9111                 long_t left, right;
9112                 left  = read_sconst(state, ins, RHS(ins, 0));
9113                 right = read_sconst(state, ins, RHS(ins, 1));
9114                 mkconst(state, ins, left * right);
9115         }
9116         else if (is_zero(RHS(ins, 1))) {
9117                 mkconst(state, ins, 0);
9118         }
9119         else if (is_one(RHS(ins, 1))) {
9120                 mkcopy(state, ins, RHS(ins, 0));
9121         }
9122         else if (is_pow2(RHS(ins, 1))) {
9123                 struct triple *val;
9124                 val = int_const(state, ins->type, tlog2(RHS(ins, 1)));
9125                 ins->op = OP_SL;
9126                 insert_triple(state, state->global_pool, val);
9127                 unuse_triple(RHS(ins, 1), ins);
9128                 use_triple(val, ins);
9129                 RHS(ins, 1) = val;
9130         }
9131 }
9132
9133 static void simplify_umul(struct compile_state *state, struct triple *ins)
9134 {
9135         if (is_const(RHS(ins, 0)) && !is_const(RHS(ins, 1))) {
9136                 struct triple *tmp;
9137                 tmp = RHS(ins, 0);
9138                 RHS(ins, 0) = RHS(ins, 1);
9139                 RHS(ins, 1) = tmp;
9140         }
9141         if (is_simple_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9142                 ulong_t left, right;
9143                 left  = read_const(state, ins, RHS(ins, 0));
9144                 right = read_const(state, ins, RHS(ins, 1));
9145                 mkconst(state, ins, left * right);
9146         }
9147         else if (is_zero(RHS(ins, 1))) {
9148                 mkconst(state, ins, 0);
9149         }
9150         else if (is_one(RHS(ins, 1))) {
9151                 mkcopy(state, ins, RHS(ins, 0));
9152         }
9153         else if (is_pow2(RHS(ins, 1))) {
9154                 struct triple *val;
9155                 val = int_const(state, ins->type, tlog2(RHS(ins, 1)));
9156                 ins->op = OP_SL;
9157                 insert_triple(state, state->global_pool, val);
9158                 unuse_triple(RHS(ins, 1), ins);
9159                 use_triple(val, ins);
9160                 RHS(ins, 1) = val;
9161         }
9162 }
9163
9164 static void simplify_sdiv(struct compile_state *state, struct triple *ins)
9165 {
9166         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
9167                 long_t left, right;
9168                 left  = read_sconst(state, ins, RHS(ins, 0));
9169                 right = read_sconst(state, ins, RHS(ins, 1));
9170                 mkconst(state, ins, left / right);
9171         }
9172         else if (is_zero(RHS(ins, 0))) {
9173                 mkconst(state, ins, 0);
9174         }
9175         else if (is_zero(RHS(ins, 1))) {
9176                 error(state, ins, "division by zero");
9177         }
9178         else if (is_one(RHS(ins, 1))) {
9179                 mkcopy(state, ins, RHS(ins, 0));
9180         }
9181         else if (is_pow2(RHS(ins, 1))) {
9182                 struct triple *val;
9183                 val = int_const(state, ins->type, tlog2(RHS(ins, 1)));
9184                 ins->op = OP_SSR;
9185                 insert_triple(state, state->global_pool, val);
9186                 unuse_triple(RHS(ins, 1), ins);
9187                 use_triple(val, ins);
9188                 RHS(ins, 1) = val;
9189         }
9190 }
9191
9192 static void simplify_udiv(struct compile_state *state, struct triple *ins)
9193 {
9194         if (is_simple_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9195                 ulong_t left, right;
9196                 left  = read_const(state, ins, RHS(ins, 0));
9197                 right = read_const(state, ins, RHS(ins, 1));
9198                 mkconst(state, ins, left / right);
9199         }
9200         else if (is_zero(RHS(ins, 0))) {
9201                 mkconst(state, ins, 0);
9202         }
9203         else if (is_zero(RHS(ins, 1))) {
9204                 error(state, ins, "division by zero");
9205         }
9206         else if (is_one(RHS(ins, 1))) {
9207                 mkcopy(state, ins, RHS(ins, 0));
9208         }
9209         else if (is_pow2(RHS(ins, 1))) {
9210                 struct triple *val;
9211                 val = int_const(state, ins->type, tlog2(RHS(ins, 1)));
9212                 ins->op = OP_USR;
9213                 insert_triple(state, state->global_pool, val);
9214                 unuse_triple(RHS(ins, 1), ins);
9215                 use_triple(val, ins);
9216                 RHS(ins, 1) = val;
9217         }
9218 }
9219
9220 static void simplify_smod(struct compile_state *state, struct triple *ins)
9221 {
9222         if (is_simple_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9223                 long_t left, right;
9224                 left  = read_const(state, ins, RHS(ins, 0));
9225                 right = read_const(state, ins, RHS(ins, 1));
9226                 mkconst(state, ins, left % right);
9227         }
9228         else if (is_zero(RHS(ins, 0))) {
9229                 mkconst(state, ins, 0);
9230         }
9231         else if (is_zero(RHS(ins, 1))) {
9232                 error(state, ins, "division by zero");
9233         }
9234         else if (is_one(RHS(ins, 1))) {
9235                 mkconst(state, ins, 0);
9236         }
9237         else if (is_pow2(RHS(ins, 1))) {
9238                 struct triple *val;
9239                 val = int_const(state, ins->type, RHS(ins, 1)->u.cval - 1);
9240                 ins->op = OP_AND;
9241                 insert_triple(state, state->global_pool, val);
9242                 unuse_triple(RHS(ins, 1), ins);
9243                 use_triple(val, ins);
9244                 RHS(ins, 1) = val;
9245         }
9246 }
9247
9248 static void simplify_umod(struct compile_state *state, struct triple *ins)
9249 {
9250         if (is_simple_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9251                 ulong_t left, right;
9252                 left  = read_const(state, ins, RHS(ins, 0));
9253                 right = read_const(state, ins, RHS(ins, 1));
9254                 mkconst(state, ins, left % right);
9255         }
9256         else if (is_zero(RHS(ins, 0))) {
9257                 mkconst(state, ins, 0);
9258         }
9259         else if (is_zero(RHS(ins, 1))) {
9260                 error(state, ins, "division by zero");
9261         }
9262         else if (is_one(RHS(ins, 1))) {
9263                 mkconst(state, ins, 0);
9264         }
9265         else if (is_pow2(RHS(ins, 1))) {
9266                 struct triple *val;
9267                 val = int_const(state, ins->type, RHS(ins, 1)->u.cval - 1);
9268                 ins->op = OP_AND;
9269                 insert_triple(state, state->global_pool, val);
9270                 unuse_triple(RHS(ins, 1), ins);
9271                 use_triple(val, ins);
9272                 RHS(ins, 1) = val;
9273         }
9274 }
9275
9276 static void simplify_add(struct compile_state *state, struct triple *ins)
9277 {
9278         /* start with the pointer on the left */
9279         if (is_pointer(RHS(ins, 1))) {
9280                 struct triple *tmp;
9281                 tmp = RHS(ins, 0);
9282                 RHS(ins, 0) = RHS(ins, 1);
9283                 RHS(ins, 1) = tmp;
9284         }
9285         if (is_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9286                 if (RHS(ins, 0)->op == OP_INTCONST) {
9287                         ulong_t left, right;
9288                         left  = read_const(state, ins, RHS(ins, 0));
9289                         right = read_const(state, ins, RHS(ins, 1));
9290                         mkconst(state, ins, left + right);
9291                 }
9292                 else if (RHS(ins, 0)->op == OP_ADDRCONST) {
9293                         struct triple *sdecl;
9294                         ulong_t left, right;
9295                         sdecl = MISC(RHS(ins, 0), 0);
9296                         left  = RHS(ins, 0)->u.cval;
9297                         right = RHS(ins, 1)->u.cval;
9298                         mkaddr_const(state, ins, sdecl, left + right);
9299                 }
9300                 else {
9301                         internal_warning(state, ins, "Optimize me!");
9302                 }
9303         }
9304         else if (is_const(RHS(ins, 0)) && !is_const(RHS(ins, 1))) {
9305                 struct triple *tmp;
9306                 tmp = RHS(ins, 1);
9307                 RHS(ins, 1) = RHS(ins, 0);
9308                 RHS(ins, 0) = tmp;
9309         }
9310 }
9311
9312 static void simplify_sub(struct compile_state *state, struct triple *ins)
9313 {
9314         if (is_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9315                 if (RHS(ins, 0)->op == OP_INTCONST) {
9316                         ulong_t left, right;
9317                         left  = read_const(state, ins, RHS(ins, 0));
9318                         right = read_const(state, ins, RHS(ins, 1));
9319                         mkconst(state, ins, left - right);
9320                 }
9321                 else if (RHS(ins, 0)->op == OP_ADDRCONST) {
9322                         struct triple *sdecl;
9323                         ulong_t left, right;
9324                         sdecl = MISC(RHS(ins, 0), 0);
9325                         left  = RHS(ins, 0)->u.cval;
9326                         right = RHS(ins, 1)->u.cval;
9327                         mkaddr_const(state, ins, sdecl, left - right);
9328                 }
9329                 else {
9330                         internal_warning(state, ins, "Optimize me!");
9331                 }
9332         }
9333 }
9334
9335 static void simplify_sl(struct compile_state *state, struct triple *ins)
9336 {
9337         if (is_simple_const(RHS(ins, 1))) {
9338                 ulong_t right;
9339                 right = read_const(state, ins, RHS(ins, 1));
9340                 if (right >= (size_of(state, ins->type))) {
9341                         warning(state, ins, "left shift count >= width of type");
9342                 }
9343         }
9344         if (is_simple_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9345                 ulong_t left, right;
9346                 left  = read_const(state, ins, RHS(ins, 0));
9347                 right = read_const(state, ins, RHS(ins, 1));
9348                 mkconst(state, ins,  left << right);
9349         }
9350 }
9351
9352 static void simplify_usr(struct compile_state *state, struct triple *ins)
9353 {
9354         if (is_simple_const(RHS(ins, 1))) {
9355                 ulong_t right;
9356                 right = read_const(state, ins, RHS(ins, 1));
9357                 if (right >= (size_of(state, ins->type))) {
9358                         warning(state, ins, "right shift count >= width of type");
9359                 }
9360         }
9361         if (is_simple_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9362                 ulong_t left, right;
9363                 left  = read_const(state, ins, RHS(ins, 0));
9364                 right = read_const(state, ins, RHS(ins, 1));
9365                 mkconst(state, ins, left >> right);
9366         }
9367 }
9368
9369 static void simplify_ssr(struct compile_state *state, struct triple *ins)
9370 {
9371         if (is_simple_const(RHS(ins, 1))) {
9372                 ulong_t right;
9373                 right = read_const(state, ins, RHS(ins, 1));
9374                 if (right >= (size_of(state, ins->type))) {
9375                         warning(state, ins, "right shift count >= width of type");
9376                 }
9377         }
9378         if (is_simple_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9379                 long_t left, right;
9380                 left  = read_sconst(state, ins, RHS(ins, 0));
9381                 right = read_sconst(state, ins, RHS(ins, 1));
9382                 mkconst(state, ins, left >> right);
9383         }
9384 }
9385
9386 static void simplify_and(struct compile_state *state, struct triple *ins)
9387 {
9388         struct triple *left, *right;
9389         left = RHS(ins, 0);
9390         right = RHS(ins, 1);
9391
9392         if (is_simple_const(left) && is_simple_const(right)) {
9393                 ulong_t lval, rval;
9394                 lval = read_const(state, ins, left);
9395                 rval = read_const(state, ins, right);
9396                 mkconst(state, ins, lval & rval);
9397         }
9398         else if (is_zero(right) || is_zero(left)) {
9399                 mkconst(state, ins, 0);
9400         }
9401 }
9402
9403 static void simplify_or(struct compile_state *state, struct triple *ins)
9404 {
9405         struct triple *left, *right;
9406         left = RHS(ins, 0);
9407         right = RHS(ins, 1);
9408
9409         if (is_simple_const(left) && is_simple_const(right)) {
9410                 ulong_t lval, rval;
9411                 lval = read_const(state, ins, left);
9412                 rval = read_const(state, ins, right);
9413                 mkconst(state, ins, lval | rval);
9414         }
9415 #if 0 /* I need to handle type mismatches here... */
9416         else if (is_zero(right)) {
9417                 mkcopy(state, ins, left);
9418         }
9419         else if (is_zero(left)) {
9420                 mkcopy(state, ins, right);
9421         }
9422 #endif
9423 }
9424
9425 static void simplify_xor(struct compile_state *state, struct triple *ins)
9426 {
9427         if (is_simple_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9428                 ulong_t left, right;
9429                 left  = read_const(state, ins, RHS(ins, 0));
9430                 right = read_const(state, ins, RHS(ins, 1));
9431                 mkconst(state, ins, left ^ right);
9432         }
9433 }
9434
9435 static void simplify_pos(struct compile_state *state, struct triple *ins)
9436 {
9437         if (is_const(RHS(ins, 0))) {
9438                 mkconst(state, ins, RHS(ins, 0)->u.cval);
9439         }
9440         else {
9441                 mkcopy(state, ins, RHS(ins, 0));
9442         }
9443 }
9444
9445 static void simplify_neg(struct compile_state *state, struct triple *ins)
9446 {
9447         if (is_simple_const(RHS(ins, 0))) {
9448                 ulong_t left;
9449                 left = read_const(state, ins, RHS(ins, 0));
9450                 mkconst(state, ins, -left);
9451         }
9452         else if (RHS(ins, 0)->op == OP_NEG) {
9453                 mkcopy(state, ins, RHS(RHS(ins, 0), 0));
9454         }
9455 }
9456
9457 static void simplify_invert(struct compile_state *state, struct triple *ins)
9458 {
9459         if (is_simple_const(RHS(ins, 0))) {
9460                 ulong_t left;
9461                 left = read_const(state, ins, RHS(ins, 0));
9462                 mkconst(state, ins, ~left);
9463         }
9464 }
9465
9466 static void simplify_eq(struct compile_state *state, struct triple *ins)
9467 {
9468         struct triple *left, *right;
9469         left = RHS(ins, 0);
9470         right = RHS(ins, 1);
9471
9472         if (is_const(left) && is_const(right)) {
9473                 int val;
9474                 val = const_eq(state, ins, left, right);
9475                 if (val >= 0) {
9476                         mkconst(state, ins, val == 1);
9477                 }
9478         }
9479         else if (left == right) {
9480                 mkconst(state, ins, 1);
9481         }
9482 }
9483
9484 static void simplify_noteq(struct compile_state *state, struct triple *ins)
9485 {
9486         struct triple *left, *right;
9487         left = RHS(ins, 0);
9488         right = RHS(ins, 1);
9489
9490         if (is_const(left) && is_const(right)) {
9491                 int val;
9492                 val = const_eq(state, ins, left, right);
9493                 if (val >= 0) {
9494                         mkconst(state, ins, val != 1);
9495                 }
9496         }
9497         if (left == right) {
9498                 mkconst(state, ins, 0);
9499         }
9500 }
9501
9502 static void simplify_sless(struct compile_state *state, struct triple *ins)
9503 {
9504         struct triple *left, *right;
9505         left = RHS(ins, 0);
9506         right = RHS(ins, 1);
9507
9508         if (is_const(left) && is_const(right)) {
9509                 int val;
9510                 val = const_scmp(state, ins, left, right);
9511                 if ((val >= -1) && (val <= 1)) {
9512                         mkconst(state, ins, val < 0);
9513                 }
9514         }
9515         else if (left == right) {
9516                 mkconst(state, ins, 0);
9517         }
9518 }
9519
9520 static void simplify_uless(struct compile_state *state, struct triple *ins)
9521 {
9522         struct triple *left, *right;
9523         left = RHS(ins, 0);
9524         right = RHS(ins, 1);
9525
9526         if (is_const(left) && is_const(right)) {
9527                 int val;
9528                 val = const_ucmp(state, ins, left, right);
9529                 if ((val >= -1) && (val <= 1)) {
9530                         mkconst(state, ins, val < 0);
9531                 }
9532         }
9533         else if (is_zero(right)) {
9534                 mkconst(state, ins, 0);
9535         }
9536         else if (left == right) {
9537                 mkconst(state, ins, 0);
9538         }
9539 }
9540
9541 static void simplify_smore(struct compile_state *state, struct triple *ins)
9542 {
9543         struct triple *left, *right;
9544         left = RHS(ins, 0);
9545         right = RHS(ins, 1);
9546
9547         if (is_const(left) && is_const(right)) {
9548                 int val;
9549                 val = const_scmp(state, ins, left, right);
9550                 if ((val >= -1) && (val <= 1)) {
9551                         mkconst(state, ins, val > 0);
9552                 }
9553         }
9554         else if (left == right) {
9555                 mkconst(state, ins, 0);
9556         }
9557 }
9558
9559 static void simplify_umore(struct compile_state *state, struct triple *ins)
9560 {
9561         struct triple *left, *right;
9562         left = RHS(ins, 0);
9563         right = RHS(ins, 1);
9564
9565         if (is_const(left) && is_const(right)) {
9566                 int val;
9567                 val = const_ucmp(state, ins, left, right);
9568                 if ((val >= -1) && (val <= 1)) {
9569                         mkconst(state, ins, val > 0);
9570                 }
9571         }
9572         else if (is_zero(left)) {
9573                 mkconst(state, ins, 0);
9574         }
9575         else if (left == right) {
9576                 mkconst(state, ins, 0);
9577         }
9578 }
9579
9580
9581 static void simplify_slesseq(struct compile_state *state, struct triple *ins)
9582 {
9583         struct triple *left, *right;
9584         left = RHS(ins, 0);
9585         right = RHS(ins, 1);
9586
9587         if (is_const(left) && is_const(right)) {
9588                 int val;
9589                 val = const_scmp(state, ins, left, right);
9590                 if ((val >= -1) && (val <= 1)) {
9591                         mkconst(state, ins, val <= 0);
9592                 }
9593         }
9594         else if (left == right) {
9595                 mkconst(state, ins, 1);
9596         }
9597 }
9598
9599 static void simplify_ulesseq(struct compile_state *state, struct triple *ins)
9600 {
9601         struct triple *left, *right;
9602         left = RHS(ins, 0);
9603         right = RHS(ins, 1);
9604
9605         if (is_const(left) && is_const(right)) {
9606                 int val;
9607                 val = const_ucmp(state, ins, left, right);
9608                 if ((val >= -1) && (val <= 1)) {
9609                         mkconst(state, ins, val <= 0);
9610                 }
9611         }
9612         else if (is_zero(left)) {
9613                 mkconst(state, ins, 1);
9614         }
9615         else if (left == right) {
9616                 mkconst(state, ins, 1);
9617         }
9618 }
9619
9620 static void simplify_smoreeq(struct compile_state *state, struct triple *ins)
9621 {
9622         struct triple *left, *right;
9623         left = RHS(ins, 0);
9624         right = RHS(ins, 1);
9625
9626         if (is_const(left) && is_const(right)) {
9627                 int val;
9628                 val = const_scmp(state, ins, left, right);
9629                 if ((val >= -1) && (val <= 1)) {
9630                         mkconst(state, ins, val >= 0);
9631                 }
9632         }
9633         else if (left == right) {
9634                 mkconst(state, ins, 1);
9635         }
9636 }
9637
9638 static void simplify_umoreeq(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_ucmp(state, ins, left, right);
9647                 if ((val >= -1) && (val <= 1)) {
9648                         mkconst(state, ins, val >= 0);
9649                 }
9650         }
9651         else if (is_zero(right)) {
9652                 mkconst(state, ins, 1);
9653         }
9654         else if (left == right) {
9655                 mkconst(state, ins, 1);
9656         }
9657 }
9658
9659 static void simplify_lfalse(struct compile_state *state, struct triple *ins)
9660 {
9661         struct triple *rhs;
9662         rhs = RHS(ins, 0);
9663
9664         if (is_const(rhs)) {
9665                 mkconst(state, ins, !const_ltrue(state, ins, rhs));
9666         }
9667         /* Otherwise if I am the only user... */
9668         else if ((rhs->use) &&
9669                 (rhs->use->member == ins) && (rhs->use->next == 0)) {
9670                 int need_copy = 1;
9671                 /* Invert a boolean operation */
9672                 switch(rhs->op) {
9673                 case OP_LTRUE:   rhs->op = OP_LFALSE;  break;
9674                 case OP_LFALSE:  rhs->op = OP_LTRUE;   break;
9675                 case OP_EQ:      rhs->op = OP_NOTEQ;   break;
9676                 case OP_NOTEQ:   rhs->op = OP_EQ;      break;
9677                 case OP_SLESS:   rhs->op = OP_SMOREEQ; break;
9678                 case OP_ULESS:   rhs->op = OP_UMOREEQ; break;
9679                 case OP_SMORE:   rhs->op = OP_SLESSEQ; break;
9680                 case OP_UMORE:   rhs->op = OP_ULESSEQ; break;
9681                 case OP_SLESSEQ: rhs->op = OP_SMORE;   break;
9682                 case OP_ULESSEQ: rhs->op = OP_UMORE;   break;
9683                 case OP_SMOREEQ: rhs->op = OP_SLESS;   break;
9684                 case OP_UMOREEQ: rhs->op = OP_ULESS;   break;
9685                 default:
9686                         need_copy = 0;
9687                         break;
9688                 }
9689                 if (need_copy) {
9690                         mkcopy(state, ins, rhs);
9691                 }
9692         }
9693 }
9694
9695 static void simplify_ltrue (struct compile_state *state, struct triple *ins)
9696 {
9697         struct triple *rhs;
9698         rhs = RHS(ins, 0);
9699
9700         if (is_const(rhs)) {
9701                 mkconst(state, ins, const_ltrue(state, ins, rhs));
9702         }
9703         else switch(rhs->op) {
9704         case OP_LTRUE:   case OP_LFALSE:  case OP_EQ:      case OP_NOTEQ:
9705         case OP_SLESS:   case OP_ULESS:   case OP_SMORE:   case OP_UMORE:
9706         case OP_SLESSEQ: case OP_ULESSEQ: case OP_SMOREEQ: case OP_UMOREEQ:
9707                 mkcopy(state, ins, rhs);
9708         }
9709
9710 }
9711
9712 static void simplify_load(struct compile_state *state, struct triple *ins)
9713 {
9714         struct triple *addr, *sdecl, *blob;
9715
9716         /* If I am doing a load with a constant pointer from a constant
9717          * table get the value.
9718          */
9719         addr = RHS(ins, 0);
9720         if ((addr->op == OP_ADDRCONST) && (sdecl = MISC(addr, 0)) &&
9721                 (sdecl->op == OP_SDECL) && (blob = MISC(sdecl, 0)) &&
9722                 (blob->op == OP_BLOBCONST)) {
9723                 unsigned char buffer[SIZEOF_WORD];
9724                 size_t reg_size, mem_size;
9725                 const char *src, *end;
9726                 ulong_t val;
9727                 reg_size = reg_size_of(state, ins->type);
9728                 if (reg_size > REG_SIZEOF_REG) {
9729                         internal_error(state, ins, "load size greater than register");
9730                 }
9731                 mem_size = size_of(state, ins->type);
9732                 end = blob->u.blob;
9733                 end += bits_to_bytes(size_of(state, sdecl->type));
9734                 src = blob->u.blob;
9735                 src += addr->u.cval;
9736
9737                 if (src > end) {
9738                         error(state, ins, "Load address out of bounds");
9739                 }
9740
9741                 memset(buffer, 0, sizeof(buffer));
9742                 memcpy(buffer, src, bits_to_bytes(mem_size));
9743
9744                 switch(mem_size) {
9745                 case SIZEOF_I8:  val = *((uint8_t *) buffer); break;
9746                 case SIZEOF_I16: val = *((uint16_t *)buffer); break;
9747                 case SIZEOF_I32: val = *((uint32_t *)buffer); break;
9748                 case SIZEOF_I64: val = *((uint64_t *)buffer); break;
9749                 default:
9750                         internal_error(state, ins, "mem_size: %d not handled",
9751                                 mem_size);
9752                         val = 0;
9753                         break;
9754                 }
9755                 mkconst(state, ins, val);
9756         }
9757 }
9758
9759 static void simplify_uextract(struct compile_state *state, struct triple *ins)
9760 {
9761         if (is_simple_const(RHS(ins, 0))) {
9762                 ulong_t val;
9763                 ulong_t mask;
9764                 val = read_const(state, ins, RHS(ins, 0));
9765                 mask = 1;
9766                 mask <<= ins->u.bitfield.size;
9767                 mask -= 1;
9768                 val >>= ins->u.bitfield.offset;
9769                 val &= mask;
9770                 mkconst(state, ins, val);
9771         }
9772 }
9773
9774 static void simplify_sextract(struct compile_state *state, struct triple *ins)
9775 {
9776         if (is_simple_const(RHS(ins, 0))) {
9777                 ulong_t val;
9778                 ulong_t mask;
9779                 long_t sval;
9780                 val = read_const(state, ins, RHS(ins, 0));
9781                 mask = 1;
9782                 mask <<= ins->u.bitfield.size;
9783                 mask -= 1;
9784                 val >>= ins->u.bitfield.offset;
9785                 val &= mask;
9786                 val <<= (SIZEOF_LONG - ins->u.bitfield.size);
9787                 sval = val;
9788                 sval >>= (SIZEOF_LONG - ins->u.bitfield.size); 
9789                 mkconst(state, ins, sval);
9790         }
9791 }
9792
9793 static void simplify_deposit(struct compile_state *state, struct triple *ins)
9794 {
9795         if (is_simple_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9796                 ulong_t targ, val;
9797                 ulong_t mask;
9798                 targ = read_const(state, ins, RHS(ins, 0));
9799                 val  = read_const(state, ins, RHS(ins, 1));
9800                 mask = 1;
9801                 mask <<= ins->u.bitfield.size;
9802                 mask -= 1;
9803                 mask <<= ins->u.bitfield.offset;
9804                 targ &= ~mask;
9805                 val <<= ins->u.bitfield.offset;
9806                 val &= mask;
9807                 targ |= val;
9808                 mkconst(state, ins, targ);
9809         }
9810 }
9811
9812 static void simplify_copy(struct compile_state *state, struct triple *ins)
9813 {
9814         struct triple *right;
9815         right = RHS(ins, 0);
9816         if (is_subset_type(ins->type, right->type)) {
9817                 ins->type = right->type;
9818         }
9819         if (equiv_types(ins->type, right->type)) {
9820                 ins->op = OP_COPY;/* I don't need to convert if the types match */
9821         } else {
9822                 if (ins->op == OP_COPY) {
9823                         internal_error(state, ins, "type mismatch on copy");
9824                 }
9825         }
9826         if (is_const(right) && (right->op == OP_ADDRCONST) && is_pointer(ins)) {
9827                 struct triple *sdecl;
9828                 ulong_t offset;
9829                 sdecl  = MISC(right, 0);
9830                 offset = right->u.cval;
9831                 mkaddr_const(state, ins, sdecl, offset);
9832         }
9833         else if (is_const(right) && is_write_compatible(state, ins->type, right->type)) {
9834                 switch(right->op) {
9835                 case OP_INTCONST:
9836                 {
9837                         ulong_t left;
9838                         left = read_const(state, ins, right);
9839                         /* Ensure I have not overflowed the destination. */
9840                         if (size_of(state, right->type) > size_of(state, ins->type)) {
9841                                 ulong_t mask;
9842                                 mask = 1;
9843                                 mask <<= size_of(state, ins->type);
9844                                 mask -= 1;
9845                                 left &= mask;
9846                         }
9847                         /* Ensure I am properly sign extended */
9848                         if (size_of(state, right->type) < size_of(state, ins->type) &&
9849                                 is_signed(right->type)) {
9850                                 long_t val;
9851                                 int shift;
9852                                 shift = SIZEOF_LONG - size_of(state, right->type);
9853                                 val = left;
9854                                 val <<= shift;
9855                                 val >>= shift;
9856                                 left = val;
9857                         }
9858                         mkconst(state, ins, left);
9859                         break;
9860                 }
9861                 default:
9862                         internal_error(state, ins, "uknown constant");
9863                         break;
9864                 }
9865         }
9866 }
9867
9868 static int phi_present(struct block *block)
9869 {
9870         struct triple *ptr;
9871         if (!block) {
9872                 return 0;
9873         }
9874         ptr = block->first;
9875         do {
9876                 if (ptr->op == OP_PHI) {
9877                         return 1;
9878                 }
9879                 ptr = ptr->next;
9880         } while(ptr != block->last);
9881         return 0;
9882 }
9883
9884 static int phi_dependency(struct block *block)
9885 {
9886         /* A block has a phi dependency if a phi function
9887          * depends on that block to exist, and makes a block
9888          * that is otherwise useless unsafe to remove.
9889          */
9890         if (block) {
9891                 struct block_set *edge;
9892                 for(edge = block->edges; edge; edge = edge->next) {
9893                         if (phi_present(edge->member)) {
9894                                 return 1;
9895                         }
9896                 }
9897         }
9898         return 0;
9899 }
9900
9901 static struct triple *branch_target(struct compile_state *state, struct triple *ins)
9902 {
9903         struct triple *targ;
9904         targ = TARG(ins, 0);
9905         /* During scc_transform temporary triples are allocated that
9906          * loop back onto themselves. If I see one don't advance the
9907          * target.
9908          */
9909         while(triple_is_structural(state, targ) && 
9910                 (targ->next != targ) && (targ->next != state->first)) {
9911                 targ = targ->next;
9912         }
9913         return targ;
9914 }
9915
9916
9917 static void simplify_branch(struct compile_state *state, struct triple *ins)
9918 {
9919         int simplified, loops;
9920         if ((ins->op != OP_BRANCH) && (ins->op != OP_CBRANCH)) {
9921                 internal_error(state, ins, "not branch");
9922         }
9923         if (ins->use != 0) {
9924                 internal_error(state, ins, "branch use");
9925         }
9926         /* The challenge here with simplify branch is that I need to 
9927          * make modifications to the control flow graph as well
9928          * as to the branch instruction itself.  That is handled
9929          * by rebuilding the basic blocks after simplify all is called.
9930          */
9931
9932         /* If we have a branch to an unconditional branch update
9933          * our target.  But watch out for dependencies from phi
9934          * functions.
9935          * Also only do this a limited number of times so
9936          * we don't get into an infinite loop.
9937          */
9938         loops = 0;
9939         do {
9940                 struct triple *targ;
9941                 simplified = 0;
9942                 targ = branch_target(state, ins);
9943                 if ((targ != ins) && (targ->op == OP_BRANCH) && 
9944                         !phi_dependency(targ->u.block))
9945                 {
9946                         unuse_triple(TARG(ins, 0), ins);
9947                         TARG(ins, 0) = TARG(targ, 0);
9948                         use_triple(TARG(ins, 0), ins);
9949                         simplified = 1;
9950                 }
9951         } while(simplified && (++loops < 20));
9952
9953         /* If we have a conditional branch with a constant condition
9954          * make it an unconditional branch.
9955          */
9956         if ((ins->op == OP_CBRANCH) && is_simple_const(RHS(ins, 0))) {
9957                 struct triple *targ;
9958                 ulong_t value;
9959                 value = read_const(state, ins, RHS(ins, 0));
9960                 unuse_triple(RHS(ins, 0), ins);
9961                 targ = TARG(ins, 0);
9962                 ins->rhs  = 0;
9963                 ins->targ = 1;
9964                 ins->op = OP_BRANCH;
9965                 if (value) {
9966                         unuse_triple(ins->next, ins);
9967                         TARG(ins, 0) = targ;
9968                 }
9969                 else {
9970                         unuse_triple(targ, ins);
9971                         TARG(ins, 0) = ins->next;
9972                 }
9973         }
9974
9975         /* If we have a branch to the next instruction,
9976          * make it a noop.
9977          */
9978         if (TARG(ins, 0) == ins->next) {
9979                 unuse_triple(TARG(ins, 0), ins);
9980                 if (ins->op == OP_CBRANCH) {
9981                         unuse_triple(RHS(ins, 0), ins);
9982                         unuse_triple(ins->next, ins);
9983                 }
9984                 ins->lhs = 0;
9985                 ins->rhs = 0;
9986                 ins->misc = 0;
9987                 ins->targ = 0;
9988                 ins->op = OP_NOOP;
9989                 if (ins->use) {
9990                         internal_error(state, ins, "noop use != 0");
9991                 }
9992         }
9993 }
9994
9995 static void simplify_label(struct compile_state *state, struct triple *ins)
9996 {
9997         /* Ignore volatile labels */
9998         if (!triple_is_pure(state, ins, ins->id)) {
9999                 return;
10000         }
10001         if (ins->use == 0) {
10002                 ins->op = OP_NOOP;
10003         }
10004         else if (ins->prev->op == OP_LABEL) {
10005                 /* In general it is not safe to merge one label that
10006                  * imediately follows another.  The problem is that the empty
10007                  * looking block may have phi functions that depend on it.
10008                  */
10009                 if (!phi_dependency(ins->prev->u.block)) {
10010                         struct triple_set *user, *next;
10011                         ins->op = OP_NOOP;
10012                         for(user = ins->use; user; user = next) {
10013                                 struct triple *use, **expr;
10014                                 next = user->next;
10015                                 use = user->member;
10016                                 expr = triple_targ(state, use, 0);
10017                                 for(;expr; expr = triple_targ(state, use, expr)) {
10018                                         if (*expr == ins) {
10019                                                 *expr = ins->prev;
10020                                                 unuse_triple(ins, use);
10021                                                 use_triple(ins->prev, use);
10022                                         }
10023                                         
10024                                 }
10025                         }
10026                         if (ins->use) {
10027                                 internal_error(state, ins, "noop use != 0");
10028                         }
10029                 }
10030         }
10031 }
10032
10033 static void simplify_phi(struct compile_state *state, struct triple *ins)
10034 {
10035         struct triple **slot;
10036         struct triple *value;
10037         int zrhs, i;
10038         ulong_t cvalue;
10039         slot = &RHS(ins, 0);
10040         zrhs = ins->rhs;
10041         if (zrhs == 0) {
10042                 return;
10043         }
10044         /* See if all of the rhs members of a phi have the same value */
10045         if (slot[0] && is_simple_const(slot[0])) {
10046                 cvalue = read_const(state, ins, slot[0]);
10047                 for(i = 1; i < zrhs; i++) {
10048                         if (    !slot[i] ||
10049                                 !is_simple_const(slot[i]) ||
10050                                 !equiv_types(slot[0]->type, slot[i]->type) ||
10051                                 (cvalue != read_const(state, ins, slot[i]))) {
10052                                 break;
10053                         }
10054                 }
10055                 if (i == zrhs) {
10056                         mkconst(state, ins, cvalue);
10057                         return;
10058                 }
10059         }
10060         
10061         /* See if all of rhs members of a phi are the same */
10062         value = slot[0];
10063         for(i = 1; i < zrhs; i++) {
10064                 if (slot[i] != value) {
10065                         break;
10066                 }
10067         }
10068         if (i == zrhs) {
10069                 /* If the phi has a single value just copy it */
10070                 if (!is_subset_type(ins->type, value->type)) {
10071                         internal_error(state, ins, "bad input type to phi");
10072                 }
10073                 /* Make the types match */
10074                 if (!equiv_types(ins->type, value->type)) {
10075                         ins->type = value->type;
10076                 }
10077                 /* Now make the actual copy */
10078                 mkcopy(state, ins, value);
10079                 return;
10080         }
10081 }
10082
10083
10084 static void simplify_bsf(struct compile_state *state, struct triple *ins)
10085 {
10086         if (is_simple_const(RHS(ins, 0))) {
10087                 ulong_t left;
10088                 left = read_const(state, ins, RHS(ins, 0));
10089                 mkconst(state, ins, bsf(left));
10090         }
10091 }
10092
10093 static void simplify_bsr(struct compile_state *state, struct triple *ins)
10094 {
10095         if (is_simple_const(RHS(ins, 0))) {
10096                 ulong_t left;
10097                 left = read_const(state, ins, RHS(ins, 0));
10098                 mkconst(state, ins, bsr(left));
10099         }
10100 }
10101
10102
10103 typedef void (*simplify_t)(struct compile_state *state, struct triple *ins);
10104 static const struct simplify_table {
10105         simplify_t func;
10106         unsigned long flag;
10107 } table_simplify[] = {
10108 #define simplify_sdivt    simplify_noop
10109 #define simplify_udivt    simplify_noop
10110 #define simplify_piece    simplify_noop
10111
10112 [OP_SDIVT      ] = { simplify_sdivt,    COMPILER_SIMPLIFY_ARITH },
10113 [OP_UDIVT      ] = { simplify_udivt,    COMPILER_SIMPLIFY_ARITH },
10114 [OP_SMUL       ] = { simplify_smul,     COMPILER_SIMPLIFY_ARITH },
10115 [OP_UMUL       ] = { simplify_umul,     COMPILER_SIMPLIFY_ARITH },
10116 [OP_SDIV       ] = { simplify_sdiv,     COMPILER_SIMPLIFY_ARITH },
10117 [OP_UDIV       ] = { simplify_udiv,     COMPILER_SIMPLIFY_ARITH },
10118 [OP_SMOD       ] = { simplify_smod,     COMPILER_SIMPLIFY_ARITH },
10119 [OP_UMOD       ] = { simplify_umod,     COMPILER_SIMPLIFY_ARITH },
10120 [OP_ADD        ] = { simplify_add,      COMPILER_SIMPLIFY_ARITH },
10121 [OP_SUB        ] = { simplify_sub,      COMPILER_SIMPLIFY_ARITH },
10122 [OP_SL         ] = { simplify_sl,       COMPILER_SIMPLIFY_SHIFT },
10123 [OP_USR        ] = { simplify_usr,      COMPILER_SIMPLIFY_SHIFT },
10124 [OP_SSR        ] = { simplify_ssr,      COMPILER_SIMPLIFY_SHIFT },
10125 [OP_AND        ] = { simplify_and,      COMPILER_SIMPLIFY_BITWISE },
10126 [OP_XOR        ] = { simplify_xor,      COMPILER_SIMPLIFY_BITWISE },
10127 [OP_OR         ] = { simplify_or,       COMPILER_SIMPLIFY_BITWISE },
10128 [OP_POS        ] = { simplify_pos,      COMPILER_SIMPLIFY_ARITH },
10129 [OP_NEG        ] = { simplify_neg,      COMPILER_SIMPLIFY_ARITH },
10130 [OP_INVERT     ] = { simplify_invert,   COMPILER_SIMPLIFY_BITWISE },
10131
10132 [OP_EQ         ] = { simplify_eq,       COMPILER_SIMPLIFY_LOGICAL },
10133 [OP_NOTEQ      ] = { simplify_noteq,    COMPILER_SIMPLIFY_LOGICAL },
10134 [OP_SLESS      ] = { simplify_sless,    COMPILER_SIMPLIFY_LOGICAL },
10135 [OP_ULESS      ] = { simplify_uless,    COMPILER_SIMPLIFY_LOGICAL },
10136 [OP_SMORE      ] = { simplify_smore,    COMPILER_SIMPLIFY_LOGICAL },
10137 [OP_UMORE      ] = { simplify_umore,    COMPILER_SIMPLIFY_LOGICAL },
10138 [OP_SLESSEQ    ] = { simplify_slesseq,  COMPILER_SIMPLIFY_LOGICAL },
10139 [OP_ULESSEQ    ] = { simplify_ulesseq,  COMPILER_SIMPLIFY_LOGICAL },
10140 [OP_SMOREEQ    ] = { simplify_smoreeq,  COMPILER_SIMPLIFY_LOGICAL },
10141 [OP_UMOREEQ    ] = { simplify_umoreeq,  COMPILER_SIMPLIFY_LOGICAL },
10142 [OP_LFALSE     ] = { simplify_lfalse,   COMPILER_SIMPLIFY_LOGICAL },
10143 [OP_LTRUE      ] = { simplify_ltrue,    COMPILER_SIMPLIFY_LOGICAL },
10144
10145 [OP_LOAD       ] = { simplify_load,     COMPILER_SIMPLIFY_OP },
10146 [OP_STORE      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10147
10148 [OP_UEXTRACT   ] = { simplify_uextract, COMPILER_SIMPLIFY_BITFIELD },
10149 [OP_SEXTRACT   ] = { simplify_sextract, COMPILER_SIMPLIFY_BITFIELD },
10150 [OP_DEPOSIT    ] = { simplify_deposit,  COMPILER_SIMPLIFY_BITFIELD },
10151
10152 [OP_NOOP       ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10153
10154 [OP_INTCONST   ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10155 [OP_BLOBCONST  ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10156 [OP_ADDRCONST  ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10157 [OP_UNKNOWNVAL ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10158
10159 [OP_WRITE      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10160 [OP_READ       ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10161 [OP_COPY       ] = { simplify_copy,     COMPILER_SIMPLIFY_COPY },
10162 [OP_CONVERT    ] = { simplify_copy,     COMPILER_SIMPLIFY_COPY },
10163 [OP_PIECE      ] = { simplify_piece,    COMPILER_SIMPLIFY_OP },
10164 [OP_ASM        ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10165
10166 [OP_DOT        ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10167 [OP_INDEX      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10168
10169 [OP_LIST       ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10170 [OP_BRANCH     ] = { simplify_branch,   COMPILER_SIMPLIFY_BRANCH },
10171 [OP_CBRANCH    ] = { simplify_branch,   COMPILER_SIMPLIFY_BRANCH },
10172 [OP_CALL       ] = { simplify_noop,     COMPILER_SIMPLIFY_BRANCH },
10173 [OP_RET        ] = { simplify_noop,     COMPILER_SIMPLIFY_BRANCH },
10174 [OP_LABEL      ] = { simplify_label,    COMPILER_SIMPLIFY_LABEL },
10175 [OP_ADECL      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10176 [OP_SDECL      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10177 [OP_PHI        ] = { simplify_phi,      COMPILER_SIMPLIFY_PHI },
10178
10179 [OP_INB        ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10180 [OP_INW        ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10181 [OP_INL        ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10182 [OP_OUTB       ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10183 [OP_OUTW       ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10184 [OP_OUTL       ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10185 [OP_BSF        ] = { simplify_bsf,      COMPILER_SIMPLIFY_OP },
10186 [OP_BSR        ] = { simplify_bsr,      COMPILER_SIMPLIFY_OP },
10187 [OP_RDMSR      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10188 [OP_WRMSR      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },               
10189 [OP_HLT        ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10190 };
10191
10192 static inline void debug_simplify(struct compile_state *state, 
10193         simplify_t do_simplify, struct triple *ins)
10194 {
10195 #if DEBUG_SIMPLIFY_HIRES
10196                 if (state->functions_joined && (do_simplify != simplify_noop)) {
10197                         /* High resolution debugging mode */
10198                         fprintf(state->dbgout, "simplifing: ");
10199                         display_triple(state->dbgout, ins);
10200                 }
10201 #endif
10202                 do_simplify(state, ins);
10203 #if DEBUG_SIMPLIFY_HIRES
10204                 if (state->functions_joined && (do_simplify != simplify_noop)) {
10205                         /* High resolution debugging mode */
10206                         fprintf(state->dbgout, "simplified: ");
10207                         display_triple(state->dbgout, ins);
10208                 }
10209 #endif
10210 }
10211 static void simplify(struct compile_state *state, struct triple *ins)
10212 {
10213         int op;
10214         simplify_t do_simplify;
10215         if (ins == &unknown_triple) {
10216                 internal_error(state, ins, "simplifying the unknown triple?");
10217         }
10218         do {
10219                 op = ins->op;
10220                 do_simplify = 0;
10221                 if ((op < 0) || (op > sizeof(table_simplify)/sizeof(table_simplify[0]))) {
10222                         do_simplify = 0;
10223                 }
10224                 else {
10225                         do_simplify = table_simplify[op].func;
10226                 }
10227                 if (do_simplify && 
10228                         !(state->compiler->flags & table_simplify[op].flag)) {
10229                         do_simplify = simplify_noop;
10230                 }
10231                 if (do_simplify && (ins->id & TRIPLE_FLAG_VOLATILE)) {
10232                         do_simplify = simplify_noop;
10233                 }
10234         
10235                 if (!do_simplify) {
10236                         internal_error(state, ins, "cannot simplify op: %d %s",
10237                                 op, tops(op));
10238                         return;
10239                 }
10240                 debug_simplify(state, do_simplify, ins);
10241         } while(ins->op != op);
10242 }
10243
10244 static void rebuild_ssa_form(struct compile_state *state);
10245
10246 static void simplify_all(struct compile_state *state)
10247 {
10248         struct triple *ins, *first;
10249         if (!(state->compiler->flags & COMPILER_SIMPLIFY)) {
10250                 return;
10251         }
10252         first = state->first;
10253         ins = first->prev;
10254         do {
10255                 simplify(state, ins);
10256                 ins = ins->prev;
10257         } while(ins != first->prev);
10258         ins = first;
10259         do {
10260                 simplify(state, ins);
10261                 ins = ins->next;
10262         }while(ins != first);
10263         rebuild_ssa_form(state);
10264
10265         print_blocks(state, __func__, state->dbgout);
10266 }
10267
10268 /*
10269  * Builtins....
10270  * ============================
10271  */
10272
10273 static void register_builtin_function(struct compile_state *state,
10274         const char *name, int op, struct type *rtype, ...)
10275 {
10276         struct type *ftype, *atype, *ctype, *crtype, *param, **next;
10277         struct triple *def, *arg, *result, *work, *last, *first, *retvar, *ret;
10278         struct hash_entry *ident;
10279         struct file_state file;
10280         int parameters;
10281         int name_len;
10282         va_list args;
10283         int i;
10284
10285         /* Dummy file state to get debug handling right */
10286         memset(&file, 0, sizeof(file));
10287         file.basename = "<built-in>";
10288         file.line = 1;
10289         file.report_line = 1;
10290         file.report_name = file.basename;
10291         file.prev = state->file;
10292         state->file = &file;
10293         state->function = name;
10294
10295         /* Find the Parameter count */
10296         valid_op(state, op);
10297         parameters = table_ops[op].rhs;
10298         if (parameters < 0 ) {
10299                 internal_error(state, 0, "Invalid builtin parameter count");
10300         }
10301
10302         /* Find the function type */
10303         ftype = new_type(TYPE_FUNCTION | STOR_INLINE | STOR_STATIC, rtype, 0);
10304         ftype->elements = parameters;
10305         next = &ftype->right;
10306         va_start(args, rtype);
10307         for(i = 0; i < parameters; i++) {
10308                 atype = va_arg(args, struct type *);
10309                 if (!*next) {
10310                         *next = atype;
10311                 } else {
10312                         *next = new_type(TYPE_PRODUCT, *next, atype);
10313                         next = &((*next)->right);
10314                 }
10315         }
10316         if (!*next) {
10317                 *next = &void_type;
10318         }
10319         va_end(args);
10320
10321         /* Get the initial closure type */
10322         ctype = new_type(TYPE_JOIN, &void_type, 0);
10323         ctype->elements = 1;
10324
10325         /* Get the return type */
10326         crtype = new_type(TYPE_TUPLE, new_type(TYPE_PRODUCT, ctype, rtype), 0);
10327         crtype->elements = 2;
10328
10329         /* Generate the needed triples */
10330         def = triple(state, OP_LIST, ftype, 0, 0);
10331         first = label(state);
10332         RHS(def, 0) = first;
10333         result = flatten(state, first, variable(state, crtype));
10334         retvar = flatten(state, first, variable(state, &void_ptr_type));
10335         ret = triple(state, OP_RET, &void_type, read_expr(state, retvar), 0);
10336
10337         /* Now string them together */
10338         param = ftype->right;
10339         for(i = 0; i < parameters; i++) {
10340                 if ((param->type & TYPE_MASK) == TYPE_PRODUCT) {
10341                         atype = param->left;
10342                 } else {
10343                         atype = param;
10344                 }
10345                 arg = flatten(state, first, variable(state, atype));
10346                 param = param->right;
10347         }
10348         work = new_triple(state, op, rtype, -1, parameters);
10349         generate_lhs_pieces(state, work);
10350         for(i = 0; i < parameters; i++) {
10351                 RHS(work, i) = read_expr(state, farg(state, def, i));
10352         }
10353         if ((rtype->type & TYPE_MASK) != TYPE_VOID) {
10354                 work = write_expr(state, deref_index(state, result, 1), work);
10355         }
10356         work = flatten(state, first, work);
10357         last = flatten(state, first, label(state));
10358         ret  = flatten(state, first, ret);
10359         name_len = strlen(name);
10360         ident = lookup(state, name, name_len);
10361         ftype->type_ident = ident;
10362         symbol(state, ident, &ident->sym_ident, def, ftype);
10363         
10364         state->file = file.prev;
10365         state->function = 0;
10366         state->main_function = 0;
10367
10368         if (!state->functions) {
10369                 state->functions = def;
10370         } else {
10371                 insert_triple(state, state->functions, def);
10372         }
10373         if (state->compiler->debug & DEBUG_INLINE) {
10374                 FILE *fp = state->dbgout;
10375                 fprintf(fp, "\n");
10376                 loc(fp, state, 0);
10377                 fprintf(fp, "\n__________ %s _________\n", __FUNCTION__);
10378                 display_func(state, fp, def);
10379                 fprintf(fp, "__________ %s _________ done\n\n", __FUNCTION__);
10380         }
10381 }
10382
10383 static struct type *partial_struct(struct compile_state *state,
10384         const char *field_name, struct type *type, struct type *rest)
10385 {
10386         struct hash_entry *field_ident;
10387         struct type *result;
10388         int field_name_len;
10389
10390         field_name_len = strlen(field_name);
10391         field_ident = lookup(state, field_name, field_name_len);
10392
10393         result = clone_type(0, type);
10394         result->field_ident = field_ident;
10395
10396         if (rest) {
10397                 result = new_type(TYPE_PRODUCT, result, rest);
10398         }
10399         return result;
10400 }
10401
10402 static struct type *register_builtin_type(struct compile_state *state,
10403         const char *name, struct type *type)
10404 {
10405         struct hash_entry *ident;
10406         int name_len;
10407
10408         name_len = strlen(name);
10409         ident = lookup(state, name, name_len);
10410         
10411         if ((type->type & TYPE_MASK) == TYPE_PRODUCT) {
10412                 ulong_t elements = 0;
10413                 struct type *field;
10414                 type = new_type(TYPE_STRUCT, type, 0);
10415                 field = type->left;
10416                 while((field->type & TYPE_MASK) == TYPE_PRODUCT) {
10417                         elements++;
10418                         field = field->right;
10419                 }
10420                 elements++;
10421                 symbol(state, ident, &ident->sym_tag, 0, type);
10422                 type->type_ident = ident;
10423                 type->elements = elements;
10424         }
10425         symbol(state, ident, &ident->sym_ident, 0, type);
10426         ident->tok = TOK_TYPE_NAME;
10427         return type;
10428 }
10429
10430
10431 static void register_builtins(struct compile_state *state)
10432 {
10433         struct type *div_type, *ldiv_type;
10434         struct type *udiv_type, *uldiv_type;
10435         struct type *msr_type;
10436
10437         div_type = register_builtin_type(state, "__builtin_div_t",
10438                 partial_struct(state, "quot", &int_type,
10439                 partial_struct(state, "rem",  &int_type, 0)));
10440         ldiv_type = register_builtin_type(state, "__builtin_ldiv_t",
10441                 partial_struct(state, "quot", &long_type,
10442                 partial_struct(state, "rem",  &long_type, 0)));
10443         udiv_type = register_builtin_type(state, "__builtin_udiv_t",
10444                 partial_struct(state, "quot", &uint_type,
10445                 partial_struct(state, "rem",  &uint_type, 0)));
10446         uldiv_type = register_builtin_type(state, "__builtin_uldiv_t",
10447                 partial_struct(state, "quot", &ulong_type,
10448                 partial_struct(state, "rem",  &ulong_type, 0)));
10449
10450         register_builtin_function(state, "__builtin_div",   OP_SDIVT, div_type,
10451                 &int_type, &int_type);
10452         register_builtin_function(state, "__builtin_ldiv",  OP_SDIVT, ldiv_type,
10453                 &long_type, &long_type);
10454         register_builtin_function(state, "__builtin_udiv",  OP_UDIVT, udiv_type,
10455                 &uint_type, &uint_type);
10456         register_builtin_function(state, "__builtin_uldiv", OP_UDIVT, uldiv_type,
10457                 &ulong_type, &ulong_type);
10458
10459         register_builtin_function(state, "__builtin_inb", OP_INB, &uchar_type, 
10460                 &ushort_type);
10461         register_builtin_function(state, "__builtin_inw", OP_INW, &ushort_type,
10462                 &ushort_type);
10463         register_builtin_function(state, "__builtin_inl", OP_INL, &uint_type,   
10464                 &ushort_type);
10465
10466         register_builtin_function(state, "__builtin_outb", OP_OUTB, &void_type, 
10467                 &uchar_type, &ushort_type);
10468         register_builtin_function(state, "__builtin_outw", OP_OUTW, &void_type, 
10469                 &ushort_type, &ushort_type);
10470         register_builtin_function(state, "__builtin_outl", OP_OUTL, &void_type, 
10471                 &uint_type, &ushort_type);
10472         
10473         register_builtin_function(state, "__builtin_bsf", OP_BSF, &int_type, 
10474                 &int_type);
10475         register_builtin_function(state, "__builtin_bsr", OP_BSR, &int_type, 
10476                 &int_type);
10477
10478         msr_type = register_builtin_type(state, "__builtin_msr_t",
10479                 partial_struct(state, "lo", &ulong_type,
10480                 partial_struct(state, "hi", &ulong_type, 0)));
10481
10482         register_builtin_function(state, "__builtin_rdmsr", OP_RDMSR, msr_type,
10483                 &ulong_type);
10484         register_builtin_function(state, "__builtin_wrmsr", OP_WRMSR, &void_type,
10485                 &ulong_type, &ulong_type, &ulong_type);
10486         
10487         register_builtin_function(state, "__builtin_hlt", OP_HLT, &void_type, 
10488                 &void_type);
10489 }
10490
10491 static struct type *declarator(
10492         struct compile_state *state, struct type *type, 
10493         struct hash_entry **ident, int need_ident);
10494 static void decl(struct compile_state *state, struct triple *first);
10495 static struct type *specifier_qualifier_list(struct compile_state *state);
10496 static int isdecl_specifier(int tok);
10497 static struct type *decl_specifiers(struct compile_state *state);
10498 static int istype(int tok);
10499 static struct triple *expr(struct compile_state *state);
10500 static struct triple *assignment_expr(struct compile_state *state);
10501 static struct type *type_name(struct compile_state *state);
10502 static void statement(struct compile_state *state, struct triple *first);
10503
10504 static struct triple *call_expr(
10505         struct compile_state *state, struct triple *func)
10506 {
10507         struct triple *def;
10508         struct type *param, *type;
10509         ulong_t pvals, index;
10510
10511         if ((func->type->type & TYPE_MASK) != TYPE_FUNCTION) {
10512                 error(state, 0, "Called object is not a function");
10513         }
10514         if (func->op != OP_LIST) {
10515                 internal_error(state, 0, "improper function");
10516         }
10517         eat(state, TOK_LPAREN);
10518         /* Find the return type without any specifiers */
10519         type = clone_type(0, func->type->left);
10520         /* Count the number of rhs entries for OP_FCALL */
10521         param = func->type->right;
10522         pvals = 0;
10523         while((param->type & TYPE_MASK) == TYPE_PRODUCT) {
10524                 pvals++;
10525                 param = param->right;
10526         }
10527         if ((param->type & TYPE_MASK) != TYPE_VOID) {
10528                 pvals++;
10529         }
10530         def = new_triple(state, OP_FCALL, type, -1, pvals);
10531         MISC(def, 0) = func;
10532
10533         param = func->type->right;
10534         for(index = 0; index < pvals; index++) {
10535                 struct triple *val;
10536                 struct type *arg_type;
10537                 val = read_expr(state, assignment_expr(state));
10538                 arg_type = param;
10539                 if ((param->type & TYPE_MASK) == TYPE_PRODUCT) {
10540                         arg_type = param->left;
10541                 }
10542                 write_compatible(state, arg_type, val->type);
10543                 RHS(def, index) = val;
10544                 if (index != (pvals - 1)) {
10545                         eat(state, TOK_COMMA);
10546                         param = param->right;
10547                 }
10548         }
10549         eat(state, TOK_RPAREN);
10550         return def;
10551 }
10552
10553
10554 static struct triple *character_constant(struct compile_state *state)
10555 {
10556         struct triple *def;
10557         struct token *tk;
10558         const signed char *str, *end;
10559         int c;
10560         int str_len;
10561         tk = eat(state, TOK_LIT_CHAR);
10562         str = tk->val.str + 1;
10563         str_len = tk->str_len - 2;
10564         if (str_len <= 0) {
10565                 error(state, 0, "empty character constant");
10566         }
10567         end = str + str_len;
10568         c = char_value(state, &str, end);
10569         if (str != end) {
10570                 error(state, 0, "multibyte character constant not supported");
10571         }
10572         def = int_const(state, &char_type, (ulong_t)((long_t)c));
10573         return def;
10574 }
10575
10576 static struct triple *string_constant(struct compile_state *state)
10577 {
10578         struct triple *def;
10579         struct token *tk;
10580         struct type *type;
10581         const signed char *str, *end;
10582         signed char *buf, *ptr;
10583         int str_len;
10584
10585         buf = 0;
10586         type = new_type(TYPE_ARRAY, &char_type, 0);
10587         type->elements = 0;
10588         /* The while loop handles string concatenation */
10589         do {
10590                 tk = eat(state, TOK_LIT_STRING);
10591                 str = tk->val.str + 1;
10592                 str_len = tk->str_len - 2;
10593                 if (str_len < 0) {
10594                         error(state, 0, "negative string constant length");
10595                 }
10596                 end = str + str_len;
10597                 ptr = buf;
10598                 buf = xmalloc(type->elements + str_len + 1, "string_constant");
10599                 memcpy(buf, ptr, type->elements);
10600                 ptr = buf + type->elements;
10601                 do {
10602                         *ptr++ = char_value(state, &str, end);
10603                 } while(str < end);
10604                 type->elements = ptr - buf;
10605         } while(peek(state) == TOK_LIT_STRING);
10606         *ptr = '\0';
10607         type->elements += 1;
10608         def = triple(state, OP_BLOBCONST, type, 0, 0);
10609         def->u.blob = buf;
10610
10611         return def;
10612 }
10613
10614
10615 static struct triple *integer_constant(struct compile_state *state)
10616 {
10617         struct triple *def;
10618         unsigned long val;
10619         struct token *tk;
10620         char *end;
10621         int u, l, decimal;
10622         struct type *type;
10623
10624         tk = eat(state, TOK_LIT_INT);
10625         errno = 0;
10626         decimal = (tk->val.str[0] != '0');
10627         val = strtoul(tk->val.str, &end, 0);
10628         if ((val > ULONG_T_MAX) || ((val == ULONG_MAX) && (errno == ERANGE))) {
10629                 error(state, 0, "Integer constant to large");
10630         }
10631         u = l = 0;
10632         if ((*end == 'u') || (*end == 'U')) {
10633                 u = 1;
10634                         end++;
10635         }
10636         if ((*end == 'l') || (*end == 'L')) {
10637                 l = 1;
10638                 end++;
10639         }
10640         if ((*end == 'u') || (*end == 'U')) {
10641                 u = 1;
10642                 end++;
10643         }
10644         if (*end) {
10645                 error(state, 0, "Junk at end of integer constant");
10646         }
10647         if (u && l)  {
10648                 type = &ulong_type;
10649         }
10650         else if (l) {
10651                 type = &long_type;
10652                 if (!decimal && (val > LONG_T_MAX)) {
10653                         type = &ulong_type;
10654                 }
10655         }
10656         else if (u) {
10657                 type = &uint_type;
10658                 if (val > UINT_T_MAX) {
10659                         type = &ulong_type;
10660                 }
10661         }
10662         else {
10663                 type = &int_type;
10664                 if (!decimal && (val > INT_T_MAX) && (val <= UINT_T_MAX)) {
10665                         type = &uint_type;
10666                 }
10667                 else if (!decimal && (val > LONG_T_MAX)) {
10668                         type = &ulong_type;
10669                 }
10670                 else if (val > INT_T_MAX) {
10671                         type = &long_type;
10672                 }
10673         }
10674         def = int_const(state, type, val);
10675         return def;
10676 }
10677
10678 static struct triple *primary_expr(struct compile_state *state)
10679 {
10680         struct triple *def;
10681         int tok;
10682         tok = peek(state);
10683         switch(tok) {
10684         case TOK_IDENT:
10685         {
10686                 struct hash_entry *ident;
10687                 /* Here ident is either:
10688                  * a varable name
10689                  * a function name
10690                  */
10691                 ident = eat(state, TOK_IDENT)->ident;
10692                 if (!ident->sym_ident) {
10693                         error(state, 0, "%s undeclared", ident->name);
10694                 }
10695                 def = ident->sym_ident->def;
10696                 break;
10697         }
10698         case TOK_ENUM_CONST:
10699         {
10700                 struct hash_entry *ident;
10701                 /* Here ident is an enumeration constant */
10702                 ident = eat(state, TOK_ENUM_CONST)->ident;
10703                 if (!ident->sym_ident) {
10704                         error(state, 0, "%s undeclared", ident->name);
10705                 }
10706                 def = ident->sym_ident->def;
10707                 break;
10708         }
10709         case TOK_MIDENT:
10710         {
10711                 struct hash_entry *ident;
10712                 ident = eat(state, TOK_MIDENT)->ident;
10713                 warning(state, 0, "Replacing undefined macro: %s with 0",
10714                         ident->name);
10715                 def = int_const(state, &int_type, 0);
10716                 break;
10717         }
10718         case TOK_LPAREN:
10719                 eat(state, TOK_LPAREN);
10720                 def = expr(state);
10721                 eat(state, TOK_RPAREN);
10722                 break;
10723         case TOK_LIT_INT:
10724                 def = integer_constant(state);
10725                 break;
10726         case TOK_LIT_FLOAT:
10727                 eat(state, TOK_LIT_FLOAT);
10728                 error(state, 0, "Floating point constants not supported");
10729                 def = 0;
10730                 FINISHME();
10731                 break;
10732         case TOK_LIT_CHAR:
10733                 def = character_constant(state);
10734                 break;
10735         case TOK_LIT_STRING:
10736                 def = string_constant(state);
10737                 break;
10738         default:
10739                 def = 0;
10740                 error(state, 0, "Unexpected token: %s\n", tokens[tok]);
10741         }
10742         return def;
10743 }
10744
10745 static struct triple *postfix_expr(struct compile_state *state)
10746 {
10747         struct triple *def;
10748         int postfix;
10749         def = primary_expr(state);
10750         do {
10751                 struct triple *left;
10752                 int tok;
10753                 postfix = 1;
10754                 left = def;
10755                 switch((tok = peek(state))) {
10756                 case TOK_LBRACKET:
10757                         eat(state, TOK_LBRACKET);
10758                         def = mk_subscript_expr(state, left, expr(state));
10759                         eat(state, TOK_RBRACKET);
10760                         break;
10761                 case TOK_LPAREN:
10762                         def = call_expr(state, def);
10763                         break;
10764                 case TOK_DOT:
10765                 {
10766                         struct hash_entry *field;
10767                         eat(state, TOK_DOT);
10768                         field = eat(state, TOK_IDENT)->ident;
10769                         def = deref_field(state, def, field);
10770                         break;
10771                 }
10772                 case TOK_ARROW:
10773                 {
10774                         struct hash_entry *field;
10775                         eat(state, TOK_ARROW);
10776                         field = eat(state, TOK_IDENT)->ident;
10777                         def = mk_deref_expr(state, read_expr(state, def));
10778                         def = deref_field(state, def, field);
10779                         break;
10780                 }
10781                 case TOK_PLUSPLUS:
10782                         eat(state, TOK_PLUSPLUS);
10783                         def = mk_post_inc_expr(state, left);
10784                         break;
10785                 case TOK_MINUSMINUS:
10786                         eat(state, TOK_MINUSMINUS);
10787                         def = mk_post_dec_expr(state, left);
10788                         break;
10789                 default:
10790                         postfix = 0;
10791                         break;
10792                 }
10793         } while(postfix);
10794         return def;
10795 }
10796
10797 static struct triple *cast_expr(struct compile_state *state);
10798
10799 static struct triple *unary_expr(struct compile_state *state)
10800 {
10801         struct triple *def, *right;
10802         int tok;
10803         switch((tok = peek(state))) {
10804         case TOK_PLUSPLUS:
10805                 eat(state, TOK_PLUSPLUS);
10806                 def = mk_pre_inc_expr(state, unary_expr(state));
10807                 break;
10808         case TOK_MINUSMINUS:
10809                 eat(state, TOK_MINUSMINUS);
10810                 def = mk_pre_dec_expr(state, unary_expr(state));
10811                 break;
10812         case TOK_AND:
10813                 eat(state, TOK_AND);
10814                 def = mk_addr_expr(state, cast_expr(state), 0);
10815                 break;
10816         case TOK_STAR:
10817                 eat(state, TOK_STAR);
10818                 def = mk_deref_expr(state, read_expr(state, cast_expr(state)));
10819                 break;
10820         case TOK_PLUS:
10821                 eat(state, TOK_PLUS);
10822                 right = read_expr(state, cast_expr(state));
10823                 arithmetic(state, right);
10824                 def = integral_promotion(state, right);
10825                 break;
10826         case TOK_MINUS:
10827                 eat(state, TOK_MINUS);
10828                 right = read_expr(state, cast_expr(state));
10829                 arithmetic(state, right);
10830                 def = integral_promotion(state, right);
10831                 def = triple(state, OP_NEG, def->type, def, 0);
10832                 break;
10833         case TOK_TILDE:
10834                 eat(state, TOK_TILDE);
10835                 right = read_expr(state, cast_expr(state));
10836                 integral(state, right);
10837                 def = integral_promotion(state, right);
10838                 def = triple(state, OP_INVERT, def->type, def, 0);
10839                 break;
10840         case TOK_BANG:
10841                 eat(state, TOK_BANG);
10842                 right = read_expr(state, cast_expr(state));
10843                 bool(state, right);
10844                 def = lfalse_expr(state, right);
10845                 break;
10846         case TOK_SIZEOF:
10847         {
10848                 struct type *type;
10849                 int tok1, tok2;
10850                 eat(state, TOK_SIZEOF);
10851                 tok1 = peek(state);
10852                 tok2 = peek2(state);
10853                 if ((tok1 == TOK_LPAREN) && istype(tok2)) {
10854                         eat(state, TOK_LPAREN);
10855                         type = type_name(state);
10856                         eat(state, TOK_RPAREN);
10857                 }
10858                 else {
10859                         struct triple *expr;
10860                         expr = unary_expr(state);
10861                         type = expr->type;
10862                         release_expr(state, expr);
10863                 }
10864                 def = int_const(state, &ulong_type, size_of_in_bytes(state, type));
10865                 break;
10866         }
10867         case TOK_ALIGNOF:
10868         {
10869                 struct type *type;
10870                 int tok1, tok2;
10871                 eat(state, TOK_ALIGNOF);
10872                 tok1 = peek(state);
10873                 tok2 = peek2(state);
10874                 if ((tok1 == TOK_LPAREN) && istype(tok2)) {
10875                         eat(state, TOK_LPAREN);
10876                         type = type_name(state);
10877                         eat(state, TOK_RPAREN);
10878                 }
10879                 else {
10880                         struct triple *expr;
10881                         expr = unary_expr(state);
10882                         type = expr->type;
10883                         release_expr(state, expr);
10884                 }
10885                 def = int_const(state, &ulong_type, align_of_in_bytes(state, type));
10886                 break;
10887         }
10888         case TOK_MDEFINED:
10889         {
10890                 /* We only come here if we are called from the preprocessor */
10891                 struct hash_entry *ident;
10892                 int parens;
10893                 eat(state, TOK_MDEFINED);
10894                 parens = 0;
10895                 if (cpp_peek(state) == TOK_LPAREN) {
10896                         cpp_eat(state, TOK_LPAREN);
10897                         parens = 1;
10898                 }
10899                 ident = cpp_eat(state, TOK_MIDENT)->ident;
10900                 if (parens) {
10901                         eat(state, TOK_RPAREN);
10902                 }
10903                 def = int_const(state, &int_type, ident->sym_define != 0);
10904                 break;
10905         }
10906         default:
10907                 def = postfix_expr(state);
10908                 break;
10909         }
10910         return def;
10911 }
10912
10913 static struct triple *cast_expr(struct compile_state *state)
10914 {
10915         struct triple *def;
10916         int tok1, tok2;
10917         tok1 = peek(state);
10918         tok2 = peek2(state);
10919         if ((tok1 == TOK_LPAREN) && istype(tok2)) {
10920                 struct type *type;
10921                 eat(state, TOK_LPAREN);
10922                 type = type_name(state);
10923                 eat(state, TOK_RPAREN);
10924                 def = mk_cast_expr(state, type, cast_expr(state));
10925         }
10926         else {
10927                 def = unary_expr(state);
10928         }
10929         return def;
10930 }
10931
10932 static struct triple *mult_expr(struct compile_state *state)
10933 {
10934         struct triple *def;
10935         int done;
10936         def = cast_expr(state);
10937         do {
10938                 struct triple *left, *right;
10939                 struct type *result_type;
10940                 int tok, op, sign;
10941                 done = 0;
10942                 switch(tok = (peek(state))) {
10943                 case TOK_STAR:
10944                 case TOK_DIV:
10945                 case TOK_MOD:
10946                         left = read_expr(state, def);
10947                         arithmetic(state, left);
10948
10949                         eat(state, tok);
10950
10951                         right = read_expr(state, cast_expr(state));
10952                         arithmetic(state, right);
10953
10954                         result_type = arithmetic_result(state, left, right);
10955                         sign = is_signed(result_type);
10956                         op = -1;
10957                         switch(tok) {
10958                         case TOK_STAR: op = sign? OP_SMUL : OP_UMUL; break;
10959                         case TOK_DIV:  op = sign? OP_SDIV : OP_UDIV; break;
10960                         case TOK_MOD:  op = sign? OP_SMOD : OP_UMOD; break;
10961                         }
10962                         def = triple(state, op, result_type, left, right);
10963                         break;
10964                 default:
10965                         done = 1;
10966                         break;
10967                 }
10968         } while(!done);
10969         return def;
10970 }
10971
10972 static struct triple *add_expr(struct compile_state *state)
10973 {
10974         struct triple *def;
10975         int done;
10976         def = mult_expr(state);
10977         do {
10978                 done = 0;
10979                 switch( peek(state)) {
10980                 case TOK_PLUS:
10981                         eat(state, TOK_PLUS);
10982                         def = mk_add_expr(state, def, mult_expr(state));
10983                         break;
10984                 case TOK_MINUS:
10985                         eat(state, TOK_MINUS);
10986                         def = mk_sub_expr(state, def, mult_expr(state));
10987                         break;
10988                 default:
10989                         done = 1;
10990                         break;
10991                 }
10992         } while(!done);
10993         return def;
10994 }
10995
10996 static struct triple *shift_expr(struct compile_state *state)
10997 {
10998         struct triple *def;
10999         int done;
11000         def = add_expr(state);
11001         do {
11002                 struct triple *left, *right;
11003                 int tok, op;
11004                 done = 0;
11005                 switch((tok = peek(state))) {
11006                 case TOK_SL:
11007                 case TOK_SR:
11008                         left = read_expr(state, def);
11009                         integral(state, left);
11010                         left = integral_promotion(state, left);
11011
11012                         eat(state, tok);
11013
11014                         right = read_expr(state, add_expr(state));
11015                         integral(state, right);
11016                         right = integral_promotion(state, right);
11017                         
11018                         op = (tok == TOK_SL)? OP_SL : 
11019                                 is_signed(left->type)? OP_SSR: OP_USR;
11020
11021                         def = triple(state, op, left->type, left, right);
11022                         break;
11023                 default:
11024                         done = 1;
11025                         break;
11026                 }
11027         } while(!done);
11028         return def;
11029 }
11030
11031 static struct triple *relational_expr(struct compile_state *state)
11032 {
11033 #warning "Extend relational exprs to work on more than arithmetic types"
11034         struct triple *def;
11035         int done;
11036         def = shift_expr(state);
11037         do {
11038                 struct triple *left, *right;
11039                 struct type *arg_type;
11040                 int tok, op, sign;
11041                 done = 0;
11042                 switch((tok = peek(state))) {
11043                 case TOK_LESS:
11044                 case TOK_MORE:
11045                 case TOK_LESSEQ:
11046                 case TOK_MOREEQ:
11047                         left = read_expr(state, def);
11048                         arithmetic(state, left);
11049
11050                         eat(state, tok);
11051
11052                         right = read_expr(state, shift_expr(state));
11053                         arithmetic(state, right);
11054
11055                         arg_type = arithmetic_result(state, left, right);
11056                         sign = is_signed(arg_type);
11057                         op = -1;
11058                         switch(tok) {
11059                         case TOK_LESS:   op = sign? OP_SLESS : OP_ULESS; break;
11060                         case TOK_MORE:   op = sign? OP_SMORE : OP_UMORE; break;
11061                         case TOK_LESSEQ: op = sign? OP_SLESSEQ : OP_ULESSEQ; break;
11062                         case TOK_MOREEQ: op = sign? OP_SMOREEQ : OP_UMOREEQ; break;
11063                         }
11064                         def = triple(state, op, &int_type, left, right);
11065                         break;
11066                 default:
11067                         done = 1;
11068                         break;
11069                 }
11070         } while(!done);
11071         return def;
11072 }
11073
11074 static struct triple *equality_expr(struct compile_state *state)
11075 {
11076 #warning "Extend equality exprs to work on more than arithmetic types"
11077         struct triple *def;
11078         int done;
11079         def = relational_expr(state);
11080         do {
11081                 struct triple *left, *right;
11082                 int tok, op;
11083                 done = 0;
11084                 switch((tok = peek(state))) {
11085                 case TOK_EQEQ:
11086                 case TOK_NOTEQ:
11087                         left = read_expr(state, def);
11088                         arithmetic(state, left);
11089                         eat(state, tok);
11090                         right = read_expr(state, relational_expr(state));
11091                         arithmetic(state, right);
11092                         op = (tok == TOK_EQEQ) ? OP_EQ: OP_NOTEQ;
11093                         def = triple(state, op, &int_type, left, right);
11094                         break;
11095                 default:
11096                         done = 1;
11097                         break;
11098                 }
11099         } while(!done);
11100         return def;
11101 }
11102
11103 static struct triple *and_expr(struct compile_state *state)
11104 {
11105         struct triple *def;
11106         def = equality_expr(state);
11107         while(peek(state) == TOK_AND) {
11108                 struct triple *left, *right;
11109                 struct type *result_type;
11110                 left = read_expr(state, def);
11111                 integral(state, left);
11112                 eat(state, TOK_AND);
11113                 right = read_expr(state, equality_expr(state));
11114                 integral(state, right);
11115                 result_type = arithmetic_result(state, left, right);
11116                 def = triple(state, OP_AND, result_type, left, right);
11117         }
11118         return def;
11119 }
11120
11121 static struct triple *xor_expr(struct compile_state *state)
11122 {
11123         struct triple *def;
11124         def = and_expr(state);
11125         while(peek(state) == TOK_XOR) {
11126                 struct triple *left, *right;
11127                 struct type *result_type;
11128                 left = read_expr(state, def);
11129                 integral(state, left);
11130                 eat(state, TOK_XOR);
11131                 right = read_expr(state, and_expr(state));
11132                 integral(state, right);
11133                 result_type = arithmetic_result(state, left, right);
11134                 def = triple(state, OP_XOR, result_type, left, right);
11135         }
11136         return def;
11137 }
11138
11139 static struct triple *or_expr(struct compile_state *state)
11140 {
11141         struct triple *def;
11142         def = xor_expr(state);
11143         while(peek(state) == TOK_OR) {
11144                 struct triple *left, *right;
11145                 struct type *result_type;
11146                 left = read_expr(state, def);
11147                 integral(state, left);
11148                 eat(state, TOK_OR);
11149                 right = read_expr(state, xor_expr(state));
11150                 integral(state, right);
11151                 result_type = arithmetic_result(state, left, right);
11152                 def = triple(state, OP_OR, result_type, left, right);
11153         }
11154         return def;
11155 }
11156
11157 static struct triple *land_expr(struct compile_state *state)
11158 {
11159         struct triple *def;
11160         def = or_expr(state);
11161         while(peek(state) == TOK_LOGAND) {
11162                 struct triple *left, *right;
11163                 left = read_expr(state, def);
11164                 bool(state, left);
11165                 eat(state, TOK_LOGAND);
11166                 right = read_expr(state, or_expr(state));
11167                 bool(state, right);
11168
11169                 def = mkland_expr(state,
11170                         ltrue_expr(state, left),
11171                         ltrue_expr(state, right));
11172         }
11173         return def;
11174 }
11175
11176 static struct triple *lor_expr(struct compile_state *state)
11177 {
11178         struct triple *def;
11179         def = land_expr(state);
11180         while(peek(state) == TOK_LOGOR) {
11181                 struct triple *left, *right;
11182                 left = read_expr(state, def);
11183                 bool(state, left);
11184                 eat(state, TOK_LOGOR);
11185                 right = read_expr(state, land_expr(state));
11186                 bool(state, right);
11187
11188                 def = mklor_expr(state, 
11189                         ltrue_expr(state, left),
11190                         ltrue_expr(state, right));
11191         }
11192         return def;
11193 }
11194
11195 static struct triple *conditional_expr(struct compile_state *state)
11196 {
11197         struct triple *def;
11198         def = lor_expr(state);
11199         if (peek(state) == TOK_QUEST) {
11200                 struct triple *test, *left, *right;
11201                 bool(state, def);
11202                 test = ltrue_expr(state, read_expr(state, def));
11203                 eat(state, TOK_QUEST);
11204                 left = read_expr(state, expr(state));
11205                 eat(state, TOK_COLON);
11206                 right = read_expr(state, conditional_expr(state));
11207
11208                 def = mkcond_expr(state, test, left, right);
11209         }
11210         return def;
11211 }
11212
11213 struct cv_triple {
11214         struct triple *val;
11215         int id;
11216 };
11217
11218 static void set_cv(struct compile_state *state, struct cv_triple *cv,
11219         struct triple *dest, struct triple *val)
11220 {
11221         if (cv[dest->id].val) {
11222                 free_triple(state, cv[dest->id].val);
11223         }
11224         cv[dest->id].val = val;
11225 }
11226 static struct triple *get_cv(struct compile_state *state, struct cv_triple *cv,
11227         struct triple *src)
11228 {
11229         return cv[src->id].val;
11230 }
11231
11232 static struct triple *eval_const_expr(
11233         struct compile_state *state, struct triple *expr)
11234 {
11235         struct triple *def;
11236         if (is_const(expr)) {
11237                 def = expr;
11238         }
11239         else {
11240                 /* If we don't start out as a constant simplify into one */
11241                 struct triple *head, *ptr;
11242                 struct cv_triple *cv;
11243                 int i, count;
11244                 head = label(state); /* dummy initial triple */
11245                 flatten(state, head, expr);
11246                 count = 1;
11247                 for(ptr = head->next; ptr != head; ptr = ptr->next) {
11248                         count++;
11249                 }
11250                 cv = xcmalloc(sizeof(struct cv_triple)*count, "const value vector");
11251                 i = 1;
11252                 for(ptr = head->next; ptr != head; ptr = ptr->next) {
11253                         cv[i].val = 0;
11254                         cv[i].id  = ptr->id;
11255                         ptr->id   = i;
11256                         i++;
11257                 }
11258                 ptr = head->next;
11259                 do {
11260                         valid_ins(state, ptr);
11261                         if ((ptr->op == OP_PHI) || (ptr->op == OP_LIST)) {
11262                                 internal_error(state, ptr, 
11263                                         "unexpected %s in constant expression",
11264                                         tops(ptr->op));
11265                         }
11266                         else if (ptr->op == OP_LIST) {
11267                         }
11268                         else if (triple_is_structural(state, ptr)) {
11269                                 ptr = ptr->next;
11270                         }
11271                         else if (triple_is_ubranch(state, ptr)) {
11272                                 ptr = TARG(ptr, 0);
11273                         }
11274                         else if (triple_is_cbranch(state, ptr)) {
11275                                 struct triple *cond_val;
11276                                 cond_val = get_cv(state, cv, RHS(ptr, 0));
11277                                 if (!cond_val || !is_const(cond_val) || 
11278                                         (cond_val->op != OP_INTCONST)) 
11279                                 {
11280                                         internal_error(state, ptr, "bad branch condition");
11281                                 }
11282                                 if (cond_val->u.cval == 0) {
11283                                         ptr = ptr->next;
11284                                 } else {
11285                                         ptr = TARG(ptr, 0);
11286                                 }
11287                         }
11288                         else if (triple_is_branch(state, ptr)) {
11289                                 error(state, ptr, "bad branch type in constant expression");
11290                         }
11291                         else if (ptr->op == OP_WRITE) {
11292                                 struct triple *val;
11293                                 val = get_cv(state, cv, RHS(ptr, 0));
11294                                 
11295                                 set_cv(state, cv, MISC(ptr, 0), 
11296                                         copy_triple(state, val));
11297                                 set_cv(state, cv, ptr, 
11298                                         copy_triple(state, val));
11299                                 ptr = ptr->next;
11300                         }
11301                         else if (ptr->op == OP_READ) {
11302                                 set_cv(state, cv, ptr, 
11303                                         copy_triple(state, 
11304                                                 get_cv(state, cv, RHS(ptr, 0))));
11305                                 ptr = ptr->next;
11306                         }
11307                         else if (triple_is_pure(state, ptr, cv[ptr->id].id)) {
11308                                 struct triple *val, **rhs;
11309                                 val = copy_triple(state, ptr);
11310                                 rhs = triple_rhs(state, val, 0);
11311                                 for(; rhs; rhs = triple_rhs(state, val, rhs)) {
11312                                         if (!*rhs) {
11313                                                 internal_error(state, ptr, "Missing rhs");
11314                                         }
11315                                         *rhs = get_cv(state, cv, *rhs);
11316                                 }
11317                                 simplify(state, val);
11318                                 set_cv(state, cv, ptr, val);
11319                                 ptr = ptr->next;
11320                         }
11321                         else {
11322                                 error(state, ptr, "impure operation in constant expression");
11323                         }
11324                         
11325                 } while(ptr != head);
11326
11327                 /* Get the result value */
11328                 def = get_cv(state, cv, head->prev);
11329                 cv[head->prev->id].val = 0;
11330
11331                 /* Free the temporary values */
11332                 for(i = 0; i < count; i++) {
11333                         if (cv[i].val) {
11334                                 free_triple(state, cv[i].val);
11335                                 cv[i].val = 0;
11336                         }
11337                 }
11338                 xfree(cv);
11339                 /* Free the intermediate expressions */
11340                 while(head->next != head) {
11341                         release_triple(state, head->next);
11342                 }
11343                 free_triple(state, head);
11344         }
11345         if (!is_const(def)) {
11346                 error(state, expr, "Not a constant expression");
11347         }
11348         return def;
11349 }
11350
11351 static struct triple *constant_expr(struct compile_state *state)
11352 {
11353         return eval_const_expr(state, conditional_expr(state));
11354 }
11355
11356 static struct triple *assignment_expr(struct compile_state *state)
11357 {
11358         struct triple *def, *left, *right;
11359         int tok, op, sign;
11360         /* The C grammer in K&R shows assignment expressions
11361          * only taking unary expressions as input on their
11362          * left hand side.  But specifies the precedence of
11363          * assignemnt as the lowest operator except for comma.
11364          *
11365          * Allowing conditional expressions on the left hand side
11366          * of an assignement results in a grammar that accepts
11367          * a larger set of statements than standard C.   As long
11368          * as the subset of the grammar that is standard C behaves
11369          * correctly this should cause no problems.
11370          * 
11371          * For the extra token strings accepted by the grammar
11372          * none of them should produce a valid lvalue, so they
11373          * should not produce functioning programs.
11374          *
11375          * GCC has this bug as well, so surprises should be minimal.
11376          */
11377         def = conditional_expr(state);
11378         left = def;
11379         switch((tok = peek(state))) {
11380         case TOK_EQ:
11381                 lvalue(state, left);
11382                 eat(state, TOK_EQ);
11383                 def = write_expr(state, left, 
11384                         read_expr(state, assignment_expr(state)));
11385                 break;
11386         case TOK_TIMESEQ:
11387         case TOK_DIVEQ:
11388         case TOK_MODEQ:
11389                 lvalue(state, left);
11390                 arithmetic(state, left);
11391                 eat(state, tok);
11392                 right = read_expr(state, assignment_expr(state));
11393                 arithmetic(state, right);
11394
11395                 sign = is_signed(left->type);
11396                 op = -1;
11397                 switch(tok) {
11398                 case TOK_TIMESEQ: op = sign? OP_SMUL : OP_UMUL; break;
11399                 case TOK_DIVEQ:   op = sign? OP_SDIV : OP_UDIV; break;
11400                 case TOK_MODEQ:   op = sign? OP_SMOD : OP_UMOD; break;
11401                 }
11402                 def = write_expr(state, left,
11403                         triple(state, op, left->type, 
11404                                 read_expr(state, left), right));
11405                 break;
11406         case TOK_PLUSEQ:
11407                 lvalue(state, left);
11408                 eat(state, TOK_PLUSEQ);
11409                 def = write_expr(state, left,
11410                         mk_add_expr(state, left, assignment_expr(state)));
11411                 break;
11412         case TOK_MINUSEQ:
11413                 lvalue(state, left);
11414                 eat(state, TOK_MINUSEQ);
11415                 def = write_expr(state, left,
11416                         mk_sub_expr(state, left, assignment_expr(state)));
11417                 break;
11418         case TOK_SLEQ:
11419         case TOK_SREQ:
11420         case TOK_ANDEQ:
11421         case TOK_XOREQ:
11422         case TOK_OREQ:
11423                 lvalue(state, left);
11424                 integral(state, left);
11425                 eat(state, tok);
11426                 right = read_expr(state, assignment_expr(state));
11427                 integral(state, right);
11428                 right = integral_promotion(state, right);
11429                 sign = is_signed(left->type);
11430                 op = -1;
11431                 switch(tok) {
11432                 case TOK_SLEQ:  op = OP_SL; break;
11433                 case TOK_SREQ:  op = sign? OP_SSR: OP_USR; break;
11434                 case TOK_ANDEQ: op = OP_AND; break;
11435                 case TOK_XOREQ: op = OP_XOR; break;
11436                 case TOK_OREQ:  op = OP_OR; break;
11437                 }
11438                 def = write_expr(state, left,
11439                         triple(state, op, left->type, 
11440                                 read_expr(state, left), right));
11441                 break;
11442         }
11443         return def;
11444 }
11445
11446 static struct triple *expr(struct compile_state *state)
11447 {
11448         struct triple *def;
11449         def = assignment_expr(state);
11450         while(peek(state) == TOK_COMMA) {
11451                 eat(state, TOK_COMMA);
11452                 def = mkprog(state, def, assignment_expr(state), 0);
11453         }
11454         return def;
11455 }
11456
11457 static void expr_statement(struct compile_state *state, struct triple *first)
11458 {
11459         if (peek(state) != TOK_SEMI) {
11460                 /* lvalue conversions always apply except when certian operators
11461                  * are applied.  I apply the lvalue conversions here
11462                  * as I know no more operators will be applied.
11463                  */
11464                 flatten(state, first, lvalue_conversion(state, expr(state)));
11465         }
11466         eat(state, TOK_SEMI);
11467 }
11468
11469 static void if_statement(struct compile_state *state, struct triple *first)
11470 {
11471         struct triple *test, *jmp1, *jmp2, *middle, *end;
11472
11473         jmp1 = jmp2 = middle = 0;
11474         eat(state, TOK_IF);
11475         eat(state, TOK_LPAREN);
11476         test = expr(state);
11477         bool(state, test);
11478         /* Cleanup and invert the test */
11479         test = lfalse_expr(state, read_expr(state, test));
11480         eat(state, TOK_RPAREN);
11481         /* Generate the needed pieces */
11482         middle = label(state);
11483         jmp1 = branch(state, middle, test);
11484         /* Thread the pieces together */
11485         flatten(state, first, test);
11486         flatten(state, first, jmp1);
11487         flatten(state, first, label(state));
11488         statement(state, first);
11489         if (peek(state) == TOK_ELSE) {
11490                 eat(state, TOK_ELSE);
11491                 /* Generate the rest of the pieces */
11492                 end = label(state);
11493                 jmp2 = branch(state, end, 0);
11494                 /* Thread them together */
11495                 flatten(state, first, jmp2);
11496                 flatten(state, first, middle);
11497                 statement(state, first);
11498                 flatten(state, first, end);
11499         }
11500         else {
11501                 flatten(state, first, middle);
11502         }
11503 }
11504
11505 static void for_statement(struct compile_state *state, struct triple *first)
11506 {
11507         struct triple *head, *test, *tail, *jmp1, *jmp2, *end;
11508         struct triple *label1, *label2, *label3;
11509         struct hash_entry *ident;
11510
11511         eat(state, TOK_FOR);
11512         eat(state, TOK_LPAREN);
11513         head = test = tail = jmp1 = jmp2 = 0;
11514         if (peek(state) != TOK_SEMI) {
11515                 head = expr(state);
11516         } 
11517         eat(state, TOK_SEMI);
11518         if (peek(state) != TOK_SEMI) {
11519                 test = expr(state);
11520                 bool(state, test);
11521                 test = ltrue_expr(state, read_expr(state, test));
11522         }
11523         eat(state, TOK_SEMI);
11524         if (peek(state) != TOK_RPAREN) {
11525                 tail = expr(state);
11526         }
11527         eat(state, TOK_RPAREN);
11528         /* Generate the needed pieces */
11529         label1 = label(state);
11530         label2 = label(state);
11531         label3 = label(state);
11532         if (test) {
11533                 jmp1 = branch(state, label3, 0);
11534                 jmp2 = branch(state, label1, test);
11535         }
11536         else {
11537                 jmp2 = branch(state, label1, 0);
11538         }
11539         end = label(state);
11540         /* Remember where break and continue go */
11541         start_scope(state);
11542         ident = state->i_break;
11543         symbol(state, ident, &ident->sym_ident, end, end->type);
11544         ident = state->i_continue;
11545         symbol(state, ident, &ident->sym_ident, label2, label2->type);
11546         /* Now include the body */
11547         flatten(state, first, head);
11548         flatten(state, first, jmp1);
11549         flatten(state, first, label1);
11550         statement(state, first);
11551         flatten(state, first, label2);
11552         flatten(state, first, tail);
11553         flatten(state, first, label3);
11554         flatten(state, first, test);
11555         flatten(state, first, jmp2);
11556         flatten(state, first, end);
11557         /* Cleanup the break/continue scope */
11558         end_scope(state);
11559 }
11560
11561 static void while_statement(struct compile_state *state, struct triple *first)
11562 {
11563         struct triple *label1, *test, *label2, *jmp1, *jmp2, *end;
11564         struct hash_entry *ident;
11565         eat(state, TOK_WHILE);
11566         eat(state, TOK_LPAREN);
11567         test = expr(state);
11568         bool(state, test);
11569         test = ltrue_expr(state, read_expr(state, test));
11570         eat(state, TOK_RPAREN);
11571         /* Generate the needed pieces */
11572         label1 = label(state);
11573         label2 = label(state);
11574         jmp1 = branch(state, label2, 0);
11575         jmp2 = branch(state, label1, test);
11576         end = label(state);
11577         /* Remember where break and continue go */
11578         start_scope(state);
11579         ident = state->i_break;
11580         symbol(state, ident, &ident->sym_ident, end, end->type);
11581         ident = state->i_continue;
11582         symbol(state, ident, &ident->sym_ident, label2, label2->type);
11583         /* Thread them together */
11584         flatten(state, first, jmp1);
11585         flatten(state, first, label1);
11586         statement(state, first);
11587         flatten(state, first, label2);
11588         flatten(state, first, test);
11589         flatten(state, first, jmp2);
11590         flatten(state, first, end);
11591         /* Cleanup the break/continue scope */
11592         end_scope(state);
11593 }
11594
11595 static void do_statement(struct compile_state *state, struct triple *first)
11596 {
11597         struct triple *label1, *label2, *test, *end;
11598         struct hash_entry *ident;
11599         eat(state, TOK_DO);
11600         /* Generate the needed pieces */
11601         label1 = label(state);
11602         label2 = label(state);
11603         end = label(state);
11604         /* Remember where break and continue go */
11605         start_scope(state);
11606         ident = state->i_break;
11607         symbol(state, ident, &ident->sym_ident, end, end->type);
11608         ident = state->i_continue;
11609         symbol(state, ident, &ident->sym_ident, label2, label2->type);
11610         /* Now include the body */
11611         flatten(state, first, label1);
11612         statement(state, first);
11613         /* Cleanup the break/continue scope */
11614         end_scope(state);
11615         /* Eat the rest of the loop */
11616         eat(state, TOK_WHILE);
11617         eat(state, TOK_LPAREN);
11618         test = read_expr(state, expr(state));
11619         bool(state, test);
11620         eat(state, TOK_RPAREN);
11621         eat(state, TOK_SEMI);
11622         /* Thread the pieces together */
11623         test = ltrue_expr(state, test);
11624         flatten(state, first, label2);
11625         flatten(state, first, test);
11626         flatten(state, first, branch(state, label1, test));
11627         flatten(state, first, end);
11628 }
11629
11630
11631 static void return_statement(struct compile_state *state, struct triple *first)
11632 {
11633         struct triple *jmp, *mv, *dest, *var, *val;
11634         int last;
11635         eat(state, TOK_RETURN);
11636
11637 #warning "FIXME implement a more general excess branch elimination"
11638         val = 0;
11639         /* If we have a return value do some more work */
11640         if (peek(state) != TOK_SEMI) {
11641                 val = read_expr(state, expr(state));
11642         }
11643         eat(state, TOK_SEMI);
11644
11645         /* See if this last statement in a function */
11646         last = ((peek(state) == TOK_RBRACE) && 
11647                 (state->scope_depth == GLOBAL_SCOPE_DEPTH +2));
11648
11649         /* Find the return variable */
11650         var = fresult(state, state->main_function);
11651
11652         /* Find the return destination */
11653         dest = state->i_return->sym_ident->def;
11654         mv = jmp = 0;
11655         /* If needed generate a jump instruction */
11656         if (!last) {
11657                 jmp = branch(state, dest, 0);
11658         }
11659         /* If needed generate an assignment instruction */
11660         if (val) {
11661                 mv = write_expr(state, deref_index(state, var, 1), val);
11662         }
11663         /* Now put the code together */
11664         if (mv) {
11665                 flatten(state, first, mv);
11666                 flatten(state, first, jmp);
11667         }
11668         else if (jmp) {
11669                 flatten(state, first, jmp);
11670         }
11671 }
11672
11673 static void break_statement(struct compile_state *state, struct triple *first)
11674 {
11675         struct triple *dest;
11676         eat(state, TOK_BREAK);
11677         eat(state, TOK_SEMI);
11678         if (!state->i_break->sym_ident) {
11679                 error(state, 0, "break statement not within loop or switch");
11680         }
11681         dest = state->i_break->sym_ident->def;
11682         flatten(state, first, branch(state, dest, 0));
11683 }
11684
11685 static void continue_statement(struct compile_state *state, struct triple *first)
11686 {
11687         struct triple *dest;
11688         eat(state, TOK_CONTINUE);
11689         eat(state, TOK_SEMI);
11690         if (!state->i_continue->sym_ident) {
11691                 error(state, 0, "continue statement outside of a loop");
11692         }
11693         dest = state->i_continue->sym_ident->def;
11694         flatten(state, first, branch(state, dest, 0));
11695 }
11696
11697 static void goto_statement(struct compile_state *state, struct triple *first)
11698 {
11699         struct hash_entry *ident;
11700         eat(state, TOK_GOTO);
11701         ident = eat(state, TOK_IDENT)->ident;
11702         if (!ident->sym_label) {
11703                 /* If this is a forward branch allocate the label now,
11704                  * it will be flattend in the appropriate location later.
11705                  */
11706                 struct triple *ins;
11707                 ins = label(state);
11708                 label_symbol(state, ident, ins, FUNCTION_SCOPE_DEPTH);
11709         }
11710         eat(state, TOK_SEMI);
11711
11712         flatten(state, first, branch(state, ident->sym_label->def, 0));
11713 }
11714
11715 static void labeled_statement(struct compile_state *state, struct triple *first)
11716 {
11717         struct triple *ins;
11718         struct hash_entry *ident;
11719
11720         ident = eat(state, TOK_IDENT)->ident;
11721         if (ident->sym_label && ident->sym_label->def) {
11722                 ins = ident->sym_label->def;
11723                 put_occurance(ins->occurance);
11724                 ins->occurance = new_occurance(state);
11725         }
11726         else {
11727                 ins = label(state);
11728                 label_symbol(state, ident, ins, FUNCTION_SCOPE_DEPTH);
11729         }
11730         if (ins->id & TRIPLE_FLAG_FLATTENED) {
11731                 error(state, 0, "label %s already defined", ident->name);
11732         }
11733         flatten(state, first, ins);
11734
11735         eat(state, TOK_COLON);
11736         statement(state, first);
11737 }
11738
11739 static void switch_statement(struct compile_state *state, struct triple *first)
11740 {
11741         struct triple *value, *top, *end, *dbranch;
11742         struct hash_entry *ident;
11743
11744         /* See if we have a valid switch statement */
11745         eat(state, TOK_SWITCH);
11746         eat(state, TOK_LPAREN);
11747         value = expr(state);
11748         integral(state, value);
11749         value = read_expr(state, value);
11750         eat(state, TOK_RPAREN);
11751         /* Generate the needed pieces */
11752         top = label(state);
11753         end = label(state);
11754         dbranch = branch(state, end, 0);
11755         /* Remember where case branches and break goes */
11756         start_scope(state);
11757         ident = state->i_switch;
11758         symbol(state, ident, &ident->sym_ident, value, value->type);
11759         ident = state->i_case;
11760         symbol(state, ident, &ident->sym_ident, top, top->type);
11761         ident = state->i_break;
11762         symbol(state, ident, &ident->sym_ident, end, end->type);
11763         ident = state->i_default;
11764         symbol(state, ident, &ident->sym_ident, dbranch, dbranch->type);
11765         /* Thread them together */
11766         flatten(state, first, value);
11767         flatten(state, first, top);
11768         flatten(state, first, dbranch);
11769         statement(state, first);
11770         flatten(state, first, end);
11771         /* Cleanup the switch scope */
11772         end_scope(state);
11773 }
11774
11775 static void case_statement(struct compile_state *state, struct triple *first)
11776 {
11777         struct triple *cvalue, *dest, *test, *jmp;
11778         struct triple *ptr, *value, *top, *dbranch;
11779
11780         /* See if w have a valid case statement */
11781         eat(state, TOK_CASE);
11782         cvalue = constant_expr(state);
11783         integral(state, cvalue);
11784         if (cvalue->op != OP_INTCONST) {
11785                 error(state, 0, "integer constant expected");
11786         }
11787         eat(state, TOK_COLON);
11788         if (!state->i_case->sym_ident) {
11789                 error(state, 0, "case statement not within a switch");
11790         }
11791
11792         /* Lookup the interesting pieces */
11793         top = state->i_case->sym_ident->def;
11794         value = state->i_switch->sym_ident->def;
11795         dbranch = state->i_default->sym_ident->def;
11796
11797         /* See if this case label has already been used */
11798         for(ptr = top; ptr != dbranch; ptr = ptr->next) {
11799                 if (ptr->op != OP_EQ) {
11800                         continue;
11801                 }
11802                 if (RHS(ptr, 1)->u.cval == cvalue->u.cval) {
11803                         error(state, 0, "duplicate case %d statement",
11804                                 cvalue->u.cval);
11805                 }
11806         }
11807         /* Generate the needed pieces */
11808         dest = label(state);
11809         test = triple(state, OP_EQ, &int_type, value, cvalue);
11810         jmp = branch(state, dest, test);
11811         /* Thread the pieces together */
11812         flatten(state, dbranch, test);
11813         flatten(state, dbranch, jmp);
11814         flatten(state, dbranch, label(state));
11815         flatten(state, first, dest);
11816         statement(state, first);
11817 }
11818
11819 static void default_statement(struct compile_state *state, struct triple *first)
11820 {
11821         struct triple *dest;
11822         struct triple *dbranch, *end;
11823
11824         /* See if we have a valid default statement */
11825         eat(state, TOK_DEFAULT);
11826         eat(state, TOK_COLON);
11827
11828         if (!state->i_case->sym_ident) {
11829                 error(state, 0, "default statement not within a switch");
11830         }
11831
11832         /* Lookup the interesting pieces */
11833         dbranch = state->i_default->sym_ident->def;
11834         end = state->i_break->sym_ident->def;
11835
11836         /* See if a default statement has already happened */
11837         if (TARG(dbranch, 0) != end) {
11838                 error(state, 0, "duplicate default statement");
11839         }
11840
11841         /* Generate the needed pieces */
11842         dest = label(state);
11843
11844         /* Blame the branch on the default statement */
11845         put_occurance(dbranch->occurance);
11846         dbranch->occurance = new_occurance(state);
11847
11848         /* Thread the pieces together */
11849         TARG(dbranch, 0) = dest;
11850         use_triple(dest, dbranch);
11851         flatten(state, first, dest);
11852         statement(state, first);
11853 }
11854
11855 static void asm_statement(struct compile_state *state, struct triple *first)
11856 {
11857         struct asm_info *info;
11858         struct {
11859                 struct triple *constraint;
11860                 struct triple *expr;
11861         } out_param[MAX_LHS], in_param[MAX_RHS], clob_param[MAX_LHS];
11862         struct triple *def, *asm_str;
11863         int out, in, clobbers, more, colons, i;
11864         int flags;
11865
11866         flags = 0;
11867         eat(state, TOK_ASM);
11868         /* For now ignore the qualifiers */
11869         switch(peek(state)) {
11870         case TOK_CONST:
11871                 eat(state, TOK_CONST);
11872                 break;
11873         case TOK_VOLATILE:
11874                 eat(state, TOK_VOLATILE);
11875                 flags |= TRIPLE_FLAG_VOLATILE;
11876                 break;
11877         }
11878         eat(state, TOK_LPAREN);
11879         asm_str = string_constant(state);
11880
11881         colons = 0;
11882         out = in = clobbers = 0;
11883         /* Outputs */
11884         if ((colons == 0) && (peek(state) == TOK_COLON)) {
11885                 eat(state, TOK_COLON);
11886                 colons++;
11887                 more = (peek(state) == TOK_LIT_STRING);
11888                 while(more) {
11889                         struct triple *var;
11890                         struct triple *constraint;
11891                         char *str;
11892                         more = 0;
11893                         if (out > MAX_LHS) {
11894                                 error(state, 0, "Maximum output count exceeded.");
11895                         }
11896                         constraint = string_constant(state);
11897                         str = constraint->u.blob;
11898                         if (str[0] != '=') {
11899                                 error(state, 0, "Output constraint does not start with =");
11900                         }
11901                         constraint->u.blob = str + 1;
11902                         eat(state, TOK_LPAREN);
11903                         var = conditional_expr(state);
11904                         eat(state, TOK_RPAREN);
11905
11906                         lvalue(state, var);
11907                         out_param[out].constraint = constraint;
11908                         out_param[out].expr       = var;
11909                         if (peek(state) == TOK_COMMA) {
11910                                 eat(state, TOK_COMMA);
11911                                 more = 1;
11912                         }
11913                         out++;
11914                 }
11915         }
11916         /* Inputs */
11917         if ((colons == 1) && (peek(state) == TOK_COLON)) {
11918                 eat(state, TOK_COLON);
11919                 colons++;
11920                 more = (peek(state) == TOK_LIT_STRING);
11921                 while(more) {
11922                         struct triple *val;
11923                         struct triple *constraint;
11924                         char *str;
11925                         more = 0;
11926                         if (in > MAX_RHS) {
11927                                 error(state, 0, "Maximum input count exceeded.");
11928                         }
11929                         constraint = string_constant(state);
11930                         str = constraint->u.blob;
11931                         if (digitp(str[0] && str[1] == '\0')) {
11932                                 int val;
11933                                 val = digval(str[0]);
11934                                 if ((val < 0) || (val >= out)) {
11935                                         error(state, 0, "Invalid input constraint %d", val);
11936                                 }
11937                         }
11938                         eat(state, TOK_LPAREN);
11939                         val = conditional_expr(state);
11940                         eat(state, TOK_RPAREN);
11941
11942                         in_param[in].constraint = constraint;
11943                         in_param[in].expr       = val;
11944                         if (peek(state) == TOK_COMMA) {
11945                                 eat(state, TOK_COMMA);
11946                                 more = 1;
11947                         }
11948                         in++;
11949                 }
11950         }
11951
11952         /* Clobber */
11953         if ((colons == 2) && (peek(state) == TOK_COLON)) {
11954                 eat(state, TOK_COLON);
11955                 colons++;
11956                 more = (peek(state) == TOK_LIT_STRING);
11957                 while(more) {
11958                         struct triple *clobber;
11959                         more = 0;
11960                         if ((clobbers + out) > MAX_LHS) {
11961                                 error(state, 0, "Maximum clobber limit exceeded.");
11962                         }
11963                         clobber = string_constant(state);
11964
11965                         clob_param[clobbers].constraint = clobber;
11966                         if (peek(state) == TOK_COMMA) {
11967                                 eat(state, TOK_COMMA);
11968                                 more = 1;
11969                         }
11970                         clobbers++;
11971                 }
11972         }
11973         eat(state, TOK_RPAREN);
11974         eat(state, TOK_SEMI);
11975
11976
11977         info = xcmalloc(sizeof(*info), "asm_info");
11978         info->str = asm_str->u.blob;
11979         free_triple(state, asm_str);
11980
11981         def = new_triple(state, OP_ASM, &void_type, clobbers + out, in);
11982         def->u.ainfo = info;
11983         def->id |= flags;
11984
11985         /* Find the register constraints */
11986         for(i = 0; i < out; i++) {
11987                 struct triple *constraint;
11988                 constraint = out_param[i].constraint;
11989                 info->tmpl.lhs[i] = arch_reg_constraint(state, 
11990                         out_param[i].expr->type, constraint->u.blob);
11991                 free_triple(state, constraint);
11992         }
11993         for(; i - out < clobbers; i++) {
11994                 struct triple *constraint;
11995                 constraint = clob_param[i - out].constraint;
11996                 info->tmpl.lhs[i] = arch_reg_clobber(state, constraint->u.blob);
11997                 free_triple(state, constraint);
11998         }
11999         for(i = 0; i < in; i++) {
12000                 struct triple *constraint;
12001                 const char *str;
12002                 constraint = in_param[i].constraint;
12003                 str = constraint->u.blob;
12004                 if (digitp(str[0]) && str[1] == '\0') {
12005                         struct reg_info cinfo;
12006                         int val;
12007                         val = digval(str[0]);
12008                         cinfo.reg = info->tmpl.lhs[val].reg;
12009                         cinfo.regcm = arch_type_to_regcm(state, in_param[i].expr->type);
12010                         cinfo.regcm &= info->tmpl.lhs[val].regcm;
12011                         if (cinfo.reg == REG_UNSET) {
12012                                 cinfo.reg = REG_VIRT0 + val;
12013                         }
12014                         if (cinfo.regcm == 0) {
12015                                 error(state, 0, "No registers for %d", val);
12016                         }
12017                         info->tmpl.lhs[val] = cinfo;
12018                         info->tmpl.rhs[i]   = cinfo;
12019                                 
12020                 } else {
12021                         info->tmpl.rhs[i] = arch_reg_constraint(state, 
12022                                 in_param[i].expr->type, str);
12023                 }
12024                 free_triple(state, constraint);
12025         }
12026
12027         /* Now build the helper expressions */
12028         for(i = 0; i < in; i++) {
12029                 RHS(def, i) = read_expr(state, in_param[i].expr);
12030         }
12031         flatten(state, first, def);
12032         for(i = 0; i < (out + clobbers); i++) {
12033                 struct type *type;
12034                 struct triple *piece;
12035                 if (i < out) {
12036                         type = out_param[i].expr->type;
12037                 } else {
12038                         size_t size = arch_reg_size(info->tmpl.lhs[i].reg);
12039                         if (size >= SIZEOF_LONG) {
12040                                 type = &ulong_type;
12041                         } 
12042                         else if (size >= SIZEOF_INT) {
12043                                 type = &uint_type;
12044                         }
12045                         else if (size >= SIZEOF_SHORT) {
12046                                 type = &ushort_type;
12047                         }
12048                         else {
12049                                 type = &uchar_type;
12050                         }
12051                 }
12052                 piece = triple(state, OP_PIECE, type, def, 0);
12053                 piece->u.cval = i;
12054                 LHS(def, i) = piece;
12055                 flatten(state, first, piece);
12056         }
12057         /* And write the helpers to their destinations */
12058         for(i = 0; i < out; i++) {
12059                 struct triple *piece;
12060                 piece = LHS(def, i);
12061                 flatten(state, first,
12062                         write_expr(state, out_param[i].expr, piece));
12063         }
12064 }
12065
12066
12067 static int isdecl(int tok)
12068 {
12069         switch(tok) {
12070         case TOK_AUTO:
12071         case TOK_REGISTER:
12072         case TOK_STATIC:
12073         case TOK_EXTERN:
12074         case TOK_TYPEDEF:
12075         case TOK_CONST:
12076         case TOK_RESTRICT:
12077         case TOK_VOLATILE:
12078         case TOK_VOID:
12079         case TOK_CHAR:
12080         case TOK_SHORT:
12081         case TOK_INT:
12082         case TOK_LONG:
12083         case TOK_FLOAT:
12084         case TOK_DOUBLE:
12085         case TOK_SIGNED:
12086         case TOK_UNSIGNED:
12087         case TOK_STRUCT:
12088         case TOK_UNION:
12089         case TOK_ENUM:
12090         case TOK_TYPE_NAME: /* typedef name */
12091                 return 1;
12092         default:
12093                 return 0;
12094         }
12095 }
12096
12097 static void compound_statement(struct compile_state *state, struct triple *first)
12098 {
12099         eat(state, TOK_LBRACE);
12100         start_scope(state);
12101
12102         /* statement-list opt */
12103         while (peek(state) != TOK_RBRACE) {
12104                 statement(state, first);
12105         }
12106         end_scope(state);
12107         eat(state, TOK_RBRACE);
12108 }
12109
12110 static void statement(struct compile_state *state, struct triple *first)
12111 {
12112         int tok;
12113         tok = peek(state);
12114         if (tok == TOK_LBRACE) {
12115                 compound_statement(state, first);
12116         }
12117         else if (tok == TOK_IF) {
12118                 if_statement(state, first); 
12119         }
12120         else if (tok == TOK_FOR) {
12121                 for_statement(state, first);
12122         }
12123         else if (tok == TOK_WHILE) {
12124                 while_statement(state, first);
12125         }
12126         else if (tok == TOK_DO) {
12127                 do_statement(state, first);
12128         }
12129         else if (tok == TOK_RETURN) {
12130                 return_statement(state, first);
12131         }
12132         else if (tok == TOK_BREAK) {
12133                 break_statement(state, first);
12134         }
12135         else if (tok == TOK_CONTINUE) {
12136                 continue_statement(state, first);
12137         }
12138         else if (tok == TOK_GOTO) {
12139                 goto_statement(state, first);
12140         }
12141         else if (tok == TOK_SWITCH) {
12142                 switch_statement(state, first);
12143         }
12144         else if (tok == TOK_ASM) {
12145                 asm_statement(state, first);
12146         }
12147         else if ((tok == TOK_IDENT) && (peek2(state) == TOK_COLON)) {
12148                 labeled_statement(state, first); 
12149         }
12150         else if (tok == TOK_CASE) {
12151                 case_statement(state, first);
12152         }
12153         else if (tok == TOK_DEFAULT) {
12154                 default_statement(state, first);
12155         }
12156         else if (isdecl(tok)) {
12157                 /* This handles C99 intermixing of statements and decls */
12158                 decl(state, first);
12159         }
12160         else {
12161                 expr_statement(state, first);
12162         }
12163 }
12164
12165 static struct type *param_decl(struct compile_state *state)
12166 {
12167         struct type *type;
12168         struct hash_entry *ident;
12169         /* Cheat so the declarator will know we are not global */
12170         start_scope(state); 
12171         ident = 0;
12172         type = decl_specifiers(state);
12173         type = declarator(state, type, &ident, 0);
12174         type->field_ident = ident;
12175         end_scope(state);
12176         return type;
12177 }
12178
12179 static struct type *param_type_list(struct compile_state *state, struct type *type)
12180 {
12181         struct type *ftype, **next;
12182         ftype = new_type(TYPE_FUNCTION | (type->type & STOR_MASK), type, param_decl(state));
12183         next = &ftype->right;
12184         ftype->elements = 1;
12185         while(peek(state) == TOK_COMMA) {
12186                 eat(state, TOK_COMMA);
12187                 if (peek(state) == TOK_DOTS) {
12188                         eat(state, TOK_DOTS);
12189                         error(state, 0, "variadic functions not supported");
12190                 }
12191                 else {
12192                         *next = new_type(TYPE_PRODUCT, *next, param_decl(state));
12193                         next = &((*next)->right);
12194                         ftype->elements++;
12195                 }
12196         }
12197         return ftype;
12198 }
12199
12200 static struct type *type_name(struct compile_state *state)
12201 {
12202         struct type *type;
12203         type = specifier_qualifier_list(state);
12204         /* abstract-declarator (may consume no tokens) */
12205         type = declarator(state, type, 0, 0);
12206         return type;
12207 }
12208
12209 static struct type *direct_declarator(
12210         struct compile_state *state, struct type *type, 
12211         struct hash_entry **pident, int need_ident)
12212 {
12213         struct hash_entry *ident;
12214         struct type *outer;
12215         int op;
12216         outer = 0;
12217         arrays_complete(state, type);
12218         switch(peek(state)) {
12219         case TOK_IDENT:
12220                 ident = eat(state, TOK_IDENT)->ident;
12221                 if (!ident) {
12222                         error(state, 0, "Unexpected identifier found");
12223                 }
12224                 /* The name of what we are declaring */
12225                 *pident = ident;
12226                 break;
12227         case TOK_LPAREN:
12228                 eat(state, TOK_LPAREN);
12229                 outer = declarator(state, type, pident, need_ident);
12230                 eat(state, TOK_RPAREN);
12231                 break;
12232         default:
12233                 if (need_ident) {
12234                         error(state, 0, "Identifier expected");
12235                 }
12236                 break;
12237         }
12238         do {
12239                 op = 1;
12240                 arrays_complete(state, type);
12241                 switch(peek(state)) {
12242                 case TOK_LPAREN:
12243                         eat(state, TOK_LPAREN);
12244                         type = param_type_list(state, type);
12245                         eat(state, TOK_RPAREN);
12246                         break;
12247                 case TOK_LBRACKET:
12248                 {
12249                         unsigned int qualifiers;
12250                         struct triple *value;
12251                         value = 0;
12252                         eat(state, TOK_LBRACKET);
12253                         if (peek(state) != TOK_RBRACKET) {
12254                                 value = constant_expr(state);
12255                                 integral(state, value);
12256                         }
12257                         eat(state, TOK_RBRACKET);
12258
12259                         qualifiers = type->type & (QUAL_MASK | STOR_MASK);
12260                         type = new_type(TYPE_ARRAY | qualifiers, type, 0);
12261                         if (value) {
12262                                 type->elements = value->u.cval;
12263                                 free_triple(state, value);
12264                         } else {
12265                                 type->elements = ELEMENT_COUNT_UNSPECIFIED;
12266                                 op = 0;
12267                         }
12268                 }
12269                         break;
12270                 default:
12271                         op = 0;
12272                         break;
12273                 }
12274         } while(op);
12275         if (outer) {
12276                 struct type *inner;
12277                 arrays_complete(state, type);
12278                 FINISHME();
12279                 for(inner = outer; inner->left; inner = inner->left)
12280                         ;
12281                 inner->left = type;
12282                 type = outer;
12283         }
12284         return type;
12285 }
12286
12287 static struct type *declarator(
12288         struct compile_state *state, struct type *type, 
12289         struct hash_entry **pident, int need_ident)
12290 {
12291         while(peek(state) == TOK_STAR) {
12292                 eat(state, TOK_STAR);
12293                 type = new_type(TYPE_POINTER | (type->type & STOR_MASK), type, 0);
12294         }
12295         type = direct_declarator(state, type, pident, need_ident);
12296         return type;
12297 }
12298
12299 static struct type *typedef_name(
12300         struct compile_state *state, unsigned int specifiers)
12301 {
12302         struct hash_entry *ident;
12303         struct type *type;
12304         ident = eat(state, TOK_TYPE_NAME)->ident;
12305         type = ident->sym_ident->type;
12306         specifiers |= type->type & QUAL_MASK;
12307         if ((specifiers & (STOR_MASK | QUAL_MASK)) != 
12308                 (type->type & (STOR_MASK | QUAL_MASK))) {
12309                 type = clone_type(specifiers, type);
12310         }
12311         return type;
12312 }
12313
12314 static struct type *enum_specifier(
12315         struct compile_state *state, unsigned int spec)
12316 {
12317         struct hash_entry *ident;
12318         ulong_t base;
12319         int tok;
12320         struct type *enum_type;
12321         enum_type = 0;
12322         ident = 0;
12323         eat(state, TOK_ENUM);
12324         tok = peek(state);
12325         if ((tok == TOK_IDENT) || (tok == TOK_ENUM_CONST) || (tok == TOK_TYPE_NAME)) {
12326                 ident = eat(state, tok)->ident;
12327         }
12328         base = 0;
12329         if (!ident || (peek(state) == TOK_LBRACE)) {
12330                 struct type **next;
12331                 eat(state, TOK_LBRACE);
12332                 enum_type = new_type(TYPE_ENUM | spec, 0, 0);
12333                 enum_type->type_ident = ident;
12334                 next = &enum_type->right;
12335                 do {
12336                         struct hash_entry *eident;
12337                         struct triple *value;
12338                         struct type *entry;
12339                         eident = eat(state, TOK_IDENT)->ident;
12340                         if (eident->sym_ident) {
12341                                 error(state, 0, "%s already declared", 
12342                                         eident->name);
12343                         }
12344                         eident->tok = TOK_ENUM_CONST;
12345                         if (peek(state) == TOK_EQ) {
12346                                 struct triple *val;
12347                                 eat(state, TOK_EQ);
12348                                 val = constant_expr(state);
12349                                 integral(state, val);
12350                                 base = val->u.cval;
12351                         }
12352                         value = int_const(state, &int_type, base);
12353                         symbol(state, eident, &eident->sym_ident, value, &int_type);
12354                         entry = new_type(TYPE_LIST, 0, 0);
12355                         entry->field_ident = eident;
12356                         *next = entry;
12357                         next = &entry->right;
12358                         base += 1;
12359                         if (peek(state) == TOK_COMMA) {
12360                                 eat(state, TOK_COMMA);
12361                         }
12362                 } while(peek(state) != TOK_RBRACE);
12363                 eat(state, TOK_RBRACE);
12364                 if (ident) {
12365                         symbol(state, ident, &ident->sym_tag, 0, enum_type);
12366                 }
12367         }
12368         if (ident && ident->sym_tag &&
12369                 ident->sym_tag->type &&
12370                 ((ident->sym_tag->type->type & TYPE_MASK) == TYPE_ENUM)) {
12371                 enum_type = clone_type(spec, ident->sym_tag->type);
12372         }
12373         else if (ident && !enum_type) {
12374                 error(state, 0, "enum %s undeclared", ident->name);
12375         }
12376         return enum_type;
12377 }
12378
12379 static struct type *struct_declarator(
12380         struct compile_state *state, struct type *type, struct hash_entry **ident)
12381 {
12382         if (peek(state) != TOK_COLON) {
12383                 type = declarator(state, type, ident, 1);
12384         }
12385         if (peek(state) == TOK_COLON) {
12386                 struct triple *value;
12387                 eat(state, TOK_COLON);
12388                 value = constant_expr(state);
12389                 if (value->op != OP_INTCONST) {
12390                         error(state, 0, "Invalid constant expression");
12391                 }
12392                 if (value->u.cval > size_of(state, type)) {
12393                         error(state, 0, "bitfield larger than base type");
12394                 }
12395                 if (!TYPE_INTEGER(type->type) || ((type->type & TYPE_MASK) == TYPE_BITFIELD)) {
12396                         error(state, 0, "bitfield base not an integer type");
12397                 }
12398                 type = new_type(TYPE_BITFIELD, type, 0);
12399                 type->elements = value->u.cval;
12400         }
12401         return type;
12402 }
12403
12404 static struct type *struct_or_union_specifier(
12405         struct compile_state *state, unsigned int spec)
12406 {
12407         struct type *struct_type;
12408         struct hash_entry *ident;
12409         unsigned int type_main;
12410         unsigned int type_join;
12411         int tok;
12412         struct_type = 0;
12413         ident = 0;
12414         switch(peek(state)) {
12415         case TOK_STRUCT:
12416                 eat(state, TOK_STRUCT);
12417                 type_main = TYPE_STRUCT;
12418                 type_join = TYPE_PRODUCT;
12419                 break;
12420         case TOK_UNION:
12421                 eat(state, TOK_UNION);
12422                 type_main = TYPE_UNION;
12423                 type_join = TYPE_OVERLAP;
12424                 break;
12425         default:
12426                 eat(state, TOK_STRUCT);
12427                 type_main = TYPE_STRUCT;
12428                 type_join = TYPE_PRODUCT;
12429                 break;
12430         }
12431         tok = peek(state);
12432         if ((tok == TOK_IDENT) || (tok == TOK_ENUM_CONST) || (tok == TOK_TYPE_NAME)) {
12433                 ident = eat(state, tok)->ident;
12434         }
12435         if (!ident || (peek(state) == TOK_LBRACE)) {
12436                 ulong_t elements;
12437                 struct type **next;
12438                 elements = 0;
12439                 eat(state, TOK_LBRACE);
12440                 next = &struct_type;
12441                 do {
12442                         struct type *base_type;
12443                         int done;
12444                         base_type = specifier_qualifier_list(state);
12445                         do {
12446                                 struct type *type;
12447                                 struct hash_entry *fident;
12448                                 done = 1;
12449                                 type = struct_declarator(state, base_type, &fident);
12450                                 elements++;
12451                                 if (peek(state) == TOK_COMMA) {
12452                                         done = 0;
12453                                         eat(state, TOK_COMMA);
12454                                 }
12455                                 type = clone_type(0, type);
12456                                 type->field_ident = fident;
12457                                 if (*next) {
12458                                         *next = new_type(type_join, *next, type);
12459                                         next = &((*next)->right);
12460                                 } else {
12461                                         *next = type;
12462                                 }
12463                         } while(!done);
12464                         eat(state, TOK_SEMI);
12465                 } while(peek(state) != TOK_RBRACE);
12466                 eat(state, TOK_RBRACE);
12467                 struct_type = new_type(type_main | spec, struct_type, 0);
12468                 struct_type->type_ident = ident;
12469                 struct_type->elements = elements;
12470                 if (ident) {
12471                         symbol(state, ident, &ident->sym_tag, 0, struct_type);
12472                 }
12473         }
12474         if (ident && ident->sym_tag && 
12475                 ident->sym_tag->type && 
12476                 ((ident->sym_tag->type->type & TYPE_MASK) == type_main)) {
12477                 struct_type = clone_type(spec, ident->sym_tag->type);
12478         }
12479         else if (ident && !struct_type) {
12480                 error(state, 0, "%s %s undeclared", 
12481                         (type_main == TYPE_STRUCT)?"struct" : "union",
12482                         ident->name);
12483         }
12484         return struct_type;
12485 }
12486
12487 static unsigned int storage_class_specifier_opt(struct compile_state *state)
12488 {
12489         unsigned int specifiers;
12490         switch(peek(state)) {
12491         case TOK_AUTO:
12492                 eat(state, TOK_AUTO);
12493                 specifiers = STOR_AUTO;
12494                 break;
12495         case TOK_REGISTER:
12496                 eat(state, TOK_REGISTER);
12497                 specifiers = STOR_REGISTER;
12498                 break;
12499         case TOK_STATIC:
12500                 eat(state, TOK_STATIC);
12501                 specifiers = STOR_STATIC;
12502                 break;
12503         case TOK_EXTERN:
12504                 eat(state, TOK_EXTERN);
12505                 specifiers = STOR_EXTERN;
12506                 break;
12507         case TOK_TYPEDEF:
12508                 eat(state, TOK_TYPEDEF);
12509                 specifiers = STOR_TYPEDEF;
12510                 break;
12511         default:
12512                 if (state->scope_depth <= GLOBAL_SCOPE_DEPTH) {
12513                         specifiers = STOR_LOCAL;
12514                 }
12515                 else {
12516                         specifiers = STOR_AUTO;
12517                 }
12518         }
12519         return specifiers;
12520 }
12521
12522 static unsigned int function_specifier_opt(struct compile_state *state)
12523 {
12524         /* Ignore the inline keyword */
12525         unsigned int specifiers;
12526         specifiers = 0;
12527         switch(peek(state)) {
12528         case TOK_INLINE:
12529                 eat(state, TOK_INLINE);
12530                 specifiers = STOR_INLINE;
12531         }
12532         return specifiers;
12533 }
12534
12535 static unsigned int attrib(struct compile_state *state, unsigned int attributes)
12536 {
12537         int tok = peek(state);
12538         switch(tok) {
12539         case TOK_COMMA:
12540         case TOK_LPAREN:
12541                 /* The empty attribute ignore it */
12542                 break;
12543         case TOK_IDENT:
12544         case TOK_ENUM_CONST:
12545         case TOK_TYPE_NAME:
12546         {
12547                 struct hash_entry *ident;
12548                 ident = eat(state, TOK_IDENT)->ident;
12549
12550                 if (ident == state->i_noinline) {
12551                         if (attributes & ATTRIB_ALWAYS_INLINE) {
12552                                 error(state, 0, "both always_inline and noinline attribtes");
12553                         }
12554                         attributes |= ATTRIB_NOINLINE;
12555                 }
12556                 else if (ident == state->i_always_inline) {
12557                         if (attributes & ATTRIB_NOINLINE) {
12558                                 error(state, 0, "both noinline and always_inline attribtes");
12559                         }
12560                         attributes |= ATTRIB_ALWAYS_INLINE;
12561                 }
12562                 else {
12563                         error(state, 0, "Unknown attribute:%s", ident->name);
12564                 }
12565                 break;
12566         }
12567         default:
12568                 error(state, 0, "Unexpected token: %s\n", tokens[tok]);
12569                 break;
12570         }
12571         return attributes;
12572 }
12573
12574 static unsigned int attribute_list(struct compile_state *state, unsigned type)
12575 {
12576         type = attrib(state, type);
12577         while(peek(state) == TOK_COMMA) {
12578                 eat(state, TOK_COMMA);
12579                 type = attrib(state, type);
12580         }
12581         return type;
12582 }
12583
12584 static unsigned int attributes_opt(struct compile_state *state, unsigned type)
12585 {
12586         if (peek(state) == TOK_ATTRIBUTE) {
12587                 eat(state, TOK_ATTRIBUTE);
12588                 eat(state, TOK_LPAREN);
12589                 eat(state, TOK_LPAREN);
12590                 type = attribute_list(state, type);
12591                 eat(state, TOK_RPAREN);
12592                 eat(state, TOK_RPAREN);
12593         }
12594         return type;
12595 }
12596
12597 static unsigned int type_qualifiers(struct compile_state *state)
12598 {
12599         unsigned int specifiers;
12600         int done;
12601         done = 0;
12602         specifiers = QUAL_NONE;
12603         do {
12604                 switch(peek(state)) {
12605                 case TOK_CONST:
12606                         eat(state, TOK_CONST);
12607                         specifiers |= QUAL_CONST;
12608                         break;
12609                 case TOK_VOLATILE:
12610                         eat(state, TOK_VOLATILE);
12611                         specifiers |= QUAL_VOLATILE;
12612                         break;
12613                 case TOK_RESTRICT:
12614                         eat(state, TOK_RESTRICT);
12615                         specifiers |= QUAL_RESTRICT;
12616                         break;
12617                 default:
12618                         done = 1;
12619                         break;
12620                 }
12621         } while(!done);
12622         return specifiers;
12623 }
12624
12625 static struct type *type_specifier(
12626         struct compile_state *state, unsigned int spec)
12627 {
12628         struct type *type;
12629         int tok;
12630         type = 0;
12631         switch((tok = peek(state))) {
12632         case TOK_VOID:
12633                 eat(state, TOK_VOID);
12634                 type = new_type(TYPE_VOID | spec, 0, 0);
12635                 break;
12636         case TOK_CHAR:
12637                 eat(state, TOK_CHAR);
12638                 type = new_type(TYPE_CHAR | spec, 0, 0);
12639                 break;
12640         case TOK_SHORT:
12641                 eat(state, TOK_SHORT);
12642                 if (peek(state) == TOK_INT) {
12643                         eat(state, TOK_INT);
12644                 }
12645                 type = new_type(TYPE_SHORT | spec, 0, 0);
12646                 break;
12647         case TOK_INT:
12648                 eat(state, TOK_INT);
12649                 type = new_type(TYPE_INT | spec, 0, 0);
12650                 break;
12651         case TOK_LONG:
12652                 eat(state, TOK_LONG);
12653                 switch(peek(state)) {
12654                 case TOK_LONG:
12655                         eat(state, TOK_LONG);
12656                         error(state, 0, "long long not supported");
12657                         break;
12658                 case TOK_DOUBLE:
12659                         eat(state, TOK_DOUBLE);
12660                         error(state, 0, "long double not supported");
12661                         break;
12662                 case TOK_INT:
12663                         eat(state, TOK_INT);
12664                         type = new_type(TYPE_LONG | spec, 0, 0);
12665                         break;
12666                 default:
12667                         type = new_type(TYPE_LONG | spec, 0, 0);
12668                         break;
12669                 }
12670                 break;
12671         case TOK_FLOAT:
12672                 eat(state, TOK_FLOAT);
12673                 error(state, 0, "type float not supported");
12674                 break;
12675         case TOK_DOUBLE:
12676                 eat(state, TOK_DOUBLE);
12677                 error(state, 0, "type double not supported");
12678                 break;
12679         case TOK_SIGNED:
12680                 eat(state, TOK_SIGNED);
12681                 switch(peek(state)) {
12682                 case TOK_LONG:
12683                         eat(state, TOK_LONG);
12684                         switch(peek(state)) {
12685                         case TOK_LONG:
12686                                 eat(state, TOK_LONG);
12687                                 error(state, 0, "type long long not supported");
12688                                 break;
12689                         case TOK_INT:
12690                                 eat(state, TOK_INT);
12691                                 type = new_type(TYPE_LONG | spec, 0, 0);
12692                                 break;
12693                         default:
12694                                 type = new_type(TYPE_LONG | spec, 0, 0);
12695                                 break;
12696                         }
12697                         break;
12698                 case TOK_INT:
12699                         eat(state, TOK_INT);
12700                         type = new_type(TYPE_INT | spec, 0, 0);
12701                         break;
12702                 case TOK_SHORT:
12703                         eat(state, TOK_SHORT);
12704                         type = new_type(TYPE_SHORT | spec, 0, 0);
12705                         break;
12706                 case TOK_CHAR:
12707                         eat(state, TOK_CHAR);
12708                         type = new_type(TYPE_CHAR | spec, 0, 0);
12709                         break;
12710                 default:
12711                         type = new_type(TYPE_INT | spec, 0, 0);
12712                         break;
12713                 }
12714                 break;
12715         case TOK_UNSIGNED:
12716                 eat(state, TOK_UNSIGNED);
12717                 switch(peek(state)) {
12718                 case TOK_LONG:
12719                         eat(state, TOK_LONG);
12720                         switch(peek(state)) {
12721                         case TOK_LONG:
12722                                 eat(state, TOK_LONG);
12723                                 error(state, 0, "unsigned long long not supported");
12724                                 break;
12725                         case TOK_INT:
12726                                 eat(state, TOK_INT);
12727                                 type = new_type(TYPE_ULONG | spec, 0, 0);
12728                                 break;
12729                         default:
12730                                 type = new_type(TYPE_ULONG | spec, 0, 0);
12731                                 break;
12732                         }
12733                         break;
12734                 case TOK_INT:
12735                         eat(state, TOK_INT);
12736                         type = new_type(TYPE_UINT | spec, 0, 0);
12737                         break;
12738                 case TOK_SHORT:
12739                         eat(state, TOK_SHORT);
12740                         type = new_type(TYPE_USHORT | spec, 0, 0);
12741                         break;
12742                 case TOK_CHAR:
12743                         eat(state, TOK_CHAR);
12744                         type = new_type(TYPE_UCHAR | spec, 0, 0);
12745                         break;
12746                 default:
12747                         type = new_type(TYPE_UINT | spec, 0, 0);
12748                         break;
12749                 }
12750                 break;
12751                 /* struct or union specifier */
12752         case TOK_STRUCT:
12753         case TOK_UNION:
12754                 type = struct_or_union_specifier(state, spec);
12755                 break;
12756                 /* enum-spefifier */
12757         case TOK_ENUM:
12758                 type = enum_specifier(state, spec);
12759                 break;
12760                 /* typedef name */
12761         case TOK_TYPE_NAME:
12762                 type = typedef_name(state, spec);
12763                 break;
12764         default:
12765                 error(state, 0, "bad type specifier %s", 
12766                         tokens[tok]);
12767                 break;
12768         }
12769         return type;
12770 }
12771
12772 static int istype(int tok)
12773 {
12774         switch(tok) {
12775         case TOK_CONST:
12776         case TOK_RESTRICT:
12777         case TOK_VOLATILE:
12778         case TOK_VOID:
12779         case TOK_CHAR:
12780         case TOK_SHORT:
12781         case TOK_INT:
12782         case TOK_LONG:
12783         case TOK_FLOAT:
12784         case TOK_DOUBLE:
12785         case TOK_SIGNED:
12786         case TOK_UNSIGNED:
12787         case TOK_STRUCT:
12788         case TOK_UNION:
12789         case TOK_ENUM:
12790         case TOK_TYPE_NAME:
12791                 return 1;
12792         default:
12793                 return 0;
12794         }
12795 }
12796
12797
12798 static struct type *specifier_qualifier_list(struct compile_state *state)
12799 {
12800         struct type *type;
12801         unsigned int specifiers = 0;
12802
12803         /* type qualifiers */
12804         specifiers |= type_qualifiers(state);
12805
12806         /* type specifier */
12807         type = type_specifier(state, specifiers);
12808
12809         return type;
12810 }
12811
12812 static int isdecl_specifier(int tok)
12813 {
12814         switch(tok) {
12815                 /* storage class specifier */
12816         case TOK_AUTO:
12817         case TOK_REGISTER:
12818         case TOK_STATIC:
12819         case TOK_EXTERN:
12820         case TOK_TYPEDEF:
12821                 /* type qualifier */
12822         case TOK_CONST:
12823         case TOK_RESTRICT:
12824         case TOK_VOLATILE:
12825                 /* type specifiers */
12826         case TOK_VOID:
12827         case TOK_CHAR:
12828         case TOK_SHORT:
12829         case TOK_INT:
12830         case TOK_LONG:
12831         case TOK_FLOAT:
12832         case TOK_DOUBLE:
12833         case TOK_SIGNED:
12834         case TOK_UNSIGNED:
12835                 /* struct or union specifier */
12836         case TOK_STRUCT:
12837         case TOK_UNION:
12838                 /* enum-spefifier */
12839         case TOK_ENUM:
12840                 /* typedef name */
12841         case TOK_TYPE_NAME:
12842                 /* function specifiers */
12843         case TOK_INLINE:
12844                 return 1;
12845         default:
12846                 return 0;
12847         }
12848 }
12849
12850 static struct type *decl_specifiers(struct compile_state *state)
12851 {
12852         struct type *type;
12853         unsigned int specifiers;
12854         /* I am overly restrictive in the arragement of specifiers supported.
12855          * C is overly flexible in this department it makes interpreting
12856          * the parse tree difficult.
12857          */
12858         specifiers = 0;
12859
12860         /* storage class specifier */
12861         specifiers |= storage_class_specifier_opt(state);
12862
12863         /* function-specifier */
12864         specifiers |= function_specifier_opt(state);
12865
12866         /* attributes */
12867         specifiers |= attributes_opt(state, 0);
12868
12869         /* type qualifier */
12870         specifiers |= type_qualifiers(state);
12871
12872         /* type specifier */
12873         type = type_specifier(state, specifiers);
12874         return type;
12875 }
12876
12877 struct field_info {
12878         struct type *type;
12879         size_t offset;
12880 };
12881
12882 static struct field_info designator(struct compile_state *state, struct type *type)
12883 {
12884         int tok;
12885         struct field_info info;
12886         info.offset = ~0U;
12887         info.type = 0;
12888         do {
12889                 switch(peek(state)) {
12890                 case TOK_LBRACKET:
12891                 {
12892                         struct triple *value;
12893                         if ((type->type & TYPE_MASK) != TYPE_ARRAY) {
12894                                 error(state, 0, "Array designator not in array initializer");
12895                         }
12896                         eat(state, TOK_LBRACKET);
12897                         value = constant_expr(state);
12898                         eat(state, TOK_RBRACKET);
12899
12900                         info.type = type->left;
12901                         info.offset = value->u.cval * size_of(state, info.type);
12902                         break;
12903                 }
12904                 case TOK_DOT:
12905                 {
12906                         struct hash_entry *field;
12907                         if (((type->type & TYPE_MASK) != TYPE_STRUCT) &&
12908                                 ((type->type & TYPE_MASK) != TYPE_UNION))
12909                         {
12910                                 error(state, 0, "Struct designator not in struct initializer");
12911                         }
12912                         eat(state, TOK_DOT);
12913                         field = eat(state, TOK_IDENT)->ident;
12914                         info.offset = field_offset(state, type, field);
12915                         info.type   = field_type(state, type, field);
12916                         break;
12917                 }
12918                 default:
12919                         error(state, 0, "Invalid designator");
12920                 }
12921                 tok = peek(state);
12922         } while((tok == TOK_LBRACKET) || (tok == TOK_DOT));
12923         eat(state, TOK_EQ);
12924         return info;
12925 }
12926
12927 static struct triple *initializer(
12928         struct compile_state *state, struct type *type)
12929 {
12930         struct triple *result;
12931 #warning "FIXME more consistent initializer handling (where should eval_const_expr go?"
12932         if (peek(state) != TOK_LBRACE) {
12933                 result = assignment_expr(state);
12934                 if (((type->type & TYPE_MASK) == TYPE_ARRAY) &&
12935                         (type->elements == ELEMENT_COUNT_UNSPECIFIED) &&
12936                         ((result->type->type & TYPE_MASK) == TYPE_ARRAY) &&
12937                         (result->type->elements != ELEMENT_COUNT_UNSPECIFIED) &&
12938                         (equiv_types(type->left, result->type->left))) {
12939                         type->elements = result->type->elements;
12940                 }
12941                 if (is_lvalue(state, result) && 
12942                         ((result->type->type & TYPE_MASK) == TYPE_ARRAY) &&
12943                         (type->type & TYPE_MASK) != TYPE_ARRAY)
12944                 {
12945                         result = lvalue_conversion(state, result);
12946                 }
12947                 if (!is_init_compatible(state, type, result->type)) {
12948                         error(state, 0, "Incompatible types in initializer");
12949                 }
12950                 if (!equiv_types(type, result->type)) {
12951                         result = mk_cast_expr(state, type, result);
12952                 }
12953         }
12954         else {
12955                 int comma;
12956                 size_t max_offset;
12957                 struct field_info info;
12958                 void *buf;
12959                 if (((type->type & TYPE_MASK) != TYPE_ARRAY) &&
12960                         ((type->type & TYPE_MASK) != TYPE_STRUCT)) {
12961                         internal_error(state, 0, "unknown initializer type");
12962                 }
12963                 info.offset = 0;
12964                 info.type = type->left;
12965                 if ((type->type & TYPE_MASK) == TYPE_STRUCT) {
12966                         info.type = next_field(state, type, 0);
12967                 }
12968                 if (type->elements == ELEMENT_COUNT_UNSPECIFIED) {
12969                         max_offset = 0;
12970                 } else {
12971                         max_offset = size_of(state, type);
12972                 }
12973                 buf = xcmalloc(bits_to_bytes(max_offset), "initializer");
12974                 eat(state, TOK_LBRACE);
12975                 do {
12976                         struct triple *value;
12977                         struct type *value_type;
12978                         size_t value_size;
12979                         void *dest;
12980                         int tok;
12981                         comma = 0;
12982                         tok = peek(state);
12983                         if ((tok == TOK_LBRACKET) || (tok == TOK_DOT)) {
12984                                 info = designator(state, type);
12985                         }
12986                         if ((type->elements != ELEMENT_COUNT_UNSPECIFIED) &&
12987                                 (info.offset >= max_offset)) {
12988                                 error(state, 0, "element beyond bounds");
12989                         }
12990                         value_type = info.type;
12991                         value = eval_const_expr(state, initializer(state, value_type));
12992                         value_size = size_of(state, value_type);
12993                         if (((type->type & TYPE_MASK) == TYPE_ARRAY) &&
12994                                 (type->elements == ELEMENT_COUNT_UNSPECIFIED) &&
12995                                 (max_offset <= info.offset)) {
12996                                 void *old_buf;
12997                                 size_t old_size;
12998                                 old_buf = buf;
12999                                 old_size = max_offset;
13000                                 max_offset = info.offset + value_size;
13001                                 buf = xmalloc(bits_to_bytes(max_offset), "initializer");
13002                                 memcpy(buf, old_buf, bits_to_bytes(old_size));
13003                                 xfree(old_buf);
13004                         }
13005                         dest = ((char *)buf) + bits_to_bytes(info.offset);
13006 #if DEBUG_INITIALIZER
13007                         fprintf(state->errout, "dest = buf + %d max_offset: %d value_size: %d op: %d\n", 
13008                                 dest - buf,
13009                                 bits_to_bytes(max_offset),
13010                                 bits_to_bytes(value_size),
13011                                 value->op);
13012 #endif
13013                         if (value->op == OP_BLOBCONST) {
13014                                 memcpy(dest, value->u.blob, bits_to_bytes(value_size));
13015                         }
13016                         else if ((value->op == OP_INTCONST) && (value_size == SIZEOF_I8)) {
13017 #if DEBUG_INITIALIZER
13018                                 fprintf(state->errout, "byte: %02x\n", value->u.cval & 0xff);
13019 #endif
13020                                 *((uint8_t *)dest) = value->u.cval & 0xff;
13021                         }
13022                         else if ((value->op == OP_INTCONST) && (value_size == SIZEOF_I16)) {
13023                                 *((uint16_t *)dest) = value->u.cval & 0xffff;
13024                         }
13025                         else if ((value->op == OP_INTCONST) && (value_size == SIZEOF_I32)) {
13026                                 *((uint32_t *)dest) = value->u.cval & 0xffffffff;
13027                         }
13028                         else {
13029                                 internal_error(state, 0, "unhandled constant initializer");
13030                         }
13031                         free_triple(state, value);
13032                         if (peek(state) == TOK_COMMA) {
13033                                 eat(state, TOK_COMMA);
13034                                 comma = 1;
13035                         }
13036                         info.offset += value_size;
13037                         if ((type->type & TYPE_MASK) == TYPE_STRUCT) {
13038                                 info.type = next_field(state, type, info.type);
13039                                 info.offset = field_offset(state, type, 
13040                                         info.type->field_ident);
13041                         }
13042                 } while(comma && (peek(state) != TOK_RBRACE));
13043                 if ((type->elements == ELEMENT_COUNT_UNSPECIFIED) &&
13044                         ((type->type & TYPE_MASK) == TYPE_ARRAY)) {
13045                         type->elements = max_offset / size_of(state, type->left);
13046                 }
13047                 eat(state, TOK_RBRACE);
13048                 result = triple(state, OP_BLOBCONST, type, 0, 0);
13049                 result->u.blob = buf;
13050         }
13051         return result;
13052 }
13053
13054 static void resolve_branches(struct compile_state *state, struct triple *first)
13055 {
13056         /* Make a second pass and finish anything outstanding
13057          * with respect to branches.  The only outstanding item
13058          * is to see if there are goto to labels that have not
13059          * been defined and to error about them.
13060          */
13061         int i;
13062         struct triple *ins;
13063         /* Also error on branches that do not use their targets */
13064         ins = first;
13065         do {
13066                 if (!triple_is_ret(state, ins)) {
13067                         struct triple **expr ;
13068                         struct triple_set *set;
13069                         expr = triple_targ(state, ins, 0);
13070                         for(; expr; expr = triple_targ(state, ins, expr)) {
13071                                 struct triple *targ;
13072                                 targ = *expr;
13073                                 for(set = targ?targ->use:0; set; set = set->next) {
13074                                         if (set->member == ins) {
13075                                                 break;
13076                                         }
13077                                 }
13078                                 if (!set) {
13079                                         internal_error(state, ins, "targ not used");
13080                                 }
13081                         }
13082                 }
13083                 ins = ins->next;
13084         } while(ins != first);
13085         /* See if there are goto to labels that have not been defined */
13086         for(i = 0; i < HASH_TABLE_SIZE; i++) {
13087                 struct hash_entry *entry;
13088                 for(entry = state->hash_table[i]; entry; entry = entry->next) {
13089                         struct triple *ins;
13090                         if (!entry->sym_label) {
13091                                 continue;
13092                         }
13093                         ins = entry->sym_label->def;
13094                         if (!(ins->id & TRIPLE_FLAG_FLATTENED)) {
13095                                 error(state, ins, "label `%s' used but not defined",
13096                                         entry->name);
13097                         }
13098                 }
13099         }
13100 }
13101
13102 static struct triple *function_definition(
13103         struct compile_state *state, struct type *type)
13104 {
13105         struct triple *def, *tmp, *first, *end, *retvar, *result, *ret;
13106         struct triple *fname;
13107         struct type *fname_type;
13108         struct hash_entry *ident;
13109         struct type *param, *crtype, *ctype;
13110         int i;
13111         if ((type->type &TYPE_MASK) != TYPE_FUNCTION) {
13112                 error(state, 0, "Invalid function header");
13113         }
13114
13115         /* Verify the function type */
13116         if (((type->right->type & TYPE_MASK) != TYPE_VOID)  &&
13117                 ((type->right->type & TYPE_MASK) != TYPE_PRODUCT) &&
13118                 (type->right->field_ident == 0)) {
13119                 error(state, 0, "Invalid function parameters");
13120         }
13121         param = type->right;
13122         i = 0;
13123         while((param->type & TYPE_MASK) == TYPE_PRODUCT) {
13124                 i++;
13125                 if (!param->left->field_ident) {
13126                         error(state, 0, "No identifier for parameter %d\n", i);
13127                 }
13128                 param = param->right;
13129         }
13130         i++;
13131         if (((param->type & TYPE_MASK) != TYPE_VOID) && !param->field_ident) {
13132                 error(state, 0, "No identifier for paramter %d\n", i);
13133         }
13134         
13135         /* Get a list of statements for this function. */
13136         def = triple(state, OP_LIST, type, 0, 0);
13137
13138         /* Start a new scope for the passed parameters */
13139         start_scope(state);
13140
13141         /* Put a label at the very start of a function */
13142         first = label(state);
13143         RHS(def, 0) = first;
13144
13145         /* Put a label at the very end of a function */
13146         end = label(state);
13147         flatten(state, first, end);
13148         /* Remember where return goes */
13149         ident = state->i_return;
13150         symbol(state, ident, &ident->sym_ident, end, end->type);
13151
13152         /* Get the initial closure type */
13153         ctype = new_type(TYPE_JOIN, &void_type, 0);
13154         ctype->elements = 1;
13155
13156         /* Add a variable for the return value */
13157         crtype = new_type(TYPE_TUPLE, 
13158                 /* Remove all type qualifiers from the return type */
13159                 new_type(TYPE_PRODUCT, ctype, clone_type(0, type->left)), 0);
13160         crtype->elements = 2;
13161         result = flatten(state, end, variable(state, crtype));
13162
13163         /* Allocate a variable for the return address */
13164         retvar = flatten(state, end, variable(state, &void_ptr_type));
13165
13166         /* Add in the return instruction */
13167         ret = triple(state, OP_RET, &void_type, read_expr(state, retvar), 0);
13168         ret = flatten(state, first, ret);
13169
13170         /* Walk through the parameters and create symbol table entries
13171          * for them.
13172          */
13173         param = type->right;
13174         while((param->type & TYPE_MASK) == TYPE_PRODUCT) {
13175                 ident = param->left->field_ident;
13176                 tmp = variable(state, param->left);
13177                 var_symbol(state, ident, tmp);
13178                 flatten(state, end, tmp);
13179                 param = param->right;
13180         }
13181         if ((param->type & TYPE_MASK) != TYPE_VOID) {
13182                 /* And don't forget the last parameter */
13183                 ident = param->field_ident;
13184                 tmp = variable(state, param);
13185                 symbol(state, ident, &ident->sym_ident, tmp, tmp->type);
13186                 flatten(state, end, tmp);
13187         }
13188
13189         /* Add the declaration static const char __func__ [] = "func-name"  */
13190         fname_type = new_type(TYPE_ARRAY, 
13191                 clone_type(QUAL_CONST | STOR_STATIC, &char_type), 0);
13192         fname_type->type |= QUAL_CONST | STOR_STATIC;
13193         fname_type->elements = strlen(state->function) + 1;
13194
13195         fname = triple(state, OP_BLOBCONST, fname_type, 0, 0);
13196         fname->u.blob = (void *)state->function;
13197         fname = flatten(state, end, fname);
13198
13199         ident = state->i___func__;
13200         symbol(state, ident, &ident->sym_ident, fname, fname_type);
13201
13202         /* Remember which function I am compiling.
13203          * Also assume the last defined function is the main function.
13204          */
13205         state->main_function = def;
13206
13207         /* Now get the actual function definition */
13208         compound_statement(state, end);
13209
13210         /* Finish anything unfinished with branches */
13211         resolve_branches(state, first);
13212
13213         /* Remove the parameter scope */
13214         end_scope(state);
13215
13216
13217         /* Remember I have defined a function */
13218         if (!state->functions) {
13219                 state->functions = def;
13220         } else {
13221                 insert_triple(state, state->functions, def);
13222         }
13223         if (state->compiler->debug & DEBUG_INLINE) {
13224                 FILE *fp = state->dbgout;
13225                 fprintf(fp, "\n");
13226                 loc(fp, state, 0);
13227                 fprintf(fp, "\n__________ %s _________\n", __FUNCTION__);
13228                 display_func(state, fp, def);
13229                 fprintf(fp, "__________ %s _________ done\n\n", __FUNCTION__);
13230         }
13231
13232         return def;
13233 }
13234
13235 static struct triple *do_decl(struct compile_state *state, 
13236         struct type *type, struct hash_entry *ident)
13237 {
13238         struct triple *def;
13239         def = 0;
13240         /* Clean up the storage types used */
13241         switch (type->type & STOR_MASK) {
13242         case STOR_AUTO:
13243         case STOR_STATIC:
13244                 /* These are the good types I am aiming for */
13245                 break;
13246         case STOR_REGISTER:
13247                 type->type &= ~STOR_MASK;
13248                 type->type |= STOR_AUTO;
13249                 break;
13250         case STOR_LOCAL:
13251         case STOR_EXTERN:
13252                 type->type &= ~STOR_MASK;
13253                 type->type |= STOR_STATIC;
13254                 break;
13255         case STOR_TYPEDEF:
13256                 if (!ident) {
13257                         error(state, 0, "typedef without name");
13258                 }
13259                 symbol(state, ident, &ident->sym_ident, 0, type);
13260                 ident->tok = TOK_TYPE_NAME;
13261                 return 0;
13262                 break;
13263         default:
13264                 internal_error(state, 0, "Undefined storage class");
13265         }
13266         if ((type->type & TYPE_MASK) == TYPE_FUNCTION) {
13267                 error(state, 0, "Function prototypes not supported");
13268         }
13269         if (ident && 
13270                 ((type->type & STOR_MASK) == STOR_STATIC) &&
13271                 ((type->type & QUAL_CONST) == 0)) {
13272                 error(state, 0, "non const static variables not supported");
13273         }
13274         if (ident) {
13275                 def = variable(state, type);
13276                 var_symbol(state, ident, def);
13277         }
13278         return def;
13279 }
13280
13281 static void decl(struct compile_state *state, struct triple *first)
13282 {
13283         struct type *base_type, *type;
13284         struct hash_entry *ident;
13285         struct triple *def;
13286         int global;
13287         global = (state->scope_depth <= GLOBAL_SCOPE_DEPTH);
13288         base_type = decl_specifiers(state);
13289         ident = 0;
13290         type = declarator(state, base_type, &ident, 0);
13291         type->type = attributes_opt(state, type->type);
13292         if (global && ident && (peek(state) == TOK_LBRACE)) {
13293                 /* function */
13294                 type->type_ident = ident;
13295                 state->function = ident->name;
13296                 def = function_definition(state, type);
13297                 symbol(state, ident, &ident->sym_ident, def, type);
13298                 state->function = 0;
13299         }
13300         else {
13301                 int done;
13302                 flatten(state, first, do_decl(state, type, ident));
13303                 /* type or variable definition */
13304                 do {
13305                         done = 1;
13306                         if (peek(state) == TOK_EQ) {
13307                                 if (!ident) {
13308                                         error(state, 0, "cannot assign to a type");
13309                                 }
13310                                 eat(state, TOK_EQ);
13311                                 flatten(state, first,
13312                                         init_expr(state, 
13313                                                 ident->sym_ident->def, 
13314                                                 initializer(state, type)));
13315                         }
13316                         arrays_complete(state, type);
13317                         if (peek(state) == TOK_COMMA) {
13318                                 eat(state, TOK_COMMA);
13319                                 ident = 0;
13320                                 type = declarator(state, base_type, &ident, 0);
13321                                 flatten(state, first, do_decl(state, type, ident));
13322                                 done = 0;
13323                         }
13324                 } while(!done);
13325                 eat(state, TOK_SEMI);
13326         }
13327 }
13328
13329 static void decls(struct compile_state *state)
13330 {
13331         struct triple *list;
13332         int tok;
13333         list = label(state);
13334         while(1) {
13335                 tok = peek(state);
13336                 if (tok == TOK_EOF) {
13337                         return;
13338                 }
13339                 if (tok == TOK_SPACE) {
13340                         eat(state, TOK_SPACE);
13341                 }
13342                 decl(state, list);
13343                 if (list->next != list) {
13344                         error(state, 0, "global variables not supported");
13345                 }
13346         }
13347 }
13348
13349 /* 
13350  * Function inlining
13351  */
13352 struct triple_reg_set {
13353         struct triple_reg_set *next;
13354         struct triple *member;
13355         struct triple *new;
13356 };
13357 struct reg_block {
13358         struct block *block;
13359         struct triple_reg_set *in;
13360         struct triple_reg_set *out;
13361         int vertex;
13362 };
13363 static void setup_basic_blocks(struct compile_state *, struct basic_blocks *bb);
13364 static void analyze_basic_blocks(struct compile_state *state, struct basic_blocks *bb);
13365 static void free_basic_blocks(struct compile_state *, struct basic_blocks *bb);
13366 static int tdominates(struct compile_state *state, struct triple *dom, struct triple *sub);
13367 static void walk_blocks(struct compile_state *state, struct basic_blocks *bb,
13368         void (*cb)(struct compile_state *state, struct block *block, void *arg),
13369         void *arg);
13370 static void print_block(
13371         struct compile_state *state, struct block *block, void *arg);
13372 static int do_triple_set(struct triple_reg_set **head, 
13373         struct triple *member, struct triple *new_member);
13374 static void do_triple_unset(struct triple_reg_set **head, struct triple *member);
13375 static struct reg_block *compute_variable_lifetimes(
13376         struct compile_state *state, struct basic_blocks *bb);
13377 static void free_variable_lifetimes(struct compile_state *state, 
13378         struct basic_blocks *bb, struct reg_block *blocks);
13379 static void print_live_variables(struct compile_state *state, 
13380         struct basic_blocks *bb, struct reg_block *rb, FILE *fp);
13381
13382
13383 static struct triple *call(struct compile_state *state,
13384         struct triple *retvar, struct triple *ret_addr, 
13385         struct triple *targ, struct triple *ret)
13386 {
13387         struct triple *call;
13388
13389         if (!retvar || !is_lvalue(state, retvar)) {
13390                 internal_error(state, 0, "writing to a non lvalue?");
13391         }
13392         write_compatible(state, retvar->type, &void_ptr_type);
13393
13394         call = new_triple(state, OP_CALL, &void_type, 1, 0);
13395         TARG(call, 0) = targ;
13396         MISC(call, 0) = ret;
13397         if (!targ || (targ->op != OP_LABEL)) {
13398                 internal_error(state, 0, "call not to a label");
13399         }
13400         if (!ret || (ret->op != OP_RET)) {
13401                 internal_error(state, 0, "call not matched with return");
13402         }
13403         return call;
13404 }
13405
13406 static void walk_functions(struct compile_state *state,
13407         void (*cb)(struct compile_state *state, struct triple *func, void *arg),
13408         void *arg)
13409 {
13410         struct triple *func, *first;
13411         func = first = state->functions;
13412         do {
13413                 cb(state, func, arg);
13414                 func = func->next;
13415         } while(func != first);
13416 }
13417
13418 static void reverse_walk_functions(struct compile_state *state,
13419         void (*cb)(struct compile_state *state, struct triple *func, void *arg),
13420         void *arg)
13421 {
13422         struct triple *func, *first;
13423         func = first = state->functions;
13424         do {
13425                 func = func->prev;
13426                 cb(state, func, arg);
13427         } while(func != first);
13428 }
13429
13430
13431 static void mark_live(struct compile_state *state, struct triple *func, void *arg)
13432 {
13433         struct triple *ptr, *first;
13434         if (func->u.cval == 0) {
13435                 return;
13436         }
13437         ptr = first = RHS(func, 0);
13438         do {
13439                 if (ptr->op == OP_FCALL) {
13440                         struct triple *called_func;
13441                         called_func = MISC(ptr, 0);
13442                         /* Mark the called function as used */
13443                         if (!(func->id & TRIPLE_FLAG_FLATTENED)) {
13444                                 called_func->u.cval++;
13445                         }
13446                         /* Remove the called function from the list */
13447                         called_func->prev->next = called_func->next;
13448                         called_func->next->prev = called_func->prev;
13449
13450                         /* Place the called function before me on the list */
13451                         called_func->next       = func;
13452                         called_func->prev       = func->prev;
13453                         called_func->prev->next = called_func;
13454                         called_func->next->prev = called_func;
13455                 }
13456                 ptr = ptr->next;
13457         } while(ptr != first);
13458         func->id |= TRIPLE_FLAG_FLATTENED;
13459 }
13460
13461 static void mark_live_functions(struct compile_state *state)
13462 {
13463         /* Ensure state->main_function is the last function in 
13464          * the list of functions.
13465          */
13466         if ((state->main_function->next != state->functions) ||
13467                 (state->functions->prev != state->main_function)) {
13468                 internal_error(state, 0, 
13469                         "state->main_function is not at the end of the function list ");
13470         }
13471         state->main_function->u.cval = 1;
13472         reverse_walk_functions(state, mark_live, 0);
13473 }
13474
13475 static int local_triple(struct compile_state *state, 
13476         struct triple *func, struct triple *ins)
13477 {
13478         int local = (ins->id & TRIPLE_FLAG_LOCAL);
13479 #if 0
13480         if (!local) {
13481                 FILE *fp = state->errout;
13482                 fprintf(fp, "global: ");
13483                 display_triple(fp, ins);
13484         }
13485 #endif
13486         return local;
13487 }
13488
13489 struct triple *copy_func(struct compile_state *state, struct triple *ofunc, 
13490         struct occurance *base_occurance)
13491 {
13492         struct triple *nfunc;
13493         struct triple *nfirst, *ofirst;
13494         struct triple *new, *old;
13495
13496         if (state->compiler->debug & DEBUG_INLINE) {
13497                 FILE *fp = state->dbgout;
13498                 fprintf(fp, "\n");
13499                 loc(fp, state, 0);
13500                 fprintf(fp, "\n__________ %s _________\n", __FUNCTION__);
13501                 display_func(state, fp, ofunc);
13502                 fprintf(fp, "__________ %s _________ done\n\n", __FUNCTION__);
13503         }
13504
13505         /* Make a new copy of the old function */
13506         nfunc = triple(state, OP_LIST, ofunc->type, 0, 0);
13507         nfirst = 0;
13508         ofirst = old = RHS(ofunc, 0);
13509         do {
13510                 struct triple *new;
13511                 struct occurance *occurance;
13512                 int old_lhs, old_rhs;
13513                 old_lhs = old->lhs;
13514                 old_rhs = old->rhs;
13515                 occurance = inline_occurance(state, base_occurance, old->occurance);
13516                 if (ofunc->u.cval && (old->op == OP_FCALL)) {
13517                         MISC(old, 0)->u.cval += 1;
13518                 }
13519                 new = alloc_triple(state, old->op, old->type, old_lhs, old_rhs,
13520                         occurance);
13521                 if (!triple_stores_block(state, new)) {
13522                         memcpy(&new->u, &old->u, sizeof(new->u));
13523                 }
13524                 if (!nfirst) {
13525                         RHS(nfunc, 0) = nfirst = new;
13526                 }
13527                 else {
13528                         insert_triple(state, nfirst, new);
13529                 }
13530                 new->id |= TRIPLE_FLAG_FLATTENED;
13531                 new->id |= old->id & TRIPLE_FLAG_COPY;
13532                 
13533                 /* During the copy remember new as user of old */
13534                 use_triple(old, new);
13535
13536                 /* Remember which instructions are local */
13537                 old->id |= TRIPLE_FLAG_LOCAL;
13538                 old = old->next;
13539         } while(old != ofirst);
13540
13541         /* Make a second pass to fix up any unresolved references */
13542         old = ofirst;
13543         new = nfirst;
13544         do {
13545                 struct triple **oexpr, **nexpr;
13546                 int count, i;
13547                 /* Lookup where the copy is, to join pointers */
13548                 count = TRIPLE_SIZE(old);
13549                 for(i = 0; i < count; i++) {
13550                         oexpr = &old->param[i];
13551                         nexpr = &new->param[i];
13552                         if (*oexpr && !*nexpr) {
13553                                 if (!local_triple(state, ofunc, *oexpr)) {
13554                                         *nexpr = *oexpr;
13555                                 }
13556                                 else if ((*oexpr)->use) {
13557                                         *nexpr = (*oexpr)->use->member;
13558                                 }
13559                                 if (*nexpr == old) {
13560                                         internal_error(state, 0, "new == old?");
13561                                 }
13562                                 use_triple(*nexpr, new);
13563                         }
13564                         if (!*nexpr && *oexpr) {
13565                                 internal_error(state, 0, "Could not copy %d", i);
13566                         }
13567                 }
13568                 old = old->next;
13569                 new = new->next;
13570         } while((old != ofirst) && (new != nfirst));
13571         
13572         /* Make a third pass to cleanup the extra useses */
13573         old = ofirst;
13574         new = nfirst;
13575         do {
13576                 unuse_triple(old, new);
13577                 /* Forget which instructions are local */
13578                 old->id &= ~TRIPLE_FLAG_LOCAL;
13579                 old = old->next;
13580                 new = new->next;
13581         } while ((old != ofirst) && (new != nfirst));
13582         return nfunc;
13583 }
13584
13585 static void expand_inline_call(
13586         struct compile_state *state, struct triple *me, struct triple *fcall)
13587 {
13588         /* Inline the function call */
13589         struct type *ptype;
13590         struct triple *ofunc, *nfunc, *nfirst, *result, *retvar, *ins;
13591         struct triple *end, *nend;
13592         int pvals, i;
13593
13594         /* Find the triples */
13595         ofunc = MISC(fcall, 0);
13596         if (ofunc->op != OP_LIST) {
13597                 internal_error(state, 0, "improper function");
13598         }
13599         nfunc = copy_func(state, ofunc, fcall->occurance);
13600         /* Prepend the parameter reading into the new function list */
13601         ptype = nfunc->type->right;
13602         pvals = fcall->rhs;
13603         for(i = 0; i < pvals; i++) {
13604                 struct type *atype;
13605                 struct triple *arg, *param;
13606                 atype = ptype;
13607                 if ((ptype->type & TYPE_MASK) == TYPE_PRODUCT) {
13608                         atype = ptype->left;
13609                 }
13610                 param = farg(state, nfunc, i);
13611                 if ((param->type->type & TYPE_MASK) != (atype->type & TYPE_MASK)) {
13612                         internal_error(state, fcall, "param %d type mismatch", i);
13613                 }
13614                 arg = RHS(fcall, i);
13615                 flatten(state, fcall, write_expr(state, param, arg));
13616                 ptype = ptype->right;
13617         }
13618         result = 0;
13619         if ((nfunc->type->left->type & TYPE_MASK) != TYPE_VOID) {
13620                 result = read_expr(state, 
13621                         deref_index(state, fresult(state, nfunc), 1));
13622         }
13623         if (state->compiler->debug & DEBUG_INLINE) {
13624                 FILE *fp = state->dbgout;
13625                 fprintf(fp, "\n");
13626                 loc(fp, state, 0);
13627                 fprintf(fp, "\n__________ %s _________\n", __FUNCTION__);
13628                 display_func(state, fp, nfunc);
13629                 fprintf(fp, "__________ %s _________ done\n\n", __FUNCTION__);
13630         }
13631
13632         /* 
13633          * Get rid of the extra triples 
13634          */
13635         /* Remove the read of the return address */
13636         ins = RHS(nfunc, 0)->prev->prev;
13637         if ((ins->op != OP_READ) || (RHS(ins, 0) != fretaddr(state, nfunc))) {
13638                 internal_error(state, ins, "Not return addres read?");
13639         }
13640         release_triple(state, ins);
13641         /* Remove the return instruction */
13642         ins = RHS(nfunc, 0)->prev;
13643         if (ins->op != OP_RET) {
13644                 internal_error(state, ins, "Not return?");
13645         }
13646         release_triple(state, ins);
13647         /* Remove the retaddres variable */
13648         retvar = fretaddr(state, nfunc);
13649         if ((retvar->lhs != 1) || 
13650                 (retvar->op != OP_ADECL) ||
13651                 (retvar->next->op != OP_PIECE) ||
13652                 (MISC(retvar->next, 0) != retvar)) {
13653                 internal_error(state, retvar, "Not the return address?");
13654         }
13655         release_triple(state, retvar->next);
13656         release_triple(state, retvar);
13657
13658         /* Remove the label at the start of the function */
13659         ins = RHS(nfunc, 0);
13660         if (ins->op != OP_LABEL) {
13661                 internal_error(state, ins, "Not label?");
13662         }
13663         nfirst = ins->next;
13664         free_triple(state, ins);
13665         /* Release the new function header */
13666         RHS(nfunc, 0) = 0;
13667         free_triple(state, nfunc);
13668
13669         /* Append the new function list onto the return list */
13670         end = fcall->prev;
13671         nend = nfirst->prev;
13672         end->next    = nfirst;
13673         nfirst->prev = end;
13674         nend->next   = fcall;
13675         fcall->prev  = nend;
13676
13677         /* Now the result reading code */
13678         if (result) {
13679                 result = flatten(state, fcall, result);
13680                 propogate_use(state, fcall, result);
13681         }
13682
13683         /* Release the original fcall instruction */
13684         release_triple(state, fcall);
13685
13686         return;
13687 }
13688
13689 /*
13690  *
13691  * Type of the result variable.
13692  * 
13693  *                                     result
13694  *                                        |
13695  *                             +----------+------------+
13696  *                             |                       |
13697  *                     union of closures         result_type
13698  *                             |
13699  *          +------------------+---------------+
13700  *          |                                  |
13701  *       closure1                    ...   closuerN
13702  *          |                                  | 
13703  *  +----+--+-+--------+-----+       +----+----+---+-----+
13704  *  |    |    |        |     |       |    |        |     |
13705  * var1 var2 var3 ... varN result   var1 var2 ... varN result
13706  *                           |
13707  *                  +--------+---------+
13708  *                  |                  |
13709  *          union of closures     result_type
13710  *                  |
13711  *            +-----+-------------------+
13712  *            |                         |
13713  *         closure1            ...  closureN
13714  *            |                         |
13715  *  +-----+---+----+----+      +----+---+----+-----+
13716  *  |     |        |    |      |    |        |     |
13717  * var1 var2 ... varN result  var1 var2 ... varN result
13718  */
13719
13720 static int add_closure_type(struct compile_state *state, 
13721         struct triple *func, struct type *closure_type)
13722 {
13723         struct type *type, *ctype, **next;
13724         struct triple *var, *new_var;
13725         int i;
13726
13727 #if 0
13728         FILE *fp = state->errout;
13729         fprintf(fp, "original_type: ");
13730         name_of(fp, fresult(state, func)->type);
13731         fprintf(fp, "\n");
13732 #endif
13733         /* find the original type */
13734         var = fresult(state, func);
13735         type = var->type;
13736         if (type->elements != 2) {
13737                 internal_error(state, var, "bad return type");
13738         }
13739
13740         /* Find the complete closure type and update it */
13741         ctype = type->left->left;
13742         next = &ctype->left;
13743         while(((*next)->type & TYPE_MASK) == TYPE_OVERLAP) {
13744                 next = &(*next)->right;
13745         }
13746         *next = new_type(TYPE_OVERLAP, *next, dup_type(state, closure_type));
13747         ctype->elements += 1;
13748
13749 #if 0
13750         fprintf(fp, "new_type: ");
13751         name_of(fp, type);
13752         fprintf(fp, "\n");
13753         fprintf(fp, "ctype: %p %d bits: %d ", 
13754                 ctype, ctype->elements, reg_size_of(state, ctype));
13755         name_of(fp, ctype);
13756         fprintf(fp, "\n");
13757 #endif
13758         
13759         /* Regenerate the variable with the new type definition */
13760         new_var = pre_triple(state, var, OP_ADECL, type, 0, 0);
13761         new_var->id |= TRIPLE_FLAG_FLATTENED;
13762         for(i = 0; i < new_var->lhs; i++) {
13763                 LHS(new_var, i)->id |= TRIPLE_FLAG_FLATTENED;
13764         }
13765         
13766         /* Point everyone at the new variable */
13767         propogate_use(state, var, new_var);
13768
13769         /* Release the original variable */
13770         for(i = 0; i < var->lhs; i++) {
13771                 release_triple(state, LHS(var, i));
13772         }
13773         release_triple(state, var);
13774         
13775         /* Return the index of the added closure type */
13776         return ctype->elements - 1;
13777 }
13778
13779 static struct triple *closure_expr(struct compile_state *state,
13780         struct triple *func, int closure_idx, int var_idx)
13781 {
13782         return deref_index(state,
13783                 deref_index(state,
13784                         deref_index(state, fresult(state, func), 0),
13785                         closure_idx),
13786                 var_idx);
13787 }
13788
13789
13790 static void insert_triple_set(
13791         struct triple_reg_set **head, struct triple *member)
13792 {
13793         struct triple_reg_set *new;
13794         new = xcmalloc(sizeof(*new), "triple_set");
13795         new->member = member;
13796         new->new    = 0;
13797         new->next   = *head;
13798         *head       = new;
13799 }
13800
13801 static int ordered_triple_set(
13802         struct triple_reg_set **head, struct triple *member)
13803 {
13804         struct triple_reg_set **ptr;
13805         if (!member)
13806                 return 0;
13807         ptr = head;
13808         while(*ptr) {
13809                 if (member == (*ptr)->member) {
13810                         return 0;
13811                 }
13812                 /* keep the list ordered */
13813                 if (member->id < (*ptr)->member->id) {
13814                         break;
13815                 }
13816                 ptr = &(*ptr)->next;
13817         }
13818         insert_triple_set(ptr, member);
13819         return 1;
13820 }
13821
13822
13823 static void free_closure_variables(struct compile_state *state,
13824         struct triple_reg_set **enclose)
13825 {
13826         struct triple_reg_set *entry, *next;
13827         for(entry = *enclose; entry; entry = next) {
13828                 next = entry->next;
13829                 do_triple_unset(enclose, entry->member);
13830         }
13831 }
13832
13833 static int lookup_closure_index(struct compile_state *state,
13834         struct triple *me, struct triple *val)
13835 {
13836         struct triple *first, *ins, *next;
13837         first = RHS(me, 0);
13838         ins = next = first;
13839         do {
13840                 struct triple *result;
13841                 struct triple *index0, *index1, *index2, *read, *write;
13842                 ins = next;
13843                 next = ins->next;
13844                 if (ins->op != OP_CALL) {
13845                         continue;
13846                 }
13847                 /* I am at a previous call point examine it closely */
13848                 if (ins->next->op != OP_LABEL) {
13849                         internal_error(state, ins, "call not followed by label");
13850                 }
13851                 /* Does this call does not enclose any variables? */
13852                 if ((ins->next->next->op != OP_INDEX) ||
13853                         (ins->next->next->u.cval != 0) ||
13854                         (result = MISC(ins->next->next, 0)) ||
13855                         (result->id & TRIPLE_FLAG_LOCAL)) {
13856                         continue;
13857                 }
13858                 index0 = ins->next->next;
13859                 /* The pattern is:
13860                  * 0 index result < 0 >
13861                  * 1 index 0 < ? >
13862                  * 2 index 1 < ? >
13863                  * 3 read  2
13864                  * 4 write 3 var
13865                  */
13866                 for(index0 = ins->next->next;
13867                         (index0->op == OP_INDEX) &&
13868                                 (MISC(index0, 0) == result) &&
13869                                 (index0->u.cval == 0) ; 
13870                         index0 = write->next)
13871                 {
13872                         index1 = index0->next;
13873                         index2 = index1->next;
13874                         read   = index2->next;
13875                         write  = read->next;
13876                         if ((index0->op != OP_INDEX) ||
13877                                 (index1->op != OP_INDEX) ||
13878                                 (index2->op != OP_INDEX) ||
13879                                 (read->op != OP_READ) ||
13880                                 (write->op != OP_WRITE) ||
13881                                 (MISC(index1, 0) != index0) ||
13882                                 (MISC(index2, 0) != index1) ||
13883                                 (RHS(read, 0) != index2) ||
13884                                 (RHS(write, 0) != read)) {
13885                                 internal_error(state, index0, "bad var read");
13886                         }
13887                         if (MISC(write, 0) == val) {
13888                                 return index2->u.cval;
13889                         }
13890                 }
13891         } while(next != first);
13892         return -1;
13893 }
13894
13895 static inline int enclose_triple(struct triple *ins)
13896 {
13897         return (ins && ((ins->type->type & TYPE_MASK) != TYPE_VOID));
13898 }
13899
13900 static void compute_closure_variables(struct compile_state *state,
13901         struct triple *me, struct triple *fcall, struct triple_reg_set **enclose)
13902 {
13903         struct triple_reg_set *set, *vars, **last_var;
13904         struct basic_blocks bb;
13905         struct reg_block *rb;
13906         struct block *block;
13907         struct triple *old_result, *first, *ins;
13908         size_t count, idx;
13909         unsigned long used_indicies;
13910         int i, max_index;
13911 #define MAX_INDICIES (sizeof(used_indicies)*CHAR_BIT)
13912 #define ID_BITS(X) ((X) & (TRIPLE_FLAG_LOCAL -1))
13913         struct { 
13914                 unsigned id;
13915                 int index;
13916         } *info;
13917
13918         
13919         /* Find the basic blocks of this function */
13920         bb.func = me;
13921         bb.first = RHS(me, 0);
13922         old_result = 0;
13923         if (!triple_is_ret(state, bb.first->prev)) {
13924                 bb.func = 0;
13925         } else {
13926                 old_result = fresult(state, me);
13927         }
13928         analyze_basic_blocks(state, &bb);
13929
13930         /* Find which variables are currently alive in a given block */
13931         rb = compute_variable_lifetimes(state, &bb);
13932
13933         /* Find the variables that are currently alive */
13934         block = block_of_triple(state, fcall);
13935         if (!block || (block->vertex <= 0) || (block->vertex > bb.last_vertex)) {
13936                 internal_error(state, fcall, "No reg block? block: %p", block);
13937         }
13938
13939 #if DEBUG_EXPLICIT_CLOSURES
13940         print_live_variables(state, &bb, rb, state->dbgout);
13941         fflush(state->dbgout);
13942 #endif
13943
13944         /* Count the number of triples in the function */
13945         first = RHS(me, 0);
13946         ins = first;
13947         count = 0;
13948         do {
13949                 count++;
13950                 ins = ins->next;
13951         } while(ins != first);
13952
13953         /* Allocate some memory to temorary hold the id info */
13954         info = xcmalloc(sizeof(*info) * (count +1), "info");
13955
13956         /* Mark the local function */
13957         first = RHS(me, 0);
13958         ins = first;
13959         idx = 1;
13960         do {
13961                 info[idx].id = ins->id;
13962                 ins->id = TRIPLE_FLAG_LOCAL | idx;
13963                 idx++;
13964                 ins = ins->next;
13965         } while(ins != first);
13966
13967         /* 
13968          * Build the list of variables to enclose.
13969          *
13970          * A target it to put the same variable in the
13971          * same slot for ever call of a given function.
13972          * After coloring this removes all of the variable
13973          * manipulation code.
13974          *
13975          * The list of variables to enclose is built ordered
13976          * program order because except in corner cases this
13977          * gives me the stability of assignment I need.
13978          *
13979          * To gurantee that stability I lookup the variables
13980          * to see where they have been used before and
13981          * I build my final list with the assigned indicies.
13982          */
13983         vars = 0;
13984         if (enclose_triple(old_result)) {
13985                 ordered_triple_set(&vars, old_result);
13986         }
13987         for(set = rb[block->vertex].out; set; set = set->next) {
13988                 if (!enclose_triple(set->member)) {
13989                         continue;
13990                 }
13991                 if ((set->member == fcall) || (set->member == old_result)) {
13992                         continue;
13993                 }
13994                 if (!local_triple(state, me, set->member)) {
13995                         internal_error(state, set->member, "not local?");
13996                 }
13997                 ordered_triple_set(&vars, set->member);
13998         }
13999
14000         /* Lookup the current indicies of the live varialbe */
14001         used_indicies = 0;
14002         max_index = -1;
14003         for(set = vars; set ; set = set->next) {
14004                 struct triple *ins;
14005                 int index;
14006                 ins = set->member;
14007                 index  = lookup_closure_index(state, me, ins);
14008                 info[ID_BITS(ins->id)].index = index;
14009                 if (index < 0) {
14010                         continue;
14011                 }
14012                 if (index >= MAX_INDICIES) {
14013                         internal_error(state, ins, "index unexpectedly large");
14014                 }
14015                 if (used_indicies & (1 << index)) {
14016                         internal_error(state, ins, "index previously used?");
14017                 }
14018                 /* Remember which indicies have been used */
14019                 used_indicies |= (1 << index);
14020                 if (index > max_index) {
14021                         max_index = index;
14022                 }
14023         }
14024
14025         /* Walk through the live variables and make certain
14026          * everything is assigned an index.
14027          */
14028         for(set = vars; set; set = set->next) {
14029                 struct triple *ins;
14030                 int index;
14031                 ins = set->member;
14032                 index = info[ID_BITS(ins->id)].index;
14033                 if (index >= 0) {
14034                         continue;
14035                 }
14036                 /* Find the lowest unused index value */
14037                 for(index = 0; index < MAX_INDICIES; index++) {
14038                         if (!(used_indicies & (1 << index))) {
14039                                 break;
14040                         }
14041                 }
14042                 if (index == MAX_INDICIES) {
14043                         internal_error(state, ins, "no free indicies?");
14044                 }
14045                 info[ID_BITS(ins->id)].index = index;
14046                 /* Remember which indicies have been used */
14047                 used_indicies |= (1 << index);
14048                 if (index > max_index) {
14049                         max_index = index;
14050                 }
14051         }
14052
14053         /* Build the return list of variables with positions matching
14054          * their indicies.
14055          */
14056         *enclose = 0;
14057         last_var = enclose;
14058         for(i = 0; i <= max_index; i++) {
14059                 struct triple *var;
14060                 var = 0;
14061                 if (used_indicies & (1 << i)) {
14062                         for(set = vars; set; set = set->next) {
14063                                 int index;
14064                                 index = info[ID_BITS(set->member->id)].index;
14065                                 if (index == i) {
14066                                         var = set->member;
14067                                         break;
14068                                 }
14069                         }
14070                         if (!var) {
14071                                 internal_error(state, me, "missing variable");
14072                         }
14073                 }
14074                 insert_triple_set(last_var, var);
14075                 last_var = &(*last_var)->next;
14076         }
14077
14078 #if DEBUG_EXPLICIT_CLOSURES
14079         /* Print out the variables to be enclosed */
14080         loc(state->dbgout, state, fcall);
14081         fprintf(state->dbgout, "Alive: \n");
14082         for(set = *enclose; set; set = set->next) {
14083                 display_triple(state->dbgout, set->member);
14084         }
14085         fflush(state->dbgout);
14086 #endif
14087
14088         /* Clear the marks */
14089         ins = first;
14090         do {
14091                 ins->id = info[ID_BITS(ins->id)].id;
14092                 ins = ins->next;
14093         } while(ins != first);
14094
14095         /* Release the ordered list of live variables */
14096         free_closure_variables(state, &vars);
14097
14098         /* Release the storage of the old ids */
14099         xfree(info);
14100
14101         /* Release the variable lifetime information */
14102         free_variable_lifetimes(state, &bb, rb);
14103
14104         /* Release the basic blocks of this function */
14105         free_basic_blocks(state, &bb);
14106 }
14107
14108 static void expand_function_call(
14109         struct compile_state *state, struct triple *me, struct triple *fcall)
14110 {
14111         /* Generate an ordinary function call */
14112         struct type *closure_type, **closure_next;
14113         struct triple *func, *func_first, *func_last, *retvar;
14114         struct triple *first;
14115         struct type *ptype, *rtype;
14116         struct triple *jmp;
14117         struct triple *ret_addr, *ret_loc, *ret_set;
14118         struct triple_reg_set *enclose, *set;
14119         int closure_idx, pvals, i;
14120
14121 #if DEBUG_EXPLICIT_CLOSURES
14122         FILE *fp = state->dbgout;
14123         fprintf(fp, "\ndisplay_func(me) ptr: %p\n", fcall);
14124         display_func(state, fp, MISC(fcall, 0));
14125         display_func(state, fp, me);
14126         fprintf(fp, "__________ %s _________ done\n\n", __FUNCTION__);
14127 #endif
14128
14129         /* Find the triples */
14130         func = MISC(fcall, 0);
14131         func_first = RHS(func, 0);
14132         retvar = fretaddr(state, func);
14133         func_last  = func_first->prev;
14134         first = fcall->next;
14135
14136         /* Find what I need to enclose */
14137         compute_closure_variables(state, me, fcall, &enclose);
14138
14139         /* Compute the closure type */
14140         closure_type = new_type(TYPE_TUPLE, 0, 0);
14141         closure_type->elements = 0;
14142         closure_next = &closure_type->left;
14143         for(set = enclose; set ; set = set->next) {
14144                 struct type *type;
14145                 type = &void_type;
14146                 if (set->member) {
14147                         type = set->member->type;
14148                 }
14149                 if (!*closure_next) {
14150                         *closure_next = type;
14151                 } else {
14152                         *closure_next = new_type(TYPE_PRODUCT, *closure_next, 
14153                                 type);
14154                         closure_next = &(*closure_next)->right;
14155                 }
14156                 closure_type->elements += 1;
14157         }
14158         if (closure_type->elements == 0) {
14159                 closure_type->type = TYPE_VOID;
14160         }
14161
14162
14163 #if DEBUG_EXPLICIT_CLOSURES
14164         fprintf(state->dbgout, "closure type: ");
14165         name_of(state->dbgout, closure_type);
14166         fprintf(state->dbgout, "\n");
14167 #endif
14168
14169         /* Update the called functions closure variable */
14170         closure_idx = add_closure_type(state, func, closure_type);
14171
14172         /* Generate some needed triples */
14173         ret_loc = label(state);
14174         ret_addr = triple(state, OP_ADDRCONST, &void_ptr_type, ret_loc, 0);
14175
14176         /* Pass the parameters to the new function */
14177         ptype = func->type->right;
14178         pvals = fcall->rhs;
14179         for(i = 0; i < pvals; i++) {
14180                 struct type *atype;
14181                 struct triple *arg, *param;
14182                 atype = ptype;
14183                 if ((ptype->type & TYPE_MASK) == TYPE_PRODUCT) {
14184                         atype = ptype->left;
14185                 }
14186                 param = farg(state, func, i);
14187                 if ((param->type->type & TYPE_MASK) != (atype->type & TYPE_MASK)) {
14188                         internal_error(state, fcall, "param type mismatch");
14189                 }
14190                 arg = RHS(fcall, i);
14191                 flatten(state, first, write_expr(state, param, arg));
14192                 ptype = ptype->right;
14193         }
14194         rtype = func->type->left;
14195
14196         /* Thread the triples together */
14197         ret_loc       = flatten(state, first, ret_loc);
14198
14199         /* Save the active variables in the result variable */
14200         for(i = 0, set = enclose; set ; set = set->next, i++) {
14201                 if (!set->member) {
14202                         continue;
14203                 }
14204                 flatten(state, ret_loc,
14205                         write_expr(state,
14206                                 closure_expr(state, func, closure_idx, i),
14207                                 read_expr(state, set->member)));
14208         }
14209
14210         /* Initialize the return value */
14211         if ((rtype->type & TYPE_MASK) != TYPE_VOID) {
14212                 flatten(state, ret_loc, 
14213                         write_expr(state, 
14214                                 deref_index(state, fresult(state, func), 1),
14215                                 new_triple(state, OP_UNKNOWNVAL, rtype,  0, 0)));
14216         }
14217
14218         ret_addr      = flatten(state, ret_loc, ret_addr);
14219         ret_set       = flatten(state, ret_loc, write_expr(state, retvar, ret_addr));
14220         jmp           = flatten(state, ret_loc, 
14221                 call(state, retvar, ret_addr, func_first, func_last));
14222
14223         /* Find the result */
14224         if ((rtype->type & TYPE_MASK) != TYPE_VOID) {
14225                 struct triple * result;
14226                 result = flatten(state, first, 
14227                         read_expr(state, 
14228                                 deref_index(state, fresult(state, func), 1)));
14229
14230                 propogate_use(state, fcall, result);
14231         }
14232
14233         /* Release the original fcall instruction */
14234         release_triple(state, fcall);
14235
14236         /* Restore the active variables from the result variable */
14237         for(i = 0, set = enclose; set ; set = set->next, i++) {
14238                 struct triple_set *use, *next;
14239                 struct triple *new;
14240                 struct basic_blocks bb;
14241                 if (!set->member || (set->member == fcall)) {
14242                         continue;
14243                 }
14244                 /* Generate an expression for the value */
14245                 new = flatten(state, first,
14246                         read_expr(state, 
14247                                 closure_expr(state, func, closure_idx, i)));
14248
14249
14250                 /* If the original is an lvalue restore the preserved value */
14251                 if (is_lvalue(state, set->member)) {
14252                         flatten(state, first,
14253                                 write_expr(state, set->member, new));
14254                         continue;
14255                 }
14256                 /*
14257                  * If the original is a value update the dominated uses.
14258                  */
14259                 
14260                 /* Analyze the basic blocks so I can see who dominates whom */
14261                 bb.func = me;
14262                 bb.first = RHS(me, 0);
14263                 if (!triple_is_ret(state, bb.first->prev)) {
14264                         bb.func = 0;
14265                 }
14266                 analyze_basic_blocks(state, &bb);
14267                 
14268
14269 #if DEBUG_EXPLICIT_CLOSURES
14270                 fprintf(state->errout, "Updating domindated uses: %p -> %p\n",
14271                         set->member, new);
14272 #endif
14273                 /* If fcall dominates the use update the expression */
14274                 for(use = set->member->use; use; use = next) {
14275                         /* Replace use modifies the use chain and 
14276                          * removes use, so I must take a copy of the
14277                          * next entry early.
14278                          */
14279                         next = use->next;
14280                         if (!tdominates(state, fcall, use->member)) {
14281                                 continue;
14282                         }
14283                         replace_use(state, set->member, new, use->member);
14284                 }
14285
14286                 /* Release the basic blocks, the instructions will be
14287                  * different next time, and flatten/insert_triple does
14288                  * not update the block values so I can't cache the analysis.
14289                  */
14290                 free_basic_blocks(state, &bb);
14291         }
14292
14293         /* Release the closure variable list */
14294         free_closure_variables(state, &enclose);
14295
14296         if (state->compiler->debug & DEBUG_INLINE) {
14297                 FILE *fp = state->dbgout;
14298                 fprintf(fp, "\n");
14299                 loc(fp, state, 0);
14300                 fprintf(fp, "\n__________ %s _________\n", __FUNCTION__);
14301                 display_func(state, fp, func);
14302                 display_func(state, fp, me);
14303                 fprintf(fp, "__________ %s _________ done\n\n", __FUNCTION__);
14304         }
14305
14306         return;
14307 }
14308
14309 static int do_inline(struct compile_state *state, struct triple *func)
14310 {
14311         int do_inline;
14312         int policy;
14313
14314         policy = state->compiler->flags & COMPILER_INLINE_MASK;
14315         switch(policy) {
14316         case COMPILER_INLINE_ALWAYS:
14317                 do_inline = 1;
14318                 if (func->type->type & ATTRIB_NOINLINE) {
14319                         error(state, func, "noinline with always_inline compiler option");
14320                 }
14321                 break;
14322         case COMPILER_INLINE_NEVER:
14323                 do_inline = 0;
14324                 if (func->type->type & ATTRIB_ALWAYS_INLINE) {
14325                         error(state, func, "always_inline with noinline compiler option");
14326                 }
14327                 break;
14328         case COMPILER_INLINE_DEFAULTON:
14329                 switch(func->type->type & STOR_MASK) {
14330                 case STOR_STATIC | STOR_INLINE:
14331                 case STOR_LOCAL  | STOR_INLINE:
14332                 case STOR_EXTERN | STOR_INLINE:
14333                         do_inline = 1;
14334                         break;
14335                 default:
14336                         do_inline = 1;
14337                         break;
14338                 }
14339                 break;
14340         case COMPILER_INLINE_DEFAULTOFF:
14341                 switch(func->type->type & STOR_MASK) {
14342                 case STOR_STATIC | STOR_INLINE:
14343                 case STOR_LOCAL  | STOR_INLINE:
14344                 case STOR_EXTERN | STOR_INLINE:
14345                         do_inline = 1;
14346                         break;
14347                 default:
14348                         do_inline = 0;
14349                         break;
14350                 }
14351                 break;
14352         case COMPILER_INLINE_NOPENALTY:
14353                 switch(func->type->type & STOR_MASK) {
14354                 case STOR_STATIC | STOR_INLINE:
14355                 case STOR_LOCAL  | STOR_INLINE:
14356                 case STOR_EXTERN | STOR_INLINE:
14357                         do_inline = 1;
14358                         break;
14359                 default:
14360                         do_inline = (func->u.cval == 1);
14361                         break;
14362                 }
14363                 break;
14364         default:
14365                 do_inline = 0;
14366                 internal_error(state, 0, "Unimplemented inline policy");
14367                 break;
14368         }
14369         /* Force inlining */
14370         if (func->type->type & ATTRIB_NOINLINE) {
14371                 do_inline = 0;
14372         }
14373         if (func->type->type & ATTRIB_ALWAYS_INLINE) {
14374                 do_inline = 1;
14375         }
14376         return do_inline;
14377 }
14378
14379 static void inline_function(struct compile_state *state, struct triple *me, void *arg)
14380 {
14381         struct triple *first, *ptr, *next;
14382         /* If the function is not used don't bother */
14383         if (me->u.cval <= 0) {
14384                 return;
14385         }
14386         if (state->compiler->debug & DEBUG_CALLS2) {
14387                 FILE *fp = state->dbgout;
14388                 fprintf(fp, "in: %s\n",
14389                         me->type->type_ident->name);
14390         }
14391
14392         first = RHS(me, 0);
14393         ptr = next = first;
14394         do {
14395                 struct triple *func, *prev;
14396                 ptr = next;
14397                 prev = ptr->prev;
14398                 next = ptr->next;
14399                 if (ptr->op != OP_FCALL) {
14400                         continue;
14401                 }
14402                 func = MISC(ptr, 0);
14403                 /* See if the function should be inlined */
14404                 if (!do_inline(state, func)) {
14405                         /* Put a label after the fcall */
14406                         post_triple(state, ptr, OP_LABEL, &void_type, 0, 0);
14407                         continue;
14408                 }
14409                 if (state->compiler->debug & DEBUG_CALLS) {
14410                         FILE *fp = state->dbgout;
14411                         if (state->compiler->debug & DEBUG_CALLS2) {
14412                                 loc(fp, state, ptr);
14413                         }
14414                         fprintf(fp, "inlining %s\n",
14415                                 func->type->type_ident->name);
14416                         fflush(fp);
14417                 }
14418
14419                 /* Update the function use counts */
14420                 func->u.cval -= 1;
14421
14422                 /* Replace the fcall with the called function */
14423                 expand_inline_call(state, me, ptr);
14424
14425                 next = prev->next;
14426         } while (next != first);
14427
14428         ptr = next = first;
14429         do {
14430                 struct triple *prev, *func;
14431                 ptr = next;
14432                 prev = ptr->prev;
14433                 next = ptr->next;
14434                 if (ptr->op != OP_FCALL) {
14435                         continue;
14436                 }
14437                 func = MISC(ptr, 0);
14438                 if (state->compiler->debug & DEBUG_CALLS) {
14439                         FILE *fp = state->dbgout;
14440                         if (state->compiler->debug & DEBUG_CALLS2) {
14441                                 loc(fp, state, ptr);
14442                         }
14443                         fprintf(fp, "calling %s\n",
14444                                 func->type->type_ident->name);
14445                         fflush(fp);
14446                 }
14447                 /* Replace the fcall with the instruction sequence
14448                  * needed to make the call.
14449                  */
14450                 expand_function_call(state, me, ptr);
14451                 next = prev->next;
14452         } while(next != first);
14453 }
14454
14455 static void inline_functions(struct compile_state *state, struct triple *func)
14456 {
14457         inline_function(state, func, 0);
14458         reverse_walk_functions(state, inline_function, 0);
14459 }
14460
14461 static void insert_function(struct compile_state *state,
14462         struct triple *func, void *arg)
14463 {
14464         struct triple *first, *end, *ffirst, *fend;
14465
14466         if (state->compiler->debug & DEBUG_INLINE) {
14467                 FILE *fp = state->errout;
14468                 fprintf(fp, "%s func count: %d\n", 
14469                         func->type->type_ident->name, func->u.cval);
14470         }
14471         if (func->u.cval == 0) {
14472                 return;
14473         }
14474
14475         /* Find the end points of the lists */
14476         first  = arg;
14477         end    = first->prev;
14478         ffirst = RHS(func, 0);
14479         fend   = ffirst->prev;
14480
14481         /* splice the lists together */
14482         end->next    = ffirst;
14483         ffirst->prev = end;
14484         fend->next   = first;
14485         first->prev  = fend;
14486 }
14487
14488 struct triple *input_asm(struct compile_state *state)
14489 {
14490         struct asm_info *info;
14491         struct triple *def;
14492         int i, out;
14493         
14494         info = xcmalloc(sizeof(*info), "asm_info");
14495         info->str = "";
14496
14497         out = sizeof(arch_input_regs)/sizeof(arch_input_regs[0]);
14498         memcpy(&info->tmpl.lhs, arch_input_regs, sizeof(arch_input_regs));
14499
14500         def = new_triple(state, OP_ASM, &void_type, out, 0);
14501         def->u.ainfo = info;
14502         def->id |= TRIPLE_FLAG_VOLATILE;
14503         
14504         for(i = 0; i < out; i++) {
14505                 struct triple *piece;
14506                 piece = triple(state, OP_PIECE, &int_type, def, 0);
14507                 piece->u.cval = i;
14508                 LHS(def, i) = piece;
14509         }
14510
14511         return def;
14512 }
14513
14514 struct triple *output_asm(struct compile_state *state)
14515 {
14516         struct asm_info *info;
14517         struct triple *def;
14518         int in;
14519         
14520         info = xcmalloc(sizeof(*info), "asm_info");
14521         info->str = "";
14522
14523         in = sizeof(arch_output_regs)/sizeof(arch_output_regs[0]);
14524         memcpy(&info->tmpl.rhs, arch_output_regs, sizeof(arch_output_regs));
14525
14526         def = new_triple(state, OP_ASM, &void_type, 0, in);
14527         def->u.ainfo = info;
14528         def->id |= TRIPLE_FLAG_VOLATILE;
14529         
14530         return def;
14531 }
14532
14533 static void join_functions(struct compile_state *state)
14534 {
14535         struct triple *jmp, *start, *end, *call, *in, *out, *func;
14536         struct file_state file;
14537         struct type *pnext, *param;
14538         struct type *result_type, *args_type;
14539         int idx;
14540
14541         /* Be clear the functions have not been joined yet */
14542         state->functions_joined = 0;
14543
14544         /* Dummy file state to get debug handing right */
14545         memset(&file, 0, sizeof(file));
14546         file.basename = "";
14547         file.line = 0;
14548         file.report_line = 0;
14549         file.report_name = file.basename;
14550         file.prev = state->file;
14551         state->file = &file;
14552         state->function = "";
14553
14554         if (!state->main_function) {
14555                 error(state, 0, "No functions to compile\n");
14556         }
14557
14558         /* The type of arguments */
14559         args_type   = state->main_function->type->right;
14560         /* The return type without any specifiers */
14561         result_type = clone_type(0, state->main_function->type->left);
14562
14563
14564         /* Verify the external arguments */
14565         if (registers_of(state, args_type) > ARCH_INPUT_REGS) {
14566                 error(state, state->main_function, 
14567                         "Too many external input arguments");
14568         }
14569         if (registers_of(state, result_type) > ARCH_OUTPUT_REGS) {
14570                 error(state, state->main_function, 
14571                         "Too many external output arguments");
14572         }
14573
14574         /* Lay down the basic program structure */
14575         end           = label(state);
14576         start         = label(state);
14577         start         = flatten(state, state->first, start);
14578         end           = flatten(state, state->first, end);
14579         in            = input_asm(state);
14580         out           = output_asm(state);
14581         call          = new_triple(state, OP_FCALL, result_type, -1, registers_of(state, args_type));
14582         MISC(call, 0) = state->main_function;
14583         in            = flatten(state, state->first, in);
14584         call          = flatten(state, state->first, call);
14585         out           = flatten(state, state->first, out);
14586
14587
14588         /* Read the external input arguments */
14589         pnext = args_type;
14590         idx = 0;
14591         while(pnext && ((pnext->type & TYPE_MASK) != TYPE_VOID)) {
14592                 struct triple *expr;
14593                 param = pnext;
14594                 pnext = 0;
14595                 if ((param->type & TYPE_MASK) == TYPE_PRODUCT) {
14596                         pnext = param->right;
14597                         param = param->left;
14598                 }
14599                 if (registers_of(state, param) != 1) {
14600                         error(state, state->main_function, 
14601                                 "Arg: %d %s requires multiple registers", 
14602                                 idx + 1, param->field_ident->name);
14603                 }
14604                 expr = read_expr(state, LHS(in, idx));
14605                 RHS(call, idx) = expr;
14606                 expr = flatten(state, call, expr);
14607                 use_triple(expr, call);
14608
14609                 idx++;  
14610         }
14611
14612
14613         /* Write the external output arguments */
14614         pnext = result_type;
14615         if ((pnext->type & TYPE_MASK) == TYPE_STRUCT) {
14616                 pnext = result_type->left;
14617         }
14618         for(idx = 0; idx < out->rhs; idx++) {
14619                 struct triple *expr;
14620                 param = pnext;
14621                 pnext = 0;
14622                 if (param && ((param->type & TYPE_MASK) == TYPE_PRODUCT)) {
14623                         pnext = param->right;
14624                         param = param->left;
14625                 }
14626                 if (param && ((param->type & TYPE_MASK) == TYPE_VOID)) {
14627                         param = 0;
14628                 }
14629                 if (param) {
14630                         if (registers_of(state, param) != 1) {
14631                                 error(state, state->main_function,
14632                                         "Result: %d %s requires multiple registers",
14633                                         idx, param->field_ident->name);
14634                         }
14635                         expr = read_expr(state, call);
14636                         if ((result_type->type & TYPE_MASK) == TYPE_STRUCT) {
14637                                 expr = deref_field(state, expr, param->field_ident);
14638                         }
14639                 } else {
14640                         expr = triple(state, OP_UNKNOWNVAL, &int_type, 0, 0);
14641                 }
14642                 flatten(state, out, expr);
14643                 RHS(out, idx) = expr;
14644                 use_triple(expr, out);
14645         }
14646
14647         /* Allocate a dummy containing function */
14648         func = triple(state, OP_LIST, 
14649                 new_type(TYPE_FUNCTION, &void_type, &void_type), 0, 0);
14650         func->type->type_ident = lookup(state, "", 0);
14651         RHS(func, 0) = state->first;
14652         func->u.cval = 1;
14653
14654         /* See which functions are called, and how often */
14655         mark_live_functions(state);
14656         inline_functions(state, func);
14657         walk_functions(state, insert_function, end);
14658
14659         if (start->next != end) {
14660                 jmp = flatten(state, start, branch(state, end, 0));
14661         }
14662
14663         /* OK now the functions have been joined. */
14664         state->functions_joined = 1;
14665
14666         /* Done now cleanup */
14667         state->file = file.prev;
14668         state->function = 0;
14669 }
14670
14671 /*
14672  * Data structurs for optimation.
14673  */
14674
14675
14676 static int do_use_block(
14677         struct block *used, struct block_set **head, struct block *user, 
14678         int front)
14679 {
14680         struct block_set **ptr, *new;
14681         if (!used)
14682                 return 0;
14683         if (!user)
14684                 return 0;
14685         ptr = head;
14686         while(*ptr) {
14687                 if ((*ptr)->member == user) {
14688                         return 0;
14689                 }
14690                 ptr = &(*ptr)->next;
14691         }
14692         new = xcmalloc(sizeof(*new), "block_set");
14693         new->member = user;
14694         if (front) {
14695                 new->next = *head;
14696                 *head = new;
14697         }
14698         else {
14699                 new->next = 0;
14700                 *ptr = new;
14701         }
14702         return 1;
14703 }
14704 static int do_unuse_block(
14705         struct block *used, struct block_set **head, struct block *unuser)
14706 {
14707         struct block_set *use, **ptr;
14708         int count;
14709         count = 0;
14710         ptr = head;
14711         while(*ptr) {
14712                 use = *ptr;
14713                 if (use->member == unuser) {
14714                         *ptr = use->next;
14715                         memset(use, -1, sizeof(*use));
14716                         xfree(use);
14717                         count += 1;
14718                 }
14719                 else {
14720                         ptr = &use->next;
14721                 }
14722         }
14723         return count;
14724 }
14725
14726 static void use_block(struct block *used, struct block *user)
14727 {
14728         int count;
14729         /* Append new to the head of the list, print_block
14730          * depends on this.
14731          */
14732         count = do_use_block(used, &used->use, user, 1); 
14733         used->users += count;
14734 }
14735 static void unuse_block(struct block *used, struct block *unuser)
14736 {
14737         int count;
14738         count = do_unuse_block(used, &used->use, unuser); 
14739         used->users -= count;
14740 }
14741
14742 static void add_block_edge(struct block *block, struct block *edge, int front)
14743 {
14744         int count;
14745         count = do_use_block(block, &block->edges, edge, front);
14746         block->edge_count += count;
14747 }
14748
14749 static void remove_block_edge(struct block *block, struct block *edge)
14750 {
14751         int count;
14752         count = do_unuse_block(block, &block->edges, edge);
14753         block->edge_count -= count;
14754 }
14755
14756 static void idom_block(struct block *idom, struct block *user)
14757 {
14758         do_use_block(idom, &idom->idominates, user, 0);
14759 }
14760
14761 static void unidom_block(struct block *idom, struct block *unuser)
14762 {
14763         do_unuse_block(idom, &idom->idominates, unuser);
14764 }
14765
14766 static void domf_block(struct block *block, struct block *domf)
14767 {
14768         do_use_block(block, &block->domfrontier, domf, 0);
14769 }
14770
14771 static void undomf_block(struct block *block, struct block *undomf)
14772 {
14773         do_unuse_block(block, &block->domfrontier, undomf);
14774 }
14775
14776 static void ipdom_block(struct block *ipdom, struct block *user)
14777 {
14778         do_use_block(ipdom, &ipdom->ipdominates, user, 0);
14779 }
14780
14781 static void unipdom_block(struct block *ipdom, struct block *unuser)
14782 {
14783         do_unuse_block(ipdom, &ipdom->ipdominates, unuser);
14784 }
14785
14786 static void ipdomf_block(struct block *block, struct block *ipdomf)
14787 {
14788         do_use_block(block, &block->ipdomfrontier, ipdomf, 0);
14789 }
14790
14791 static void unipdomf_block(struct block *block, struct block *unipdomf)
14792 {
14793         do_unuse_block(block, &block->ipdomfrontier, unipdomf);
14794 }
14795
14796 static int walk_triples(
14797         struct compile_state *state, 
14798         int (*cb)(struct compile_state *state, struct triple *ptr, void *arg),
14799         void *arg)
14800 {
14801         struct triple *ptr;
14802         int result;
14803         ptr = state->first;
14804         do {
14805                 result = cb(state, ptr, arg);
14806                 if (ptr->next->prev != ptr) {
14807                         internal_error(state, ptr->next, "bad prev");
14808                 }
14809                 ptr = ptr->next;
14810         } while((result == 0) && (ptr != state->first));
14811         return result;
14812 }
14813
14814 #define PRINT_LIST 1
14815 static int do_print_triple(struct compile_state *state, struct triple *ins, void *arg)
14816 {
14817         FILE *fp = arg;
14818         int op;
14819         op = ins->op;
14820         if (op == OP_LIST) {
14821 #if !PRINT_LIST
14822                 return 0;
14823 #endif
14824         }
14825         if ((op == OP_LABEL) && (ins->use)) {
14826                 fprintf(fp, "\n%p:\n", ins);
14827         }
14828         display_triple(fp, ins);
14829
14830         if (triple_is_branch(state, ins) && ins->use && 
14831                 (ins->op != OP_RET) && (ins->op != OP_FCALL)) {
14832                 internal_error(state, ins, "branch used?");
14833         }
14834         if (triple_is_branch(state, ins)) {
14835                 fprintf(fp, "\n");
14836         }
14837         return 0;
14838 }
14839
14840 static void print_triples(struct compile_state *state)
14841 {
14842         if (state->compiler->debug & DEBUG_TRIPLES) {
14843                 FILE *fp = state->dbgout;
14844                 fprintf(fp, "--------------- triples ---------------\n");
14845                 walk_triples(state, do_print_triple, fp);
14846                 fprintf(fp, "\n");
14847         }
14848 }
14849
14850 struct cf_block {
14851         struct block *block;
14852 };
14853 static void find_cf_blocks(struct cf_block *cf, struct block *block)
14854 {
14855         struct block_set *edge;
14856         if (!block || (cf[block->vertex].block == block)) {
14857                 return;
14858         }
14859         cf[block->vertex].block = block;
14860         for(edge = block->edges; edge; edge = edge->next) {
14861                 find_cf_blocks(cf, edge->member);
14862         }
14863 }
14864
14865 static void print_control_flow(struct compile_state *state,
14866         FILE *fp, struct basic_blocks *bb)
14867 {
14868         struct cf_block *cf;
14869         int i;
14870         fprintf(fp, "\ncontrol flow\n");
14871         cf = xcmalloc(sizeof(*cf) * (bb->last_vertex + 1), "cf_block");
14872         find_cf_blocks(cf, bb->first_block);
14873
14874         for(i = 1; i <= bb->last_vertex; i++) {
14875                 struct block *block;
14876                 struct block_set *edge;
14877                 block = cf[i].block;
14878                 if (!block)
14879                         continue;
14880                 fprintf(fp, "(%p) %d:", block, block->vertex);
14881                 for(edge = block->edges; edge; edge = edge->next) {
14882                         fprintf(fp, " %d", edge->member->vertex);
14883                 }
14884                 fprintf(fp, "\n");
14885         }
14886
14887         xfree(cf);
14888 }
14889
14890 static void free_basic_block(struct compile_state *state, struct block *block)
14891 {
14892         struct block_set *edge, *entry;
14893         struct block *child;
14894         if (!block) {
14895                 return;
14896         }
14897         if (block->vertex == -1) {
14898                 return;
14899         }
14900         block->vertex = -1;
14901         for(edge = block->edges; edge; edge = edge->next) {
14902                 if (edge->member) {
14903                         unuse_block(edge->member, block);
14904                 }
14905         }
14906         if (block->idom) {
14907                 unidom_block(block->idom, block);
14908         }
14909         block->idom = 0;
14910         if (block->ipdom) {
14911                 unipdom_block(block->ipdom, block);
14912         }
14913         block->ipdom = 0;
14914         while((entry = block->use)) {
14915                 child = entry->member;
14916                 unuse_block(block, child);
14917                 if (child && (child->vertex != -1)) {
14918                         for(edge = child->edges; edge; edge = edge->next) {
14919                                 edge->member = 0;
14920                         }
14921                 }
14922         }
14923         while((entry = block->idominates)) {
14924                 child = entry->member;
14925                 unidom_block(block, child);
14926                 if (child && (child->vertex != -1)) {
14927                         child->idom = 0;
14928                 }
14929         }
14930         while((entry = block->domfrontier)) {
14931                 child = entry->member;
14932                 undomf_block(block, child);
14933         }
14934         while((entry = block->ipdominates)) {
14935                 child = entry->member;
14936                 unipdom_block(block, child);
14937                 if (child && (child->vertex != -1)) {
14938                         child->ipdom = 0;
14939                 }
14940         }
14941         while((entry = block->ipdomfrontier)) {
14942                 child = entry->member;
14943                 unipdomf_block(block, child);
14944         }
14945         if (block->users != 0) {
14946                 internal_error(state, 0, "block still has users");
14947         }
14948         while((edge = block->edges)) {
14949                 child = edge->member;
14950                 remove_block_edge(block, child);
14951                 
14952                 if (child && (child->vertex != -1)) {
14953                         free_basic_block(state, child);
14954                 }
14955         }
14956         memset(block, -1, sizeof(*block));
14957         xfree(block);
14958 }
14959
14960 static void free_basic_blocks(struct compile_state *state, 
14961         struct basic_blocks *bb)
14962 {
14963         struct triple *first, *ins;
14964         free_basic_block(state, bb->first_block);
14965         bb->last_vertex = 0;
14966         bb->first_block = bb->last_block = 0;
14967         first = bb->first;
14968         ins = first;
14969         do {
14970                 if (triple_stores_block(state, ins)) {
14971                         ins->u.block = 0;
14972                 }
14973                 ins = ins->next;
14974         } while(ins != first);
14975         
14976 }
14977
14978 static struct block *basic_block(struct compile_state *state, 
14979         struct basic_blocks *bb, struct triple *first)
14980 {
14981         struct block *block;
14982         struct triple *ptr;
14983         if (!triple_is_label(state, first)) {
14984                 internal_error(state, first, "block does not start with a label");
14985         }
14986         /* See if this basic block has already been setup */
14987         if (first->u.block != 0) {
14988                 return first->u.block;
14989         }
14990         /* Allocate another basic block structure */
14991         bb->last_vertex += 1;
14992         block = xcmalloc(sizeof(*block), "block");
14993         block->first = block->last = first;
14994         block->vertex = bb->last_vertex;
14995         ptr = first;
14996         do {
14997                 if ((ptr != first) && triple_is_label(state, ptr) && (ptr->use)) { 
14998                         break;
14999                 }
15000                 block->last = ptr;
15001                 /* If ptr->u is not used remember where the baic block is */
15002                 if (triple_stores_block(state, ptr)) {
15003                         ptr->u.block = block;
15004                 }
15005                 if (triple_is_branch(state, ptr)) {
15006                         break;
15007                 }
15008                 ptr = ptr->next;
15009         } while (ptr != bb->first);
15010         if ((ptr == bb->first) ||
15011                 ((ptr->next == bb->first) && (
15012                         triple_is_end(state, ptr) || 
15013                         triple_is_ret(state, ptr))))
15014         {
15015                 /* The block has no outflowing edges */
15016         }
15017         else if (triple_is_label(state, ptr)) {
15018                 struct block *next;
15019                 next = basic_block(state, bb, ptr);
15020                 add_block_edge(block, next, 0);
15021                 use_block(next, block);
15022         }
15023         else if (triple_is_branch(state, ptr)) {
15024                 struct triple **expr, *first;
15025                 struct block *child;
15026                 /* Find the branch targets.
15027                  * I special case the first branch as that magically
15028                  * avoids some difficult cases for the register allocator.
15029                  */
15030                 expr = triple_edge_targ(state, ptr, 0);
15031                 if (!expr) {
15032                         internal_error(state, ptr, "branch without targets");
15033                 }
15034                 first = *expr;
15035                 expr = triple_edge_targ(state, ptr, expr);
15036                 for(; expr; expr = triple_edge_targ(state, ptr, expr)) {
15037                         if (!*expr) continue;
15038                         child = basic_block(state, bb, *expr);
15039                         use_block(child, block);
15040                         add_block_edge(block, child, 0);
15041                 }
15042                 if (first) {
15043                         child = basic_block(state, bb, first);
15044                         use_block(child, block);
15045                         add_block_edge(block, child, 1);
15046
15047                         /* Be certain the return block of a call is
15048                          * in a basic block.  When it is not find
15049                          * start of the block, insert a label if
15050                          * necessary and build the basic block.
15051                          * Then add a fake edge from the start block
15052                          * to the return block of the function.
15053                          */
15054                         if (state->functions_joined && triple_is_call(state, ptr)
15055                                 && !block_of_triple(state, MISC(ptr, 0))) {
15056                                 struct block *tail;
15057                                 struct triple *start;
15058                                 start = triple_to_block_start(state, MISC(ptr, 0));
15059                                 if (!triple_is_label(state, start)) {
15060                                         start = pre_triple(state,
15061                                                 start, OP_LABEL, &void_type, 0, 0);
15062                                 }
15063                                 tail = basic_block(state, bb, start);
15064                                 add_block_edge(child, tail, 0);
15065                                 use_block(tail, child);
15066                         }
15067                 }
15068         }
15069         else {
15070                 internal_error(state, 0, "Bad basic block split");
15071         }
15072 #if 0
15073 {
15074         struct block_set *edge;
15075         FILE *fp = state->errout;
15076         fprintf(fp, "basic_block: %10p [%2d] ( %10p - %10p )",
15077                 block, block->vertex, 
15078                 block->first, block->last);
15079         for(edge = block->edges; edge; edge = edge->next) {
15080                 fprintf(fp, " %10p [%2d]",
15081                         edge->member ? edge->member->first : 0,
15082                         edge->member ? edge->member->vertex : -1);
15083         }
15084         fprintf(fp, "\n");
15085 }
15086 #endif
15087         return block;
15088 }
15089
15090
15091 static void walk_blocks(struct compile_state *state, struct basic_blocks *bb,
15092         void (*cb)(struct compile_state *state, struct block *block, void *arg),
15093         void *arg)
15094 {
15095         struct triple *ptr, *first;
15096         struct block *last_block;
15097         last_block = 0;
15098         first = bb->first;
15099         ptr = first;
15100         do {
15101                 if (triple_stores_block(state, ptr)) {
15102                         struct block *block;
15103                         block = ptr->u.block;
15104                         if (block && (block != last_block)) {
15105                                 cb(state, block, arg);
15106                         }
15107                         last_block = block;
15108                 }
15109                 ptr = ptr->next;
15110         } while(ptr != first);
15111 }
15112
15113 static void print_block(
15114         struct compile_state *state, struct block *block, void *arg)
15115 {
15116         struct block_set *user, *edge;
15117         struct triple *ptr;
15118         FILE *fp = arg;
15119
15120         fprintf(fp, "\nblock: %p (%d) ",
15121                 block, 
15122                 block->vertex);
15123
15124         for(edge = block->edges; edge; edge = edge->next) {
15125                 fprintf(fp, " %p<-%p",
15126                         edge->member,
15127                         (edge->member && edge->member->use)?
15128                         edge->member->use->member : 0);
15129         }
15130         fprintf(fp, "\n");
15131         if (block->first->op == OP_LABEL) {
15132                 fprintf(fp, "%p:\n", block->first);
15133         }
15134         for(ptr = block->first; ; ) {
15135                 display_triple(fp, ptr);
15136                 if (ptr == block->last)
15137                         break;
15138                 ptr = ptr->next;
15139                 if (ptr == block->first) {
15140                         internal_error(state, 0, "missing block last?");
15141                 }
15142         }
15143         fprintf(fp, "users %d: ", block->users);
15144         for(user = block->use; user; user = user->next) {
15145                 fprintf(fp, "%p (%d) ", 
15146                         user->member,
15147                         user->member->vertex);
15148         }
15149         fprintf(fp,"\n\n");
15150 }
15151
15152
15153 static void romcc_print_blocks(struct compile_state *state, FILE *fp)
15154 {
15155         fprintf(fp, "--------------- blocks ---------------\n");
15156         walk_blocks(state, &state->bb, print_block, fp);
15157 }
15158 static void print_blocks(struct compile_state *state, const char *func, FILE *fp)
15159 {
15160         static void print_dominators(struct compile_state *state, FILE *fp, struct basic_blocks *bb);
15161         static void print_dominance_frontiers(struct compile_state *state, FILE *fp, struct basic_blocks *bb);
15162         if (state->compiler->debug & DEBUG_BASIC_BLOCKS) {
15163                 fprintf(fp, "After %s\n", func);
15164                 romcc_print_blocks(state, fp);
15165                 if (state->compiler->debug & DEBUG_FDOMINATORS) {
15166                         print_dominators(state, fp, &state->bb);
15167                         print_dominance_frontiers(state, fp, &state->bb);
15168                 }
15169                 print_control_flow(state, fp, &state->bb);
15170         }
15171 }
15172
15173 static void prune_nonblock_triples(struct compile_state *state, 
15174         struct basic_blocks *bb)
15175 {
15176         struct block *block;
15177         struct triple *first, *ins, *next;
15178         /* Delete the triples not in a basic block */
15179         block = 0;
15180         first = bb->first;
15181         ins = first;
15182         do {
15183                 next = ins->next;
15184                 if (ins->op == OP_LABEL) {
15185                         block = ins->u.block;
15186                 }
15187                 if (!block) {
15188                         struct triple_set *use;
15189                         for(use = ins->use; use; use = use->next) {
15190                                 struct block *block;
15191                                 block = block_of_triple(state, use->member);
15192                                 if (block != 0) {
15193                                         internal_error(state, ins, "pruning used ins?");
15194                                 }
15195                         }
15196                         release_triple(state, ins);
15197                 }
15198                 if (block && block->last == ins) {
15199                         block = 0;
15200                 }
15201                 ins = next;
15202         } while(ins != first);
15203 }
15204
15205 static void setup_basic_blocks(struct compile_state *state, 
15206         struct basic_blocks *bb)
15207 {
15208         if (!triple_stores_block(state, bb->first)) {
15209                 internal_error(state, 0, "ins will not store block?");
15210         }
15211         /* Initialize the state */
15212         bb->first_block = bb->last_block = 0;
15213         bb->last_vertex = 0;
15214         free_basic_blocks(state, bb);
15215
15216         /* Find the basic blocks */
15217         bb->first_block = basic_block(state, bb, bb->first);
15218
15219         /* Be certain the last instruction of a function, or the
15220          * entire program is in a basic block.  When it is not find 
15221          * the start of the block, insert a label if necessary and build 
15222          * basic block.  Then add a fake edge from the start block
15223          * to the final block.
15224          */
15225         if (!block_of_triple(state, bb->first->prev)) {
15226                 struct triple *start;
15227                 struct block *tail;
15228                 start = triple_to_block_start(state, bb->first->prev);
15229                 if (!triple_is_label(state, start)) {
15230                         start = pre_triple(state,
15231                                 start, OP_LABEL, &void_type, 0, 0);
15232                 }
15233                 tail = basic_block(state, bb, start);
15234                 add_block_edge(bb->first_block, tail, 0);
15235                 use_block(tail, bb->first_block);
15236         }
15237         
15238         /* Find the last basic block.
15239          */
15240         bb->last_block = block_of_triple(state, bb->first->prev);
15241
15242         /* Delete the triples not in a basic block */
15243         prune_nonblock_triples(state, bb);
15244
15245 #if 0
15246         /* If we are debugging print what I have just done */
15247         if (state->compiler->debug & DEBUG_BASIC_BLOCKS) {
15248                 print_blocks(state, state->dbgout);
15249                 print_control_flow(state, bb);
15250         }
15251 #endif
15252 }
15253
15254
15255 struct sdom_block {
15256         struct block *block;
15257         struct sdom_block *sdominates;
15258         struct sdom_block *sdom_next;
15259         struct sdom_block *sdom;
15260         struct sdom_block *label;
15261         struct sdom_block *parent;
15262         struct sdom_block *ancestor;
15263         int vertex;
15264 };
15265
15266
15267 static void unsdom_block(struct sdom_block *block)
15268 {
15269         struct sdom_block **ptr;
15270         if (!block->sdom_next) {
15271                 return;
15272         }
15273         ptr = &block->sdom->sdominates;
15274         while(*ptr) {
15275                 if ((*ptr) == block) {
15276                         *ptr = block->sdom_next;
15277                         return;
15278                 }
15279                 ptr = &(*ptr)->sdom_next;
15280         }
15281 }
15282
15283 static void sdom_block(struct sdom_block *sdom, struct sdom_block *block)
15284 {
15285         unsdom_block(block);
15286         block->sdom = sdom;
15287         block->sdom_next = sdom->sdominates;
15288         sdom->sdominates = block;
15289 }
15290
15291
15292
15293 static int initialize_sdblock(struct sdom_block *sd,
15294         struct block *parent, struct block *block, int vertex)
15295 {
15296         struct block_set *edge;
15297         if (!block || (sd[block->vertex].block == block)) {
15298                 return vertex;
15299         }
15300         vertex += 1;
15301         /* Renumber the blocks in a convinient fashion */
15302         block->vertex = vertex;
15303         sd[vertex].block    = block;
15304         sd[vertex].sdom     = &sd[vertex];
15305         sd[vertex].label    = &sd[vertex];
15306         sd[vertex].parent   = parent? &sd[parent->vertex] : 0;
15307         sd[vertex].ancestor = 0;
15308         sd[vertex].vertex   = vertex;
15309         for(edge = block->edges; edge; edge = edge->next) {
15310                 vertex = initialize_sdblock(sd, block, edge->member, vertex);
15311         }
15312         return vertex;
15313 }
15314
15315 static int initialize_spdblock(
15316         struct compile_state *state, struct sdom_block *sd,
15317         struct block *parent, struct block *block, int vertex)
15318 {
15319         struct block_set *user;
15320         if (!block || (sd[block->vertex].block == block)) {
15321                 return vertex;
15322         }
15323         vertex += 1;
15324         /* Renumber the blocks in a convinient fashion */
15325         block->vertex = vertex;
15326         sd[vertex].block    = block;
15327         sd[vertex].sdom     = &sd[vertex];
15328         sd[vertex].label    = &sd[vertex];
15329         sd[vertex].parent   = parent? &sd[parent->vertex] : 0;
15330         sd[vertex].ancestor = 0;
15331         sd[vertex].vertex   = vertex;
15332         for(user = block->use; user; user = user->next) {
15333                 vertex = initialize_spdblock(state, sd, block, user->member, vertex);
15334         }
15335         return vertex;
15336 }
15337
15338 static int setup_spdblocks(struct compile_state *state, 
15339         struct basic_blocks *bb, struct sdom_block *sd)
15340 {
15341         struct block *block;
15342         int vertex;
15343         /* Setup as many sdpblocks as possible without using fake edges */
15344         vertex = initialize_spdblock(state, sd, 0, bb->last_block, 0);
15345
15346         /* Walk through the graph and find unconnected blocks.  Add a
15347          * fake edge from the unconnected blocks to the end of the
15348          * graph. 
15349          */
15350         block = bb->first_block->last->next->u.block;
15351         for(; block && block != bb->first_block; block = block->last->next->u.block) {
15352                 if (sd[block->vertex].block == block) {
15353                         continue;
15354                 }
15355 #if DEBUG_SDP_BLOCKS
15356                 {
15357                         FILE *fp = state->errout;
15358                         fprintf(fp, "Adding %d\n", vertex +1);
15359                 }
15360 #endif
15361                 add_block_edge(block, bb->last_block, 0);
15362                 use_block(bb->last_block, block);
15363
15364                 vertex = initialize_spdblock(state, sd, bb->last_block, block, vertex);
15365         }
15366         return vertex;
15367 }
15368
15369 static void compress_ancestors(struct sdom_block *v)
15370 {
15371         /* This procedure assumes ancestor(v) != 0 */
15372         /* if (ancestor(ancestor(v)) != 0) {
15373          *      compress(ancestor(ancestor(v)));
15374          *      if (semi(label(ancestor(v))) < semi(label(v))) {
15375          *              label(v) = label(ancestor(v));
15376          *      }
15377          *      ancestor(v) = ancestor(ancestor(v));
15378          * }
15379          */
15380         if (!v->ancestor) {
15381                 return;
15382         }
15383         if (v->ancestor->ancestor) {
15384                 compress_ancestors(v->ancestor->ancestor);
15385                 if (v->ancestor->label->sdom->vertex < v->label->sdom->vertex) {
15386                         v->label = v->ancestor->label;
15387                 }
15388                 v->ancestor = v->ancestor->ancestor;
15389         }
15390 }
15391
15392 static void compute_sdom(struct compile_state *state, 
15393         struct basic_blocks *bb, struct sdom_block *sd)
15394 {
15395         int i;
15396         /* // step 2 
15397          *  for each v <= pred(w) {
15398          *      u = EVAL(v);
15399          *      if (semi[u] < semi[w] { 
15400          *              semi[w] = semi[u]; 
15401          *      } 
15402          * }
15403          * add w to bucket(vertex(semi[w]));
15404          * LINK(parent(w), w);
15405          *
15406          * // step 3
15407          * for each v <= bucket(parent(w)) {
15408          *      delete v from bucket(parent(w));
15409          *      u = EVAL(v);
15410          *      dom(v) = (semi[u] < semi[v]) ? u : parent(w);
15411          * }
15412          */
15413         for(i = bb->last_vertex; i >= 2; i--) {
15414                 struct sdom_block *v, *parent, *next;
15415                 struct block_set *user;
15416                 struct block *block;
15417                 block = sd[i].block;
15418                 parent = sd[i].parent;
15419                 /* Step 2 */
15420                 for(user = block->use; user; user = user->next) {
15421                         struct sdom_block *v, *u;
15422                         v = &sd[user->member->vertex];
15423                         u = !(v->ancestor)? v : (compress_ancestors(v), v->label);
15424                         if (u->sdom->vertex < sd[i].sdom->vertex) {
15425                                 sd[i].sdom = u->sdom;
15426                         }
15427                 }
15428                 sdom_block(sd[i].sdom, &sd[i]);
15429                 sd[i].ancestor = parent;
15430                 /* Step 3 */
15431                 for(v = parent->sdominates; v; v = next) {
15432                         struct sdom_block *u;
15433                         next = v->sdom_next;
15434                         unsdom_block(v);
15435                         u = (!v->ancestor) ? v : (compress_ancestors(v), v->label);
15436                         v->block->idom = (u->sdom->vertex < v->sdom->vertex)? 
15437                                 u->block : parent->block;
15438                 }
15439         }
15440 }
15441
15442 static void compute_spdom(struct compile_state *state, 
15443         struct basic_blocks *bb, struct sdom_block *sd)
15444 {
15445         int i;
15446         /* // step 2 
15447          *  for each v <= pred(w) {
15448          *      u = EVAL(v);
15449          *      if (semi[u] < semi[w] { 
15450          *              semi[w] = semi[u]; 
15451          *      } 
15452          * }
15453          * add w to bucket(vertex(semi[w]));
15454          * LINK(parent(w), w);
15455          *
15456          * // step 3
15457          * for each v <= bucket(parent(w)) {
15458          *      delete v from bucket(parent(w));
15459          *      u = EVAL(v);
15460          *      dom(v) = (semi[u] < semi[v]) ? u : parent(w);
15461          * }
15462          */
15463         for(i = bb->last_vertex; i >= 2; i--) {
15464                 struct sdom_block *u, *v, *parent, *next;
15465                 struct block_set *edge;
15466                 struct block *block;
15467                 block = sd[i].block;
15468                 parent = sd[i].parent;
15469                 /* Step 2 */
15470                 for(edge = block->edges; edge; edge = edge->next) {
15471                         v = &sd[edge->member->vertex];
15472                         u = !(v->ancestor)? v : (compress_ancestors(v), v->label);
15473                         if (u->sdom->vertex < sd[i].sdom->vertex) {
15474                                 sd[i].sdom = u->sdom;
15475                         }
15476                 }
15477                 sdom_block(sd[i].sdom, &sd[i]);
15478                 sd[i].ancestor = parent;
15479                 /* Step 3 */
15480                 for(v = parent->sdominates; v; v = next) {
15481                         struct sdom_block *u;
15482                         next = v->sdom_next;
15483                         unsdom_block(v);
15484                         u = (!v->ancestor) ? v : (compress_ancestors(v), v->label);
15485                         v->block->ipdom = (u->sdom->vertex < v->sdom->vertex)? 
15486                                 u->block : parent->block;
15487                 }
15488         }
15489 }
15490
15491 static void compute_idom(struct compile_state *state, 
15492         struct basic_blocks *bb, struct sdom_block *sd)
15493 {
15494         int i;
15495         for(i = 2; i <= bb->last_vertex; i++) {
15496                 struct block *block;
15497                 block = sd[i].block;
15498                 if (block->idom->vertex != sd[i].sdom->vertex) {
15499                         block->idom = block->idom->idom;
15500                 }
15501                 idom_block(block->idom, block);
15502         }
15503         sd[1].block->idom = 0;
15504 }
15505
15506 static void compute_ipdom(struct compile_state *state, 
15507         struct basic_blocks *bb, struct sdom_block *sd)
15508 {
15509         int i;
15510         for(i = 2; i <= bb->last_vertex; i++) {
15511                 struct block *block;
15512                 block = sd[i].block;
15513                 if (block->ipdom->vertex != sd[i].sdom->vertex) {
15514                         block->ipdom = block->ipdom->ipdom;
15515                 }
15516                 ipdom_block(block->ipdom, block);
15517         }
15518         sd[1].block->ipdom = 0;
15519 }
15520
15521         /* Theorem 1:
15522          *   Every vertex of a flowgraph G = (V, E, r) except r has
15523          *   a unique immediate dominator.  
15524          *   The edges {(idom(w), w) |w <= V - {r}} form a directed tree
15525          *   rooted at r, called the dominator tree of G, such that 
15526          *   v dominates w if and only if v is a proper ancestor of w in
15527          *   the dominator tree.
15528          */
15529         /* Lemma 1:  
15530          *   If v and w are vertices of G such that v <= w,
15531          *   than any path from v to w must contain a common ancestor
15532          *   of v and w in T.
15533          */
15534         /* Lemma 2:  For any vertex w != r, idom(w) -> w */
15535         /* Lemma 3:  For any vertex w != r, sdom(w) -> w */
15536         /* Lemma 4:  For any vertex w != r, idom(w) -> sdom(w) */
15537         /* Theorem 2:
15538          *   Let w != r.  Suppose every u for which sdom(w) -> u -> w satisfies
15539          *   sdom(u) >= sdom(w).  Then idom(w) = sdom(w).
15540          */
15541         /* Theorem 3:
15542          *   Let w != r and let u be a vertex for which sdom(u) is 
15543          *   minimum amoung vertices u satisfying sdom(w) -> u -> w.
15544          *   Then sdom(u) <= sdom(w) and idom(u) = idom(w).
15545          */
15546         /* Lemma 5:  Let vertices v,w satisfy v -> w.
15547          *           Then v -> idom(w) or idom(w) -> idom(v)
15548          */
15549
15550 static void find_immediate_dominators(struct compile_state *state,
15551         struct basic_blocks *bb)
15552 {
15553         struct sdom_block *sd;
15554         /* w->sdom = min{v| there is a path v = v0,v1,...,vk = w such that:
15555          *           vi > w for (1 <= i <= k - 1}
15556          */
15557         /* Theorem 4:
15558          *   For any vertex w != r.
15559          *   sdom(w) = min(
15560          *                 {v|(v,w) <= E  and v < w } U 
15561          *                 {sdom(u) | u > w and there is an edge (v, w) such that u -> v})
15562          */
15563         /* Corollary 1:
15564          *   Let w != r and let u be a vertex for which sdom(u) is 
15565          *   minimum amoung vertices u satisfying sdom(w) -> u -> w.
15566          *   Then:
15567          *                   { sdom(w) if sdom(w) = sdom(u),
15568          *        idom(w) = {
15569          *                   { idom(u) otherwise
15570          */
15571         /* The algorithm consists of the following 4 steps.
15572          * Step 1.  Carry out a depth-first search of the problem graph.  
15573          *    Number the vertices from 1 to N as they are reached during
15574          *    the search.  Initialize the variables used in succeeding steps.
15575          * Step 2.  Compute the semidominators of all vertices by applying
15576          *    theorem 4.   Carry out the computation vertex by vertex in
15577          *    decreasing order by number.
15578          * Step 3.  Implicitly define the immediate dominator of each vertex
15579          *    by applying Corollary 1.
15580          * Step 4.  Explicitly define the immediate dominator of each vertex,
15581          *    carrying out the computation vertex by vertex in increasing order
15582          *    by number.
15583          */
15584         /* Step 1 initialize the basic block information */
15585         sd = xcmalloc(sizeof(*sd) * (bb->last_vertex + 1), "sdom_state");
15586         initialize_sdblock(sd, 0, bb->first_block, 0);
15587 #if 0
15588         sd[1].size  = 0;
15589         sd[1].label = 0;
15590         sd[1].sdom  = 0;
15591 #endif
15592         /* Step 2 compute the semidominators */
15593         /* Step 3 implicitly define the immediate dominator of each vertex */
15594         compute_sdom(state, bb, sd);
15595         /* Step 4 explicitly define the immediate dominator of each vertex */
15596         compute_idom(state, bb, sd);
15597         xfree(sd);
15598 }
15599
15600 static void find_post_dominators(struct compile_state *state,
15601         struct basic_blocks *bb)
15602 {
15603         struct sdom_block *sd;
15604         int vertex;
15605         /* Step 1 initialize the basic block information */
15606         sd = xcmalloc(sizeof(*sd) * (bb->last_vertex + 1), "sdom_state");
15607
15608         vertex = setup_spdblocks(state, bb, sd);
15609         if (vertex != bb->last_vertex) {
15610                 internal_error(state, 0, "missing %d blocks",
15611                         bb->last_vertex - vertex);
15612         }
15613
15614         /* Step 2 compute the semidominators */
15615         /* Step 3 implicitly define the immediate dominator of each vertex */
15616         compute_spdom(state, bb, sd);
15617         /* Step 4 explicitly define the immediate dominator of each vertex */
15618         compute_ipdom(state, bb, sd);
15619         xfree(sd);
15620 }
15621
15622
15623
15624 static void find_block_domf(struct compile_state *state, struct block *block)
15625 {
15626         struct block *child;
15627         struct block_set *user, *edge;
15628         if (block->domfrontier != 0) {
15629                 internal_error(state, block->first, "domfrontier present?");
15630         }
15631         for(user = block->idominates; user; user = user->next) {
15632                 child = user->member;
15633                 if (child->idom != block) {
15634                         internal_error(state, block->first, "bad idom");
15635                 }
15636                 find_block_domf(state, child);
15637         }
15638         for(edge = block->edges; edge; edge = edge->next) {
15639                 if (edge->member->idom != block) {
15640                         domf_block(block, edge->member);
15641                 }
15642         }
15643         for(user = block->idominates; user; user = user->next) {
15644                 struct block_set *frontier;
15645                 child = user->member;
15646                 for(frontier = child->domfrontier; frontier; frontier = frontier->next) {
15647                         if (frontier->member->idom != block) {
15648                                 domf_block(block, frontier->member);
15649                         }
15650                 }
15651         }
15652 }
15653
15654 static void find_block_ipdomf(struct compile_state *state, struct block *block)
15655 {
15656         struct block *child;
15657         struct block_set *user;
15658         if (block->ipdomfrontier != 0) {
15659                 internal_error(state, block->first, "ipdomfrontier present?");
15660         }
15661         for(user = block->ipdominates; user; user = user->next) {
15662                 child = user->member;
15663                 if (child->ipdom != block) {
15664                         internal_error(state, block->first, "bad ipdom");
15665                 }
15666                 find_block_ipdomf(state, child);
15667         }
15668         for(user = block->use; user; user = user->next) {
15669                 if (user->member->ipdom != block) {
15670                         ipdomf_block(block, user->member);
15671                 }
15672         }
15673         for(user = block->ipdominates; user; user = user->next) {
15674                 struct block_set *frontier;
15675                 child = user->member;
15676                 for(frontier = child->ipdomfrontier; frontier; frontier = frontier->next) {
15677                         if (frontier->member->ipdom != block) {
15678                                 ipdomf_block(block, frontier->member);
15679                         }
15680                 }
15681         }
15682 }
15683
15684 static void print_dominated(
15685         struct compile_state *state, struct block *block, void *arg)
15686 {
15687         struct block_set *user;
15688         FILE *fp = arg;
15689
15690         fprintf(fp, "%d:", block->vertex);
15691         for(user = block->idominates; user; user = user->next) {
15692                 fprintf(fp, " %d", user->member->vertex);
15693                 if (user->member->idom != block) {
15694                         internal_error(state, user->member->first, "bad idom");
15695                 }
15696         }
15697         fprintf(fp,"\n");
15698 }
15699
15700 static void print_dominated2(
15701         struct compile_state *state, FILE *fp, int depth, struct block *block)
15702 {
15703         struct block_set *user;
15704         struct triple *ins;
15705         struct occurance *ptr, *ptr2;
15706         const char *filename1, *filename2;
15707         int equal_filenames;
15708         int i;
15709         for(i = 0; i < depth; i++) {
15710                 fprintf(fp, "   ");
15711         }
15712         fprintf(fp, "%3d: %p (%p - %p) @", 
15713                 block->vertex, block, block->first, block->last);
15714         ins = block->first;
15715         while(ins != block->last && (ins->occurance->line == 0)) {
15716                 ins = ins->next;
15717         }
15718         ptr = ins->occurance;
15719         ptr2 = block->last->occurance;
15720         filename1 = ptr->filename? ptr->filename : "";
15721         filename2 = ptr2->filename? ptr2->filename : "";
15722         equal_filenames = (strcmp(filename1, filename2) == 0);
15723         if ((ptr == ptr2) || (equal_filenames && ptr->line == ptr2->line)) {
15724                 fprintf(fp, " %s:%d", ptr->filename, ptr->line);
15725         } else if (equal_filenames) {
15726                 fprintf(fp, " %s:(%d - %d)",
15727                         ptr->filename, ptr->line, ptr2->line);
15728         } else {
15729                 fprintf(fp, " (%s:%d - %s:%d)",
15730                         ptr->filename, ptr->line,
15731                         ptr2->filename, ptr2->line);
15732         }
15733         fprintf(fp, "\n");
15734         for(user = block->idominates; user; user = user->next) {
15735                 print_dominated2(state, fp, depth + 1, user->member);
15736         }
15737 }
15738
15739 static void print_dominators(struct compile_state *state, FILE *fp, struct basic_blocks *bb)
15740 {
15741         fprintf(fp, "\ndominates\n");
15742         walk_blocks(state, bb, print_dominated, fp);
15743         fprintf(fp, "dominates\n");
15744         print_dominated2(state, fp, 0, bb->first_block);
15745 }
15746
15747
15748 static int print_frontiers(
15749         struct compile_state *state, FILE *fp, struct block *block, int vertex)
15750 {
15751         struct block_set *user, *edge;
15752
15753         if (!block || (block->vertex != vertex + 1)) {
15754                 return vertex;
15755         }
15756         vertex += 1;
15757
15758         fprintf(fp, "%d:", block->vertex);
15759         for(user = block->domfrontier; user; user = user->next) {
15760                 fprintf(fp, " %d", user->member->vertex);
15761         }
15762         fprintf(fp, "\n");
15763         
15764         for(edge = block->edges; edge; edge = edge->next) {
15765                 vertex = print_frontiers(state, fp, edge->member, vertex);
15766         }
15767         return vertex;
15768 }
15769 static void print_dominance_frontiers(struct compile_state *state,
15770         FILE *fp, struct basic_blocks *bb)
15771 {
15772         fprintf(fp, "\ndominance frontiers\n");
15773         print_frontiers(state, fp, bb->first_block, 0);
15774         
15775 }
15776
15777 static void analyze_idominators(struct compile_state *state, struct basic_blocks *bb)
15778 {
15779         /* Find the immediate dominators */
15780         find_immediate_dominators(state, bb);
15781         /* Find the dominance frontiers */
15782         find_block_domf(state, bb->first_block);
15783         /* If debuging print the print what I have just found */
15784         if (state->compiler->debug & DEBUG_FDOMINATORS) {
15785                 print_dominators(state, state->dbgout, bb);
15786                 print_dominance_frontiers(state, state->dbgout, bb);
15787                 print_control_flow(state, state->dbgout, bb);
15788         }
15789 }
15790
15791
15792 static void print_ipdominated(
15793         struct compile_state *state, struct block *block, void *arg)
15794 {
15795         struct block_set *user;
15796         FILE *fp = arg;
15797
15798         fprintf(fp, "%d:", block->vertex);
15799         for(user = block->ipdominates; user; user = user->next) {
15800                 fprintf(fp, " %d", user->member->vertex);
15801                 if (user->member->ipdom != block) {
15802                         internal_error(state, user->member->first, "bad ipdom");
15803                 }
15804         }
15805         fprintf(fp, "\n");
15806 }
15807
15808 static void print_ipdominators(struct compile_state *state, FILE *fp,
15809         struct basic_blocks *bb)
15810 {
15811         fprintf(fp, "\nipdominates\n");
15812         walk_blocks(state, bb, print_ipdominated, fp);
15813 }
15814
15815 static int print_pfrontiers(
15816         struct compile_state *state, FILE *fp, struct block *block, int vertex)
15817 {
15818         struct block_set *user;
15819
15820         if (!block || (block->vertex != vertex + 1)) {
15821                 return vertex;
15822         }
15823         vertex += 1;
15824
15825         fprintf(fp, "%d:", block->vertex);
15826         for(user = block->ipdomfrontier; user; user = user->next) {
15827                 fprintf(fp, " %d", user->member->vertex);
15828         }
15829         fprintf(fp, "\n");
15830         for(user = block->use; user; user = user->next) {
15831                 vertex = print_pfrontiers(state, fp, user->member, vertex);
15832         }
15833         return vertex;
15834 }
15835 static void print_ipdominance_frontiers(struct compile_state *state,
15836         FILE *fp, struct basic_blocks *bb)
15837 {
15838         fprintf(fp, "\nipdominance frontiers\n");
15839         print_pfrontiers(state, fp, bb->last_block, 0);
15840         
15841 }
15842
15843 static void analyze_ipdominators(struct compile_state *state,
15844         struct basic_blocks *bb)
15845 {
15846         /* Find the post dominators */
15847         find_post_dominators(state, bb);
15848         /* Find the control dependencies (post dominance frontiers) */
15849         find_block_ipdomf(state, bb->last_block);
15850         /* If debuging print the print what I have just found */
15851         if (state->compiler->debug & DEBUG_RDOMINATORS) {
15852                 print_ipdominators(state, state->dbgout, bb);
15853                 print_ipdominance_frontiers(state, state->dbgout, bb);
15854                 print_control_flow(state, state->dbgout, bb);
15855         }
15856 }
15857
15858 static int bdominates(struct compile_state *state,
15859         struct block *dom, struct block *sub)
15860 {
15861         while(sub && (sub != dom)) {
15862                 sub = sub->idom;
15863         }
15864         return sub == dom;
15865 }
15866
15867 static int tdominates(struct compile_state *state,
15868         struct triple *dom, struct triple *sub)
15869 {
15870         struct block *bdom, *bsub;
15871         int result;
15872         bdom = block_of_triple(state, dom);
15873         bsub = block_of_triple(state, sub);
15874         if (bdom != bsub) {
15875                 result = bdominates(state, bdom, bsub);
15876         } 
15877         else {
15878                 struct triple *ins;
15879                 if (!bdom || !bsub) {
15880                         internal_error(state, dom, "huh?");
15881                 }
15882                 ins = sub;
15883                 while((ins != bsub->first) && (ins != dom)) {
15884                         ins = ins->prev;
15885                 }
15886                 result = (ins == dom);
15887         }
15888         return result;
15889 }
15890
15891 static void analyze_basic_blocks(
15892         struct compile_state *state, struct basic_blocks *bb)
15893 {
15894         setup_basic_blocks(state, bb);
15895         analyze_idominators(state, bb);
15896         analyze_ipdominators(state, bb);
15897 }
15898
15899 static void insert_phi_operations(struct compile_state *state)
15900 {
15901         size_t size;
15902         struct triple *first;
15903         int *has_already, *work;
15904         struct block *work_list, **work_list_tail;
15905         int iter;
15906         struct triple *var, *vnext;
15907
15908         size = sizeof(int) * (state->bb.last_vertex + 1);
15909         has_already = xcmalloc(size, "has_already");
15910         work =        xcmalloc(size, "work");
15911         iter = 0;
15912
15913         first = state->first;
15914         for(var = first->next; var != first ; var = vnext) {
15915                 struct block *block;
15916                 struct triple_set *user, *unext;
15917                 vnext = var->next;
15918
15919                 if (!triple_is_auto_var(state, var) || !var->use) {
15920                         continue;
15921                 }
15922                         
15923                 iter += 1;
15924                 work_list = 0;
15925                 work_list_tail = &work_list;
15926                 for(user = var->use; user; user = unext) {
15927                         unext = user->next;
15928                         if (MISC(var, 0) == user->member) {
15929                                 continue;
15930                         }
15931                         if (user->member->op == OP_READ) {
15932                                 continue;
15933                         }
15934                         if (user->member->op != OP_WRITE) {
15935                                 internal_error(state, user->member, 
15936                                         "bad variable access");
15937                         }
15938                         block = user->member->u.block;
15939                         if (!block) {
15940                                 warning(state, user->member, "dead code");
15941                                 release_triple(state, user->member);
15942                                 continue;
15943                         }
15944                         if (work[block->vertex] >= iter) {
15945                                 continue;
15946                         }
15947                         work[block->vertex] = iter;
15948                         *work_list_tail = block;
15949                         block->work_next = 0;
15950                         work_list_tail = &block->work_next;
15951                 }
15952                 for(block = work_list; block; block = block->work_next) {
15953                         struct block_set *df;
15954                         for(df = block->domfrontier; df; df = df->next) {
15955                                 struct triple *phi;
15956                                 struct block *front;
15957                                 int in_edges;
15958                                 front = df->member;
15959
15960                                 if (has_already[front->vertex] >= iter) {
15961                                         continue;
15962                                 }
15963                                 /* Count how many edges flow into this block */
15964                                 in_edges = front->users;
15965                                 /* Insert a phi function for this variable */
15966                                 get_occurance(var->occurance);
15967                                 phi = alloc_triple(
15968                                         state, OP_PHI, var->type, -1, in_edges, 
15969                                         var->occurance);
15970                                 phi->u.block = front;
15971                                 MISC(phi, 0) = var;
15972                                 use_triple(var, phi);
15973 #if 1
15974                                 if (phi->rhs != in_edges) {
15975                                         internal_error(state, phi, "phi->rhs: %d != in_edges: %d",
15976                                                 phi->rhs, in_edges);
15977                                 }
15978 #endif
15979                                 /* Insert the phi functions immediately after the label */
15980                                 insert_triple(state, front->first->next, phi);
15981                                 if (front->first == front->last) {
15982                                         front->last = front->first->next;
15983                                 }
15984                                 has_already[front->vertex] = iter;
15985                                 transform_to_arch_instruction(state, phi);
15986
15987                                 /* If necessary plan to visit the basic block */
15988                                 if (work[front->vertex] >= iter) {
15989                                         continue;
15990                                 }
15991                                 work[front->vertex] = iter;
15992                                 *work_list_tail = front;
15993                                 front->work_next = 0;
15994                                 work_list_tail = &front->work_next;
15995                         }
15996                 }
15997         }
15998         xfree(has_already);
15999         xfree(work);
16000 }
16001
16002
16003 struct stack {
16004         struct triple_set *top;
16005         unsigned orig_id;
16006 };
16007
16008 static int count_auto_vars(struct compile_state *state)
16009 {
16010         struct triple *first, *ins;
16011         int auto_vars = 0;
16012         first = state->first;
16013         ins = first;
16014         do {
16015                 if (triple_is_auto_var(state, ins)) {
16016                         auto_vars += 1;
16017                 }
16018                 ins = ins->next;
16019         } while(ins != first);
16020         return auto_vars;
16021 }
16022
16023 static void number_auto_vars(struct compile_state *state, struct stack *stacks)
16024 {
16025         struct triple *first, *ins;
16026         int auto_vars = 0;
16027         first = state->first;
16028         ins = first;
16029         do {
16030                 if (triple_is_auto_var(state, ins)) {
16031                         auto_vars += 1;
16032                         stacks[auto_vars].orig_id = ins->id;
16033                         ins->id = auto_vars;
16034                 }
16035                 ins = ins->next;
16036         } while(ins != first);
16037 }
16038
16039 static void restore_auto_vars(struct compile_state *state, struct stack *stacks)
16040 {
16041         struct triple *first, *ins;
16042         first = state->first;
16043         ins = first;
16044         do {
16045                 if (triple_is_auto_var(state, ins)) {
16046                         ins->id = stacks[ins->id].orig_id;
16047                 }
16048                 ins = ins->next;
16049         } while(ins != first);
16050 }
16051
16052 static struct triple *peek_triple(struct stack *stacks, struct triple *var)
16053 {
16054         struct triple_set *head;
16055         struct triple *top_val;
16056         top_val = 0;
16057         head = stacks[var->id].top;
16058         if (head) {
16059                 top_val = head->member;
16060         }
16061         return top_val;
16062 }
16063
16064 static void push_triple(struct stack *stacks, struct triple *var, struct triple *val)
16065 {
16066         struct triple_set *new;
16067         /* Append new to the head of the list,
16068          * it's the only sensible behavoir for a stack.
16069          */
16070         new = xcmalloc(sizeof(*new), "triple_set");
16071         new->member = val;
16072         new->next   = stacks[var->id].top;
16073         stacks[var->id].top = new;
16074 }
16075
16076 static void pop_triple(struct stack *stacks, struct triple *var, struct triple *oldval)
16077 {
16078         struct triple_set *set, **ptr;
16079         ptr = &stacks[var->id].top;
16080         while(*ptr) {
16081                 set = *ptr;
16082                 if (set->member == oldval) {
16083                         *ptr = set->next;
16084                         xfree(set);
16085                         /* Only free one occurance from the stack */
16086                         return;
16087                 }
16088                 else {
16089                         ptr = &set->next;
16090                 }
16091         }
16092 }
16093
16094 /*
16095  * C(V)
16096  * S(V)
16097  */
16098 static void fixup_block_phi_variables(
16099         struct compile_state *state, struct stack *stacks, struct block *parent, struct block *block)
16100 {
16101         struct block_set *set;
16102         struct triple *ptr;
16103         int edge;
16104         if (!parent || !block)
16105                 return;
16106         /* Find the edge I am coming in on */
16107         edge = 0;
16108         for(set = block->use; set; set = set->next, edge++) {
16109                 if (set->member == parent) {
16110                         break;
16111                 }
16112         }
16113         if (!set) {
16114                 internal_error(state, 0, "phi input is not on a control predecessor");
16115         }
16116         for(ptr = block->first; ; ptr = ptr->next) {
16117                 if (ptr->op == OP_PHI) {
16118                         struct triple *var, *val, **slot;
16119                         var = MISC(ptr, 0);
16120                         if (!var) {
16121                                 internal_error(state, ptr, "no var???");
16122                         }
16123                         /* Find the current value of the variable */
16124                         val = peek_triple(stacks, var);
16125                         if (val && ((val->op == OP_WRITE) || (val->op == OP_READ))) {
16126                                 internal_error(state, val, "bad value in phi");
16127                         }
16128                         if (edge >= ptr->rhs) {
16129                                 internal_error(state, ptr, "edges > phi rhs");
16130                         }
16131                         slot = &RHS(ptr, edge);
16132                         if ((*slot != 0) && (*slot != val)) {
16133                                 internal_error(state, ptr, "phi already bound on this edge");
16134                         }
16135                         *slot = val;
16136                         use_triple(val, ptr);
16137                 }
16138                 if (ptr == block->last) {
16139                         break;
16140                 }
16141         }
16142 }
16143
16144
16145 static void rename_block_variables(
16146         struct compile_state *state, struct stack *stacks, struct block *block)
16147 {
16148         struct block_set *user, *edge;
16149         struct triple *ptr, *next, *last;
16150         int done;
16151         if (!block)
16152                 return;
16153         last = block->first;
16154         done = 0;
16155         for(ptr = block->first; !done; ptr = next) {
16156                 next = ptr->next;
16157                 if (ptr == block->last) {
16158                         done = 1;
16159                 }
16160                 /* RHS(A) */
16161                 if (ptr->op == OP_READ) {
16162                         struct triple *var, *val;
16163                         var = RHS(ptr, 0);
16164                         if (!triple_is_auto_var(state, var)) {
16165                                 internal_error(state, ptr, "read of non auto var!");
16166                         }
16167                         unuse_triple(var, ptr);
16168                         /* Find the current value of the variable */
16169                         val = peek_triple(stacks, var);
16170                         if (!val) {
16171                                 /* Let the optimizer at variables that are not initially
16172                                  * set.  But give it a bogus value so things seem to
16173                                  * work by accident.  This is useful for bitfields because
16174                                  * setting them always involves a read-modify-write.
16175                                  */
16176                                 if (TYPE_ARITHMETIC(ptr->type->type)) {
16177                                         val = pre_triple(state, ptr, OP_INTCONST, ptr->type, 0, 0);
16178                                         val->u.cval = 0xdeadbeaf;
16179                                 } else {
16180                                         val = pre_triple(state, ptr, OP_UNKNOWNVAL, ptr->type, 0, 0);
16181                                 }
16182                         }
16183                         if (!val) {
16184                                 error(state, ptr, "variable used without being set");
16185                         }
16186                         if ((val->op == OP_WRITE) || (val->op == OP_READ)) {
16187                                 internal_error(state, val, "bad value in read");
16188                         }
16189                         propogate_use(state, ptr, val);
16190                         release_triple(state, ptr);
16191                         continue;
16192                 }
16193                 /* LHS(A) */
16194                 if (ptr->op == OP_WRITE) {
16195                         struct triple *var, *val, *tval;
16196                         var = MISC(ptr, 0);
16197                         if (!triple_is_auto_var(state, var)) {
16198                                 internal_error(state, ptr, "write to non auto var!");
16199                         }
16200                         tval = val = RHS(ptr, 0);
16201                         if ((val->op == OP_WRITE) || (val->op == OP_READ) ||
16202                                 triple_is_auto_var(state, val)) {
16203                                 internal_error(state, ptr, "bad value in write");
16204                         }
16205                         /* Insert a cast if the types differ */
16206                         if (!is_subset_type(ptr->type, val->type)) {
16207                                 if (val->op == OP_INTCONST) {
16208                                         tval = pre_triple(state, ptr, OP_INTCONST, ptr->type, 0, 0);
16209                                         tval->u.cval = val->u.cval;
16210                                 }
16211                                 else {
16212                                         tval = pre_triple(state, ptr, OP_CONVERT, ptr->type, val, 0);
16213                                         use_triple(val, tval);
16214                                 }
16215                                 transform_to_arch_instruction(state, tval);
16216                                 unuse_triple(val, ptr);
16217                                 RHS(ptr, 0) = tval;
16218                                 use_triple(tval, ptr);
16219                         }
16220                         propogate_use(state, ptr, tval);
16221                         unuse_triple(var, ptr);
16222                         /* Push OP_WRITE ptr->right onto a stack of variable uses */
16223                         push_triple(stacks, var, tval);
16224                 }
16225                 if (ptr->op == OP_PHI) {
16226                         struct triple *var;
16227                         var = MISC(ptr, 0);
16228                         if (!triple_is_auto_var(state, var)) {
16229                                 internal_error(state, ptr, "phi references non auto var!");
16230                         }
16231                         /* Push OP_PHI onto a stack of variable uses */
16232                         push_triple(stacks, var, ptr);
16233                 }
16234                 last = ptr;
16235         }
16236         block->last = last;
16237
16238         /* Fixup PHI functions in the cf successors */
16239         for(edge = block->edges; edge; edge = edge->next) {
16240                 fixup_block_phi_variables(state, stacks, block, edge->member);
16241         }
16242         /* rename variables in the dominated nodes */
16243         for(user = block->idominates; user; user = user->next) {
16244                 rename_block_variables(state, stacks, user->member);
16245         }
16246         /* pop the renamed variable stack */
16247         last = block->first;
16248         done = 0;
16249         for(ptr = block->first; !done ; ptr = next) {
16250                 next = ptr->next;
16251                 if (ptr == block->last) {
16252                         done = 1;
16253                 }
16254                 if (ptr->op == OP_WRITE) {
16255                         struct triple *var;
16256                         var = MISC(ptr, 0);
16257                         /* Pop OP_WRITE ptr->right from the stack of variable uses */
16258                         pop_triple(stacks, var, RHS(ptr, 0));
16259                         release_triple(state, ptr);
16260                         continue;
16261                 }
16262                 if (ptr->op == OP_PHI) {
16263                         struct triple *var;
16264                         var = MISC(ptr, 0);
16265                         /* Pop OP_WRITE ptr->right from the stack of variable uses */
16266                         pop_triple(stacks, var, ptr);
16267                 }
16268                 last = ptr;
16269         }
16270         block->last = last;
16271 }
16272
16273 static void rename_variables(struct compile_state *state)
16274 {
16275         struct stack *stacks;
16276         int auto_vars;
16277
16278         /* Allocate stacks for the Variables */
16279         auto_vars = count_auto_vars(state);
16280         stacks = xcmalloc(sizeof(stacks[0])*(auto_vars + 1), "auto var stacks");
16281
16282         /* Give each auto_var a stack */
16283         number_auto_vars(state, stacks);
16284
16285         /* Rename the variables */
16286         rename_block_variables(state, stacks, state->bb.first_block);
16287
16288         /* Remove the stacks from the auto_vars */
16289         restore_auto_vars(state, stacks);
16290         xfree(stacks);
16291 }
16292
16293 static void prune_block_variables(struct compile_state *state,
16294         struct block *block)
16295 {
16296         struct block_set *user;
16297         struct triple *next, *ptr;
16298         int done;
16299
16300         done = 0;
16301         for(ptr = block->first; !done; ptr = next) {
16302                 /* Be extremely careful I am deleting the list
16303                  * as I walk trhough it.
16304                  */
16305                 next = ptr->next;
16306                 if (ptr == block->last) {
16307                         done = 1;
16308                 }
16309                 if (triple_is_auto_var(state, ptr)) {
16310                         struct triple_set *user, *next;
16311                         for(user = ptr->use; user; user = next) {
16312                                 struct triple *use;
16313                                 next = user->next;
16314                                 use = user->member;
16315                                 if (MISC(ptr, 0) == user->member) {
16316                                         continue;
16317                                 }
16318                                 if (use->op != OP_PHI) {
16319                                         internal_error(state, use, "decl still used");
16320                                 }
16321                                 if (MISC(use, 0) != ptr) {
16322                                         internal_error(state, use, "bad phi use of decl");
16323                                 }
16324                                 unuse_triple(ptr, use);
16325                                 MISC(use, 0) = 0;
16326                         }
16327                         if ((ptr->u.cval == 0) && (MISC(ptr, 0)->lhs == 1)) {
16328                                 /* Delete the adecl */
16329                                 release_triple(state, MISC(ptr, 0));
16330                                 /* And the piece */
16331                                 release_triple(state, ptr);
16332                         }
16333                         continue;
16334                 }
16335         }
16336         for(user = block->idominates; user; user = user->next) {
16337                 prune_block_variables(state, user->member);
16338         }
16339 }
16340
16341 struct phi_triple {
16342         struct triple *phi;
16343         unsigned orig_id;
16344         int alive;
16345 };
16346
16347 static void keep_phi(struct compile_state *state, struct phi_triple *live, struct triple *phi)
16348 {
16349         struct triple **slot;
16350         int zrhs, i;
16351         if (live[phi->id].alive) {
16352                 return;
16353         }
16354         live[phi->id].alive = 1;
16355         zrhs = phi->rhs;
16356         slot = &RHS(phi, 0);
16357         for(i = 0; i < zrhs; i++) {
16358                 struct triple *used;
16359                 used = slot[i];
16360                 if (used && (used->op == OP_PHI)) {
16361                         keep_phi(state, live, used);
16362                 }
16363         }
16364 }
16365
16366 static void prune_unused_phis(struct compile_state *state)
16367 {
16368         struct triple *first, *phi;
16369         struct phi_triple *live;
16370         int phis, i;
16371         
16372         /* Find the first instruction */
16373         first = state->first;
16374
16375         /* Count how many phi functions I need to process */
16376         phis = 0;
16377         for(phi = first->next; phi != first; phi = phi->next) {
16378                 if (phi->op == OP_PHI) {
16379                         phis += 1;
16380                 }
16381         }
16382         
16383         /* Mark them all dead */
16384         live = xcmalloc(sizeof(*live) * (phis + 1), "phi_triple");
16385         phis = 0;
16386         for(phi = first->next; phi != first; phi = phi->next) {
16387                 if (phi->op != OP_PHI) {
16388                         continue;
16389                 }
16390                 live[phis].alive   = 0;
16391                 live[phis].orig_id = phi->id;
16392                 live[phis].phi     = phi;
16393                 phi->id = phis;
16394                 phis += 1;
16395         }
16396         
16397         /* Mark phis alive that are used by non phis */
16398         for(i = 0; i < phis; i++) {
16399                 struct triple_set *set;
16400                 for(set = live[i].phi->use; !live[i].alive && set; set = set->next) {
16401                         if (set->member->op != OP_PHI) {
16402                                 keep_phi(state, live, live[i].phi);
16403                                 break;
16404                         }
16405                 }
16406         }
16407
16408         /* Delete the extraneous phis */
16409         for(i = 0; i < phis; i++) {
16410                 struct triple **slot;
16411                 int zrhs, j;
16412                 if (!live[i].alive) {
16413                         release_triple(state, live[i].phi);
16414                         continue;
16415                 }
16416                 phi = live[i].phi;
16417                 slot = &RHS(phi, 0);
16418                 zrhs = phi->rhs;
16419                 for(j = 0; j < zrhs; j++) {
16420                         if(!slot[j]) {
16421                                 struct triple *unknown;
16422                                 get_occurance(phi->occurance);
16423                                 unknown = flatten(state, state->global_pool,
16424                                         alloc_triple(state, OP_UNKNOWNVAL,
16425                                                 phi->type, 0, 0, phi->occurance));
16426                                 slot[j] = unknown;
16427                                 use_triple(unknown, phi);
16428                                 transform_to_arch_instruction(state, unknown);
16429 #if 0                           
16430                                 warning(state, phi, "variable not set at index %d on all paths to use", j);
16431 #endif
16432                         }
16433                 }
16434         }
16435         xfree(live);
16436 }
16437
16438 static void transform_to_ssa_form(struct compile_state *state)
16439 {
16440         insert_phi_operations(state);
16441         rename_variables(state);
16442
16443         prune_block_variables(state, state->bb.first_block);
16444         prune_unused_phis(state);
16445
16446         print_blocks(state, __func__, state->dbgout);
16447 }
16448
16449
16450 static void clear_vertex(
16451         struct compile_state *state, struct block *block, void *arg)
16452 {
16453         /* Clear the current blocks vertex and the vertex of all
16454          * of the current blocks neighbors in case there are malformed
16455          * blocks with now instructions at this point.
16456          */
16457         struct block_set *user, *edge;
16458         block->vertex = 0;
16459         for(edge = block->edges; edge; edge = edge->next) {
16460                 edge->member->vertex = 0;
16461         }
16462         for(user = block->use; user; user = user->next) {
16463                 user->member->vertex = 0;
16464         }
16465 }
16466
16467 static void mark_live_block(
16468         struct compile_state *state, struct block *block, int *next_vertex)
16469 {
16470         /* See if this is a block that has not been marked */
16471         if (block->vertex != 0) {
16472                 return;
16473         }
16474         block->vertex = *next_vertex;
16475         *next_vertex += 1;
16476         if (triple_is_branch(state, block->last)) {
16477                 struct triple **targ;
16478                 targ = triple_edge_targ(state, block->last, 0);
16479                 for(; targ; targ = triple_edge_targ(state, block->last, targ)) {
16480                         if (!*targ) {
16481                                 continue;
16482                         }
16483                         if (!triple_stores_block(state, *targ)) {
16484                                 internal_error(state, 0, "bad targ");
16485                         }
16486                         mark_live_block(state, (*targ)->u.block, next_vertex);
16487                 }
16488                 /* Ensure the last block of a function remains alive */
16489                 if (triple_is_call(state, block->last)) {
16490                         mark_live_block(state, MISC(block->last, 0)->u.block, next_vertex);
16491                 }
16492         }
16493         else if (block->last->next != state->first) {
16494                 struct triple *ins;
16495                 ins = block->last->next;
16496                 if (!triple_stores_block(state, ins)) {
16497                         internal_error(state, 0, "bad block start");
16498                 }
16499                 mark_live_block(state, ins->u.block, next_vertex);
16500         }
16501 }
16502
16503 static void transform_from_ssa_form(struct compile_state *state)
16504 {
16505         /* To get out of ssa form we insert moves on the incoming
16506          * edges to blocks containting phi functions.
16507          */
16508         struct triple *first;
16509         struct triple *phi, *var, *next;
16510         int next_vertex;
16511
16512         /* Walk the control flow to see which blocks remain alive */
16513         walk_blocks(state, &state->bb, clear_vertex, 0);
16514         next_vertex = 1;
16515         mark_live_block(state, state->bb.first_block, &next_vertex);
16516
16517         /* Walk all of the operations to find the phi functions */
16518         first = state->first;
16519         for(phi = first->next; phi != first ; phi = next) {
16520                 struct block_set *set;
16521                 struct block *block;
16522                 struct triple **slot;
16523                 struct triple *var;
16524                 struct triple_set *use, *use_next;
16525                 int edge, writers, readers;
16526                 next = phi->next;
16527                 if (phi->op != OP_PHI) {
16528                         continue;
16529                 }
16530
16531                 block = phi->u.block;
16532                 slot  = &RHS(phi, 0);
16533
16534                 /* If this phi is in a dead block just forget it */
16535                 if (block->vertex == 0) {
16536                         release_triple(state, phi);
16537                         continue;
16538                 }
16539
16540                 /* Forget uses from code in dead blocks */
16541                 for(use = phi->use; use; use = use_next) {
16542                         struct block *ublock;
16543                         struct triple **expr;
16544                         use_next = use->next;
16545                         ublock = block_of_triple(state, use->member);
16546                         if ((use->member == phi) || (ublock->vertex != 0)) {
16547                                 continue;
16548                         }
16549                         expr = triple_rhs(state, use->member, 0);
16550                         for(; expr; expr = triple_rhs(state, use->member, expr)) {
16551                                 if (*expr == phi) {
16552                                         *expr = 0;
16553                                 }
16554                         }
16555                         unuse_triple(phi, use->member);
16556                 }
16557                 /* A variable to replace the phi function */
16558                 if (registers_of(state, phi->type) != 1) {
16559                         internal_error(state, phi, "phi->type does not fit in a single register!");
16560                 }
16561                 var = post_triple(state, phi, OP_ADECL, phi->type, 0, 0);
16562                 var = var->next; /* point at the var */
16563                         
16564                 /* Replaces use of phi with var */
16565                 propogate_use(state, phi, var);
16566
16567                 /* Count the readers */
16568                 readers = 0;
16569                 for(use = var->use; use; use = use->next) {
16570                         if (use->member != MISC(var, 0)) {
16571                                 readers++;
16572                         }
16573                 }
16574
16575                 /* Walk all of the incoming edges/blocks and insert moves.
16576                  */
16577                 writers = 0;
16578                 for(edge = 0, set = block->use; set; set = set->next, edge++) {
16579                         struct block *eblock, *vblock;
16580                         struct triple *move;
16581                         struct triple *val, *base;
16582                         eblock = set->member;
16583                         val = slot[edge];
16584                         slot[edge] = 0;
16585                         unuse_triple(val, phi);
16586                         vblock = block_of_triple(state, val);
16587
16588                         /* If we don't have a value that belongs in an OP_WRITE
16589                          * continue on.
16590                          */
16591                         if (!val || (val == &unknown_triple) || (val == phi)
16592                                 || (vblock && (vblock->vertex == 0))) {
16593                                 continue;
16594                         }
16595                         /* If the value should never occur error */
16596                         if (!vblock) {
16597                                 internal_error(state, val, "no vblock?");
16598                                 continue;
16599                         }
16600
16601                         /* If the value occurs in a dead block see if a replacement
16602                          * block can be found.
16603                          */
16604                         while(eblock && (eblock->vertex == 0)) {
16605                                 eblock = eblock->idom;
16606                         }
16607                         /* If not continue on with the next value. */
16608                         if (!eblock || (eblock->vertex == 0)) {
16609                                 continue;
16610                         }
16611
16612                         /* If we have an empty incoming block ignore it. */
16613                         if (!eblock->first) {
16614                                 internal_error(state, 0, "empty block?");
16615                         }
16616                         
16617                         /* Make certain the write is placed in the edge block... */
16618                         /* Walk through the edge block backwards to find an
16619                          * appropriate location for the OP_WRITE.
16620                          */
16621                         for(base = eblock->last; base != eblock->first; base = base->prev) {
16622                                 struct triple **expr;
16623                                 if (base->op == OP_PIECE) {
16624                                         base = MISC(base, 0);
16625                                 }
16626                                 if ((base == var) || (base == val)) {
16627                                         goto out;
16628                                 }
16629                                 expr = triple_lhs(state, base, 0);
16630                                 for(; expr; expr = triple_lhs(state, base, expr)) {
16631                                         if ((*expr) == val) {
16632                                                 goto out;
16633                                         }
16634                                 }
16635                                 expr = triple_rhs(state, base, 0);
16636                                 for(; expr; expr = triple_rhs(state, base, expr)) {
16637                                         if ((*expr) == var) {
16638                                                 goto out;
16639                                         }
16640                                 }
16641                         }
16642                 out:
16643                         if (triple_is_branch(state, base)) {
16644                                 internal_error(state, base,
16645                                         "Could not insert write to phi");
16646                         }
16647                         move = post_triple(state, base, OP_WRITE, var->type, val, var);
16648                         use_triple(val, move);
16649                         use_triple(var, move);
16650                         writers++;
16651                 }
16652                 if (!writers && readers) {
16653                         internal_error(state, var, "no value written to in use phi?");
16654                 }
16655                 /* If var is not used free it */
16656                 if (!writers) {
16657                         release_triple(state, MISC(var, 0));
16658                         release_triple(state, var);
16659                 }
16660                 /* Release the phi function */
16661                 release_triple(state, phi);
16662         }
16663         
16664         /* Walk all of the operations to find the adecls */
16665         for(var = first->next; var != first ; var = var->next) {
16666                 struct triple_set *use, *use_next;
16667                 if (!triple_is_auto_var(state, var)) {
16668                         continue;
16669                 }
16670
16671                 /* Walk through all of the rhs uses of var and
16672                  * replace them with read of var.
16673                  */
16674                 for(use = var->use; use; use = use_next) {
16675                         struct triple *read, *user;
16676                         struct triple **slot;
16677                         int zrhs, i, used;
16678                         use_next = use->next;
16679                         user = use->member;
16680                         
16681                         /* Generate a read of var */
16682                         read = pre_triple(state, user, OP_READ, var->type, var, 0);
16683                         use_triple(var, read);
16684
16685                         /* Find the rhs uses and see if they need to be replaced */
16686                         used = 0;
16687                         zrhs = user->rhs;
16688                         slot = &RHS(user, 0);
16689                         for(i = 0; i < zrhs; i++) {
16690                                 if (slot[i] == var) {
16691                                         slot[i] = read;
16692                                         used = 1;
16693                                 }
16694                         }
16695                         /* If we did use it cleanup the uses */
16696                         if (used) {
16697                                 unuse_triple(var, user);
16698                                 use_triple(read, user);
16699                         } 
16700                         /* If we didn't use it release the extra triple */
16701                         else {
16702                                 release_triple(state, read);
16703                         }
16704                 }
16705         }
16706 }
16707
16708 #define HI() if (state->compiler->debug & DEBUG_REBUILD_SSA_FORM) { \
16709         FILE *fp = state->dbgout; \
16710         fprintf(fp, "@ %s:%d\n", __FILE__, __LINE__); romcc_print_blocks(state, fp); \
16711         } 
16712
16713 static void rebuild_ssa_form(struct compile_state *state)
16714 {
16715 HI();
16716         transform_from_ssa_form(state);
16717 HI();
16718         state->bb.first = state->first;
16719         free_basic_blocks(state, &state->bb);
16720         analyze_basic_blocks(state, &state->bb);
16721 HI();
16722         insert_phi_operations(state);
16723 HI();
16724         rename_variables(state);
16725 HI();
16726         
16727         prune_block_variables(state, state->bb.first_block);
16728 HI();
16729         prune_unused_phis(state);
16730 HI();
16731 }
16732 #undef HI
16733
16734 /* 
16735  * Register conflict resolution
16736  * =========================================================
16737  */
16738
16739 static struct reg_info find_def_color(
16740         struct compile_state *state, struct triple *def)
16741 {
16742         struct triple_set *set;
16743         struct reg_info info;
16744         info.reg = REG_UNSET;
16745         info.regcm = 0;
16746         if (!triple_is_def(state, def)) {
16747                 return info;
16748         }
16749         info = arch_reg_lhs(state, def, 0);
16750         if (info.reg >= MAX_REGISTERS) {
16751                 info.reg = REG_UNSET;
16752         }
16753         for(set = def->use; set; set = set->next) {
16754                 struct reg_info tinfo;
16755                 int i;
16756                 i = find_rhs_use(state, set->member, def);
16757                 if (i < 0) {
16758                         continue;
16759                 }
16760                 tinfo = arch_reg_rhs(state, set->member, i);
16761                 if (tinfo.reg >= MAX_REGISTERS) {
16762                         tinfo.reg = REG_UNSET;
16763                 }
16764                 if ((tinfo.reg != REG_UNSET) && 
16765                         (info.reg != REG_UNSET) &&
16766                         (tinfo.reg != info.reg)) {
16767                         internal_error(state, def, "register conflict");
16768                 }
16769                 if ((info.regcm & tinfo.regcm) == 0) {
16770                         internal_error(state, def, "regcm conflict %x & %x == 0",
16771                                 info.regcm, tinfo.regcm);
16772                 }
16773                 if (info.reg == REG_UNSET) {
16774                         info.reg = tinfo.reg;
16775                 }
16776                 info.regcm &= tinfo.regcm;
16777         }
16778         if (info.reg >= MAX_REGISTERS) {
16779                 internal_error(state, def, "register out of range");
16780         }
16781         return info;
16782 }
16783
16784 static struct reg_info find_lhs_pre_color(
16785         struct compile_state *state, struct triple *ins, int index)
16786 {
16787         struct reg_info info;
16788         int zlhs, zrhs, i;
16789         zrhs = ins->rhs;
16790         zlhs = ins->lhs;
16791         if (!zlhs && triple_is_def(state, ins)) {
16792                 zlhs = 1;
16793         }
16794         if (index >= zlhs) {
16795                 internal_error(state, ins, "Bad lhs %d", index);
16796         }
16797         info = arch_reg_lhs(state, ins, index);
16798         for(i = 0; i < zrhs; i++) {
16799                 struct reg_info rinfo;
16800                 rinfo = arch_reg_rhs(state, ins, i);
16801                 if ((info.reg == rinfo.reg) &&
16802                         (rinfo.reg >= MAX_REGISTERS)) {
16803                         struct reg_info tinfo;
16804                         tinfo = find_lhs_pre_color(state, RHS(ins, index), 0);
16805                         info.reg = tinfo.reg;
16806                         info.regcm &= tinfo.regcm;
16807                         break;
16808                 }
16809         }
16810         if (info.reg >= MAX_REGISTERS) {
16811                 info.reg = REG_UNSET;
16812         }
16813         return info;
16814 }
16815
16816 static struct reg_info find_rhs_post_color(
16817         struct compile_state *state, struct triple *ins, int index);
16818
16819 static struct reg_info find_lhs_post_color(
16820         struct compile_state *state, struct triple *ins, int index)
16821 {
16822         struct triple_set *set;
16823         struct reg_info info;
16824         struct triple *lhs;
16825 #if DEBUG_TRIPLE_COLOR
16826         fprintf(state->errout, "find_lhs_post_color(%p, %d)\n",
16827                 ins, index);
16828 #endif
16829         if ((index == 0) && triple_is_def(state, ins)) {
16830                 lhs = ins;
16831         }
16832         else if (index < ins->lhs) {
16833                 lhs = LHS(ins, index);
16834         }
16835         else {
16836                 internal_error(state, ins, "Bad lhs %d", index);
16837                 lhs = 0;
16838         }
16839         info = arch_reg_lhs(state, ins, index);
16840         if (info.reg >= MAX_REGISTERS) {
16841                 info.reg = REG_UNSET;
16842         }
16843         for(set = lhs->use; set; set = set->next) {
16844                 struct reg_info rinfo;
16845                 struct triple *user;
16846                 int zrhs, i;
16847                 user = set->member;
16848                 zrhs = user->rhs;
16849                 for(i = 0; i < zrhs; i++) {
16850                         if (RHS(user, i) != lhs) {
16851                                 continue;
16852                         }
16853                         rinfo = find_rhs_post_color(state, user, i);
16854                         if ((info.reg != REG_UNSET) &&
16855                                 (rinfo.reg != REG_UNSET) &&
16856                                 (info.reg != rinfo.reg)) {
16857                                 internal_error(state, ins, "register conflict");
16858                         }
16859                         if ((info.regcm & rinfo.regcm) == 0) {
16860                                 internal_error(state, ins, "regcm conflict %x & %x == 0",
16861                                         info.regcm, rinfo.regcm);
16862                         }
16863                         if (info.reg == REG_UNSET) {
16864                                 info.reg = rinfo.reg;
16865                         }
16866                         info.regcm &= rinfo.regcm;
16867                 }
16868         }
16869 #if DEBUG_TRIPLE_COLOR
16870         fprintf(state->errout, "find_lhs_post_color(%p, %d) -> ( %d, %x)\n",
16871                 ins, index, info.reg, info.regcm);
16872 #endif
16873         return info;
16874 }
16875
16876 static struct reg_info find_rhs_post_color(
16877         struct compile_state *state, struct triple *ins, int index)
16878 {
16879         struct reg_info info, rinfo;
16880         int zlhs, i;
16881 #if DEBUG_TRIPLE_COLOR
16882         fprintf(state->errout, "find_rhs_post_color(%p, %d)\n",
16883                 ins, index);
16884 #endif
16885         rinfo = arch_reg_rhs(state, ins, index);
16886         zlhs = ins->lhs;
16887         if (!zlhs && triple_is_def(state, ins)) {
16888                 zlhs = 1;
16889         }
16890         info = rinfo;
16891         if (info.reg >= MAX_REGISTERS) {
16892                 info.reg = REG_UNSET;
16893         }
16894         for(i = 0; i < zlhs; i++) {
16895                 struct reg_info linfo;
16896                 linfo = arch_reg_lhs(state, ins, i);
16897                 if ((linfo.reg == rinfo.reg) &&
16898                         (linfo.reg >= MAX_REGISTERS)) {
16899                         struct reg_info tinfo;
16900                         tinfo = find_lhs_post_color(state, ins, i);
16901                         if (tinfo.reg >= MAX_REGISTERS) {
16902                                 tinfo.reg = REG_UNSET;
16903                         }
16904                         info.regcm &= linfo.regcm;
16905                         info.regcm &= tinfo.regcm;
16906                         if (info.reg != REG_UNSET) {
16907                                 internal_error(state, ins, "register conflict");
16908                         }
16909                         if (info.regcm == 0) {
16910                                 internal_error(state, ins, "regcm conflict");
16911                         }
16912                         info.reg = tinfo.reg;
16913                 }
16914         }
16915 #if DEBUG_TRIPLE_COLOR
16916         fprintf(state->errout, "find_rhs_post_color(%p, %d) -> ( %d, %x)\n",
16917                 ins, index, info.reg, info.regcm);
16918 #endif
16919         return info;
16920 }
16921
16922 static struct reg_info find_lhs_color(
16923         struct compile_state *state, struct triple *ins, int index)
16924 {
16925         struct reg_info pre, post, info;
16926 #if DEBUG_TRIPLE_COLOR
16927         fprintf(state->errout, "find_lhs_color(%p, %d)\n",
16928                 ins, index);
16929 #endif
16930         pre = find_lhs_pre_color(state, ins, index);
16931         post = find_lhs_post_color(state, ins, index);
16932         if ((pre.reg != post.reg) &&
16933                 (pre.reg != REG_UNSET) &&
16934                 (post.reg != REG_UNSET)) {
16935                 internal_error(state, ins, "register conflict");
16936         }
16937         info.regcm = pre.regcm & post.regcm;
16938         info.reg = pre.reg;
16939         if (info.reg == REG_UNSET) {
16940                 info.reg = post.reg;
16941         }
16942 #if DEBUG_TRIPLE_COLOR
16943         fprintf(state->errout, "find_lhs_color(%p, %d) -> ( %d, %x) ... (%d, %x) (%d, %x)\n",
16944                 ins, index, info.reg, info.regcm,
16945                 pre.reg, pre.regcm, post.reg, post.regcm);
16946 #endif
16947         return info;
16948 }
16949
16950 static struct triple *post_copy(struct compile_state *state, struct triple *ins)
16951 {
16952         struct triple_set *entry, *next;
16953         struct triple *out;
16954         struct reg_info info, rinfo;
16955
16956         info = arch_reg_lhs(state, ins, 0);
16957         out = post_triple(state, ins, OP_COPY, ins->type, ins, 0);
16958         use_triple(RHS(out, 0), out);
16959         /* Get the users of ins to use out instead */
16960         for(entry = ins->use; entry; entry = next) {
16961                 int i;
16962                 next = entry->next;
16963                 if (entry->member == out) {
16964                         continue;
16965                 }
16966                 i = find_rhs_use(state, entry->member, ins);
16967                 if (i < 0) {
16968                         continue;
16969                 }
16970                 rinfo = arch_reg_rhs(state, entry->member, i);
16971                 if ((info.reg == REG_UNNEEDED) && (rinfo.reg == REG_UNNEEDED)) {
16972                         continue;
16973                 }
16974                 replace_rhs_use(state, ins, out, entry->member);
16975         }
16976         transform_to_arch_instruction(state, out);
16977         return out;
16978 }
16979
16980 static struct triple *typed_pre_copy(
16981         struct compile_state *state, struct type *type, struct triple *ins, int index)
16982 {
16983         /* Carefully insert enough operations so that I can
16984          * enter any operation with a GPR32.
16985          */
16986         struct triple *in;
16987         struct triple **expr;
16988         unsigned classes;
16989         struct reg_info info;
16990         int op;
16991         if (ins->op == OP_PHI) {
16992                 internal_error(state, ins, "pre_copy on a phi?");
16993         }
16994         classes = arch_type_to_regcm(state, type);
16995         info = arch_reg_rhs(state, ins, index);
16996         expr = &RHS(ins, index);
16997         if ((info.regcm & classes) == 0) {
16998                 FILE *fp = state->errout;
16999                 fprintf(fp, "src_type: ");
17000                 name_of(fp, ins->type);
17001                 fprintf(fp, "\ndst_type: ");
17002                 name_of(fp, type);
17003                 fprintf(fp, "\n");
17004                 internal_error(state, ins, "pre_copy with no register classes");
17005         }
17006         op = OP_COPY;
17007         if (!equiv_types(type, (*expr)->type)) {
17008                 op = OP_CONVERT;
17009         }
17010         in = pre_triple(state, ins, op, type, *expr, 0);
17011         unuse_triple(*expr, ins);
17012         *expr = in;
17013         use_triple(RHS(in, 0), in);
17014         use_triple(in, ins);
17015         transform_to_arch_instruction(state, in);
17016         return in;
17017         
17018 }
17019 static struct triple *pre_copy(
17020         struct compile_state *state, struct triple *ins, int index)
17021 {
17022         return typed_pre_copy(state, RHS(ins, index)->type, ins, index);
17023 }
17024
17025
17026 static void insert_copies_to_phi(struct compile_state *state)
17027 {
17028         /* To get out of ssa form we insert moves on the incoming
17029          * edges to blocks containting phi functions.
17030          */
17031         struct triple *first;
17032         struct triple *phi;
17033
17034         /* Walk all of the operations to find the phi functions */
17035         first = state->first;
17036         for(phi = first->next; phi != first ; phi = phi->next) {
17037                 struct block_set *set;
17038                 struct block *block;
17039                 struct triple **slot, *copy;
17040                 int edge;
17041                 if (phi->op != OP_PHI) {
17042                         continue;
17043                 }
17044                 phi->id |= TRIPLE_FLAG_POST_SPLIT;
17045                 block = phi->u.block;
17046                 slot  = &RHS(phi, 0);
17047                 /* Phi's that feed into mandatory live range joins
17048                  * cause nasty complications.  Insert a copy of
17049                  * the phi value so I never have to deal with
17050                  * that in the rest of the code.
17051                  */
17052                 copy = post_copy(state, phi);
17053                 copy->id |= TRIPLE_FLAG_PRE_SPLIT;
17054                 /* Walk all of the incoming edges/blocks and insert moves.
17055                  */
17056                 for(edge = 0, set = block->use; set; set = set->next, edge++) {
17057                         struct block *eblock;
17058                         struct triple *move;
17059                         struct triple *val;
17060                         struct triple *ptr;
17061                         eblock = set->member;
17062                         val = slot[edge];
17063
17064                         if (val == phi) {
17065                                 continue;
17066                         }
17067
17068                         get_occurance(val->occurance);
17069                         move = build_triple(state, OP_COPY, val->type, val, 0,
17070                                 val->occurance);
17071                         move->u.block = eblock;
17072                         move->id |= TRIPLE_FLAG_PRE_SPLIT;
17073                         use_triple(val, move);
17074                         
17075                         slot[edge] = move;
17076                         unuse_triple(val, phi);
17077                         use_triple(move, phi);
17078
17079                         /* Walk up the dominator tree until I have found the appropriate block */
17080                         while(eblock && !tdominates(state, val, eblock->last)) {
17081                                 eblock = eblock->idom;
17082                         }
17083                         if (!eblock) {
17084                                 internal_error(state, phi, "Cannot find block dominated by %p",
17085                                         val);
17086                         }
17087
17088                         /* Walk through the block backwards to find
17089                          * an appropriate location for the OP_COPY.
17090                          */
17091                         for(ptr = eblock->last; ptr != eblock->first; ptr = ptr->prev) {
17092                                 struct triple **expr;
17093                                 if (ptr->op == OP_PIECE) {
17094                                         ptr = MISC(ptr, 0);
17095                                 }
17096                                 if ((ptr == phi) || (ptr == val)) {
17097                                         goto out;
17098                                 }
17099                                 expr = triple_lhs(state, ptr, 0);
17100                                 for(;expr; expr = triple_lhs(state, ptr, expr)) {
17101                                         if ((*expr) == val) {
17102                                                 goto out;
17103                                         }
17104                                 }
17105                                 expr = triple_rhs(state, ptr, 0);
17106                                 for(;expr; expr = triple_rhs(state, ptr, expr)) {
17107                                         if ((*expr) == phi) {
17108                                                 goto out;
17109                                         }
17110                                 }
17111                         }
17112                 out:
17113                         if (triple_is_branch(state, ptr)) {
17114                                 internal_error(state, ptr,
17115                                         "Could not insert write to phi");
17116                         }
17117                         insert_triple(state, after_lhs(state, ptr), move);
17118                         if (eblock->last == after_lhs(state, ptr)->prev) {
17119                                 eblock->last = move;
17120                         }
17121                         transform_to_arch_instruction(state, move);
17122                 }
17123         }
17124         print_blocks(state, __func__, state->dbgout);
17125 }
17126
17127 struct triple_reg_set;
17128 struct reg_block;
17129
17130
17131 static int do_triple_set(struct triple_reg_set **head, 
17132         struct triple *member, struct triple *new_member)
17133 {
17134         struct triple_reg_set **ptr, *new;
17135         if (!member)
17136                 return 0;
17137         ptr = head;
17138         while(*ptr) {
17139                 if ((*ptr)->member == member) {
17140                         return 0;
17141                 }
17142                 ptr = &(*ptr)->next;
17143         }
17144         new = xcmalloc(sizeof(*new), "triple_set");
17145         new->member = member;
17146         new->new    = new_member;
17147         new->next   = *head;
17148         *head       = new;
17149         return 1;
17150 }
17151
17152 static void do_triple_unset(struct triple_reg_set **head, struct triple *member)
17153 {
17154         struct triple_reg_set *entry, **ptr;
17155         ptr = head;
17156         while(*ptr) {
17157                 entry = *ptr;
17158                 if (entry->member == member) {
17159                         *ptr = entry->next;
17160                         xfree(entry);
17161                         return;
17162                 }
17163                 else {
17164                         ptr = &entry->next;
17165                 }
17166         }
17167 }
17168
17169 static int in_triple(struct reg_block *rb, struct triple *in)
17170 {
17171         return do_triple_set(&rb->in, in, 0);
17172 }
17173 static void unin_triple(struct reg_block *rb, struct triple *unin)
17174 {
17175         do_triple_unset(&rb->in, unin);
17176 }
17177
17178 static int out_triple(struct reg_block *rb, struct triple *out)
17179 {
17180         return do_triple_set(&rb->out, out, 0);
17181 }
17182 static void unout_triple(struct reg_block *rb, struct triple *unout)
17183 {
17184         do_triple_unset(&rb->out, unout);
17185 }
17186
17187 static int initialize_regblock(struct reg_block *blocks,
17188         struct block *block, int vertex)
17189 {
17190         struct block_set *user;
17191         if (!block || (blocks[block->vertex].block == block)) {
17192                 return vertex;
17193         }
17194         vertex += 1;
17195         /* Renumber the blocks in a convinient fashion */
17196         block->vertex = vertex;
17197         blocks[vertex].block    = block;
17198         blocks[vertex].vertex   = vertex;
17199         for(user = block->use; user; user = user->next) {
17200                 vertex = initialize_regblock(blocks, user->member, vertex);
17201         }
17202         return vertex;
17203 }
17204
17205 static struct triple *part_to_piece(struct compile_state *state, struct triple *ins)
17206 {
17207 /* Part to piece is a best attempt and it cannot be correct all by
17208  * itself.  If various values are read as different sizes in different
17209  * parts of the code this function cannot work.  Or rather it cannot
17210  * work in conjunction with compute_variable_liftimes.  As the
17211  * analysis will get confused.
17212  */
17213         struct triple *base;
17214         unsigned reg;
17215         if (!is_lvalue(state, ins)) {
17216                 return ins;
17217         }
17218         base = 0;
17219         reg = 0;
17220         while(ins && triple_is_part(state, ins) && (ins->op != OP_PIECE)) {
17221                 base = MISC(ins, 0);
17222                 switch(ins->op) {
17223                 case OP_INDEX:
17224                         reg += index_reg_offset(state, base->type, ins->u.cval)/REG_SIZEOF_REG;
17225                         break;
17226                 case OP_DOT:
17227                         reg += field_reg_offset(state, base->type, ins->u.field)/REG_SIZEOF_REG;
17228                         break;
17229                 default:
17230                         internal_error(state, ins, "unhandled part");
17231                         break;
17232                 }
17233                 ins = base;
17234         }
17235         if (base) {
17236                 if (reg > base->lhs) {
17237                         internal_error(state, base, "part out of range?");
17238                 }
17239                 ins = LHS(base, reg);
17240         }
17241         return ins;
17242 }
17243
17244 static int this_def(struct compile_state *state, 
17245         struct triple *ins, struct triple *other)
17246 {
17247         if (ins == other) {
17248                 return 1;
17249         }
17250         if (ins->op == OP_WRITE) {
17251                 ins = part_to_piece(state, MISC(ins, 0));
17252         }
17253         return ins == other;
17254 }
17255
17256 static int phi_in(struct compile_state *state, struct reg_block *blocks,
17257         struct reg_block *rb, struct block *suc)
17258 {
17259         /* Read the conditional input set of a successor block
17260          * (i.e. the input to the phi nodes) and place it in the
17261          * current blocks output set.
17262          */
17263         struct block_set *set;
17264         struct triple *ptr;
17265         int edge;
17266         int done, change;
17267         change = 0;
17268         /* Find the edge I am coming in on */
17269         for(edge = 0, set = suc->use; set; set = set->next, edge++) {
17270                 if (set->member == rb->block) {
17271                         break;
17272                 }
17273         }
17274         if (!set) {
17275                 internal_error(state, 0, "Not coming on a control edge?");
17276         }
17277         for(done = 0, ptr = suc->first; !done; ptr = ptr->next) {
17278                 struct triple **slot, *expr, *ptr2;
17279                 int out_change, done2;
17280                 done = (ptr == suc->last);
17281                 if (ptr->op != OP_PHI) {
17282                         continue;
17283                 }
17284                 slot = &RHS(ptr, 0);
17285                 expr = slot[edge];
17286                 out_change = out_triple(rb, expr);
17287                 if (!out_change) {
17288                         continue;
17289                 }
17290                 /* If we don't define the variable also plast it
17291                  * in the current blocks input set.
17292                  */
17293                 ptr2 = rb->block->first;
17294                 for(done2 = 0; !done2; ptr2 = ptr2->next) {
17295                         if (this_def(state, ptr2, expr)) {
17296                                 break;
17297                         }
17298                         done2 = (ptr2 == rb->block->last);
17299                 }
17300                 if (!done2) {
17301                         continue;
17302                 }
17303                 change |= in_triple(rb, expr);
17304         }
17305         return change;
17306 }
17307
17308 static int reg_in(struct compile_state *state, struct reg_block *blocks,
17309         struct reg_block *rb, struct block *suc)
17310 {
17311         struct triple_reg_set *in_set;
17312         int change;
17313         change = 0;
17314         /* Read the input set of a successor block
17315          * and place it in the current blocks output set.
17316          */
17317         in_set = blocks[suc->vertex].in;
17318         for(; in_set; in_set = in_set->next) {
17319                 int out_change, done;
17320                 struct triple *first, *last, *ptr;
17321                 out_change = out_triple(rb, in_set->member);
17322                 if (!out_change) {
17323                         continue;
17324                 }
17325                 /* If we don't define the variable also place it
17326                  * in the current blocks input set.
17327                  */
17328                 first = rb->block->first;
17329                 last = rb->block->last;
17330                 done = 0;
17331                 for(ptr = first; !done; ptr = ptr->next) {
17332                         if (this_def(state, ptr, in_set->member)) {
17333                                 break;
17334                         }
17335                         done = (ptr == last);
17336                 }
17337                 if (!done) {
17338                         continue;
17339                 }
17340                 change |= in_triple(rb, in_set->member);
17341         }
17342         change |= phi_in(state, blocks, rb, suc);
17343         return change;
17344 }
17345
17346 static int use_in(struct compile_state *state, struct reg_block *rb)
17347 {
17348         /* Find the variables we use but don't define and add
17349          * it to the current blocks input set.
17350          */
17351 #warning "FIXME is this O(N^2) algorithm bad?"
17352         struct block *block;
17353         struct triple *ptr;
17354         int done;
17355         int change;
17356         block = rb->block;
17357         change = 0;
17358         for(done = 0, ptr = block->last; !done; ptr = ptr->prev) {
17359                 struct triple **expr;
17360                 done = (ptr == block->first);
17361                 /* The variable a phi function uses depends on the
17362                  * control flow, and is handled in phi_in, not
17363                  * here.
17364                  */
17365                 if (ptr->op == OP_PHI) {
17366                         continue;
17367                 }
17368                 expr = triple_rhs(state, ptr, 0);
17369                 for(;expr; expr = triple_rhs(state, ptr, expr)) {
17370                         struct triple *rhs, *test;
17371                         int tdone;
17372                         rhs = part_to_piece(state, *expr);
17373                         if (!rhs) {
17374                                 continue;
17375                         }
17376
17377                         /* See if rhs is defined in this block.
17378                          * A write counts as a definition.
17379                          */
17380                         for(tdone = 0, test = ptr; !tdone; test = test->prev) {
17381                                 tdone = (test == block->first);
17382                                 if (this_def(state, test, rhs)) {
17383                                         rhs = 0;
17384                                         break;
17385                                 }
17386                         }
17387                         /* If I still have a valid rhs add it to in */
17388                         change |= in_triple(rb, rhs);
17389                 }
17390         }
17391         return change;
17392 }
17393
17394 static struct reg_block *compute_variable_lifetimes(
17395         struct compile_state *state, struct basic_blocks *bb)
17396 {
17397         struct reg_block *blocks;
17398         int change;
17399         blocks = xcmalloc(
17400                 sizeof(*blocks)*(bb->last_vertex + 1), "reg_block");
17401         initialize_regblock(blocks, bb->last_block, 0);
17402         do {
17403                 int i;
17404                 change = 0;
17405                 for(i = 1; i <= bb->last_vertex; i++) {
17406                         struct block_set *edge;
17407                         struct reg_block *rb;
17408                         rb = &blocks[i];
17409                         /* Add the all successor's input set to in */
17410                         for(edge = rb->block->edges; edge; edge = edge->next) {
17411                                 change |= reg_in(state, blocks, rb, edge->member);
17412                         }
17413                         /* Add use to in... */
17414                         change |= use_in(state, rb);
17415                 }
17416         } while(change);
17417         return blocks;
17418 }
17419
17420 static void free_variable_lifetimes(struct compile_state *state, 
17421         struct basic_blocks *bb, struct reg_block *blocks)
17422 {
17423         int i;
17424         /* free in_set && out_set on each block */
17425         for(i = 1; i <= bb->last_vertex; i++) {
17426                 struct triple_reg_set *entry, *next;
17427                 struct reg_block *rb;
17428                 rb = &blocks[i];
17429                 for(entry = rb->in; entry ; entry = next) {
17430                         next = entry->next;
17431                         do_triple_unset(&rb->in, entry->member);
17432                 }
17433                 for(entry = rb->out; entry; entry = next) {
17434                         next = entry->next;
17435                         do_triple_unset(&rb->out, entry->member);
17436                 }
17437         }
17438         xfree(blocks);
17439
17440 }
17441
17442 typedef void (*wvl_cb_t)(
17443         struct compile_state *state, 
17444         struct reg_block *blocks, struct triple_reg_set *live, 
17445         struct reg_block *rb, struct triple *ins, void *arg);
17446
17447 static void walk_variable_lifetimes(struct compile_state *state,
17448         struct basic_blocks *bb, struct reg_block *blocks, 
17449         wvl_cb_t cb, void *arg)
17450 {
17451         int i;
17452         
17453         for(i = 1; i <= state->bb.last_vertex; i++) {
17454                 struct triple_reg_set *live;
17455                 struct triple_reg_set *entry, *next;
17456                 struct triple *ptr, *prev;
17457                 struct reg_block *rb;
17458                 struct block *block;
17459                 int done;
17460
17461                 /* Get the blocks */
17462                 rb = &blocks[i];
17463                 block = rb->block;
17464
17465                 /* Copy out into live */
17466                 live = 0;
17467                 for(entry = rb->out; entry; entry = next) {
17468                         next = entry->next;
17469                         do_triple_set(&live, entry->member, entry->new);
17470                 }
17471                 /* Walk through the basic block calculating live */
17472                 for(done = 0, ptr = block->last; !done; ptr = prev) {
17473                         struct triple **expr;
17474
17475                         prev = ptr->prev;
17476                         done = (ptr == block->first);
17477
17478                         /* Ensure the current definition is in live */
17479                         if (triple_is_def(state, ptr)) {
17480                                 do_triple_set(&live, ptr, 0);
17481                         }
17482
17483                         /* Inform the callback function of what is
17484                          * going on.
17485                          */
17486                          cb(state, blocks, live, rb, ptr, arg);
17487                         
17488                         /* Remove the current definition from live */
17489                         do_triple_unset(&live, ptr);
17490
17491                         /* Add the current uses to live.
17492                          *
17493                          * It is safe to skip phi functions because they do
17494                          * not have any block local uses, and the block
17495                          * output sets already properly account for what
17496                          * control flow depedent uses phi functions do have.
17497                          */
17498                         if (ptr->op == OP_PHI) {
17499                                 continue;
17500                         }
17501                         expr = triple_rhs(state, ptr, 0);
17502                         for(;expr; expr = triple_rhs(state, ptr, expr)) {
17503                                 /* If the triple is not a definition skip it. */
17504                                 if (!*expr || !triple_is_def(state, *expr)) {
17505                                         continue;
17506                                 }
17507                                 do_triple_set(&live, *expr, 0);
17508                         }
17509                 }
17510                 /* Free live */
17511                 for(entry = live; entry; entry = next) {
17512                         next = entry->next;
17513                         do_triple_unset(&live, entry->member);
17514                 }
17515         }
17516 }
17517
17518 struct print_live_variable_info {
17519         struct reg_block *rb;
17520         FILE *fp;
17521 };
17522 static void print_live_variables_block(
17523         struct compile_state *state, struct block *block, void *arg)
17524
17525 {
17526         struct print_live_variable_info *info = arg;
17527         struct block_set *edge;
17528         FILE *fp = info->fp;
17529         struct reg_block *rb;
17530         struct triple *ptr;
17531         int phi_present;
17532         int done;
17533         rb = &info->rb[block->vertex];
17534
17535         fprintf(fp, "\nblock: %p (%d),",
17536                 block,  block->vertex);
17537         for(edge = block->edges; edge; edge = edge->next) {
17538                 fprintf(fp, " %p<-%p",
17539                         edge->member, 
17540                         edge->member && edge->member->use?edge->member->use->member : 0);
17541         }
17542         fprintf(fp, "\n");
17543         if (rb->in) {
17544                 struct triple_reg_set *in_set;
17545                 fprintf(fp, "        in:");
17546                 for(in_set = rb->in; in_set; in_set = in_set->next) {
17547                         fprintf(fp, " %-10p", in_set->member);
17548                 }
17549                 fprintf(fp, "\n");
17550         }
17551         phi_present = 0;
17552         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
17553                 done = (ptr == block->last);
17554                 if (ptr->op == OP_PHI) {
17555                         phi_present = 1;
17556                         break;
17557                 }
17558         }
17559         if (phi_present) {
17560                 int edge;
17561                 for(edge = 0; edge < block->users; edge++) {
17562                         fprintf(fp, "     in(%d):", edge);
17563                         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
17564                                 struct triple **slot;
17565                                 done = (ptr == block->last);
17566                                 if (ptr->op != OP_PHI) {
17567                                         continue;
17568                                 }
17569                                 slot = &RHS(ptr, 0);
17570                                 fprintf(fp, " %-10p", slot[edge]);
17571                         }
17572                         fprintf(fp, "\n");
17573                 }
17574         }
17575         if (block->first->op == OP_LABEL) {
17576                 fprintf(fp, "%p:\n", block->first);
17577         }
17578         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
17579                 done = (ptr == block->last);
17580                 display_triple(fp, ptr);
17581         }
17582         if (rb->out) {
17583                 struct triple_reg_set *out_set;
17584                 fprintf(fp, "       out:");
17585                 for(out_set = rb->out; out_set; out_set = out_set->next) {
17586                         fprintf(fp, " %-10p", out_set->member);
17587                 }
17588                 fprintf(fp, "\n");
17589         }
17590         fprintf(fp, "\n");
17591 }
17592
17593 static void print_live_variables(struct compile_state *state, 
17594         struct basic_blocks *bb, struct reg_block *rb, FILE *fp)
17595 {
17596         struct print_live_variable_info info;
17597         info.rb = rb;
17598         info.fp = fp;
17599         fprintf(fp, "\nlive variables by block\n");
17600         walk_blocks(state, bb, print_live_variables_block, &info);
17601
17602 }
17603
17604
17605 static int count_triples(struct compile_state *state)
17606 {
17607         struct triple *first, *ins;
17608         int triples = 0;
17609         first = state->first;
17610         ins = first;
17611         do {
17612                 triples++;
17613                 ins = ins->next;
17614         } while (ins != first);
17615         return triples;
17616 }
17617
17618
17619 struct dead_triple {
17620         struct triple *triple;
17621         struct dead_triple *work_next;
17622         struct block *block;
17623         int old_id;
17624         int flags;
17625 #define TRIPLE_FLAG_ALIVE 1
17626 #define TRIPLE_FLAG_FREE  1
17627 };
17628
17629 static void print_dead_triples(struct compile_state *state, 
17630         struct dead_triple *dtriple)
17631 {
17632         struct triple *first, *ins;
17633         struct dead_triple *dt;
17634         FILE *fp;
17635         if (!(state->compiler->debug & DEBUG_TRIPLES)) {
17636                 return;
17637         }
17638         fp = state->dbgout;
17639         fprintf(fp, "--------------- dtriples ---------------\n");
17640         first = state->first;
17641         ins = first;
17642         do {
17643                 dt = &dtriple[ins->id];
17644                 if ((ins->op == OP_LABEL) && (ins->use)) {
17645                         fprintf(fp, "\n%p:\n", ins);
17646                 }
17647                 fprintf(fp, "%c", 
17648                         (dt->flags & TRIPLE_FLAG_ALIVE)?' ': '-');
17649                 display_triple(fp, ins);
17650                 if (triple_is_branch(state, ins)) {
17651                         fprintf(fp, "\n");
17652                 }
17653                 ins = ins->next;
17654         } while(ins != first);
17655         fprintf(fp, "\n");
17656 }
17657
17658
17659 static void awaken(
17660         struct compile_state *state,
17661         struct dead_triple *dtriple, struct triple **expr,
17662         struct dead_triple ***work_list_tail)
17663 {
17664         struct triple *triple;
17665         struct dead_triple *dt;
17666         if (!expr) {
17667                 return;
17668         }
17669         triple = *expr;
17670         if (!triple) {
17671                 return;
17672         }
17673         if (triple->id <= 0)  {
17674                 internal_error(state, triple, "bad triple id: %d",
17675                         triple->id);
17676         }
17677         if (triple->op == OP_NOOP) {
17678                 internal_error(state, triple, "awakening noop?");
17679                 return;
17680         }
17681         dt = &dtriple[triple->id];
17682         if (!(dt->flags & TRIPLE_FLAG_ALIVE)) {
17683                 dt->flags |= TRIPLE_FLAG_ALIVE;
17684                 if (!dt->work_next) {
17685                         **work_list_tail = dt;
17686                         *work_list_tail = &dt->work_next;
17687                 }
17688         }
17689 }
17690
17691 static void eliminate_inefectual_code(struct compile_state *state)
17692 {
17693         struct block *block;
17694         struct dead_triple *dtriple, *work_list, **work_list_tail, *dt;
17695         int triples, i;
17696         struct triple *first, *final, *ins;
17697
17698         if (!(state->compiler->flags & COMPILER_ELIMINATE_INEFECTUAL_CODE)) {
17699                 return;
17700         }
17701
17702         /* Setup the work list */
17703         work_list = 0;
17704         work_list_tail = &work_list;
17705
17706         first = state->first;
17707         final = state->first->prev;
17708
17709         /* Count how many triples I have */
17710         triples = count_triples(state);
17711
17712         /* Now put then in an array and mark all of the triples dead */
17713         dtriple = xcmalloc(sizeof(*dtriple) * (triples + 1), "dtriples");
17714         
17715         ins = first;
17716         i = 1;
17717         block = 0;
17718         do {
17719                 dtriple[i].triple = ins;
17720                 dtriple[i].block  = block_of_triple(state, ins);
17721                 dtriple[i].flags  = 0;
17722                 dtriple[i].old_id = ins->id;
17723                 ins->id = i;
17724                 /* See if it is an operation we always keep */
17725                 if (!triple_is_pure(state, ins, dtriple[i].old_id)) {
17726                         awaken(state, dtriple, &ins, &work_list_tail);
17727                 }
17728                 i++;
17729                 ins = ins->next;
17730         } while(ins != first);
17731         while(work_list) {
17732                 struct block *block;
17733                 struct dead_triple *dt;
17734                 struct block_set *user;
17735                 struct triple **expr;
17736                 dt = work_list;
17737                 work_list = dt->work_next;
17738                 if (!work_list) {
17739                         work_list_tail = &work_list;
17740                 }
17741                 /* Make certain the block the current instruction is in lives */
17742                 block = block_of_triple(state, dt->triple);
17743                 awaken(state, dtriple, &block->first, &work_list_tail);
17744                 if (triple_is_branch(state, block->last)) {
17745                         awaken(state, dtriple, &block->last, &work_list_tail);
17746                 } else {
17747                         awaken(state, dtriple, &block->last->next, &work_list_tail);
17748                 }
17749
17750                 /* Wake up the data depencencies of this triple */
17751                 expr = 0;
17752                 do {
17753                         expr = triple_rhs(state, dt->triple, expr);
17754                         awaken(state, dtriple, expr, &work_list_tail);
17755                 } while(expr);
17756                 do {
17757                         expr = triple_lhs(state, dt->triple, expr);
17758                         awaken(state, dtriple, expr, &work_list_tail);
17759                 } while(expr);
17760                 do {
17761                         expr = triple_misc(state, dt->triple, expr);
17762                         awaken(state, dtriple, expr, &work_list_tail);
17763                 } while(expr);
17764                 /* Wake up the forward control dependencies */
17765                 do {
17766                         expr = triple_targ(state, dt->triple, expr);
17767                         awaken(state, dtriple, expr, &work_list_tail);
17768                 } while(expr);
17769                 /* Wake up the reverse control dependencies of this triple */
17770                 for(user = dt->block->ipdomfrontier; user; user = user->next) {
17771                         struct triple *last;
17772                         last = user->member->last;
17773                         while((last->op == OP_NOOP) && (last != user->member->first)) {
17774                                 internal_warning(state, last, "awakening noop?");
17775                                 last = last->prev;
17776                         }
17777                         awaken(state, dtriple, &last, &work_list_tail);
17778                 }
17779         }
17780         print_dead_triples(state, dtriple);
17781         for(dt = &dtriple[1]; dt <= &dtriple[triples]; dt++) {
17782                 if ((dt->triple->op == OP_NOOP) && 
17783                         (dt->flags & TRIPLE_FLAG_ALIVE)) {
17784                         internal_error(state, dt->triple, "noop effective?");
17785                 }
17786                 dt->triple->id = dt->old_id;    /* Restore the color */
17787                 if (!(dt->flags & TRIPLE_FLAG_ALIVE)) {
17788                         release_triple(state, dt->triple);
17789                 }
17790         }
17791         xfree(dtriple);
17792
17793         rebuild_ssa_form(state);
17794
17795         print_blocks(state, __func__, state->dbgout);
17796 }
17797
17798
17799 static void insert_mandatory_copies(struct compile_state *state)
17800 {
17801         struct triple *ins, *first;
17802
17803         /* The object is with a minimum of inserted copies,
17804          * to resolve in fundamental register conflicts between
17805          * register value producers and consumers.
17806          * Theoretically we may be greater than minimal when we
17807          * are inserting copies before instructions but that
17808          * case should be rare.
17809          */
17810         first = state->first;
17811         ins = first;
17812         do {
17813                 struct triple_set *entry, *next;
17814                 struct triple *tmp;
17815                 struct reg_info info;
17816                 unsigned reg, regcm;
17817                 int do_post_copy, do_pre_copy;
17818                 tmp = 0;
17819                 if (!triple_is_def(state, ins)) {
17820                         goto next;
17821                 }
17822                 /* Find the architecture specific color information */
17823                 info = find_lhs_pre_color(state, ins, 0);
17824                 if (info.reg >= MAX_REGISTERS) {
17825                         info.reg = REG_UNSET;
17826                 }
17827
17828                 reg = REG_UNSET;
17829                 regcm = arch_type_to_regcm(state, ins->type);
17830                 do_post_copy = do_pre_copy = 0;
17831
17832                 /* Walk through the uses of ins and check for conflicts */
17833                 for(entry = ins->use; entry; entry = next) {
17834                         struct reg_info rinfo;
17835                         int i;
17836                         next = entry->next;
17837                         i = find_rhs_use(state, entry->member, ins);
17838                         if (i < 0) {
17839                                 continue;
17840                         }
17841                         
17842                         /* Find the users color requirements */
17843                         rinfo = arch_reg_rhs(state, entry->member, i);
17844                         if (rinfo.reg >= MAX_REGISTERS) {
17845                                 rinfo.reg = REG_UNSET;
17846                         }
17847                         
17848                         /* See if I need a pre_copy */
17849                         if (rinfo.reg != REG_UNSET) {
17850                                 if ((reg != REG_UNSET) && (reg != rinfo.reg)) {
17851                                         do_pre_copy = 1;
17852                                 }
17853                                 reg = rinfo.reg;
17854                         }
17855                         regcm &= rinfo.regcm;
17856                         regcm = arch_regcm_normalize(state, regcm);
17857                         if (regcm == 0) {
17858                                 do_pre_copy = 1;
17859                         }
17860                         /* Always use pre_copies for constants.
17861                          * They do not take up any registers until a
17862                          * copy places them in one.
17863                          */
17864                         if ((info.reg == REG_UNNEEDED) && 
17865                                 (rinfo.reg != REG_UNNEEDED)) {
17866                                 do_pre_copy = 1;
17867                         }
17868                 }
17869                 do_post_copy =
17870                         !do_pre_copy &&
17871                         (((info.reg != REG_UNSET) && 
17872                                 (reg != REG_UNSET) &&
17873                                 (info.reg != reg)) ||
17874                         ((info.regcm & regcm) == 0));
17875
17876                 reg = info.reg;
17877                 regcm = info.regcm;
17878                 /* Walk through the uses of ins and do a pre_copy or see if a post_copy is warranted */
17879                 for(entry = ins->use; entry; entry = next) {
17880                         struct reg_info rinfo;
17881                         int i;
17882                         next = entry->next;
17883                         i = find_rhs_use(state, entry->member, ins);
17884                         if (i < 0) {
17885                                 continue;
17886                         }
17887                         
17888                         /* Find the users color requirements */
17889                         rinfo = arch_reg_rhs(state, entry->member, i);
17890                         if (rinfo.reg >= MAX_REGISTERS) {
17891                                 rinfo.reg = REG_UNSET;
17892                         }
17893
17894                         /* Now see if it is time to do the pre_copy */
17895                         if (rinfo.reg != REG_UNSET) {
17896                                 if (((reg != REG_UNSET) && (reg != rinfo.reg)) ||
17897                                         ((regcm & rinfo.regcm) == 0) ||
17898                                         /* Don't let a mandatory coalesce sneak
17899                                          * into a operation that is marked to prevent
17900                                          * coalescing.
17901                                          */
17902                                         ((reg != REG_UNNEEDED) &&
17903                                         ((ins->id & TRIPLE_FLAG_POST_SPLIT) ||
17904                                         (entry->member->id & TRIPLE_FLAG_PRE_SPLIT)))
17905                                         ) {
17906                                         if (do_pre_copy) {
17907                                                 struct triple *user;
17908                                                 user = entry->member;
17909                                                 if (RHS(user, i) != ins) {
17910                                                         internal_error(state, user, "bad rhs");
17911                                                 }
17912                                                 tmp = pre_copy(state, user, i);
17913                                                 tmp->id |= TRIPLE_FLAG_PRE_SPLIT;
17914                                                 continue;
17915                                         } else {
17916                                                 do_post_copy = 1;
17917                                         }
17918                                 }
17919                                 reg = rinfo.reg;
17920                         }
17921                         if ((regcm & rinfo.regcm) == 0) {
17922                                 if (do_pre_copy) {
17923                                         struct triple *user;
17924                                         user = entry->member;
17925                                         if (RHS(user, i) != ins) {
17926                                                 internal_error(state, user, "bad rhs");
17927                                         }
17928                                         tmp = pre_copy(state, user, i);
17929                                         tmp->id |= TRIPLE_FLAG_PRE_SPLIT;
17930                                         continue;
17931                                 } else {
17932                                         do_post_copy = 1;
17933                                 }
17934                         }
17935                         regcm &= rinfo.regcm;
17936                         
17937                 }
17938                 if (do_post_copy) {
17939                         struct reg_info pre, post;
17940                         tmp = post_copy(state, ins);
17941                         tmp->id |= TRIPLE_FLAG_PRE_SPLIT;
17942                         pre = arch_reg_lhs(state, ins, 0);
17943                         post = arch_reg_lhs(state, tmp, 0);
17944                         if ((pre.reg == post.reg) && (pre.regcm == post.regcm)) {
17945                                 internal_error(state, tmp, "useless copy");
17946                         }
17947                 }
17948         next:
17949                 ins = ins->next;
17950         } while(ins != first);
17951
17952         print_blocks(state, __func__, state->dbgout);
17953 }
17954
17955
17956 struct live_range_edge;
17957 struct live_range_def;
17958 struct live_range {
17959         struct live_range_edge *edges;
17960         struct live_range_def *defs;
17961 /* Note. The list pointed to by defs is kept in order.
17962  * That is baring splits in the flow control
17963  * defs dominates defs->next wich dominates defs->next->next
17964  * etc.
17965  */
17966         unsigned color;
17967         unsigned classes;
17968         unsigned degree;
17969         unsigned length;
17970         struct live_range *group_next, **group_prev;
17971 };
17972
17973 struct live_range_edge {
17974         struct live_range_edge *next;
17975         struct live_range *node;
17976 };
17977
17978 struct live_range_def {
17979         struct live_range_def *next;
17980         struct live_range_def *prev;
17981         struct live_range *lr;
17982         struct triple *def;
17983         unsigned orig_id;
17984 };
17985
17986 #define LRE_HASH_SIZE 2048
17987 struct lre_hash {
17988         struct lre_hash *next;
17989         struct live_range *left;
17990         struct live_range *right;
17991 };
17992
17993
17994 struct reg_state {
17995         struct lre_hash *hash[LRE_HASH_SIZE];
17996         struct reg_block *blocks;
17997         struct live_range_def *lrd;
17998         struct live_range *lr;
17999         struct live_range *low, **low_tail;
18000         struct live_range *high, **high_tail;
18001         unsigned defs;
18002         unsigned ranges;
18003         int passes, max_passes;
18004 };
18005
18006
18007 struct print_interference_block_info {
18008         struct reg_state *rstate;
18009         FILE *fp;
18010         int need_edges;
18011 };
18012 static void print_interference_block(
18013         struct compile_state *state, struct block *block, void *arg)
18014
18015 {
18016         struct print_interference_block_info *info = arg;
18017         struct reg_state *rstate = info->rstate;
18018         struct block_set *edge;
18019         FILE *fp = info->fp;
18020         struct reg_block *rb;
18021         struct triple *ptr;
18022         int phi_present;
18023         int done;
18024         rb = &rstate->blocks[block->vertex];
18025
18026         fprintf(fp, "\nblock: %p (%d),",
18027                 block,  block->vertex);
18028         for(edge = block->edges; edge; edge = edge->next) {
18029                 fprintf(fp, " %p<-%p",
18030                         edge->member, 
18031                         edge->member && edge->member->use?edge->member->use->member : 0);
18032         }
18033         fprintf(fp, "\n");
18034         if (rb->in) {
18035                 struct triple_reg_set *in_set;
18036                 fprintf(fp, "        in:");
18037                 for(in_set = rb->in; in_set; in_set = in_set->next) {
18038                         fprintf(fp, " %-10p", in_set->member);
18039                 }
18040                 fprintf(fp, "\n");
18041         }
18042         phi_present = 0;
18043         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
18044                 done = (ptr == block->last);
18045                 if (ptr->op == OP_PHI) {
18046                         phi_present = 1;
18047                         break;
18048                 }
18049         }
18050         if (phi_present) {
18051                 int edge;
18052                 for(edge = 0; edge < block->users; edge++) {
18053                         fprintf(fp, "     in(%d):", edge);
18054                         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
18055                                 struct triple **slot;
18056                                 done = (ptr == block->last);
18057                                 if (ptr->op != OP_PHI) {
18058                                         continue;
18059                                 }
18060                                 slot = &RHS(ptr, 0);
18061                                 fprintf(fp, " %-10p", slot[edge]);
18062                         }
18063                         fprintf(fp, "\n");
18064                 }
18065         }
18066         if (block->first->op == OP_LABEL) {
18067                 fprintf(fp, "%p:\n", block->first);
18068         }
18069         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
18070                 struct live_range *lr;
18071                 unsigned id;
18072                 int op;
18073                 op = ptr->op;
18074                 done = (ptr == block->last);
18075                 lr = rstate->lrd[ptr->id].lr;
18076                 
18077                 id = ptr->id;
18078                 ptr->id = rstate->lrd[id].orig_id;
18079                 SET_REG(ptr->id, lr->color);
18080                 display_triple(fp, ptr);
18081                 ptr->id = id;
18082
18083                 if (triple_is_def(state, ptr) && (lr->defs == 0)) {
18084                         internal_error(state, ptr, "lr has no defs!");
18085                 }
18086                 if (info->need_edges) {
18087                         if (lr->defs) {
18088                                 struct live_range_def *lrd;
18089                                 fprintf(fp, "       range:");
18090                                 lrd = lr->defs;
18091                                 do {
18092                                         fprintf(fp, " %-10p", lrd->def);
18093                                         lrd = lrd->next;
18094                                 } while(lrd != lr->defs);
18095                                 fprintf(fp, "\n");
18096                         }
18097                         if (lr->edges > 0) {
18098                                 struct live_range_edge *edge;
18099                                 fprintf(fp, "       edges:");
18100                                 for(edge = lr->edges; edge; edge = edge->next) {
18101                                         struct live_range_def *lrd;
18102                                         lrd = edge->node->defs;
18103                                         do {
18104                                                 fprintf(fp, " %-10p", lrd->def);
18105                                                 lrd = lrd->next;
18106                                         } while(lrd != edge->node->defs);
18107                                         fprintf(fp, "|");
18108                                 }
18109                                 fprintf(fp, "\n");
18110                         }
18111                 }
18112                 /* Do a bunch of sanity checks */
18113                 valid_ins(state, ptr);
18114                 if ((ptr->id < 0) || (ptr->id > rstate->defs)) {
18115                         internal_error(state, ptr, "Invalid triple id: %d",
18116                                 ptr->id);
18117                 }
18118         }
18119         if (rb->out) {
18120                 struct triple_reg_set *out_set;
18121                 fprintf(fp, "       out:");
18122                 for(out_set = rb->out; out_set; out_set = out_set->next) {
18123                         fprintf(fp, " %-10p", out_set->member);
18124                 }
18125                 fprintf(fp, "\n");
18126         }
18127         fprintf(fp, "\n");
18128 }
18129
18130 static void print_interference_blocks(
18131         struct compile_state *state, struct reg_state *rstate, FILE *fp, int need_edges)
18132 {
18133         struct print_interference_block_info info;
18134         info.rstate = rstate;
18135         info.fp = fp;
18136         info.need_edges = need_edges;
18137         fprintf(fp, "\nlive variables by block\n");
18138         walk_blocks(state, &state->bb, print_interference_block, &info);
18139
18140 }
18141
18142 static unsigned regc_max_size(struct compile_state *state, int classes)
18143 {
18144         unsigned max_size;
18145         int i;
18146         max_size = 0;
18147         for(i = 0; i < MAX_REGC; i++) {
18148                 if (classes & (1 << i)) {
18149                         unsigned size;
18150                         size = arch_regc_size(state, i);
18151                         if (size > max_size) {
18152                                 max_size = size;
18153                         }
18154                 }
18155         }
18156         return max_size;
18157 }
18158
18159 static int reg_is_reg(struct compile_state *state, int reg1, int reg2)
18160 {
18161         unsigned equivs[MAX_REG_EQUIVS];
18162         int i;
18163         if ((reg1 < 0) || (reg1 >= MAX_REGISTERS)) {
18164                 internal_error(state, 0, "invalid register");
18165         }
18166         if ((reg2 < 0) || (reg2 >= MAX_REGISTERS)) {
18167                 internal_error(state, 0, "invalid register");
18168         }
18169         arch_reg_equivs(state, equivs, reg1);
18170         for(i = 0; (i < MAX_REG_EQUIVS) && equivs[i] != REG_UNSET; i++) {
18171                 if (equivs[i] == reg2) {
18172                         return 1;
18173                 }
18174         }
18175         return 0;
18176 }
18177
18178 static void reg_fill_used(struct compile_state *state, char *used, int reg)
18179 {
18180         unsigned equivs[MAX_REG_EQUIVS];
18181         int i;
18182         if (reg == REG_UNNEEDED) {
18183                 return;
18184         }
18185         arch_reg_equivs(state, equivs, reg);
18186         for(i = 0; (i < MAX_REG_EQUIVS) && equivs[i] != REG_UNSET; i++) {
18187                 used[equivs[i]] = 1;
18188         }
18189         return;
18190 }
18191
18192 static void reg_inc_used(struct compile_state *state, char *used, int reg)
18193 {
18194         unsigned equivs[MAX_REG_EQUIVS];
18195         int i;
18196         if (reg == REG_UNNEEDED) {
18197                 return;
18198         }
18199         arch_reg_equivs(state, equivs, reg);
18200         for(i = 0; (i < MAX_REG_EQUIVS) && equivs[i] != REG_UNSET; i++) {
18201                 used[equivs[i]] += 1;
18202         }
18203         return;
18204 }
18205
18206 static unsigned int hash_live_edge(
18207         struct live_range *left, struct live_range *right)
18208 {
18209         unsigned int hash, val;
18210         unsigned long lval, rval;
18211         lval = ((unsigned long)left)/sizeof(struct live_range);
18212         rval = ((unsigned long)right)/sizeof(struct live_range);
18213         hash = 0;
18214         while(lval) {
18215                 val = lval & 0xff;
18216                 lval >>= 8;
18217                 hash = (hash *263) + val;
18218         }
18219         while(rval) {
18220                 val = rval & 0xff;
18221                 rval >>= 8;
18222                 hash = (hash *263) + val;
18223         }
18224         hash = hash & (LRE_HASH_SIZE - 1);
18225         return hash;
18226 }
18227
18228 static struct lre_hash **lre_probe(struct reg_state *rstate,
18229         struct live_range *left, struct live_range *right)
18230 {
18231         struct lre_hash **ptr;
18232         unsigned int index;
18233         /* Ensure left <= right */
18234         if (left > right) {
18235                 struct live_range *tmp;
18236                 tmp = left;
18237                 left = right;
18238                 right = tmp;
18239         }
18240         index = hash_live_edge(left, right);
18241         
18242         ptr = &rstate->hash[index];
18243         while(*ptr) {
18244                 if (((*ptr)->left == left) && ((*ptr)->right == right)) {
18245                         break;
18246                 }
18247                 ptr = &(*ptr)->next;
18248         }
18249         return ptr;
18250 }
18251
18252 static int interfere(struct reg_state *rstate,
18253         struct live_range *left, struct live_range *right)
18254 {
18255         struct lre_hash **ptr;
18256         ptr = lre_probe(rstate, left, right);
18257         return ptr && *ptr;
18258 }
18259
18260 static void add_live_edge(struct reg_state *rstate, 
18261         struct live_range *left, struct live_range *right)
18262 {
18263         /* FIXME the memory allocation overhead is noticeable here... */
18264         struct lre_hash **ptr, *new_hash;
18265         struct live_range_edge *edge;
18266
18267         if (left == right) {
18268                 return;
18269         }
18270         if ((left == &rstate->lr[0]) || (right == &rstate->lr[0])) {
18271                 return;
18272         }
18273         /* Ensure left <= right */
18274         if (left > right) {
18275                 struct live_range *tmp;
18276                 tmp = left;
18277                 left = right;
18278                 right = tmp;
18279         }
18280         ptr = lre_probe(rstate, left, right);
18281         if (*ptr) {
18282                 return;
18283         }
18284 #if 0
18285         fprintf(state->errout, "new_live_edge(%p, %p)\n",
18286                 left, right);
18287 #endif
18288         new_hash = xmalloc(sizeof(*new_hash), "lre_hash");
18289         new_hash->next  = *ptr;
18290         new_hash->left  = left;
18291         new_hash->right = right;
18292         *ptr = new_hash;
18293
18294         edge = xmalloc(sizeof(*edge), "live_range_edge");
18295         edge->next   = left->edges;
18296         edge->node   = right;
18297         left->edges  = edge;
18298         left->degree += 1;
18299         
18300         edge = xmalloc(sizeof(*edge), "live_range_edge");
18301         edge->next    = right->edges;
18302         edge->node    = left;
18303         right->edges  = edge;
18304         right->degree += 1;
18305 }
18306
18307 static void remove_live_edge(struct reg_state *rstate,
18308         struct live_range *left, struct live_range *right)
18309 {
18310         struct live_range_edge *edge, **ptr;
18311         struct lre_hash **hptr, *entry;
18312         hptr = lre_probe(rstate, left, right);
18313         if (!hptr || !*hptr) {
18314                 return;
18315         }
18316         entry = *hptr;
18317         *hptr = entry->next;
18318         xfree(entry);
18319
18320         for(ptr = &left->edges; *ptr; ptr = &(*ptr)->next) {
18321                 edge = *ptr;
18322                 if (edge->node == right) {
18323                         *ptr = edge->next;
18324                         memset(edge, 0, sizeof(*edge));
18325                         xfree(edge);
18326                         right->degree--;
18327                         break;
18328                 }
18329         }
18330         for(ptr = &right->edges; *ptr; ptr = &(*ptr)->next) {
18331                 edge = *ptr;
18332                 if (edge->node == left) {
18333                         *ptr = edge->next;
18334                         memset(edge, 0, sizeof(*edge));
18335                         xfree(edge);
18336                         left->degree--;
18337                         break;
18338                 }
18339         }
18340 }
18341
18342 static void remove_live_edges(struct reg_state *rstate, struct live_range *range)
18343 {
18344         struct live_range_edge *edge, *next;
18345         for(edge = range->edges; edge; edge = next) {
18346                 next = edge->next;
18347                 remove_live_edge(rstate, range, edge->node);
18348         }
18349 }
18350
18351 static void transfer_live_edges(struct reg_state *rstate, 
18352         struct live_range *dest, struct live_range *src)
18353 {
18354         struct live_range_edge *edge, *next;
18355         for(edge = src->edges; edge; edge = next) {
18356                 struct live_range *other;
18357                 next = edge->next;
18358                 other = edge->node;
18359                 remove_live_edge(rstate, src, other);
18360                 add_live_edge(rstate, dest, other);
18361         }
18362 }
18363
18364
18365 /* Interference graph...
18366  * 
18367  * new(n) --- Return a graph with n nodes but no edges.
18368  * add(g,x,y) --- Return a graph including g with an between x and y
18369  * interfere(g, x, y) --- Return true if there exists an edge between the nodes
18370  *                x and y in the graph g
18371  * degree(g, x) --- Return the degree of the node x in the graph g
18372  * neighbors(g, x, f) --- Apply function f to each neighbor of node x in the graph g
18373  *
18374  * Implement with a hash table && a set of adjcency vectors.
18375  * The hash table supports constant time implementations of add and interfere.
18376  * The adjacency vectors support an efficient implementation of neighbors.
18377  */
18378
18379 /* 
18380  *     +---------------------------------------------------+
18381  *     |         +--------------+                          |
18382  *     v         v              |                          |
18383  * renumber -> build graph -> colalesce -> spill_costs -> simplify -> select 
18384  *
18385  * -- In simplify implment optimistic coloring... (No backtracking)
18386  * -- Implement Rematerialization it is the only form of spilling we can perform
18387  *    Essentially this means dropping a constant from a register because
18388  *    we can regenerate it later.
18389  *
18390  * --- Very conservative colalescing (don't colalesce just mark the opportunities)
18391  *     coalesce at phi points...
18392  * --- Bias coloring if at all possible do the coalesing a compile time.
18393  *
18394  *
18395  */
18396
18397 static void different_colored(
18398         struct compile_state *state, struct reg_state *rstate, 
18399         struct triple *parent, struct triple *ins)
18400 {
18401         struct live_range *lr;
18402         struct triple **expr;
18403         lr = rstate->lrd[ins->id].lr;
18404         expr = triple_rhs(state, ins, 0);
18405         for(;expr; expr = triple_rhs(state, ins, expr)) {
18406                 struct live_range *lr2;
18407                 if (!*expr || (*expr == parent) || (*expr == ins)) {
18408                         continue;
18409                 }
18410                 lr2 = rstate->lrd[(*expr)->id].lr;
18411                 if (lr->color == lr2->color) {
18412                         internal_error(state, ins, "live range too big");
18413                 }
18414         }
18415 }
18416
18417
18418 static struct live_range *coalesce_ranges(
18419         struct compile_state *state, struct reg_state *rstate,
18420         struct live_range *lr1, struct live_range *lr2)
18421 {
18422         struct live_range_def *head, *mid1, *mid2, *end, *lrd;
18423         unsigned color;
18424         unsigned classes;
18425         if (lr1 == lr2) {
18426                 return lr1;
18427         }
18428         if (!lr1->defs || !lr2->defs) {
18429                 internal_error(state, 0,
18430                         "cannot coalese dead live ranges");
18431         }
18432         if ((lr1->color == REG_UNNEEDED) ||
18433                 (lr2->color == REG_UNNEEDED)) {
18434                 internal_error(state, 0, 
18435                         "cannot coalesce live ranges without a possible color");
18436         }
18437         if ((lr1->color != lr2->color) &&
18438                 (lr1->color != REG_UNSET) &&
18439                 (lr2->color != REG_UNSET)) {
18440                 internal_error(state, lr1->defs->def, 
18441                         "cannot coalesce live ranges of different colors");
18442         }
18443         color = lr1->color;
18444         if (color == REG_UNSET) {
18445                 color = lr2->color;
18446         }
18447         classes = lr1->classes & lr2->classes;
18448         if (!classes) {
18449                 internal_error(state, lr1->defs->def,
18450                         "cannot coalesce live ranges with dissimilar register classes");
18451         }
18452         if (state->compiler->debug & DEBUG_COALESCING) {
18453                 FILE *fp = state->errout;
18454                 fprintf(fp, "coalescing:");
18455                 lrd = lr1->defs;
18456                 do {
18457                         fprintf(fp, " %p", lrd->def);
18458                         lrd = lrd->next;
18459                 } while(lrd != lr1->defs);
18460                 fprintf(fp, " |");
18461                 lrd = lr2->defs;
18462                 do {
18463                         fprintf(fp, " %p", lrd->def);
18464                         lrd = lrd->next;
18465                 } while(lrd != lr2->defs);
18466                 fprintf(fp, "\n");
18467         }
18468         /* If there is a clear dominate live range put it in lr1,
18469          * For purposes of this test phi functions are
18470          * considered dominated by the definitions that feed into
18471          * them. 
18472          */
18473         if ((lr1->defs->prev->def->op == OP_PHI) ||
18474                 ((lr2->defs->prev->def->op != OP_PHI) &&
18475                 tdominates(state, lr2->defs->def, lr1->defs->def))) {
18476                 struct live_range *tmp;
18477                 tmp = lr1;
18478                 lr1 = lr2;
18479                 lr2 = tmp;
18480         }
18481 #if 0
18482         if (lr1->defs->orig_id  & TRIPLE_FLAG_POST_SPLIT) {
18483                 fprintf(state->errout, "lr1 post\n");
18484         }
18485         if (lr1->defs->orig_id & TRIPLE_FLAG_PRE_SPLIT) {
18486                 fprintf(state->errout, "lr1 pre\n");
18487         }
18488         if (lr2->defs->orig_id  & TRIPLE_FLAG_POST_SPLIT) {
18489                 fprintf(state->errout, "lr2 post\n");
18490         }
18491         if (lr2->defs->orig_id & TRIPLE_FLAG_PRE_SPLIT) {
18492                 fprintf(state->errout, "lr2 pre\n");
18493         }
18494 #endif
18495 #if 0
18496         fprintf(state->errout, "coalesce color1(%p): %3d color2(%p) %3d\n",
18497                 lr1->defs->def,
18498                 lr1->color,
18499                 lr2->defs->def,
18500                 lr2->color);
18501 #endif
18502         
18503         /* Append lr2 onto lr1 */
18504 #warning "FIXME should this be a merge instead of a splice?"
18505         /* This FIXME item applies to the correctness of live_range_end 
18506          * and to the necessity of making multiple passes of coalesce_live_ranges.
18507          * A failure to find some coalesce opportunities in coaleace_live_ranges
18508          * does not impact the correct of the compiler just the efficiency with
18509          * which registers are allocated.
18510          */
18511         head = lr1->defs;
18512         mid1 = lr1->defs->prev;
18513         mid2 = lr2->defs;
18514         end  = lr2->defs->prev;
18515         
18516         head->prev = end;
18517         end->next  = head;
18518
18519         mid1->next = mid2;
18520         mid2->prev = mid1;
18521
18522         /* Fixup the live range in the added live range defs */
18523         lrd = head;
18524         do {
18525                 lrd->lr = lr1;
18526                 lrd = lrd->next;
18527         } while(lrd != head);
18528
18529         /* Mark lr2 as free. */
18530         lr2->defs = 0;
18531         lr2->color = REG_UNNEEDED;
18532         lr2->classes = 0;
18533
18534         if (!lr1->defs) {
18535                 internal_error(state, 0, "lr1->defs == 0 ?");
18536         }
18537
18538         lr1->color   = color;
18539         lr1->classes = classes;
18540
18541         /* Keep the graph in sync by transfering the edges from lr2 to lr1 */
18542         transfer_live_edges(rstate, lr1, lr2);
18543
18544         return lr1;
18545 }
18546
18547 static struct live_range_def *live_range_head(
18548         struct compile_state *state, struct live_range *lr,
18549         struct live_range_def *last)
18550 {
18551         struct live_range_def *result;
18552         result = 0;
18553         if (last == 0) {
18554                 result = lr->defs;
18555         }
18556         else if (!tdominates(state, lr->defs->def, last->next->def)) {
18557                 result = last->next;
18558         }
18559         return result;
18560 }
18561
18562 static struct live_range_def *live_range_end(
18563         struct compile_state *state, struct live_range *lr,
18564         struct live_range_def *last)
18565 {
18566         struct live_range_def *result;
18567         result = 0;
18568         if (last == 0) {
18569                 result = lr->defs->prev;
18570         }
18571         else if (!tdominates(state, last->prev->def, lr->defs->prev->def)) {
18572                 result = last->prev;
18573         }
18574         return result;
18575 }
18576
18577
18578 static void initialize_live_ranges(
18579         struct compile_state *state, struct reg_state *rstate)
18580 {
18581         struct triple *ins, *first;
18582         size_t count, size;
18583         int i, j;
18584
18585         first = state->first;
18586         /* First count how many instructions I have.
18587          */
18588         count = count_triples(state);
18589         /* Potentially I need one live range definitions for each
18590          * instruction.
18591          */
18592         rstate->defs = count;
18593         /* Potentially I need one live range for each instruction
18594          * plus an extra for the dummy live range.
18595          */
18596         rstate->ranges = count + 1;
18597         size = sizeof(rstate->lrd[0]) * rstate->defs;
18598         rstate->lrd = xcmalloc(size, "live_range_def");
18599         size = sizeof(rstate->lr[0]) * rstate->ranges;
18600         rstate->lr  = xcmalloc(size, "live_range");
18601
18602         /* Setup the dummy live range */
18603         rstate->lr[0].classes = 0;
18604         rstate->lr[0].color = REG_UNSET;
18605         rstate->lr[0].defs = 0;
18606         i = j = 0;
18607         ins = first;
18608         do {
18609                 /* If the triple is a variable give it a live range */
18610                 if (triple_is_def(state, ins)) {
18611                         struct reg_info info;
18612                         /* Find the architecture specific color information */
18613                         info = find_def_color(state, ins);
18614                         i++;
18615                         rstate->lr[i].defs    = &rstate->lrd[j];
18616                         rstate->lr[i].color   = info.reg;
18617                         rstate->lr[i].classes = info.regcm;
18618                         rstate->lr[i].degree  = 0;
18619                         rstate->lrd[j].lr = &rstate->lr[i];
18620                 } 
18621                 /* Otherwise give the triple the dummy live range. */
18622                 else {
18623                         rstate->lrd[j].lr = &rstate->lr[0];
18624                 }
18625
18626                 /* Initalize the live_range_def */
18627                 rstate->lrd[j].next    = &rstate->lrd[j];
18628                 rstate->lrd[j].prev    = &rstate->lrd[j];
18629                 rstate->lrd[j].def     = ins;
18630                 rstate->lrd[j].orig_id = ins->id;
18631                 ins->id = j;
18632
18633                 j++;
18634                 ins = ins->next;
18635         } while(ins != first);
18636         rstate->ranges = i;
18637
18638         /* Make a second pass to handle achitecture specific register
18639          * constraints.
18640          */
18641         ins = first;
18642         do {
18643                 int zlhs, zrhs, i, j;
18644                 if (ins->id > rstate->defs) {
18645                         internal_error(state, ins, "bad id");
18646                 }
18647                 
18648                 /* Walk through the template of ins and coalesce live ranges */
18649                 zlhs = ins->lhs;
18650                 if ((zlhs == 0) && triple_is_def(state, ins)) {
18651                         zlhs = 1;
18652                 }
18653                 zrhs = ins->rhs;
18654
18655                 if (state->compiler->debug & DEBUG_COALESCING2) {
18656                         fprintf(state->errout, "mandatory coalesce: %p %d %d\n",
18657                                 ins, zlhs, zrhs);
18658                 }
18659
18660                 for(i = 0; i < zlhs; i++) {
18661                         struct reg_info linfo;
18662                         struct live_range_def *lhs;
18663                         linfo = arch_reg_lhs(state, ins, i);
18664                         if (linfo.reg < MAX_REGISTERS) {
18665                                 continue;
18666                         }
18667                         if (triple_is_def(state, ins)) {
18668                                 lhs = &rstate->lrd[ins->id];
18669                         } else {
18670                                 lhs = &rstate->lrd[LHS(ins, i)->id];
18671                         }
18672
18673                         if (state->compiler->debug & DEBUG_COALESCING2) {
18674                                 fprintf(state->errout, "coalesce lhs(%d): %p %d\n",
18675                                         i, lhs, linfo.reg);
18676                         }
18677
18678                         for(j = 0; j < zrhs; j++) {
18679                                 struct reg_info rinfo;
18680                                 struct live_range_def *rhs;
18681                                 rinfo = arch_reg_rhs(state, ins, j);
18682                                 if (rinfo.reg < MAX_REGISTERS) {
18683                                         continue;
18684                                 }
18685                                 rhs = &rstate->lrd[RHS(ins, j)->id];
18686
18687                                 if (state->compiler->debug & DEBUG_COALESCING2) {
18688                                         fprintf(state->errout, "coalesce rhs(%d): %p %d\n",
18689                                                 j, rhs, rinfo.reg);
18690                                 }
18691
18692                                 if (rinfo.reg == linfo.reg) {
18693                                         coalesce_ranges(state, rstate, 
18694                                                 lhs->lr, rhs->lr);
18695                                 }
18696                         }
18697                 }
18698                 ins = ins->next;
18699         } while(ins != first);
18700 }
18701
18702 static void graph_ins(
18703         struct compile_state *state, 
18704         struct reg_block *blocks, struct triple_reg_set *live, 
18705         struct reg_block *rb, struct triple *ins, void *arg)
18706 {
18707         struct reg_state *rstate = arg;
18708         struct live_range *def;
18709         struct triple_reg_set *entry;
18710
18711         /* If the triple is not a definition
18712          * we do not have a definition to add to
18713          * the interference graph.
18714          */
18715         if (!triple_is_def(state, ins)) {
18716                 return;
18717         }
18718         def = rstate->lrd[ins->id].lr;
18719         
18720         /* Create an edge between ins and everything that is
18721          * alive, unless the live_range cannot share
18722          * a physical register with ins.
18723          */
18724         for(entry = live; entry; entry = entry->next) {
18725                 struct live_range *lr;
18726                 if ((entry->member->id < 0) || (entry->member->id > rstate->defs)) {
18727                         internal_error(state, 0, "bad entry?");
18728                 }
18729                 lr = rstate->lrd[entry->member->id].lr;
18730                 if (def == lr) {
18731                         continue;
18732                 }
18733                 if (!arch_regcm_intersect(def->classes, lr->classes)) {
18734                         continue;
18735                 }
18736                 add_live_edge(rstate, def, lr);
18737         }
18738         return;
18739 }
18740
18741 static struct live_range *get_verify_live_range(
18742         struct compile_state *state, struct reg_state *rstate, struct triple *ins)
18743 {
18744         struct live_range *lr;
18745         struct live_range_def *lrd;
18746         int ins_found;
18747         if ((ins->id < 0) || (ins->id > rstate->defs)) {
18748                 internal_error(state, ins, "bad ins?");
18749         }
18750         lr = rstate->lrd[ins->id].lr;
18751         ins_found = 0;
18752         lrd = lr->defs;
18753         do {
18754                 if (lrd->def == ins) {
18755                         ins_found = 1;
18756                 }
18757                 lrd = lrd->next;
18758         } while(lrd != lr->defs);
18759         if (!ins_found) {
18760                 internal_error(state, ins, "ins not in live range");
18761         }
18762         return lr;
18763 }
18764
18765 static void verify_graph_ins(
18766         struct compile_state *state, 
18767         struct reg_block *blocks, struct triple_reg_set *live, 
18768         struct reg_block *rb, struct triple *ins, void *arg)
18769 {
18770         struct reg_state *rstate = arg;
18771         struct triple_reg_set *entry1, *entry2;
18772
18773
18774         /* Compare live against edges and make certain the code is working */
18775         for(entry1 = live; entry1; entry1 = entry1->next) {
18776                 struct live_range *lr1;
18777                 lr1 = get_verify_live_range(state, rstate, entry1->member);
18778                 for(entry2 = live; entry2; entry2 = entry2->next) {
18779                         struct live_range *lr2;
18780                         struct live_range_edge *edge2;
18781                         int lr1_found;
18782                         int lr2_degree;
18783                         if (entry2 == entry1) {
18784                                 continue;
18785                         }
18786                         lr2 = get_verify_live_range(state, rstate, entry2->member);
18787                         if (lr1 == lr2) {
18788                                 internal_error(state, entry2->member, 
18789                                         "live range with 2 values simultaneously alive");
18790                         }
18791                         if (!arch_regcm_intersect(lr1->classes, lr2->classes)) {
18792                                 continue;
18793                         }
18794                         if (!interfere(rstate, lr1, lr2)) {
18795                                 internal_error(state, entry2->member, 
18796                                         "edges don't interfere?");
18797                         }
18798                                 
18799                         lr1_found = 0;
18800                         lr2_degree = 0;
18801                         for(edge2 = lr2->edges; edge2; edge2 = edge2->next) {
18802                                 lr2_degree++;
18803                                 if (edge2->node == lr1) {
18804                                         lr1_found = 1;
18805                                 }
18806                         }
18807                         if (lr2_degree != lr2->degree) {
18808                                 internal_error(state, entry2->member,
18809                                         "computed degree: %d does not match reported degree: %d\n",
18810                                         lr2_degree, lr2->degree);
18811                         }
18812                         if (!lr1_found) {
18813                                 internal_error(state, entry2->member, "missing edge");
18814                         }
18815                 }
18816         }
18817         return;
18818 }
18819
18820
18821 static void print_interference_ins(
18822         struct compile_state *state, 
18823         struct reg_block *blocks, struct triple_reg_set *live, 
18824         struct reg_block *rb, struct triple *ins, void *arg)
18825 {
18826         struct reg_state *rstate = arg;
18827         struct live_range *lr;
18828         unsigned id;
18829         FILE *fp = state->dbgout;
18830
18831         lr = rstate->lrd[ins->id].lr;
18832         id = ins->id;
18833         ins->id = rstate->lrd[id].orig_id;
18834         SET_REG(ins->id, lr->color);
18835         display_triple(state->dbgout, ins);
18836         ins->id = id;
18837
18838         if (lr->defs) {
18839                 struct live_range_def *lrd;
18840                 fprintf(fp, "       range:");
18841                 lrd = lr->defs;
18842                 do {
18843                         fprintf(fp, " %-10p", lrd->def);
18844                         lrd = lrd->next;
18845                 } while(lrd != lr->defs);
18846                 fprintf(fp, "\n");
18847         }
18848         if (live) {
18849                 struct triple_reg_set *entry;
18850                 fprintf(fp, "        live:");
18851                 for(entry = live; entry; entry = entry->next) {
18852                         fprintf(fp, " %-10p", entry->member);
18853                 }
18854                 fprintf(fp, "\n");
18855         }
18856         if (lr->edges) {
18857                 struct live_range_edge *entry;
18858                 fprintf(fp, "       edges:");
18859                 for(entry = lr->edges; entry; entry = entry->next) {
18860                         struct live_range_def *lrd;
18861                         lrd = entry->node->defs;
18862                         do {
18863                                 fprintf(fp, " %-10p", lrd->def);
18864                                 lrd = lrd->next;
18865                         } while(lrd != entry->node->defs);
18866                         fprintf(fp, "|");
18867                 }
18868                 fprintf(fp, "\n");
18869         }
18870         if (triple_is_branch(state, ins)) {
18871                 fprintf(fp, "\n");
18872         }
18873         return;
18874 }
18875
18876 static int coalesce_live_ranges(
18877         struct compile_state *state, struct reg_state *rstate)
18878 {
18879         /* At the point where a value is moved from one
18880          * register to another that value requires two
18881          * registers, thus increasing register pressure.
18882          * Live range coaleescing reduces the register
18883          * pressure by keeping a value in one register
18884          * longer.
18885          *
18886          * In the case of a phi function all paths leading
18887          * into it must be allocated to the same register
18888          * otherwise the phi function may not be removed.
18889          *
18890          * Forcing a value to stay in a single register
18891          * for an extended period of time does have
18892          * limitations when applied to non homogenous
18893          * register pool.  
18894          *
18895          * The two cases I have identified are:
18896          * 1) Two forced register assignments may
18897          *    collide.
18898          * 2) Registers may go unused because they
18899          *    are only good for storing the value
18900          *    and not manipulating it.
18901          *
18902          * Because of this I need to split live ranges,
18903          * even outside of the context of coalesced live
18904          * ranges.  The need to split live ranges does
18905          * impose some constraints on live range coalescing.
18906          *
18907          * - Live ranges may not be coalesced across phi
18908          *   functions.  This creates a 2 headed live
18909          *   range that cannot be sanely split.
18910          *
18911          * - phi functions (coalesced in initialize_live_ranges) 
18912          *   are handled as pre split live ranges so we will
18913          *   never attempt to split them.
18914          */
18915         int coalesced;
18916         int i;
18917
18918         coalesced = 0;
18919         for(i = 0; i <= rstate->ranges; i++) {
18920                 struct live_range *lr1;
18921                 struct live_range_def *lrd1;
18922                 lr1 = &rstate->lr[i];
18923                 if (!lr1->defs) {
18924                         continue;
18925                 }
18926                 lrd1 = live_range_end(state, lr1, 0);
18927                 for(; lrd1; lrd1 = live_range_end(state, lr1, lrd1)) {
18928                         struct triple_set *set;
18929                         if (lrd1->def->op != OP_COPY) {
18930                                 continue;
18931                         }
18932                         /* Skip copies that are the result of a live range split. */
18933                         if (lrd1->orig_id & TRIPLE_FLAG_POST_SPLIT) {
18934                                 continue;
18935                         }
18936                         for(set = lrd1->def->use; set; set = set->next) {
18937                                 struct live_range_def *lrd2;
18938                                 struct live_range *lr2, *res;
18939
18940                                 lrd2 = &rstate->lrd[set->member->id];
18941
18942                                 /* Don't coalesce with instructions
18943                                  * that are the result of a live range
18944                                  * split.
18945                                  */
18946                                 if (lrd2->orig_id & TRIPLE_FLAG_PRE_SPLIT) {
18947                                         continue;
18948                                 }
18949                                 lr2 = rstate->lrd[set->member->id].lr;
18950                                 if (lr1 == lr2) {
18951                                         continue;
18952                                 }
18953                                 if ((lr1->color != lr2->color) &&
18954                                         (lr1->color != REG_UNSET) &&
18955                                         (lr2->color != REG_UNSET)) {
18956                                         continue;
18957                                 }
18958                                 if ((lr1->classes & lr2->classes) == 0) {
18959                                         continue;
18960                                 }
18961                                 
18962                                 if (interfere(rstate, lr1, lr2)) {
18963                                         continue;
18964                                 }
18965
18966                                 res = coalesce_ranges(state, rstate, lr1, lr2);
18967                                 coalesced += 1;
18968                                 if (res != lr1) {
18969                                         goto next;
18970                                 }
18971                         }
18972                 }
18973         next:
18974                 ;
18975         }
18976         return coalesced;
18977 }
18978
18979
18980 static void fix_coalesce_conflicts(struct compile_state *state,
18981         struct reg_block *blocks, struct triple_reg_set *live,
18982         struct reg_block *rb, struct triple *ins, void *arg)
18983 {
18984         int *conflicts = arg;
18985         int zlhs, zrhs, i, j;
18986
18987         /* See if we have a mandatory coalesce operation between
18988          * a lhs and a rhs value.  If so and the rhs value is also
18989          * alive then this triple needs to be pre copied.  Otherwise
18990          * we would have two definitions in the same live range simultaneously
18991          * alive.
18992          */
18993         zlhs = ins->lhs;
18994         if ((zlhs == 0) && triple_is_def(state, ins)) {
18995                 zlhs = 1;
18996         }
18997         zrhs = ins->rhs;
18998         for(i = 0; i < zlhs; i++) {
18999                 struct reg_info linfo;
19000                 linfo = arch_reg_lhs(state, ins, i);
19001                 if (linfo.reg < MAX_REGISTERS) {
19002                         continue;
19003                 }
19004                 for(j = 0; j < zrhs; j++) {
19005                         struct reg_info rinfo;
19006                         struct triple *rhs;
19007                         struct triple_reg_set *set;
19008                         int found;
19009                         found = 0;
19010                         rinfo = arch_reg_rhs(state, ins, j);
19011                         if (rinfo.reg != linfo.reg) {
19012                                 continue;
19013                         }
19014                         rhs = RHS(ins, j);
19015                         for(set = live; set && !found; set = set->next) {
19016                                 if (set->member == rhs) {
19017                                         found = 1;
19018                                 }
19019                         }
19020                         if (found) {
19021                                 struct triple *copy;
19022                                 copy = pre_copy(state, ins, j);
19023                                 copy->id |= TRIPLE_FLAG_PRE_SPLIT;
19024                                 (*conflicts)++;
19025                         }
19026                 }
19027         }
19028         return;
19029 }
19030
19031 static int correct_coalesce_conflicts(
19032         struct compile_state *state, struct reg_block *blocks)
19033 {
19034         int conflicts;
19035         conflicts = 0;
19036         walk_variable_lifetimes(state, &state->bb, blocks, 
19037                 fix_coalesce_conflicts, &conflicts);
19038         return conflicts;
19039 }
19040
19041 static void replace_set_use(struct compile_state *state,
19042         struct triple_reg_set *head, struct triple *orig, struct triple *new)
19043 {
19044         struct triple_reg_set *set;
19045         for(set = head; set; set = set->next) {
19046                 if (set->member == orig) {
19047                         set->member = new;
19048                 }
19049         }
19050 }
19051
19052 static void replace_block_use(struct compile_state *state, 
19053         struct reg_block *blocks, struct triple *orig, struct triple *new)
19054 {
19055         int i;
19056 #warning "WISHLIST visit just those blocks that need it *"
19057         for(i = 1; i <= state->bb.last_vertex; i++) {
19058                 struct reg_block *rb;
19059                 rb = &blocks[i];
19060                 replace_set_use(state, rb->in, orig, new);
19061                 replace_set_use(state, rb->out, orig, new);
19062         }
19063 }
19064
19065 static void color_instructions(struct compile_state *state)
19066 {
19067         struct triple *ins, *first;
19068         first = state->first;
19069         ins = first;
19070         do {
19071                 if (triple_is_def(state, ins)) {
19072                         struct reg_info info;
19073                         info = find_lhs_color(state, ins, 0);
19074                         if (info.reg >= MAX_REGISTERS) {
19075                                 info.reg = REG_UNSET;
19076                         }
19077                         SET_INFO(ins->id, info);
19078                 }
19079                 ins = ins->next;
19080         } while(ins != first);
19081 }
19082
19083 static struct reg_info read_lhs_color(
19084         struct compile_state *state, struct triple *ins, int index)
19085 {
19086         struct reg_info info;
19087         if ((index == 0) && triple_is_def(state, ins)) {
19088                 info.reg   = ID_REG(ins->id);
19089                 info.regcm = ID_REGCM(ins->id);
19090         }
19091         else if (index < ins->lhs) {
19092                 info = read_lhs_color(state, LHS(ins, index), 0);
19093         }
19094         else {
19095                 internal_error(state, ins, "Bad lhs %d", index);
19096                 info.reg = REG_UNSET;
19097                 info.regcm = 0;
19098         }
19099         return info;
19100 }
19101
19102 static struct triple *resolve_tangle(
19103         struct compile_state *state, struct triple *tangle)
19104 {
19105         struct reg_info info, uinfo;
19106         struct triple_set *set, *next;
19107         struct triple *copy;
19108
19109 #warning "WISHLIST recalculate all affected instructions colors"
19110         info = find_lhs_color(state, tangle, 0);
19111         for(set = tangle->use; set; set = next) {
19112                 struct triple *user;
19113                 int i, zrhs;
19114                 next = set->next;
19115                 user = set->member;
19116                 zrhs = user->rhs;
19117                 for(i = 0; i < zrhs; i++) {
19118                         if (RHS(user, i) != tangle) {
19119                                 continue;
19120                         }
19121                         uinfo = find_rhs_post_color(state, user, i);
19122                         if (uinfo.reg == info.reg) {
19123                                 copy = pre_copy(state, user, i);
19124                                 copy->id |= TRIPLE_FLAG_PRE_SPLIT;
19125                                 SET_INFO(copy->id, uinfo);
19126                         }
19127                 }
19128         }
19129         copy = 0;
19130         uinfo = find_lhs_pre_color(state, tangle, 0);
19131         if (uinfo.reg == info.reg) {
19132                 struct reg_info linfo;
19133                 copy = post_copy(state, tangle);
19134                 copy->id |= TRIPLE_FLAG_PRE_SPLIT;
19135                 linfo = find_lhs_color(state, copy, 0);
19136                 SET_INFO(copy->id, linfo);
19137         }
19138         info = find_lhs_color(state, tangle, 0);
19139         SET_INFO(tangle->id, info);
19140         
19141         return copy;
19142 }
19143
19144
19145 static void fix_tangles(struct compile_state *state,
19146         struct reg_block *blocks, struct triple_reg_set *live,
19147         struct reg_block *rb, struct triple *ins, void *arg)
19148 {
19149         int *tangles = arg;
19150         struct triple *tangle;
19151         do {
19152                 char used[MAX_REGISTERS];
19153                 struct triple_reg_set *set;
19154                 tangle = 0;
19155
19156                 /* Find out which registers have multiple uses at this point */
19157                 memset(used, 0, sizeof(used));
19158                 for(set = live; set; set = set->next) {
19159                         struct reg_info info;
19160                         info = read_lhs_color(state, set->member, 0);
19161                         if (info.reg == REG_UNSET) {
19162                                 continue;
19163                         }
19164                         reg_inc_used(state, used, info.reg);
19165                 }
19166                 
19167                 /* Now find the least dominated definition of a register in
19168                  * conflict I have seen so far.
19169                  */
19170                 for(set = live; set; set = set->next) {
19171                         struct reg_info info;
19172                         info = read_lhs_color(state, set->member, 0);
19173                         if (used[info.reg] < 2) {
19174                                 continue;
19175                         }
19176                         /* Changing copies that feed into phi functions
19177                          * is incorrect.
19178                          */
19179                         if (set->member->use && 
19180                                 (set->member->use->member->op == OP_PHI)) {
19181                                 continue;
19182                         }
19183                         if (!tangle || tdominates(state, set->member, tangle)) {
19184                                 tangle = set->member;
19185                         }
19186                 }
19187                 /* If I have found a tangle resolve it */
19188                 if (tangle) {
19189                         struct triple *post_copy;
19190                         (*tangles)++;
19191                         post_copy = resolve_tangle(state, tangle);
19192                         if (post_copy) {
19193                                 replace_block_use(state, blocks, tangle, post_copy);
19194                         }
19195                         if (post_copy && (tangle != ins)) {
19196                                 replace_set_use(state, live, tangle, post_copy);
19197                         }
19198                 }
19199         } while(tangle);
19200         return;
19201 }
19202
19203 static int correct_tangles(
19204         struct compile_state *state, struct reg_block *blocks)
19205 {
19206         int tangles;
19207         tangles = 0;
19208         color_instructions(state);
19209         walk_variable_lifetimes(state, &state->bb, blocks, 
19210                 fix_tangles, &tangles);
19211         return tangles;
19212 }
19213
19214
19215 static void ids_from_rstate(struct compile_state *state, struct reg_state *rstate);
19216 static void cleanup_rstate(struct compile_state *state, struct reg_state *rstate);
19217
19218 struct triple *find_constrained_def(
19219         struct compile_state *state, struct live_range *range, struct triple *constrained)
19220 {
19221         struct live_range_def *lrd, *lrd_next;
19222         lrd_next = range->defs;
19223         do {
19224                 struct reg_info info;
19225                 unsigned regcm;
19226
19227                 lrd = lrd_next;
19228                 lrd_next = lrd->next;
19229
19230                 regcm = arch_type_to_regcm(state, lrd->def->type);
19231                 info = find_lhs_color(state, lrd->def, 0);
19232                 regcm      = arch_regcm_reg_normalize(state, regcm);
19233                 info.regcm = arch_regcm_reg_normalize(state, info.regcm);
19234                 /* If the 2 register class masks are equal then
19235                  * the current register class is not constrained.
19236                  */
19237                 if (regcm == info.regcm) {
19238                         continue;
19239                 }
19240                 
19241                 /* If there is just one use.
19242                  * That use cannot accept a larger register class.
19243                  * There are no intervening definitions except
19244                  * definitions that feed into that use.
19245                  * Then a triple is not constrained.
19246                  * FIXME handle this case!
19247                  */
19248 #warning "FIXME ignore cases that cannot be fixed (a definition followed by a use)"
19249                 
19250
19251                 /* Of the constrained live ranges deal with the
19252                  * least dominated one first.
19253                  */
19254                 if (state->compiler->debug & DEBUG_RANGE_CONFLICTS) {
19255                         fprintf(state->errout, "canidate: %p %-8s regcm: %x %x\n",
19256                                 lrd->def, tops(lrd->def->op), regcm, info.regcm);
19257                 }
19258                 if (!constrained || 
19259                         tdominates(state, lrd->def, constrained))
19260                 {
19261                         constrained = lrd->def;
19262                 }
19263         } while(lrd_next != range->defs);
19264         return constrained;
19265 }
19266
19267 static int split_constrained_ranges(
19268         struct compile_state *state, struct reg_state *rstate, 
19269         struct live_range *range)
19270 {
19271         /* Walk through the edges in conflict and our current live
19272          * range, and find definitions that are more severly constrained
19273          * than they type of data they contain require.
19274          * 
19275          * Then pick one of those ranges and relax the constraints.
19276          */
19277         struct live_range_edge *edge;
19278         struct triple *constrained;
19279
19280         constrained = 0;
19281         for(edge = range->edges; edge; edge = edge->next) {
19282                 constrained = find_constrained_def(state, edge->node, constrained);
19283         }
19284 #warning "FIXME should I call find_constrained_def here only if no previous constrained def was found?"
19285         if (!constrained) {
19286                 constrained = find_constrained_def(state, range, constrained);
19287         }
19288
19289         if (state->compiler->debug & DEBUG_RANGE_CONFLICTS) {
19290                 fprintf(state->errout, "constrained: ");
19291                 display_triple(state->errout, constrained);
19292         }
19293         if (constrained) {
19294                 ids_from_rstate(state, rstate);
19295                 cleanup_rstate(state, rstate);
19296                 resolve_tangle(state, constrained);
19297         }
19298         return !!constrained;
19299 }
19300         
19301 static int split_ranges(
19302         struct compile_state *state, struct reg_state *rstate,
19303         char *used, struct live_range *range)
19304 {
19305         int split;
19306         if (state->compiler->debug & DEBUG_RANGE_CONFLICTS) {
19307                 fprintf(state->errout, "split_ranges %d %s %p\n", 
19308                         rstate->passes, tops(range->defs->def->op), range->defs->def);
19309         }
19310         if ((range->color == REG_UNNEEDED) ||
19311                 (rstate->passes >= rstate->max_passes)) {
19312                 return 0;
19313         }
19314         split = split_constrained_ranges(state, rstate, range);
19315
19316         /* Ideally I would split the live range that will not be used
19317          * for the longest period of time in hopes that this will 
19318          * (a) allow me to spill a register or
19319          * (b) allow me to place a value in another register.
19320          *
19321          * So far I don't have a test case for this, the resolving
19322          * of mandatory constraints has solved all of my
19323          * know issues.  So I have choosen not to write any
19324          * code until I cat get a better feel for cases where
19325          * it would be useful to have.
19326          *
19327          */
19328 #warning "WISHLIST implement live range splitting..."
19329         
19330         if (!split && (state->compiler->debug & DEBUG_RANGE_CONFLICTS2)) {
19331                 FILE *fp = state->errout;
19332                 print_interference_blocks(state, rstate, fp, 0);
19333                 print_dominators(state, fp, &state->bb);
19334         }
19335         return split;
19336 }
19337
19338 static FILE *cgdebug_fp(struct compile_state *state)
19339 {
19340         FILE *fp;
19341         fp = 0;
19342         if (!fp && (state->compiler->debug & DEBUG_COLOR_GRAPH2)) {
19343                 fp = state->errout;
19344         }
19345         if (!fp && (state->compiler->debug & DEBUG_COLOR_GRAPH)) {
19346                 fp = state->dbgout;
19347         }
19348         return fp;
19349 }
19350
19351 static void cgdebug_printf(struct compile_state *state, const char *fmt, ...)
19352 {
19353         FILE *fp;
19354         fp = cgdebug_fp(state);
19355         if (fp) {
19356                 va_list args;
19357                 va_start(args, fmt);
19358                 vfprintf(fp, fmt, args);
19359                 va_end(args);
19360         }
19361 }
19362
19363 static void cgdebug_flush(struct compile_state *state)
19364 {
19365         FILE *fp;
19366         fp = cgdebug_fp(state);
19367         if (fp) {
19368                 fflush(fp);
19369         }
19370 }
19371
19372 static void cgdebug_loc(struct compile_state *state, struct triple *ins)
19373 {
19374         FILE *fp;
19375         fp = cgdebug_fp(state);
19376         if (fp) {
19377                 loc(fp, state, ins);
19378         }
19379 }
19380
19381 static int select_free_color(struct compile_state *state, 
19382         struct reg_state *rstate, struct live_range *range)
19383 {
19384         struct triple_set *entry;
19385         struct live_range_def *lrd;
19386         struct live_range_def *phi;
19387         struct live_range_edge *edge;
19388         char used[MAX_REGISTERS];
19389         struct triple **expr;
19390
19391         /* Instead of doing just the trivial color select here I try
19392          * a few extra things because a good color selection will help reduce
19393          * copies.
19394          */
19395
19396         /* Find the registers currently in use */
19397         memset(used, 0, sizeof(used));
19398         for(edge = range->edges; edge; edge = edge->next) {
19399                 if (edge->node->color == REG_UNSET) {
19400                         continue;
19401                 }
19402                 reg_fill_used(state, used, edge->node->color);
19403         }
19404
19405         if (state->compiler->debug & DEBUG_COLOR_GRAPH2) {
19406                 int i;
19407                 i = 0;
19408                 for(edge = range->edges; edge; edge = edge->next) {
19409                         i++;
19410                 }
19411                 cgdebug_printf(state, "\n%s edges: %d", 
19412                         tops(range->defs->def->op), i);
19413                 cgdebug_loc(state, range->defs->def);
19414                 cgdebug_printf(state, "\n");
19415                 for(i = 0; i < MAX_REGISTERS; i++) {
19416                         if (used[i]) {
19417                                 cgdebug_printf(state, "used: %s\n",
19418                                         arch_reg_str(i));
19419                         }
19420                 }
19421         }       
19422
19423         /* If a color is already assigned see if it will work */
19424         if (range->color != REG_UNSET) {
19425                 struct live_range_def *lrd;
19426                 if (!used[range->color]) {
19427                         return 1;
19428                 }
19429                 for(edge = range->edges; edge; edge = edge->next) {
19430                         if (edge->node->color != range->color) {
19431                                 continue;
19432                         }
19433                         warning(state, edge->node->defs->def, "edge: ");
19434                         lrd = edge->node->defs;
19435                         do {
19436                                 warning(state, lrd->def, " %p %s",
19437                                         lrd->def, tops(lrd->def->op));
19438                                 lrd = lrd->next;
19439                         } while(lrd != edge->node->defs);
19440                 }
19441                 lrd = range->defs;
19442                 warning(state, range->defs->def, "def: ");
19443                 do {
19444                         warning(state, lrd->def, " %p %s",
19445                                 lrd->def, tops(lrd->def->op));
19446                         lrd = lrd->next;
19447                 } while(lrd != range->defs);
19448                 internal_error(state, range->defs->def,
19449                         "live range with already used color %s",
19450                         arch_reg_str(range->color));
19451         }
19452
19453         /* If I feed into an expression reuse it's color.
19454          * This should help remove copies in the case of 2 register instructions
19455          * and phi functions.
19456          */
19457         phi = 0;
19458         lrd = live_range_end(state, range, 0);
19459         for(; (range->color == REG_UNSET) && lrd ; lrd = live_range_end(state, range, lrd)) {
19460                 entry = lrd->def->use;
19461                 for(;(range->color == REG_UNSET) && entry; entry = entry->next) {
19462                         struct live_range_def *insd;
19463                         unsigned regcm;
19464                         insd = &rstate->lrd[entry->member->id];
19465                         if (insd->lr->defs == 0) {
19466                                 continue;
19467                         }
19468                         if (!phi && (insd->def->op == OP_PHI) &&
19469                                 !interfere(rstate, range, insd->lr)) {
19470                                 phi = insd;
19471                         }
19472                         if (insd->lr->color == REG_UNSET) {
19473                                 continue;
19474                         }
19475                         regcm = insd->lr->classes;
19476                         if (((regcm & range->classes) == 0) ||
19477                                 (used[insd->lr->color])) {
19478                                 continue;
19479                         }
19480                         if (interfere(rstate, range, insd->lr)) {
19481                                 continue;
19482                         }
19483                         range->color = insd->lr->color;
19484                 }
19485         }
19486         /* If I feed into a phi function reuse it's color or the color
19487          * of something else that feeds into the phi function.
19488          */
19489         if (phi) {
19490                 if (phi->lr->color != REG_UNSET) {
19491                         if (used[phi->lr->color]) {
19492                                 range->color = phi->lr->color;
19493                         }
19494                 }
19495                 else {
19496                         expr = triple_rhs(state, phi->def, 0);
19497                         for(; expr; expr = triple_rhs(state, phi->def, expr)) {
19498                                 struct live_range *lr;
19499                                 unsigned regcm;
19500                                 if (!*expr) {
19501                                         continue;
19502                                 }
19503                                 lr = rstate->lrd[(*expr)->id].lr;
19504                                 if (lr->color == REG_UNSET) {
19505                                         continue;
19506                                 }
19507                                 regcm = lr->classes;
19508                                 if (((regcm & range->classes) == 0) ||
19509                                         (used[lr->color])) {
19510                                         continue;
19511                                 }
19512                                 if (interfere(rstate, range, lr)) {
19513                                         continue;
19514                                 }
19515                                 range->color = lr->color;
19516                         }
19517                 }
19518         }
19519         /* If I don't interfere with a rhs node reuse it's color */
19520         lrd = live_range_head(state, range, 0);
19521         for(; (range->color == REG_UNSET) && lrd ; lrd = live_range_head(state, range, lrd)) {
19522                 expr = triple_rhs(state, lrd->def, 0);
19523                 for(; expr; expr = triple_rhs(state, lrd->def, expr)) {
19524                         struct live_range *lr;
19525                         unsigned regcm;
19526                         if (!*expr) {
19527                                 continue;
19528                         }
19529                         lr = rstate->lrd[(*expr)->id].lr;
19530                         if (lr->color == REG_UNSET) {
19531                                 continue;
19532                         }
19533                         regcm = lr->classes;
19534                         if (((regcm & range->classes) == 0) ||
19535                                 (used[lr->color])) {
19536                                 continue;
19537                         }
19538                         if (interfere(rstate, range, lr)) {
19539                                 continue;
19540                         }
19541                         range->color = lr->color;
19542                         break;
19543                 }
19544         }
19545         /* If I have not opportunitically picked a useful color
19546          * pick the first color that is free.
19547          */
19548         if (range->color == REG_UNSET) {
19549                 range->color = 
19550                         arch_select_free_register(state, used, range->classes);
19551         }
19552         if (range->color == REG_UNSET) {
19553                 struct live_range_def *lrd;
19554                 int i;
19555                 if (split_ranges(state, rstate, used, range)) {
19556                         return 0;
19557                 }
19558                 for(edge = range->edges; edge; edge = edge->next) {
19559                         warning(state, edge->node->defs->def, "edge reg %s",
19560                                 arch_reg_str(edge->node->color));
19561                         lrd = edge->node->defs;
19562                         do {
19563                                 warning(state, lrd->def, " %s %p",
19564                                         tops(lrd->def->op), lrd->def);
19565                                 lrd = lrd->next;
19566                         } while(lrd != edge->node->defs);
19567                 }
19568                 warning(state, range->defs->def, "range: ");
19569                 lrd = range->defs;
19570                 do {
19571                         warning(state, lrd->def, " %s %p",
19572                                 tops(lrd->def->op), lrd->def);
19573                         lrd = lrd->next;
19574                 } while(lrd != range->defs);
19575                         
19576                 warning(state, range->defs->def, "classes: %x",
19577                         range->classes);
19578                 for(i = 0; i < MAX_REGISTERS; i++) {
19579                         if (used[i]) {
19580                                 warning(state, range->defs->def, "used: %s",
19581                                         arch_reg_str(i));
19582                         }
19583                 }
19584                 error(state, range->defs->def, "too few registers");
19585         }
19586         range->classes &= arch_reg_regcm(state, range->color);
19587         if ((range->color == REG_UNSET) || (range->classes == 0)) {
19588                 internal_error(state, range->defs->def, "select_free_color did not?");
19589         }
19590         return 1;
19591 }
19592
19593 static int color_graph(struct compile_state *state, struct reg_state *rstate)
19594 {
19595         int colored;
19596         struct live_range_edge *edge;
19597         struct live_range *range;
19598         if (rstate->low) {
19599                 cgdebug_printf(state, "Lo: ");
19600                 range = rstate->low;
19601                 if (*range->group_prev != range) {
19602                         internal_error(state, 0, "lo: *prev != range?");
19603                 }
19604                 *range->group_prev = range->group_next;
19605                 if (range->group_next) {
19606                         range->group_next->group_prev = range->group_prev;
19607                 }
19608                 if (&range->group_next == rstate->low_tail) {
19609                         rstate->low_tail = range->group_prev;
19610                 }
19611                 if (rstate->low == range) {
19612                         internal_error(state, 0, "low: next != prev?");
19613                 }
19614         }
19615         else if (rstate->high) {
19616                 cgdebug_printf(state, "Hi: ");
19617                 range = rstate->high;
19618                 if (*range->group_prev != range) {
19619                         internal_error(state, 0, "hi: *prev != range?");
19620                 }
19621                 *range->group_prev = range->group_next;
19622                 if (range->group_next) {
19623                         range->group_next->group_prev = range->group_prev;
19624                 }
19625                 if (&range->group_next == rstate->high_tail) {
19626                         rstate->high_tail = range->group_prev;
19627                 }
19628                 if (rstate->high == range) {
19629                         internal_error(state, 0, "high: next != prev?");
19630                 }
19631         }
19632         else {
19633                 return 1;
19634         }
19635         cgdebug_printf(state, " %d\n", range - rstate->lr);
19636         range->group_prev = 0;
19637         for(edge = range->edges; edge; edge = edge->next) {
19638                 struct live_range *node;
19639                 node = edge->node;
19640                 /* Move nodes from the high to the low list */
19641                 if (node->group_prev && (node->color == REG_UNSET) &&
19642                         (node->degree == regc_max_size(state, node->classes))) {
19643                         if (*node->group_prev != node) {
19644                                 internal_error(state, 0, "move: *prev != node?");
19645                         }
19646                         *node->group_prev = node->group_next;
19647                         if (node->group_next) {
19648                                 node->group_next->group_prev = node->group_prev;
19649                         }
19650                         if (&node->group_next == rstate->high_tail) {
19651                                 rstate->high_tail = node->group_prev;
19652                         }
19653                         cgdebug_printf(state, "Moving...%d to low\n", node - rstate->lr);
19654                         node->group_prev  = rstate->low_tail;
19655                         node->group_next  = 0;
19656                         *rstate->low_tail = node;
19657                         rstate->low_tail  = &node->group_next;
19658                         if (*node->group_prev != node) {
19659                                 internal_error(state, 0, "move2: *prev != node?");
19660                         }
19661                 }
19662                 node->degree -= 1;
19663         }
19664         colored = color_graph(state, rstate);
19665         if (colored) {
19666                 cgdebug_printf(state, "Coloring %d @", range - rstate->lr);
19667                 cgdebug_loc(state, range->defs->def);
19668                 cgdebug_flush(state);
19669                 colored = select_free_color(state, rstate, range);
19670                 if (colored) {
19671                         cgdebug_printf(state, " %s\n", arch_reg_str(range->color));
19672                 }
19673         }
19674         return colored;
19675 }
19676
19677 static void verify_colors(struct compile_state *state, struct reg_state *rstate)
19678 {
19679         struct live_range *lr;
19680         struct live_range_edge *edge;
19681         struct triple *ins, *first;
19682         char used[MAX_REGISTERS];
19683         first = state->first;
19684         ins = first;
19685         do {
19686                 if (triple_is_def(state, ins)) {
19687                         if ((ins->id < 0) || (ins->id > rstate->defs)) {
19688                                 internal_error(state, ins, 
19689                                         "triple without a live range def");
19690                         }
19691                         lr = rstate->lrd[ins->id].lr;
19692                         if (lr->color == REG_UNSET) {
19693                                 internal_error(state, ins,
19694                                         "triple without a color");
19695                         }
19696                         /* Find the registers used by the edges */
19697                         memset(used, 0, sizeof(used));
19698                         for(edge = lr->edges; edge; edge = edge->next) {
19699                                 if (edge->node->color == REG_UNSET) {
19700                                         internal_error(state, 0,
19701                                                 "live range without a color");
19702                         }
19703                                 reg_fill_used(state, used, edge->node->color);
19704                         }
19705                         if (used[lr->color]) {
19706                                 internal_error(state, ins,
19707                                         "triple with already used color");
19708                         }
19709                 }
19710                 ins = ins->next;
19711         } while(ins != first);
19712 }
19713
19714 static void color_triples(struct compile_state *state, struct reg_state *rstate)
19715 {
19716         struct live_range_def *lrd;
19717         struct live_range *lr;
19718         struct triple *first, *ins;
19719         first = state->first;
19720         ins = first;
19721         do {
19722                 if ((ins->id < 0) || (ins->id > rstate->defs)) {
19723                         internal_error(state, ins, 
19724                                 "triple without a live range");
19725                 }
19726                 lrd = &rstate->lrd[ins->id];
19727                 lr = lrd->lr;
19728                 ins->id = lrd->orig_id;
19729                 SET_REG(ins->id, lr->color);
19730                 ins = ins->next;
19731         } while (ins != first);
19732 }
19733
19734 static struct live_range *merge_sort_lr(
19735         struct live_range *first, struct live_range *last)
19736 {
19737         struct live_range *mid, *join, **join_tail, *pick;
19738         size_t size;
19739         size = (last - first) + 1;
19740         if (size >= 2) {
19741                 mid = first + size/2;
19742                 first = merge_sort_lr(first, mid -1);
19743                 mid   = merge_sort_lr(mid, last);
19744                 
19745                 join = 0;
19746                 join_tail = &join;
19747                 /* merge the two lists */
19748                 while(first && mid) {
19749                         if ((first->degree < mid->degree) ||
19750                                 ((first->degree == mid->degree) &&
19751                                         (first->length < mid->length))) {
19752                                 pick = first;
19753                                 first = first->group_next;
19754                                 if (first) {
19755                                         first->group_prev = 0;
19756                                 }
19757                         }
19758                         else {
19759                                 pick = mid;
19760                                 mid = mid->group_next;
19761                                 if (mid) {
19762                                         mid->group_prev = 0;
19763                                 }
19764                         }
19765                         pick->group_next = 0;
19766                         pick->group_prev = join_tail;
19767                         *join_tail = pick;
19768                         join_tail = &pick->group_next;
19769                 }
19770                 /* Splice the remaining list */
19771                 pick = (first)? first : mid;
19772                 *join_tail = pick;
19773                 if (pick) { 
19774                         pick->group_prev = join_tail;
19775                 }
19776         }
19777         else {
19778                 if (!first->defs) {
19779                         first = 0;
19780                 }
19781                 join = first;
19782         }
19783         return join;
19784 }
19785
19786 static void ids_from_rstate(struct compile_state *state, 
19787         struct reg_state *rstate)
19788 {
19789         struct triple *ins, *first;
19790         if (!rstate->defs) {
19791                 return;
19792         }
19793         /* Display the graph if desired */
19794         if (state->compiler->debug & DEBUG_INTERFERENCE) {
19795                 FILE *fp = state->dbgout;
19796                 print_interference_blocks(state, rstate, fp, 0);
19797                 print_control_flow(state, fp, &state->bb);
19798                 fflush(fp);
19799         }
19800         first = state->first;
19801         ins = first;
19802         do {
19803                 if (ins->id) {
19804                         struct live_range_def *lrd;
19805                         lrd = &rstate->lrd[ins->id];
19806                         ins->id = lrd->orig_id;
19807                 }
19808                 ins = ins->next;
19809         } while(ins != first);
19810 }
19811
19812 static void cleanup_live_edges(struct reg_state *rstate)
19813 {
19814         int i;
19815         /* Free the edges on each node */
19816         for(i = 1; i <= rstate->ranges; i++) {
19817                 remove_live_edges(rstate, &rstate->lr[i]);
19818         }
19819 }
19820
19821 static void cleanup_rstate(struct compile_state *state, struct reg_state *rstate)
19822 {
19823         cleanup_live_edges(rstate);
19824         xfree(rstate->lrd);
19825         xfree(rstate->lr);
19826
19827         /* Free the variable lifetime information */
19828         if (rstate->blocks) {
19829                 free_variable_lifetimes(state, &state->bb, rstate->blocks);
19830         }
19831         rstate->defs = 0;
19832         rstate->ranges = 0;
19833         rstate->lrd = 0;
19834         rstate->lr = 0;
19835         rstate->blocks = 0;
19836 }
19837
19838 static void verify_consistency(struct compile_state *state);
19839 static void allocate_registers(struct compile_state *state)
19840 {
19841         struct reg_state rstate;
19842         int colored;
19843
19844         /* Clear out the reg_state */
19845         memset(&rstate, 0, sizeof(rstate));
19846         rstate.max_passes = state->compiler->max_allocation_passes;
19847
19848         do {
19849                 struct live_range **point, **next;
19850                 int conflicts;
19851                 int tangles;
19852                 int coalesced;
19853
19854                 if (state->compiler->debug & DEBUG_RANGE_CONFLICTS) {
19855                         FILE *fp = state->errout;
19856                         fprintf(fp, "pass: %d\n", rstate.passes);
19857                         fflush(fp);
19858                 }
19859
19860                 /* Restore ids */
19861                 ids_from_rstate(state, &rstate);
19862
19863                 /* Cleanup the temporary data structures */
19864                 cleanup_rstate(state, &rstate);
19865
19866                 /* Compute the variable lifetimes */
19867                 rstate.blocks = compute_variable_lifetimes(state, &state->bb);
19868
19869                 /* Fix invalid mandatory live range coalesce conflicts */
19870                 conflicts = correct_coalesce_conflicts(state, rstate.blocks);
19871
19872                 /* Fix two simultaneous uses of the same register.
19873                  * In a few pathlogical cases a partial untangle moves
19874                  * the tangle to a part of the graph we won't revisit.
19875                  * So we keep looping until we have no more tangle fixes
19876                  * to apply.
19877                  */
19878                 do {
19879                         tangles = correct_tangles(state, rstate.blocks);
19880                 } while(tangles);
19881
19882                 
19883                 print_blocks(state, "resolve_tangles", state->dbgout);
19884                 verify_consistency(state);
19885                 
19886                 /* Allocate and initialize the live ranges */
19887                 initialize_live_ranges(state, &rstate);
19888
19889                 /* Note currently doing coalescing in a loop appears to 
19890                  * buys me nothing.  The code is left this way in case
19891                  * there is some value in it.  Or if a future bugfix
19892                  * yields some benefit.
19893                  */
19894                 do {
19895                         if (state->compiler->debug & DEBUG_COALESCING) {
19896                                 fprintf(state->errout, "coalescing\n");
19897                         }
19898
19899                         /* Remove any previous live edge calculations */
19900                         cleanup_live_edges(&rstate);
19901
19902                         /* Compute the interference graph */
19903                         walk_variable_lifetimes(
19904                                 state, &state->bb, rstate.blocks, 
19905                                 graph_ins, &rstate);
19906                         
19907                         /* Display the interference graph if desired */
19908                         if (state->compiler->debug & DEBUG_INTERFERENCE) {
19909                                 print_interference_blocks(state, &rstate, state->dbgout, 1);
19910                                 fprintf(state->dbgout, "\nlive variables by instruction\n");
19911                                 walk_variable_lifetimes(
19912                                         state, &state->bb, rstate.blocks, 
19913                                         print_interference_ins, &rstate);
19914                         }
19915                         
19916                         coalesced = coalesce_live_ranges(state, &rstate);
19917
19918                         if (state->compiler->debug & DEBUG_COALESCING) {
19919                                 fprintf(state->errout, "coalesced: %d\n", coalesced);
19920                         }
19921                 } while(coalesced);
19922
19923 #if DEBUG_CONSISTENCY > 1
19924 # if 0
19925                 fprintf(state->errout, "verify_graph_ins...\n");
19926 # endif
19927                 /* Verify the interference graph */
19928                 walk_variable_lifetimes(
19929                         state, &state->bb, rstate.blocks, 
19930                         verify_graph_ins, &rstate);
19931 # if 0
19932                 fprintf(state->errout, "verify_graph_ins done\n");
19933 #endif
19934 #endif
19935                         
19936                 /* Build the groups low and high.  But with the nodes
19937                  * first sorted by degree order.
19938                  */
19939                 rstate.low_tail  = &rstate.low;
19940                 rstate.high_tail = &rstate.high;
19941                 rstate.high = merge_sort_lr(&rstate.lr[1], &rstate.lr[rstate.ranges]);
19942                 if (rstate.high) {
19943                         rstate.high->group_prev = &rstate.high;
19944                 }
19945                 for(point = &rstate.high; *point; point = &(*point)->group_next)
19946                         ;
19947                 rstate.high_tail = point;
19948                 /* Walk through the high list and move everything that needs
19949                  * to be onto low.
19950                  */
19951                 for(point = &rstate.high; *point; point = next) {
19952                         struct live_range *range;
19953                         next = &(*point)->group_next;
19954                         range = *point;
19955                         
19956                         /* If it has a low degree or it already has a color
19957                          * place the node in low.
19958                          */
19959                         if ((range->degree < regc_max_size(state, range->classes)) ||
19960                                 (range->color != REG_UNSET)) {
19961                                 cgdebug_printf(state, "Lo: %5d degree %5d%s\n", 
19962                                         range - rstate.lr, range->degree,
19963                                         (range->color != REG_UNSET) ? " (colored)": "");
19964                                 *range->group_prev = range->group_next;
19965                                 if (range->group_next) {
19966                                         range->group_next->group_prev = range->group_prev;
19967                                 }
19968                                 if (&range->group_next == rstate.high_tail) {
19969                                         rstate.high_tail = range->group_prev;
19970                                 }
19971                                 range->group_prev  = rstate.low_tail;
19972                                 range->group_next  = 0;
19973                                 *rstate.low_tail   = range;
19974                                 rstate.low_tail    = &range->group_next;
19975                                 next = point;
19976                         }
19977                         else {
19978                                 cgdebug_printf(state, "hi: %5d degree %5d%s\n", 
19979                                         range - rstate.lr, range->degree,
19980                                         (range->color != REG_UNSET) ? " (colored)": "");
19981                         }
19982                 }
19983                 /* Color the live_ranges */
19984                 colored = color_graph(state, &rstate);
19985                 rstate.passes++;
19986         } while (!colored);
19987
19988         /* Verify the graph was properly colored */
19989         verify_colors(state, &rstate);
19990
19991         /* Move the colors from the graph to the triples */
19992         color_triples(state, &rstate);
19993
19994         /* Cleanup the temporary data structures */
19995         cleanup_rstate(state, &rstate);
19996
19997         /* Display the new graph */
19998         print_blocks(state, __func__, state->dbgout);
19999 }
20000
20001 /* Sparce Conditional Constant Propogation
20002  * =========================================
20003  */
20004 struct ssa_edge;
20005 struct flow_block;
20006 struct lattice_node {
20007         unsigned old_id;
20008         struct triple *def;
20009         struct ssa_edge *out;
20010         struct flow_block *fblock;
20011         struct triple *val;
20012         /* lattice high   val == def
20013          * lattice const  is_const(val)
20014          * lattice low    other
20015          */
20016 };
20017 struct ssa_edge {
20018         struct lattice_node *src;
20019         struct lattice_node *dst;
20020         struct ssa_edge *work_next;
20021         struct ssa_edge *work_prev;
20022         struct ssa_edge *out_next;
20023 };
20024 struct flow_edge {
20025         struct flow_block *src;
20026         struct flow_block *dst;
20027         struct flow_edge *work_next;
20028         struct flow_edge *work_prev;
20029         struct flow_edge *in_next;
20030         struct flow_edge *out_next;
20031         int executable;
20032 };
20033 #define MAX_FLOW_BLOCK_EDGES 3
20034 struct flow_block {
20035         struct block *block;
20036         struct flow_edge *in;
20037         struct flow_edge *out;
20038         struct flow_edge *edges;
20039 };
20040
20041 struct scc_state {
20042         int ins_count;
20043         struct lattice_node *lattice;
20044         struct ssa_edge     *ssa_edges;
20045         struct flow_block   *flow_blocks;
20046         struct flow_edge    *flow_work_list;
20047         struct ssa_edge     *ssa_work_list;
20048 };
20049
20050
20051 static int is_scc_const(struct compile_state *state, struct triple *ins)
20052 {
20053         return ins && (triple_is_ubranch(state, ins) || is_const(ins));
20054 }
20055
20056 static int is_lattice_hi(struct compile_state *state, struct lattice_node *lnode)
20057 {
20058         return !is_scc_const(state, lnode->val) && (lnode->val == lnode->def);
20059 }
20060
20061 static int is_lattice_const(struct compile_state *state, struct lattice_node *lnode)
20062 {
20063         return is_scc_const(state, lnode->val);
20064 }
20065
20066 static int is_lattice_lo(struct compile_state *state, struct lattice_node *lnode)
20067 {
20068         return (lnode->val != lnode->def) && !is_scc_const(state, lnode->val);
20069 }
20070
20071 static void scc_add_fedge(struct compile_state *state, struct scc_state *scc, 
20072         struct flow_edge *fedge)
20073 {
20074         if (state->compiler->debug & DEBUG_SCC_TRANSFORM2) {
20075                 fprintf(state->errout, "adding fedge: %p (%4d -> %5d)\n",
20076                         fedge,
20077                         fedge->src->block?fedge->src->block->last->id: 0,
20078                         fedge->dst->block?fedge->dst->block->first->id: 0);
20079         }
20080         if ((fedge == scc->flow_work_list) ||
20081                 (fedge->work_next != fedge) ||
20082                 (fedge->work_prev != fedge)) {
20083
20084                 if (state->compiler->debug & DEBUG_SCC_TRANSFORM2) {
20085                         fprintf(state->errout, "dupped fedge: %p\n",
20086                                 fedge);
20087                 }
20088                 return;
20089         }
20090         if (!scc->flow_work_list) {
20091                 scc->flow_work_list = fedge;
20092                 fedge->work_next = fedge->work_prev = fedge;
20093         }
20094         else {
20095                 struct flow_edge *ftail;
20096                 ftail = scc->flow_work_list->work_prev;
20097                 fedge->work_next = ftail->work_next;
20098                 fedge->work_prev = ftail;
20099                 fedge->work_next->work_prev = fedge;
20100                 fedge->work_prev->work_next = fedge;
20101         }
20102 }
20103
20104 static struct flow_edge *scc_next_fedge(
20105         struct compile_state *state, struct scc_state *scc)
20106 {
20107         struct flow_edge *fedge;
20108         fedge = scc->flow_work_list;
20109         if (fedge) {
20110                 fedge->work_next->work_prev = fedge->work_prev;
20111                 fedge->work_prev->work_next = fedge->work_next;
20112                 if (fedge->work_next != fedge) {
20113                         scc->flow_work_list = fedge->work_next;
20114                 } else {
20115                         scc->flow_work_list = 0;
20116                 }
20117                 fedge->work_next = fedge->work_prev = fedge;
20118         }
20119         return fedge;
20120 }
20121
20122 static void scc_add_sedge(struct compile_state *state, struct scc_state *scc,
20123         struct ssa_edge *sedge)
20124 {
20125         if (state->compiler->debug & DEBUG_SCC_TRANSFORM2) {
20126                 fprintf(state->errout, "adding sedge: %5d (%4d -> %5d)\n",
20127                         sedge - scc->ssa_edges,
20128                         sedge->src->def->id,
20129                         sedge->dst->def->id);
20130         }
20131         if ((sedge == scc->ssa_work_list) ||
20132                 (sedge->work_next != sedge) ||
20133                 (sedge->work_prev != sedge)) {
20134
20135                 if (state->compiler->debug & DEBUG_SCC_TRANSFORM2) {
20136                         fprintf(state->errout, "dupped sedge: %5d\n",
20137                                 sedge - scc->ssa_edges);
20138                 }
20139                 return;
20140         }
20141         if (!scc->ssa_work_list) {
20142                 scc->ssa_work_list = sedge;
20143                 sedge->work_next = sedge->work_prev = sedge;
20144         }
20145         else {
20146                 struct ssa_edge *stail;
20147                 stail = scc->ssa_work_list->work_prev;
20148                 sedge->work_next = stail->work_next;
20149                 sedge->work_prev = stail;
20150                 sedge->work_next->work_prev = sedge;
20151                 sedge->work_prev->work_next = sedge;
20152         }
20153 }
20154
20155 static struct ssa_edge *scc_next_sedge(
20156         struct compile_state *state, struct scc_state *scc)
20157 {
20158         struct ssa_edge *sedge;
20159         sedge = scc->ssa_work_list;
20160         if (sedge) {
20161                 sedge->work_next->work_prev = sedge->work_prev;
20162                 sedge->work_prev->work_next = sedge->work_next;
20163                 if (sedge->work_next != sedge) {
20164                         scc->ssa_work_list = sedge->work_next;
20165                 } else {
20166                         scc->ssa_work_list = 0;
20167                 }
20168                 sedge->work_next = sedge->work_prev = sedge;
20169         }
20170         return sedge;
20171 }
20172
20173 static void initialize_scc_state(
20174         struct compile_state *state, struct scc_state *scc)
20175 {
20176         int ins_count, ssa_edge_count;
20177         int ins_index, ssa_edge_index, fblock_index;
20178         struct triple *first, *ins;
20179         struct block *block;
20180         struct flow_block *fblock;
20181
20182         memset(scc, 0, sizeof(*scc));
20183
20184         /* Inialize pass zero find out how much memory we need */
20185         first = state->first;
20186         ins = first;
20187         ins_count = ssa_edge_count = 0;
20188         do {
20189                 struct triple_set *edge;
20190                 ins_count += 1;
20191                 for(edge = ins->use; edge; edge = edge->next) {
20192                         ssa_edge_count++;
20193                 }
20194                 ins = ins->next;
20195         } while(ins != first);
20196         if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
20197                 fprintf(state->errout, "ins_count: %d ssa_edge_count: %d vertex_count: %d\n",
20198                         ins_count, ssa_edge_count, state->bb.last_vertex);
20199         }
20200         scc->ins_count   = ins_count;
20201         scc->lattice     = 
20202                 xcmalloc(sizeof(*scc->lattice)*(ins_count + 1), "lattice");
20203         scc->ssa_edges   = 
20204                 xcmalloc(sizeof(*scc->ssa_edges)*(ssa_edge_count + 1), "ssa_edges");
20205         scc->flow_blocks = 
20206                 xcmalloc(sizeof(*scc->flow_blocks)*(state->bb.last_vertex + 1), 
20207                         "flow_blocks");
20208
20209         /* Initialize pass one collect up the nodes */
20210         fblock = 0;
20211         block = 0;
20212         ins_index = ssa_edge_index = fblock_index = 0;
20213         ins = first;
20214         do {
20215                 if ((ins->op == OP_LABEL) && (block != ins->u.block)) {
20216                         block = ins->u.block;
20217                         if (!block) {
20218                                 internal_error(state, ins, "label without block");
20219                         }
20220                         fblock_index += 1;
20221                         block->vertex = fblock_index;
20222                         fblock = &scc->flow_blocks[fblock_index];
20223                         fblock->block = block;
20224                         fblock->edges = xcmalloc(sizeof(*fblock->edges)*block->edge_count,
20225                                 "flow_edges");
20226                 }
20227                 {
20228                         struct lattice_node *lnode;
20229                         ins_index += 1;
20230                         lnode = &scc->lattice[ins_index];
20231                         lnode->def = ins;
20232                         lnode->out = 0;
20233                         lnode->fblock = fblock;
20234                         lnode->val = ins; /* LATTICE HIGH */
20235                         if (lnode->val->op == OP_UNKNOWNVAL) {
20236                                 lnode->val = 0; /* LATTICE LOW by definition */
20237                         }
20238                         lnode->old_id = ins->id;
20239                         ins->id = ins_index;
20240                 }
20241                 ins = ins->next;
20242         } while(ins != first);
20243         /* Initialize pass two collect up the edges */
20244         block = 0;
20245         fblock = 0;
20246         ins = first;
20247         do {
20248                 {
20249                         struct triple_set *edge;
20250                         struct ssa_edge **stail;
20251                         struct lattice_node *lnode;
20252                         lnode = &scc->lattice[ins->id];
20253                         lnode->out = 0;
20254                         stail = &lnode->out;
20255                         for(edge = ins->use; edge; edge = edge->next) {
20256                                 struct ssa_edge *sedge;
20257                                 ssa_edge_index += 1;
20258                                 sedge = &scc->ssa_edges[ssa_edge_index];
20259                                 *stail = sedge;
20260                                 stail = &sedge->out_next;
20261                                 sedge->src = lnode;
20262                                 sedge->dst = &scc->lattice[edge->member->id];
20263                                 sedge->work_next = sedge->work_prev = sedge;
20264                                 sedge->out_next = 0;
20265                         }
20266                 }
20267                 if ((ins->op == OP_LABEL) && (block != ins->u.block)) {
20268                         struct flow_edge *fedge, **ftail;
20269                         struct block_set *bedge;
20270                         block = ins->u.block;
20271                         fblock = &scc->flow_blocks[block->vertex];
20272                         fblock->in = 0;
20273                         fblock->out = 0;
20274                         ftail = &fblock->out;
20275
20276                         fedge = fblock->edges;
20277                         bedge = block->edges;
20278                         for(; bedge; bedge = bedge->next, fedge++) {
20279                                 fedge->dst = &scc->flow_blocks[bedge->member->vertex];
20280                                 if (fedge->dst->block != bedge->member) {
20281                                         internal_error(state, 0, "block mismatch");
20282                                 }
20283                                 *ftail = fedge;
20284                                 ftail = &fedge->out_next;
20285                                 fedge->out_next = 0;
20286                         }
20287                         for(fedge = fblock->out; fedge; fedge = fedge->out_next) {
20288                                 fedge->src = fblock;
20289                                 fedge->work_next = fedge->work_prev = fedge;
20290                                 fedge->executable = 0;
20291                         }
20292                 }
20293                 ins = ins->next;
20294         } while (ins != first);
20295         block = 0;
20296         fblock = 0;
20297         ins = first;
20298         do {
20299                 if ((ins->op  == OP_LABEL) && (block != ins->u.block)) {
20300                         struct flow_edge **ftail;
20301                         struct block_set *bedge;
20302                         block = ins->u.block;
20303                         fblock = &scc->flow_blocks[block->vertex];
20304                         ftail = &fblock->in;
20305                         for(bedge = block->use; bedge; bedge = bedge->next) {
20306                                 struct block *src_block;
20307                                 struct flow_block *sfblock;
20308                                 struct flow_edge *sfedge;
20309                                 src_block = bedge->member;
20310                                 sfblock = &scc->flow_blocks[src_block->vertex];
20311                                 for(sfedge = sfblock->out; sfedge; sfedge = sfedge->out_next) {
20312                                         if (sfedge->dst == fblock) {
20313                                                 break;
20314                                         }
20315                                 }
20316                                 if (!sfedge) {
20317                                         internal_error(state, 0, "edge mismatch");
20318                                 }
20319                                 *ftail = sfedge;
20320                                 ftail = &sfedge->in_next;
20321                                 sfedge->in_next = 0;
20322                         }
20323                 }
20324                 ins = ins->next;
20325         } while(ins != first);
20326         /* Setup a dummy block 0 as a node above the start node */
20327         {
20328                 struct flow_block *fblock, *dst;
20329                 struct flow_edge *fedge;
20330                 fblock = &scc->flow_blocks[0];
20331                 fblock->block = 0;
20332                 fblock->edges = xcmalloc(sizeof(*fblock->edges)*1, "flow_edges");
20333                 fblock->in = 0;
20334                 fblock->out = fblock->edges;
20335                 dst = &scc->flow_blocks[state->bb.first_block->vertex];
20336                 fedge = fblock->edges;
20337                 fedge->src        = fblock;
20338                 fedge->dst        = dst;
20339                 fedge->work_next  = fedge;
20340                 fedge->work_prev  = fedge;
20341                 fedge->in_next    = fedge->dst->in;
20342                 fedge->out_next   = 0;
20343                 fedge->executable = 0;
20344                 fedge->dst->in = fedge;
20345                 
20346                 /* Initialize the work lists */
20347                 scc->flow_work_list = 0;
20348                 scc->ssa_work_list  = 0;
20349                 scc_add_fedge(state, scc, fedge);
20350         }
20351         if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
20352                 fprintf(state->errout, "ins_index: %d ssa_edge_index: %d fblock_index: %d\n",
20353                         ins_index, ssa_edge_index, fblock_index);
20354         }
20355 }
20356
20357         
20358 static void free_scc_state(
20359         struct compile_state *state, struct scc_state *scc)
20360 {
20361         int i;
20362         for(i = 0; i < state->bb.last_vertex + 1; i++) {
20363                 struct flow_block *fblock;
20364                 fblock = &scc->flow_blocks[i];
20365                 if (fblock->edges) {
20366                         xfree(fblock->edges);
20367                         fblock->edges = 0;
20368                 }
20369         }
20370         xfree(scc->flow_blocks);
20371         xfree(scc->ssa_edges);
20372         xfree(scc->lattice);
20373         
20374 }
20375
20376 static struct lattice_node *triple_to_lattice(
20377         struct compile_state *state, struct scc_state *scc, struct triple *ins)
20378 {
20379         if (ins->id <= 0) {
20380                 internal_error(state, ins, "bad id");
20381         }
20382         return &scc->lattice[ins->id];
20383 }
20384
20385 static struct triple *preserve_lval(
20386         struct compile_state *state, struct lattice_node *lnode)
20387 {
20388         struct triple *old;
20389         /* Preserve the original value */
20390         if (lnode->val) {
20391                 old = dup_triple(state, lnode->val);
20392                 if (lnode->val != lnode->def) {
20393                         xfree(lnode->val);
20394                 }
20395                 lnode->val = 0;
20396         } else {
20397                 old = 0;
20398         }
20399         return old;
20400 }
20401
20402 static int lval_changed(struct compile_state *state, 
20403         struct triple *old, struct lattice_node *lnode)
20404 {
20405         int changed;
20406         /* See if the lattice value has changed */
20407         changed = 1;
20408         if (!old && !lnode->val) {
20409                 changed = 0;
20410         }
20411         if (changed &&
20412                 lnode->val && old &&
20413                 (memcmp(lnode->val->param, old->param,
20414                         TRIPLE_SIZE(lnode->val) * sizeof(lnode->val->param[0])) == 0) &&
20415                 (memcmp(&lnode->val->u, &old->u, sizeof(old->u)) == 0)) {
20416                 changed = 0;
20417         }
20418         if (old) {
20419                 xfree(old);
20420         }
20421         return changed;
20422
20423 }
20424
20425 static void scc_debug_lnode(
20426         struct compile_state *state, struct scc_state *scc,
20427         struct lattice_node *lnode, int changed)
20428 {
20429         if ((state->compiler->debug & DEBUG_SCC_TRANSFORM2) && lnode->val) {
20430                 display_triple_changes(state->errout, lnode->val, lnode->def);
20431         }
20432         if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
20433                 FILE *fp = state->errout;
20434                 struct triple *val, **expr;
20435                 val = lnode->val? lnode->val : lnode->def;
20436                 fprintf(fp, "%p %s %3d %10s (",
20437                         lnode->def, 
20438                         ((lnode->def->op == OP_PHI)? "phi: ": "expr:"),
20439                         lnode->def->id,
20440                         tops(lnode->def->op));
20441                 expr = triple_rhs(state, lnode->def, 0);
20442                 for(;expr;expr = triple_rhs(state, lnode->def, expr)) {
20443                         if (*expr) {
20444                                 fprintf(fp, " %d", (*expr)->id);
20445                         }
20446                 }
20447                 if (val->op == OP_INTCONST) {
20448                         fprintf(fp, " <0x%08lx>", (unsigned long)(val->u.cval));
20449                 }
20450                 fprintf(fp, " ) -> %s %s\n",
20451                         (is_lattice_hi(state, lnode)? "hi":
20452                                 is_lattice_const(state, lnode)? "const" : "lo"),
20453                         changed? "changed" : ""
20454                         );
20455         }
20456 }
20457
20458 static int compute_lnode_val(struct compile_state *state, struct scc_state *scc,
20459         struct lattice_node *lnode)
20460 {
20461         int changed;
20462         struct triple *old, *scratch;
20463         struct triple **dexpr, **vexpr;
20464         int count, i;
20465         
20466         /* Store the original value */
20467         old = preserve_lval(state, lnode);
20468
20469         /* Reinitialize the value */
20470         lnode->val = scratch = dup_triple(state, lnode->def);
20471         scratch->id = lnode->old_id;
20472         scratch->next     = scratch;
20473         scratch->prev     = scratch;
20474         scratch->use      = 0;
20475
20476         count = TRIPLE_SIZE(scratch);
20477         for(i = 0; i < count; i++) {
20478                 dexpr = &lnode->def->param[i];
20479                 vexpr = &scratch->param[i];
20480                 *vexpr = *dexpr;
20481                 if (((i < TRIPLE_MISC_OFF(scratch)) ||
20482                         (i >= TRIPLE_TARG_OFF(scratch))) &&
20483                         *dexpr) {
20484                         struct lattice_node *tmp;
20485                         tmp = triple_to_lattice(state, scc, *dexpr);
20486                         *vexpr = (tmp->val)? tmp->val : tmp->def;
20487                 }
20488         }
20489         if (triple_is_branch(state, scratch)) {
20490                 scratch->next = lnode->def->next;
20491         }
20492         /* Recompute the value */
20493 #warning "FIXME see if simplify does anything bad"
20494         /* So far it looks like only the strength reduction
20495          * optimization are things I need to worry about.
20496          */
20497         simplify(state, scratch);
20498         /* Cleanup my value */
20499         if (scratch->use) {
20500                 internal_error(state, lnode->def, "scratch used?");
20501         }
20502         if ((scratch->prev != scratch) ||
20503                 ((scratch->next != scratch) &&
20504                         (!triple_is_branch(state, lnode->def) ||
20505                                 (scratch->next != lnode->def->next)))) {
20506                 internal_error(state, lnode->def, "scratch in list?");
20507         }
20508         /* undo any uses... */
20509         count = TRIPLE_SIZE(scratch);
20510         for(i = 0; i < count; i++) {
20511                 vexpr = &scratch->param[i];
20512                 if (*vexpr) {
20513                         unuse_triple(*vexpr, scratch);
20514                 }
20515         }
20516         if (lnode->val->op == OP_UNKNOWNVAL) {
20517                 lnode->val = 0; /* Lattice low by definition */
20518         }
20519         /* Find the case when I am lattice high */
20520         if (lnode->val && 
20521                 (lnode->val->op == lnode->def->op) &&
20522                 (memcmp(lnode->val->param, lnode->def->param, 
20523                         count * sizeof(lnode->val->param[0])) == 0) &&
20524                 (memcmp(&lnode->val->u, &lnode->def->u, sizeof(lnode->def->u)) == 0)) {
20525                 lnode->val = lnode->def;
20526         }
20527         /* Only allow lattice high when all of my inputs
20528          * are also lattice high.  Occassionally I can
20529          * have constants with a lattice low input, so
20530          * I do not need to check that case.
20531          */
20532         if (is_lattice_hi(state, lnode)) {
20533                 struct lattice_node *tmp;
20534                 int rhs;
20535                 rhs = lnode->val->rhs;
20536                 for(i = 0; i < rhs; i++) {
20537                         tmp = triple_to_lattice(state, scc, RHS(lnode->val, i));
20538                         if (!is_lattice_hi(state, tmp)) {
20539                                 lnode->val = 0;
20540                                 break;
20541                         }
20542                 }
20543         }
20544         /* Find the cases that are always lattice lo */
20545         if (lnode->val && 
20546                 triple_is_def(state, lnode->val) &&
20547                 !triple_is_pure(state, lnode->val, lnode->old_id)) {
20548                 lnode->val = 0;
20549         }
20550         /* See if the lattice value has changed */
20551         changed = lval_changed(state, old, lnode);
20552         /* See if this value should not change */
20553         if ((lnode->val != lnode->def) && 
20554                 ((      !triple_is_def(state, lnode->def)  &&
20555                         !triple_is_cbranch(state, lnode->def)) ||
20556                         (lnode->def->op == OP_PIECE))) {
20557 #warning "FIXME constant propogate through expressions with multiple left hand sides"
20558                 if (changed) {
20559                         internal_warning(state, lnode->def, "non def changes value?");
20560                 }
20561                 lnode->val = 0;
20562         }
20563
20564         /* See if we need to free the scratch value */
20565         if (lnode->val != scratch) {
20566                 xfree(scratch);
20567         }
20568         
20569         return changed;
20570 }
20571
20572
20573 static void scc_visit_cbranch(struct compile_state *state, struct scc_state *scc,
20574         struct lattice_node *lnode)
20575 {
20576         struct lattice_node *cond;
20577         struct flow_edge *left, *right;
20578         int changed;
20579
20580         /* Update the branch value */
20581         changed = compute_lnode_val(state, scc, lnode);
20582         scc_debug_lnode(state, scc, lnode, changed);
20583
20584         /* This only applies to conditional branches */
20585         if (!triple_is_cbranch(state, lnode->def)) {
20586                 internal_error(state, lnode->def, "not a conditional branch");
20587         }
20588
20589         if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
20590                 struct flow_edge *fedge;
20591                 FILE *fp = state->errout;
20592                 fprintf(fp, "%s: %d (",
20593                         tops(lnode->def->op),
20594                         lnode->def->id);
20595                 
20596                 for(fedge = lnode->fblock->out; fedge; fedge = fedge->out_next) {
20597                         fprintf(fp, " %d", fedge->dst->block->vertex);
20598                 }
20599                 fprintf(fp, " )");
20600                 if (lnode->def->rhs > 0) {
20601                         fprintf(fp, " <- %d",
20602                                 RHS(lnode->def, 0)->id);
20603                 }
20604                 fprintf(fp, "\n");
20605         }
20606         cond = triple_to_lattice(state, scc, RHS(lnode->def,0));
20607         for(left = cond->fblock->out; left; left = left->out_next) {
20608                 if (left->dst->block->first == lnode->def->next) {
20609                         break;
20610                 }
20611         }
20612         if (!left) {
20613                 internal_error(state, lnode->def, "Cannot find left branch edge");
20614         }
20615         for(right = cond->fblock->out; right; right = right->out_next) {
20616                 if (right->dst->block->first == TARG(lnode->def, 0)) {
20617                         break;
20618                 }
20619         }
20620         if (!right) {
20621                 internal_error(state, lnode->def, "Cannot find right branch edge");
20622         }
20623         /* I should only come here if the controlling expressions value
20624          * has changed, which means it must be either a constant or lo.
20625          */
20626         if (is_lattice_hi(state, cond)) {
20627                 internal_error(state, cond->def, "condition high?");
20628                 return;
20629         }
20630         if (is_lattice_lo(state, cond)) {
20631                 scc_add_fedge(state, scc, left);
20632                 scc_add_fedge(state, scc, right);
20633         }
20634         else if (cond->val->u.cval) {
20635                 scc_add_fedge(state, scc, right);
20636         } else {
20637                 scc_add_fedge(state, scc, left);
20638         }
20639
20640 }
20641
20642
20643 static void scc_add_sedge_dst(struct compile_state *state, 
20644         struct scc_state *scc, struct ssa_edge *sedge)
20645 {
20646         if (triple_is_cbranch(state, sedge->dst->def)) {
20647                 scc_visit_cbranch(state, scc, sedge->dst);
20648         }
20649         else if (triple_is_def(state, sedge->dst->def)) {
20650                 scc_add_sedge(state, scc, sedge);
20651         }
20652 }
20653
20654 static void scc_visit_phi(struct compile_state *state, struct scc_state *scc, 
20655         struct lattice_node *lnode)
20656 {
20657         struct lattice_node *tmp;
20658         struct triple **slot, *old;
20659         struct flow_edge *fedge;
20660         int changed;
20661         int index;
20662         if (lnode->def->op != OP_PHI) {
20663                 internal_error(state, lnode->def, "not phi");
20664         }
20665         /* Store the original value */
20666         old = preserve_lval(state, lnode);
20667
20668         /* default to lattice high */
20669         lnode->val = lnode->def;
20670         slot = &RHS(lnode->def, 0);
20671         index = 0;
20672         for(fedge = lnode->fblock->in; fedge; index++, fedge = fedge->in_next) {
20673                 if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
20674                         fprintf(state->errout, "Examining edge: %d vertex: %d executable: %d\n", 
20675                                 index,
20676                                 fedge->dst->block->vertex,
20677                                 fedge->executable
20678                                 );
20679                 }
20680                 if (!fedge->executable) {
20681                         continue;
20682                 }
20683                 if (!slot[index]) {
20684                         internal_error(state, lnode->def, "no phi value");
20685                 }
20686                 tmp = triple_to_lattice(state, scc, slot[index]);
20687                 /* meet(X, lattice low) = lattice low */
20688                 if (is_lattice_lo(state, tmp)) {
20689                         lnode->val = 0;
20690                 }
20691                 /* meet(X, lattice high) = X */
20692                 else if (is_lattice_hi(state, tmp)) {
20693                         lnode->val = lnode->val;
20694                 }
20695                 /* meet(lattice high, X) = X */
20696                 else if (is_lattice_hi(state, lnode)) {
20697                         lnode->val = dup_triple(state, tmp->val);
20698                         /* Only change the type if necessary */
20699                         if (!is_subset_type(lnode->def->type, tmp->val->type)) {
20700                                 lnode->val->type = lnode->def->type;
20701                         }
20702                 }
20703                 /* meet(const, const) = const or lattice low */
20704                 else if (!constants_equal(state, lnode->val, tmp->val)) {
20705                         lnode->val = 0;
20706                 }
20707
20708                 /* meet(lattice low, X) = lattice low */
20709                 if (is_lattice_lo(state, lnode)) {
20710                         lnode->val = 0;
20711                         break;
20712                 }
20713         }
20714         changed = lval_changed(state, old, lnode);
20715         scc_debug_lnode(state, scc, lnode, changed);
20716
20717         /* If the lattice value has changed update the work lists. */
20718         if (changed) {
20719                 struct ssa_edge *sedge;
20720                 for(sedge = lnode->out; sedge; sedge = sedge->out_next) {
20721                         scc_add_sedge_dst(state, scc, sedge);
20722                 }
20723         }
20724 }
20725
20726
20727 static void scc_visit_expr(struct compile_state *state, struct scc_state *scc,
20728         struct lattice_node *lnode)
20729 {
20730         int changed;
20731
20732         if (!triple_is_def(state, lnode->def)) {
20733                 internal_warning(state, lnode->def, "not visiting an expression?");
20734         }
20735         changed = compute_lnode_val(state, scc, lnode);
20736         scc_debug_lnode(state, scc, lnode, changed);
20737
20738         if (changed) {
20739                 struct ssa_edge *sedge;
20740                 for(sedge = lnode->out; sedge; sedge = sedge->out_next) {
20741                         scc_add_sedge_dst(state, scc, sedge);
20742                 }
20743         }
20744 }
20745
20746 static void scc_writeback_values(
20747         struct compile_state *state, struct scc_state *scc)
20748 {
20749         struct triple *first, *ins;
20750         first = state->first;
20751         ins = first;
20752         do {
20753                 struct lattice_node *lnode;
20754                 lnode = triple_to_lattice(state, scc, ins);
20755                 if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
20756                         if (is_lattice_hi(state, lnode) &&
20757                                 (lnode->val->op != OP_NOOP))
20758                         {
20759                                 struct flow_edge *fedge;
20760                                 int executable;
20761                                 executable = 0;
20762                                 for(fedge = lnode->fblock->in; 
20763                                     !executable && fedge; fedge = fedge->in_next) {
20764                                         executable |= fedge->executable;
20765                                 }
20766                                 if (executable) {
20767                                         internal_warning(state, lnode->def,
20768                                                 "lattice node %d %s->%s still high?",
20769                                                 ins->id, 
20770                                                 tops(lnode->def->op),
20771                                                 tops(lnode->val->op));
20772                                 }
20773                         }
20774                 }
20775
20776                 /* Restore id */
20777                 ins->id = lnode->old_id;
20778                 if (lnode->val && (lnode->val != ins)) {
20779                         /* See if it something I know how to write back */
20780                         switch(lnode->val->op) {
20781                         case OP_INTCONST:
20782                                 mkconst(state, ins, lnode->val->u.cval);
20783                                 break;
20784                         case OP_ADDRCONST:
20785                                 mkaddr_const(state, ins, 
20786                                         MISC(lnode->val, 0), lnode->val->u.cval);
20787                                 break;
20788                         default:
20789                                 /* By default don't copy the changes,
20790                                  * recompute them in place instead.
20791                                  */
20792                                 simplify(state, ins);
20793                                 break;
20794                         }
20795                         if (is_const(lnode->val) &&
20796                                 !constants_equal(state, lnode->val, ins)) {
20797                                 internal_error(state, 0, "constants not equal");
20798                         }
20799                         /* Free the lattice nodes */
20800                         xfree(lnode->val);
20801                         lnode->val = 0;
20802                 }
20803                 ins = ins->next;
20804         } while(ins != first);
20805 }
20806
20807 static void scc_transform(struct compile_state *state)
20808 {
20809         struct scc_state scc;
20810         if (!(state->compiler->flags & COMPILER_SCC_TRANSFORM)) {
20811                 return;
20812         }
20813
20814         initialize_scc_state(state, &scc);
20815
20816         while(scc.flow_work_list || scc.ssa_work_list) {
20817                 struct flow_edge *fedge;
20818                 struct ssa_edge *sedge;
20819                 struct flow_edge *fptr;
20820                 while((fedge = scc_next_fedge(state, &scc))) {
20821                         struct block *block;
20822                         struct triple *ptr;
20823                         struct flow_block *fblock;
20824                         int reps;
20825                         int done;
20826                         if (fedge->executable) {
20827                                 continue;
20828                         }
20829                         if (!fedge->dst) {
20830                                 internal_error(state, 0, "fedge without dst");
20831                         }
20832                         if (!fedge->src) {
20833                                 internal_error(state, 0, "fedge without src");
20834                         }
20835                         fedge->executable = 1;
20836                         fblock = fedge->dst;
20837                         block = fblock->block;
20838                         reps = 0;
20839                         for(fptr = fblock->in; fptr; fptr = fptr->in_next) {
20840                                 if (fptr->executable) {
20841                                         reps++;
20842                                 }
20843                         }
20844                         
20845                         if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
20846                                 fprintf(state->errout, "vertex: %d reps: %d\n", 
20847                                         block->vertex, reps);
20848                         }
20849
20850                         done = 0;
20851                         for(ptr = block->first; !done; ptr = ptr->next) {
20852                                 struct lattice_node *lnode;
20853                                 done = (ptr == block->last);
20854                                 lnode = &scc.lattice[ptr->id];
20855                                 if (ptr->op == OP_PHI) {
20856                                         scc_visit_phi(state, &scc, lnode);
20857                                 }
20858                                 else if ((reps == 1) && triple_is_def(state, ptr))
20859                                 {
20860                                         scc_visit_expr(state, &scc, lnode);
20861                                 }
20862                         }
20863                         /* Add unconditional branch edges */
20864                         if (!triple_is_cbranch(state, fblock->block->last)) {
20865                                 struct flow_edge *out;
20866                                 for(out = fblock->out; out; out = out->out_next) {
20867                                         scc_add_fedge(state, &scc, out);
20868                                 }
20869                         }
20870                 }
20871                 while((sedge = scc_next_sedge(state, &scc))) {
20872                         struct lattice_node *lnode;
20873                         struct flow_block *fblock;
20874                         lnode = sedge->dst;
20875                         fblock = lnode->fblock;
20876
20877                         if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
20878                                 fprintf(state->errout, "sedge: %5d (%5d -> %5d)\n",
20879                                         sedge - scc.ssa_edges,
20880                                         sedge->src->def->id,
20881                                         sedge->dst->def->id);
20882                         }
20883
20884                         if (lnode->def->op == OP_PHI) {
20885                                 scc_visit_phi(state, &scc, lnode);
20886                         }
20887                         else {
20888                                 for(fptr = fblock->in; fptr; fptr = fptr->in_next) {
20889                                         if (fptr->executable) {
20890                                                 break;
20891                                         }
20892                                 }
20893                                 if (fptr) {
20894                                         scc_visit_expr(state, &scc, lnode);
20895                                 }
20896                         }
20897                 }
20898         }
20899         
20900         scc_writeback_values(state, &scc);
20901         free_scc_state(state, &scc);
20902         rebuild_ssa_form(state);
20903         
20904         print_blocks(state, __func__, state->dbgout);
20905 }
20906
20907
20908 static void transform_to_arch_instructions(struct compile_state *state)
20909 {
20910         struct triple *ins, *first;
20911         first = state->first;
20912         ins = first;
20913         do {
20914                 ins = transform_to_arch_instruction(state, ins);
20915         } while(ins != first);
20916         
20917         print_blocks(state, __func__, state->dbgout);
20918 }
20919
20920 #if DEBUG_CONSISTENCY
20921 static void verify_uses(struct compile_state *state)
20922 {
20923         struct triple *first, *ins;
20924         struct triple_set *set;
20925         first = state->first;
20926         ins = first;
20927         do {
20928                 struct triple **expr;
20929                 expr = triple_rhs(state, ins, 0);
20930                 for(; expr; expr = triple_rhs(state, ins, expr)) {
20931                         struct triple *rhs;
20932                         rhs = *expr;
20933                         for(set = rhs?rhs->use:0; set; set = set->next) {
20934                                 if (set->member == ins) {
20935                                         break;
20936                                 }
20937                         }
20938                         if (!set) {
20939                                 internal_error(state, ins, "rhs not used");
20940                         }
20941                 }
20942                 expr = triple_lhs(state, ins, 0);
20943                 for(; expr; expr = triple_lhs(state, ins, expr)) {
20944                         struct triple *lhs;
20945                         lhs = *expr;
20946                         for(set =  lhs?lhs->use:0; set; set = set->next) {
20947                                 if (set->member == ins) {
20948                                         break;
20949                                 }
20950                         }
20951                         if (!set) {
20952                                 internal_error(state, ins, "lhs not used");
20953                         }
20954                 }
20955                 expr = triple_misc(state, ins, 0);
20956                 if (ins->op != OP_PHI) {
20957                         for(; expr; expr = triple_targ(state, ins, expr)) {
20958                                 struct triple *misc;
20959                                 misc = *expr;
20960                                 for(set = misc?misc->use:0; set; set = set->next) {
20961                                         if (set->member == ins) {
20962                                                 break;
20963                                         }
20964                                 }
20965                                 if (!set) {
20966                                         internal_error(state, ins, "misc not used");
20967                                 }
20968                         }
20969                 }
20970                 if (!triple_is_ret(state, ins)) {
20971                         expr = triple_targ(state, ins, 0);
20972                         for(; expr; expr = triple_targ(state, ins, expr)) {
20973                                 struct triple *targ;
20974                                 targ = *expr;
20975                                 for(set = targ?targ->use:0; set; set = set->next) {
20976                                         if (set->member == ins) {
20977                                                 break;
20978                                         }
20979                                 }
20980                                 if (!set) {
20981                                         internal_error(state, ins, "targ not used");
20982                                 }
20983                         }
20984                 }
20985                 ins = ins->next;
20986         } while(ins != first);
20987         
20988 }
20989 static void verify_blocks_present(struct compile_state *state)
20990 {
20991         struct triple *first, *ins;
20992         if (!state->bb.first_block) {
20993                 return;
20994         }
20995         first = state->first;
20996         ins = first;
20997         do {
20998                 valid_ins(state, ins);
20999                 if (triple_stores_block(state, ins)) {
21000                         if (!ins->u.block) {
21001                                 internal_error(state, ins, 
21002                                         "%p not in a block?", ins);
21003                         }
21004                 }
21005                 ins = ins->next;
21006         } while(ins != first);
21007         
21008         
21009 }
21010
21011 static int edge_present(struct compile_state *state, struct block *block, struct triple *edge)
21012 {
21013         struct block_set *bedge;
21014         struct block *targ;
21015         targ = block_of_triple(state, edge);
21016         for(bedge = block->edges; bedge; bedge = bedge->next) {
21017                 if (bedge->member == targ) {
21018                         return 1;
21019                 }
21020         }
21021         return 0;
21022 }
21023
21024 static void verify_blocks(struct compile_state *state)
21025 {
21026         struct triple *ins;
21027         struct block *block;
21028         int blocks;
21029         block = state->bb.first_block;
21030         if (!block) {
21031                 return;
21032         }
21033         blocks = 0;
21034         do {
21035                 int users;
21036                 struct block_set *user, *edge;
21037                 blocks++;
21038                 for(ins = block->first; ins != block->last->next; ins = ins->next) {
21039                         if (triple_stores_block(state, ins) && (ins->u.block != block)) {
21040                                 internal_error(state, ins, "inconsitent block specified");
21041                         }
21042                         valid_ins(state, ins);
21043                 }
21044                 users = 0;
21045                 for(user = block->use; user; user = user->next) {
21046                         users++;
21047                         if (!user->member->first) {
21048                                 internal_error(state, block->first, "user is empty");
21049                         }
21050                         if ((block == state->bb.last_block) &&
21051                                 (user->member == state->bb.first_block)) {
21052                                 continue;
21053                         }
21054                         for(edge = user->member->edges; edge; edge = edge->next) {
21055                                 if (edge->member == block) {
21056                                         break;
21057                                 }
21058                         }
21059                         if (!edge) {
21060                                 internal_error(state, user->member->first,
21061                                         "user does not use block");
21062                         }
21063                 }
21064                 if (triple_is_branch(state, block->last)) {
21065                         struct triple **expr;
21066                         expr = triple_edge_targ(state, block->last, 0);
21067                         for(;expr; expr = triple_edge_targ(state, block->last, expr)) {
21068                                 if (*expr && !edge_present(state, block, *expr)) {
21069                                         internal_error(state, block->last, "no edge to targ");
21070                                 }
21071                         }
21072                 }
21073                 if (!triple_is_ubranch(state, block->last) &&
21074                         (block != state->bb.last_block) &&
21075                         !edge_present(state, block, block->last->next)) {
21076                         internal_error(state, block->last, "no edge to block->last->next");
21077                 }
21078                 for(edge = block->edges; edge; edge = edge->next) {
21079                         for(user = edge->member->use; user; user = user->next) {
21080                                 if (user->member == block) {
21081                                         break;
21082                                 }
21083                         }
21084                         if (!user || user->member != block) {
21085                                 internal_error(state, block->first,
21086                                         "block does not use edge");
21087                         }
21088                         if (!edge->member->first) {
21089                                 internal_error(state, block->first, "edge block is empty");
21090                         }
21091                 }
21092                 if (block->users != users) {
21093                         internal_error(state, block->first, 
21094                                 "computed users %d != stored users %d",
21095                                 users, block->users);
21096                 }
21097                 if (!triple_stores_block(state, block->last->next)) {
21098                         internal_error(state, block->last->next, 
21099                                 "cannot find next block");
21100                 }
21101                 block = block->last->next->u.block;
21102                 if (!block) {
21103                         internal_error(state, block->last->next,
21104                                 "bad next block");
21105                 }
21106         } while(block != state->bb.first_block);
21107         if (blocks != state->bb.last_vertex) {
21108                 internal_error(state, 0, "computed blocks: %d != stored blocks %d",
21109                         blocks, state->bb.last_vertex);
21110         }
21111 }
21112
21113 static void verify_domination(struct compile_state *state)
21114 {
21115         struct triple *first, *ins;
21116         struct triple_set *set;
21117         if (!state->bb.first_block) {
21118                 return;
21119         }
21120         
21121         first = state->first;
21122         ins = first;
21123         do {
21124                 for(set = ins->use; set; set = set->next) {
21125                         struct triple **slot;
21126                         struct triple *use_point;
21127                         int i, zrhs;
21128                         use_point = 0;
21129                         zrhs = set->member->rhs;
21130                         slot = &RHS(set->member, 0);
21131                         /* See if the use is on the right hand side */
21132                         for(i = 0; i < zrhs; i++) {
21133                                 if (slot[i] == ins) {
21134                                         break;
21135                                 }
21136                         }
21137                         if (i < zrhs) {
21138                                 use_point = set->member;
21139                                 if (set->member->op == OP_PHI) {
21140                                         struct block_set *bset;
21141                                         int edge;
21142                                         bset = set->member->u.block->use;
21143                                         for(edge = 0; bset && (edge < i); edge++) {
21144                                                 bset = bset->next;
21145                                         }
21146                                         if (!bset) {
21147                                                 internal_error(state, set->member, 
21148                                                         "no edge for phi rhs %d", i);
21149                                         }
21150                                         use_point = bset->member->last;
21151                                 }
21152                         }
21153                         if (use_point &&
21154                                 !tdominates(state, ins, use_point)) {
21155                                 if (is_const(ins)) {
21156                                         internal_warning(state, ins, 
21157                                         "non dominated rhs use point %p?", use_point);
21158                                 }
21159                                 else {
21160                                         internal_error(state, ins, 
21161                                                 "non dominated rhs use point %p?", use_point);
21162                                 }
21163                         }
21164                 }
21165                 ins = ins->next;
21166         } while(ins != first);
21167 }
21168
21169 static void verify_rhs(struct compile_state *state)
21170 {
21171         struct triple *first, *ins;
21172         first = state->first;
21173         ins = first;
21174         do {
21175                 struct triple **slot;
21176                 int zrhs, i;
21177                 zrhs = ins->rhs;
21178                 slot = &RHS(ins, 0);
21179                 for(i = 0; i < zrhs; i++) {
21180                         if (slot[i] == 0) {
21181                                 internal_error(state, ins,
21182                                         "missing rhs %d on %s",
21183                                         i, tops(ins->op));
21184                         }
21185                         if ((ins->op != OP_PHI) && (slot[i] == ins)) {
21186                                 internal_error(state, ins,
21187                                         "ins == rhs[%d] on %s",
21188                                         i, tops(ins->op));
21189                         }
21190                 }
21191                 ins = ins->next;
21192         } while(ins != first);
21193 }
21194
21195 static void verify_piece(struct compile_state *state)
21196 {
21197         struct triple *first, *ins;
21198         first = state->first;
21199         ins = first;
21200         do {
21201                 struct triple *ptr;
21202                 int lhs, i;
21203                 lhs = ins->lhs;
21204                 for(ptr = ins->next, i = 0; i < lhs; i++, ptr = ptr->next) {
21205                         if (ptr != LHS(ins, i)) {
21206                                 internal_error(state, ins, "malformed lhs on %s",
21207                                         tops(ins->op));
21208                         }
21209                         if (ptr->op != OP_PIECE) {
21210                                 internal_error(state, ins, "bad lhs op %s at %d on %s",
21211                                         tops(ptr->op), i, tops(ins->op));
21212                         }
21213                         if (ptr->u.cval != i) {
21214                                 internal_error(state, ins, "bad u.cval of %d %d expected",
21215                                         ptr->u.cval, i);
21216                         }
21217                 }
21218                 ins = ins->next;
21219         } while(ins != first);
21220 }
21221
21222 static void verify_ins_colors(struct compile_state *state)
21223 {
21224         struct triple *first, *ins;
21225         
21226         first = state->first;
21227         ins = first;
21228         do {
21229                 ins = ins->next;
21230         } while(ins != first);
21231 }
21232
21233 static void verify_unknown(struct compile_state *state)
21234 {
21235         struct triple *first, *ins;
21236         if (    (unknown_triple.next != &unknown_triple) ||
21237                 (unknown_triple.prev != &unknown_triple) ||
21238 #if 0
21239                 (unknown_triple.use != 0) ||
21240 #endif
21241                 (unknown_triple.op != OP_UNKNOWNVAL) ||
21242                 (unknown_triple.lhs != 0) ||
21243                 (unknown_triple.rhs != 0) ||
21244                 (unknown_triple.misc != 0) ||
21245                 (unknown_triple.targ != 0) ||
21246                 (unknown_triple.template_id != 0) ||
21247                 (unknown_triple.id != -1) ||
21248                 (unknown_triple.type != &unknown_type) ||
21249                 (unknown_triple.occurance != &dummy_occurance) ||
21250                 (unknown_triple.param[0] != 0) ||
21251                 (unknown_triple.param[1] != 0)) {
21252                 internal_error(state, &unknown_triple, "unknown_triple corrupted!");
21253         }
21254         if (    (dummy_occurance.count != 2) ||
21255                 (strcmp(dummy_occurance.filename, __FILE__) != 0) ||
21256                 (strcmp(dummy_occurance.function, "") != 0) ||
21257                 (dummy_occurance.col != 0) ||
21258                 (dummy_occurance.parent != 0)) {
21259                 internal_error(state, &unknown_triple, "dummy_occurance corrupted!");
21260         }
21261         if (    (unknown_type.type != TYPE_UNKNOWN)) {
21262                 internal_error(state, &unknown_triple, "unknown_type corrupted!");
21263         }
21264         first = state->first;
21265         ins = first;
21266         do {
21267                 int params, i;
21268                 if (ins == &unknown_triple) {
21269                         internal_error(state, ins, "unknown triple in list");
21270                 }
21271                 params = TRIPLE_SIZE(ins);
21272                 for(i = 0; i < params; i++) {
21273                         if (ins->param[i] == &unknown_triple) {
21274                                 internal_error(state, ins, "unknown triple used!");
21275                         }
21276                 }
21277                 ins = ins->next;
21278         } while(ins != first);
21279 }
21280
21281 static void verify_types(struct compile_state *state)
21282 {
21283         struct triple *first, *ins;
21284         first = state->first;
21285         ins = first;
21286         do {
21287                 struct type *invalid;
21288                 invalid = invalid_type(state, ins->type);
21289                 if (invalid) {
21290                         FILE *fp = state->errout;
21291                         fprintf(fp, "type: ");
21292                         name_of(fp, ins->type);
21293                         fprintf(fp, "\n");
21294                         fprintf(fp, "invalid type: ");
21295                         name_of(fp, invalid);
21296                         fprintf(fp, "\n");
21297                         internal_error(state, ins, "invalid ins type");
21298                 }
21299         } while(ins != first);
21300 }
21301
21302 static void verify_copy(struct compile_state *state)
21303 {
21304         struct triple *first, *ins, *next;
21305         first = state->first;
21306         next = ins = first;
21307         do {
21308                 ins = next;
21309                 next = ins->next;
21310                 if (ins->op != OP_COPY) {
21311                         continue;
21312                 }
21313                 if (!equiv_types(ins->type, RHS(ins, 0)->type)) {
21314                         FILE *fp = state->errout;
21315                         fprintf(fp, "src type: ");
21316                         name_of(fp, RHS(ins, 0)->type);
21317                         fprintf(fp, "\n");
21318                         fprintf(fp, "dst type: ");
21319                         name_of(fp, ins->type);
21320                         fprintf(fp, "\n");
21321                         internal_error(state, ins, "type mismatch in copy");
21322                 }
21323         } while(next != first);
21324 }
21325
21326 static void verify_consistency(struct compile_state *state)
21327 {
21328         verify_unknown(state);
21329         verify_uses(state);
21330         verify_blocks_present(state);
21331         verify_blocks(state);
21332         verify_domination(state);
21333         verify_rhs(state);
21334         verify_piece(state);
21335         verify_ins_colors(state);
21336         verify_types(state);
21337         verify_copy(state);
21338         if (state->compiler->debug & DEBUG_VERIFICATION) {
21339                 fprintf(state->dbgout, "consistency verified\n");
21340         }
21341 }
21342 #else 
21343 static void verify_consistency(struct compile_state *state) {}
21344 #endif /* DEBUG_CONSISTENCY */
21345
21346 static void optimize(struct compile_state *state)
21347 {
21348         /* Join all of the functions into one giant function */
21349         join_functions(state);
21350
21351         /* Dump what the instruction graph intially looks like */
21352         print_triples(state);
21353
21354         /* Replace structures with simpler data types */
21355         decompose_compound_types(state);
21356         print_triples(state);
21357
21358         verify_consistency(state);
21359         /* Analyze the intermediate code */
21360         state->bb.first = state->first;
21361         analyze_basic_blocks(state, &state->bb);
21362
21363         /* Transform the code to ssa form. */
21364         /*
21365          * The transformation to ssa form puts a phi function
21366          * on each of edge of a dominance frontier where that
21367          * phi function might be needed.  At -O2 if we don't
21368          * eleminate the excess phi functions we can get an
21369          * exponential code size growth.  So I kill the extra
21370          * phi functions early and I kill them often.
21371          */
21372         transform_to_ssa_form(state);
21373         verify_consistency(state);
21374
21375         /* Remove dead code */
21376         eliminate_inefectual_code(state);
21377         verify_consistency(state);
21378
21379         /* Do strength reduction and simple constant optimizations */
21380         simplify_all(state);
21381         verify_consistency(state);
21382         /* Propogate constants throughout the code */
21383         scc_transform(state);
21384         verify_consistency(state);
21385 #warning "WISHLIST implement single use constants (least possible register pressure)"
21386 #warning "WISHLIST implement induction variable elimination"
21387         /* Select architecture instructions and an initial partial
21388          * coloring based on architecture constraints.
21389          */
21390         transform_to_arch_instructions(state);
21391         verify_consistency(state);
21392
21393         /* Remove dead code */
21394         eliminate_inefectual_code(state);
21395         verify_consistency(state);
21396
21397         /* Color all of the variables to see if they will fit in registers */
21398         insert_copies_to_phi(state);
21399         verify_consistency(state);
21400
21401         insert_mandatory_copies(state);
21402         verify_consistency(state);
21403
21404         allocate_registers(state);
21405         verify_consistency(state);
21406
21407         /* Remove the optimization information.
21408          * This is more to check for memory consistency than to free memory.
21409          */
21410         free_basic_blocks(state, &state->bb);
21411 }
21412
21413 static void print_op_asm(struct compile_state *state,
21414         struct triple *ins, FILE *fp)
21415 {
21416         struct asm_info *info;
21417         const char *ptr;
21418         unsigned lhs, rhs, i;
21419         info = ins->u.ainfo;
21420         lhs = ins->lhs;
21421         rhs = ins->rhs;
21422         /* Don't count the clobbers in lhs */
21423         for(i = 0; i < lhs; i++) {
21424                 if (LHS(ins, i)->type == &void_type) {
21425                         break;
21426                 }
21427         }
21428         lhs = i;
21429         fprintf(fp, "#ASM\n");
21430         fputc('\t', fp);
21431         for(ptr = info->str; *ptr; ptr++) {
21432                 char *next;
21433                 unsigned long param;
21434                 struct triple *piece;
21435                 if (*ptr != '%') {
21436                         fputc(*ptr, fp);
21437                         continue;
21438                 }
21439                 ptr++;
21440                 if (*ptr == '%') {
21441                         fputc('%', fp);
21442                         continue;
21443                 }
21444                 param = strtoul(ptr, &next, 10);
21445                 if (ptr == next) {
21446                         error(state, ins, "Invalid asm template");
21447                 }
21448                 if (param >= (lhs + rhs)) {
21449                         error(state, ins, "Invalid param %%%u in asm template",
21450                                 param);
21451                 }
21452                 piece = (param < lhs)? LHS(ins, param) : RHS(ins, param - lhs);
21453                 fprintf(fp, "%s", 
21454                         arch_reg_str(ID_REG(piece->id)));
21455                 ptr = next -1;
21456         }
21457         fprintf(fp, "\n#NOT ASM\n");
21458 }
21459
21460
21461 /* Only use the low x86 byte registers.  This allows me
21462  * allocate the entire register when a byte register is used.
21463  */
21464 #define X86_4_8BIT_GPRS 1
21465
21466 /* x86 featrues */
21467 #define X86_MMX_REGS  (1<<0)
21468 #define X86_XMM_REGS  (1<<1)
21469 #define X86_NOOP_COPY (1<<2)
21470
21471 /* The x86 register classes */
21472 #define REGC_FLAGS       0
21473 #define REGC_GPR8        1
21474 #define REGC_GPR16       2
21475 #define REGC_GPR32       3
21476 #define REGC_DIVIDEND64  4
21477 #define REGC_DIVIDEND32  5
21478 #define REGC_MMX         6
21479 #define REGC_XMM         7
21480 #define REGC_GPR32_8     8
21481 #define REGC_GPR16_8     9
21482 #define REGC_GPR8_LO    10
21483 #define REGC_IMM32      11
21484 #define REGC_IMM16      12
21485 #define REGC_IMM8       13
21486 #define LAST_REGC  REGC_IMM8
21487 #if LAST_REGC >= MAX_REGC
21488 #error "MAX_REGC is to low"
21489 #endif
21490
21491 /* Register class masks */
21492 #define REGCM_FLAGS      (1 << REGC_FLAGS)
21493 #define REGCM_GPR8       (1 << REGC_GPR8)
21494 #define REGCM_GPR16      (1 << REGC_GPR16)
21495 #define REGCM_GPR32      (1 << REGC_GPR32)
21496 #define REGCM_DIVIDEND64 (1 << REGC_DIVIDEND64)
21497 #define REGCM_DIVIDEND32 (1 << REGC_DIVIDEND32)
21498 #define REGCM_MMX        (1 << REGC_MMX)
21499 #define REGCM_XMM        (1 << REGC_XMM)
21500 #define REGCM_GPR32_8    (1 << REGC_GPR32_8)
21501 #define REGCM_GPR16_8    (1 << REGC_GPR16_8)
21502 #define REGCM_GPR8_LO    (1 << REGC_GPR8_LO)
21503 #define REGCM_IMM32      (1 << REGC_IMM32)
21504 #define REGCM_IMM16      (1 << REGC_IMM16)
21505 #define REGCM_IMM8       (1 << REGC_IMM8)
21506 #define REGCM_ALL        ((1 << (LAST_REGC + 1)) - 1)
21507 #define REGCM_IMMALL    (REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8)
21508
21509 /* The x86 registers */
21510 #define REG_EFLAGS  2
21511 #define REGC_FLAGS_FIRST REG_EFLAGS
21512 #define REGC_FLAGS_LAST  REG_EFLAGS
21513 #define REG_AL      3
21514 #define REG_BL      4
21515 #define REG_CL      5
21516 #define REG_DL      6
21517 #define REG_AH      7
21518 #define REG_BH      8
21519 #define REG_CH      9
21520 #define REG_DH      10
21521 #define REGC_GPR8_LO_FIRST REG_AL
21522 #define REGC_GPR8_LO_LAST  REG_DL
21523 #define REGC_GPR8_FIRST  REG_AL
21524 #define REGC_GPR8_LAST   REG_DH
21525 #define REG_AX     11
21526 #define REG_BX     12
21527 #define REG_CX     13
21528 #define REG_DX     14
21529 #define REG_SI     15
21530 #define REG_DI     16
21531 #define REG_BP     17
21532 #define REG_SP     18
21533 #define REGC_GPR16_FIRST REG_AX
21534 #define REGC_GPR16_LAST  REG_SP
21535 #define REG_EAX    19
21536 #define REG_EBX    20
21537 #define REG_ECX    21
21538 #define REG_EDX    22
21539 #define REG_ESI    23
21540 #define REG_EDI    24
21541 #define REG_EBP    25
21542 #define REG_ESP    26
21543 #define REGC_GPR32_FIRST REG_EAX
21544 #define REGC_GPR32_LAST  REG_ESP
21545 #define REG_EDXEAX 27
21546 #define REGC_DIVIDEND64_FIRST REG_EDXEAX
21547 #define REGC_DIVIDEND64_LAST  REG_EDXEAX
21548 #define REG_DXAX   28
21549 #define REGC_DIVIDEND32_FIRST REG_DXAX
21550 #define REGC_DIVIDEND32_LAST  REG_DXAX
21551 #define REG_MMX0   29
21552 #define REG_MMX1   30
21553 #define REG_MMX2   31
21554 #define REG_MMX3   32
21555 #define REG_MMX4   33
21556 #define REG_MMX5   34
21557 #define REG_MMX6   35
21558 #define REG_MMX7   36
21559 #define REGC_MMX_FIRST REG_MMX0
21560 #define REGC_MMX_LAST  REG_MMX7
21561 #define REG_XMM0   37
21562 #define REG_XMM1   38
21563 #define REG_XMM2   39
21564 #define REG_XMM3   40
21565 #define REG_XMM4   41
21566 #define REG_XMM5   42
21567 #define REG_XMM6   43
21568 #define REG_XMM7   44
21569 #define REGC_XMM_FIRST REG_XMM0
21570 #define REGC_XMM_LAST  REG_XMM7
21571 #warning "WISHLIST figure out how to use pinsrw and pextrw to better use extended regs"
21572 #define LAST_REG   REG_XMM7
21573
21574 #define REGC_GPR32_8_FIRST REG_EAX
21575 #define REGC_GPR32_8_LAST  REG_EDX
21576 #define REGC_GPR16_8_FIRST REG_AX
21577 #define REGC_GPR16_8_LAST  REG_DX
21578
21579 #define REGC_IMM8_FIRST    -1
21580 #define REGC_IMM8_LAST     -1
21581 #define REGC_IMM16_FIRST   -2
21582 #define REGC_IMM16_LAST    -1
21583 #define REGC_IMM32_FIRST   -4
21584 #define REGC_IMM32_LAST    -1
21585
21586 #if LAST_REG >= MAX_REGISTERS
21587 #error "MAX_REGISTERS to low"
21588 #endif
21589
21590
21591 static unsigned regc_size[LAST_REGC +1] = {
21592         [REGC_FLAGS]      = REGC_FLAGS_LAST      - REGC_FLAGS_FIRST + 1,
21593         [REGC_GPR8]       = REGC_GPR8_LAST       - REGC_GPR8_FIRST + 1,
21594         [REGC_GPR16]      = REGC_GPR16_LAST      - REGC_GPR16_FIRST + 1,
21595         [REGC_GPR32]      = REGC_GPR32_LAST      - REGC_GPR32_FIRST + 1,
21596         [REGC_DIVIDEND64] = REGC_DIVIDEND64_LAST - REGC_DIVIDEND64_FIRST + 1,
21597         [REGC_DIVIDEND32] = REGC_DIVIDEND32_LAST - REGC_DIVIDEND32_FIRST + 1,
21598         [REGC_MMX]        = REGC_MMX_LAST        - REGC_MMX_FIRST + 1,
21599         [REGC_XMM]        = REGC_XMM_LAST        - REGC_XMM_FIRST + 1,
21600         [REGC_GPR32_8]    = REGC_GPR32_8_LAST    - REGC_GPR32_8_FIRST + 1,
21601         [REGC_GPR16_8]    = REGC_GPR16_8_LAST    - REGC_GPR16_8_FIRST + 1,
21602         [REGC_GPR8_LO]    = REGC_GPR8_LO_LAST    - REGC_GPR8_LO_FIRST + 1,
21603         [REGC_IMM32]      = 0,
21604         [REGC_IMM16]      = 0,
21605         [REGC_IMM8]       = 0,
21606 };
21607
21608 static const struct {
21609         int first, last;
21610 } regcm_bound[LAST_REGC + 1] = {
21611         [REGC_FLAGS]      = { REGC_FLAGS_FIRST,      REGC_FLAGS_LAST },
21612         [REGC_GPR8]       = { REGC_GPR8_FIRST,       REGC_GPR8_LAST },
21613         [REGC_GPR16]      = { REGC_GPR16_FIRST,      REGC_GPR16_LAST },
21614         [REGC_GPR32]      = { REGC_GPR32_FIRST,      REGC_GPR32_LAST },
21615         [REGC_DIVIDEND64] = { REGC_DIVIDEND64_FIRST, REGC_DIVIDEND64_LAST },
21616         [REGC_DIVIDEND32] = { REGC_DIVIDEND32_FIRST, REGC_DIVIDEND32_LAST },
21617         [REGC_MMX]        = { REGC_MMX_FIRST,        REGC_MMX_LAST },
21618         [REGC_XMM]        = { REGC_XMM_FIRST,        REGC_XMM_LAST },
21619         [REGC_GPR32_8]    = { REGC_GPR32_8_FIRST,    REGC_GPR32_8_LAST },
21620         [REGC_GPR16_8]    = { REGC_GPR16_8_FIRST,    REGC_GPR16_8_LAST },
21621         [REGC_GPR8_LO]    = { REGC_GPR8_LO_FIRST,    REGC_GPR8_LO_LAST },
21622         [REGC_IMM32]      = { REGC_IMM32_FIRST,      REGC_IMM32_LAST },
21623         [REGC_IMM16]      = { REGC_IMM16_FIRST,      REGC_IMM16_LAST },
21624         [REGC_IMM8]       = { REGC_IMM8_FIRST,       REGC_IMM8_LAST },
21625 };
21626
21627 #if ARCH_INPUT_REGS != 4
21628 #error ARCH_INPUT_REGS size mismatch
21629 #endif
21630 static const struct reg_info arch_input_regs[ARCH_INPUT_REGS] = {
21631         { .reg = REG_EAX, .regcm = REGCM_GPR32 },
21632         { .reg = REG_EBX, .regcm = REGCM_GPR32 },
21633         { .reg = REG_ECX, .regcm = REGCM_GPR32 },
21634         { .reg = REG_EDX, .regcm = REGCM_GPR32 },
21635 };
21636
21637 #if ARCH_OUTPUT_REGS != 4
21638 #error ARCH_INPUT_REGS size mismatch
21639 #endif
21640 static const struct reg_info arch_output_regs[ARCH_OUTPUT_REGS] = {
21641         { .reg = REG_EAX, .regcm = REGCM_GPR32 },
21642         { .reg = REG_EBX, .regcm = REGCM_GPR32 },
21643         { .reg = REG_ECX, .regcm = REGCM_GPR32 },
21644         { .reg = REG_EDX, .regcm = REGCM_GPR32 },
21645 };
21646
21647 static void init_arch_state(struct arch_state *arch)
21648 {
21649         memset(arch, 0, sizeof(*arch));
21650         arch->features = 0;
21651 }
21652
21653 static const struct compiler_flag arch_flags[] = {
21654         { "mmx",       X86_MMX_REGS },
21655         { "sse",       X86_XMM_REGS },
21656         { "noop-copy", X86_NOOP_COPY },
21657         { 0,     0 },
21658 };
21659 static const struct compiler_flag arch_cpus[] = {
21660         { "i386", 0 },
21661         { "p2",   X86_MMX_REGS },
21662         { "p3",   X86_MMX_REGS | X86_XMM_REGS },
21663         { "p4",   X86_MMX_REGS | X86_XMM_REGS },
21664         { "k7",   X86_MMX_REGS },
21665         { "k8",   X86_MMX_REGS | X86_XMM_REGS },
21666         { "c3",   X86_MMX_REGS },
21667         { "c3-2", X86_MMX_REGS | X86_XMM_REGS }, /* Nehemiah */
21668         {  0,     0 }
21669 };
21670 static int arch_encode_flag(struct arch_state *arch, const char *flag)
21671 {
21672         int result;
21673         int act;
21674
21675         act = 1;
21676         result = -1;
21677         if (strncmp(flag, "no-", 3) == 0) {
21678                 flag += 3;
21679                 act = 0;
21680         }
21681         if (act && strncmp(flag, "cpu=", 4) == 0) {
21682                 flag += 4;
21683                 result = set_flag(arch_cpus, &arch->features, 1, flag);
21684         }
21685         else {
21686                 result = set_flag(arch_flags, &arch->features, act, flag);
21687         }
21688         return result;
21689 }
21690
21691 static void arch_usage(FILE *fp)
21692 {
21693         flag_usage(fp, arch_flags, "-m", "-mno-");
21694         flag_usage(fp, arch_cpus, "-mcpu=", 0);
21695 }
21696
21697 static unsigned arch_regc_size(struct compile_state *state, int class)
21698 {
21699         if ((class < 0) || (class > LAST_REGC)) {
21700                 return 0;
21701         }
21702         return regc_size[class];
21703 }
21704
21705 static int arch_regcm_intersect(unsigned regcm1, unsigned regcm2)
21706 {
21707         /* See if two register classes may have overlapping registers */
21708         unsigned gpr_mask = REGCM_GPR8 | REGCM_GPR8_LO | REGCM_GPR16_8 | REGCM_GPR16 |
21709                 REGCM_GPR32_8 | REGCM_GPR32 | 
21710                 REGCM_DIVIDEND32 | REGCM_DIVIDEND64;
21711
21712         /* Special case for the immediates */
21713         if ((regcm1 & (REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8)) &&
21714                 ((regcm1 & ~(REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8)) == 0) &&
21715                 (regcm2 & (REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8)) &&
21716                 ((regcm2 & ~(REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8)) == 0)) { 
21717                 return 0;
21718         }
21719         return (regcm1 & regcm2) ||
21720                 ((regcm1 & gpr_mask) && (regcm2 & gpr_mask));
21721 }
21722
21723 static void arch_reg_equivs(
21724         struct compile_state *state, unsigned *equiv, int reg)
21725 {
21726         if ((reg < 0) || (reg > LAST_REG)) {
21727                 internal_error(state, 0, "invalid register");
21728         }
21729         *equiv++ = reg;
21730         switch(reg) {
21731         case REG_AL:
21732 #if X86_4_8BIT_GPRS
21733                 *equiv++ = REG_AH;
21734 #endif
21735                 *equiv++ = REG_AX;
21736                 *equiv++ = REG_EAX;
21737                 *equiv++ = REG_DXAX;
21738                 *equiv++ = REG_EDXEAX;
21739                 break;
21740         case REG_AH:
21741 #if X86_4_8BIT_GPRS
21742                 *equiv++ = REG_AL;
21743 #endif
21744                 *equiv++ = REG_AX;
21745                 *equiv++ = REG_EAX;
21746                 *equiv++ = REG_DXAX;
21747                 *equiv++ = REG_EDXEAX;
21748                 break;
21749         case REG_BL:  
21750 #if X86_4_8BIT_GPRS
21751                 *equiv++ = REG_BH;
21752 #endif
21753                 *equiv++ = REG_BX;
21754                 *equiv++ = REG_EBX;
21755                 break;
21756
21757         case REG_BH:
21758 #if X86_4_8BIT_GPRS
21759                 *equiv++ = REG_BL;
21760 #endif
21761                 *equiv++ = REG_BX;
21762                 *equiv++ = REG_EBX;
21763                 break;
21764         case REG_CL:
21765 #if X86_4_8BIT_GPRS
21766                 *equiv++ = REG_CH;
21767 #endif
21768                 *equiv++ = REG_CX;
21769                 *equiv++ = REG_ECX;
21770                 break;
21771
21772         case REG_CH:
21773 #if X86_4_8BIT_GPRS
21774                 *equiv++ = REG_CL;
21775 #endif
21776                 *equiv++ = REG_CX;
21777                 *equiv++ = REG_ECX;
21778                 break;
21779         case REG_DL:
21780 #if X86_4_8BIT_GPRS
21781                 *equiv++ = REG_DH;
21782 #endif
21783                 *equiv++ = REG_DX;
21784                 *equiv++ = REG_EDX;
21785                 *equiv++ = REG_DXAX;
21786                 *equiv++ = REG_EDXEAX;
21787                 break;
21788         case REG_DH:
21789 #if X86_4_8BIT_GPRS
21790                 *equiv++ = REG_DL;
21791 #endif
21792                 *equiv++ = REG_DX;
21793                 *equiv++ = REG_EDX;
21794                 *equiv++ = REG_DXAX;
21795                 *equiv++ = REG_EDXEAX;
21796                 break;
21797         case REG_AX:
21798                 *equiv++ = REG_AL;
21799                 *equiv++ = REG_AH;
21800                 *equiv++ = REG_EAX;
21801                 *equiv++ = REG_DXAX;
21802                 *equiv++ = REG_EDXEAX;
21803                 break;
21804         case REG_BX:
21805                 *equiv++ = REG_BL;
21806                 *equiv++ = REG_BH;
21807                 *equiv++ = REG_EBX;
21808                 break;
21809         case REG_CX:  
21810                 *equiv++ = REG_CL;
21811                 *equiv++ = REG_CH;
21812                 *equiv++ = REG_ECX;
21813                 break;
21814         case REG_DX:  
21815                 *equiv++ = REG_DL;
21816                 *equiv++ = REG_DH;
21817                 *equiv++ = REG_EDX;
21818                 *equiv++ = REG_DXAX;
21819                 *equiv++ = REG_EDXEAX;
21820                 break;
21821         case REG_SI:  
21822                 *equiv++ = REG_ESI;
21823                 break;
21824         case REG_DI:
21825                 *equiv++ = REG_EDI;
21826                 break;
21827         case REG_BP:
21828                 *equiv++ = REG_EBP;
21829                 break;
21830         case REG_SP:
21831                 *equiv++ = REG_ESP;
21832                 break;
21833         case REG_EAX:
21834                 *equiv++ = REG_AL;
21835                 *equiv++ = REG_AH;
21836                 *equiv++ = REG_AX;
21837                 *equiv++ = REG_DXAX;
21838                 *equiv++ = REG_EDXEAX;
21839                 break;
21840         case REG_EBX:
21841                 *equiv++ = REG_BL;
21842                 *equiv++ = REG_BH;
21843                 *equiv++ = REG_BX;
21844                 break;
21845         case REG_ECX:
21846                 *equiv++ = REG_CL;
21847                 *equiv++ = REG_CH;
21848                 *equiv++ = REG_CX;
21849                 break;
21850         case REG_EDX:
21851                 *equiv++ = REG_DL;
21852                 *equiv++ = REG_DH;
21853                 *equiv++ = REG_DX;
21854                 *equiv++ = REG_DXAX;
21855                 *equiv++ = REG_EDXEAX;
21856                 break;
21857         case REG_ESI: 
21858                 *equiv++ = REG_SI;
21859                 break;
21860         case REG_EDI: 
21861                 *equiv++ = REG_DI;
21862                 break;
21863         case REG_EBP: 
21864                 *equiv++ = REG_BP;
21865                 break;
21866         case REG_ESP: 
21867                 *equiv++ = REG_SP;
21868                 break;
21869         case REG_DXAX: 
21870                 *equiv++ = REG_AL;
21871                 *equiv++ = REG_AH;
21872                 *equiv++ = REG_DL;
21873                 *equiv++ = REG_DH;
21874                 *equiv++ = REG_AX;
21875                 *equiv++ = REG_DX;
21876                 *equiv++ = REG_EAX;
21877                 *equiv++ = REG_EDX;
21878                 *equiv++ = REG_EDXEAX;
21879                 break;
21880         case REG_EDXEAX: 
21881                 *equiv++ = REG_AL;
21882                 *equiv++ = REG_AH;
21883                 *equiv++ = REG_DL;
21884                 *equiv++ = REG_DH;
21885                 *equiv++ = REG_AX;
21886                 *equiv++ = REG_DX;
21887                 *equiv++ = REG_EAX;
21888                 *equiv++ = REG_EDX;
21889                 *equiv++ = REG_DXAX;
21890                 break;
21891         }
21892         *equiv++ = REG_UNSET; 
21893 }
21894
21895 static unsigned arch_avail_mask(struct compile_state *state)
21896 {
21897         unsigned avail_mask;
21898         /* REGCM_GPR8 is not available */
21899         avail_mask = REGCM_GPR8_LO | REGCM_GPR16_8 | REGCM_GPR16 | 
21900                 REGCM_GPR32 | REGCM_GPR32_8 | 
21901                 REGCM_DIVIDEND32 | REGCM_DIVIDEND64 |
21902                 REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8 | REGCM_FLAGS;
21903         if (state->arch->features & X86_MMX_REGS) {
21904                 avail_mask |= REGCM_MMX;
21905         }
21906         if (state->arch->features & X86_XMM_REGS) {
21907                 avail_mask |= REGCM_XMM;
21908         }
21909         return avail_mask;
21910 }
21911
21912 static unsigned arch_regcm_normalize(struct compile_state *state, unsigned regcm)
21913 {
21914         unsigned mask, result;
21915         int class, class2;
21916         result = regcm;
21917
21918         for(class = 0, mask = 1; mask; mask <<= 1, class++) {
21919                 if ((result & mask) == 0) {
21920                         continue;
21921                 }
21922                 if (class > LAST_REGC) {
21923                         result &= ~mask;
21924                 }
21925                 for(class2 = 0; class2 <= LAST_REGC; class2++) {
21926                         if ((regcm_bound[class2].first >= regcm_bound[class].first) &&
21927                                 (regcm_bound[class2].last <= regcm_bound[class].last)) {
21928                                 result |= (1 << class2);
21929                         }
21930                 }
21931         }
21932         result &= arch_avail_mask(state);
21933         return result;
21934 }
21935
21936 static unsigned arch_regcm_reg_normalize(struct compile_state *state, unsigned regcm)
21937 {
21938         /* Like arch_regcm_normalize except immediate register classes are excluded */
21939         regcm = arch_regcm_normalize(state, regcm);
21940         /* Remove the immediate register classes */
21941         regcm &= ~(REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8);
21942         return regcm;
21943         
21944 }
21945
21946 static unsigned arch_reg_regcm(struct compile_state *state, int reg)
21947 {
21948         unsigned mask;
21949         int class;
21950         mask = 0;
21951         for(class = 0; class <= LAST_REGC; class++) {
21952                 if ((reg >= regcm_bound[class].first) &&
21953                         (reg <= regcm_bound[class].last)) {
21954                         mask |= (1 << class);
21955                 }
21956         }
21957         if (!mask) {
21958                 internal_error(state, 0, "reg %d not in any class", reg);
21959         }
21960         return mask;
21961 }
21962
21963 static struct reg_info arch_reg_constraint(
21964         struct compile_state *state, struct type *type, const char *constraint)
21965 {
21966         static const struct {
21967                 char class;
21968                 unsigned int mask;
21969                 unsigned int reg;
21970         } constraints[] = {
21971                 { 'r', REGCM_GPR32,   REG_UNSET },
21972                 { 'g', REGCM_GPR32,   REG_UNSET },
21973                 { 'p', REGCM_GPR32,   REG_UNSET },
21974                 { 'q', REGCM_GPR8_LO, REG_UNSET },
21975                 { 'Q', REGCM_GPR32_8, REG_UNSET },
21976                 { 'x', REGCM_XMM,     REG_UNSET },
21977                 { 'y', REGCM_MMX,     REG_UNSET },
21978                 { 'a', REGCM_GPR32,   REG_EAX },
21979                 { 'b', REGCM_GPR32,   REG_EBX },
21980                 { 'c', REGCM_GPR32,   REG_ECX },
21981                 { 'd', REGCM_GPR32,   REG_EDX },
21982                 { 'D', REGCM_GPR32,   REG_EDI },
21983                 { 'S', REGCM_GPR32,   REG_ESI },
21984                 { '\0', 0, REG_UNSET },
21985         };
21986         unsigned int regcm;
21987         unsigned int mask, reg;
21988         struct reg_info result;
21989         const char *ptr;
21990         regcm = arch_type_to_regcm(state, type);
21991         reg = REG_UNSET;
21992         mask = 0;
21993         for(ptr = constraint; *ptr; ptr++) {
21994                 int i;
21995                 if (*ptr ==  ' ') {
21996                         continue;
21997                 }
21998                 for(i = 0; constraints[i].class != '\0'; i++) {
21999                         if (constraints[i].class == *ptr) {
22000                                 break;
22001                         }
22002                 }
22003                 if (constraints[i].class == '\0') {
22004                         error(state, 0, "invalid register constraint ``%c''", *ptr);
22005                         break;
22006                 }
22007                 if ((constraints[i].mask & regcm) == 0) {
22008                         error(state, 0, "invalid register class %c specified",
22009                                 *ptr);
22010                 }
22011                 mask |= constraints[i].mask;
22012                 if (constraints[i].reg != REG_UNSET) {
22013                         if ((reg != REG_UNSET) && (reg != constraints[i].reg)) {
22014                                 error(state, 0, "Only one register may be specified");
22015                         }
22016                         reg = constraints[i].reg;
22017                 }
22018         }
22019         result.reg = reg;
22020         result.regcm = mask;
22021         return result;
22022 }
22023
22024 static struct reg_info arch_reg_clobber(
22025         struct compile_state *state, const char *clobber)
22026 {
22027         struct reg_info result;
22028         if (strcmp(clobber, "memory") == 0) {
22029                 result.reg = REG_UNSET;
22030                 result.regcm = 0;
22031         }
22032         else if (strcmp(clobber, "eax") == 0) {
22033                 result.reg = REG_EAX;
22034                 result.regcm = REGCM_GPR32;
22035         }
22036         else if (strcmp(clobber, "ebx") == 0) {
22037                 result.reg = REG_EBX;
22038                 result.regcm = REGCM_GPR32;
22039         }
22040         else if (strcmp(clobber, "ecx") == 0) {
22041                 result.reg = REG_ECX;
22042                 result.regcm = REGCM_GPR32;
22043         }
22044         else if (strcmp(clobber, "edx") == 0) {
22045                 result.reg = REG_EDX;
22046                 result.regcm = REGCM_GPR32;
22047         }
22048         else if (strcmp(clobber, "esi") == 0) {
22049                 result.reg = REG_ESI;
22050                 result.regcm = REGCM_GPR32;
22051         }
22052         else if (strcmp(clobber, "edi") == 0) {
22053                 result.reg = REG_EDI;
22054                 result.regcm = REGCM_GPR32;
22055         }
22056         else if (strcmp(clobber, "ebp") == 0) {
22057                 result.reg = REG_EBP;
22058                 result.regcm = REGCM_GPR32;
22059         }
22060         else if (strcmp(clobber, "esp") == 0) {
22061                 result.reg = REG_ESP;
22062                 result.regcm = REGCM_GPR32;
22063         }
22064         else if (strcmp(clobber, "cc") == 0) {
22065                 result.reg = REG_EFLAGS;
22066                 result.regcm = REGCM_FLAGS;
22067         }
22068         else if ((strncmp(clobber, "xmm", 3) == 0)  &&
22069                 octdigitp(clobber[3]) && (clobber[4] == '\0')) {
22070                 result.reg = REG_XMM0 + octdigval(clobber[3]);
22071                 result.regcm = REGCM_XMM;
22072         }
22073         else if ((strncmp(clobber, "mm", 2) == 0) &&
22074                 octdigitp(clobber[3]) && (clobber[4] == '\0')) {
22075                 result.reg = REG_MMX0 + octdigval(clobber[3]);
22076                 result.regcm = REGCM_MMX;
22077         }
22078         else {
22079                 error(state, 0, "unknown register name `%s' in asm",
22080                         clobber);
22081                 result.reg = REG_UNSET;
22082                 result.regcm = 0;
22083         }
22084         return result;
22085 }
22086
22087 static int do_select_reg(struct compile_state *state, 
22088         char *used, int reg, unsigned classes)
22089 {
22090         unsigned mask;
22091         if (used[reg]) {
22092                 return REG_UNSET;
22093         }
22094         mask = arch_reg_regcm(state, reg);
22095         return (classes & mask) ? reg : REG_UNSET;
22096 }
22097
22098 static int arch_select_free_register(
22099         struct compile_state *state, char *used, int classes)
22100 {
22101         /* Live ranges with the most neighbors are colored first.
22102          *
22103          * Generally it does not matter which colors are given
22104          * as the register allocator attempts to color live ranges
22105          * in an order where you are guaranteed not to run out of colors.
22106          *
22107          * Occasionally the register allocator cannot find an order
22108          * of register selection that will find a free color.  To
22109          * increase the odds the register allocator will work when
22110          * it guesses first give out registers from register classes
22111          * least likely to run out of registers.
22112          * 
22113          */
22114         int i, reg;
22115         reg = REG_UNSET;
22116         for(i = REGC_XMM_FIRST; (reg == REG_UNSET) && (i <= REGC_XMM_LAST); i++) {
22117                 reg = do_select_reg(state, used, i, classes);
22118         }
22119         for(i = REGC_MMX_FIRST; (reg == REG_UNSET) && (i <= REGC_MMX_LAST); i++) {
22120                 reg = do_select_reg(state, used, i, classes);
22121         }
22122         for(i = REGC_GPR32_LAST; (reg == REG_UNSET) && (i >= REGC_GPR32_FIRST); i--) {
22123                 reg = do_select_reg(state, used, i, classes);
22124         }
22125         for(i = REGC_GPR16_FIRST; (reg == REG_UNSET) && (i <= REGC_GPR16_LAST); i++) {
22126                 reg = do_select_reg(state, used, i, classes);
22127         }
22128         for(i = REGC_GPR8_FIRST; (reg == REG_UNSET) && (i <= REGC_GPR8_LAST); i++) {
22129                 reg = do_select_reg(state, used, i, classes);
22130         }
22131         for(i = REGC_GPR8_LO_FIRST; (reg == REG_UNSET) && (i <= REGC_GPR8_LO_LAST); i++) {
22132                 reg = do_select_reg(state, used, i, classes);
22133         }
22134         for(i = REGC_DIVIDEND32_FIRST; (reg == REG_UNSET) && (i <= REGC_DIVIDEND32_LAST); i++) {
22135                 reg = do_select_reg(state, used, i, classes);
22136         }
22137         for(i = REGC_DIVIDEND64_FIRST; (reg == REG_UNSET) && (i <= REGC_DIVIDEND64_LAST); i++) {
22138                 reg = do_select_reg(state, used, i, classes);
22139         }
22140         for(i = REGC_FLAGS_FIRST; (reg == REG_UNSET) && (i <= REGC_FLAGS_LAST); i++) {
22141                 reg = do_select_reg(state, used, i, classes);
22142         }
22143         return reg;
22144 }
22145
22146
22147 static unsigned arch_type_to_regcm(struct compile_state *state, struct type *type) 
22148 {
22149 #warning "FIXME force types smaller (if legal) before I get here"
22150         unsigned mask;
22151         mask = 0;
22152         switch(type->type & TYPE_MASK) {
22153         case TYPE_ARRAY:
22154         case TYPE_VOID: 
22155                 mask = 0; 
22156                 break;
22157         case TYPE_CHAR:
22158         case TYPE_UCHAR:
22159                 mask = REGCM_GPR8 | REGCM_GPR8_LO |
22160                         REGCM_GPR16 | REGCM_GPR16_8 | 
22161                         REGCM_GPR32 | REGCM_GPR32_8 |
22162                         REGCM_DIVIDEND32 | REGCM_DIVIDEND64 |
22163                         REGCM_MMX | REGCM_XMM |
22164                         REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8;
22165                 break;
22166         case TYPE_SHORT:
22167         case TYPE_USHORT:
22168                 mask =  REGCM_GPR16 | REGCM_GPR16_8 |
22169                         REGCM_GPR32 | REGCM_GPR32_8 |
22170                         REGCM_DIVIDEND32 | REGCM_DIVIDEND64 |
22171                         REGCM_MMX | REGCM_XMM |
22172                         REGCM_IMM32 | REGCM_IMM16;
22173                 break;
22174         case TYPE_ENUM:
22175         case TYPE_INT:
22176         case TYPE_UINT:
22177         case TYPE_LONG:
22178         case TYPE_ULONG:
22179         case TYPE_POINTER:
22180                 mask =  REGCM_GPR32 | REGCM_GPR32_8 |
22181                         REGCM_DIVIDEND32 | REGCM_DIVIDEND64 |
22182                         REGCM_MMX | REGCM_XMM |
22183                         REGCM_IMM32;
22184                 break;
22185         case TYPE_JOIN:
22186         case TYPE_UNION:
22187                 mask = arch_type_to_regcm(state, type->left);
22188                 break;
22189         case TYPE_OVERLAP:
22190                 mask = arch_type_to_regcm(state, type->left) &
22191                         arch_type_to_regcm(state, type->right);
22192                 break;
22193         case TYPE_BITFIELD:
22194                 mask = arch_type_to_regcm(state, type->left);
22195                 break;
22196         default:
22197                 fprintf(state->errout, "type: ");
22198                 name_of(state->errout, type);
22199                 fprintf(state->errout, "\n");
22200                 internal_error(state, 0, "no register class for type");
22201                 break;
22202         }
22203         mask = arch_regcm_normalize(state, mask);
22204         return mask;
22205 }
22206
22207 static int is_imm32(struct triple *imm)
22208 {
22209         return ((imm->op == OP_INTCONST) && (imm->u.cval <= 0xffffffffUL)) ||
22210                 (imm->op == OP_ADDRCONST);
22211         
22212 }
22213 static int is_imm16(struct triple *imm)
22214 {
22215         return ((imm->op == OP_INTCONST) && (imm->u.cval <= 0xffff));
22216 }
22217 static int is_imm8(struct triple *imm)
22218 {
22219         return ((imm->op == OP_INTCONST) && (imm->u.cval <= 0xff));
22220 }
22221
22222 static int get_imm32(struct triple *ins, struct triple **expr)
22223 {
22224         struct triple *imm;
22225         imm = *expr;
22226         while(imm->op == OP_COPY) {
22227                 imm = RHS(imm, 0);
22228         }
22229         if (!is_imm32(imm)) {
22230                 return 0;
22231         }
22232         unuse_triple(*expr, ins);
22233         use_triple(imm, ins);
22234         *expr = imm;
22235         return 1;
22236 }
22237
22238 static int get_imm8(struct triple *ins, struct triple **expr)
22239 {
22240         struct triple *imm;
22241         imm = *expr;
22242         while(imm->op == OP_COPY) {
22243                 imm = RHS(imm, 0);
22244         }
22245         if (!is_imm8(imm)) {
22246                 return 0;
22247         }
22248         unuse_triple(*expr, ins);
22249         use_triple(imm, ins);
22250         *expr = imm;
22251         return 1;
22252 }
22253
22254 #define TEMPLATE_NOP           0
22255 #define TEMPLATE_INTCONST8     1
22256 #define TEMPLATE_INTCONST32    2
22257 #define TEMPLATE_UNKNOWNVAL    3
22258 #define TEMPLATE_COPY8_REG     5
22259 #define TEMPLATE_COPY16_REG    6
22260 #define TEMPLATE_COPY32_REG    7
22261 #define TEMPLATE_COPY_IMM8     8
22262 #define TEMPLATE_COPY_IMM16    9
22263 #define TEMPLATE_COPY_IMM32   10
22264 #define TEMPLATE_PHI8         11
22265 #define TEMPLATE_PHI16        12
22266 #define TEMPLATE_PHI32        13
22267 #define TEMPLATE_STORE8       14
22268 #define TEMPLATE_STORE16      15
22269 #define TEMPLATE_STORE32      16
22270 #define TEMPLATE_LOAD8        17
22271 #define TEMPLATE_LOAD16       18
22272 #define TEMPLATE_LOAD32       19
22273 #define TEMPLATE_BINARY8_REG  20
22274 #define TEMPLATE_BINARY16_REG 21
22275 #define TEMPLATE_BINARY32_REG 22
22276 #define TEMPLATE_BINARY8_IMM  23
22277 #define TEMPLATE_BINARY16_IMM 24
22278 #define TEMPLATE_BINARY32_IMM 25
22279 #define TEMPLATE_SL8_CL       26
22280 #define TEMPLATE_SL16_CL      27
22281 #define TEMPLATE_SL32_CL      28
22282 #define TEMPLATE_SL8_IMM      29
22283 #define TEMPLATE_SL16_IMM     30
22284 #define TEMPLATE_SL32_IMM     31
22285 #define TEMPLATE_UNARY8       32
22286 #define TEMPLATE_UNARY16      33
22287 #define TEMPLATE_UNARY32      34
22288 #define TEMPLATE_CMP8_REG     35
22289 #define TEMPLATE_CMP16_REG    36
22290 #define TEMPLATE_CMP32_REG    37
22291 #define TEMPLATE_CMP8_IMM     38
22292 #define TEMPLATE_CMP16_IMM    39
22293 #define TEMPLATE_CMP32_IMM    40
22294 #define TEMPLATE_TEST8        41
22295 #define TEMPLATE_TEST16       42
22296 #define TEMPLATE_TEST32       43
22297 #define TEMPLATE_SET          44
22298 #define TEMPLATE_JMP          45
22299 #define TEMPLATE_RET          46
22300 #define TEMPLATE_INB_DX       47
22301 #define TEMPLATE_INB_IMM      48
22302 #define TEMPLATE_INW_DX       49
22303 #define TEMPLATE_INW_IMM      50
22304 #define TEMPLATE_INL_DX       51
22305 #define TEMPLATE_INL_IMM      52
22306 #define TEMPLATE_OUTB_DX      53
22307 #define TEMPLATE_OUTB_IMM     54
22308 #define TEMPLATE_OUTW_DX      55
22309 #define TEMPLATE_OUTW_IMM     56
22310 #define TEMPLATE_OUTL_DX      57
22311 #define TEMPLATE_OUTL_IMM     58
22312 #define TEMPLATE_BSF          59
22313 #define TEMPLATE_RDMSR        60
22314 #define TEMPLATE_WRMSR        61
22315 #define TEMPLATE_UMUL8        62
22316 #define TEMPLATE_UMUL16       63
22317 #define TEMPLATE_UMUL32       64
22318 #define TEMPLATE_DIV8         65
22319 #define TEMPLATE_DIV16        66
22320 #define TEMPLATE_DIV32        67
22321 #define LAST_TEMPLATE       TEMPLATE_DIV32
22322 #if LAST_TEMPLATE >= MAX_TEMPLATES
22323 #error "MAX_TEMPLATES to low"
22324 #endif
22325
22326 #define COPY8_REGCM     (REGCM_DIVIDEND64 | REGCM_DIVIDEND32 | REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO | REGCM_MMX | REGCM_XMM)
22327 #define COPY16_REGCM    (REGCM_DIVIDEND64 | REGCM_DIVIDEND32 | REGCM_GPR32 | REGCM_GPR16 | REGCM_MMX | REGCM_XMM)  
22328 #define COPY32_REGCM    (REGCM_DIVIDEND64 | REGCM_DIVIDEND32 | REGCM_GPR32 | REGCM_MMX | REGCM_XMM)
22329
22330
22331 static struct ins_template templates[] = {
22332         [TEMPLATE_NOP]      = {
22333                 .lhs = { 
22334                         [ 0] = { REG_UNNEEDED, REGCM_IMMALL },
22335                         [ 1] = { REG_UNNEEDED, REGCM_IMMALL },
22336                         [ 2] = { REG_UNNEEDED, REGCM_IMMALL },
22337                         [ 3] = { REG_UNNEEDED, REGCM_IMMALL },
22338                         [ 4] = { REG_UNNEEDED, REGCM_IMMALL },
22339                         [ 5] = { REG_UNNEEDED, REGCM_IMMALL },
22340                         [ 6] = { REG_UNNEEDED, REGCM_IMMALL },
22341                         [ 7] = { REG_UNNEEDED, REGCM_IMMALL },
22342                         [ 8] = { REG_UNNEEDED, REGCM_IMMALL },
22343                         [ 9] = { REG_UNNEEDED, REGCM_IMMALL },
22344                         [10] = { REG_UNNEEDED, REGCM_IMMALL },
22345                         [11] = { REG_UNNEEDED, REGCM_IMMALL },
22346                         [12] = { REG_UNNEEDED, REGCM_IMMALL },
22347                         [13] = { REG_UNNEEDED, REGCM_IMMALL },
22348                         [14] = { REG_UNNEEDED, REGCM_IMMALL },
22349                         [15] = { REG_UNNEEDED, REGCM_IMMALL },
22350                         [16] = { REG_UNNEEDED, REGCM_IMMALL },
22351                         [17] = { REG_UNNEEDED, REGCM_IMMALL },
22352                         [18] = { REG_UNNEEDED, REGCM_IMMALL },
22353                         [19] = { REG_UNNEEDED, REGCM_IMMALL },
22354                         [20] = { REG_UNNEEDED, REGCM_IMMALL },
22355                         [21] = { REG_UNNEEDED, REGCM_IMMALL },
22356                         [22] = { REG_UNNEEDED, REGCM_IMMALL },
22357                         [23] = { REG_UNNEEDED, REGCM_IMMALL },
22358                         [24] = { REG_UNNEEDED, REGCM_IMMALL },
22359                         [25] = { REG_UNNEEDED, REGCM_IMMALL },
22360                         [26] = { REG_UNNEEDED, REGCM_IMMALL },
22361                         [27] = { REG_UNNEEDED, REGCM_IMMALL },
22362                         [28] = { REG_UNNEEDED, REGCM_IMMALL },
22363                         [29] = { REG_UNNEEDED, REGCM_IMMALL },
22364                         [30] = { REG_UNNEEDED, REGCM_IMMALL },
22365                         [31] = { REG_UNNEEDED, REGCM_IMMALL },
22366                         [32] = { REG_UNNEEDED, REGCM_IMMALL },
22367                         [33] = { REG_UNNEEDED, REGCM_IMMALL },
22368                         [34] = { REG_UNNEEDED, REGCM_IMMALL },
22369                         [35] = { REG_UNNEEDED, REGCM_IMMALL },
22370                         [36] = { REG_UNNEEDED, REGCM_IMMALL },
22371                         [37] = { REG_UNNEEDED, REGCM_IMMALL },
22372                         [38] = { REG_UNNEEDED, REGCM_IMMALL },
22373                         [39] = { REG_UNNEEDED, REGCM_IMMALL },
22374                         [40] = { REG_UNNEEDED, REGCM_IMMALL },
22375                         [41] = { REG_UNNEEDED, REGCM_IMMALL },
22376                         [42] = { REG_UNNEEDED, REGCM_IMMALL },
22377                         [43] = { REG_UNNEEDED, REGCM_IMMALL },
22378                         [44] = { REG_UNNEEDED, REGCM_IMMALL },
22379                         [45] = { REG_UNNEEDED, REGCM_IMMALL },
22380                         [46] = { REG_UNNEEDED, REGCM_IMMALL },
22381                         [47] = { REG_UNNEEDED, REGCM_IMMALL },
22382                         [48] = { REG_UNNEEDED, REGCM_IMMALL },
22383                         [49] = { REG_UNNEEDED, REGCM_IMMALL },
22384                         [50] = { REG_UNNEEDED, REGCM_IMMALL },
22385                         [51] = { REG_UNNEEDED, REGCM_IMMALL },
22386                         [52] = { REG_UNNEEDED, REGCM_IMMALL },
22387                         [53] = { REG_UNNEEDED, REGCM_IMMALL },
22388                         [54] = { REG_UNNEEDED, REGCM_IMMALL },
22389                         [55] = { REG_UNNEEDED, REGCM_IMMALL },
22390                         [56] = { REG_UNNEEDED, REGCM_IMMALL },
22391                         [57] = { REG_UNNEEDED, REGCM_IMMALL },
22392                         [58] = { REG_UNNEEDED, REGCM_IMMALL },
22393                         [59] = { REG_UNNEEDED, REGCM_IMMALL },
22394                         [60] = { REG_UNNEEDED, REGCM_IMMALL },
22395                         [61] = { REG_UNNEEDED, REGCM_IMMALL },
22396                         [62] = { REG_UNNEEDED, REGCM_IMMALL },
22397                         [63] = { REG_UNNEEDED, REGCM_IMMALL },
22398                 },
22399         },
22400         [TEMPLATE_INTCONST8] = { 
22401                 .lhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
22402         },
22403         [TEMPLATE_INTCONST32] = { 
22404                 .lhs = { [0] = { REG_UNNEEDED, REGCM_IMM32 } },
22405         },
22406         [TEMPLATE_UNKNOWNVAL] = {
22407                 .lhs = { [0] = { REG_UNSET, COPY32_REGCM } },
22408         },
22409         [TEMPLATE_COPY8_REG] = {
22410                 .lhs = { [0] = { REG_UNSET, COPY8_REGCM } },
22411                 .rhs = { [0] = { REG_UNSET, COPY8_REGCM }  },
22412         },
22413         [TEMPLATE_COPY16_REG] = {
22414                 .lhs = { [0] = { REG_UNSET, COPY16_REGCM } },
22415                 .rhs = { [0] = { REG_UNSET, COPY16_REGCM }  },
22416         },
22417         [TEMPLATE_COPY32_REG] = {
22418                 .lhs = { [0] = { REG_UNSET, COPY32_REGCM } },
22419                 .rhs = { [0] = { REG_UNSET, COPY32_REGCM }  },
22420         },
22421         [TEMPLATE_COPY_IMM8] = {
22422                 .lhs = { [0] = { REG_UNSET, COPY8_REGCM } },
22423                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
22424         },
22425         [TEMPLATE_COPY_IMM16] = {
22426                 .lhs = { [0] = { REG_UNSET, COPY16_REGCM } },
22427                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM16 | REGCM_IMM8 } },
22428         },
22429         [TEMPLATE_COPY_IMM32] = {
22430                 .lhs = { [0] = { REG_UNSET, COPY32_REGCM } },
22431                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8 } },
22432         },
22433         [TEMPLATE_PHI8] = { 
22434                 .lhs = { [0] = { REG_VIRT0, COPY8_REGCM } },
22435                 .rhs = { [0] = { REG_VIRT0, COPY8_REGCM } },
22436         },
22437         [TEMPLATE_PHI16] = { 
22438                 .lhs = { [0] = { REG_VIRT0, COPY16_REGCM } },
22439                 .rhs = { [0] = { REG_VIRT0, COPY16_REGCM } }, 
22440         },
22441         [TEMPLATE_PHI32] = { 
22442                 .lhs = { [0] = { REG_VIRT0, COPY32_REGCM } },
22443                 .rhs = { [0] = { REG_VIRT0, COPY32_REGCM } }, 
22444         },
22445         [TEMPLATE_STORE8] = {
22446                 .rhs = { 
22447                         [0] = { REG_UNSET, REGCM_GPR32 },
22448                         [1] = { REG_UNSET, REGCM_GPR8_LO },
22449                 },
22450         },
22451         [TEMPLATE_STORE16] = {
22452                 .rhs = { 
22453                         [0] = { REG_UNSET, REGCM_GPR32 },
22454                         [1] = { REG_UNSET, REGCM_GPR16 },
22455                 },
22456         },
22457         [TEMPLATE_STORE32] = {
22458                 .rhs = { 
22459                         [0] = { REG_UNSET, REGCM_GPR32 },
22460                         [1] = { REG_UNSET, REGCM_GPR32 },
22461                 },
22462         },
22463         [TEMPLATE_LOAD8] = {
22464                 .lhs = { [0] = { REG_UNSET, REGCM_GPR8_LO } },
22465                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
22466         },
22467         [TEMPLATE_LOAD16] = {
22468                 .lhs = { [0] = { REG_UNSET, REGCM_GPR16 } },
22469                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
22470         },
22471         [TEMPLATE_LOAD32] = {
22472                 .lhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
22473                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
22474         },
22475         [TEMPLATE_BINARY8_REG] = {
22476                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
22477                 .rhs = { 
22478                         [0] = { REG_VIRT0, REGCM_GPR8_LO },
22479                         [1] = { REG_UNSET, REGCM_GPR8_LO },
22480                 },
22481         },
22482         [TEMPLATE_BINARY16_REG] = {
22483                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
22484                 .rhs = { 
22485                         [0] = { REG_VIRT0, REGCM_GPR16 },
22486                         [1] = { REG_UNSET, REGCM_GPR16 },
22487                 },
22488         },
22489         [TEMPLATE_BINARY32_REG] = {
22490                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
22491                 .rhs = { 
22492                         [0] = { REG_VIRT0, REGCM_GPR32 },
22493                         [1] = { REG_UNSET, REGCM_GPR32 },
22494                 },
22495         },
22496         [TEMPLATE_BINARY8_IMM] = {
22497                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
22498                 .rhs = { 
22499                         [0] = { REG_VIRT0,    REGCM_GPR8_LO },
22500                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
22501                 },
22502         },
22503         [TEMPLATE_BINARY16_IMM] = {
22504                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
22505                 .rhs = { 
22506                         [0] = { REG_VIRT0,    REGCM_GPR16 },
22507                         [1] = { REG_UNNEEDED, REGCM_IMM16 },
22508                 },
22509         },
22510         [TEMPLATE_BINARY32_IMM] = {
22511                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
22512                 .rhs = { 
22513                         [0] = { REG_VIRT0,    REGCM_GPR32 },
22514                         [1] = { REG_UNNEEDED, REGCM_IMM32 },
22515                 },
22516         },
22517         [TEMPLATE_SL8_CL] = {
22518                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
22519                 .rhs = { 
22520                         [0] = { REG_VIRT0, REGCM_GPR8_LO },
22521                         [1] = { REG_CL, REGCM_GPR8_LO },
22522                 },
22523         },
22524         [TEMPLATE_SL16_CL] = {
22525                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
22526                 .rhs = { 
22527                         [0] = { REG_VIRT0, REGCM_GPR16 },
22528                         [1] = { REG_CL, REGCM_GPR8_LO },
22529                 },
22530         },
22531         [TEMPLATE_SL32_CL] = {
22532                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
22533                 .rhs = { 
22534                         [0] = { REG_VIRT0, REGCM_GPR32 },
22535                         [1] = { REG_CL, REGCM_GPR8_LO },
22536                 },
22537         },
22538         [TEMPLATE_SL8_IMM] = {
22539                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
22540                 .rhs = { 
22541                         [0] = { REG_VIRT0,    REGCM_GPR8_LO },
22542                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
22543                 },
22544         },
22545         [TEMPLATE_SL16_IMM] = {
22546                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
22547                 .rhs = { 
22548                         [0] = { REG_VIRT0,    REGCM_GPR16 },
22549                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
22550                 },
22551         },
22552         [TEMPLATE_SL32_IMM] = {
22553                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
22554                 .rhs = { 
22555                         [0] = { REG_VIRT0,    REGCM_GPR32 },
22556                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
22557                 },
22558         },
22559         [TEMPLATE_UNARY8] = {
22560                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
22561                 .rhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
22562         },
22563         [TEMPLATE_UNARY16] = {
22564                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
22565                 .rhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
22566         },
22567         [TEMPLATE_UNARY32] = {
22568                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
22569                 .rhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
22570         },
22571         [TEMPLATE_CMP8_REG] = {
22572                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22573                 .rhs = {
22574                         [0] = { REG_UNSET, REGCM_GPR8_LO },
22575                         [1] = { REG_UNSET, REGCM_GPR8_LO },
22576                 },
22577         },
22578         [TEMPLATE_CMP16_REG] = {
22579                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22580                 .rhs = {
22581                         [0] = { REG_UNSET, REGCM_GPR16 },
22582                         [1] = { REG_UNSET, REGCM_GPR16 },
22583                 },
22584         },
22585         [TEMPLATE_CMP32_REG] = {
22586                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22587                 .rhs = {
22588                         [0] = { REG_UNSET, REGCM_GPR32 },
22589                         [1] = { REG_UNSET, REGCM_GPR32 },
22590                 },
22591         },
22592         [TEMPLATE_CMP8_IMM] = {
22593                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22594                 .rhs = {
22595                         [0] = { REG_UNSET, REGCM_GPR8_LO },
22596                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
22597                 },
22598         },
22599         [TEMPLATE_CMP16_IMM] = {
22600                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22601                 .rhs = {
22602                         [0] = { REG_UNSET, REGCM_GPR16 },
22603                         [1] = { REG_UNNEEDED, REGCM_IMM16 },
22604                 },
22605         },
22606         [TEMPLATE_CMP32_IMM] = {
22607                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22608                 .rhs = {
22609                         [0] = { REG_UNSET, REGCM_GPR32 },
22610                         [1] = { REG_UNNEEDED, REGCM_IMM32 },
22611                 },
22612         },
22613         [TEMPLATE_TEST8] = {
22614                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22615                 .rhs = { [0] = { REG_UNSET, REGCM_GPR8_LO } },
22616         },
22617         [TEMPLATE_TEST16] = {
22618                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22619                 .rhs = { [0] = { REG_UNSET, REGCM_GPR16 } },
22620         },
22621         [TEMPLATE_TEST32] = {
22622                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22623                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
22624         },
22625         [TEMPLATE_SET] = {
22626                 .lhs = { [0] = { REG_UNSET, REGCM_GPR8_LO } },
22627                 .rhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22628         },
22629         [TEMPLATE_JMP] = {
22630                 .rhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22631         },
22632         [TEMPLATE_RET] = {
22633                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
22634         },
22635         [TEMPLATE_INB_DX] = {
22636                 .lhs = { [0] = { REG_AL,  REGCM_GPR8_LO } },  
22637                 .rhs = { [0] = { REG_DX, REGCM_GPR16 } },
22638         },
22639         [TEMPLATE_INB_IMM] = {
22640                 .lhs = { [0] = { REG_AL,  REGCM_GPR8_LO } },  
22641                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
22642         },
22643         [TEMPLATE_INW_DX]  = { 
22644                 .lhs = { [0] = { REG_AX,  REGCM_GPR16 } }, 
22645                 .rhs = { [0] = { REG_DX, REGCM_GPR16 } },
22646         },
22647         [TEMPLATE_INW_IMM] = { 
22648                 .lhs = { [0] = { REG_AX,  REGCM_GPR16 } }, 
22649                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
22650         },
22651         [TEMPLATE_INL_DX]  = {
22652                 .lhs = { [0] = { REG_EAX, REGCM_GPR32 } },
22653                 .rhs = { [0] = { REG_DX, REGCM_GPR16 } },
22654         },
22655         [TEMPLATE_INL_IMM] = {
22656                 .lhs = { [0] = { REG_EAX, REGCM_GPR32 } },
22657                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
22658         },
22659         [TEMPLATE_OUTB_DX] = { 
22660                 .rhs = {
22661                         [0] = { REG_AL,  REGCM_GPR8_LO },
22662                         [1] = { REG_DX, REGCM_GPR16 },
22663                 },
22664         },
22665         [TEMPLATE_OUTB_IMM] = { 
22666                 .rhs = {
22667                         [0] = { REG_AL,  REGCM_GPR8_LO },  
22668                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
22669                 },
22670         },
22671         [TEMPLATE_OUTW_DX] = { 
22672                 .rhs = {
22673                         [0] = { REG_AX,  REGCM_GPR16 },
22674                         [1] = { REG_DX, REGCM_GPR16 },
22675                 },
22676         },
22677         [TEMPLATE_OUTW_IMM] = {
22678                 .rhs = {
22679                         [0] = { REG_AX,  REGCM_GPR16 }, 
22680                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
22681                 },
22682         },
22683         [TEMPLATE_OUTL_DX] = { 
22684                 .rhs = {
22685                         [0] = { REG_EAX, REGCM_GPR32 },
22686                         [1] = { REG_DX, REGCM_GPR16 },
22687                 },
22688         },
22689         [TEMPLATE_OUTL_IMM] = { 
22690                 .rhs = {
22691                         [0] = { REG_EAX, REGCM_GPR32 }, 
22692                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
22693                 },
22694         },
22695         [TEMPLATE_BSF] = {
22696                 .lhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
22697                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
22698         },
22699         [TEMPLATE_RDMSR] = {
22700                 .lhs = { 
22701                         [0] = { REG_EAX, REGCM_GPR32 },
22702                         [1] = { REG_EDX, REGCM_GPR32 },
22703                 },
22704                 .rhs = { [0] = { REG_ECX, REGCM_GPR32 } },
22705         },
22706         [TEMPLATE_WRMSR] = {
22707                 .rhs = {
22708                         [0] = { REG_ECX, REGCM_GPR32 },
22709                         [1] = { REG_EAX, REGCM_GPR32 },
22710                         [2] = { REG_EDX, REGCM_GPR32 },
22711                 },
22712         },
22713         [TEMPLATE_UMUL8] = {
22714                 .lhs = { [0] = { REG_AX, REGCM_GPR16 } },
22715                 .rhs = { 
22716                         [0] = { REG_AL, REGCM_GPR8_LO },
22717                         [1] = { REG_UNSET, REGCM_GPR8_LO },
22718                 },
22719         },
22720         [TEMPLATE_UMUL16] = {
22721                 .lhs = { [0] = { REG_DXAX, REGCM_DIVIDEND32 } },
22722                 .rhs = { 
22723                         [0] = { REG_AX, REGCM_GPR16 },
22724                         [1] = { REG_UNSET, REGCM_GPR16 },
22725                 },
22726         },
22727         [TEMPLATE_UMUL32] = {
22728                 .lhs = { [0] = { REG_EDXEAX, REGCM_DIVIDEND64 } },
22729                 .rhs = { 
22730                         [0] = { REG_EAX, REGCM_GPR32 },
22731                         [1] = { REG_UNSET, REGCM_GPR32 },
22732                 },
22733         },
22734         [TEMPLATE_DIV8] = {
22735                 .lhs = { 
22736                         [0] = { REG_AL, REGCM_GPR8_LO },
22737                         [1] = { REG_AH, REGCM_GPR8 },
22738                 },
22739                 .rhs = {
22740                         [0] = { REG_AX, REGCM_GPR16 },
22741                         [1] = { REG_UNSET, REGCM_GPR8_LO },
22742                 },
22743         },
22744         [TEMPLATE_DIV16] = {
22745                 .lhs = { 
22746                         [0] = { REG_AX, REGCM_GPR16 },
22747                         [1] = { REG_DX, REGCM_GPR16 },
22748                 },
22749                 .rhs = {
22750                         [0] = { REG_DXAX, REGCM_DIVIDEND32 },
22751                         [1] = { REG_UNSET, REGCM_GPR16 },
22752                 },
22753         },
22754         [TEMPLATE_DIV32] = {
22755                 .lhs = { 
22756                         [0] = { REG_EAX, REGCM_GPR32 },
22757                         [1] = { REG_EDX, REGCM_GPR32 },
22758                 },
22759                 .rhs = {
22760                         [0] = { REG_EDXEAX, REGCM_DIVIDEND64 },
22761                         [1] = { REG_UNSET, REGCM_GPR32 },
22762                 },
22763         },
22764 };
22765
22766 static void fixup_branch(struct compile_state *state,
22767         struct triple *branch, int jmp_op, int cmp_op, struct type *cmp_type,
22768         struct triple *left, struct triple *right)
22769 {
22770         struct triple *test;
22771         if (!left) {
22772                 internal_error(state, branch, "no branch test?");
22773         }
22774         test = pre_triple(state, branch,
22775                 cmp_op, cmp_type, left, right);
22776         test->template_id = TEMPLATE_TEST32; 
22777         if (cmp_op == OP_CMP) {
22778                 test->template_id = TEMPLATE_CMP32_REG;
22779                 if (get_imm32(test, &RHS(test, 1))) {
22780                         test->template_id = TEMPLATE_CMP32_IMM;
22781                 }
22782         }
22783         use_triple(RHS(test, 0), test);
22784         use_triple(RHS(test, 1), test);
22785         unuse_triple(RHS(branch, 0), branch);
22786         RHS(branch, 0) = test;
22787         branch->op = jmp_op;
22788         branch->template_id = TEMPLATE_JMP;
22789         use_triple(RHS(branch, 0), branch);
22790 }
22791
22792 static void fixup_branches(struct compile_state *state,
22793         struct triple *cmp, struct triple *use, int jmp_op)
22794 {
22795         struct triple_set *entry, *next;
22796         for(entry = use->use; entry; entry = next) {
22797                 next = entry->next;
22798                 if (entry->member->op == OP_COPY) {
22799                         fixup_branches(state, cmp, entry->member, jmp_op);
22800                 }
22801                 else if (entry->member->op == OP_CBRANCH) {
22802                         struct triple *branch;
22803                         struct triple *left, *right;
22804                         left = right = 0;
22805                         left = RHS(cmp, 0);
22806                         if (cmp->rhs > 1) {
22807                                 right = RHS(cmp, 1);
22808                         }
22809                         branch = entry->member;
22810                         fixup_branch(state, branch, jmp_op, 
22811                                 cmp->op, cmp->type, left, right);
22812                 }
22813         }
22814 }
22815
22816 static void bool_cmp(struct compile_state *state, 
22817         struct triple *ins, int cmp_op, int jmp_op, int set_op)
22818 {
22819         struct triple_set *entry, *next;
22820         struct triple *set, *convert;
22821
22822         /* Put a barrier up before the cmp which preceeds the
22823          * copy instruction.  If a set actually occurs this gives
22824          * us a chance to move variables in registers out of the way.
22825          */
22826
22827         /* Modify the comparison operator */
22828         ins->op = cmp_op;
22829         ins->template_id = TEMPLATE_TEST32;
22830         if (cmp_op == OP_CMP) {
22831                 ins->template_id = TEMPLATE_CMP32_REG;
22832                 if (get_imm32(ins, &RHS(ins, 1))) {
22833                         ins->template_id =  TEMPLATE_CMP32_IMM;
22834                 }
22835         }
22836         /* Generate the instruction sequence that will transform the
22837          * result of the comparison into a logical value.
22838          */
22839         set = post_triple(state, ins, set_op, &uchar_type, ins, 0);
22840         use_triple(ins, set);
22841         set->template_id = TEMPLATE_SET;
22842
22843         convert = set;
22844         if (!equiv_types(ins->type, set->type)) {
22845                 convert = post_triple(state, set, OP_CONVERT, ins->type, set, 0);
22846                 use_triple(set, convert);
22847                 convert->template_id = TEMPLATE_COPY32_REG;
22848         }
22849
22850         for(entry = ins->use; entry; entry = next) {
22851                 next = entry->next;
22852                 if (entry->member == set) {
22853                         continue;
22854                 }
22855                 replace_rhs_use(state, ins, convert, entry->member);
22856         }
22857         fixup_branches(state, ins, convert, jmp_op);
22858 }
22859
22860 struct reg_info arch_reg_lhs(struct compile_state *state, struct triple *ins, int index)
22861 {
22862         struct ins_template *template;
22863         struct reg_info result;
22864         int zlhs;
22865         if (ins->op == OP_PIECE) {
22866                 index = ins->u.cval;
22867                 ins = MISC(ins, 0);
22868         }
22869         zlhs = ins->lhs;
22870         if (triple_is_def(state, ins)) {
22871                 zlhs = 1;
22872         }
22873         if (index >= zlhs) {
22874                 internal_error(state, ins, "index %d out of range for %s",
22875                         index, tops(ins->op));
22876         }
22877         switch(ins->op) {
22878         case OP_ASM:
22879                 template = &ins->u.ainfo->tmpl;
22880                 break;
22881         default:
22882                 if (ins->template_id > LAST_TEMPLATE) {
22883                         internal_error(state, ins, "bad template number %d", 
22884                                 ins->template_id);
22885                 }
22886                 template = &templates[ins->template_id];
22887                 break;
22888         }
22889         result = template->lhs[index];
22890         result.regcm = arch_regcm_normalize(state, result.regcm);
22891         if (result.reg != REG_UNNEEDED) {
22892                 result.regcm &= ~(REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8);
22893         }
22894         if (result.regcm == 0) {
22895                 internal_error(state, ins, "lhs %d regcm == 0", index);
22896         }
22897         return result;
22898 }
22899
22900 struct reg_info arch_reg_rhs(struct compile_state *state, struct triple *ins, int index)
22901 {
22902         struct reg_info result;
22903         struct ins_template *template;
22904         if ((index > ins->rhs) ||
22905                 (ins->op == OP_PIECE)) {
22906                 internal_error(state, ins, "index %d out of range for %s\n",
22907                         index, tops(ins->op));
22908         }
22909         switch(ins->op) {
22910         case OP_ASM:
22911                 template = &ins->u.ainfo->tmpl;
22912                 break;
22913         case OP_PHI:
22914                 index = 0;
22915                 /* Fall through */
22916         default:
22917                 if (ins->template_id > LAST_TEMPLATE) {
22918                         internal_error(state, ins, "bad template number %d", 
22919                                 ins->template_id);
22920                 }
22921                 template = &templates[ins->template_id];
22922                 break;
22923         }
22924         result = template->rhs[index];
22925         result.regcm = arch_regcm_normalize(state, result.regcm);
22926         if (result.regcm == 0) {
22927                 internal_error(state, ins, "rhs %d regcm == 0", index);
22928         }
22929         return result;
22930 }
22931
22932 static struct triple *mod_div(struct compile_state *state,
22933         struct triple *ins, int div_op, int index)
22934 {
22935         struct triple *div, *piece0, *piece1;
22936         
22937         /* Generate the appropriate division instruction */
22938         div = post_triple(state, ins, div_op, ins->type, 0, 0);
22939         RHS(div, 0) = RHS(ins, 0);
22940         RHS(div, 1) = RHS(ins, 1);
22941         piece0 = LHS(div, 0);
22942         piece1 = LHS(div, 1);
22943         div->template_id  = TEMPLATE_DIV32;
22944         use_triple(RHS(div, 0), div);
22945         use_triple(RHS(div, 1), div);
22946         use_triple(LHS(div, 0), div);
22947         use_triple(LHS(div, 1), div);
22948
22949         /* Replate uses of ins with the appropriate piece of the div */
22950         propogate_use(state, ins, LHS(div, index));
22951         release_triple(state, ins);
22952
22953         /* Return the address of the next instruction */
22954         return piece1->next;
22955 }
22956
22957 static int noop_adecl(struct triple *adecl)
22958 {
22959         struct triple_set *use;
22960         /* It's a noop if it doesn't specify stoorage */
22961         if (adecl->lhs == 0) {
22962                 return 1;
22963         }
22964         /* Is the adecl used? If not it's a noop */
22965         for(use = adecl->use; use ; use = use->next) {
22966                 if ((use->member->op != OP_PIECE) ||
22967                         (MISC(use->member, 0) != adecl)) {
22968                         return 0;
22969                 }
22970         }
22971         return 1;
22972 }
22973
22974 static struct triple *x86_deposit(struct compile_state *state, struct triple *ins)
22975 {
22976         struct triple *mask, *nmask, *shift;
22977         struct triple *val, *val_mask, *val_shift;
22978         struct triple *targ, *targ_mask;
22979         struct triple *new;
22980         ulong_t the_mask, the_nmask;
22981
22982         targ = RHS(ins, 0);
22983         val = RHS(ins, 1);
22984
22985         /* Get constant for the mask value */
22986         the_mask = 1;
22987         the_mask <<= ins->u.bitfield.size;
22988         the_mask -= 1;
22989         the_mask <<= ins->u.bitfield.offset;
22990         mask = pre_triple(state, ins, OP_INTCONST, &uint_type, 0, 0);
22991         mask->u.cval = the_mask;
22992
22993         /* Get the inverted mask value */
22994         the_nmask = ~the_mask;
22995         nmask = pre_triple(state, ins, OP_INTCONST, &uint_type, 0, 0);
22996         nmask->u.cval = the_nmask;
22997
22998         /* Get constant for the shift value */
22999         shift = pre_triple(state, ins, OP_INTCONST, &uint_type, 0, 0);
23000         shift->u.cval = ins->u.bitfield.offset;
23001
23002         /* Shift and mask the source value */
23003         val_shift = val;
23004         if (shift->u.cval != 0) {
23005                 val_shift = pre_triple(state, ins, OP_SL, val->type, val, shift);
23006                 use_triple(val, val_shift);
23007                 use_triple(shift, val_shift);
23008         }
23009         val_mask = val_shift;
23010         if (is_signed(val->type)) {
23011                 val_mask = pre_triple(state, ins, OP_AND, val->type, val_shift, mask);
23012                 use_triple(val_shift, val_mask);
23013                 use_triple(mask, val_mask);
23014         }
23015
23016         /* Mask the target value */
23017         targ_mask = pre_triple(state, ins, OP_AND, targ->type, targ, nmask);
23018         use_triple(targ, targ_mask);
23019         use_triple(nmask, targ_mask);
23020
23021         /* Now combined them together */
23022         new = pre_triple(state, ins, OP_OR, targ->type, targ_mask, val_mask);
23023         use_triple(targ_mask, new);
23024         use_triple(val_mask, new);
23025
23026         /* Move all of the users over to the new expression */
23027         propogate_use(state, ins, new);
23028
23029         /* Delete the original triple */
23030         release_triple(state, ins);
23031
23032         /* Restart the transformation at mask */
23033         return mask;
23034 }
23035
23036 static struct triple *x86_extract(struct compile_state *state, struct triple *ins)
23037 {
23038         struct triple *mask, *shift;
23039         struct triple *val, *val_mask, *val_shift;
23040         ulong_t the_mask;
23041
23042         val = RHS(ins, 0);
23043
23044         /* Get constant for the mask value */
23045         the_mask = 1;
23046         the_mask <<= ins->u.bitfield.size;
23047         the_mask -= 1;
23048         mask = pre_triple(state, ins, OP_INTCONST, &int_type, 0, 0);
23049         mask->u.cval = the_mask;
23050
23051         /* Get constant for the right shift value */
23052         shift = pre_triple(state, ins, OP_INTCONST, &int_type, 0, 0);
23053         shift->u.cval = ins->u.bitfield.offset;
23054
23055         /* Shift arithmetic right, to correct the sign */
23056         val_shift = val;
23057         if (shift->u.cval != 0) {
23058                 int op;
23059                 if (ins->op == OP_SEXTRACT) {
23060                         op = OP_SSR;
23061                 } else {
23062                         op = OP_USR;
23063                 }
23064                 val_shift = pre_triple(state, ins, op, val->type, val, shift);
23065                 use_triple(val, val_shift);
23066                 use_triple(shift, val_shift);
23067         }
23068
23069         /* Finally mask the value */
23070         val_mask = pre_triple(state, ins, OP_AND, ins->type, val_shift, mask);
23071         use_triple(val_shift, val_mask);
23072         use_triple(mask,      val_mask);
23073
23074         /* Move all of the users over to the new expression */
23075         propogate_use(state, ins, val_mask);
23076
23077         /* Release the original instruction */
23078         release_triple(state, ins);
23079
23080         return mask;
23081
23082 }
23083
23084 static struct triple *transform_to_arch_instruction(
23085         struct compile_state *state, struct triple *ins)
23086 {
23087         /* Transform from generic 3 address instructions
23088          * to archtecture specific instructions.
23089          * And apply architecture specific constraints to instructions.
23090          * Copies are inserted to preserve the register flexibility
23091          * of 3 address instructions.
23092          */
23093         struct triple *next, *value;
23094         size_t size;
23095         next = ins->next;
23096         switch(ins->op) {
23097         case OP_INTCONST:
23098                 ins->template_id = TEMPLATE_INTCONST32;
23099                 if (ins->u.cval < 256) {
23100                         ins->template_id = TEMPLATE_INTCONST8;
23101                 }
23102                 break;
23103         case OP_ADDRCONST:
23104                 ins->template_id = TEMPLATE_INTCONST32;
23105                 break;
23106         case OP_UNKNOWNVAL:
23107                 ins->template_id = TEMPLATE_UNKNOWNVAL;
23108                 break;
23109         case OP_NOOP:
23110         case OP_SDECL:
23111         case OP_BLOBCONST:
23112         case OP_LABEL:
23113                 ins->template_id = TEMPLATE_NOP;
23114                 break;
23115         case OP_COPY:
23116         case OP_CONVERT:
23117                 size = size_of(state, ins->type);
23118                 value = RHS(ins, 0);
23119                 if (is_imm8(value) && (size <= SIZEOF_I8)) {
23120                         ins->template_id = TEMPLATE_COPY_IMM8;
23121                 }
23122                 else if (is_imm16(value) && (size <= SIZEOF_I16)) {
23123                         ins->template_id = TEMPLATE_COPY_IMM16;
23124                 }
23125                 else if (is_imm32(value) && (size <= SIZEOF_I32)) {
23126                         ins->template_id = TEMPLATE_COPY_IMM32;
23127                 }
23128                 else if (is_const(value)) {
23129                         internal_error(state, ins, "bad constant passed to copy");
23130                 }
23131                 else if (size <= SIZEOF_I8) {
23132                         ins->template_id = TEMPLATE_COPY8_REG;
23133                 }
23134                 else if (size <= SIZEOF_I16) {
23135                         ins->template_id = TEMPLATE_COPY16_REG;
23136                 }
23137                 else if (size <= SIZEOF_I32) {
23138                         ins->template_id = TEMPLATE_COPY32_REG;
23139                 }
23140                 else {
23141                         internal_error(state, ins, "bad type passed to copy");
23142                 }
23143                 break;
23144         case OP_PHI:
23145                 size = size_of(state, ins->type);
23146                 if (size <= SIZEOF_I8) {
23147                         ins->template_id = TEMPLATE_PHI8;
23148                 }
23149                 else if (size <= SIZEOF_I16) {
23150                         ins->template_id = TEMPLATE_PHI16;
23151                 }
23152                 else if (size <= SIZEOF_I32) {
23153                         ins->template_id = TEMPLATE_PHI32;
23154                 }
23155                 else {
23156                         internal_error(state, ins, "bad type passed to phi");
23157                 }
23158                 break;
23159         case OP_ADECL:
23160                 /* Adecls should always be treated as dead code and
23161                  * removed.  If we are not optimizing they may linger.
23162                  */
23163                 if (!noop_adecl(ins)) {
23164                         internal_error(state, ins, "adecl remains?");
23165                 }
23166                 ins->template_id = TEMPLATE_NOP;
23167                 next = after_lhs(state, ins);
23168                 break;
23169         case OP_STORE:
23170                 switch(ins->type->type & TYPE_MASK) {
23171                 case TYPE_CHAR:    case TYPE_UCHAR:
23172                         ins->template_id = TEMPLATE_STORE8;
23173                         break;
23174                 case TYPE_SHORT:   case TYPE_USHORT:
23175                         ins->template_id = TEMPLATE_STORE16;
23176                         break;
23177                 case TYPE_INT:     case TYPE_UINT:
23178                 case TYPE_LONG:    case TYPE_ULONG:
23179                 case TYPE_POINTER:
23180                         ins->template_id = TEMPLATE_STORE32;
23181                         break;
23182                 default:
23183                         internal_error(state, ins, "unknown type in store");
23184                         break;
23185                 }
23186                 break;
23187         case OP_LOAD:
23188                 switch(ins->type->type & TYPE_MASK) {
23189                 case TYPE_CHAR:   case TYPE_UCHAR:
23190                 case TYPE_SHORT:  case TYPE_USHORT:
23191                 case TYPE_INT:    case TYPE_UINT:
23192                 case TYPE_LONG:   case TYPE_ULONG:
23193                 case TYPE_POINTER:
23194                         break;
23195                 default:
23196                         internal_error(state, ins, "unknown type in load");
23197                         break;
23198                 }
23199                 ins->template_id = TEMPLATE_LOAD32;
23200                 break;
23201         case OP_ADD:
23202         case OP_SUB:
23203         case OP_AND:
23204         case OP_XOR:
23205         case OP_OR:
23206         case OP_SMUL:
23207                 ins->template_id = TEMPLATE_BINARY32_REG;
23208                 if (get_imm32(ins, &RHS(ins, 1))) {
23209                         ins->template_id = TEMPLATE_BINARY32_IMM;
23210                 }
23211                 break;
23212         case OP_SDIVT:
23213         case OP_UDIVT:
23214                 ins->template_id = TEMPLATE_DIV32;
23215                 next = after_lhs(state, ins);
23216                 break;
23217         case OP_UMUL:
23218                 ins->template_id = TEMPLATE_UMUL32;
23219                 break;
23220         case OP_UDIV:
23221                 next = mod_div(state, ins, OP_UDIVT, 0);
23222                 break;
23223         case OP_SDIV:
23224                 next = mod_div(state, ins, OP_SDIVT, 0);
23225                 break;
23226         case OP_UMOD:
23227                 next = mod_div(state, ins, OP_UDIVT, 1);
23228                 break;
23229         case OP_SMOD:
23230                 next = mod_div(state, ins, OP_SDIVT, 1);
23231                 break;
23232         case OP_SL:
23233         case OP_SSR:
23234         case OP_USR:
23235                 ins->template_id = TEMPLATE_SL32_CL;
23236                 if (get_imm8(ins, &RHS(ins, 1))) {
23237                         ins->template_id = TEMPLATE_SL32_IMM;
23238                 } else if (size_of(state, RHS(ins, 1)->type) > SIZEOF_CHAR) {
23239                         typed_pre_copy(state, &uchar_type, ins, 1);
23240                 }
23241                 break;
23242         case OP_INVERT:
23243         case OP_NEG:
23244                 ins->template_id = TEMPLATE_UNARY32;
23245                 break;
23246         case OP_EQ: 
23247                 bool_cmp(state, ins, OP_CMP, OP_JMP_EQ, OP_SET_EQ); 
23248                 break;
23249         case OP_NOTEQ:
23250                 bool_cmp(state, ins, OP_CMP, OP_JMP_NOTEQ, OP_SET_NOTEQ);
23251                 break;
23252         case OP_SLESS:
23253                 bool_cmp(state, ins, OP_CMP, OP_JMP_SLESS, OP_SET_SLESS);
23254                 break;
23255         case OP_ULESS:
23256                 bool_cmp(state, ins, OP_CMP, OP_JMP_ULESS, OP_SET_ULESS);
23257                 break;
23258         case OP_SMORE:
23259                 bool_cmp(state, ins, OP_CMP, OP_JMP_SMORE, OP_SET_SMORE);
23260                 break;
23261         case OP_UMORE:
23262                 bool_cmp(state, ins, OP_CMP, OP_JMP_UMORE, OP_SET_UMORE);
23263                 break;
23264         case OP_SLESSEQ:
23265                 bool_cmp(state, ins, OP_CMP, OP_JMP_SLESSEQ, OP_SET_SLESSEQ);
23266                 break;
23267         case OP_ULESSEQ:
23268                 bool_cmp(state, ins, OP_CMP, OP_JMP_ULESSEQ, OP_SET_ULESSEQ);
23269                 break;
23270         case OP_SMOREEQ:
23271                 bool_cmp(state, ins, OP_CMP, OP_JMP_SMOREEQ, OP_SET_SMOREEQ);
23272                 break;
23273         case OP_UMOREEQ:
23274                 bool_cmp(state, ins, OP_CMP, OP_JMP_UMOREEQ, OP_SET_UMOREEQ);
23275                 break;
23276         case OP_LTRUE:
23277                 bool_cmp(state, ins, OP_TEST, OP_JMP_NOTEQ, OP_SET_NOTEQ);
23278                 break;
23279         case OP_LFALSE:
23280                 bool_cmp(state, ins, OP_TEST, OP_JMP_EQ, OP_SET_EQ);
23281                 break;
23282         case OP_BRANCH:
23283                 ins->op = OP_JMP;
23284                 ins->template_id = TEMPLATE_NOP;
23285                 break;
23286         case OP_CBRANCH:
23287                 fixup_branch(state, ins, OP_JMP_NOTEQ, OP_TEST, 
23288                         RHS(ins, 0)->type, RHS(ins, 0), 0);
23289                 break;
23290         case OP_CALL:
23291                 ins->template_id = TEMPLATE_NOP;
23292                 break;
23293         case OP_RET:
23294                 ins->template_id = TEMPLATE_RET;
23295                 break;
23296         case OP_INB:
23297         case OP_INW:
23298         case OP_INL:
23299                 switch(ins->op) {
23300                 case OP_INB: ins->template_id = TEMPLATE_INB_DX; break;
23301                 case OP_INW: ins->template_id = TEMPLATE_INW_DX; break;
23302                 case OP_INL: ins->template_id = TEMPLATE_INL_DX; break;
23303                 }
23304                 if (get_imm8(ins, &RHS(ins, 0))) {
23305                         ins->template_id += 1;
23306                 }
23307                 break;
23308         case OP_OUTB:
23309         case OP_OUTW:
23310         case OP_OUTL:
23311                 switch(ins->op) {
23312                 case OP_OUTB: ins->template_id = TEMPLATE_OUTB_DX; break;
23313                 case OP_OUTW: ins->template_id = TEMPLATE_OUTW_DX; break;
23314                 case OP_OUTL: ins->template_id = TEMPLATE_OUTL_DX; break;
23315                 }
23316                 if (get_imm8(ins, &RHS(ins, 1))) {
23317                         ins->template_id += 1;
23318                 }
23319                 break;
23320         case OP_BSF:
23321         case OP_BSR:
23322                 ins->template_id = TEMPLATE_BSF;
23323                 break;
23324         case OP_RDMSR:
23325                 ins->template_id = TEMPLATE_RDMSR;
23326                 next = after_lhs(state, ins);
23327                 break;
23328         case OP_WRMSR:
23329                 ins->template_id = TEMPLATE_WRMSR;
23330                 break;
23331         case OP_HLT:
23332                 ins->template_id = TEMPLATE_NOP;
23333                 break;
23334         case OP_ASM:
23335                 ins->template_id = TEMPLATE_NOP;
23336                 next = after_lhs(state, ins);
23337                 break;
23338                 /* Already transformed instructions */
23339         case OP_TEST:
23340                 ins->template_id = TEMPLATE_TEST32;
23341                 break;
23342         case OP_CMP:
23343                 ins->template_id = TEMPLATE_CMP32_REG;
23344                 if (get_imm32(ins, &RHS(ins, 1))) {
23345                         ins->template_id = TEMPLATE_CMP32_IMM;
23346                 }
23347                 break;
23348         case OP_JMP:
23349                 ins->template_id = TEMPLATE_NOP;
23350                 break;
23351         case OP_JMP_EQ:      case OP_JMP_NOTEQ:
23352         case OP_JMP_SLESS:   case OP_JMP_ULESS:
23353         case OP_JMP_SMORE:   case OP_JMP_UMORE:
23354         case OP_JMP_SLESSEQ: case OP_JMP_ULESSEQ:
23355         case OP_JMP_SMOREEQ: case OP_JMP_UMOREEQ:
23356                 ins->template_id = TEMPLATE_JMP;
23357                 break;
23358         case OP_SET_EQ:      case OP_SET_NOTEQ:
23359         case OP_SET_SLESS:   case OP_SET_ULESS:
23360         case OP_SET_SMORE:   case OP_SET_UMORE:
23361         case OP_SET_SLESSEQ: case OP_SET_ULESSEQ:
23362         case OP_SET_SMOREEQ: case OP_SET_UMOREEQ:
23363                 ins->template_id = TEMPLATE_SET;
23364                 break;
23365         case OP_DEPOSIT:
23366                 next = x86_deposit(state, ins);
23367                 break;
23368         case OP_SEXTRACT:
23369         case OP_UEXTRACT:
23370                 next = x86_extract(state, ins);
23371                 break;
23372                 /* Unhandled instructions */
23373         case OP_PIECE:
23374         default:
23375                 internal_error(state, ins, "unhandled ins: %d %s",
23376                         ins->op, tops(ins->op));
23377                 break;
23378         }
23379         return next;
23380 }
23381
23382 static long next_label(struct compile_state *state)
23383 {
23384         static long label_counter = 1000;
23385         return ++label_counter;
23386 }
23387 static void generate_local_labels(struct compile_state *state)
23388 {
23389         struct triple *first, *label;
23390         first = state->first;
23391         label = first;
23392         do {
23393                 if ((label->op == OP_LABEL) || 
23394                         (label->op == OP_SDECL)) {
23395                         if (label->use) {
23396                                 label->u.cval = next_label(state);
23397                         } else {
23398                                 label->u.cval = 0;
23399                         }
23400                         
23401                 }
23402                 label = label->next;
23403         } while(label != first);
23404 }
23405
23406 static int check_reg(struct compile_state *state, 
23407         struct triple *triple, int classes)
23408 {
23409         unsigned mask;
23410         int reg;
23411         reg = ID_REG(triple->id);
23412         if (reg == REG_UNSET) {
23413                 internal_error(state, triple, "register not set");
23414         }
23415         mask = arch_reg_regcm(state, reg);
23416         if (!(classes & mask)) {
23417                 internal_error(state, triple, "reg %d in wrong class",
23418                         reg);
23419         }
23420         return reg;
23421 }
23422
23423
23424 #if REG_XMM7 != 44
23425 #error "Registers have renumberd fix arch_reg_str"
23426 #endif
23427 static const char *arch_regs[] = {
23428         "%unset",
23429         "%unneeded",
23430         "%eflags",
23431         "%al", "%bl", "%cl", "%dl", "%ah", "%bh", "%ch", "%dh",
23432         "%ax", "%bx", "%cx", "%dx", "%si", "%di", "%bp", "%sp",
23433         "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi", "%ebp", "%esp",
23434         "%edx:%eax",
23435         "%dx:%ax",
23436         "%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7",
23437         "%xmm0", "%xmm1", "%xmm2", "%xmm3", 
23438         "%xmm4", "%xmm5", "%xmm6", "%xmm7",
23439 };
23440 static const char *arch_reg_str(int reg)
23441 {
23442         if (!((reg >= REG_EFLAGS) && (reg <= REG_XMM7))) {
23443                 reg = 0;
23444         }
23445         return arch_regs[reg];
23446 }
23447
23448 static const char *reg(struct compile_state *state, struct triple *triple,
23449         int classes)
23450 {
23451         int reg;
23452         reg = check_reg(state, triple, classes);
23453         return arch_reg_str(reg);
23454 }
23455
23456 static int arch_reg_size(int reg)
23457 {
23458         int size;
23459         size = 0;
23460         if (reg == REG_EFLAGS) {
23461                 size = 32;
23462         }
23463         else if ((reg >= REG_AL) && (reg <= REG_DH)) {
23464                 size = 8;
23465         }
23466         else if ((reg >= REG_AX) && (reg <= REG_SP)) {
23467                 size = 16;
23468         }
23469         else if ((reg >= REG_EAX) && (reg <= REG_ESP)) {
23470                 size = 32;
23471         }
23472         else if (reg == REG_EDXEAX) {
23473                 size = 64;
23474         }
23475         else if (reg == REG_DXAX) {
23476                 size = 32;
23477         }
23478         else if ((reg >= REG_MMX0) && (reg <= REG_MMX7)) {
23479                 size = 64;
23480         }
23481         else if ((reg >= REG_XMM0) && (reg <= REG_XMM7)) {
23482                 size = 128;
23483         }
23484         return size;
23485 }
23486
23487 static int reg_size(struct compile_state *state, struct triple *ins)
23488 {
23489         int reg;
23490         reg = ID_REG(ins->id);
23491         if (reg == REG_UNSET) {
23492                 internal_error(state, ins, "register not set");
23493         }
23494         return arch_reg_size(reg);
23495 }
23496         
23497
23498
23499 const char *type_suffix(struct compile_state *state, struct type *type)
23500 {
23501         const char *suffix;
23502         switch(size_of(state, type)) {
23503         case SIZEOF_I8:  suffix = "b"; break;
23504         case SIZEOF_I16: suffix = "w"; break;
23505         case SIZEOF_I32: suffix = "l"; break;
23506         default:
23507                 internal_error(state, 0, "unknown suffix");
23508                 suffix = 0;
23509                 break;
23510         }
23511         return suffix;
23512 }
23513
23514 static void print_const_val(
23515         struct compile_state *state, struct triple *ins, FILE *fp)
23516 {
23517         switch(ins->op) {
23518         case OP_INTCONST:
23519                 fprintf(fp, " $%ld ", 
23520                         (long)(ins->u.cval));
23521                 break;
23522         case OP_ADDRCONST:
23523                 if ((MISC(ins, 0)->op != OP_SDECL) &&
23524                         (MISC(ins, 0)->op != OP_LABEL))
23525                 {
23526                         internal_error(state, ins, "bad base for addrconst");
23527                 }
23528                 if (MISC(ins, 0)->u.cval <= 0) {
23529                         internal_error(state, ins, "unlabeled constant");
23530                 }
23531                 fprintf(fp, " $L%s%lu+%lu ",
23532                         state->compiler->label_prefix, 
23533                         (unsigned long)(MISC(ins, 0)->u.cval),
23534                         (unsigned long)(ins->u.cval));
23535                 break;
23536         default:
23537                 internal_error(state, ins, "unknown constant type");
23538                 break;
23539         }
23540 }
23541
23542 static void print_const(struct compile_state *state,
23543         struct triple *ins, FILE *fp)
23544 {
23545         switch(ins->op) {
23546         case OP_INTCONST:
23547                 switch(ins->type->type & TYPE_MASK) {
23548                 case TYPE_CHAR:
23549                 case TYPE_UCHAR:
23550                         fprintf(fp, ".byte 0x%02lx\n", 
23551                                 (unsigned long)(ins->u.cval));
23552                         break;
23553                 case TYPE_SHORT:
23554                 case TYPE_USHORT:
23555                         fprintf(fp, ".short 0x%04lx\n", 
23556                                 (unsigned long)(ins->u.cval));
23557                         break;
23558                 case TYPE_INT:
23559                 case TYPE_UINT:
23560                 case TYPE_LONG:
23561                 case TYPE_ULONG:
23562                 case TYPE_POINTER:
23563                         fprintf(fp, ".int %lu\n", 
23564                                 (unsigned long)(ins->u.cval));
23565                         break;
23566                 default:
23567                         fprintf(state->errout, "type: ");
23568                         name_of(state->errout, ins->type);
23569                         fprintf(state->errout, "\n");
23570                         internal_error(state, ins, "Unknown constant type. Val: %lu",
23571                                 (unsigned long)(ins->u.cval));
23572                 }
23573                 
23574                 break;
23575         case OP_ADDRCONST:
23576                 if ((MISC(ins, 0)->op != OP_SDECL) &&
23577                         (MISC(ins, 0)->op != OP_LABEL)) {
23578                         internal_error(state, ins, "bad base for addrconst");
23579                 }
23580                 if (MISC(ins, 0)->u.cval <= 0) {
23581                         internal_error(state, ins, "unlabeled constant");
23582                 }
23583                 fprintf(fp, ".int L%s%lu+%lu\n",
23584                         state->compiler->label_prefix,
23585                         (unsigned long)(MISC(ins, 0)->u.cval),
23586                         (unsigned long)(ins->u.cval));
23587                 break;
23588         case OP_BLOBCONST:
23589         {
23590                 unsigned char *blob;
23591                 size_t size, i;
23592                 size = size_of_in_bytes(state, ins->type);
23593                 blob = ins->u.blob;
23594                 for(i = 0; i < size; i++) {
23595                         fprintf(fp, ".byte 0x%02x\n",
23596                                 blob[i]);
23597                 }
23598                 break;
23599         }
23600         default:
23601                 internal_error(state, ins, "Unknown constant type");
23602                 break;
23603         }
23604 }
23605
23606 #define TEXT_SECTION ".rom.text"
23607 #define DATA_SECTION ".rom.data"
23608
23609 static long get_const_pool_ref(
23610         struct compile_state *state, struct triple *ins, size_t size, FILE *fp)
23611 {
23612         size_t fill_bytes;
23613         long ref;
23614         ref = next_label(state);
23615         fprintf(fp, ".section \"" DATA_SECTION "\"\n");
23616         fprintf(fp, ".balign %d\n", align_of_in_bytes(state, ins->type));
23617         fprintf(fp, "L%s%lu:\n", state->compiler->label_prefix, ref);
23618         print_const(state, ins, fp);
23619         fill_bytes = bits_to_bytes(size - size_of(state, ins->type));
23620         if (fill_bytes) {
23621                 fprintf(fp, ".fill %d, 1, 0\n", fill_bytes);
23622         }
23623         fprintf(fp, ".section \"" TEXT_SECTION "\"\n");
23624         return ref;
23625 }
23626
23627 static long get_mask_pool_ref(
23628         struct compile_state *state, struct triple *ins, unsigned long mask, FILE *fp)
23629 {
23630         long ref;
23631         if (mask == 0xff) {
23632                 ref = 1;
23633         }
23634         else if (mask == 0xffff) {
23635                 ref = 2;
23636         }
23637         else {
23638                 ref = 0;
23639                 internal_error(state, ins, "unhandled mask value");
23640         }
23641         return ref;
23642 }
23643
23644 static void print_binary_op(struct compile_state *state,
23645         const char *op, struct triple *ins, FILE *fp) 
23646 {
23647         unsigned mask;
23648         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO;
23649         if (ID_REG(RHS(ins, 0)->id) != ID_REG(ins->id)) {
23650                 internal_error(state, ins, "invalid register assignment");
23651         }
23652         if (is_const(RHS(ins, 1))) {
23653                 fprintf(fp, "\t%s ", op);
23654                 print_const_val(state, RHS(ins, 1), fp);
23655                 fprintf(fp, ", %s\n",
23656                         reg(state, RHS(ins, 0), mask));
23657         }
23658         else {
23659                 unsigned lmask, rmask;
23660                 int lreg, rreg;
23661                 lreg = check_reg(state, RHS(ins, 0), mask);
23662                 rreg = check_reg(state, RHS(ins, 1), mask);
23663                 lmask = arch_reg_regcm(state, lreg);
23664                 rmask = arch_reg_regcm(state, rreg);
23665                 mask = lmask & rmask;
23666                 fprintf(fp, "\t%s %s, %s\n",
23667                         op,
23668                         reg(state, RHS(ins, 1), mask),
23669                         reg(state, RHS(ins, 0), mask));
23670         }
23671 }
23672 static void print_unary_op(struct compile_state *state, 
23673         const char *op, struct triple *ins, FILE *fp)
23674 {
23675         unsigned mask;
23676         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO;
23677         fprintf(fp, "\t%s %s\n",
23678                 op,
23679                 reg(state, RHS(ins, 0), mask));
23680 }
23681
23682 static void print_op_shift(struct compile_state *state,
23683         const char *op, struct triple *ins, FILE *fp)
23684 {
23685         unsigned mask;
23686         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO;
23687         if (ID_REG(RHS(ins, 0)->id) != ID_REG(ins->id)) {
23688                 internal_error(state, ins, "invalid register assignment");
23689         }
23690         if (is_const(RHS(ins, 1))) {
23691                 fprintf(fp, "\t%s ", op);
23692                 print_const_val(state, RHS(ins, 1), fp);
23693                 fprintf(fp, ", %s\n",
23694                         reg(state, RHS(ins, 0), mask));
23695         }
23696         else {
23697                 fprintf(fp, "\t%s %s, %s\n",
23698                         op,
23699                         reg(state, RHS(ins, 1), REGCM_GPR8_LO),
23700                         reg(state, RHS(ins, 0), mask));
23701         }
23702 }
23703
23704 static void print_op_in(struct compile_state *state, struct triple *ins, FILE *fp)
23705 {
23706         const char *op;
23707         int mask;
23708         int dreg;
23709         mask = 0;
23710         switch(ins->op) {
23711         case OP_INB: op = "inb", mask = REGCM_GPR8_LO; break;
23712         case OP_INW: op = "inw", mask = REGCM_GPR16; break;
23713         case OP_INL: op = "inl", mask = REGCM_GPR32; break;
23714         default:
23715                 internal_error(state, ins, "not an in operation");
23716                 op = 0;
23717                 break;
23718         }
23719         dreg = check_reg(state, ins, mask);
23720         if (!reg_is_reg(state, dreg, REG_EAX)) {
23721                 internal_error(state, ins, "dst != %%eax");
23722         }
23723         if (is_const(RHS(ins, 0))) {
23724                 fprintf(fp, "\t%s ", op);
23725                 print_const_val(state, RHS(ins, 0), fp);
23726                 fprintf(fp, ", %s\n",
23727                         reg(state, ins, mask));
23728         }
23729         else {
23730                 int addr_reg;
23731                 addr_reg = check_reg(state, RHS(ins, 0), REGCM_GPR16);
23732                 if (!reg_is_reg(state, addr_reg, REG_DX)) {
23733                         internal_error(state, ins, "src != %%dx");
23734                 }
23735                 fprintf(fp, "\t%s %s, %s\n",
23736                         op, 
23737                         reg(state, RHS(ins, 0), REGCM_GPR16),
23738                         reg(state, ins, mask));
23739         }
23740 }
23741
23742 static void print_op_out(struct compile_state *state, struct triple *ins, FILE *fp)
23743 {
23744         const char *op;
23745         int mask;
23746         int lreg;
23747         mask = 0;
23748         switch(ins->op) {
23749         case OP_OUTB: op = "outb", mask = REGCM_GPR8_LO; break;
23750         case OP_OUTW: op = "outw", mask = REGCM_GPR16; break;
23751         case OP_OUTL: op = "outl", mask = REGCM_GPR32; break;
23752         default:
23753                 internal_error(state, ins, "not an out operation");
23754                 op = 0;
23755                 break;
23756         }
23757         lreg = check_reg(state, RHS(ins, 0), mask);
23758         if (!reg_is_reg(state, lreg, REG_EAX)) {
23759                 internal_error(state, ins, "src != %%eax");
23760         }
23761         if (is_const(RHS(ins, 1))) {
23762                 fprintf(fp, "\t%s %s,", 
23763                         op, reg(state, RHS(ins, 0), mask));
23764                 print_const_val(state, RHS(ins, 1), fp);
23765                 fprintf(fp, "\n");
23766         }
23767         else {
23768                 int addr_reg;
23769                 addr_reg = check_reg(state, RHS(ins, 1), REGCM_GPR16);
23770                 if (!reg_is_reg(state, addr_reg, REG_DX)) {
23771                         internal_error(state, ins, "dst != %%dx");
23772                 }
23773                 fprintf(fp, "\t%s %s, %s\n",
23774                         op, 
23775                         reg(state, RHS(ins, 0), mask),
23776                         reg(state, RHS(ins, 1), REGCM_GPR16));
23777         }
23778 }
23779
23780 static void print_op_move(struct compile_state *state,
23781         struct triple *ins, FILE *fp)
23782 {
23783         /* op_move is complex because there are many types
23784          * of registers we can move between.
23785          * Because OP_COPY will be introduced in arbitrary locations
23786          * OP_COPY must not affect flags.
23787          * OP_CONVERT can change the flags and it is the only operation
23788          * where it is expected the types in the registers can change.
23789          */
23790         int omit_copy = 1; /* Is it o.k. to omit a noop copy? */
23791         struct triple *dst, *src;
23792         if (state->arch->features & X86_NOOP_COPY) {
23793                 omit_copy = 0;
23794         }
23795         if ((ins->op == OP_COPY) || (ins->op == OP_CONVERT)) {
23796                 src = RHS(ins, 0);
23797                 dst = ins;
23798         }
23799         else {
23800                 internal_error(state, ins, "unknown move operation");
23801                 src = dst = 0;
23802         }
23803         if (reg_size(state, dst) < size_of(state, dst->type)) {
23804                 internal_error(state, ins, "Invalid destination register");
23805         }
23806         if (!equiv_types(src->type, dst->type) && (dst->op == OP_COPY)) {
23807                 fprintf(state->errout, "src type: ");
23808                 name_of(state->errout, src->type);
23809                 fprintf(state->errout, "\n");
23810                 fprintf(state->errout, "dst type: ");
23811                 name_of(state->errout, dst->type);
23812                 fprintf(state->errout, "\n");
23813                 internal_error(state, ins, "Type mismatch for OP_COPY");
23814         }
23815
23816         if (!is_const(src)) {
23817                 int src_reg, dst_reg;
23818                 int src_regcm, dst_regcm;
23819                 src_reg   = ID_REG(src->id);
23820                 dst_reg   = ID_REG(dst->id);
23821                 src_regcm = arch_reg_regcm(state, src_reg);
23822                 dst_regcm = arch_reg_regcm(state, dst_reg);
23823                 /* If the class is the same just move the register */
23824                 if (src_regcm & dst_regcm & 
23825                         (REGCM_GPR8_LO | REGCM_GPR16 | REGCM_GPR32)) {
23826                         if ((src_reg != dst_reg) || !omit_copy) {
23827                                 fprintf(fp, "\tmov %s, %s\n",
23828                                         reg(state, src, src_regcm),
23829                                         reg(state, dst, dst_regcm));
23830                         }
23831                 }
23832                 /* Move 32bit to 16bit */
23833                 else if ((src_regcm & REGCM_GPR32) &&
23834                         (dst_regcm & REGCM_GPR16)) {
23835                         src_reg = (src_reg - REGC_GPR32_FIRST) + REGC_GPR16_FIRST;
23836                         if ((src_reg != dst_reg) || !omit_copy) {
23837                                 fprintf(fp, "\tmovw %s, %s\n",
23838                                         arch_reg_str(src_reg), 
23839                                         arch_reg_str(dst_reg));
23840                         }
23841                 }
23842                 /* Move from 32bit gprs to 16bit gprs */
23843                 else if ((src_regcm & REGCM_GPR32) &&
23844                         (dst_regcm & REGCM_GPR16)) {
23845                         dst_reg = (dst_reg - REGC_GPR16_FIRST) + REGC_GPR32_FIRST;
23846                         if ((src_reg != dst_reg) || !omit_copy) {
23847                                 fprintf(fp, "\tmov %s, %s\n",
23848                                         arch_reg_str(src_reg),
23849                                         arch_reg_str(dst_reg));
23850                         }
23851                 }
23852                 /* Move 32bit to 8bit */
23853                 else if ((src_regcm & REGCM_GPR32_8) &&
23854                         (dst_regcm & REGCM_GPR8_LO))
23855                 {
23856                         src_reg = (src_reg - REGC_GPR32_8_FIRST) + REGC_GPR8_FIRST;
23857                         if ((src_reg != dst_reg) || !omit_copy) {
23858                                 fprintf(fp, "\tmovb %s, %s\n",
23859                                         arch_reg_str(src_reg),
23860                                         arch_reg_str(dst_reg));
23861                         }
23862                 }
23863                 /* Move 16bit to 8bit */
23864                 else if ((src_regcm & REGCM_GPR16_8) &&
23865                         (dst_regcm & REGCM_GPR8_LO))
23866                 {
23867                         src_reg = (src_reg - REGC_GPR16_8_FIRST) + REGC_GPR8_FIRST;
23868                         if ((src_reg != dst_reg) || !omit_copy) {
23869                                 fprintf(fp, "\tmovb %s, %s\n",
23870                                         arch_reg_str(src_reg),
23871                                         arch_reg_str(dst_reg));
23872                         }
23873                 }
23874                 /* Move 8/16bit to 16/32bit */
23875                 else if ((src_regcm & (REGCM_GPR8_LO | REGCM_GPR16)) && 
23876                         (dst_regcm & (REGCM_GPR16 | REGCM_GPR32))) {
23877                         const char *op;
23878                         op = is_signed(src->type)? "movsx": "movzx";
23879                         fprintf(fp, "\t%s %s, %s\n",
23880                                 op,
23881                                 reg(state, src, src_regcm),
23882                                 reg(state, dst, dst_regcm));
23883                 }
23884                 /* Move between sse registers */
23885                 else if ((src_regcm & dst_regcm & REGCM_XMM)) {
23886                         if ((src_reg != dst_reg) || !omit_copy) {
23887                                 fprintf(fp, "\tmovdqa %s, %s\n",
23888                                         reg(state, src, src_regcm),
23889                                         reg(state, dst, dst_regcm));
23890                         }
23891                 }
23892                 /* Move between mmx registers */
23893                 else if ((src_regcm & dst_regcm & REGCM_MMX)) {
23894                         if ((src_reg != dst_reg) || !omit_copy) {
23895                                 fprintf(fp, "\tmovq %s, %s\n",
23896                                         reg(state, src, src_regcm),
23897                                         reg(state, dst, dst_regcm));
23898                         }
23899                 }
23900                 /* Move from sse to mmx registers */
23901                 else if ((src_regcm & REGCM_XMM) && (dst_regcm & REGCM_MMX)) {
23902                         fprintf(fp, "\tmovdq2q %s, %s\n",
23903                                 reg(state, src, src_regcm),
23904                                 reg(state, dst, dst_regcm));
23905                 }
23906                 /* Move from mmx to sse registers */
23907                 else if ((src_regcm & REGCM_MMX) && (dst_regcm & REGCM_XMM)) {
23908                         fprintf(fp, "\tmovq2dq %s, %s\n",
23909                                 reg(state, src, src_regcm),
23910                                 reg(state, dst, dst_regcm));
23911                 }
23912                 /* Move between 32bit gprs & mmx/sse registers */
23913                 else if ((src_regcm & (REGCM_GPR32 | REGCM_MMX | REGCM_XMM)) &&
23914                         (dst_regcm & (REGCM_GPR32 | REGCM_MMX | REGCM_XMM))) {
23915                         fprintf(fp, "\tmovd %s, %s\n",
23916                                 reg(state, src, src_regcm),
23917                                 reg(state, dst, dst_regcm));
23918                 }
23919                 /* Move from 16bit gprs &  mmx/sse registers */
23920                 else if ((src_regcm & REGCM_GPR16) &&
23921                         (dst_regcm & (REGCM_MMX | REGCM_XMM))) {
23922                         const char *op;
23923                         int mid_reg;
23924                         op = is_signed(src->type)? "movsx":"movzx";
23925                         mid_reg = (src_reg - REGC_GPR16_FIRST) + REGC_GPR32_FIRST;
23926                         fprintf(fp, "\t%s %s, %s\n\tmovd %s, %s\n",
23927                                 op,
23928                                 arch_reg_str(src_reg),
23929                                 arch_reg_str(mid_reg),
23930                                 arch_reg_str(mid_reg),
23931                                 arch_reg_str(dst_reg));
23932                 }
23933                 /* Move from mmx/sse registers to 16bit gprs */
23934                 else if ((src_regcm & (REGCM_MMX | REGCM_XMM)) &&
23935                         (dst_regcm & REGCM_GPR16)) {
23936                         dst_reg = (dst_reg - REGC_GPR16_FIRST) + REGC_GPR32_FIRST;
23937                         fprintf(fp, "\tmovd %s, %s\n",
23938                                 arch_reg_str(src_reg),
23939                                 arch_reg_str(dst_reg));
23940                 }
23941                 /* Move from gpr to 64bit dividend */
23942                 else if ((src_regcm & (REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO))  &&
23943                         (dst_regcm & REGCM_DIVIDEND64)) {
23944                         const char *extend;
23945                         extend = is_signed(src->type)? "cltd":"movl $0, %edx";
23946                         fprintf(fp, "\tmov %s, %%eax\n\t%s\n",
23947                                 arch_reg_str(src_reg), 
23948                                 extend);
23949                 }
23950                 /* Move from 64bit gpr to gpr */
23951                 else if ((src_regcm & REGCM_DIVIDEND64) &&
23952                         (dst_regcm & (REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO))) {
23953                         if (dst_regcm & REGCM_GPR32) {
23954                                 src_reg = REG_EAX;
23955                         } 
23956                         else if (dst_regcm & REGCM_GPR16) {
23957                                 src_reg = REG_AX;
23958                         }
23959                         else if (dst_regcm & REGCM_GPR8_LO) {
23960                                 src_reg = REG_AL;
23961                         }
23962                         fprintf(fp, "\tmov %s, %s\n",
23963                                 arch_reg_str(src_reg),
23964                                 arch_reg_str(dst_reg));
23965                 }
23966                 /* Move from mmx/sse registers to 64bit gpr */
23967                 else if ((src_regcm & (REGCM_MMX | REGCM_XMM)) &&
23968                         (dst_regcm & REGCM_DIVIDEND64)) {
23969                         const char *extend;
23970                         extend = is_signed(src->type)? "cltd": "movl $0, %edx";
23971                         fprintf(fp, "\tmovd %s, %%eax\n\t%s\n",
23972                                 arch_reg_str(src_reg),
23973                                 extend);
23974                 }
23975                 /* Move from 64bit gpr to mmx/sse register */
23976                 else if ((src_regcm & REGCM_DIVIDEND64) &&
23977                         (dst_regcm & (REGCM_XMM | REGCM_MMX))) {
23978                         fprintf(fp, "\tmovd %%eax, %s\n",
23979                                 arch_reg_str(dst_reg));
23980                 }
23981 #if X86_4_8BIT_GPRS
23982                 /* Move from 8bit gprs to  mmx/sse registers */
23983                 else if ((src_regcm & REGCM_GPR8_LO) && (src_reg <= REG_DL) &&
23984                         (dst_regcm & (REGCM_MMX | REGCM_XMM))) {
23985                         const char *op;
23986                         int mid_reg;
23987                         op = is_signed(src->type)? "movsx":"movzx";
23988                         mid_reg = (src_reg - REGC_GPR8_FIRST) + REGC_GPR32_FIRST;
23989                         fprintf(fp, "\t%s %s, %s\n\tmovd %s, %s\n",
23990                                 op,
23991                                 reg(state, src, src_regcm),
23992                                 arch_reg_str(mid_reg),
23993                                 arch_reg_str(mid_reg),
23994                                 reg(state, dst, dst_regcm));
23995                 }
23996                 /* Move from mmx/sse registers and 8bit gprs */
23997                 else if ((src_regcm & (REGCM_MMX | REGCM_XMM)) &&
23998                         (dst_regcm & REGCM_GPR8_LO) && (dst_reg <= REG_DL)) {
23999                         int mid_reg;
24000                         mid_reg = (dst_reg - REGC_GPR8_FIRST) + REGC_GPR32_FIRST;
24001                         fprintf(fp, "\tmovd %s, %s\n",
24002                                 reg(state, src, src_regcm),
24003                                 arch_reg_str(mid_reg));
24004                 }
24005                 /* Move from 32bit gprs to 8bit gprs */
24006                 else if ((src_regcm & REGCM_GPR32) &&
24007                         (dst_regcm & REGCM_GPR8_LO)) {
24008                         dst_reg = (dst_reg - REGC_GPR8_FIRST) + REGC_GPR32_FIRST;
24009                         if ((src_reg != dst_reg) || !omit_copy) {
24010                                 fprintf(fp, "\tmov %s, %s\n",
24011                                         arch_reg_str(src_reg),
24012                                         arch_reg_str(dst_reg));
24013                         }
24014                 }
24015                 /* Move from 16bit gprs to 8bit gprs */
24016                 else if ((src_regcm & REGCM_GPR16) &&
24017                         (dst_regcm & REGCM_GPR8_LO)) {
24018                         dst_reg = (dst_reg - REGC_GPR8_FIRST) + REGC_GPR16_FIRST;
24019                         if ((src_reg != dst_reg) || !omit_copy) {
24020                                 fprintf(fp, "\tmov %s, %s\n",
24021                                         arch_reg_str(src_reg),
24022                                         arch_reg_str(dst_reg));
24023                         }
24024                 }
24025 #endif /* X86_4_8BIT_GPRS */
24026                 /* Move from %eax:%edx to %eax:%edx */
24027                 else if ((src_regcm & REGCM_DIVIDEND64) &&
24028                         (dst_regcm & REGCM_DIVIDEND64) &&
24029                         (src_reg == dst_reg)) {
24030                         if (!omit_copy) {
24031                                 fprintf(fp, "\t/*mov %s, %s*/\n",
24032                                         arch_reg_str(src_reg),
24033                                         arch_reg_str(dst_reg));
24034                         }
24035                 }
24036                 else {
24037                         if ((src_regcm & ~REGCM_FLAGS) == 0) {
24038                                 internal_error(state, ins, "attempt to copy from %%eflags!");
24039                         }
24040                         internal_error(state, ins, "unknown copy type");
24041                 }
24042         }
24043         else {
24044                 size_t dst_size;
24045                 int dst_reg;
24046                 int dst_regcm;
24047                 dst_size = size_of(state, dst->type);
24048                 dst_reg = ID_REG(dst->id);
24049                 dst_regcm = arch_reg_regcm(state, dst_reg);
24050                 if (dst_regcm & (REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO)) {
24051                         fprintf(fp, "\tmov ");
24052                         print_const_val(state, src, fp);
24053                         fprintf(fp, ", %s\n",
24054                                 reg(state, dst, REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO));
24055                 }
24056                 else if (dst_regcm & REGCM_DIVIDEND64) {
24057                         if (dst_size > SIZEOF_I32) {
24058                                 internal_error(state, ins, "%dbit constant...", dst_size);
24059                         }
24060                         fprintf(fp, "\tmov $0, %%edx\n");
24061                         fprintf(fp, "\tmov ");
24062                         print_const_val(state, src, fp);
24063                         fprintf(fp, ", %%eax\n");
24064                 }
24065                 else if (dst_regcm & REGCM_DIVIDEND32) {
24066                         if (dst_size > SIZEOF_I16) {
24067                                 internal_error(state, ins, "%dbit constant...", dst_size);
24068                         }
24069                         fprintf(fp, "\tmov $0, %%dx\n");
24070                         fprintf(fp, "\tmov ");
24071                         print_const_val(state, src, fp);
24072                         fprintf(fp, ", %%ax");
24073                 }
24074                 else if (dst_regcm & (REGCM_XMM | REGCM_MMX)) {
24075                         long ref;
24076                         if (dst_size > SIZEOF_I32) {
24077                                 internal_error(state, ins, "%d bit constant...", dst_size);
24078                         }
24079                         ref = get_const_pool_ref(state, src, SIZEOF_I32, fp);
24080                         fprintf(fp, "\tmovd L%s%lu, %s\n",
24081                                 state->compiler->label_prefix, ref,
24082                                 reg(state, dst, (REGCM_XMM | REGCM_MMX)));
24083                 }
24084                 else {
24085                         internal_error(state, ins, "unknown copy immediate type");
24086                 }
24087         }
24088         /* Leave now if this is not a type conversion */
24089         if (ins->op != OP_CONVERT) {
24090                 return;
24091         }
24092         /* Now make certain I have not logically overflowed the destination */
24093         if ((size_of(state, src->type) > size_of(state, dst->type)) &&
24094                 (size_of(state, dst->type) < reg_size(state, dst)))
24095         {
24096                 unsigned long mask;
24097                 int dst_reg;
24098                 int dst_regcm;
24099                 if (size_of(state, dst->type) >= 32) {
24100                         fprintf(state->errout, "dst type: ");
24101                         name_of(state->errout, dst->type);
24102                         fprintf(state->errout, "\n");
24103                         internal_error(state, dst, "unhandled dst type size");
24104                 }
24105                 mask = 1;
24106                 mask <<= size_of(state, dst->type);
24107                 mask -= 1;
24108
24109                 dst_reg = ID_REG(dst->id);
24110                 dst_regcm = arch_reg_regcm(state, dst_reg);
24111
24112                 if (dst_regcm & (REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO)) {
24113                         fprintf(fp, "\tand $0x%lx, %s\n",
24114                                 mask, reg(state, dst, REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO));
24115                 }
24116                 else if (dst_regcm & REGCM_MMX) {
24117                         long ref;
24118                         ref = get_mask_pool_ref(state, dst, mask, fp);
24119                         fprintf(fp, "\tpand L%s%lu, %s\n",
24120                                 state->compiler->label_prefix, ref,
24121                                 reg(state, dst, REGCM_MMX));
24122                 }
24123                 else if (dst_regcm & REGCM_XMM) {
24124                         long ref;
24125                         ref = get_mask_pool_ref(state, dst, mask, fp);
24126                         fprintf(fp, "\tpand L%s%lu, %s\n",
24127                                 state->compiler->label_prefix, ref,
24128                                 reg(state, dst, REGCM_XMM));
24129                 }
24130                 else {
24131                         fprintf(state->errout, "dst type: ");
24132                         name_of(state->errout, dst->type);
24133                         fprintf(state->errout, "\n");
24134                         fprintf(state->errout, "dst: %s\n", reg(state, dst, REGCM_ALL));
24135                         internal_error(state, dst, "failed to trunc value: mask %lx", mask);
24136                 }
24137         }
24138         /* Make certain I am properly sign extended */
24139         if ((size_of(state, src->type) < size_of(state, dst->type)) &&
24140                 (is_signed(src->type)))
24141         {
24142                 int bits, reg_bits, shift_bits;
24143                 int dst_reg;
24144                 int dst_regcm;
24145
24146                 bits = size_of(state, src->type);
24147                 reg_bits = reg_size(state, dst);
24148                 if (reg_bits > 32) {
24149                         reg_bits = 32;
24150                 }
24151                 shift_bits = reg_bits - size_of(state, src->type);
24152                 dst_reg = ID_REG(dst->id);
24153                 dst_regcm = arch_reg_regcm(state, dst_reg);
24154
24155                 if (shift_bits < 0) {
24156                         internal_error(state, dst, "negative shift?");
24157                 }
24158
24159                 if (dst_regcm & (REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO)) {
24160                         fprintf(fp, "\tshl $%d, %s\n", 
24161                                 shift_bits, 
24162                                 reg(state, dst, REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO));
24163                         fprintf(fp, "\tsar $%d, %s\n", 
24164                                 shift_bits, 
24165                                 reg(state, dst, REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO));
24166                 }
24167                 else if (dst_regcm & (REGCM_MMX | REGCM_XMM)) {
24168                         fprintf(fp, "\tpslld $%d, %s\n",
24169                                 shift_bits, 
24170                                 reg(state, dst, REGCM_MMX | REGCM_XMM));
24171                         fprintf(fp, "\tpsrad $%d, %s\n",
24172                                 shift_bits, 
24173                                 reg(state, dst, REGCM_MMX | REGCM_XMM));
24174                 }
24175                 else {
24176                         fprintf(state->errout, "dst type: ");
24177                         name_of(state->errout, dst->type);
24178                         fprintf(state->errout, "\n");
24179                         fprintf(state->errout, "dst: %s\n", reg(state, dst, REGCM_ALL));
24180                         internal_error(state, dst, "failed to signed extend value");
24181                 }
24182         }
24183 }
24184
24185 static void print_op_load(struct compile_state *state,
24186         struct triple *ins, FILE *fp)
24187 {
24188         struct triple *dst, *src;
24189         const char *op;
24190         dst = ins;
24191         src = RHS(ins, 0);
24192         if (is_const(src) || is_const(dst)) {
24193                 internal_error(state, ins, "unknown load operation");
24194         }
24195         switch(ins->type->type & TYPE_MASK) {
24196         case TYPE_CHAR:   op = "movsbl"; break;
24197         case TYPE_UCHAR:  op = "movzbl"; break;
24198         case TYPE_SHORT:  op = "movswl"; break;
24199         case TYPE_USHORT: op = "movzwl"; break;
24200         case TYPE_INT:    case TYPE_UINT:
24201         case TYPE_LONG:   case TYPE_ULONG:
24202         case TYPE_POINTER:
24203                 op = "movl"; 
24204                 break;
24205         default:
24206                 internal_error(state, ins, "unknown type in load");
24207                 op = "<invalid opcode>";
24208                 break;
24209         }
24210         fprintf(fp, "\t%s (%s), %s\n",
24211                 op, 
24212                 reg(state, src, REGCM_GPR32),
24213                 reg(state, dst, REGCM_GPR32));
24214 }
24215
24216
24217 static void print_op_store(struct compile_state *state,
24218         struct triple *ins, FILE *fp)
24219 {
24220         struct triple *dst, *src;
24221         dst = RHS(ins, 0);
24222         src = RHS(ins, 1);
24223         if (is_const(src) && (src->op == OP_INTCONST)) {
24224                 long_t value;
24225                 value = (long_t)(src->u.cval);
24226                 fprintf(fp, "\tmov%s $%ld, (%s)\n",
24227                         type_suffix(state, src->type),
24228                         (long)(value),
24229                         reg(state, dst, REGCM_GPR32));
24230         }
24231         else if (is_const(dst) && (dst->op == OP_INTCONST)) {
24232                 fprintf(fp, "\tmov%s %s, 0x%08lx\n",
24233                         type_suffix(state, src->type),
24234                         reg(state, src, REGCM_GPR8_LO | REGCM_GPR16 | REGCM_GPR32),
24235                         (unsigned long)(dst->u.cval));
24236         }
24237         else {
24238                 if (is_const(src) || is_const(dst)) {
24239                         internal_error(state, ins, "unknown store operation");
24240                 }
24241                 fprintf(fp, "\tmov%s %s, (%s)\n",
24242                         type_suffix(state, src->type),
24243                         reg(state, src, REGCM_GPR8_LO | REGCM_GPR16 | REGCM_GPR32),
24244                         reg(state, dst, REGCM_GPR32));
24245         }
24246         
24247         
24248 }
24249
24250 static void print_op_smul(struct compile_state *state,
24251         struct triple *ins, FILE *fp)
24252 {
24253         if (!is_const(RHS(ins, 1))) {
24254                 fprintf(fp, "\timul %s, %s\n",
24255                         reg(state, RHS(ins, 1), REGCM_GPR32),
24256                         reg(state, RHS(ins, 0), REGCM_GPR32));
24257         }
24258         else {
24259                 fprintf(fp, "\timul ");
24260                 print_const_val(state, RHS(ins, 1), fp);
24261                 fprintf(fp, ", %s\n", reg(state, RHS(ins, 0), REGCM_GPR32));
24262         }
24263 }
24264
24265 static void print_op_cmp(struct compile_state *state,
24266         struct triple *ins, FILE *fp)
24267 {
24268         unsigned mask;
24269         int dreg;
24270         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO;
24271         dreg = check_reg(state, ins, REGCM_FLAGS);
24272         if (!reg_is_reg(state, dreg, REG_EFLAGS)) {
24273                 internal_error(state, ins, "bad dest register for cmp");
24274         }
24275         if (is_const(RHS(ins, 1))) {
24276                 fprintf(fp, "\tcmp ");
24277                 print_const_val(state, RHS(ins, 1), fp);
24278                 fprintf(fp, ", %s\n", reg(state, RHS(ins, 0), mask));
24279         }
24280         else {
24281                 unsigned lmask, rmask;
24282                 int lreg, rreg;
24283                 lreg = check_reg(state, RHS(ins, 0), mask);
24284                 rreg = check_reg(state, RHS(ins, 1), mask);
24285                 lmask = arch_reg_regcm(state, lreg);
24286                 rmask = arch_reg_regcm(state, rreg);
24287                 mask = lmask & rmask;
24288                 fprintf(fp, "\tcmp %s, %s\n",
24289                         reg(state, RHS(ins, 1), mask),
24290                         reg(state, RHS(ins, 0), mask));
24291         }
24292 }
24293
24294 static void print_op_test(struct compile_state *state,
24295         struct triple *ins, FILE *fp)
24296 {
24297         unsigned mask;
24298         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO;
24299         fprintf(fp, "\ttest %s, %s\n",
24300                 reg(state, RHS(ins, 0), mask),
24301                 reg(state, RHS(ins, 0), mask));
24302 }
24303
24304 static void print_op_branch(struct compile_state *state,
24305         struct triple *branch, FILE *fp)
24306 {
24307         const char *bop = "j";
24308         if ((branch->op == OP_JMP) || (branch->op == OP_CALL)) {
24309                 if (branch->rhs != 0) {
24310                         internal_error(state, branch, "jmp with condition?");
24311                 }
24312                 bop = "jmp";
24313         }
24314         else {
24315                 struct triple *ptr;
24316                 if (branch->rhs != 1) {
24317                         internal_error(state, branch, "jmpcc without condition?");
24318                 }
24319                 check_reg(state, RHS(branch, 0), REGCM_FLAGS);
24320                 if ((RHS(branch, 0)->op != OP_CMP) &&
24321                         (RHS(branch, 0)->op != OP_TEST)) {
24322                         internal_error(state, branch, "bad branch test");
24323                 }
24324 #warning "FIXME I have observed instructions between the test and branch instructions"
24325                 ptr = RHS(branch, 0);
24326                 for(ptr = RHS(branch, 0)->next; ptr != branch; ptr = ptr->next) {
24327                         if (ptr->op != OP_COPY) {
24328                                 internal_error(state, branch, "branch does not follow test");
24329                         }
24330                 }
24331                 switch(branch->op) {
24332                 case OP_JMP_EQ:       bop = "jz";  break;
24333                 case OP_JMP_NOTEQ:    bop = "jnz"; break;
24334                 case OP_JMP_SLESS:    bop = "jl";  break;
24335                 case OP_JMP_ULESS:    bop = "jb";  break;
24336                 case OP_JMP_SMORE:    bop = "jg";  break;
24337                 case OP_JMP_UMORE:    bop = "ja";  break;
24338                 case OP_JMP_SLESSEQ:  bop = "jle"; break;
24339                 case OP_JMP_ULESSEQ:  bop = "jbe"; break;
24340                 case OP_JMP_SMOREEQ:  bop = "jge"; break;
24341                 case OP_JMP_UMOREEQ:  bop = "jae"; break;
24342                 default:
24343                         internal_error(state, branch, "Invalid branch op");
24344                         break;
24345                 }
24346                 
24347         }
24348 #if 1
24349         if (branch->op == OP_CALL) {
24350                 fprintf(fp, "\t/* call */\n");
24351         }
24352 #endif
24353         fprintf(fp, "\t%s L%s%lu\n",
24354                 bop, 
24355                 state->compiler->label_prefix,
24356                 (unsigned long)(TARG(branch, 0)->u.cval));
24357 }
24358
24359 static void print_op_ret(struct compile_state *state,
24360         struct triple *branch, FILE *fp)
24361 {
24362         fprintf(fp, "\tjmp *%s\n",
24363                 reg(state, RHS(branch, 0), REGCM_GPR32));
24364 }
24365
24366 static void print_op_set(struct compile_state *state,
24367         struct triple *set, FILE *fp)
24368 {
24369         const char *sop = "set";
24370         if (set->rhs != 1) {
24371                 internal_error(state, set, "setcc without condition?");
24372         }
24373         check_reg(state, RHS(set, 0), REGCM_FLAGS);
24374         if ((RHS(set, 0)->op != OP_CMP) &&
24375                 (RHS(set, 0)->op != OP_TEST)) {
24376                 internal_error(state, set, "bad set test");
24377         }
24378         if (RHS(set, 0)->next != set) {
24379                 internal_error(state, set, "set does not follow test");
24380         }
24381         switch(set->op) {
24382         case OP_SET_EQ:       sop = "setz";  break;
24383         case OP_SET_NOTEQ:    sop = "setnz"; break;
24384         case OP_SET_SLESS:    sop = "setl";  break;
24385         case OP_SET_ULESS:    sop = "setb";  break;
24386         case OP_SET_SMORE:    sop = "setg";  break;
24387         case OP_SET_UMORE:    sop = "seta";  break;
24388         case OP_SET_SLESSEQ:  sop = "setle"; break;
24389         case OP_SET_ULESSEQ:  sop = "setbe"; break;
24390         case OP_SET_SMOREEQ:  sop = "setge"; break;
24391         case OP_SET_UMOREEQ:  sop = "setae"; break;
24392         default:
24393                 internal_error(state, set, "Invalid set op");
24394                 break;
24395         }
24396         fprintf(fp, "\t%s %s\n",
24397                 sop, reg(state, set, REGCM_GPR8_LO));
24398 }
24399
24400 static void print_op_bit_scan(struct compile_state *state, 
24401         struct triple *ins, FILE *fp) 
24402 {
24403         const char *op;
24404         switch(ins->op) {
24405         case OP_BSF: op = "bsf"; break;
24406         case OP_BSR: op = "bsr"; break;
24407         default: 
24408                 internal_error(state, ins, "unknown bit scan");
24409                 op = 0;
24410                 break;
24411         }
24412         fprintf(fp, 
24413                 "\t%s %s, %s\n"
24414                 "\tjnz 1f\n"
24415                 "\tmovl $-1, %s\n"
24416                 "1:\n",
24417                 op,
24418                 reg(state, RHS(ins, 0), REGCM_GPR32),
24419                 reg(state, ins, REGCM_GPR32),
24420                 reg(state, ins, REGCM_GPR32));
24421 }
24422
24423
24424 static void print_sdecl(struct compile_state *state,
24425         struct triple *ins, FILE *fp)
24426 {
24427         fprintf(fp, ".section \"" DATA_SECTION "\"\n");
24428         fprintf(fp, ".balign %d\n", align_of_in_bytes(state, ins->type));
24429         fprintf(fp, "L%s%lu:\n", 
24430                 state->compiler->label_prefix, (unsigned long)(ins->u.cval));
24431         print_const(state, MISC(ins, 0), fp);
24432         fprintf(fp, ".section \"" TEXT_SECTION "\"\n");
24433                 
24434 }
24435
24436 static void print_instruction(struct compile_state *state,
24437         struct triple *ins, FILE *fp)
24438 {
24439         /* Assumption: after I have exted the register allocator
24440          * everything is in a valid register. 
24441          */
24442         switch(ins->op) {
24443         case OP_ASM:
24444                 print_op_asm(state, ins, fp);
24445                 break;
24446         case OP_ADD:    print_binary_op(state, "add", ins, fp); break;
24447         case OP_SUB:    print_binary_op(state, "sub", ins, fp); break;
24448         case OP_AND:    print_binary_op(state, "and", ins, fp); break;
24449         case OP_XOR:    print_binary_op(state, "xor", ins, fp); break;
24450         case OP_OR:     print_binary_op(state, "or",  ins, fp); break;
24451         case OP_SL:     print_op_shift(state, "shl", ins, fp); break;
24452         case OP_USR:    print_op_shift(state, "shr", ins, fp); break;
24453         case OP_SSR:    print_op_shift(state, "sar", ins, fp); break;
24454         case OP_POS:    break;
24455         case OP_NEG:    print_unary_op(state, "neg", ins, fp); break;
24456         case OP_INVERT: print_unary_op(state, "not", ins, fp); break;
24457         case OP_NOOP:
24458         case OP_INTCONST:
24459         case OP_ADDRCONST:
24460         case OP_BLOBCONST:
24461                 /* Don't generate anything here for constants */
24462         case OP_PHI:
24463                 /* Don't generate anything for variable declarations. */
24464                 break;
24465         case OP_UNKNOWNVAL:
24466                 fprintf(fp, " /* unknown %s */\n",
24467                         reg(state, ins, REGCM_ALL));
24468                 break;
24469         case OP_SDECL:
24470                 print_sdecl(state, ins, fp);
24471                 break;
24472         case OP_COPY:   
24473         case OP_CONVERT:
24474                 print_op_move(state, ins, fp);
24475                 break;
24476         case OP_LOAD:
24477                 print_op_load(state, ins, fp);
24478                 break;
24479         case OP_STORE:
24480                 print_op_store(state, ins, fp);
24481                 break;
24482         case OP_SMUL:
24483                 print_op_smul(state, ins, fp);
24484                 break;
24485         case OP_CMP:    print_op_cmp(state, ins, fp); break;
24486         case OP_TEST:   print_op_test(state, ins, fp); break;
24487         case OP_JMP:
24488         case OP_JMP_EQ:      case OP_JMP_NOTEQ:
24489         case OP_JMP_SLESS:   case OP_JMP_ULESS:
24490         case OP_JMP_SMORE:   case OP_JMP_UMORE:
24491         case OP_JMP_SLESSEQ: case OP_JMP_ULESSEQ:
24492         case OP_JMP_SMOREEQ: case OP_JMP_UMOREEQ:
24493         case OP_CALL:
24494                 print_op_branch(state, ins, fp);
24495                 break;
24496         case OP_RET:
24497                 print_op_ret(state, ins, fp);
24498                 break;
24499         case OP_SET_EQ:      case OP_SET_NOTEQ:
24500         case OP_SET_SLESS:   case OP_SET_ULESS:
24501         case OP_SET_SMORE:   case OP_SET_UMORE:
24502         case OP_SET_SLESSEQ: case OP_SET_ULESSEQ:
24503         case OP_SET_SMOREEQ: case OP_SET_UMOREEQ:
24504                 print_op_set(state, ins, fp);
24505                 break;
24506         case OP_INB:  case OP_INW:  case OP_INL:
24507                 print_op_in(state, ins, fp); 
24508                 break;
24509         case OP_OUTB: case OP_OUTW: case OP_OUTL:
24510                 print_op_out(state, ins, fp); 
24511                 break;
24512         case OP_BSF:
24513         case OP_BSR:
24514                 print_op_bit_scan(state, ins, fp);
24515                 break;
24516         case OP_RDMSR:
24517                 after_lhs(state, ins);
24518                 fprintf(fp, "\trdmsr\n");
24519                 break;
24520         case OP_WRMSR:
24521                 fprintf(fp, "\twrmsr\n");
24522                 break;
24523         case OP_HLT:
24524                 fprintf(fp, "\thlt\n");
24525                 break;
24526         case OP_SDIVT:
24527                 fprintf(fp, "\tidiv %s\n", reg(state, RHS(ins, 1), REGCM_GPR32));
24528                 break;
24529         case OP_UDIVT:
24530                 fprintf(fp, "\tdiv %s\n", reg(state, RHS(ins, 1), REGCM_GPR32));
24531                 break;
24532         case OP_UMUL:
24533                 fprintf(fp, "\tmul %s\n", reg(state, RHS(ins, 1), REGCM_GPR32));
24534                 break;
24535         case OP_LABEL:
24536                 if (!ins->use) {
24537                         return;
24538                 }
24539                 fprintf(fp, "L%s%lu:\n", 
24540                         state->compiler->label_prefix, (unsigned long)(ins->u.cval));
24541                 break;
24542         case OP_ADECL:
24543                 /* Ignore adecls with no registers error otherwise */
24544                 if (!noop_adecl(ins)) {
24545                         internal_error(state, ins, "adecl remains?");
24546                 }
24547                 break;
24548                 /* Ignore OP_PIECE */
24549         case OP_PIECE:
24550                 break;
24551                 /* Operations that should never get here */
24552         case OP_SDIV: case OP_UDIV:
24553         case OP_SMOD: case OP_UMOD:
24554         case OP_LTRUE:   case OP_LFALSE:  case OP_EQ:      case OP_NOTEQ:
24555         case OP_SLESS:   case OP_ULESS:   case OP_SMORE:   case OP_UMORE:
24556         case OP_SLESSEQ: case OP_ULESSEQ: case OP_SMOREEQ: case OP_UMOREEQ:
24557         default:
24558                 internal_error(state, ins, "unknown op: %d %s",
24559                         ins->op, tops(ins->op));
24560                 break;
24561         }
24562 }
24563
24564 static void print_instructions(struct compile_state *state)
24565 {
24566         struct triple *first, *ins;
24567         int print_location;
24568         struct occurance *last_occurance;
24569         FILE *fp;
24570         int max_inline_depth;
24571         max_inline_depth = 0;
24572         print_location = 1;
24573         last_occurance = 0;
24574         fp = state->output;
24575         /* Masks for common sizes */
24576         fprintf(fp, ".section \"" DATA_SECTION "\"\n");
24577         fprintf(fp, ".balign 16\n");
24578         fprintf(fp, "L%s1:\n", state->compiler->label_prefix);
24579         fprintf(fp, ".int 0xff, 0, 0, 0\n");
24580         fprintf(fp, "L%s2:\n", state->compiler->label_prefix);
24581         fprintf(fp, ".int 0xffff, 0, 0, 0\n");
24582         fprintf(fp, ".section \"" TEXT_SECTION "\"\n");
24583         first = state->first;
24584         ins = first;
24585         do {
24586                 if (print_location && 
24587                         last_occurance != ins->occurance) {
24588                         if (!ins->occurance->parent) {
24589                                 fprintf(fp, "\t/* %s,%s:%d.%d */\n",
24590                                         ins->occurance->function,
24591                                         ins->occurance->filename,
24592                                         ins->occurance->line,
24593                                         ins->occurance->col);
24594                         }
24595                         else {
24596                                 struct occurance *ptr;
24597                                 int inline_depth;
24598                                 fprintf(fp, "\t/*\n");
24599                                 inline_depth = 0;
24600                                 for(ptr = ins->occurance; ptr; ptr = ptr->parent) {
24601                                         inline_depth++;
24602                                         fprintf(fp, "\t * %s,%s:%d.%d\n",
24603                                                 ptr->function,
24604                                                 ptr->filename,
24605                                                 ptr->line,
24606                                                 ptr->col);
24607                                 }
24608                                 fprintf(fp, "\t */\n");
24609                                 if (inline_depth > max_inline_depth) {
24610                                         max_inline_depth = inline_depth;
24611                                 }
24612                         }
24613                         if (last_occurance) {
24614                                 put_occurance(last_occurance);
24615                         }
24616                         get_occurance(ins->occurance);
24617                         last_occurance = ins->occurance;
24618                 }
24619
24620                 print_instruction(state, ins, fp);
24621                 ins = ins->next;
24622         } while(ins != first);
24623         if (print_location) {
24624                 fprintf(fp, "/* max inline depth %d */\n",
24625                         max_inline_depth);
24626         }
24627 }
24628
24629 static void generate_code(struct compile_state *state)
24630 {
24631         generate_local_labels(state);
24632         print_instructions(state);
24633         
24634 }
24635
24636 static void print_preprocessed_tokens(struct compile_state *state)
24637 {
24638         int tok;
24639         FILE *fp;
24640         int line;
24641         const char *filename;
24642         fp = state->output;
24643         filename = 0;
24644         line = 0;
24645         for(;;) {
24646                 struct token *tk;
24647                 const char *token_str;
24648                 tok = peek(state);
24649                 if (tok == TOK_EOF) {
24650                         break;
24651                 }
24652                 tk = eat(state, tok);
24653                 token_str = 
24654                         tk->ident ? tk->ident->name :
24655                         tk->str_len ? tk->val.str :
24656                         tokens[tk->tok];
24657                 
24658                 if ((state->file->line != line) || 
24659                         (state->file->basename != filename)) {
24660                         int i, col;
24661                         if ((state->file->basename == filename) &&
24662                                 (line < state->file->line)) {
24663                                 while(line < state->file->line) {
24664                                         fprintf(fp, "\n");
24665                                         line++;
24666                                 }
24667                         }
24668                         else {
24669                                 fprintf(fp, "\n#line %d \"%s\"\n",
24670                                         state->file->line, state->file->basename);
24671                         }
24672                         line = state->file->line;
24673                         filename = state->file->basename;
24674                         col = get_col(state->file) - strlen(token_str);
24675                         for(i = 0; i < col; i++) {
24676                                 fprintf(fp, " ");
24677                         }
24678                 }
24679                 
24680                 fprintf(fp, "%s ", token_str);
24681                 
24682                 if (state->compiler->debug & DEBUG_TOKENS) {
24683                         loc(state->dbgout, state, 0);
24684                         fprintf(state->dbgout, "%s <- `%s'\n",
24685                                 tokens[tok], token_str);
24686                 }
24687         }
24688 }
24689
24690 static void compile(const char *filename, 
24691         struct compiler_state *compiler, struct arch_state *arch)
24692 {
24693         int i;
24694         struct compile_state state;
24695         struct triple *ptr;
24696         memset(&state, 0, sizeof(state));
24697         state.compiler = compiler;
24698         state.arch     = arch;
24699         state.file = 0;
24700         for(i = 0; i < sizeof(state.token)/sizeof(state.token[0]); i++) {
24701                 memset(&state.token[i], 0, sizeof(state.token[i]));
24702                 state.token[i].tok = -1;
24703         }
24704         /* Remember the output descriptors */
24705         state.errout = stderr;
24706         state.dbgout = stdout;
24707         /* Remember the output filename */
24708         state.output    = fopen(state.compiler->ofilename, "w");
24709         if (!state.output) {
24710                 error(&state, 0, "Cannot open output file %s\n",
24711                         state.compiler->ofilename);
24712         }
24713         /* Make certain a good cleanup happens */
24714         exit_state = &state;
24715         atexit(exit_cleanup);
24716
24717         /* Prep the preprocessor */
24718         state.if_depth = 0;
24719         memset(state.if_bytes, 0, sizeof(state.if_bytes));
24720         /* register the C keywords */
24721         register_keywords(&state);
24722         /* register the keywords the macro preprocessor knows */
24723         register_macro_keywords(&state);
24724         /* generate some builtin macros */
24725         register_builtin_macros(&state);
24726         /* Memorize where some special keywords are. */
24727         state.i_switch        = lookup(&state, "switch", 6);
24728         state.i_case          = lookup(&state, "case", 4);
24729         state.i_continue      = lookup(&state, "continue", 8);
24730         state.i_break         = lookup(&state, "break", 5);
24731         state.i_default       = lookup(&state, "default", 7);
24732         state.i_return        = lookup(&state, "return", 6);
24733         /* Memorize where predefined macros are. */
24734         state.i___VA_ARGS__   = lookup(&state, "__VA_ARGS__", 11);
24735         state.i___FILE__      = lookup(&state, "__FILE__", 8);
24736         state.i___LINE__      = lookup(&state, "__LINE__", 8);
24737         /* Memorize where predefined identifiers are. */
24738         state.i___func__      = lookup(&state, "__func__", 8);
24739         /* Memorize where some attribute keywords are. */
24740         state.i_noinline      = lookup(&state, "noinline", 8);
24741         state.i_always_inline = lookup(&state, "always_inline", 13);
24742
24743         /* Process the command line macros */
24744         process_cmdline_macros(&state);
24745
24746         /* Allocate beginning bounding labels for the function list */
24747         state.first = label(&state);
24748         state.first->id |= TRIPLE_FLAG_VOLATILE;
24749         use_triple(state.first, state.first);
24750         ptr = label(&state);
24751         ptr->id |= TRIPLE_FLAG_VOLATILE;
24752         use_triple(ptr, ptr);
24753         flatten(&state, state.first, ptr);
24754
24755         /* Allocate a label for the pool of global variables */
24756         state.global_pool = label(&state);
24757         state.global_pool->id |= TRIPLE_FLAG_VOLATILE;
24758         flatten(&state, state.first, state.global_pool);
24759
24760         /* Enter the globl definition scope */
24761         start_scope(&state);
24762         register_builtins(&state);
24763         compile_file(&state, filename, 1);
24764
24765         /* Stop if all we want is preprocessor output */
24766         if (state.compiler->flags & COMPILER_CPP_ONLY) {
24767                 print_preprocessed_tokens(&state);
24768                 return;
24769         }
24770
24771         decls(&state);
24772
24773         /* Exit the global definition scope */
24774         end_scope(&state);
24775
24776         /* Now that basic compilation has happened 
24777          * optimize the intermediate code 
24778          */
24779         optimize(&state);
24780
24781         generate_code(&state);
24782         if (state.compiler->debug) {
24783                 fprintf(state.errout, "done\n");
24784         }
24785         exit_state = 0;
24786 }
24787
24788 static void version(FILE *fp)
24789 {
24790         fprintf(fp, "romcc " VERSION " released " RELEASE_DATE "\n");
24791 }
24792
24793 static void usage(void)
24794 {
24795         FILE *fp = stdout;
24796         version(fp);
24797         fprintf(fp,
24798                 "\nUsage: romcc [options] <source>.c\n"
24799                 "Compile a C source file generating a binary that does not implicilty use RAM\n"
24800                 "Options: \n"
24801                 "-o <output file name>\n"
24802                 "-f<option>            Specify a generic compiler option\n"
24803                 "-m<option>            Specify a arch dependent option\n"
24804                 "--                    Specify this is the last option\n"
24805                 "\nGeneric compiler options:\n"
24806         );
24807         compiler_usage(fp);
24808         fprintf(fp,
24809                 "\nArchitecture compiler options:\n"
24810         );
24811         arch_usage(fp);
24812         fprintf(fp,
24813                 "\n"
24814         );
24815 }
24816
24817 static void arg_error(char *fmt, ...)
24818 {
24819         va_list args;
24820         va_start(args, fmt);
24821         vfprintf(stderr, fmt, args);
24822         va_end(args);
24823         usage();
24824         exit(1);
24825 }
24826
24827 int main(int argc, char **argv)
24828 {
24829         const char *filename;
24830         struct compiler_state compiler;
24831         struct arch_state arch;
24832         int all_opts;
24833         
24834         
24835         /* I don't want any surprises */
24836         setlocale(LC_ALL, "C");
24837
24838         init_compiler_state(&compiler);
24839         init_arch_state(&arch);
24840         filename = 0;
24841         all_opts = 0;
24842         while(argc > 1) {
24843                 if (!all_opts && (strcmp(argv[1], "-o") == 0) && (argc > 2)) {
24844                         compiler.ofilename = argv[2];
24845                         argv += 2;
24846                         argc -= 2;
24847                 }
24848                 else if (!all_opts && argv[1][0] == '-') {
24849                         int result;
24850                         result = -1;
24851                         if (strcmp(argv[1], "--") == 0) {
24852                                 result = 0;
24853                                 all_opts = 1;
24854                         }
24855                         else if (strncmp(argv[1], "-E", 2) == 0) {
24856                                 result = compiler_encode_flag(&compiler, argv[1]);
24857                         }
24858                         else if (strncmp(argv[1], "-O", 2) == 0) {
24859                                 result = compiler_encode_flag(&compiler, argv[1]);
24860                         }
24861                         else if (strncmp(argv[1], "-I", 2) == 0) {
24862                                 result = compiler_encode_flag(&compiler, argv[1]);
24863                         }
24864                         else if (strncmp(argv[1], "-D", 2) == 0) {
24865                                 result = compiler_encode_flag(&compiler, argv[1]);
24866                         }
24867                         else if (strncmp(argv[1], "-U", 2) == 0) {
24868                                 result = compiler_encode_flag(&compiler, argv[1]);
24869                         }
24870                         else if (strncmp(argv[1], "--label-prefix=", 15) == 0) {
24871                                 result = compiler_encode_flag(&compiler, argv[1]+2);
24872                         }
24873                         else if (strncmp(argv[1], "-f", 2) == 0) {
24874                                 result = compiler_encode_flag(&compiler, argv[1]+2);
24875                         }
24876                         else if (strncmp(argv[1], "-m", 2) == 0) {
24877                                 result = arch_encode_flag(&arch, argv[1]+2);
24878                         }
24879                         if (result < 0) {
24880                                 arg_error("Invalid option specified: %s\n",
24881                                         argv[1]);
24882                         }
24883                         argv++;
24884                         argc--;
24885                 }
24886                 else {
24887                         if (filename) {
24888                                 arg_error("Only one filename may be specified\n");
24889                         }
24890                         filename = argv[1];
24891                         argv++;
24892                         argc--;
24893                 }
24894         }
24895         if (!filename) {
24896                 arg_error("No filename specified\n");
24897         }
24898         compile(filename, &compiler, &arch);
24899
24900         return 0;
24901 }