- Clean up the CPP output a little bit
[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 "67"
7 #define RELEASE_DATE "9 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         int macro : 1;
340 };
341 struct hash_entry;
342 struct token {
343         int tok;
344         struct hash_entry *ident;
345         int str_len;
346         union {
347                 ulong_t integer;
348                 const char *str;
349                 int notmacro;
350         } val;
351 };
352
353 /* I have two classes of types:
354  * Operational types.
355  * Logical types.  (The type the C standard says the operation is of)
356  *
357  * The operational types are:
358  * chars
359  * shorts
360  * ints
361  * longs
362  *
363  * floats
364  * doubles
365  * long doubles
366  *
367  * pointer
368  */
369
370
371 /* Machine model.
372  * No memory is useable by the compiler.
373  * There is no floating point support.
374  * All operations take place in general purpose registers.
375  * There is one type of general purpose register.
376  * Unsigned longs are stored in that general purpose register.
377  */
378
379 /* Operations on general purpose registers.
380  */
381
382 #define OP_SDIVT      0
383 #define OP_UDIVT      1
384 #define OP_SMUL       2
385 #define OP_UMUL       3
386 #define OP_SDIV       4
387 #define OP_UDIV       5
388 #define OP_SMOD       6
389 #define OP_UMOD       7
390 #define OP_ADD        8
391 #define OP_SUB        9
392 #define OP_SL        10
393 #define OP_USR       11
394 #define OP_SSR       12 
395 #define OP_AND       13 
396 #define OP_XOR       14
397 #define OP_OR        15
398 #define OP_POS       16 /* Dummy positive operator don't use it */
399 #define OP_NEG       17
400 #define OP_INVERT    18
401                      
402 #define OP_EQ        20
403 #define OP_NOTEQ     21
404 #define OP_SLESS     22
405 #define OP_ULESS     23
406 #define OP_SMORE     24
407 #define OP_UMORE     25
408 #define OP_SLESSEQ   26
409 #define OP_ULESSEQ   27
410 #define OP_SMOREEQ   28
411 #define OP_UMOREEQ   29
412                      
413 #define OP_LFALSE    30  /* Test if the expression is logically false */
414 #define OP_LTRUE     31  /* Test if the expression is logcially true */
415
416 #define OP_LOAD      32
417 #define OP_STORE     33
418 /* For OP_STORE ->type holds the type
419  * RHS(0) holds the destination address
420  * RHS(1) holds the value to store.
421  */
422
423 #define OP_UEXTRACT  34
424 /* OP_UEXTRACT extracts an unsigned bitfield from a pseudo register
425  * RHS(0) holds the psuedo register to extract from
426  * ->type holds the size of the bitfield.
427  * ->u.bitfield.size holds the size of the bitfield.
428  * ->u.bitfield.offset holds the offset to extract from
429  */
430 #define OP_SEXTRACT  35
431 /* OP_SEXTRACT extracts a signed bitfield from a pseudo register
432  * RHS(0) holds the psuedo register to extract from
433  * ->type holds the size of the bitfield.
434  * ->u.bitfield.size holds the size of the bitfield.
435  * ->u.bitfield.offset holds the offset to extract from
436  */
437 #define OP_DEPOSIT   36
438 /* OP_DEPOSIT replaces a bitfield with a new value.
439  * RHS(0) holds the value to replace a bitifield in.
440  * RHS(1) holds the replacement value
441  * ->u.bitfield.size holds the size of the bitfield.
442  * ->u.bitfield.offset holds the deposit into
443  */
444
445 #define OP_NOOP      37
446
447 #define OP_MIN_CONST 50
448 #define OP_MAX_CONST 58
449 #define IS_CONST_OP(X) (((X) >= OP_MIN_CONST) && ((X) <= OP_MAX_CONST))
450 #define OP_INTCONST  50
451 /* For OP_INTCONST ->type holds the type.
452  * ->u.cval holds the constant value.
453  */
454 #define OP_BLOBCONST 51
455 /* For OP_BLOBCONST ->type holds the layout and size
456  * information.  u.blob holds a pointer to the raw binary
457  * data for the constant initializer.
458  */
459 #define OP_ADDRCONST 52
460 /* For OP_ADDRCONST ->type holds the type.
461  * MISC(0) holds the reference to the static variable.
462  * ->u.cval holds an offset from that value.
463  */
464 #define OP_UNKNOWNVAL 59
465 /* For OP_UNKNOWNAL ->type holds the type.
466  * For some reason we don't know what value this type has.
467  * This allows for variables that have don't have values
468  * assigned yet, or variables whose value we simply do not know.
469  */
470
471 #define OP_WRITE     60 
472 /* OP_WRITE moves one pseudo register to another.
473  * MISC(0) holds the destination pseudo register, which must be an OP_DECL.
474  * RHS(0) holds the psuedo to move.
475  */
476
477 #define OP_READ      61
478 /* OP_READ reads the value of a variable and makes
479  * it available for the pseudo operation.
480  * Useful for things like def-use chains.
481  * RHS(0) holds points to the triple to read from.
482  */
483 #define OP_COPY      62
484 /* OP_COPY makes a copy of the pseudo register or constant in RHS(0).
485  */
486 #define OP_CONVERT   63
487 /* OP_CONVERT makes a copy of the pseudo register or constant in RHS(0).
488  * And then the type is converted appropriately.
489  */
490 #define OP_PIECE     64
491 /* OP_PIECE returns one piece of a instruction that returns a structure.
492  * MISC(0) is the instruction
493  * u.cval is the LHS piece of the instruction to return.
494  */
495 #define OP_ASM       65
496 /* OP_ASM holds a sequence of assembly instructions, the result
497  * of a C asm directive.
498  * RHS(x) holds input value x to the assembly sequence.
499  * LHS(x) holds the output value x from the assembly sequence.
500  * u.blob holds the string of assembly instructions.
501  */
502
503 #define OP_DEREF     66
504 /* OP_DEREF generates an lvalue from a pointer.
505  * RHS(0) holds the pointer value.
506  * OP_DEREF serves as a place holder to indicate all necessary
507  * checks have been done to indicate a value is an lvalue.
508  */
509 #define OP_DOT       67
510 /* OP_DOT references a submember of a structure lvalue.
511  * MISC(0) holds the lvalue.
512  * ->u.field holds the name of the field we want.
513  *
514  * Not seen after structures are flattened.
515  */
516 #define OP_INDEX     68
517 /* OP_INDEX references a submember of a tuple or array lvalue.
518  * MISC(0) holds the lvalue.
519  * ->u.cval holds the index into the lvalue.
520  *
521  * Not seen after structures are flattened.
522  */
523 #define OP_VAL       69
524 /* OP_VAL returns the value of a subexpression of the current expression.
525  * Useful for operators that have side effects.
526  * RHS(0) holds the expression.
527  * MISC(0) holds the subexpression of RHS(0) that is the
528  * value of the expression.
529  *
530  * Not seen outside of expressions.
531  */
532
533 #define OP_TUPLE     70
534 /* OP_TUPLE is an array of triples that are either variable
535  * or values for a structure or an array.  It is used as
536  * a place holder when flattening compound types.
537  * The value represented by an OP_TUPLE is held in N registers.
538  * LHS(0..N-1) refer to those registers.
539  * ->use is a list of statements that use the value.
540  * 
541  * Although OP_TUPLE always has register sized pieces they are not
542  * used until structures are flattened/decomposed into their register
543  * components. 
544  * ???? registers ????
545  */
546
547 #define OP_BITREF    71
548 /* OP_BITREF describes a bitfield as an lvalue.
549  * RHS(0) holds the register value.
550  * ->type holds the type of the bitfield.
551  * ->u.bitfield.size holds the size of the bitfield.
552  * ->u.bitfield.offset holds the offset of the bitfield in the register
553  */
554
555
556 #define OP_FCALL     72
557 /* OP_FCALL performs a procedure call. 
558  * MISC(0) holds a pointer to the OP_LIST of a function
559  * RHS(x) holds argument x of a function
560  * 
561  * Currently not seen outside of expressions.
562  */
563 #define OP_PROG      73
564 /* OP_PROG is an expression that holds a list of statements, or
565  * expressions.  The final expression is the value of the expression.
566  * RHS(0) holds the start of the list.
567  */
568
569 /* statements */
570 #define OP_LIST      80
571 /* OP_LIST Holds a list of statements that compose a function, and a result value.
572  * RHS(0) holds the list of statements.
573  * A list of all functions is maintained.
574  */
575
576 #define OP_BRANCH    81 /* an unconditional branch */
577 /* For branch instructions
578  * TARG(0) holds the branch target.
579  * ->next holds where to branch to if the branch is not taken.
580  * The branch target can only be a label
581  */
582
583 #define OP_CBRANCH   82 /* a conditional branch */
584 /* For conditional branch instructions
585  * RHS(0) holds the branch condition.
586  * TARG(0) holds the branch target.
587  * ->next holds where to branch to if the branch is not taken.
588  * The branch target can only be a label
589  */
590
591 #define OP_CALL      83 /* an uncontional branch that will return */
592 /* For call instructions
593  * MISC(0) holds the OP_RET that returns from the branch
594  * TARG(0) holds the branch target.
595  * ->next holds where to branch to if the branch is not taken.
596  * The branch target can only be a label
597  */
598
599 #define OP_RET       84 /* an uncontinonal branch through a variable back to an OP_CALL */
600 /* For call instructions
601  * RHS(0) holds the variable with the return address
602  * The branch target can only be a label
603  */
604
605 #define OP_LABEL     86
606 /* OP_LABEL is a triple that establishes an target for branches.
607  * ->use is the list of all branches that use this label.
608  */
609
610 #define OP_ADECL     87 
611 /* OP_ADECL is a triple that establishes an lvalue for assignments.
612  * A variable takes N registers to contain.
613  * LHS(0..N-1) refer to an OP_PIECE triple that represents
614  * the Xth register that the variable is stored in.
615  * ->use is a list of statements that use the variable.
616  * 
617  * Although OP_ADECL always has register sized pieces they are not
618  * used until structures are flattened/decomposed into their register
619  * components. 
620  */
621
622 #define OP_SDECL     88
623 /* OP_SDECL is a triple that establishes a variable of static
624  * storage duration.
625  * ->use is a list of statements that use the variable.
626  * MISC(0) holds the initializer expression.
627  */
628
629
630 #define OP_PHI       89
631 /* OP_PHI is a triple used in SSA form code.  
632  * It is used when multiple code paths merge and a variable needs
633  * a single assignment from any of those code paths.
634  * The operation is a cross between OP_DECL and OP_WRITE, which
635  * is what OP_PHI is generated from.
636  * 
637  * RHS(x) points to the value from code path x
638  * The number of RHS entries is the number of control paths into the block
639  * in which OP_PHI resides.  The elements of the array point to point
640  * to the variables OP_PHI is derived from.
641  *
642  * MISC(0) holds a pointer to the orginal OP_DECL node.
643  */
644
645 #if 0
646 /* continuation helpers
647  */
648 #define OP_CPS_BRANCH    90 /* an unconditional branch */
649 /* OP_CPS_BRANCH calls a continuation 
650  * RHS(x) holds argument x of the function
651  * TARG(0) holds OP_CPS_START target
652  */
653 #define OP_CPS_CBRANCH   91  /* a conditional branch */
654 /* OP_CPS_CBRANCH conditionally calls one of two continuations 
655  * RHS(0) holds the branch condition
656  * RHS(x + 1) holds argument x of the function
657  * TARG(0) holds the OP_CPS_START to jump to when true
658  * ->next holds the OP_CPS_START to jump to when false
659  */
660 #define OP_CPS_CALL      92  /* an uncontional branch that will return */
661 /* For OP_CPS_CALL instructions
662  * RHS(x) holds argument x of the function
663  * MISC(0) holds the OP_CPS_RET that returns from the branch
664  * TARG(0) holds the branch target.
665  * ->next holds where the OP_CPS_RET will return to.
666  */
667 #define OP_CPS_RET       93
668 /* OP_CPS_RET conditionally calls one of two continuations 
669  * RHS(0) holds the variable with the return function address
670  * RHS(x + 1) holds argument x of the function
671  * The branch target may be any OP_CPS_START
672  */
673 #define OP_CPS_END       94
674 /* OP_CPS_END is the triple at the end of the program.
675  * For most practical purposes it is a branch.
676  */
677 #define OP_CPS_START     95
678 /* OP_CPS_START is a triple at the start of a continuation
679  * The arguments variables takes N registers to contain.
680  * LHS(0..N-1) refer to an OP_PIECE triple that represents
681  * the Xth register that the arguments are stored in.
682  */
683 #endif
684
685 /* Architecture specific instructions */
686 #define OP_CMP         100
687 #define OP_TEST        101
688 #define OP_SET_EQ      102
689 #define OP_SET_NOTEQ   103
690 #define OP_SET_SLESS   104
691 #define OP_SET_ULESS   105
692 #define OP_SET_SMORE   106
693 #define OP_SET_UMORE   107
694 #define OP_SET_SLESSEQ 108
695 #define OP_SET_ULESSEQ 109
696 #define OP_SET_SMOREEQ 110
697 #define OP_SET_UMOREEQ 111
698
699 #define OP_JMP         112
700 #define OP_JMP_EQ      113
701 #define OP_JMP_NOTEQ   114
702 #define OP_JMP_SLESS   115
703 #define OP_JMP_ULESS   116
704 #define OP_JMP_SMORE   117
705 #define OP_JMP_UMORE   118
706 #define OP_JMP_SLESSEQ 119
707 #define OP_JMP_ULESSEQ 120
708 #define OP_JMP_SMOREEQ 121
709 #define OP_JMP_UMOREEQ 122
710
711 /* Builtin operators that it is just simpler to use the compiler for */
712 #define OP_INB         130
713 #define OP_INW         131
714 #define OP_INL         132
715 #define OP_OUTB        133
716 #define OP_OUTW        134
717 #define OP_OUTL        135
718 #define OP_BSF         136
719 #define OP_BSR         137
720 #define OP_RDMSR       138
721 #define OP_WRMSR       139
722 #define OP_HLT         140
723
724 struct op_info {
725         const char *name;
726         unsigned flags;
727 #define PURE       0x001 /* Triple has no side effects */
728 #define IMPURE     0x002 /* Triple has side effects */
729 #define PURE_BITS(FLAGS) ((FLAGS) & 0x3)
730 #define DEF        0x004 /* Triple is a variable definition */
731 #define BLOCK      0x008 /* Triple stores the current block */
732 #define STRUCTURAL 0x010 /* Triple does not generate a machine instruction */
733 #define BRANCH_BITS(FLAGS) ((FLAGS) & 0xe0 )
734 #define UBRANCH    0x020 /* Triple is an unconditional branch instruction */
735 #define CBRANCH    0x040 /* Triple is a conditional branch instruction */
736 #define RETBRANCH  0x060 /* Triple is a return instruction */
737 #define CALLBRANCH 0x080 /* Triple is a call instruction */
738 #define ENDBRANCH  0x0a0 /* Triple is an end instruction */
739 #define PART       0x100 /* Triple is really part of another triple */
740 #define BITFIELD   0x200 /* Triple manipulates a bitfield */
741         signed char lhs, rhs, misc, targ;
742 };
743
744 #define OP(LHS, RHS, MISC, TARG, FLAGS, NAME) { \
745         .name = (NAME), \
746         .flags = (FLAGS), \
747         .lhs = (LHS), \
748         .rhs = (RHS), \
749         .misc = (MISC), \
750         .targ = (TARG), \
751          }
752 static const struct op_info table_ops[] = {
753 [OP_SDIVT      ] = OP( 2,  2, 0, 0, PURE | BLOCK , "sdivt"),
754 [OP_UDIVT      ] = OP( 2,  2, 0, 0, PURE | BLOCK , "udivt"),
755 [OP_SMUL       ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "smul"),
756 [OP_UMUL       ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "umul"),
757 [OP_SDIV       ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "sdiv"),
758 [OP_UDIV       ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "udiv"),
759 [OP_SMOD       ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "smod"),
760 [OP_UMOD       ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "umod"),
761 [OP_ADD        ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "add"),
762 [OP_SUB        ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "sub"),
763 [OP_SL         ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "sl"),
764 [OP_USR        ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "usr"),
765 [OP_SSR        ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "ssr"),
766 [OP_AND        ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "and"),
767 [OP_XOR        ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "xor"),
768 [OP_OR         ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "or"),
769 [OP_POS        ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK , "pos"),
770 [OP_NEG        ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK , "neg"),
771 [OP_INVERT     ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK , "invert"),
772
773 [OP_EQ         ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "eq"),
774 [OP_NOTEQ      ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "noteq"),
775 [OP_SLESS      ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "sless"),
776 [OP_ULESS      ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "uless"),
777 [OP_SMORE      ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "smore"),
778 [OP_UMORE      ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "umore"),
779 [OP_SLESSEQ    ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "slesseq"),
780 [OP_ULESSEQ    ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "ulesseq"),
781 [OP_SMOREEQ    ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "smoreeq"),
782 [OP_UMOREEQ    ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "umoreeq"),
783 [OP_LFALSE     ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK , "lfalse"),
784 [OP_LTRUE      ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK , "ltrue"),
785
786 [OP_LOAD       ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "load"),
787 [OP_STORE      ] = OP( 0,  2, 0, 0, PURE | BLOCK , "store"),
788
789 [OP_UEXTRACT   ] = OP( 0,  1, 0, 0, PURE | DEF | BITFIELD, "uextract"),
790 [OP_SEXTRACT   ] = OP( 0,  1, 0, 0, PURE | DEF | BITFIELD, "sextract"),
791 [OP_DEPOSIT    ] = OP( 0,  2, 0, 0, PURE | DEF | BITFIELD, "deposit"),
792
793 [OP_NOOP       ] = OP( 0,  0, 0, 0, PURE | BLOCK | STRUCTURAL, "noop"),
794
795 [OP_INTCONST   ] = OP( 0,  0, 0, 0, PURE | DEF, "intconst"),
796 [OP_BLOBCONST  ] = OP( 0,  0, 0, 0, PURE , "blobconst"),
797 [OP_ADDRCONST  ] = OP( 0,  0, 1, 0, PURE | DEF, "addrconst"),
798 [OP_UNKNOWNVAL ] = OP( 0,  0, 0, 0, PURE | DEF, "unknown"),
799
800 #warning "FIXME is it correct for OP_WRITE to be a def?  I currently use it as one..."
801 [OP_WRITE      ] = OP( 0,  1, 1, 0, PURE | DEF | BLOCK, "write"),
802 [OP_READ       ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "read"),
803 [OP_COPY       ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "copy"),
804 [OP_CONVERT    ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "convert"),
805 [OP_PIECE      ] = OP( 0,  0, 1, 0, PURE | DEF | STRUCTURAL | PART, "piece"),
806 [OP_ASM        ] = OP(-1, -1, 0, 0, PURE, "asm"),
807 [OP_DEREF      ] = OP( 0,  1, 0, 0, 0 | DEF | BLOCK, "deref"), 
808 [OP_DOT        ] = OP( 0,  0, 1, 0, PURE | DEF | PART, "dot"),
809 [OP_INDEX      ] = OP( 0,  0, 1, 0, PURE | DEF | PART, "index"),
810
811 [OP_VAL        ] = OP( 0,  1, 1, 0, 0 | DEF | BLOCK, "val"),
812 [OP_TUPLE      ] = OP(-1,  0, 0, 0, 0 | PURE | BLOCK | STRUCTURAL, "tuple"),
813 [OP_BITREF     ] = OP( 0,  1, 0, 0, 0 | DEF | PURE | STRUCTURAL | BITFIELD, "bitref"),
814 /* Call is special most it can stand in for anything so it depends on context */
815 [OP_FCALL      ] = OP( 0, -1, 1, 0, 0 | BLOCK | CALLBRANCH, "fcall"),
816 [OP_PROG       ] = OP( 0,  1, 0, 0, 0 | IMPURE | BLOCK | STRUCTURAL, "prog"),
817 /* The sizes of OP_FCALL depends upon context */
818
819 [OP_LIST       ] = OP( 0,  1, 1, 0, 0 | DEF | STRUCTURAL, "list"),
820 [OP_BRANCH     ] = OP( 0,  0, 0, 1, PURE | BLOCK | UBRANCH, "branch"),
821 [OP_CBRANCH    ] = OP( 0,  1, 0, 1, PURE | BLOCK | CBRANCH, "cbranch"),
822 [OP_CALL       ] = OP( 0,  0, 1, 1, PURE | BLOCK | CALLBRANCH, "call"),
823 [OP_RET        ] = OP( 0,  1, 0, 0, PURE | BLOCK | RETBRANCH, "ret"),
824 [OP_LABEL      ] = OP( 0,  0, 0, 0, PURE | BLOCK | STRUCTURAL, "label"),
825 [OP_ADECL      ] = OP( 0,  0, 0, 0, PURE | BLOCK | STRUCTURAL, "adecl"),
826 [OP_SDECL      ] = OP( 0,  0, 1, 0, PURE | BLOCK | STRUCTURAL, "sdecl"),
827 /* The number of RHS elements of OP_PHI depend upon context */
828 [OP_PHI        ] = OP( 0, -1, 1, 0, PURE | DEF | BLOCK, "phi"),
829
830 #if 0
831 [OP_CPS_BRANCH ] = OP( 0, -1, 0, 1, PURE | BLOCK | UBRANCH,     "cps_branch"),
832 [OP_CPS_CBRANCH] = OP( 0, -1, 0, 1, PURE | BLOCK | CBRANCH,     "cps_cbranch"),
833 [OP_CPS_CALL   ] = OP( 0, -1, 1, 1, PURE | BLOCK | CALLBRANCH,  "cps_call"),
834 [OP_CPS_RET    ] = OP( 0, -1, 0, 0, PURE | BLOCK | RETBRANCH,   "cps_ret"),
835 [OP_CPS_END    ] = OP( 0, -1, 0, 0, IMPURE | BLOCK | ENDBRANCH, "cps_end"),
836 [OP_CPS_START  ] = OP( -1, 0, 0, 0, PURE | BLOCK | STRUCTURAL,  "cps_start"),
837 #endif
838
839 [OP_CMP        ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK, "cmp"),
840 [OP_TEST       ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "test"),
841 [OP_SET_EQ     ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_eq"),
842 [OP_SET_NOTEQ  ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_noteq"),
843 [OP_SET_SLESS  ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_sless"),
844 [OP_SET_ULESS  ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_uless"),
845 [OP_SET_SMORE  ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_smore"),
846 [OP_SET_UMORE  ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_umore"),
847 [OP_SET_SLESSEQ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_slesseq"),
848 [OP_SET_ULESSEQ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_ulesseq"),
849 [OP_SET_SMOREEQ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_smoreq"),
850 [OP_SET_UMOREEQ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_umoreq"),
851 [OP_JMP        ] = OP( 0,  0, 0, 1, PURE | BLOCK | UBRANCH, "jmp"),
852 [OP_JMP_EQ     ] = OP( 0,  1, 0, 1, PURE | BLOCK | CBRANCH, "jmp_eq"),
853 [OP_JMP_NOTEQ  ] = OP( 0,  1, 0, 1, PURE | BLOCK | CBRANCH, "jmp_noteq"),
854 [OP_JMP_SLESS  ] = OP( 0,  1, 0, 1, PURE | BLOCK | CBRANCH, "jmp_sless"),
855 [OP_JMP_ULESS  ] = OP( 0,  1, 0, 1, PURE | BLOCK | CBRANCH, "jmp_uless"),
856 [OP_JMP_SMORE  ] = OP( 0,  1, 0, 1, PURE | BLOCK | CBRANCH, "jmp_smore"),
857 [OP_JMP_UMORE  ] = OP( 0,  1, 0, 1, PURE | BLOCK | CBRANCH, "jmp_umore"),
858 [OP_JMP_SLESSEQ] = OP( 0,  1, 0, 1, PURE | BLOCK | CBRANCH, "jmp_slesseq"),
859 [OP_JMP_ULESSEQ] = OP( 0,  1, 0, 1, PURE | BLOCK | CBRANCH, "jmp_ulesseq"),
860 [OP_JMP_SMOREEQ] = OP( 0,  1, 0, 1, PURE | BLOCK | CBRANCH, "jmp_smoreq"),
861 [OP_JMP_UMOREEQ] = OP( 0,  1, 0, 1, PURE | BLOCK | CBRANCH, "jmp_umoreq"),
862
863 [OP_INB        ] = OP( 0,  1, 0, 0, IMPURE | DEF | BLOCK, "__inb"),
864 [OP_INW        ] = OP( 0,  1, 0, 0, IMPURE | DEF | BLOCK, "__inw"),
865 [OP_INL        ] = OP( 0,  1, 0, 0, IMPURE | DEF | BLOCK, "__inl"),
866 [OP_OUTB       ] = OP( 0,  2, 0, 0, IMPURE| BLOCK, "__outb"),
867 [OP_OUTW       ] = OP( 0,  2, 0, 0, IMPURE| BLOCK, "__outw"),
868 [OP_OUTL       ] = OP( 0,  2, 0, 0, IMPURE| BLOCK, "__outl"),
869 [OP_BSF        ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "__bsf"),
870 [OP_BSR        ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "__bsr"),
871 [OP_RDMSR      ] = OP( 2,  1, 0, 0, IMPURE | BLOCK, "__rdmsr"),
872 [OP_WRMSR      ] = OP( 0,  3, 0, 0, IMPURE | BLOCK, "__wrmsr"),
873 [OP_HLT        ] = OP( 0,  0, 0, 0, IMPURE | BLOCK, "__hlt"),
874 };
875 #undef OP
876 #define OP_MAX      (sizeof(table_ops)/sizeof(table_ops[0]))
877
878 static const char *tops(int index) 
879 {
880         static const char unknown[] = "unknown op";
881         if (index < 0) {
882                 return unknown;
883         }
884         if (index > OP_MAX) {
885                 return unknown;
886         }
887         return table_ops[index].name;
888 }
889
890 struct asm_info;
891 struct triple;
892 struct block;
893 struct triple_set {
894         struct triple_set *next;
895         struct triple *member;
896 };
897
898 #define MAX_LHS  63
899 #define MAX_RHS  127
900 #define MAX_MISC 3
901 #define MAX_TARG 1
902
903 struct occurance {
904         int count;
905         const char *filename;
906         const char *function;
907         int line;
908         int col;
909         struct occurance *parent;
910 };
911 struct bitfield {
912         ulong_t size : 8;
913         ulong_t offset : 24;
914 };
915 struct triple {
916         struct triple *next, *prev;
917         struct triple_set *use;
918         struct type *type;
919         unsigned int op : 8;
920         unsigned int template_id : 7;
921         unsigned int lhs  : 6;
922         unsigned int rhs  : 7;
923         unsigned int misc : 2;
924         unsigned int targ : 1;
925 #define TRIPLE_SIZE(TRIPLE) \
926         ((TRIPLE)->lhs + (TRIPLE)->rhs + (TRIPLE)->misc + (TRIPLE)->targ)
927 #define TRIPLE_LHS_OFF(PTR)  (0)
928 #define TRIPLE_RHS_OFF(PTR)  (TRIPLE_LHS_OFF(PTR) + (PTR)->lhs)
929 #define TRIPLE_MISC_OFF(PTR) (TRIPLE_RHS_OFF(PTR) + (PTR)->rhs)
930 #define TRIPLE_TARG_OFF(PTR) (TRIPLE_MISC_OFF(PTR) + (PTR)->misc)
931 #define LHS(PTR,INDEX) ((PTR)->param[TRIPLE_LHS_OFF(PTR) + (INDEX)])
932 #define RHS(PTR,INDEX) ((PTR)->param[TRIPLE_RHS_OFF(PTR) + (INDEX)])
933 #define TARG(PTR,INDEX) ((PTR)->param[TRIPLE_TARG_OFF(PTR) + (INDEX)])
934 #define MISC(PTR,INDEX) ((PTR)->param[TRIPLE_MISC_OFF(PTR) + (INDEX)])
935         unsigned id; /* A scratch value and finally the register */
936 #define TRIPLE_FLAG_FLATTENED   (1 << 31)
937 #define TRIPLE_FLAG_PRE_SPLIT   (1 << 30)
938 #define TRIPLE_FLAG_POST_SPLIT  (1 << 29)
939 #define TRIPLE_FLAG_VOLATILE    (1 << 28)
940 #define TRIPLE_FLAG_INLINE      (1 << 27) /* ???? */
941 #define TRIPLE_FLAG_LOCAL       (1 << 26)
942
943 #define TRIPLE_FLAG_COPY TRIPLE_FLAG_VOLATILE
944         struct occurance *occurance;
945         union {
946                 ulong_t cval;
947                 struct bitfield bitfield;
948                 struct block  *block;
949                 void *blob;
950                 struct hash_entry *field;
951                 struct asm_info *ainfo;
952                 struct triple *func;
953                 struct symbol *symbol;
954         } u;
955         struct triple *param[2];
956 };
957
958 struct reg_info {
959         unsigned reg;
960         unsigned regcm;
961 };
962 struct ins_template {
963         struct reg_info lhs[MAX_LHS + 1], rhs[MAX_RHS + 1];
964 };
965
966 struct asm_info {
967         struct ins_template tmpl;
968         char *str;
969 };
970
971 struct block_set {
972         struct block_set *next;
973         struct block *member;
974 };
975 struct block {
976         struct block *work_next;
977         struct triple *first, *last;
978         int edge_count;
979         struct block_set *edges;
980         int users;
981         struct block_set *use;
982         struct block_set *idominates;
983         struct block_set *domfrontier;
984         struct block *idom;
985         struct block_set *ipdominates;
986         struct block_set *ipdomfrontier;
987         struct block *ipdom;
988         int vertex;
989         
990 };
991
992 struct symbol {
993         struct symbol *next;
994         struct hash_entry *ident;
995         struct triple *def;
996         struct type *type;
997         int scope_depth;
998 };
999
1000 struct macro_arg {
1001         struct macro_arg *next;
1002         struct hash_entry *ident;
1003 };
1004 struct macro {
1005         struct hash_entry *ident;
1006         char *buf;
1007         int buf_len;
1008         int buf_off;
1009         struct macro_arg *args;
1010         int argc;
1011 };
1012
1013 struct hash_entry {
1014         struct hash_entry *next;
1015         const char *name;
1016         int name_len;
1017         int tok;
1018         struct macro *sym_define;
1019         struct symbol *sym_label;
1020         struct symbol *sym_tag;
1021         struct symbol *sym_ident;
1022 };
1023
1024 #define HASH_TABLE_SIZE 2048
1025
1026 struct compiler_state {
1027         const char *label_prefix;
1028         const char *ofilename;
1029         unsigned long flags;
1030         unsigned long debug;
1031         unsigned long max_allocation_passes;
1032
1033         size_t include_path_count;
1034         const char **include_paths;
1035
1036         size_t define_count;
1037         const char **defines;
1038
1039         size_t undef_count;
1040         const char **undefs;
1041 };
1042 struct arch_state {
1043         unsigned long features;
1044 };
1045 struct basic_blocks {
1046         struct triple *func;
1047         struct triple *first;
1048         struct block *first_block, *last_block;
1049         int last_vertex;
1050 };
1051 #define MAX_CPP_IF_DEPTH 63
1052 struct compile_state {
1053         struct compiler_state *compiler;
1054         struct arch_state *arch;
1055         FILE *output;
1056         FILE *errout;
1057         FILE *dbgout;
1058         struct file_state *file;
1059         struct occurance *last_occurance;
1060         const char *function;
1061         int    token_base;
1062         struct token token[6];
1063         struct hash_entry *hash_table[HASH_TABLE_SIZE];
1064         struct hash_entry *i_switch;
1065         struct hash_entry *i_case;
1066         struct hash_entry *i_continue;
1067         struct hash_entry *i_break;
1068         struct hash_entry *i_default;
1069         struct hash_entry *i_return;
1070         /* Additional hash entries for predefined macros */
1071         struct hash_entry *i_defined;
1072         struct hash_entry *i___VA_ARGS__;
1073         struct hash_entry *i___FILE__;
1074         struct hash_entry *i___LINE__;
1075         /* Additional hash entries for predefined identifiers */
1076         struct hash_entry *i___func__;
1077         /* Additional hash entries for attributes */
1078         struct hash_entry *i_noinline;
1079         struct hash_entry *i_always_inline;
1080         int scope_depth;
1081         unsigned char if_bytes[(MAX_CPP_IF_DEPTH + CHAR_BIT -1)/CHAR_BIT];
1082         int if_depth;
1083         int eat_depth, eat_targ;
1084         int macro_line;
1085         struct file_state *macro_file;
1086         struct triple *functions;
1087         struct triple *main_function;
1088         struct triple *first;
1089         struct triple *global_pool;
1090         struct basic_blocks bb;
1091         int functions_joined;
1092 };
1093
1094 /* visibility global/local */
1095 /* static/auto duration */
1096 /* typedef, register, inline */
1097 #define STOR_SHIFT         0
1098 #define STOR_MASK     0x001f
1099 /* Visibility */
1100 #define STOR_GLOBAL   0x0001
1101 /* Duration */
1102 #define STOR_PERM     0x0002
1103 /* Definition locality */
1104 #define STOR_NONLOCAL 0x0004  /* The definition is not in this translation unit */
1105 /* Storage specifiers */
1106 #define STOR_AUTO     0x0000
1107 #define STOR_STATIC   0x0002
1108 #define STOR_LOCAL    0x0003
1109 #define STOR_EXTERN   0x0007
1110 #define STOR_INLINE   0x0008
1111 #define STOR_REGISTER 0x0010
1112 #define STOR_TYPEDEF  0x0018
1113
1114 #define QUAL_SHIFT         5
1115 #define QUAL_MASK     0x00e0
1116 #define QUAL_NONE     0x0000
1117 #define QUAL_CONST    0x0020
1118 #define QUAL_VOLATILE 0x0040
1119 #define QUAL_RESTRICT 0x0080
1120
1121 #define TYPE_SHIFT         8
1122 #define TYPE_MASK     0x1f00
1123 #define TYPE_INTEGER(TYPE)    ((((TYPE) >= TYPE_CHAR) && ((TYPE) <= TYPE_ULLONG)) || ((TYPE) == TYPE_ENUM) || ((TYPE) == TYPE_BITFIELD))
1124 #define TYPE_ARITHMETIC(TYPE) ((((TYPE) >= TYPE_CHAR) && ((TYPE) <= TYPE_LDOUBLE)) || ((TYPE) == TYPE_ENUM) || ((TYPE) == TYPE_BITFIELD))
1125 #define TYPE_UNSIGNED(TYPE)   ((TYPE) & 0x0100)
1126 #define TYPE_SIGNED(TYPE)     (!TYPE_UNSIGNED(TYPE))
1127 #define TYPE_MKUNSIGNED(TYPE) (((TYPE) & ~0xF000) | 0x0100)
1128 #define TYPE_RANK(TYPE)       ((TYPE) & ~0xF1FF)
1129 #define TYPE_PTR(TYPE)        (((TYPE) & TYPE_MASK) == TYPE_POINTER)
1130 #define TYPE_DEFAULT  0x0000
1131 #define TYPE_VOID     0x0100
1132 #define TYPE_CHAR     0x0200
1133 #define TYPE_UCHAR    0x0300
1134 #define TYPE_SHORT    0x0400
1135 #define TYPE_USHORT   0x0500
1136 #define TYPE_INT      0x0600
1137 #define TYPE_UINT     0x0700
1138 #define TYPE_LONG     0x0800
1139 #define TYPE_ULONG    0x0900
1140 #define TYPE_LLONG    0x0a00 /* long long */
1141 #define TYPE_ULLONG   0x0b00
1142 #define TYPE_FLOAT    0x0c00
1143 #define TYPE_DOUBLE   0x0d00
1144 #define TYPE_LDOUBLE  0x0e00 /* long double */
1145
1146 /* Note: TYPE_ENUM is chosen very carefully so TYPE_RANK works */
1147 #define TYPE_ENUM     0x1600
1148 #define TYPE_LIST     0x1700
1149 /* TYPE_LIST is a basic building block when defining enumerations
1150  * type->field_ident holds the name of this enumeration entry.
1151  * type->right holds the entry in the list.
1152  */
1153
1154 #define TYPE_STRUCT   0x1000
1155 /* For TYPE_STRUCT
1156  * type->left holds the link list of TYPE_PRODUCT entries that
1157  * make up the structure.
1158  * type->elements hold the length of the linked list
1159  */
1160 #define TYPE_UNION    0x1100
1161 /* For TYPE_UNION
1162  * type->left holds the link list of TYPE_OVERLAP entries that
1163  * make up the union.
1164  * type->elements hold the length of the linked list
1165  */
1166 #define TYPE_POINTER  0x1200 
1167 /* For TYPE_POINTER:
1168  * type->left holds the type pointed to.
1169  */
1170 #define TYPE_FUNCTION 0x1300 
1171 /* For TYPE_FUNCTION:
1172  * type->left holds the return type.
1173  * type->right holds the type of the arguments
1174  * type->elements holds the count of the arguments
1175  */
1176 #define TYPE_PRODUCT  0x1400
1177 /* TYPE_PRODUCT is a basic building block when defining structures
1178  * type->left holds the type that appears first in memory.
1179  * type->right holds the type that appears next in memory.
1180  */
1181 #define TYPE_OVERLAP  0x1500
1182 /* TYPE_OVERLAP is a basic building block when defining unions
1183  * type->left and type->right holds to types that overlap
1184  * each other in memory.
1185  */
1186 #define TYPE_ARRAY    0x1800
1187 /* TYPE_ARRAY is a basic building block when definitng arrays.
1188  * type->left holds the type we are an array of.
1189  * type->elements holds the number of elements.
1190  */
1191 #define TYPE_TUPLE    0x1900
1192 /* TYPE_TUPLE is a basic building block when defining 
1193  * positionally reference type conglomerations. (i.e. closures)
1194  * In essence it is a wrapper for TYPE_PRODUCT, like TYPE_STRUCT
1195  * except it has no field names.
1196  * type->left holds the liked list of TYPE_PRODUCT entries that
1197  * make up the closure type.
1198  * type->elements hold the number of elements in the closure.
1199  */
1200 #define TYPE_JOIN     0x1a00
1201 /* TYPE_JOIN is a basic building block when defining 
1202  * positionally reference type conglomerations. (i.e. closures)
1203  * In essence it is a wrapper for TYPE_OVERLAP, like TYPE_UNION
1204  * except it has no field names.
1205  * type->left holds the liked list of TYPE_OVERLAP entries that
1206  * make up the closure type.
1207  * type->elements hold the number of elements in the closure.
1208  */
1209 #define TYPE_BITFIELD 0x1b00
1210 /* TYPE_BITFIED is the type of a bitfield.
1211  * type->left holds the type basic type TYPE_BITFIELD is derived from.
1212  * type->elements holds the number of bits in the bitfield.
1213  */
1214 #define TYPE_UNKNOWN  0x1c00
1215 /* TYPE_UNKNOWN is the type of an unknown value.
1216  * Used on unknown consts and other places where I don't know the type.
1217  */
1218
1219 #define ATTRIB_SHIFT                 16
1220 #define ATTRIB_MASK          0xffff0000
1221 #define ATTRIB_NOINLINE      0x00010000
1222 #define ATTRIB_ALWAYS_INLINE 0x00020000
1223
1224 #define ELEMENT_COUNT_UNSPECIFIED ULONG_T_MAX
1225
1226 struct type {
1227         unsigned int type;
1228         struct type *left, *right;
1229         ulong_t elements;
1230         struct hash_entry *field_ident;
1231         struct hash_entry *type_ident;
1232 };
1233
1234 #define TEMPLATE_BITS      7
1235 #define MAX_TEMPLATES      (1<<TEMPLATE_BITS)
1236 #define MAX_REG_EQUIVS     16
1237 #define MAX_REGC           14
1238 #define MAX_REGISTERS      75
1239 #define REGISTER_BITS      7
1240 #define MAX_VIRT_REGISTERS (1<<REGISTER_BITS)
1241 #define REG_ERROR          0
1242 #define REG_UNSET          1
1243 #define REG_UNNEEDED       2
1244 #define REG_VIRT0          (MAX_REGISTERS + 0)
1245 #define REG_VIRT1          (MAX_REGISTERS + 1)
1246 #define REG_VIRT2          (MAX_REGISTERS + 2)
1247 #define REG_VIRT3          (MAX_REGISTERS + 3)
1248 #define REG_VIRT4          (MAX_REGISTERS + 4)
1249 #define REG_VIRT5          (MAX_REGISTERS + 5)
1250 #define REG_VIRT6          (MAX_REGISTERS + 6)
1251 #define REG_VIRT7          (MAX_REGISTERS + 7)
1252 #define REG_VIRT8          (MAX_REGISTERS + 8)
1253 #define REG_VIRT9          (MAX_REGISTERS + 9)
1254
1255 #if (MAX_REGISTERS + 9) > MAX_VIRT_REGISTERS
1256 #error "MAX_VIRT_REGISTERS to small"
1257 #endif
1258 #if (MAX_REGC + REGISTER_BITS) >= 26
1259 #error "Too many id bits used"
1260 #endif
1261
1262 /* Provision for 8 register classes */
1263 #define REG_SHIFT  0
1264 #define REGC_SHIFT REGISTER_BITS
1265 #define REGC_MASK (((1 << MAX_REGC) - 1) << REGISTER_BITS)
1266 #define REG_MASK (MAX_VIRT_REGISTERS -1)
1267 #define ID_REG(ID)              ((ID) & REG_MASK)
1268 #define SET_REG(ID, REG)        ((ID) = (((ID) & ~REG_MASK) | ((REG) & REG_MASK)))
1269 #define ID_REGCM(ID)            (((ID) & REGC_MASK) >> REGC_SHIFT)
1270 #define SET_REGCM(ID, REGCM)    ((ID) = (((ID) & ~REGC_MASK) | (((REGCM) << REGC_SHIFT) & REGC_MASK)))
1271 #define SET_INFO(ID, INFO)      ((ID) = (((ID) & ~(REG_MASK | REGC_MASK)) | \
1272                 (((INFO).reg) & REG_MASK) | ((((INFO).regcm) << REGC_SHIFT) & REGC_MASK)))
1273
1274 #define ARCH_INPUT_REGS 4
1275 #define ARCH_OUTPUT_REGS 4
1276
1277 static const struct reg_info arch_input_regs[ARCH_INPUT_REGS];
1278 static const struct reg_info arch_output_regs[ARCH_OUTPUT_REGS];
1279 static unsigned arch_reg_regcm(struct compile_state *state, int reg);
1280 static unsigned arch_regcm_normalize(struct compile_state *state, unsigned regcm);
1281 static unsigned arch_regcm_reg_normalize(struct compile_state *state, unsigned regcm);
1282 static void arch_reg_equivs(
1283         struct compile_state *state, unsigned *equiv, int reg);
1284 static int arch_select_free_register(
1285         struct compile_state *state, char *used, int classes);
1286 static unsigned arch_regc_size(struct compile_state *state, int class);
1287 static int arch_regcm_intersect(unsigned regcm1, unsigned regcm2);
1288 static unsigned arch_type_to_regcm(struct compile_state *state, struct type *type);
1289 static const char *arch_reg_str(int reg);
1290 static struct reg_info arch_reg_constraint(
1291         struct compile_state *state, struct type *type, const char *constraint);
1292 static struct reg_info arch_reg_clobber(
1293         struct compile_state *state, const char *clobber);
1294 static struct reg_info arch_reg_lhs(struct compile_state *state, 
1295         struct triple *ins, int index);
1296 static struct reg_info arch_reg_rhs(struct compile_state *state, 
1297         struct triple *ins, int index);
1298 static int arch_reg_size(int reg);
1299 static struct triple *transform_to_arch_instruction(
1300         struct compile_state *state, struct triple *ins);
1301 static struct triple *flatten(
1302         struct compile_state *state, struct triple *first, struct triple *ptr);
1303
1304
1305
1306
1307 #define DEBUG_ABORT_ON_ERROR    0x00000001
1308 #define DEBUG_BASIC_BLOCKS      0x00000002
1309 #define DEBUG_FDOMINATORS       0x00000004
1310 #define DEBUG_RDOMINATORS       0x00000008
1311 #define DEBUG_TRIPLES           0x00000010
1312 #define DEBUG_INTERFERENCE      0x00000020
1313 #define DEBUG_SCC_TRANSFORM     0x00000040
1314 #define DEBUG_SCC_TRANSFORM2    0x00000080
1315 #define DEBUG_REBUILD_SSA_FORM  0x00000100
1316 #define DEBUG_INLINE            0x00000200
1317 #define DEBUG_RANGE_CONFLICTS   0x00000400
1318 #define DEBUG_RANGE_CONFLICTS2  0x00000800
1319 #define DEBUG_COLOR_GRAPH       0x00001000
1320 #define DEBUG_COLOR_GRAPH2      0x00002000
1321 #define DEBUG_COALESCING        0x00004000
1322 #define DEBUG_COALESCING2       0x00008000
1323 #define DEBUG_VERIFICATION      0x00010000
1324 #define DEBUG_CALLS             0x00020000
1325 #define DEBUG_CALLS2            0x00040000
1326 #define DEBUG_TOKENS            0x80000000
1327
1328 #define DEBUG_DEFAULT ( \
1329         DEBUG_ABORT_ON_ERROR | \
1330         DEBUG_BASIC_BLOCKS | \
1331         DEBUG_FDOMINATORS | \
1332         DEBUG_RDOMINATORS | \
1333         DEBUG_TRIPLES | \
1334         0 )
1335
1336 #define DEBUG_ALL ( \
1337         DEBUG_ABORT_ON_ERROR   | \
1338         DEBUG_BASIC_BLOCKS     | \
1339         DEBUG_FDOMINATORS      | \
1340         DEBUG_RDOMINATORS      | \
1341         DEBUG_TRIPLES          | \
1342         DEBUG_INTERFERENCE     | \
1343         DEBUG_SCC_TRANSFORM    | \
1344         DEBUG_SCC_TRANSFORM2   | \
1345         DEBUG_REBUILD_SSA_FORM | \
1346         DEBUG_INLINE           | \
1347         DEBUG_RANGE_CONFLICTS  | \
1348         DEBUG_RANGE_CONFLICTS2 | \
1349         DEBUG_COLOR_GRAPH      | \
1350         DEBUG_COLOR_GRAPH2     | \
1351         DEBUG_COALESCING       | \
1352         DEBUG_COALESCING2      | \
1353         DEBUG_VERIFICATION     | \
1354         DEBUG_CALLS            | \
1355         DEBUG_CALLS2           | \
1356         DEBUG_TOKENS           | \
1357         0 )
1358
1359 #define COMPILER_INLINE_MASK               0x00000007
1360 #define COMPILER_INLINE_ALWAYS             0x00000000
1361 #define COMPILER_INLINE_NEVER              0x00000001
1362 #define COMPILER_INLINE_DEFAULTON          0x00000002
1363 #define COMPILER_INLINE_DEFAULTOFF         0x00000003
1364 #define COMPILER_INLINE_NOPENALTY          0x00000004
1365 #define COMPILER_ELIMINATE_INEFECTUAL_CODE 0x00000008
1366 #define COMPILER_SIMPLIFY                  0x00000010
1367 #define COMPILER_SCC_TRANSFORM             0x00000020
1368 #define COMPILER_SIMPLIFY_OP               0x00000040
1369 #define COMPILER_SIMPLIFY_PHI              0x00000080
1370 #define COMPILER_SIMPLIFY_LABEL            0x00000100
1371 #define COMPILER_SIMPLIFY_BRANCH           0x00000200
1372 #define COMPILER_SIMPLIFY_COPY             0x00000400
1373 #define COMPILER_SIMPLIFY_ARITH            0x00000800
1374 #define COMPILER_SIMPLIFY_SHIFT            0x00001000
1375 #define COMPILER_SIMPLIFY_BITWISE          0x00002000
1376 #define COMPILER_SIMPLIFY_LOGICAL          0x00004000
1377 #define COMPILER_SIMPLIFY_BITFIELD         0x00008000
1378
1379 #define COMPILER_CPP_ONLY                  0x80000000
1380
1381 #define COMPILER_DEFAULT_FLAGS ( \
1382         COMPILER_ELIMINATE_INEFECTUAL_CODE | \
1383         COMPILER_INLINE_DEFAULTON | \
1384         COMPILER_SIMPLIFY_OP | \
1385         COMPILER_SIMPLIFY_PHI | \
1386         COMPILER_SIMPLIFY_LABEL | \
1387         COMPILER_SIMPLIFY_BRANCH | \
1388         COMPILER_SIMPLIFY_COPY | \
1389         COMPILER_SIMPLIFY_ARITH | \
1390         COMPILER_SIMPLIFY_SHIFT | \
1391         COMPILER_SIMPLIFY_BITWISE | \
1392         COMPILER_SIMPLIFY_LOGICAL | \
1393         COMPILER_SIMPLIFY_BITFIELD | \
1394         0 )
1395
1396 #define GLOBAL_SCOPE_DEPTH   1
1397 #define FUNCTION_SCOPE_DEPTH (GLOBAL_SCOPE_DEPTH + 1)
1398
1399 static void compile_file(struct compile_state *old_state, const char *filename, int local);
1400
1401
1402
1403 static void init_compiler_state(struct compiler_state *compiler)
1404 {
1405         memset(compiler, 0, sizeof(*compiler));
1406         compiler->label_prefix = "";
1407         compiler->ofilename = "auto.inc";
1408         compiler->flags = COMPILER_DEFAULT_FLAGS;
1409         compiler->debug = 0;
1410         compiler->max_allocation_passes = MAX_ALLOCATION_PASSES;
1411         compiler->include_path_count = 1;
1412         compiler->include_paths      = xcmalloc(sizeof(char *), "include_paths");
1413         compiler->define_count       = 1;
1414         compiler->defines            = xcmalloc(sizeof(char *), "defines");
1415         compiler->undef_count        = 1;
1416         compiler->undefs             = xcmalloc(sizeof(char *), "undefs");
1417 }
1418
1419 struct compiler_flag {
1420         const char *name;
1421         unsigned long flag;
1422 };
1423
1424 struct compiler_arg {
1425         const char *name;
1426         unsigned long mask;
1427         struct compiler_flag flags[16];
1428 };
1429
1430 static int set_flag(
1431         const struct compiler_flag *ptr, unsigned long *flags,
1432         int act, const char *flag)
1433 {
1434         int result = -1;
1435         for(; ptr->name; ptr++) {
1436                 if (strcmp(ptr->name, flag) == 0) {
1437                         break;
1438                 }
1439         }
1440         if (ptr->name) {
1441                 result = 0;
1442                 *flags &= ~(ptr->flag);
1443                 if (act) {
1444                         *flags |= ptr->flag;
1445                 }
1446         }
1447         return result;
1448 }
1449
1450 static int set_arg(
1451         const struct compiler_arg *ptr, unsigned long *flags, const char *arg)
1452 {
1453         const char *val;
1454         int result = -1;
1455         int len;
1456         val = strchr(arg, '=');
1457         if (val) {
1458                 len = val - arg;
1459                 val++;
1460                 for(; ptr->name; ptr++) {
1461                         if (strncmp(ptr->name, arg, len) == 0) {
1462                                 break;
1463                         }
1464                 }
1465                 if (ptr->name) {
1466                         *flags &= ~ptr->mask;
1467                         result = set_flag(&ptr->flags[0], flags, 1, val);
1468                 }
1469         }
1470         return result;
1471 }
1472         
1473
1474 static void flag_usage(FILE *fp, const struct compiler_flag *ptr, 
1475         const char *prefix, const char *invert_prefix)
1476 {
1477         for(;ptr->name; ptr++) {
1478                 fprintf(fp, "%s%s\n", prefix, ptr->name);
1479                 if (invert_prefix) {
1480                         fprintf(fp, "%s%s\n", invert_prefix, ptr->name);
1481                 }
1482         }
1483 }
1484
1485 static void arg_usage(FILE *fp, const struct compiler_arg *ptr,
1486         const char *prefix)
1487 {
1488         for(;ptr->name; ptr++) {
1489                 const struct compiler_flag *flag;
1490                 for(flag = &ptr->flags[0]; flag->name; flag++) {
1491                         fprintf(fp, "%s%s=%s\n", 
1492                                 prefix, ptr->name, flag->name);
1493                 }
1494         }
1495 }
1496
1497 static int append_string(size_t *max, const char ***vec, const char *str,
1498         const char *name)
1499 {
1500         size_t count;
1501         count = ++(*max);
1502         *vec = xrealloc(*vec, sizeof(char *)*count, "name");
1503         (*vec)[count -1] = 0;
1504         (*vec)[count -2] = str; 
1505         return 0;
1506 }
1507
1508 static void arg_error(char *fmt, ...);
1509 static const char *identifier(const char *str, const char *end);
1510
1511 static int append_include_path(struct compiler_state *compiler, const char *str)
1512 {
1513         int result;
1514         if (!exists(str, ".")) {
1515                 arg_error("Nonexistent include path: `%s'\n",
1516                         str);
1517         }
1518         result = append_string(&compiler->include_path_count,
1519                 &compiler->include_paths, str, "include_paths");
1520         return result;
1521 }
1522
1523 static int append_define(struct compiler_state *compiler, const char *str)
1524 {
1525         const char *end, *rest;
1526         int result;
1527
1528         end = strchr(str, '=');
1529         if (!end) {
1530                 end = str + strlen(str);
1531         }
1532         rest = identifier(str, end);
1533         if (rest != end) {
1534                 int len = end - str - 1;
1535                 arg_error("Invalid name cannot define macro: `%*.*s'\n", 
1536                         len, len, str);
1537         }
1538         result = append_string(&compiler->define_count,
1539                 &compiler->defines, str, "defines");
1540         return result;
1541 }
1542
1543 static int append_undef(struct compiler_state *compiler, const char *str)
1544 {
1545         const char *end, *rest;
1546         int result;
1547
1548         end = str + strlen(str);
1549         rest = identifier(str, end);
1550         if (rest != end) {
1551                 int len = end - str - 1;
1552                 arg_error("Invalid name cannot undefine macro: `%*.*s'\n", 
1553                         len, len, str);
1554         }
1555         result = append_string(&compiler->undef_count,
1556                 &compiler->undefs, str, "undefs");
1557         return result;
1558 }
1559
1560 static const struct compiler_flag romcc_flags[] = {
1561         { "cpp-only",                  COMPILER_CPP_ONLY },
1562         { "eliminate-inefectual-code", COMPILER_ELIMINATE_INEFECTUAL_CODE },
1563         { "simplify",                  COMPILER_SIMPLIFY },
1564         { "scc-transform",             COMPILER_SCC_TRANSFORM },
1565         { "simplify-op",               COMPILER_SIMPLIFY_OP },
1566         { "simplify-phi",              COMPILER_SIMPLIFY_PHI },
1567         { "simplify-label",            COMPILER_SIMPLIFY_LABEL },
1568         { "simplify-branch",           COMPILER_SIMPLIFY_BRANCH },
1569         { "simplify-copy",             COMPILER_SIMPLIFY_COPY },
1570         { "simplify-arith",            COMPILER_SIMPLIFY_ARITH },
1571         { "simplify-shift",            COMPILER_SIMPLIFY_SHIFT },
1572         { "simplify-bitwise",          COMPILER_SIMPLIFY_BITWISE },
1573         { "simplify-logical",          COMPILER_SIMPLIFY_LOGICAL },
1574         { "simplify-bitfield",         COMPILER_SIMPLIFY_BITFIELD },
1575         { 0, 0 },
1576 };
1577 static const struct compiler_arg romcc_args[] = {
1578         { "inline-policy",             COMPILER_INLINE_MASK,
1579                 {
1580                         { "always",      COMPILER_INLINE_ALWAYS, },
1581                         { "never",       COMPILER_INLINE_NEVER, },
1582                         { "defaulton",   COMPILER_INLINE_DEFAULTON, },
1583                         { "defaultoff",  COMPILER_INLINE_DEFAULTOFF, },
1584                         { "nopenalty",   COMPILER_INLINE_NOPENALTY, },
1585                         { 0, 0 },
1586                 },
1587         },
1588         { 0, 0 },
1589 };
1590 static const struct compiler_flag romcc_opt_flags[] = {
1591         { "-O",  COMPILER_SIMPLIFY },
1592         { "-O2", COMPILER_SIMPLIFY | COMPILER_SCC_TRANSFORM },
1593         { "-E",  COMPILER_CPP_ONLY },
1594         { 0, 0, },
1595 };
1596 static const struct compiler_flag romcc_debug_flags[] = {
1597         { "all",                   DEBUG_ALL },
1598         { "abort-on-error",        DEBUG_ABORT_ON_ERROR },
1599         { "basic-blocks",          DEBUG_BASIC_BLOCKS },
1600         { "fdominators",           DEBUG_FDOMINATORS },
1601         { "rdominators",           DEBUG_RDOMINATORS },
1602         { "triples",               DEBUG_TRIPLES },
1603         { "interference",          DEBUG_INTERFERENCE },
1604         { "scc-transform",         DEBUG_SCC_TRANSFORM },
1605         { "scc-transform2",        DEBUG_SCC_TRANSFORM2 },
1606         { "rebuild-ssa-form",      DEBUG_REBUILD_SSA_FORM },
1607         { "inline",                DEBUG_INLINE },
1608         { "live-range-conflicts",  DEBUG_RANGE_CONFLICTS },
1609         { "live-range-conflicts2", DEBUG_RANGE_CONFLICTS2 },
1610         { "color-graph",           DEBUG_COLOR_GRAPH },
1611         { "color-graph2",          DEBUG_COLOR_GRAPH2 },
1612         { "coalescing",            DEBUG_COALESCING },
1613         { "coalescing2",           DEBUG_COALESCING2 },
1614         { "verification",          DEBUG_VERIFICATION },
1615         { "calls",                 DEBUG_CALLS },
1616         { "calls2",                DEBUG_CALLS2 },
1617         { "tokens",                DEBUG_TOKENS },
1618         { 0, 0 },
1619 };
1620
1621 static int compiler_encode_flag(
1622         struct compiler_state *compiler, const char *flag)
1623 {
1624         int act;
1625         int result;
1626
1627         act = 1;
1628         result = -1;
1629         if (strncmp(flag, "no-", 3) == 0) {
1630                 flag += 3;
1631                 act = 0;
1632         }
1633         if (strncmp(flag, "-O", 2) == 0) {
1634                 result = set_flag(romcc_opt_flags, &compiler->flags, act, flag);
1635         }
1636         else if (strncmp(flag, "-E", 2) == 0) {
1637                 result = set_flag(romcc_opt_flags, &compiler->flags, act, flag);
1638         }
1639         else if (strncmp(flag, "-I", 2) == 0) {
1640                 result = append_include_path(compiler, flag + 2);
1641         }
1642         else if (strncmp(flag, "-D", 2) == 0) {
1643                 result = append_define(compiler, flag + 2);
1644         }
1645         else if (strncmp(flag, "-U", 2) == 0) {
1646                 result = append_undef(compiler, flag + 2);
1647         }
1648         else if (act && strncmp(flag, "label-prefix=", 13) == 0) {
1649                 result = 0;
1650                 compiler->label_prefix = flag + 13;
1651         }
1652         else if (act && strncmp(flag, "max-allocation-passes=", 22) == 0) {
1653                 unsigned long max_passes;
1654                 char *end;
1655                 max_passes = strtoul(flag + 22, &end, 10);
1656                 if (end[0] == '\0') {
1657                         result = 0;
1658                         compiler->max_allocation_passes = max_passes;
1659                 }
1660         }
1661         else if (act && strcmp(flag, "debug") == 0) {
1662                 result = 0;
1663                 compiler->debug |= DEBUG_DEFAULT;
1664         }
1665         else if (strncmp(flag, "debug-", 6) == 0) {
1666                 flag += 6;
1667                 result = set_flag(romcc_debug_flags, &compiler->debug, act, flag);
1668         }
1669         else {
1670                 result = set_flag(romcc_flags, &compiler->flags, act, flag);
1671                 if (result < 0) {
1672                         result = set_arg(romcc_args, &compiler->flags, flag);
1673                 }
1674         }
1675         return result;
1676 }
1677
1678 static void compiler_usage(FILE *fp)
1679 {
1680         flag_usage(fp, romcc_opt_flags, "", 0);
1681         flag_usage(fp, romcc_flags, "-f", "-fno-");
1682         arg_usage(fp,  romcc_args, "-f");
1683         flag_usage(fp, romcc_debug_flags, "-fdebug-", "-fno-debug-");
1684         fprintf(fp, "-flabel-prefix=<prefix for assembly language labels>\n");
1685         fprintf(fp, "--label-prefix=<prefix for assembly language labels>\n");
1686         fprintf(fp, "-I<include path>\n");
1687         fprintf(fp, "-D<macro>[=defn]\n");
1688         fprintf(fp, "-U<macro>\n");
1689 }
1690
1691 static void do_cleanup(struct compile_state *state)
1692 {
1693         if (state->output) {
1694                 fclose(state->output);
1695                 unlink(state->compiler->ofilename);
1696                 state->output = 0;
1697         }
1698         if (state->dbgout) {
1699                 fflush(state->dbgout);
1700         }
1701         if (state->errout) {
1702                 fflush(state->errout);
1703         }
1704 }
1705
1706 static struct compile_state *exit_state;
1707 static void exit_cleanup(void)
1708 {
1709         if (exit_state) {
1710                 do_cleanup(exit_state);
1711         }
1712 }
1713
1714 static int get_col(struct file_state *file)
1715 {
1716         int col;
1717         const char *ptr, *end;
1718         ptr = file->line_start;
1719         end = file->pos;
1720         for(col = 0; ptr < end; ptr++) {
1721                 if (*ptr != '\t') {
1722                         col++;
1723                 } 
1724                 else {
1725                         col = (col & ~7) + 8;
1726                 }
1727         }
1728         return col;
1729 }
1730
1731 static void loc(FILE *fp, struct compile_state *state, struct triple *triple)
1732 {
1733         int col;
1734         if (triple && triple->occurance) {
1735                 struct occurance *spot;
1736                 for(spot = triple->occurance; spot; spot = spot->parent) {
1737                         fprintf(fp, "%s:%d.%d: ", 
1738                                 spot->filename, spot->line, spot->col);
1739                 }
1740                 return;
1741         }
1742         if (!state->file) {
1743                 return;
1744         }
1745         col = get_col(state->file);
1746         fprintf(fp, "%s:%d.%d: ", 
1747                 state->file->report_name, state->file->report_line, col);
1748 }
1749
1750 static void internal_error(struct compile_state *state, struct triple *ptr, 
1751         const char *fmt, ...)
1752 {
1753         FILE *fp = state->errout;
1754         va_list args;
1755         va_start(args, fmt);
1756         loc(fp, state, ptr);
1757         fputc('\n', fp);
1758         if (ptr) {
1759                 fprintf(fp, "%p %-10s ", ptr, tops(ptr->op));
1760         }
1761         fprintf(fp, "Internal compiler error: ");
1762         vfprintf(fp, fmt, args);
1763         fprintf(fp, "\n");
1764         va_end(args);
1765         do_cleanup(state);
1766         abort();
1767 }
1768
1769
1770 static void internal_warning(struct compile_state *state, struct triple *ptr, 
1771         const char *fmt, ...)
1772 {
1773         FILE *fp = state->errout;
1774         va_list args;
1775         va_start(args, fmt);
1776         loc(fp, state, ptr);
1777         if (ptr) {
1778                 fprintf(fp, "%p %-10s ", ptr, tops(ptr->op));
1779         }
1780         fprintf(fp, "Internal compiler warning: ");
1781         vfprintf(fp, fmt, args);
1782         fprintf(fp, "\n");
1783         va_end(args);
1784 }
1785
1786
1787
1788 static void error(struct compile_state *state, struct triple *ptr, 
1789         const char *fmt, ...)
1790 {
1791         FILE *fp = state->errout;
1792         va_list args;
1793         va_start(args, fmt);
1794         loc(fp, state, ptr);
1795         fputc('\n', fp);
1796         if (ptr && (state->compiler->debug & DEBUG_ABORT_ON_ERROR)) {
1797                 fprintf(fp, "%p %-10s ", ptr, tops(ptr->op));
1798         }
1799         vfprintf(fp, fmt, args);
1800         va_end(args);
1801         fprintf(fp, "\n");
1802         do_cleanup(state);
1803         if (state->compiler->debug & DEBUG_ABORT_ON_ERROR) {
1804                 abort();
1805         }
1806         exit(1);
1807 }
1808
1809 static void warning(struct compile_state *state, struct triple *ptr, 
1810         const char *fmt, ...)
1811 {
1812         FILE *fp = state->errout;
1813         va_list args;
1814         va_start(args, fmt);
1815         loc(fp, state, ptr);
1816         fprintf(fp, "warning: "); 
1817         if (ptr && (state->compiler->debug & DEBUG_ABORT_ON_ERROR)) {
1818                 fprintf(fp, "%p %-10s ", ptr, tops(ptr->op));
1819         }
1820         vfprintf(fp, fmt, args);
1821         fprintf(fp, "\n");
1822         va_end(args);
1823 }
1824
1825 #define FINISHME() warning(state, 0, "FINISHME @ %s.%s:%d", __FILE__, __func__, __LINE__)
1826
1827 static void valid_op(struct compile_state *state, int op)
1828 {
1829         char *fmt = "invalid op: %d";
1830         if (op >= OP_MAX) {
1831                 internal_error(state, 0, fmt, op);
1832         }
1833         if (op < 0) {
1834                 internal_error(state, 0, fmt, op);
1835         }
1836 }
1837
1838 static void valid_ins(struct compile_state *state, struct triple *ptr)
1839 {
1840         valid_op(state, ptr->op);
1841 }
1842
1843 static void valid_param_count(struct compile_state *state, struct triple *ins)
1844 {
1845         int lhs, rhs, misc, targ;
1846         valid_ins(state, ins);
1847         lhs  = table_ops[ins->op].lhs;
1848         rhs  = table_ops[ins->op].rhs;
1849         misc = table_ops[ins->op].misc;
1850         targ = table_ops[ins->op].targ;
1851
1852         if ((lhs >= 0) && (ins->lhs != lhs)) {
1853                 internal_error(state, ins, "Bad lhs count");
1854         }
1855         if ((rhs >= 0) && (ins->rhs != rhs)) {
1856                 internal_error(state, ins, "Bad rhs count");
1857         }
1858         if ((misc >= 0) && (ins->misc != misc)) {
1859                 internal_error(state, ins, "Bad misc count");
1860         }
1861         if ((targ >= 0) && (ins->targ != targ)) {
1862                 internal_error(state, ins, "Bad targ count");
1863         }
1864 }
1865
1866 static void process_trigraphs(struct compile_state *state)
1867 {
1868         char *src, *dest, *end;
1869         struct file_state *file;
1870         file = state->file;
1871         src = dest = file->buf;
1872         end = file->buf + file->size;
1873         while((end - src) >= 3) {
1874                 if ((src[0] == '?') && (src[1] == '?')) {
1875                         int c = -1;
1876                         switch(src[2]) {
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                         case '-': c = '~'; break;
1886                         }
1887                         if (c != -1) {
1888                                 *dest++ = c;
1889                                 src += 3;
1890                         }
1891                         else {
1892                                 *dest++ = *src++;
1893                         }
1894                 }
1895                 else {
1896                         *dest++ = *src++;
1897                 }
1898         }
1899         while(src != end) {
1900                 *dest++ = *src++;
1901         }
1902         file->size = dest - file->buf;
1903 }
1904
1905 static void splice_lines(struct compile_state *state)
1906 {
1907         char *src, *dest, *end;
1908         struct file_state *file;
1909         file = state->file;
1910         src = dest = file->buf;
1911         end = file->buf + file->size;
1912         while((end - src) >= 2) {
1913                 if ((src[0] == '\\') && (src[1] == '\n')) {
1914                         src += 2;
1915                 }
1916                 else {
1917                         *dest++ = *src++;
1918                 }
1919         }
1920         while(src != end) {
1921                 *dest++ = *src++;
1922         }
1923         file->size = dest - file->buf;
1924 }
1925
1926 static struct type void_type;
1927 static struct type unknown_type;
1928 static void use_triple(struct triple *used, struct triple *user)
1929 {
1930         struct triple_set **ptr, *new;
1931         if (!used)
1932                 return;
1933         if (!user)
1934                 return;
1935         ptr = &used->use;
1936         while(*ptr) {
1937                 if ((*ptr)->member == user) {
1938                         return;
1939                 }
1940                 ptr = &(*ptr)->next;
1941         }
1942         /* Append new to the head of the list, 
1943          * copy_func and rename_block_variables
1944          * depends on this.
1945          */
1946         new = xcmalloc(sizeof(*new), "triple_set");
1947         new->member = user;
1948         new->next   = used->use;
1949         used->use   = new;
1950 }
1951
1952 static void unuse_triple(struct triple *used, struct triple *unuser)
1953 {
1954         struct triple_set *use, **ptr;
1955         if (!used) {
1956                 return;
1957         }
1958         ptr = &used->use;
1959         while(*ptr) {
1960                 use = *ptr;
1961                 if (use->member == unuser) {
1962                         *ptr = use->next;
1963                         xfree(use);
1964                 }
1965                 else {
1966                         ptr = &use->next;
1967                 }
1968         }
1969 }
1970
1971 static void put_occurance(struct occurance *occurance)
1972 {
1973         if (occurance) {
1974                 occurance->count -= 1;
1975                 if (occurance->count <= 0) {
1976                         if (occurance->parent) {
1977                                 put_occurance(occurance->parent);
1978                         }
1979                         xfree(occurance);
1980                 }
1981         }
1982 }
1983
1984 static void get_occurance(struct occurance *occurance)
1985 {
1986         if (occurance) {
1987                 occurance->count += 1;
1988         }
1989 }
1990
1991
1992 static struct occurance *new_occurance(struct compile_state *state)
1993 {
1994         struct occurance *result, *last;
1995         const char *filename;
1996         const char *function;
1997         int line, col;
1998
1999         function = "";
2000         filename = 0;
2001         line = 0;
2002         col  = 0;
2003         if (state->file) {
2004                 filename = state->file->report_name;
2005                 line     = state->file->report_line;
2006                 col      = get_col(state->file);
2007         }
2008         if (state->function) {
2009                 function = state->function;
2010         }
2011         last = state->last_occurance;
2012         if (last &&
2013                 (last->col == col) &&
2014                 (last->line == line) &&
2015                 (last->function == function) &&
2016                 ((last->filename == filename) ||
2017                         (strcmp(last->filename, filename) == 0))) 
2018         {
2019                 get_occurance(last);
2020                 return last;
2021         }
2022         if (last) {
2023                 state->last_occurance = 0;
2024                 put_occurance(last);
2025         }
2026         result = xmalloc(sizeof(*result), "occurance");
2027         result->count    = 2;
2028         result->filename = filename;
2029         result->function = function;
2030         result->line     = line;
2031         result->col      = col;
2032         result->parent   = 0;
2033         state->last_occurance = result;
2034         return result;
2035 }
2036
2037 static struct occurance *inline_occurance(struct compile_state *state,
2038         struct occurance *base, struct occurance *top)
2039 {
2040         struct occurance *result, *last;
2041         if (top->parent) {
2042                 internal_error(state, 0, "inlining an already inlined function?");
2043         }
2044         /* If I have a null base treat it that way */
2045         if ((base->parent == 0) &&
2046                 (base->col == 0) &&
2047                 (base->line == 0) &&
2048                 (base->function[0] == '\0') &&
2049                 (base->filename[0] == '\0')) {
2050                 base = 0;
2051         }
2052         /* See if I can reuse the last occurance I had */
2053         last = state->last_occurance;
2054         if (last &&
2055                 (last->parent   == base) &&
2056                 (last->col      == top->col) &&
2057                 (last->line     == top->line) &&
2058                 (last->function == top->function) &&
2059                 (last->filename == top->filename)) {
2060                 get_occurance(last);
2061                 return last;
2062         }
2063         /* I can't reuse the last occurance so free it */
2064         if (last) {
2065                 state->last_occurance = 0;
2066                 put_occurance(last);
2067         }
2068         /* Generate a new occurance structure */
2069         get_occurance(base);
2070         result = xmalloc(sizeof(*result), "occurance");
2071         result->count    = 2;
2072         result->filename = top->filename;
2073         result->function = top->function;
2074         result->line     = top->line;
2075         result->col      = top->col;
2076         result->parent   = base;
2077         state->last_occurance = result;
2078         return result;
2079 }
2080
2081 static struct occurance dummy_occurance = {
2082         .count    = 2,
2083         .filename = __FILE__,
2084         .function = "",
2085         .line     = __LINE__,
2086         .col      = 0,
2087         .parent   = 0,
2088 };
2089
2090 /* The undef triple is used as a place holder when we are removing pointers
2091  * from a triple.  Having allows certain sanity checks to pass even
2092  * when the original triple that was pointed to is gone.
2093  */
2094 static struct triple unknown_triple = {
2095         .next      = &unknown_triple,
2096         .prev      = &unknown_triple,
2097         .use       = 0,
2098         .op        = OP_UNKNOWNVAL,
2099         .lhs       = 0,
2100         .rhs       = 0,
2101         .misc      = 0,
2102         .targ      = 0,
2103         .type      = &unknown_type,
2104         .id        = -1, /* An invalid id */
2105         .u = { .cval = 0, },
2106         .occurance = &dummy_occurance,
2107         .param = { [0] = 0, [1] = 0, },
2108 };
2109
2110
2111 static size_t registers_of(struct compile_state *state, struct type *type);
2112
2113 static struct triple *alloc_triple(struct compile_state *state, 
2114         int op, struct type *type, int lhs_wanted, int rhs_wanted,
2115         struct occurance *occurance)
2116 {
2117         size_t size, extra_count, min_count;
2118         int lhs, rhs, misc, targ;
2119         struct triple *ret, dummy;
2120         dummy.op = op;
2121         dummy.occurance = occurance;
2122         valid_op(state, op);
2123         lhs = table_ops[op].lhs;
2124         rhs = table_ops[op].rhs;
2125         misc = table_ops[op].misc;
2126         targ = table_ops[op].targ;
2127
2128         switch(op) {
2129         case OP_FCALL:
2130                 rhs = rhs_wanted;
2131                 break;
2132         case OP_PHI:
2133                 rhs = rhs_wanted;
2134                 break;
2135         case OP_ADECL:
2136                 lhs = registers_of(state, type);
2137                 break;
2138         case OP_TUPLE:
2139                 lhs = registers_of(state, type);
2140                 break;
2141         case OP_ASM:
2142                 rhs = rhs_wanted;
2143                 lhs = lhs_wanted;
2144                 break;
2145         }
2146         if ((rhs < 0) || (rhs > MAX_RHS)) {
2147                 internal_error(state, &dummy, "bad rhs count %d", rhs);
2148         }
2149         if ((lhs < 0) || (lhs > MAX_LHS)) {
2150                 internal_error(state, &dummy, "bad lhs count %d", lhs);
2151         }
2152         if ((misc < 0) || (misc > MAX_MISC)) {
2153                 internal_error(state, &dummy, "bad misc count %d", misc);
2154         }
2155         if ((targ < 0) || (targ > MAX_TARG)) {
2156                 internal_error(state, &dummy, "bad targs count %d", targ);
2157         }
2158
2159         min_count = sizeof(ret->param)/sizeof(ret->param[0]);
2160         extra_count = lhs + rhs + misc + targ;
2161         extra_count = (extra_count < min_count)? 0 : extra_count - min_count;
2162
2163         size = sizeof(*ret) + sizeof(ret->param[0]) * extra_count;
2164         ret = xcmalloc(size, "tripple");
2165         ret->op        = op;
2166         ret->lhs       = lhs;
2167         ret->rhs       = rhs;
2168         ret->misc      = misc;
2169         ret->targ      = targ;
2170         ret->type      = type;
2171         ret->next      = ret;
2172         ret->prev      = ret;
2173         ret->occurance = occurance;
2174         /* A simple sanity check */
2175         if ((ret->op != op) ||
2176                 (ret->lhs != lhs) ||
2177                 (ret->rhs != rhs) ||
2178                 (ret->misc != misc) ||
2179                 (ret->targ != targ) ||
2180                 (ret->type != type) ||
2181                 (ret->next != ret) ||
2182                 (ret->prev != ret) ||
2183                 (ret->occurance != occurance)) {
2184                 internal_error(state, ret, "huh?");
2185         }
2186         return ret;
2187 }
2188
2189 struct triple *dup_triple(struct compile_state *state, struct triple *src)
2190 {
2191         struct triple *dup;
2192         int src_lhs, src_rhs, src_size;
2193         src_lhs = src->lhs;
2194         src_rhs = src->rhs;
2195         src_size = TRIPLE_SIZE(src);
2196         get_occurance(src->occurance);
2197         dup = alloc_triple(state, src->op, src->type, src_lhs, src_rhs,
2198                 src->occurance);
2199         memcpy(dup, src, sizeof(*src));
2200         memcpy(dup->param, src->param, src_size * sizeof(src->param[0]));
2201         return dup;
2202 }
2203
2204 static struct triple *copy_triple(struct compile_state *state, struct triple *src)
2205 {
2206         struct triple *copy;
2207         copy = dup_triple(state, src);
2208         copy->use = 0;
2209         copy->next = copy->prev = copy;
2210         return copy;
2211 }
2212
2213 static struct triple *new_triple(struct compile_state *state, 
2214         int op, struct type *type, int lhs, int rhs)
2215 {
2216         struct triple *ret;
2217         struct occurance *occurance;
2218         occurance = new_occurance(state);
2219         ret = alloc_triple(state, op, type, lhs, rhs, occurance);
2220         return ret;
2221 }
2222
2223 static struct triple *build_triple(struct compile_state *state, 
2224         int op, struct type *type, struct triple *left, struct triple *right,
2225         struct occurance *occurance)
2226 {
2227         struct triple *ret;
2228         size_t count;
2229         ret = alloc_triple(state, op, type, -1, -1, occurance);
2230         count = TRIPLE_SIZE(ret);
2231         if (count > 0) {
2232                 ret->param[0] = left;
2233         }
2234         if (count > 1) {
2235                 ret->param[1] = right;
2236         }
2237         return ret;
2238 }
2239
2240 static struct triple *triple(struct compile_state *state, 
2241         int op, struct type *type, struct triple *left, struct triple *right)
2242 {
2243         struct triple *ret;
2244         size_t count;
2245         ret = new_triple(state, op, type, -1, -1);
2246         count = TRIPLE_SIZE(ret);
2247         if (count >= 1) {
2248                 ret->param[0] = left;
2249         }
2250         if (count >= 2) {
2251                 ret->param[1] = right;
2252         }
2253         return ret;
2254 }
2255
2256 static struct triple *branch(struct compile_state *state, 
2257         struct triple *targ, struct triple *test)
2258 {
2259         struct triple *ret;
2260         if (test) {
2261                 ret = new_triple(state, OP_CBRANCH, &void_type, -1, 1);
2262                 RHS(ret, 0) = test;
2263         } else {
2264                 ret = new_triple(state, OP_BRANCH, &void_type, -1, 0);
2265         }
2266         TARG(ret, 0) = targ;
2267         /* record the branch target was used */
2268         if (!targ || (targ->op != OP_LABEL)) {
2269                 internal_error(state, 0, "branch not to label");
2270         }
2271         return ret;
2272 }
2273
2274 static int triple_is_label(struct compile_state *state, struct triple *ins);
2275 static int triple_is_call(struct compile_state *state, struct triple *ins);
2276 static int triple_is_cbranch(struct compile_state *state, struct triple *ins);
2277 static void insert_triple(struct compile_state *state,
2278         struct triple *first, struct triple *ptr)
2279 {
2280         if (ptr) {
2281                 if ((ptr->id & TRIPLE_FLAG_FLATTENED) || (ptr->next != ptr)) {
2282                         internal_error(state, ptr, "expression already used");
2283                 }
2284                 ptr->next       = first;
2285                 ptr->prev       = first->prev;
2286                 ptr->prev->next = ptr;
2287                 ptr->next->prev = ptr;
2288
2289                 if (triple_is_cbranch(state, ptr->prev) ||
2290                         triple_is_call(state, ptr->prev)) {
2291                         unuse_triple(first, ptr->prev);
2292                         use_triple(ptr, ptr->prev);
2293                 }
2294         }
2295 }
2296
2297 static int triple_stores_block(struct compile_state *state, struct triple *ins)
2298 {
2299         /* This function is used to determine if u.block 
2300          * is utilized to store the current block number.
2301          */
2302         int stores_block;
2303         valid_ins(state, ins);
2304         stores_block = (table_ops[ins->op].flags & BLOCK) == BLOCK;
2305         return stores_block;
2306 }
2307
2308 static int triple_is_branch(struct compile_state *state, struct triple *ins);
2309 static struct block *block_of_triple(struct compile_state *state, 
2310         struct triple *ins)
2311 {
2312         struct triple *first;
2313         if (!ins || ins == &unknown_triple) {
2314                 return 0;
2315         }
2316         first = state->first;
2317         while(ins != first && !triple_is_branch(state, ins->prev) &&
2318                 !triple_stores_block(state, ins)) 
2319         { 
2320                 if (ins == ins->prev) {
2321                         internal_error(state, ins, "ins == ins->prev?");
2322                 }
2323                 ins = ins->prev;
2324         }
2325         return triple_stores_block(state, ins)? ins->u.block: 0;
2326 }
2327
2328 static void generate_lhs_pieces(struct compile_state *state, struct triple *ins);
2329 static struct triple *pre_triple(struct compile_state *state,
2330         struct triple *base,
2331         int op, struct type *type, struct triple *left, struct triple *right)
2332 {
2333         struct block *block;
2334         struct triple *ret;
2335         int i;
2336         /* If I am an OP_PIECE jump to the real instruction */
2337         if (base->op == OP_PIECE) {
2338                 base = MISC(base, 0);
2339         }
2340         block = block_of_triple(state, base);
2341         get_occurance(base->occurance);
2342         ret = build_triple(state, op, type, left, right, base->occurance);
2343         generate_lhs_pieces(state, ret);
2344         if (triple_stores_block(state, ret)) {
2345                 ret->u.block = block;
2346         }
2347         insert_triple(state, base, ret);
2348         for(i = 0; i < ret->lhs; i++) {
2349                 struct triple *piece;
2350                 piece = LHS(ret, i);
2351                 insert_triple(state, base, piece);
2352                 use_triple(ret, piece);
2353                 use_triple(piece, ret);
2354         }
2355         if (block && (block->first == base)) {
2356                 block->first = ret;
2357         }
2358         return ret;
2359 }
2360
2361 static struct triple *post_triple(struct compile_state *state,
2362         struct triple *base,
2363         int op, struct type *type, struct triple *left, struct triple *right)
2364 {
2365         struct block *block;
2366         struct triple *ret, *next;
2367         int zlhs, i;
2368         /* If I am an OP_PIECE jump to the real instruction */
2369         if (base->op == OP_PIECE) {
2370                 base = MISC(base, 0);
2371         }
2372         /* If I have a left hand side skip over it */
2373         zlhs = base->lhs;
2374         if (zlhs) {
2375                 base = LHS(base, zlhs - 1);
2376         }
2377
2378         block = block_of_triple(state, base);
2379         get_occurance(base->occurance);
2380         ret = build_triple(state, op, type, left, right, base->occurance);
2381         generate_lhs_pieces(state, ret);
2382         if (triple_stores_block(state, ret)) {
2383                 ret->u.block = block;
2384         }
2385         next = base->next;
2386         insert_triple(state, next, ret);
2387         zlhs = ret->lhs;
2388         for(i = 0; i < zlhs; i++) {
2389                 struct triple *piece;
2390                 piece = LHS(ret, i);
2391                 insert_triple(state, next, piece);
2392                 use_triple(ret, piece);
2393                 use_triple(piece, ret);
2394         }
2395         if (block && (block->last == base)) {
2396                 block->last = ret;
2397                 if (zlhs) {
2398                         block->last = LHS(ret, zlhs - 1);
2399                 }
2400         }
2401         return ret;
2402 }
2403
2404 static struct type *reg_type(
2405         struct compile_state *state, struct type *type, int reg);
2406
2407 static void generate_lhs_piece(
2408         struct compile_state *state, struct triple *ins, int index)
2409 {
2410         struct type *piece_type;
2411         struct triple *piece;
2412         get_occurance(ins->occurance);
2413         piece_type = reg_type(state, ins->type, index * REG_SIZEOF_REG);
2414
2415         if ((piece_type->type & TYPE_MASK) == TYPE_BITFIELD) {
2416                 piece_type = piece_type->left;
2417         }
2418 #if 0
2419 {
2420         static void name_of(FILE *fp, struct type *type);
2421         FILE * fp = state->errout;
2422         fprintf(fp, "piece_type(%d): ", index);
2423         name_of(fp, piece_type);
2424         fprintf(fp, "\n");
2425 }
2426 #endif
2427         piece = alloc_triple(state, OP_PIECE, piece_type, -1, -1, ins->occurance);
2428         piece->u.cval  = index;
2429         LHS(ins, piece->u.cval) = piece;
2430         MISC(piece, 0) = ins;
2431 }
2432
2433 static void generate_lhs_pieces(struct compile_state *state, struct triple *ins)
2434 {
2435         int i, zlhs;
2436         zlhs = ins->lhs;
2437         for(i = 0; i < zlhs; i++) {
2438                 generate_lhs_piece(state, ins, i);
2439         }
2440 }
2441
2442 static struct triple *label(struct compile_state *state)
2443 {
2444         /* Labels don't get a type */
2445         struct triple *result;
2446         result = triple(state, OP_LABEL, &void_type, 0, 0);
2447         return result;
2448 }
2449
2450 static struct triple *mkprog(struct compile_state *state, ...)
2451 {
2452         struct triple *prog, *head, *arg;
2453         va_list args;
2454         int i;
2455
2456         head = label(state);
2457         prog = new_triple(state, OP_PROG, &void_type, -1, -1);
2458         RHS(prog, 0) = head;
2459         va_start(args, state);
2460         i = 0;
2461         while((arg = va_arg(args, struct triple *)) != 0) {
2462                 if (++i >= 100) {
2463                         internal_error(state, 0, "too many arguments to mkprog");
2464                 }
2465                 flatten(state, head, arg);
2466         }
2467         va_end(args);
2468         prog->type = head->prev->type;
2469         return prog;
2470 }
2471 static void name_of(FILE *fp, struct type *type);
2472 static void display_triple(FILE *fp, struct triple *ins)
2473 {
2474         struct occurance *ptr;
2475         const char *reg;
2476         char pre, post, vol;
2477         pre = post = vol = ' ';
2478         if (ins) {
2479                 if (ins->id & TRIPLE_FLAG_PRE_SPLIT) {
2480                         pre = '^';
2481                 }
2482                 if (ins->id & TRIPLE_FLAG_POST_SPLIT) {
2483                         post = ',';
2484                 }
2485                 if (ins->id & TRIPLE_FLAG_VOLATILE) {
2486                         vol = 'v';
2487                 }
2488                 reg = arch_reg_str(ID_REG(ins->id));
2489         }
2490         if (ins == 0) {
2491                 fprintf(fp, "(%p) <nothing> ", ins);
2492         }
2493         else if (ins->op == OP_INTCONST) {
2494                 fprintf(fp, "(%p) %c%c%c %-7s %-2d %-10s <0x%08lx>         ",
2495                         ins, pre, post, vol, reg, ins->template_id, tops(ins->op), 
2496                         (unsigned long)(ins->u.cval));
2497         }
2498         else if (ins->op == OP_ADDRCONST) {
2499                 fprintf(fp, "(%p) %c%c%c %-7s %-2d %-10s %-10p <0x%08lx>",
2500                         ins, pre, post, vol, reg, ins->template_id, tops(ins->op), 
2501                         MISC(ins, 0), (unsigned long)(ins->u.cval));
2502         }
2503         else if (ins->op == OP_INDEX) {
2504                 fprintf(fp, "(%p) %c%c%c %-7s %-2d %-10s %-10p <0x%08lx>",
2505                         ins, pre, post, vol, reg, ins->template_id, tops(ins->op), 
2506                         RHS(ins, 0), (unsigned long)(ins->u.cval));
2507         }
2508         else if (ins->op == OP_PIECE) {
2509                 fprintf(fp, "(%p) %c%c%c %-7s %-2d %-10s %-10p <0x%08lx>",
2510                         ins, pre, post, vol, reg, ins->template_id, tops(ins->op), 
2511                         MISC(ins, 0), (unsigned long)(ins->u.cval));
2512         }
2513         else {
2514                 int i, count;
2515                 fprintf(fp, "(%p) %c%c%c %-7s %-2d %-10s", 
2516                         ins, pre, post, vol, reg, ins->template_id, tops(ins->op));
2517                 if (table_ops[ins->op].flags & BITFIELD) {
2518                         fprintf(fp, " <%2d-%2d:%2d>", 
2519                                 ins->u.bitfield.offset,
2520                                 ins->u.bitfield.offset + ins->u.bitfield.size,
2521                                 ins->u.bitfield.size);
2522                 }
2523                 count = TRIPLE_SIZE(ins);
2524                 for(i = 0; i < count; i++) {
2525                         fprintf(fp, " %-10p", ins->param[i]);
2526                 }
2527                 for(; i < 2; i++) {
2528                         fprintf(fp, "           ");
2529                 }
2530         }
2531         if (ins) {
2532                 struct triple_set *user;
2533 #if DEBUG_DISPLAY_TYPES
2534                 fprintf(fp, " <");
2535                 name_of(fp, ins->type);
2536                 fprintf(fp, "> ");
2537 #endif
2538 #if DEBUG_DISPLAY_USES
2539                 fprintf(fp, " [");
2540                 for(user = ins->use; user; user = user->next) {
2541                         fprintf(fp, " %-10p", user->member);
2542                 }
2543                 fprintf(fp, " ]");
2544 #endif
2545                 fprintf(fp, " @");
2546                 for(ptr = ins->occurance; ptr; ptr = ptr->parent) {
2547                         fprintf(fp, " %s,%s:%d.%d",
2548                                 ptr->function, 
2549                                 ptr->filename,
2550                                 ptr->line, 
2551                                 ptr->col);
2552                 }
2553                 if (ins->op == OP_ASM) {
2554                         fprintf(fp, "\n\t%s", ins->u.ainfo->str);
2555                 }
2556         }
2557         fprintf(fp, "\n");
2558         fflush(fp);
2559 }
2560
2561 static int equiv_types(struct type *left, struct type *right);
2562 static void display_triple_changes(
2563         FILE *fp, const struct triple *new, const struct triple *orig)
2564 {
2565
2566         int new_count, orig_count;
2567         new_count = TRIPLE_SIZE(new);
2568         orig_count = TRIPLE_SIZE(orig);
2569         if ((new->op != orig->op) ||
2570                 (new_count != orig_count) ||
2571                 (memcmp(orig->param, new->param,        
2572                         orig_count * sizeof(orig->param[0])) != 0) ||
2573                 (memcmp(&orig->u, &new->u, sizeof(orig->u)) != 0)) 
2574         {
2575                 struct occurance *ptr;
2576                 int i, min_count, indent;
2577                 fprintf(fp, "(%p %p)", new, orig);
2578                 if (orig->op == new->op) {
2579                         fprintf(fp, " %-11s", tops(orig->op));
2580                 } else {
2581                         fprintf(fp, " [%-10s %-10s]", 
2582                                 tops(new->op), tops(orig->op));
2583                 }
2584                 min_count = new_count;
2585                 if (min_count > orig_count) {
2586                         min_count = orig_count;
2587                 }
2588                 for(indent = i = 0; i < min_count; i++) {
2589                         if (orig->param[i] == new->param[i]) {
2590                                 fprintf(fp, " %-11p", 
2591                                         orig->param[i]);
2592                                 indent += 12;
2593                         } else {
2594                                 fprintf(fp, " [%-10p %-10p]",
2595                                         new->param[i], 
2596                                         orig->param[i]);
2597                                 indent += 24;
2598                         }
2599                 }
2600                 for(; i < orig_count; i++) {
2601                         fprintf(fp, " [%-9p]", orig->param[i]);
2602                         indent += 12;
2603                 }
2604                 for(; i < new_count; i++) {
2605                         fprintf(fp, " [%-9p]", new->param[i]);
2606                         indent += 12;
2607                 }
2608                 if ((new->op == OP_INTCONST)||
2609                         (new->op == OP_ADDRCONST)) {
2610                         fprintf(fp, " <0x%08lx>", 
2611                                 (unsigned long)(new->u.cval));
2612                         indent += 13;
2613                 }
2614                 for(;indent < 36; indent++) {
2615                         putc(' ', fp);
2616                 }
2617
2618 #if DEBUG_DISPLAY_TYPES
2619                 fprintf(fp, " <");
2620                 name_of(fp, new->type);
2621                 if (!equiv_types(new->type, orig->type)) {
2622                         fprintf(fp, " -- ");
2623                         name_of(fp, orig->type);
2624                 }
2625                 fprintf(fp, "> ");
2626 #endif
2627
2628                 fprintf(fp, " @");
2629                 for(ptr = orig->occurance; ptr; ptr = ptr->parent) {
2630                         fprintf(fp, " %s,%s:%d.%d",
2631                                 ptr->function, 
2632                                 ptr->filename,
2633                                 ptr->line, 
2634                                 ptr->col);
2635                         
2636                 }
2637                 fprintf(fp, "\n");
2638                 fflush(fp);
2639         }
2640 }
2641
2642 static int triple_is_pure(struct compile_state *state, struct triple *ins, unsigned id)
2643 {
2644         /* Does the triple have no side effects.
2645          * I.e. Rexecuting the triple with the same arguments 
2646          * gives the same value.
2647          */
2648         unsigned pure;
2649         valid_ins(state, ins);
2650         pure = PURE_BITS(table_ops[ins->op].flags);
2651         if ((pure != PURE) && (pure != IMPURE)) {
2652                 internal_error(state, 0, "Purity of %s not known",
2653                         tops(ins->op));
2654         }
2655         return (pure == PURE) && !(id & TRIPLE_FLAG_VOLATILE);
2656 }
2657
2658 static int triple_is_branch_type(struct compile_state *state, 
2659         struct triple *ins, unsigned type)
2660 {
2661         /* Is this one of the passed branch types? */
2662         valid_ins(state, ins);
2663         return (BRANCH_BITS(table_ops[ins->op].flags) == type);
2664 }
2665
2666 static int triple_is_branch(struct compile_state *state, struct triple *ins)
2667 {
2668         /* Is this triple a branch instruction? */
2669         valid_ins(state, ins);
2670         return (BRANCH_BITS(table_ops[ins->op].flags) != 0);
2671 }
2672
2673 static int triple_is_cbranch(struct compile_state *state, struct triple *ins)
2674 {
2675         /* Is this triple a conditional branch instruction? */
2676         return triple_is_branch_type(state, ins, CBRANCH);
2677 }
2678
2679 static int triple_is_ubranch(struct compile_state *state, struct triple *ins)
2680 {
2681         /* Is this triple a unconditional branch instruction? */
2682         unsigned type;
2683         valid_ins(state, ins);
2684         type = BRANCH_BITS(table_ops[ins->op].flags);
2685         return (type != 0) && (type != CBRANCH);
2686 }
2687
2688 static int triple_is_call(struct compile_state *state, struct triple *ins)
2689 {
2690         /* Is this triple a call instruction? */
2691         return triple_is_branch_type(state, ins, CALLBRANCH);
2692 }
2693
2694 static int triple_is_ret(struct compile_state *state, struct triple *ins)
2695 {
2696         /* Is this triple a return instruction? */
2697         return triple_is_branch_type(state, ins, RETBRANCH);
2698 }
2699
2700 static int triple_is_simple_ubranch(struct compile_state *state, struct triple *ins)
2701 {
2702         /* Is this triple an unconditional branch and not a call or a
2703          * return? */
2704         return triple_is_branch_type(state, ins, UBRANCH);
2705 }
2706
2707 static int triple_is_end(struct compile_state *state, struct triple *ins)
2708 {
2709         return triple_is_branch_type(state, ins, ENDBRANCH);
2710 }
2711
2712 static int triple_is_label(struct compile_state *state, struct triple *ins)
2713 {
2714         valid_ins(state, ins);
2715         return (ins->op == OP_LABEL);
2716 }
2717
2718 static struct triple *triple_to_block_start(
2719         struct compile_state *state, struct triple *start)
2720 {
2721         while(!triple_is_branch(state, start->prev) &&
2722                 (!triple_is_label(state, start) || !start->use)) {
2723                 start = start->prev;
2724         }
2725         return start;
2726 }
2727
2728 static int triple_is_def(struct compile_state *state, struct triple *ins)
2729 {
2730         /* This function is used to determine which triples need
2731          * a register.
2732          */
2733         int is_def;
2734         valid_ins(state, ins);
2735         is_def = (table_ops[ins->op].flags & DEF) == DEF;
2736         if (ins->lhs >= 1) {
2737                 is_def = 0;
2738         }
2739         return is_def;
2740 }
2741
2742 static int triple_is_structural(struct compile_state *state, struct triple *ins)
2743 {
2744         int is_structural;
2745         valid_ins(state, ins);
2746         is_structural = (table_ops[ins->op].flags & STRUCTURAL) == STRUCTURAL;
2747         return is_structural;
2748 }
2749
2750 static int triple_is_part(struct compile_state *state, struct triple *ins)
2751 {
2752         int is_part;
2753         valid_ins(state, ins);
2754         is_part = (table_ops[ins->op].flags & PART) == PART;
2755         return is_part;
2756 }
2757
2758 static int triple_is_auto_var(struct compile_state *state, struct triple *ins)
2759 {
2760         return (ins->op == OP_PIECE) && (MISC(ins, 0)->op == OP_ADECL);
2761 }
2762
2763 static struct triple **triple_iter(struct compile_state *state,
2764         size_t count, struct triple **vector,
2765         struct triple *ins, struct triple **last)
2766 {
2767         struct triple **ret;
2768         ret = 0;
2769         if (count) {
2770                 if (!last) {
2771                         ret = vector;
2772                 }
2773                 else if ((last >= vector) && (last < (vector + count - 1))) {
2774                         ret = last + 1;
2775                 }
2776         }
2777         return ret;
2778         
2779 }
2780
2781 static struct triple **triple_lhs(struct compile_state *state,
2782         struct triple *ins, struct triple **last)
2783 {
2784         return triple_iter(state, ins->lhs, &LHS(ins,0), 
2785                 ins, last);
2786 }
2787
2788 static struct triple **triple_rhs(struct compile_state *state,
2789         struct triple *ins, struct triple **last)
2790 {
2791         return triple_iter(state, ins->rhs, &RHS(ins,0), 
2792                 ins, last);
2793 }
2794
2795 static struct triple **triple_misc(struct compile_state *state,
2796         struct triple *ins, struct triple **last)
2797 {
2798         return triple_iter(state, ins->misc, &MISC(ins,0), 
2799                 ins, last);
2800 }
2801
2802 static struct triple **do_triple_targ(struct compile_state *state,
2803         struct triple *ins, struct triple **last, int call_edges, int next_edges)
2804 {
2805         size_t count;
2806         struct triple **ret, **vector;
2807         int next_is_targ;
2808         ret = 0;
2809         count = ins->targ;
2810         next_is_targ = 0;
2811         if (triple_is_cbranch(state, ins)) {
2812                 next_is_targ = 1;
2813         }
2814         if (!call_edges && triple_is_call(state, ins)) {
2815                 count = 0;
2816         }
2817         if (next_edges && triple_is_call(state, ins)) {
2818                 next_is_targ = 1;
2819         }
2820         vector = &TARG(ins, 0);
2821         if (!ret && next_is_targ) {
2822                 if (!last) {
2823                         ret = &ins->next;
2824                 } else if (last == &ins->next) {
2825                         last = 0;
2826                 }
2827         }
2828         if (!ret && count) {
2829                 if (!last) {
2830                         ret = vector;
2831                 }
2832                 else if ((last >= vector) && (last < (vector + count - 1))) {
2833                         ret = last + 1;
2834                 }
2835                 else if (last == vector + count - 1) {
2836                         last = 0;
2837                 }
2838         }
2839         if (!ret && triple_is_ret(state, ins) && call_edges) {
2840                 struct triple_set *use;
2841                 for(use = ins->use; use; use = use->next) {
2842                         if (!triple_is_call(state, use->member)) {
2843                                 continue;
2844                         }
2845                         if (!last) {
2846                                 ret = &use->member->next;
2847                                 break;
2848                         }
2849                         else if (last == &use->member->next) {
2850                                 last = 0;
2851                         }
2852                 }
2853         }
2854         return ret;
2855 }
2856
2857 static struct triple **triple_targ(struct compile_state *state,
2858         struct triple *ins, struct triple **last)
2859 {
2860         return do_triple_targ(state, ins, last, 1, 1);
2861 }
2862
2863 static struct triple **triple_edge_targ(struct compile_state *state,
2864         struct triple *ins, struct triple **last)
2865 {
2866         return do_triple_targ(state, ins, last, 
2867                 state->functions_joined, !state->functions_joined);
2868 }
2869
2870 static struct triple *after_lhs(struct compile_state *state, struct triple *ins)
2871 {
2872         struct triple *next;
2873         int lhs, i;
2874         lhs = ins->lhs;
2875         next = ins->next;
2876         for(i = 0; i < lhs; i++) {
2877                 struct triple *piece;
2878                 piece = LHS(ins, i);
2879                 if (next != piece) {
2880                         internal_error(state, ins, "malformed lhs on %s",
2881                                 tops(ins->op));
2882                 }
2883                 if (next->op != OP_PIECE) {
2884                         internal_error(state, ins, "bad lhs op %s at %d on %s",
2885                                 tops(next->op), i, tops(ins->op));
2886                 }
2887                 if (next->u.cval != i) {
2888                         internal_error(state, ins, "bad u.cval of %d %d expected",
2889                                 next->u.cval, i);
2890                 }
2891                 next = next->next;
2892         }
2893         return next;
2894 }
2895
2896 /* Function piece accessor functions */
2897 static struct triple *do_farg(struct compile_state *state, 
2898         struct triple *func, unsigned index)
2899 {
2900         struct type *ftype;
2901         struct triple *first, *arg;
2902         unsigned i;
2903
2904         ftype = func->type;
2905         if((index < 0) || (index >= (ftype->elements + 2))) {
2906                 internal_error(state, func, "bad argument index: %d", index);
2907         }
2908         first = RHS(func, 0);
2909         arg = first->next;
2910         for(i = 0; i < index; i++, arg = after_lhs(state, arg)) {
2911                 /* do nothing */
2912         }
2913         if (arg->op != OP_ADECL) {
2914                 internal_error(state, 0, "arg not adecl?");
2915         }
2916         return arg;
2917 }
2918 static struct triple *fresult(struct compile_state *state, struct triple *func)
2919 {
2920         return do_farg(state, func, 0);
2921 }
2922 static struct triple *fretaddr(struct compile_state *state, struct triple *func)
2923 {
2924         return do_farg(state, func, 1);
2925 }
2926 static struct triple *farg(struct compile_state *state, 
2927         struct triple *func, unsigned index)
2928 {
2929         return do_farg(state, func, index + 2);
2930 }
2931
2932
2933 static void display_func(struct compile_state *state, FILE *fp, struct triple *func)
2934 {
2935         struct triple *first, *ins;
2936         fprintf(fp, "display_func %s\n", func->type->type_ident->name);
2937         first = ins = RHS(func, 0);
2938         do {
2939                 if (triple_is_label(state, ins) && ins->use) {
2940                         fprintf(fp, "%p:\n", ins);
2941                 }
2942                 display_triple(fp, ins);
2943
2944                 if (triple_is_branch(state, ins)) {
2945                         fprintf(fp, "\n");
2946                 }
2947                 if (ins->next->prev != ins) {
2948                         internal_error(state, ins->next, "bad prev");
2949                 }
2950                 ins = ins->next;
2951         } while(ins != first);
2952 }
2953
2954 static void verify_use(struct compile_state *state,
2955         struct triple *user, struct triple *used)
2956 {
2957         int size, i;
2958         size = TRIPLE_SIZE(user);
2959         for(i = 0; i < size; i++) {
2960                 if (user->param[i] == used) {
2961                         break;
2962                 }
2963         }
2964         if (triple_is_branch(state, user)) {
2965                 if (user->next == used) {
2966                         i = -1;
2967                 }
2968         }
2969         if (i == size) {
2970                 internal_error(state, user, "%s(%p) does not use %s(%p)",
2971                         tops(user->op), user, tops(used->op), used);
2972         }
2973 }
2974
2975 static int find_rhs_use(struct compile_state *state, 
2976         struct triple *user, struct triple *used)
2977 {
2978         struct triple **param;
2979         int size, i;
2980         verify_use(state, user, used);
2981 #warning "AUDIT ME ->rhs"
2982         size = user->rhs;
2983         param = &RHS(user, 0);
2984         for(i = 0; i < size; i++) {
2985                 if (param[i] == used) {
2986                         return i;
2987                 }
2988         }
2989         return -1;
2990 }
2991
2992 static void free_triple(struct compile_state *state, struct triple *ptr)
2993 {
2994         size_t size;
2995         size = sizeof(*ptr) - sizeof(ptr->param) +
2996                 (sizeof(ptr->param[0])*TRIPLE_SIZE(ptr));
2997         ptr->prev->next = ptr->next;
2998         ptr->next->prev = ptr->prev;
2999         if (ptr->use) {
3000                 internal_error(state, ptr, "ptr->use != 0");
3001         }
3002         put_occurance(ptr->occurance);
3003         memset(ptr, -1, size);
3004         xfree(ptr);
3005 }
3006
3007 static void release_triple(struct compile_state *state, struct triple *ptr)
3008 {
3009         struct triple_set *set, *next;
3010         struct triple **expr;
3011         struct block *block;
3012         if (ptr == &unknown_triple) {
3013                 return;
3014         }
3015         valid_ins(state, ptr);
3016         /* Make certain the we are not the first or last element of a block */
3017         block = block_of_triple(state, ptr);
3018         if (block) {
3019                 if ((block->last == ptr) && (block->first == ptr)) {
3020                         block->last = block->first = 0;
3021                 }
3022                 else if (block->last == ptr) {
3023                         block->last = ptr->prev;
3024                 }
3025                 else if (block->first == ptr) {
3026                         block->first = ptr->next;
3027                 }
3028         }
3029         /* Remove ptr from use chains where it is the user */
3030         expr = triple_rhs(state, ptr, 0);
3031         for(; expr; expr = triple_rhs(state, ptr, expr)) {
3032                 if (*expr) {
3033                         unuse_triple(*expr, ptr);
3034                 }
3035         }
3036         expr = triple_lhs(state, ptr, 0);
3037         for(; expr; expr = triple_lhs(state, ptr, expr)) {
3038                 if (*expr) {
3039                         unuse_triple(*expr, ptr);
3040                 }
3041         }
3042         expr = triple_misc(state, ptr, 0);
3043         for(; expr; expr = triple_misc(state, ptr, expr)) {
3044                 if (*expr) {
3045                         unuse_triple(*expr, ptr);
3046                 }
3047         }
3048         expr = triple_targ(state, ptr, 0);
3049         for(; expr; expr = triple_targ(state, ptr, expr)) {
3050                 if (*expr){
3051                         unuse_triple(*expr, ptr);
3052                 }
3053         }
3054         /* Reomve ptr from use chains where it is used */
3055         for(set = ptr->use; set; set = next) {
3056                 next = set->next;
3057                 valid_ins(state, set->member);
3058                 expr = triple_rhs(state, set->member, 0);
3059                 for(; expr; expr = triple_rhs(state, set->member, expr)) {
3060                         if (*expr == ptr) {
3061                                 *expr = &unknown_triple;
3062                         }
3063                 }
3064                 expr = triple_lhs(state, set->member, 0);
3065                 for(; expr; expr = triple_lhs(state, set->member, expr)) {
3066                         if (*expr == ptr) {
3067                                 *expr = &unknown_triple;
3068                         }
3069                 }
3070                 expr = triple_misc(state, set->member, 0);
3071                 for(; expr; expr = triple_misc(state, set->member, expr)) {
3072                         if (*expr == ptr) {
3073                                 *expr = &unknown_triple;
3074                         }
3075                 }
3076                 expr = triple_targ(state, set->member, 0);
3077                 for(; expr; expr = triple_targ(state, set->member, expr)) {
3078                         if (*expr == ptr) {
3079                                 *expr = &unknown_triple;
3080                         }
3081                 }
3082                 unuse_triple(ptr, set->member);
3083         }
3084         free_triple(state, ptr);
3085 }
3086
3087 static void print_triples(struct compile_state *state);
3088 static void print_blocks(struct compile_state *state, const char *func, FILE *fp);
3089
3090 #define TOK_UNKNOWN     0
3091 #define TOK_SPACE       1
3092 #define TOK_SEMI        2
3093 #define TOK_LBRACE      3
3094 #define TOK_RBRACE      4
3095 #define TOK_COMMA       5
3096 #define TOK_EQ          6
3097 #define TOK_COLON       7
3098 #define TOK_LBRACKET    8
3099 #define TOK_RBRACKET    9
3100 #define TOK_LPAREN      10
3101 #define TOK_RPAREN      11
3102 #define TOK_STAR        12
3103 #define TOK_DOTS        13
3104 #define TOK_MORE        14
3105 #define TOK_LESS        15
3106 #define TOK_TIMESEQ     16
3107 #define TOK_DIVEQ       17
3108 #define TOK_MODEQ       18
3109 #define TOK_PLUSEQ      19
3110 #define TOK_MINUSEQ     20
3111 #define TOK_SLEQ        21
3112 #define TOK_SREQ        22
3113 #define TOK_ANDEQ       23
3114 #define TOK_XOREQ       24
3115 #define TOK_OREQ        25
3116 #define TOK_EQEQ        26
3117 #define TOK_NOTEQ       27
3118 #define TOK_QUEST       28
3119 #define TOK_LOGOR       29
3120 #define TOK_LOGAND      30
3121 #define TOK_OR          31
3122 #define TOK_AND         32
3123 #define TOK_XOR         33
3124 #define TOK_LESSEQ      34
3125 #define TOK_MOREEQ      35
3126 #define TOK_SL          36
3127 #define TOK_SR          37
3128 #define TOK_PLUS        38
3129 #define TOK_MINUS       39
3130 #define TOK_DIV         40
3131 #define TOK_MOD         41
3132 #define TOK_PLUSPLUS    42
3133 #define TOK_MINUSMINUS  43
3134 #define TOK_BANG        44
3135 #define TOK_ARROW       45
3136 #define TOK_DOT         46
3137 #define TOK_TILDE       47
3138 #define TOK_LIT_STRING  48
3139 #define TOK_LIT_CHAR    49
3140 #define TOK_LIT_INT     50
3141 #define TOK_LIT_FLOAT   51
3142 #define TOK_MACRO       52
3143 #define TOK_CONCATENATE 53
3144
3145 #define TOK_IDENT       54
3146 #define TOK_STRUCT_NAME 55
3147 #define TOK_ENUM_CONST  56
3148 #define TOK_TYPE_NAME   57
3149
3150 #define TOK_AUTO        58
3151 #define TOK_BREAK       59
3152 #define TOK_CASE        60
3153 #define TOK_CHAR        61
3154 #define TOK_CONST       62
3155 #define TOK_CONTINUE    63
3156 #define TOK_DEFAULT     64
3157 #define TOK_DO          65
3158 #define TOK_DOUBLE      66
3159 #define TOK_ELSE        67
3160 #define TOK_ENUM        68
3161 #define TOK_EXTERN      69
3162 #define TOK_FLOAT       70
3163 #define TOK_FOR         71
3164 #define TOK_GOTO        72
3165 #define TOK_IF          73
3166 #define TOK_INLINE      74
3167 #define TOK_INT         75
3168 #define TOK_LONG        76
3169 #define TOK_REGISTER    77
3170 #define TOK_RESTRICT    78
3171 #define TOK_RETURN      79
3172 #define TOK_SHORT       80
3173 #define TOK_SIGNED      81
3174 #define TOK_SIZEOF      82
3175 #define TOK_STATIC      83
3176 #define TOK_STRUCT      84
3177 #define TOK_SWITCH      85
3178 #define TOK_TYPEDEF     86
3179 #define TOK_UNION       87
3180 #define TOK_UNSIGNED    88
3181 #define TOK_VOID        89
3182 #define TOK_VOLATILE    90
3183 #define TOK_WHILE       91
3184 #define TOK_ASM         92
3185 #define TOK_ATTRIBUTE   93
3186 #define TOK_ALIGNOF     94
3187 #define TOK_FIRST_KEYWORD TOK_AUTO
3188 #define TOK_LAST_KEYWORD  TOK_ALIGNOF
3189
3190 #define TOK_MDEFINE     100
3191 #define TOK_MDEFINED    101
3192 #define TOK_MUNDEF      102
3193 #define TOK_MINCLUDE    103
3194 #define TOK_MLINE       104
3195 #define TOK_MERROR      105
3196 #define TOK_MWARNING    106
3197 #define TOK_MPRAGMA     107
3198 #define TOK_MIFDEF      108
3199 #define TOK_MIFNDEF     109
3200 #define TOK_MELIF       110
3201 #define TOK_MENDIF      111
3202
3203 #define TOK_FIRST_MACRO TOK_MDEFINE
3204 #define TOK_LAST_MACRO  TOK_MENDIF
3205          
3206 #define TOK_MIF         112
3207 #define TOK_MELSE       113
3208 #define TOK_MIDENT      114
3209
3210 #define TOK_EOL         115
3211 #define TOK_EOF         116
3212
3213 static const char *tokens[] = {
3214 [TOK_UNKNOWN     ] = ":unknown:",
3215 [TOK_SPACE       ] = ":space:",
3216 [TOK_SEMI        ] = ";",
3217 [TOK_LBRACE      ] = "{",
3218 [TOK_RBRACE      ] = "}",
3219 [TOK_COMMA       ] = ",",
3220 [TOK_EQ          ] = "=",
3221 [TOK_COLON       ] = ":",
3222 [TOK_LBRACKET    ] = "[",
3223 [TOK_RBRACKET    ] = "]",
3224 [TOK_LPAREN      ] = "(",
3225 [TOK_RPAREN      ] = ")",
3226 [TOK_STAR        ] = "*",
3227 [TOK_DOTS        ] = "...",
3228 [TOK_MORE        ] = ">",
3229 [TOK_LESS        ] = "<",
3230 [TOK_TIMESEQ     ] = "*=",
3231 [TOK_DIVEQ       ] = "/=",
3232 [TOK_MODEQ       ] = "%=",
3233 [TOK_PLUSEQ      ] = "+=",
3234 [TOK_MINUSEQ     ] = "-=",
3235 [TOK_SLEQ        ] = "<<=",
3236 [TOK_SREQ        ] = ">>=",
3237 [TOK_ANDEQ       ] = "&=",
3238 [TOK_XOREQ       ] = "^=",
3239 [TOK_OREQ        ] = "|=",
3240 [TOK_EQEQ        ] = "==",
3241 [TOK_NOTEQ       ] = "!=",
3242 [TOK_QUEST       ] = "?",
3243 [TOK_LOGOR       ] = "||",
3244 [TOK_LOGAND      ] = "&&",
3245 [TOK_OR          ] = "|",
3246 [TOK_AND         ] = "&",
3247 [TOK_XOR         ] = "^",
3248 [TOK_LESSEQ      ] = "<=",
3249 [TOK_MOREEQ      ] = ">=",
3250 [TOK_SL          ] = "<<",
3251 [TOK_SR          ] = ">>",
3252 [TOK_PLUS        ] = "+",
3253 [TOK_MINUS       ] = "-",
3254 [TOK_DIV         ] = "/",
3255 [TOK_MOD         ] = "%",
3256 [TOK_PLUSPLUS    ] = "++",
3257 [TOK_MINUSMINUS  ] = "--",
3258 [TOK_BANG        ] = "!",
3259 [TOK_ARROW       ] = "->",
3260 [TOK_DOT         ] = ".",
3261 [TOK_TILDE       ] = "~",
3262 [TOK_LIT_STRING  ] = ":string:",
3263 [TOK_IDENT       ] = ":ident:",
3264 [TOK_TYPE_NAME   ] = ":typename:",
3265 [TOK_LIT_CHAR    ] = ":char:",
3266 [TOK_LIT_INT     ] = ":integer:",
3267 [TOK_LIT_FLOAT   ] = ":float:",
3268 [TOK_MACRO       ] = "#",
3269 [TOK_CONCATENATE ] = "##",
3270
3271 [TOK_AUTO        ] = "auto",
3272 [TOK_BREAK       ] = "break",
3273 [TOK_CASE        ] = "case",
3274 [TOK_CHAR        ] = "char",
3275 [TOK_CONST       ] = "const",
3276 [TOK_CONTINUE    ] = "continue",
3277 [TOK_DEFAULT     ] = "default",
3278 [TOK_DO          ] = "do",
3279 [TOK_DOUBLE      ] = "double",
3280 [TOK_ELSE        ] = "else",
3281 [TOK_ENUM        ] = "enum",
3282 [TOK_EXTERN      ] = "extern",
3283 [TOK_FLOAT       ] = "float",
3284 [TOK_FOR         ] = "for",
3285 [TOK_GOTO        ] = "goto",
3286 [TOK_IF          ] = "if",
3287 [TOK_INLINE      ] = "inline",
3288 [TOK_INT         ] = "int",
3289 [TOK_LONG        ] = "long",
3290 [TOK_REGISTER    ] = "register",
3291 [TOK_RESTRICT    ] = "restrict",
3292 [TOK_RETURN      ] = "return",
3293 [TOK_SHORT       ] = "short",
3294 [TOK_SIGNED      ] = "signed",
3295 [TOK_SIZEOF      ] = "sizeof",
3296 [TOK_STATIC      ] = "static",
3297 [TOK_STRUCT      ] = "struct",
3298 [TOK_SWITCH      ] = "switch",
3299 [TOK_TYPEDEF     ] = "typedef",
3300 [TOK_UNION       ] = "union",
3301 [TOK_UNSIGNED    ] = "unsigned",
3302 [TOK_VOID        ] = "void",
3303 [TOK_VOLATILE    ] = "volatile",
3304 [TOK_WHILE       ] = "while",
3305 [TOK_ASM         ] = "asm",
3306 [TOK_ATTRIBUTE   ] = "__attribute__",
3307 [TOK_ALIGNOF     ] = "__alignof__",
3308
3309 [TOK_MDEFINE     ] = "#define",
3310 [TOK_MDEFINED    ] = "#defined",
3311 [TOK_MUNDEF      ] = "#undef",
3312 [TOK_MINCLUDE    ] = "#include",
3313 [TOK_MLINE       ] = "#line",
3314 [TOK_MERROR      ] = "#error",
3315 [TOK_MWARNING    ] = "#warning",
3316 [TOK_MPRAGMA     ] = "#pragma",
3317 [TOK_MIFDEF      ] = "#ifdef",
3318 [TOK_MIFNDEF     ] = "#ifndef",
3319 [TOK_MELIF       ] = "#elif",
3320 [TOK_MENDIF      ] = "#endif",
3321
3322 [TOK_MIF         ] = "#if",
3323 [TOK_MELSE       ] = "#else",
3324 [TOK_MIDENT      ] = "#:ident:",
3325 [TOK_EOL         ] = "EOL", 
3326 [TOK_EOF         ] = "EOF",
3327 };
3328
3329 static unsigned int hash(const char *str, int str_len)
3330 {
3331         unsigned int hash;
3332         const char *end;
3333         end = str + str_len;
3334         hash = 0;
3335         for(; str < end; str++) {
3336                 hash = (hash *263) + *str;
3337         }
3338         hash = hash & (HASH_TABLE_SIZE -1);
3339         return hash;
3340 }
3341
3342 static struct hash_entry *lookup(
3343         struct compile_state *state, const char *name, int name_len)
3344 {
3345         struct hash_entry *entry;
3346         unsigned int index;
3347         index = hash(name, name_len);
3348         entry = state->hash_table[index];
3349         while(entry && 
3350                 ((entry->name_len != name_len) ||
3351                         (memcmp(entry->name, name, name_len) != 0))) {
3352                 entry = entry->next;
3353         }
3354         if (!entry) {
3355                 char *new_name;
3356                 /* Get a private copy of the name */
3357                 new_name = xmalloc(name_len + 1, "hash_name");
3358                 memcpy(new_name, name, name_len);
3359                 new_name[name_len] = '\0';
3360
3361                 /* Create a new hash entry */
3362                 entry = xcmalloc(sizeof(*entry), "hash_entry");
3363                 entry->next = state->hash_table[index];
3364                 entry->name = new_name;
3365                 entry->name_len = name_len;
3366
3367                 /* Place the new entry in the hash table */
3368                 state->hash_table[index] = entry;
3369         }
3370         return entry;
3371 }
3372
3373 static void ident_to_keyword(struct compile_state *state, struct token *tk)
3374 {
3375         struct hash_entry *entry;
3376         entry = tk->ident;
3377         if (entry && ((entry->tok == TOK_TYPE_NAME) ||
3378                 (entry->tok == TOK_ENUM_CONST) ||
3379                 ((entry->tok >= TOK_FIRST_KEYWORD) && 
3380                         (entry->tok <= TOK_LAST_KEYWORD)))) {
3381                 tk->tok = entry->tok;
3382         }
3383 }
3384
3385 static void ident_to_macro(struct compile_state *state, struct token *tk)
3386 {
3387         struct hash_entry *entry;
3388         entry = tk->ident;
3389         if (!entry)
3390                 return;
3391         if ((entry->tok >= TOK_FIRST_MACRO) && (entry->tok <= TOK_LAST_MACRO)) {
3392                 tk->tok = entry->tok;
3393         }
3394         else if (entry->tok == TOK_IF) {
3395                 tk->tok = TOK_MIF;
3396         }
3397         else if (entry->tok == TOK_ELSE) {
3398                 tk->tok = TOK_MELSE;
3399         }
3400         else {
3401                 tk->tok = TOK_MIDENT;
3402         }
3403 }
3404
3405 static void hash_keyword(
3406         struct compile_state *state, const char *keyword, int tok)
3407 {
3408         struct hash_entry *entry;
3409         entry = lookup(state, keyword, strlen(keyword));
3410         if (entry && entry->tok != TOK_UNKNOWN) {
3411                 die("keyword %s already hashed", keyword);
3412         }
3413         entry->tok  = tok;
3414 }
3415
3416 static void romcc_symbol(
3417         struct compile_state *state, struct hash_entry *ident,
3418         struct symbol **chain, struct triple *def, struct type *type, int depth)
3419 {
3420         struct symbol *sym;
3421         if (*chain && ((*chain)->scope_depth >= depth)) {
3422                 error(state, 0, "%s already defined", ident->name);
3423         }
3424         sym = xcmalloc(sizeof(*sym), "symbol");
3425         sym->ident = ident;
3426         sym->def   = def;
3427         sym->type  = type;
3428         sym->scope_depth = depth;
3429         sym->next = *chain;
3430         *chain    = sym;
3431 }
3432
3433 static void symbol(
3434         struct compile_state *state, struct hash_entry *ident,
3435         struct symbol **chain, struct triple *def, struct type *type)
3436 {
3437         romcc_symbol(state, ident, chain, def, type, state->scope_depth);
3438 }
3439
3440 static void var_symbol(struct compile_state *state, 
3441         struct hash_entry *ident, struct triple *def)
3442 {
3443         if ((def->type->type & TYPE_MASK) == TYPE_PRODUCT) {
3444                 internal_error(state, 0, "bad var type");
3445         }
3446         symbol(state, ident, &ident->sym_ident, def, def->type);
3447 }
3448
3449 static void label_symbol(struct compile_state *state, 
3450         struct hash_entry *ident, struct triple *label, int depth)
3451 {
3452         romcc_symbol(state, ident, &ident->sym_label, label, &void_type, depth);
3453 }
3454
3455 static void start_scope(struct compile_state *state)
3456 {
3457         state->scope_depth++;
3458 }
3459
3460 static void end_scope_syms(struct compile_state *state,
3461         struct symbol **chain, int depth)
3462 {
3463         struct symbol *sym, *next;
3464         sym = *chain;
3465         while(sym && (sym->scope_depth == depth)) {
3466                 next = sym->next;
3467                 xfree(sym);
3468                 sym = next;
3469         }
3470         *chain = sym;
3471 }
3472
3473 static void end_scope(struct compile_state *state)
3474 {
3475         int i;
3476         int depth;
3477         /* Walk through the hash table and remove all symbols
3478          * in the current scope. 
3479          */
3480         depth = state->scope_depth;
3481         for(i = 0; i < HASH_TABLE_SIZE; i++) {
3482                 struct hash_entry *entry;
3483                 entry = state->hash_table[i];
3484                 while(entry) {
3485                         end_scope_syms(state, &entry->sym_label, depth);
3486                         end_scope_syms(state, &entry->sym_tag,   depth);
3487                         end_scope_syms(state, &entry->sym_ident, depth);
3488                         entry = entry->next;
3489                 }
3490         }
3491         state->scope_depth = depth - 1;
3492 }
3493
3494 static void register_keywords(struct compile_state *state)
3495 {
3496         hash_keyword(state, "auto",          TOK_AUTO);
3497         hash_keyword(state, "break",         TOK_BREAK);
3498         hash_keyword(state, "case",          TOK_CASE);
3499         hash_keyword(state, "char",          TOK_CHAR);
3500         hash_keyword(state, "const",         TOK_CONST);
3501         hash_keyword(state, "continue",      TOK_CONTINUE);
3502         hash_keyword(state, "default",       TOK_DEFAULT);
3503         hash_keyword(state, "do",            TOK_DO);
3504         hash_keyword(state, "double",        TOK_DOUBLE);
3505         hash_keyword(state, "else",          TOK_ELSE);
3506         hash_keyword(state, "enum",          TOK_ENUM);
3507         hash_keyword(state, "extern",        TOK_EXTERN);
3508         hash_keyword(state, "float",         TOK_FLOAT);
3509         hash_keyword(state, "for",           TOK_FOR);
3510         hash_keyword(state, "goto",          TOK_GOTO);
3511         hash_keyword(state, "if",            TOK_IF);
3512         hash_keyword(state, "inline",        TOK_INLINE);
3513         hash_keyword(state, "int",           TOK_INT);
3514         hash_keyword(state, "long",          TOK_LONG);
3515         hash_keyword(state, "register",      TOK_REGISTER);
3516         hash_keyword(state, "restrict",      TOK_RESTRICT);
3517         hash_keyword(state, "return",        TOK_RETURN);
3518         hash_keyword(state, "short",         TOK_SHORT);
3519         hash_keyword(state, "signed",        TOK_SIGNED);
3520         hash_keyword(state, "sizeof",        TOK_SIZEOF);
3521         hash_keyword(state, "static",        TOK_STATIC);
3522         hash_keyword(state, "struct",        TOK_STRUCT);
3523         hash_keyword(state, "switch",        TOK_SWITCH);
3524         hash_keyword(state, "typedef",       TOK_TYPEDEF);
3525         hash_keyword(state, "union",         TOK_UNION);
3526         hash_keyword(state, "unsigned",      TOK_UNSIGNED);
3527         hash_keyword(state, "void",          TOK_VOID);
3528         hash_keyword(state, "volatile",      TOK_VOLATILE);
3529         hash_keyword(state, "__volatile__",  TOK_VOLATILE);
3530         hash_keyword(state, "while",         TOK_WHILE);
3531         hash_keyword(state, "asm",           TOK_ASM);
3532         hash_keyword(state, "__asm__",       TOK_ASM);
3533         hash_keyword(state, "__attribute__", TOK_ATTRIBUTE);
3534         hash_keyword(state, "__alignof__",   TOK_ALIGNOF);
3535 }
3536
3537 static void register_macro_keywords(struct compile_state *state)
3538 {
3539         hash_keyword(state, "define",        TOK_MDEFINE);
3540         hash_keyword(state, "defined",       TOK_MDEFINED);
3541         hash_keyword(state, "undef",         TOK_MUNDEF);
3542         hash_keyword(state, "include",       TOK_MINCLUDE);
3543         hash_keyword(state, "line",          TOK_MLINE);
3544         hash_keyword(state, "error",         TOK_MERROR);
3545         hash_keyword(state, "warning",       TOK_MWARNING);
3546         hash_keyword(state, "pragma",        TOK_MPRAGMA);
3547         hash_keyword(state, "ifdef",         TOK_MIFDEF);
3548         hash_keyword(state, "ifndef",        TOK_MIFNDEF);
3549         hash_keyword(state, "elif",          TOK_MELIF);
3550         hash_keyword(state, "endif",         TOK_MENDIF);
3551 }
3552
3553
3554 static void undef_macro(struct compile_state *state, struct hash_entry *ident)
3555 {
3556         if (ident->sym_define != 0) {
3557                 struct macro *macro;
3558                 struct macro_arg *arg, *anext;
3559                 macro = ident->sym_define;
3560                 ident->sym_define = 0;
3561                 
3562                 /* Free the macro arguments... */
3563                 anext = macro->args;
3564                 while(anext) {
3565                         arg = anext;
3566                         anext = arg->next;
3567                         xfree(arg);
3568                 }
3569
3570                 /* Free the macro buffer */
3571                 xfree(macro->buf);
3572
3573                 /* Now free the macro itself */
3574                 xfree(macro);
3575         }
3576 }
3577
3578 static void define_macro(
3579         struct compile_state *state,
3580         struct hash_entry *ident, 
3581         const char *value, int value_len, int value_off, 
3582         struct macro_arg *args)
3583 {
3584         struct macro *macro;
3585         struct macro_arg *arg;
3586         macro = ident->sym_define;
3587         if (macro != 0) {
3588                 /* Explicitly allow identical redefinitions of the same macro */
3589                 if ((macro->buf_len == value_len) &&
3590                         (memcmp(macro->buf, value, value_len) == 0)) {
3591                         return;
3592                 }
3593                 error(state, 0, "macro %s already defined\n", ident->name);
3594         }
3595 #if 0
3596         fprintf(state->errout, "%s: `%*.*s'\n",
3597                 ident->name,
3598                 value_len - value_off,
3599                 value_len - value_off,
3600                 value + value_off);
3601 #endif
3602         macro = xmalloc(sizeof(*macro), "macro");
3603         macro->ident = ident;
3604         macro->buf_len = value_len;
3605         macro->buf_off = value_off;
3606         macro->args    = args;
3607         macro->buf = xmalloc(macro->buf_len + 1, "macro buf");
3608
3609         macro->argc = 0;
3610         for(arg = args; arg; arg = arg->next) {
3611                 macro->argc += 1;
3612         }      
3613
3614         memcpy(macro->buf, value, macro->buf_len);
3615         macro->buf[macro->buf_len] = '\0';
3616
3617         ident->sym_define = macro;
3618 }
3619
3620 static void register_builtin_macro(struct compile_state *state,
3621         const char *name, const char *value)
3622 {
3623         struct hash_entry *ident;
3624
3625         if (value[0] == '(') {
3626                 internal_error(state, 0, "Builtin macros with arguments not supported");
3627         }
3628         ident = lookup(state, name, strlen(name));
3629         define_macro(state, ident, value, strlen(value), 0, 0);
3630 }
3631
3632 static void register_builtin_macros(struct compile_state *state)
3633 {
3634         char buf[30];
3635         char scratch[30];
3636         time_t now;
3637         struct tm *tm;
3638         now = time(NULL);
3639         tm = localtime(&now);
3640
3641         register_builtin_macro(state, "__ROMCC__", VERSION_MAJOR);
3642         register_builtin_macro(state, "__ROMCC_MINOR__", VERSION_MINOR);
3643         register_builtin_macro(state, "__FILE__", "\"This should be the filename\"");
3644         register_builtin_macro(state, "__LINE__", "54321");
3645
3646         strftime(scratch, sizeof(scratch), "%b %e %Y", tm);
3647         sprintf(buf, "\"%s\"", scratch);
3648         register_builtin_macro(state, "__DATE__", buf);
3649
3650         strftime(scratch, sizeof(scratch), "%H:%M:%S", tm);
3651         sprintf(buf, "\"%s\"", scratch);
3652         register_builtin_macro(state, "__TIME__", buf);
3653
3654         /* I can't be a conforming implementation of C :( */
3655         register_builtin_macro(state, "__STDC__", "0");
3656         /* In particular I don't conform to C99 */
3657         register_builtin_macro(state, "__STDC_VERSION__", "199901L");
3658         
3659 }
3660
3661 static void process_cmdline_macros(struct compile_state *state)
3662 {
3663         const char **macro, *name;
3664         struct hash_entry *ident;
3665         for(macro = state->compiler->defines; (name = *macro); macro++) {
3666                 const char *body;
3667                 size_t name_len;
3668
3669                 name_len = strlen(name);
3670                 body = strchr(name, '=');
3671                 if (!body) {
3672                         body = "\0";
3673                 } else {
3674                         name_len = body - name;
3675                         body++;
3676                 }
3677                 ident = lookup(state, name, name_len);
3678                 define_macro(state, ident, body, strlen(body), 0, 0);
3679         }
3680         for(macro = state->compiler->undefs; (name = *macro); macro++) {
3681                 ident = lookup(state, name, strlen(name));
3682                 undef_macro(state, ident);
3683         }
3684 }
3685
3686 static int spacep(int c)
3687 {
3688         int ret = 0;
3689         switch(c) {
3690         case ' ':
3691         case '\t':
3692         case '\f':
3693         case '\v':
3694         case '\r':
3695                 ret = 1;
3696                 break;
3697         }
3698         return ret;
3699 }
3700
3701 static int eolp(int c)
3702 {
3703         int ret = 0;
3704         switch(c) {
3705         case '\n':
3706                 ret = 1;
3707                 break;
3708         }
3709         return ret;
3710 }
3711
3712 static int digitp(int c)
3713 {
3714         int ret = 0;
3715         switch(c) {
3716         case '0': case '1': case '2': case '3': case '4': 
3717         case '5': case '6': case '7': case '8': case '9':
3718                 ret = 1;
3719                 break;
3720         }
3721         return ret;
3722 }
3723 static int digval(int c)
3724 {
3725         int val = -1;
3726         if ((c >= '0') && (c <= '9')) {
3727                 val = c - '0';
3728         }
3729         return val;
3730 }
3731
3732 static int hexdigitp(int c)
3733 {
3734         int ret = 0;
3735         switch(c) {
3736         case '0': case '1': case '2': case '3': case '4': 
3737         case '5': case '6': case '7': case '8': case '9':
3738         case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
3739         case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
3740                 ret = 1;
3741                 break;
3742         }
3743         return ret;
3744 }
3745 static int hexdigval(int c) 
3746 {
3747         int val = -1;
3748         if ((c >= '0') && (c <= '9')) {
3749                 val = c - '0';
3750         }
3751         else if ((c >= 'A') && (c <= 'F')) {
3752                 val = 10 + (c - 'A');
3753         }
3754         else if ((c >= 'a') && (c <= 'f')) {
3755                 val = 10 + (c - 'a');
3756         }
3757         return val;
3758 }
3759
3760 static int octdigitp(int c)
3761 {
3762         int ret = 0;
3763         switch(c) {
3764         case '0': case '1': case '2': case '3': 
3765         case '4': case '5': case '6': case '7':
3766                 ret = 1;
3767                 break;
3768         }
3769         return ret;
3770 }
3771 static int octdigval(int c)
3772 {
3773         int val = -1;
3774         if ((c >= '0') && (c <= '7')) {
3775                 val = c - '0';
3776         }
3777         return val;
3778 }
3779
3780 static int letterp(int c)
3781 {
3782         int ret = 0;
3783         switch(c) {
3784         case 'a': case 'b': case 'c': case 'd': case 'e':
3785         case 'f': case 'g': case 'h': case 'i': case 'j':
3786         case 'k': case 'l': case 'm': case 'n': case 'o':
3787         case 'p': case 'q': case 'r': case 's': case 't':
3788         case 'u': case 'v': case 'w': case 'x': case 'y':
3789         case 'z':
3790         case 'A': case 'B': case 'C': case 'D': case 'E':
3791         case 'F': case 'G': case 'H': case 'I': case 'J':
3792         case 'K': case 'L': case 'M': case 'N': case 'O':
3793         case 'P': case 'Q': case 'R': case 'S': case 'T':
3794         case 'U': case 'V': case 'W': case 'X': case 'Y':
3795         case 'Z':
3796         case '_':
3797                 ret = 1;
3798                 break;
3799         }
3800         return ret;
3801 }
3802
3803 static const char *identifier(const char *str, const char *end)
3804 {
3805         if (letterp(*str)) {
3806                 for(; str < end; str++) {
3807                         int c;
3808                         c = *str;
3809                         if (!letterp(c) && !digitp(c)) {
3810                                 break;
3811                         }
3812                 }
3813         }
3814         return str;
3815 }
3816
3817 static int char_value(struct compile_state *state,
3818         const signed char **strp, const signed char *end)
3819 {
3820         const signed char *str;
3821         int c;
3822         str = *strp;
3823         c = *str++;
3824         if ((c == '\\') && (str < end)) {
3825                 switch(*str) {
3826                 case 'n':  c = '\n'; str++; break;
3827                 case 't':  c = '\t'; str++; break;
3828                 case 'v':  c = '\v'; str++; break;
3829                 case 'b':  c = '\b'; str++; break;
3830                 case 'r':  c = '\r'; str++; break;
3831                 case 'f':  c = '\f'; str++; break;
3832                 case 'a':  c = '\a'; str++; break;
3833                 case '\\': c = '\\'; str++; break;
3834                 case '?':  c = '?';  str++; break;
3835                 case '\'': c = '\''; str++; break;
3836                 case '"':  c = '"';  str++; break;
3837                 case 'x': 
3838                         c = 0;
3839                         str++;
3840                         while((str < end) && hexdigitp(*str)) {
3841                                 c <<= 4;
3842                                 c += hexdigval(*str);
3843                                 str++;
3844                         }
3845                         break;
3846                 case '0': case '1': case '2': case '3': 
3847                 case '4': case '5': case '6': case '7':
3848                         c = 0;
3849                         while((str < end) && octdigitp(*str)) {
3850                                 c <<= 3;
3851                                 c += octdigval(*str);
3852                                 str++;
3853                         }
3854                         break;
3855                 default:
3856                         error(state, 0, "Invalid character constant");
3857                         break;
3858                 }
3859         }
3860         *strp = str;
3861         return c;
3862 }
3863
3864 static const char *after_digits(const char *ptr, const char *end)
3865 {
3866         while((ptr < end) && digitp(*ptr)) {
3867                 ptr++;
3868         }
3869         return ptr;
3870 }
3871
3872 static const char *after_octdigits(const char *ptr, const char *end)
3873 {
3874         while((ptr < end) && octdigitp(*ptr)) {
3875                 ptr++;
3876         }
3877         return ptr;
3878 }
3879
3880 static const char *after_hexdigits(const char *ptr, const char *end)
3881 {
3882         while((ptr < end) && hexdigitp(*ptr)) {
3883                 ptr++;
3884         }
3885         return ptr;
3886 }
3887
3888 static void save_string(struct compile_state *state, 
3889         struct token *tk, const char *start, const char *end, const char *id)
3890 {
3891         char *str;
3892         int str_len;
3893         /* Create a private copy of the string */
3894         str_len = end - start + 1;
3895         str = xmalloc(str_len + 1, id);
3896         memcpy(str, start, str_len);
3897         str[str_len] = '\0';
3898
3899         /* Store the copy in the token */
3900         tk->val.str = str;
3901         tk->str_len = str_len;
3902 }
3903
3904 static int lparen_peek(struct compile_state *state, struct file_state *file)
3905 {
3906         const char *tokp, *end;
3907         /* Is the next token going to be an lparen? 
3908          * Whitespace tokens are significant for seeing if a macro
3909          * should be expanded.
3910          */
3911         tokp = file->pos;
3912         end = file->buf + file->size;
3913         return (tokp < end) && (*tokp == '(');
3914 }
3915
3916 static void raw_next_token(struct compile_state *state, 
3917         struct file_state *file, struct token *tk)
3918 {
3919         const char *token;
3920         int c, c1, c2, c3;
3921         const char *tokp, *end;
3922         int tok;
3923
3924         tk->str_len = 0;
3925         tk->ident = 0;
3926         token = tokp = file->pos;
3927         end = file->buf + file->size;
3928         tok = TOK_UNKNOWN;
3929         c = -1;
3930         if (tokp < end) {
3931                 c = *tokp;
3932         }
3933         c1 = -1;
3934         if ((tokp + 1) < end) {
3935                 c1 = tokp[1];
3936         }
3937         c2 = -1;
3938         if ((tokp + 2) < end) {
3939                 c2 = tokp[2];
3940         }
3941         c3 = -1;
3942         if ((tokp + 3) < end) {
3943                 c3 = tokp[3];
3944         }
3945         if (tokp >= end) {
3946                 tok = TOK_EOF;
3947                 tokp = end;
3948         }
3949         /* End of Line */
3950         else if (eolp(c)) {
3951                 tok = TOK_EOL;
3952                 file->line++;
3953                 file->report_line++;
3954                 file->line_start = tokp + 1;
3955         }
3956         /* Whitespace */
3957         else if (spacep(c)) {
3958                 tok = TOK_SPACE;
3959                 while ((tokp < end) && spacep(c)) {
3960                         c = *(++tokp);
3961                 }
3962                 if (!spacep(c)) {
3963                         tokp--;
3964                 }
3965         }
3966         /* EOL Comments */
3967         else if ((c == '/') && (c1 == '/')) {
3968                 tok = TOK_SPACE;
3969                 for(tokp += 2; tokp < end; tokp++) {
3970                         c = *tokp;
3971                         if (c == '\n') {
3972                                 tokp--;
3973                                 break;
3974                         }
3975                 }
3976         }
3977         /* Comments */
3978         else if ((c == '/') && (c1 == '*')) {
3979                 int line;
3980                 const char *line_start;
3981                 line = file->line;
3982                 line_start = file->line_start;
3983                 for(tokp += 2; (end - tokp) >= 2; tokp++) {
3984                         c = *tokp;
3985                         if (c == '\n') {
3986                                 line++;
3987                                 line_start = tokp +1;
3988                         }
3989                         else if ((c == '*') && (tokp[1] == '/')) {
3990                                 tok = TOK_SPACE;
3991                                 tokp += 1;
3992                                 break;
3993                         }
3994                 }
3995                 if (tok == TOK_UNKNOWN) {
3996                         error(state, 0, "unterminated comment");
3997                 }
3998                 file->report_line += line - file->line;
3999                 file->line = line;
4000                 file->line_start = line_start;
4001         }
4002         /* string constants */
4003         else if ((c == '"') ||
4004                 ((c == 'L') && (c1 == '"'))) {
4005                 int line;
4006                 const char *line_start;
4007                 int wchar;
4008                 line = file->line;
4009                 line_start = file->line_start;
4010                 wchar = 0;
4011                 if (c == 'L') {
4012                         wchar = 1;
4013                         tokp++;
4014                 }
4015                 for(tokp += 1; tokp < end; tokp++) {
4016                         c = *tokp;
4017                         if (c == '\n') {
4018                                 line++;
4019                                 line_start = tokp + 1;
4020                         }
4021                         else if ((c == '\\') && (tokp +1 < end)) {
4022                                 tokp++;
4023                         }
4024                         else if (c == '"') {
4025                                 tok = TOK_LIT_STRING;
4026                                 break;
4027                         }
4028                 }
4029                 if (tok == TOK_UNKNOWN) {
4030                         error(state, 0, "unterminated string constant");
4031                 }
4032                 if (line != file->line) {
4033                         warning(state, 0, "multiline string constant");
4034                 }
4035                 file->report_line += line - file->line;
4036                 file->line = line;
4037                 file->line_start = line_start;
4038
4039                 /* Save the string value */
4040                 save_string(state, tk, token, tokp, "literal string");
4041         }
4042         /* character constants */
4043         else if ((c == '\'') ||
4044                 ((c == 'L') && (c1 == '\''))) {
4045                 int line;
4046                 const char *line_start;
4047                 int wchar;
4048                 line = file->line;
4049                 line_start = file->line_start;
4050                 wchar = 0;
4051                 if (c == 'L') {
4052                         wchar = 1;
4053                         tokp++;
4054                 }
4055                 for(tokp += 1; tokp < end; tokp++) {
4056                         c = *tokp;
4057                         if (c == '\n') {
4058                                 line++;
4059                                 line_start = tokp + 1;
4060                         }
4061                         else if ((c == '\\') && (tokp +1 < end)) {
4062                                 tokp++;
4063                         }
4064                         else if (c == '\'') {
4065                                 tok = TOK_LIT_CHAR;
4066                                 break;
4067                         }
4068                 }
4069                 if (tok == TOK_UNKNOWN) {
4070                         error(state, 0, "unterminated character constant");
4071                 }
4072                 if (line != file->line) {
4073                         warning(state, 0, "multiline character constant");
4074                 }
4075                 file->report_line += line - file->line;
4076                 file->line = line;
4077                 file->line_start = line_start;
4078
4079                 /* Save the character value */
4080                 save_string(state, tk, token, tokp, "literal character");
4081         }
4082         /* integer and floating constants 
4083          * Integer Constants
4084          * {digits}
4085          * 0[Xx]{hexdigits}
4086          * 0{octdigit}+
4087          * 
4088          * Floating constants
4089          * {digits}.{digits}[Ee][+-]?{digits}
4090          * {digits}.{digits}
4091          * {digits}[Ee][+-]?{digits}
4092          * .{digits}[Ee][+-]?{digits}
4093          * .{digits}
4094          */
4095         
4096         else if (digitp(c) || ((c == '.') && (digitp(c1)))) {
4097                 const char *next, *new;
4098                 int is_float;
4099                 is_float = 0;
4100                 if (c != '.') {
4101                         next = after_digits(tokp, end);
4102                 }
4103                 else {
4104                         next = tokp;
4105                 }
4106                 if (next[0] == '.') {
4107                         new = after_digits(next, end);
4108                         is_float = (new != next);
4109                         next = new;
4110                 }
4111                 if ((next[0] == 'e') || (next[0] == 'E')) {
4112                         if (((next + 1) < end) && 
4113                                 ((next[1] == '+') || (next[1] == '-'))) {
4114                                 next++;
4115                         }
4116                         new = after_digits(next, end);
4117                         is_float = (new != next);
4118                         next = new;
4119                 }
4120                 if (is_float) {
4121                         tok = TOK_LIT_FLOAT;
4122                         if ((next < end) && (
4123                                 (next[0] == 'f') ||
4124                                 (next[0] == 'F') ||
4125                                 (next[0] == 'l') ||
4126                                 (next[0] == 'L'))
4127                                 ) {
4128                                 next++;
4129                         }
4130                 }
4131                 if (!is_float && digitp(c)) {
4132                         tok = TOK_LIT_INT;
4133                         if ((c == '0') && ((c1 == 'x') || (c1 == 'X'))) {
4134                                 next = after_hexdigits(tokp + 2, end);
4135                         }
4136                         else if (c == '0') {
4137                                 next = after_octdigits(tokp, end);
4138                         }
4139                         else {
4140                                 next = after_digits(tokp, end);
4141                         }
4142                         /* crazy integer suffixes */
4143                         if ((next < end) && 
4144                                 ((next[0] == 'u') || (next[0] == 'U'))) { 
4145                                 next++;
4146                                 if ((next < end) &&
4147                                         ((next[0] == 'l') || (next[0] == 'L'))) {
4148                                         next++;
4149                                 }
4150                         }
4151                         else if ((next < end) &&
4152                                 ((next[0] == 'l') || (next[0] == 'L'))) {
4153                                 next++;
4154                                 if ((next < end) && 
4155                                         ((next[0] == 'u') || (next[0] == 'U'))) { 
4156                                         next++;
4157                                 }
4158                         }
4159                 }
4160                 tokp = next - 1;
4161
4162                 /* Save the integer/floating point value */
4163                 save_string(state, tk, token, tokp, "literal number");
4164         }
4165         /* identifiers */
4166         else if (letterp(c)) {
4167                 tok = TOK_IDENT;
4168                 tokp = identifier(tokp, end);
4169                 tokp -= 1;
4170                 tk->ident = lookup(state, token, tokp +1 - token);
4171                 /* See if this identifier can be macro expanded */
4172                 tk->val.notmacro = 0;
4173                 if ((tokp < end) && (tokp[1] == '$')) {
4174                         tokp++;
4175                         tk->val.notmacro = 1;
4176                 }
4177         }
4178         /* C99 alternate macro characters */
4179         else if ((c == '%') && (c1 == ':') && (c2 == '%') && (c3 == ':')) { 
4180                 tokp += 3; 
4181                 tok = TOK_CONCATENATE; 
4182         }
4183         else if ((c == '.') && (c1 == '.') && (c2 == '.')) { tokp += 2; tok = TOK_DOTS; }
4184         else if ((c == '<') && (c1 == '<') && (c2 == '=')) { tokp += 2; tok = TOK_SLEQ; }
4185         else if ((c == '>') && (c1 == '>') && (c2 == '=')) { tokp += 2; tok = TOK_SREQ; }
4186         else if ((c == '*') && (c1 == '=')) { tokp += 1; tok = TOK_TIMESEQ; }
4187         else if ((c == '/') && (c1 == '=')) { tokp += 1; tok = TOK_DIVEQ; }
4188         else if ((c == '%') && (c1 == '=')) { tokp += 1; tok = TOK_MODEQ; }
4189         else if ((c == '+') && (c1 == '=')) { tokp += 1; tok = TOK_PLUSEQ; }
4190         else if ((c == '-') && (c1 == '=')) { tokp += 1; tok = TOK_MINUSEQ; }
4191         else if ((c == '&') && (c1 == '=')) { tokp += 1; tok = TOK_ANDEQ; }
4192         else if ((c == '^') && (c1 == '=')) { tokp += 1; tok = TOK_XOREQ; }
4193         else if ((c == '|') && (c1 == '=')) { tokp += 1; tok = TOK_OREQ; }
4194         else if ((c == '=') && (c1 == '=')) { tokp += 1; tok = TOK_EQEQ; }
4195         else if ((c == '!') && (c1 == '=')) { tokp += 1; tok = TOK_NOTEQ; }
4196         else if ((c == '|') && (c1 == '|')) { tokp += 1; tok = TOK_LOGOR; }
4197         else if ((c == '&') && (c1 == '&')) { tokp += 1; tok = TOK_LOGAND; }
4198         else if ((c == '<') && (c1 == '=')) { tokp += 1; tok = TOK_LESSEQ; }
4199         else if ((c == '>') && (c1 == '=')) { tokp += 1; tok = TOK_MOREEQ; }
4200         else if ((c == '<') && (c1 == '<')) { tokp += 1; tok = TOK_SL; }
4201         else if ((c == '>') && (c1 == '>')) { tokp += 1; tok = TOK_SR; }
4202         else if ((c == '+') && (c1 == '+')) { tokp += 1; tok = TOK_PLUSPLUS; }
4203         else if ((c == '-') && (c1 == '-')) { tokp += 1; tok = TOK_MINUSMINUS; }
4204         else if ((c == '-') && (c1 == '>')) { tokp += 1; tok = TOK_ARROW; }
4205         else if ((c == '<') && (c1 == ':')) { tokp += 1; tok = TOK_LBRACKET; }
4206         else if ((c == ':') && (c1 == '>')) { tokp += 1; tok = TOK_RBRACKET; }
4207         else if ((c == '<') && (c1 == '%')) { tokp += 1; tok = TOK_LBRACE; }
4208         else if ((c == '%') && (c1 == '>')) { tokp += 1; tok = TOK_RBRACE; }
4209         else if ((c == '%') && (c1 == ':')) { tokp += 1; tok = TOK_MACRO; }
4210         else if ((c == '#') && (c1 == '#')) { tokp += 1; tok = TOK_CONCATENATE; }
4211         else if (c == ';') { tok = TOK_SEMI; }
4212         else if (c == '{') { tok = TOK_LBRACE; }
4213         else if (c == '}') { tok = TOK_RBRACE; }
4214         else if (c == ',') { tok = TOK_COMMA; }
4215         else if (c == '=') { tok = TOK_EQ; }
4216         else if (c == ':') { tok = TOK_COLON; }
4217         else if (c == '[') { tok = TOK_LBRACKET; }
4218         else if (c == ']') { tok = TOK_RBRACKET; }
4219         else if (c == '(') { tok = TOK_LPAREN; }
4220         else if (c == ')') { tok = TOK_RPAREN; }
4221         else if (c == '*') { tok = TOK_STAR; }
4222         else if (c == '>') { tok = TOK_MORE; }
4223         else if (c == '<') { tok = TOK_LESS; }
4224         else if (c == '?') { tok = TOK_QUEST; }
4225         else if (c == '|') { tok = TOK_OR; }
4226         else if (c == '&') { tok = TOK_AND; }
4227         else if (c == '^') { tok = TOK_XOR; }
4228         else if (c == '+') { tok = TOK_PLUS; }
4229         else if (c == '-') { tok = TOK_MINUS; }
4230         else if (c == '/') { tok = TOK_DIV; }
4231         else if (c == '%') { tok = TOK_MOD; }
4232         else if (c == '!') { tok = TOK_BANG; }
4233         else if (c == '.') { tok = TOK_DOT; }
4234         else if (c == '~') { tok = TOK_TILDE; }
4235         else if (c == '#') { tok = TOK_MACRO; }
4236
4237         file->pos = tokp + 1;
4238         tk->tok = tok;
4239         if (tok == TOK_IDENT) {
4240                 if (state->token_base == 0) {
4241                         ident_to_keyword(state, tk);
4242                 } else {
4243                         ident_to_macro(state, tk);
4244                 }
4245         }
4246 }
4247
4248 static void next_token(struct compile_state *state, struct token *tk)
4249 {
4250         struct file_state *file;
4251         file = state->file;
4252         /* Don't return space tokens. */
4253         do {
4254                 raw_next_token(state, file, tk);
4255                 if (tk->tok == TOK_MACRO) {
4256                         /* Only match preprocessor directives at the start of a line */
4257                         const char *ptr;
4258                         for(ptr = file->line_start; spacep(*ptr); ptr++)
4259                                 ;
4260                         if (ptr != file->pos - 1) {
4261                                 tk->tok = TOK_UNKNOWN;
4262                         }
4263                 }
4264                 if (tk->tok == TOK_UNKNOWN) {
4265                         error(state, 0, "unknown token");
4266                 }
4267         } while(tk->tok == TOK_SPACE);
4268 }
4269
4270 static void check_tok(struct compile_state *state, struct token *tk, int tok)
4271 {
4272         if (tk->tok != tok) {
4273                 const char *name1, *name2;
4274                 name1 = tokens[tk->tok];
4275                 name2 = "";
4276                 if ((tk->tok == TOK_IDENT) || (tk->tok == TOK_MIDENT)) {
4277                         name2 = tk->ident->name;
4278                 }
4279                 error(state, 0, "\tfound %s %s expected %s",
4280                         name1, name2, tokens[tok]);
4281         }
4282 }
4283
4284 struct macro_arg_value {
4285         struct hash_entry *ident;
4286         unsigned char *value;
4287         size_t len;
4288 };
4289 static struct macro_arg_value *read_macro_args(
4290         struct compile_state *state, struct macro *macro, 
4291         struct file_state *file, struct token *tk)
4292 {
4293         struct macro_arg_value *argv;
4294         struct macro_arg *arg;
4295         int paren_depth;
4296         int i;
4297
4298         if (macro->argc == 0) {
4299                 do {
4300                         raw_next_token(state, file, tk);
4301                 } while(tk->tok == TOK_SPACE);
4302                 return 0;
4303         }
4304         argv = xcmalloc(sizeof(*argv) * macro->argc, "macro args");
4305         for(i = 0, arg = macro->args; arg; arg = arg->next, i++) {
4306                 argv[i].value = 0;
4307                 argv[i].len   = 0;
4308                 argv[i].ident = arg->ident;
4309         }
4310         paren_depth = 0;
4311         i = 0;
4312         
4313         for(;;) {
4314                 const char *start;
4315                 size_t len;
4316                 start = file->pos;
4317                 raw_next_token(state, file, tk);
4318                 
4319                 if (!paren_depth && (tk->tok == TOK_COMMA) &&
4320                         (argv[i].ident != state->i___VA_ARGS__)) 
4321                 {
4322                         i++;
4323                         if (i >= macro->argc) {
4324                                 error(state, 0, "too many args to %s\n",
4325                                         macro->ident->name);
4326                         }
4327                         continue;
4328                 }
4329                 
4330                 if (tk->tok == TOK_LPAREN) {
4331                         paren_depth++;
4332                 }
4333                 
4334                 if (tk->tok == TOK_RPAREN) {
4335                         if (paren_depth == 0) {
4336                                 break;
4337                         }
4338                         paren_depth--;
4339                 }
4340                 if (tk->tok == TOK_EOF) {
4341                         error(state, 0, "End of file encountered while parsing macro arguments");
4342                 }
4343                 
4344                 len = file->pos - start;
4345                 argv[i].value = xrealloc(
4346                         argv[i].value, argv[i].len + len, "macro args");
4347                 memcpy(argv[i].value + argv[i].len, start, len);
4348                 argv[i].len += len;
4349         }
4350         if (i != macro->argc -1) {
4351                 error(state, 0, "missing %s arg %d\n", 
4352                         macro->ident->name, i +2);
4353         }
4354         return argv;
4355 }
4356
4357
4358 static void free_macro_args(struct macro *macro, struct macro_arg_value *argv)
4359 {
4360         int i;
4361         for(i = 0; i < macro->argc; i++) {
4362                 xfree(argv[i].value);
4363         }
4364         xfree(argv);
4365 }
4366
4367 struct macro_buf {
4368         char *str;
4369         size_t len, pos;
4370 };
4371
4372 static void append_macro_text(struct compile_state *state,
4373         struct macro *macro, struct macro_buf *buf, 
4374         const char *fstart, size_t flen)
4375 {
4376 #if 0
4377         fprintf(state->errout, "append: `%*.*s' `%*.*s'\n",
4378                 buf->pos, buf->pos, buf->str,
4379                 flen, flen, fstart);
4380 #endif
4381         if ((buf->pos + flen) < buf->len) {
4382                 memcpy(buf->str + buf->pos, fstart, flen);
4383         } else {
4384                 buf->str = xrealloc(buf->str, buf->len + flen, macro->ident->name);
4385                 memcpy(buf->str + buf->pos, fstart, flen);
4386                 buf->len += flen;
4387         }
4388         buf->pos += flen;
4389 }
4390
4391 static int compile_macro(struct compile_state *state, 
4392         struct file_state **filep, struct token *tk);
4393
4394 static void macro_expand_args(struct compile_state *state, 
4395         struct macro *macro, struct macro_arg_value *argv, struct token *tk)
4396 {
4397         size_t i;
4398         
4399         for(i = 0; i < macro->argc; i++) {
4400                 struct file_state fmacro, *file;
4401                 struct macro_buf buf;
4402                 const char *fstart;
4403                 size_t flen;
4404
4405                 fmacro.basename    = argv[i].ident->name;
4406                 fmacro.dirname     = "";
4407                 fmacro.size        = argv[i].len;
4408                 fmacro.buf         = argv[i].value;
4409                 fmacro.pos         = fmacro.buf;
4410                 fmacro.line_start  = fmacro.buf;
4411                 fmacro.line        = 1;
4412                 fmacro.report_line = 1;
4413                 fmacro.report_name = fmacro.basename;
4414                 fmacro.report_dir  = fmacro.dirname;
4415                 fmacro.prev        = 0;
4416
4417                 buf.len = argv[i].len;
4418                 buf.str = xmalloc(buf.len, argv[i].ident->name);
4419                 buf.pos = 0;
4420
4421                 file = &fmacro;
4422                 for(;;) {
4423                         fstart = file->pos;
4424                         raw_next_token(state, file, tk);
4425                         flen = file->pos - fstart;
4426                         
4427                         if (tk->tok == TOK_EOF) {
4428                                 struct file_state *old;
4429                                 old = file;
4430                                 file = file->prev;
4431                                 if (!file) {
4432                                         break;
4433                                 }
4434                                 /* old->basename is used keep it */
4435                                 xfree(old->dirname);
4436                                 xfree(old->buf);
4437                                 xfree(old);
4438                                 continue;
4439                         }
4440                         else if (tk->ident && tk->ident->sym_define) {
4441                                 if (compile_macro(state, &file, tk)) {
4442                                         continue;
4443                                 }
4444                         }
4445
4446                         append_macro_text(state, macro, &buf,
4447                                 fstart, flen);
4448                 }
4449                         
4450                 xfree(argv[i].value);
4451                 argv[i].value = buf.str;
4452                 argv[i].len   = buf.pos;
4453         }
4454         return;
4455 }
4456
4457 static void expand_macro(struct compile_state *state,
4458         struct macro *macro, struct macro_buf *buf,
4459         struct macro_arg_value *argv, struct token *tk)
4460 {
4461         struct file_state fmacro;
4462         const char space[] = " ";
4463         const char *fstart;
4464         size_t flen;
4465         size_t i, j;
4466         fmacro.basename = macro->ident->name;
4467         fmacro.dirname  = "";
4468         fmacro.size = macro->buf_len - macro->buf_off;;
4469         fmacro.buf  = macro->buf + macro->buf_off;
4470         fmacro.pos  = fmacro.buf;
4471         fmacro.line_start = fmacro.buf;
4472         fmacro.line = 1;
4473         fmacro.report_line = 1;
4474         fmacro.report_name = fmacro.basename;
4475         fmacro.report_dir  = fmacro.dirname;
4476         fmacro.prev = 0;
4477         
4478         buf->len = macro->buf_len + 3;
4479         buf->str = xmalloc(buf->len, macro->ident->name);
4480         buf->pos = 0;
4481         
4482         fstart = fmacro.pos;
4483         raw_next_token(state, &fmacro, tk);
4484         while(tk->tok != TOK_EOF) {
4485                 flen = fmacro.pos - fstart;
4486                 switch(tk->tok) {
4487                 case TOK_IDENT:
4488                         for(i = 0; i < macro->argc; i++) {
4489                                 if (argv[i].ident == tk->ident) {
4490                                         break;
4491                                 }
4492                         }
4493                         if (i >= macro->argc) {
4494                                 break;
4495                         }
4496                         /* Substitute macro parameter */
4497                         fstart = argv[i].value;
4498                         flen   = argv[i].len;
4499                         break;
4500                 case TOK_MACRO:
4501                         if (!macro->buf_off) {
4502                                 break;
4503                         }
4504                         do {
4505                                 raw_next_token(state, &fmacro, tk);
4506                         } while(tk->tok == TOK_SPACE);
4507                         check_tok(state, tk, TOK_IDENT);
4508                         for(i = 0; i < macro->argc; i++) {
4509                                 if (argv[i].ident == tk->ident) {
4510                                         break;
4511                                 }
4512                         }
4513                         if (i >= macro->argc) {
4514                                 error(state, 0, "parameter `%s' not found",
4515                                         tk->ident->name);
4516                         }
4517                         /* Stringize token */
4518                         append_macro_text(state, macro, buf, "\"", 1);
4519                         for(j = 0; j < argv[i].len; j++) {
4520                                 char *str = argv[i].value + j;
4521                                 size_t len = 1;
4522                                 if (*str == '\\') {
4523                                         str = "\\";
4524                                         len = 2;
4525                                 } 
4526                                 else if (*str == '"') {
4527                                         str = "\\\"";
4528                                         len = 2;
4529                                 }
4530                                 append_macro_text(state, macro, buf, str, len);
4531                         }
4532                         append_macro_text(state, macro, buf, "\"", 1);
4533                         fstart = 0;
4534                         flen   = 0;
4535                         break;
4536                 case TOK_CONCATENATE:
4537                         /* Concatenate tokens */
4538                         /* Delete the previous whitespace token */
4539                         if (buf->str[buf->pos - 1] == ' ') {
4540                                 buf->pos -= 1;
4541                         }
4542                         /* Skip the next sequence of whitspace tokens */
4543                         do {
4544                                 fstart = fmacro.pos;
4545                                 raw_next_token(state, &fmacro, tk);
4546                         } while(tk->tok == TOK_SPACE);
4547                         /* Restart at the top of the loop.
4548                          * I need to process the non white space token.
4549                          */
4550                         continue;
4551                         break;
4552                 case TOK_SPACE:
4553                         /* Collapse multiple spaces into one */
4554                         if (buf->str[buf->pos - 1] != ' ') {
4555                                 fstart = space;
4556                                 flen   = 1;
4557                         } else {
4558                                 fstart = 0;
4559                                 flen   = 0;
4560                         }
4561                         break;
4562                 default:
4563                         break;
4564                 }
4565
4566                 append_macro_text(state, macro, buf, fstart, flen);
4567                 
4568                 fstart = fmacro.pos;
4569                 raw_next_token(state, &fmacro, tk);
4570         }
4571 }
4572
4573 static void tag_macro_name(struct compile_state *state,
4574         struct macro *macro, struct macro_buf *buf,
4575         struct token *tk)
4576 {
4577         /* Guard all instances of the macro name in the replacement
4578          * text from further macro expansion.
4579          */
4580         struct file_state fmacro;
4581         const char *fstart;
4582         size_t flen;
4583         fmacro.basename = macro->ident->name;
4584         fmacro.dirname  = "";
4585         fmacro.size = buf->pos;
4586         fmacro.buf  = buf->str;
4587         fmacro.pos  = fmacro.buf;
4588         fmacro.line_start = fmacro.buf;
4589         fmacro.line = 1;
4590         fmacro.report_line = 1;
4591         fmacro.report_name = fmacro.basename;
4592         fmacro.report_dir  = fmacro.dirname;
4593         fmacro.prev = 0;
4594         
4595         buf->len = macro->buf_len + 3;
4596         buf->str = xmalloc(buf->len, macro->ident->name);
4597         buf->pos = 0;
4598         
4599         fstart = fmacro.pos;
4600         raw_next_token(state, &fmacro, tk);
4601         while(tk->tok != TOK_EOF) {
4602                 flen = fmacro.pos - fstart;
4603                 if ((tk->tok == TOK_IDENT) &&
4604                         (tk->ident == macro->ident) &&
4605                         (tk->val.notmacro == 0)) {
4606                         append_macro_text(state, macro, buf, fstart, flen);
4607                         fstart = "$";
4608                         flen   = 1;
4609                 }
4610
4611                 append_macro_text(state, macro, buf, fstart, flen);
4612                 
4613                 fstart = fmacro.pos;
4614                 raw_next_token(state, &fmacro, tk);
4615         }
4616         xfree(fmacro.buf);
4617 }
4618         
4619 static int compile_macro(struct compile_state *state, 
4620         struct file_state **filep, struct token *tk)
4621 {
4622         struct file_state *file;
4623         struct hash_entry *ident;
4624         struct macro *macro;
4625         struct macro_arg_value *argv;
4626         struct macro_buf buf;
4627
4628 #if 0
4629         fprintf(state->errout, "macro: %s\n", tk->ident->name);
4630 #endif
4631         ident = tk->ident;
4632         macro = ident->sym_define;
4633
4634         /* If this token comes from a macro expansion ignore it */
4635         if (tk->val.notmacro) {
4636                 return 0;
4637         }
4638         /* If I am a function like macro and the identifier is not followed
4639          * by a left parenthesis, do nothing.
4640          */
4641         if ((macro->buf_off != 0) && !lparen_peek(state, *filep)) {
4642                 return 0;
4643         }
4644
4645         /* Read in the macro arguments */
4646         argv = 0;
4647         if (macro->buf_off) {
4648                 raw_next_token(state, *filep, tk);
4649                 check_tok(state, tk, TOK_LPAREN);
4650
4651                 argv = read_macro_args(state, macro, *filep, tk);
4652
4653                 check_tok(state, tk, TOK_RPAREN);
4654         }
4655         /* Macro expand the macro arguments */
4656         macro_expand_args(state, macro, argv, tk);
4657
4658         buf.str = 0;
4659         buf.len = 0;
4660         buf.pos = 0;
4661         if (ident == state->i___FILE__) {
4662                 buf.len = strlen(state->file->basename) + 1 + 2 + 3;
4663                 buf.str = xmalloc(buf.len, ident->name);
4664                 sprintf(buf.str, "\"%s\"", state->file->basename);
4665                 buf.pos = strlen(buf.str);
4666         }
4667         else if (ident == state->i___LINE__) {
4668                 buf.len = 30;
4669                 buf.str = xmalloc(buf.len, ident->name);
4670                 sprintf(buf.str, "%d", state->file->line);
4671                 buf.pos = strlen(buf.str);
4672         }
4673         else {
4674                 expand_macro(state, macro, &buf, argv, tk);
4675         }
4676         /* Tag the macro name with a $ so it will no longer
4677          * be regonized as a canidate for macro expansion.
4678          */
4679         tag_macro_name(state, macro, &buf, tk);
4680         append_macro_text(state, macro, &buf, "\n\0", 2);
4681
4682 #if 0
4683         fprintf(state->errout, "%s: %d -> `%*.*s'\n",
4684                 ident->name, buf.pos, buf.pos, (int)(buf.pos), buf.str);
4685 #endif
4686
4687         free_macro_args(macro, argv);
4688
4689         file = xmalloc(sizeof(*file), "file_state");
4690         file->basename = xstrdup(ident->name);
4691         file->dirname = xstrdup("");
4692         file->buf = buf.str;
4693         file->size = buf.pos - 2;
4694         file->pos = file->buf;
4695         file->line_start = file->pos;
4696         file->line = 1;
4697         file->report_line = 1;
4698         file->report_name = file->basename;
4699         file->report_dir  = file->dirname;
4700         file->macro       = 1;
4701         file->prev = *filep;
4702         *filep = file;
4703         return 1;
4704 }
4705
4706 static void eat_tokens(struct compile_state *state, int targ_tok)
4707 {
4708         if (state->eat_depth > 0) {
4709                 internal_error(state, 0, "Already eating...");
4710         }
4711         state->eat_depth = state->if_depth;
4712         state->eat_targ = targ_tok;
4713 }
4714 static int if_eat(struct compile_state *state)
4715 {
4716         return state->eat_depth > 0;
4717 }
4718 static int if_value(struct compile_state *state)
4719 {
4720         int index, offset;
4721         index = state->if_depth / CHAR_BIT;
4722         offset = state->if_depth % CHAR_BIT;
4723         return !!(state->if_bytes[index] & (1 << (offset)));
4724 }
4725 static void set_if_value(struct compile_state *state, int value) 
4726 {
4727         int index, offset;
4728         index = state->if_depth / CHAR_BIT;
4729         offset = state->if_depth % CHAR_BIT;
4730
4731         state->if_bytes[index] &= ~(1 << offset);
4732         if (value) {
4733                 state->if_bytes[index] |= (1 << offset);
4734         }
4735 }
4736 static void in_if(struct compile_state *state, const char *name)
4737 {
4738         if (state->if_depth <= 0) {
4739                 error(state, 0, "%s without #if", name);
4740         }
4741 }
4742 static void enter_if(struct compile_state *state)
4743 {
4744         state->if_depth += 1;
4745         if (state->if_depth > MAX_CPP_IF_DEPTH) {
4746                 error(state, 0, "#if depth too great");
4747         }
4748 }
4749 static void reenter_if(struct compile_state *state, const char *name)
4750 {
4751         in_if(state, name);
4752         if ((state->eat_depth == state->if_depth) &&
4753                 (state->eat_targ == TOK_MELSE)) {
4754                 state->eat_depth = 0;
4755                 state->eat_targ = 0;
4756         }
4757 }
4758 static void enter_else(struct compile_state *state, const char *name)
4759 {
4760         in_if(state, name);
4761         if ((state->eat_depth == state->if_depth) &&
4762                 (state->eat_targ == TOK_MELSE)) {
4763                 state->eat_depth = 0;
4764                 state->eat_targ = 0;
4765         }
4766 }
4767 static void exit_if(struct compile_state *state, const char *name)
4768 {
4769         in_if(state, name);
4770         if (state->eat_depth == state->if_depth) {
4771                 state->eat_depth = 0;
4772                 state->eat_targ = 0;
4773         }
4774         state->if_depth -= 1;
4775 }
4776
4777 static void cpp_token(struct compile_state *state, struct token *tk)
4778 {
4779         struct file_state *file;
4780         int rescan;
4781
4782         next_token(state, tk);
4783         do {
4784                 rescan = 0;
4785                 file = state->file;
4786                 /* Exit out of an include directive or macro call */
4787                 if ((tk->tok == TOK_EOF) && 
4788                         (state->file && state->macro_file) &&
4789                         file->prev) 
4790                 {
4791                         state->file = file->prev;
4792                         /* file->basename is used keep it */
4793                         xfree(file->dirname);
4794                         xfree(file->buf);
4795                         xfree(file);
4796                         next_token(state, tk);
4797                         rescan = 1;
4798                 }
4799         } while(rescan);
4800 }
4801
4802 static void preprocess(struct compile_state *state, struct token *tk);
4803
4804 static void token(struct compile_state *state, struct token *tk)
4805 {
4806         int rescan;
4807         cpp_token(state, tk);
4808         do {
4809                 rescan = 0;
4810                 /* Process a macro directive */
4811                 if (tk->tok == TOK_MACRO) {
4812                         preprocess(state, tk);
4813                         rescan = 1;
4814                 }
4815                 /* Expand a macro call */
4816                 else if (tk->ident && tk->ident->sym_define) {
4817                         rescan = compile_macro(state, &state->file, tk);
4818                         if (rescan) {
4819                                 cpp_token(state, tk);
4820                         }
4821                 }
4822                 /* Eat tokens disabled by the preprocessor (Unless we are parsing a preprocessor directive */
4823                 else if (if_eat(state) && (state->token_base == 0)) {
4824                         cpp_token(state, tk);
4825                         rescan = 1;
4826                 }
4827                 /* Make certain EOL only shows up in preprocessor directives */
4828                 else if ((tk->tok == TOK_EOL) && (state->token_base == 0)) {
4829                         cpp_token(state, tk);
4830                         rescan = 1;
4831                 }
4832         } while(rescan);
4833 }
4834
4835
4836 static inline struct token *get_token(struct compile_state *state, int offset)
4837 {
4838         int index;
4839         index = state->token_base + offset;
4840         if (index >= sizeof(state->token)/sizeof(state->token[0])) {
4841                 internal_error(state, 0, "token array to small");
4842         }
4843         return &state->token[index];
4844 }
4845
4846 static struct token *do_eat_token(struct compile_state *state, int tok)
4847 {
4848         struct token *tk;
4849         int i;
4850         check_tok(state, get_token(state, 1), tok);
4851         
4852         /* Free the old token value */
4853         tk = get_token(state, 0);
4854         if (tk->str_len) {
4855                 memset((void *)tk->val.str, -1, tk->str_len);
4856                 xfree(tk->val.str);
4857         }
4858         /* Overwrite the old token with newer tokens */
4859         for(i = state->token_base; i < sizeof(state->token)/sizeof(state->token[0]) - 1; i++) {
4860                 state->token[i] = state->token[i + 1];
4861         }
4862         /* Clear the last token */
4863         memset(&state->token[i], 0, sizeof(state->token[i]));
4864         state->token[i].tok = -1;
4865
4866         /* Return the token */
4867         return tk;
4868 }
4869
4870 static int cpp_peek(struct compile_state *state)
4871 {
4872         struct token *tk1;
4873         tk1 = get_token(state, 1);
4874         if (tk1->tok == -1) {
4875                 cpp_token(state, tk1);
4876         }
4877         return tk1->tok;
4878 }
4879
4880 static struct token *cpp_eat(struct compile_state *state, int tok)
4881 {
4882         cpp_peek(state);
4883         return do_eat_token(state, tok);
4884 }
4885
4886 static int peek(struct compile_state *state)
4887 {
4888         struct token *tk1;
4889         tk1 = get_token(state, 1);
4890         if (tk1->tok == -1) {
4891                 token(state, tk1);
4892         }
4893         return tk1->tok;
4894 }
4895
4896 static int peek2(struct compile_state *state)
4897 {
4898         struct token *tk1, *tk2;
4899         tk1 = get_token(state, 1);
4900         tk2 = get_token(state, 2);
4901         if (tk1->tok == -1) {
4902                 token(state, tk1);
4903         }
4904         if (tk2->tok == -1) {
4905                 token(state, tk2);
4906         }
4907         return tk2->tok;
4908 }
4909
4910 static struct token *eat(struct compile_state *state, int tok)
4911 {
4912         peek(state);
4913         return do_eat_token(state, tok);
4914 }
4915
4916 static void compile_file(struct compile_state *state, const char *filename, int local)
4917 {
4918         char cwd[MAX_CWD_SIZE];
4919         const char *subdir, *base;
4920         int subdir_len;
4921         struct file_state *file;
4922         char *basename;
4923         file = xmalloc(sizeof(*file), "file_state");
4924
4925         base = strrchr(filename, '/');
4926         subdir = filename;
4927         if (base != 0) {
4928                 subdir_len = base - filename;
4929                 base++;
4930         }
4931         else {
4932                 base = filename;
4933                 subdir_len = 0;
4934         }
4935         basename = xmalloc(strlen(base) +1, "basename");
4936         strcpy(basename, base);
4937         file->basename = basename;
4938
4939         if (getcwd(cwd, sizeof(cwd)) == 0) {
4940                 die("cwd buffer to small");
4941         }
4942         if (subdir[0] == '/') {
4943                 file->dirname = xmalloc(subdir_len + 1, "dirname");
4944                 memcpy(file->dirname, subdir, subdir_len);
4945                 file->dirname[subdir_len] = '\0';
4946         }
4947         else {
4948                 const char *dir;
4949                 int dirlen;
4950                 const char **path;
4951                 /* Find the appropriate directory... */
4952                 dir = 0;
4953                 if (!state->file && exists(cwd, filename)) {
4954                         dir = cwd;
4955                 }
4956                 if (local && state->file && exists(state->file->dirname, filename)) {
4957                         dir = state->file->dirname;
4958                 }
4959                 for(path = state->compiler->include_paths; !dir && *path; path++) {
4960                         if (exists(*path, filename)) {
4961                                 dir = *path;
4962                         }
4963                 }
4964                 if (!dir) {
4965                         error(state, 0, "Cannot find `%s'\n", filename);
4966                 }
4967                 dirlen = strlen(dir);
4968                 file->dirname = xmalloc(dirlen + 1 + subdir_len + 1, "dirname");
4969                 memcpy(file->dirname, dir, dirlen);
4970                 file->dirname[dirlen] = '/';
4971                 memcpy(file->dirname + dirlen + 1, subdir, subdir_len);
4972                 file->dirname[dirlen + 1 + subdir_len] = '\0';
4973         }
4974         file->buf = slurp_file(file->dirname, file->basename, &file->size);
4975
4976         file->pos = file->buf;
4977         file->line_start = file->pos;
4978         file->line = 1;
4979
4980         file->report_line = 1;
4981         file->report_name = file->basename;
4982         file->report_dir  = file->dirname;
4983         file->macro       = 0;
4984
4985         file->prev = state->file;
4986         state->file = file;
4987         
4988         process_trigraphs(state);
4989         splice_lines(state);
4990 }
4991
4992 static struct triple *constant_expr(struct compile_state *state);
4993 static void integral(struct compile_state *state, struct triple *def);
4994
4995 static int mcexpr(struct compile_state *state)
4996 {
4997         struct triple *cvalue;
4998         cvalue = constant_expr(state);
4999         integral(state, cvalue);
5000         if (cvalue->op != OP_INTCONST) {
5001                 error(state, 0, "integer constant expected");
5002         }
5003         return cvalue->u.cval != 0;
5004 }
5005
5006 static void preprocess(struct compile_state *state, struct token *current_token)
5007 {
5008         /* Doing much more with the preprocessor would require
5009          * a parser and a major restructuring.
5010          * Postpone that for later.
5011          */
5012         struct file_state *file;
5013         int old_token_base;
5014         int line;
5015         int tok;
5016         
5017         file = state->file;
5018         state->macro_line = line = file->line;
5019         state->macro_file = file;
5020
5021         old_token_base = state->token_base;
5022         state->token_base = current_token - state->token;
5023
5024         tok = cpp_peek(state);
5025         switch(tok) {
5026         case TOK_LIT_INT:
5027         {
5028                 struct token *tk;
5029                 int override_line;
5030                 tk = cpp_eat(state, TOK_LIT_INT);
5031                 override_line = strtoul(tk->val.str, 0, 10);
5032                 /* I have a cpp line marker parse it */
5033                 if (cpp_peek(state) == TOK_LIT_STRING) {
5034                         const char *token, *base;
5035                         char *name, *dir;
5036                         int name_len, dir_len;
5037                         tk = cpp_eat(state, TOK_LIT_STRING);
5038                         name = xmalloc(tk->str_len, "report_name");
5039                         token = tk->val.str + 1;
5040                         base = strrchr(token, '/');
5041                         name_len = tk->str_len -2;
5042                         if (base != 0) {
5043                                 dir_len = base - token;
5044                                 base++;
5045                                 name_len -= base - token;
5046                         } else {
5047                                 dir_len = 0;
5048                                 base = token;
5049                         }
5050                         memcpy(name, base, name_len);
5051                         name[name_len] = '\0';
5052                         dir = xmalloc(dir_len + 1, "report_dir");
5053                         memcpy(dir, token, dir_len);
5054                         dir[dir_len] = '\0';
5055                         file->report_line = override_line - 1;
5056                         file->report_name = name;
5057                         file->report_dir = dir;
5058                         file->macro      = 0;
5059                 }
5060                 break;
5061         }
5062         case TOK_MLINE:
5063         {
5064                 struct token *tk;
5065                 cpp_eat(state, TOK_MLINE);
5066                 tk = eat(state, TOK_LIT_INT);
5067                 file->report_line = strtoul(tk->val.str, 0, 10) -1;
5068                 if (cpp_peek(state) == TOK_LIT_STRING) {
5069                         const char *token, *base;
5070                         char *name, *dir;
5071                         int name_len, dir_len;
5072                         tk = cpp_eat(state, TOK_LIT_STRING);
5073                         name = xmalloc(tk->str_len, "report_name");
5074                         token = tk->val.str + 1;
5075                         base = strrchr(token, '/');
5076                         name_len = tk->str_len - 2;
5077                         if (base != 0) {
5078                                 dir_len = base - token;
5079                                 base++;
5080                                 name_len -= base - token;
5081                         } else {
5082                                 dir_len = 0;
5083                                 base = token;
5084                         }
5085                         memcpy(name, base, name_len);
5086                         name[name_len] = '\0';
5087                         dir = xmalloc(dir_len + 1, "report_dir");
5088                         memcpy(dir, token, dir_len);
5089                         dir[dir_len] = '\0';
5090                         file->report_name = name;
5091                         file->report_dir = dir;
5092                         file->macro      = 0;
5093                 }
5094                 break;
5095         }
5096         case TOK_MUNDEF:
5097         {
5098                 struct hash_entry *ident;
5099                 cpp_eat(state, TOK_MUNDEF);
5100                 if (if_eat(state))  /* quit early when #if'd out */
5101                         break;
5102                 
5103                 ident = cpp_eat(state, TOK_MIDENT)->ident;
5104
5105                 undef_macro(state, ident);
5106                 break;
5107         }
5108         case TOK_MPRAGMA:
5109                 cpp_eat(state, TOK_MPRAGMA);
5110                 if (if_eat(state))  /* quit early when #if'd out */
5111                         break;
5112                 warning(state, 0, "Ignoring pragma"); 
5113                 break;
5114         case TOK_MELIF:
5115                 cpp_eat(state, TOK_MELIF);
5116                 reenter_if(state, "#elif");
5117                 if (if_eat(state))   /* quit early when #if'd out */
5118                         break;
5119                 /* If the #if was taken the #elif just disables the following code */
5120                 if (if_value(state)) {
5121                         eat_tokens(state, TOK_MENDIF);
5122                 }
5123                 /* If the previous #if was not taken see if the #elif enables the 
5124                  * trailing code.
5125                  */
5126                 else {
5127                         set_if_value(state, mcexpr(state));
5128                         if (!if_value(state)) {
5129                                 eat_tokens(state, TOK_MELSE);
5130                         }
5131                 }
5132                 break;
5133         case TOK_MIF:
5134                 cpp_eat(state, TOK_MIF);
5135                 enter_if(state);
5136                 if (if_eat(state))  /* quit early when #if'd out */
5137                         break;
5138                 set_if_value(state, mcexpr(state));
5139                 if (!if_value(state)) {
5140                         eat_tokens(state, TOK_MELSE);
5141                 }
5142                 break;
5143         case TOK_MIFNDEF:
5144         {
5145                 struct hash_entry *ident;
5146
5147                 cpp_eat(state, TOK_MIFNDEF);
5148                 enter_if(state);
5149                 if (if_eat(state))  /* quit early when #if'd out */
5150                         break;
5151                 ident = cpp_eat(state, TOK_MIDENT)->ident;
5152                 set_if_value(state, ident->sym_define == 0);
5153                 if (!if_value(state)) {
5154                         eat_tokens(state, TOK_MELSE);
5155                 }
5156                 break;
5157         }
5158         case TOK_MIFDEF:
5159         {
5160                 struct hash_entry *ident;
5161                 cpp_eat(state, TOK_MIFDEF);
5162                 enter_if(state);
5163                 if (if_eat(state))  /* quit early when #if'd out */
5164                         break;
5165                 ident = cpp_eat(state, TOK_MIDENT)->ident;
5166                 set_if_value(state, ident->sym_define != 0);
5167                 if (!if_value(state)) {
5168                         eat_tokens(state, TOK_MELSE);
5169                 }
5170                 break;
5171         }
5172         case TOK_MELSE:
5173                 cpp_eat(state, TOK_MELSE);
5174                 enter_else(state, "#else");
5175                 if (!if_eat(state) && if_value(state)) {
5176                         eat_tokens(state, TOK_MENDIF);
5177                 }
5178                 break;
5179         case TOK_MENDIF:
5180                 cpp_eat(state, TOK_MENDIF);
5181                 exit_if(state, "#endif");
5182                 break;
5183         case TOK_MDEFINE:
5184         {
5185                 struct hash_entry *ident;
5186                 struct macro_arg *args, **larg;
5187                 const char *start, *mstart, *ptr;
5188
5189                 cpp_eat(state, TOK_MDEFINE);
5190                 if (if_eat(state))  /* quit early when #if'd out */
5191                         break;
5192
5193                 ident = cpp_eat(state, TOK_MIDENT)->ident;
5194                 args = 0;
5195                 larg = &args;
5196
5197                 /* Remember the start of the macro */
5198                 start = file->pos;
5199
5200                 /* Find the end of the line. */
5201                 for(ptr = start; *ptr != '\n'; ptr++)  
5202                         ;
5203
5204                 /* remove the trailing whitespace */
5205                 ptr-=1;
5206                 while(spacep(*ptr)) {
5207                         ptr--;
5208                 }
5209
5210                 /* Remove leading whitespace */
5211                 while(spacep(*start) && (start < ptr)) {
5212                         start++;
5213                 }
5214                 /* Remember where the macro starts */
5215                 mstart = start;
5216
5217                 /* Parse macro parameters */
5218                 if (lparen_peek(state, state->file)) {
5219                         cpp_eat(state, TOK_LPAREN);
5220                         
5221                         for(;;) {
5222                                 struct macro_arg *narg, *arg;
5223                                 struct hash_entry *aident;
5224                                 int tok;
5225
5226                                 tok = cpp_peek(state);
5227                                 if (!args && (tok == TOK_RPAREN)) {
5228                                         break;
5229                                 }
5230                                 else if (tok == TOK_DOTS) {
5231                                         cpp_eat(state, TOK_DOTS);
5232                                         aident = state->i___VA_ARGS__;
5233                                 } 
5234                                 else {
5235                                         aident = cpp_eat(state, TOK_MIDENT)->ident;
5236                                 }
5237                                 
5238                                 narg = xcmalloc(sizeof(*arg), "macro arg");
5239                                 narg->ident = aident;
5240
5241                                 /* Verify I don't have a duplicate identifier */
5242                                 for(arg = args; arg; arg = arg->next) {
5243                                         if (arg->ident == narg->ident) {
5244                                                 error(state, 0, "Duplicate macro arg `%s'",
5245                                                         narg->ident->name);
5246                                         }
5247                                 }
5248                                 /* Add the new argument to the end of the list */
5249                                 *larg = narg;
5250                                 larg = &narg->next;
5251
5252                                 if ((aident == state->i___VA_ARGS__) ||
5253                                         (cpp_peek(state) != TOK_COMMA)) {
5254                                         break;
5255                                 }
5256                                 cpp_eat(state, TOK_COMMA);
5257                         }
5258                         cpp_eat(state, TOK_RPAREN);
5259
5260                         /* Get the start of the macro body */
5261                         mstart = file->pos;
5262
5263                         /* Remove leading whitespace */
5264                         while(spacep(*mstart) && (mstart < ptr)) {
5265                                 mstart++;
5266                         }
5267                 }
5268                 define_macro(state, ident, start, ptr - start + 1, 
5269                         mstart - start, args);
5270                 break;
5271         }
5272         case TOK_MERROR:
5273         {
5274                 const char *end;
5275                 int len;
5276                 
5277                 cpp_eat(state, TOK_MERROR);
5278                 /* Find the end of the line */
5279                 for(end = file->pos; *end != '\n'; end++)
5280                         ;
5281                 len = (end - file->pos);
5282                 if (!if_eat(state)) {
5283                         error(state, 0, "%*.*s", len, len, file->pos);
5284                 }
5285                 file->pos = end;
5286                 break;
5287         }
5288         case TOK_MWARNING:
5289         {
5290                 const char *end;
5291                 int len;
5292                 
5293                 cpp_eat(state, TOK_MWARNING);
5294                 /* Find the end of the line */
5295                 for(end = file->pos; *end != '\n'; end++)
5296                         ;
5297                 len = (end - file->pos);
5298                 if (!if_eat(state)) {
5299                         warning(state, 0, "%*.*s", len, len, file->pos);
5300                 }
5301                 file->pos = end;
5302                 break;
5303         }
5304         case TOK_MINCLUDE:
5305         {
5306                 char *name;
5307                 int local;
5308                 local = 0;
5309                 name = 0;
5310
5311                 cpp_eat(state, TOK_MINCLUDE);
5312                 tok = peek(state);
5313                 if (tok == TOK_LIT_STRING) {
5314                         struct token *tk;
5315                         const char *token;
5316                         int name_len;
5317                         tk = eat(state, TOK_LIT_STRING);
5318                         name = xmalloc(tk->str_len, "include");
5319                         token = tk->val.str +1;
5320                         name_len = tk->str_len -2;
5321                         if (*token == '"') {
5322                                 token++;
5323                                 name_len--;
5324                         }
5325                         memcpy(name, token, name_len);
5326                         name[name_len] = '\0';
5327                         local = 1;
5328                 }
5329                 else if (tok == TOK_LESS) {
5330                         const char *start, *end;
5331                         eat(state, TOK_LESS);
5332                         start = file->pos;
5333                         for(end = start; *end != '\n'; end++) {
5334                                 if (*end == '>') {
5335                                         break;
5336                                 }
5337                         }
5338                         if (*end == '\n') {
5339                                 error(state, 0, "Unterminated include directive");
5340                         }
5341                         name = xmalloc(end - start + 1, "include");
5342                         memcpy(name, start, end - start);
5343                         name[end - start] = '\0';
5344                         file->pos = end;
5345                         local = 0;
5346                         eat(state, TOK_MORE);
5347                 }
5348                 else {
5349                         error(state, 0, "Invalid include directive");
5350                 }
5351                 /* Error if there are any tokens after the include */
5352                 if (cpp_peek(state) != TOK_EOL) {
5353                         error(state, 0, "garbage after include directive");
5354                 }
5355                 if (!if_eat(state)) {
5356                         compile_file(state, name, local);
5357                 }
5358                 xfree(name);
5359                 break;
5360         }
5361         case TOK_EOL:
5362                 /* Ignore # without a follwing ident */
5363                 break;
5364         default:
5365         {
5366                 const char *name1, *name2;
5367                 name1 = tokens[tok];
5368                 name2 = "";
5369                 if (tok == TOK_MIDENT) {
5370                         name2 = get_token(state, 1)->ident->name;
5371                 }
5372                 error(state, 0, "Invalid preprocessor directive: %s %s", 
5373                         name1, name2);
5374                 break;
5375         }
5376         }
5377         /* Consume the rest of the macro line */
5378         do {
5379                 tok = cpp_peek(state);
5380                 cpp_eat(state, tok);
5381         } while((tok != TOK_EOF) && (tok != TOK_EOL));
5382         state->token_base = old_token_base;
5383         return;
5384 }
5385
5386 /* Type helper functions */
5387
5388 static struct type *new_type(
5389         unsigned int type, struct type *left, struct type *right)
5390 {
5391         struct type *result;
5392         result = xmalloc(sizeof(*result), "type");
5393         result->type = type;
5394         result->left = left;
5395         result->right = right;
5396         result->field_ident = 0;
5397         result->type_ident = 0;
5398         result->elements = 0;
5399         return result;
5400 }
5401
5402 static struct type *clone_type(unsigned int specifiers, struct type *old)
5403 {
5404         struct type *result;
5405         result = xmalloc(sizeof(*result), "type");
5406         memcpy(result, old, sizeof(*result));
5407         result->type &= TYPE_MASK;
5408         result->type |= specifiers;
5409         return result;
5410 }
5411
5412 static struct type *dup_type(struct compile_state *state, struct type *orig)
5413 {
5414         struct type *new;
5415         new = xcmalloc(sizeof(*new), "type");
5416         new->type = orig->type;
5417         new->field_ident = orig->field_ident;
5418         new->type_ident  = orig->type_ident;
5419         new->elements    = orig->elements;
5420         if (orig->left) {
5421                 new->left = dup_type(state, orig->left);
5422         }
5423         if (orig->right) {
5424                 new->right = dup_type(state, orig->right);
5425         }
5426         return new;
5427 }
5428
5429
5430 static struct type *invalid_type(struct compile_state *state, struct type *type)
5431 {
5432         struct type *invalid, *member;
5433         invalid = 0;
5434         if (!type) {
5435                 internal_error(state, 0, "type missing?");
5436         }
5437         switch(type->type & TYPE_MASK) {
5438         case TYPE_VOID:
5439         case TYPE_CHAR:         case TYPE_UCHAR:
5440         case TYPE_SHORT:        case TYPE_USHORT:
5441         case TYPE_INT:          case TYPE_UINT:
5442         case TYPE_LONG:         case TYPE_ULONG:
5443         case TYPE_LLONG:        case TYPE_ULLONG:
5444         case TYPE_POINTER:
5445         case TYPE_ENUM:
5446                 break;
5447         case TYPE_BITFIELD:
5448                 invalid = invalid_type(state, type->left);
5449                 break;
5450         case TYPE_ARRAY:
5451                 invalid = invalid_type(state, type->left);
5452                 break;
5453         case TYPE_STRUCT:
5454         case TYPE_TUPLE:
5455                 member = type->left;
5456                 while(member && (invalid == 0) && 
5457                         ((member->type & TYPE_MASK) == TYPE_PRODUCT)) {
5458                         invalid = invalid_type(state, member->left);
5459                         member = member->right;
5460                 }
5461                 if (!invalid) {
5462                         invalid = invalid_type(state, member);
5463                 }
5464                 break;
5465         case TYPE_UNION:
5466         case TYPE_JOIN:
5467                 member = type->left;
5468                 while(member && (invalid == 0) &&
5469                         ((member->type & TYPE_MASK) == TYPE_OVERLAP)) {
5470                         invalid = invalid_type(state, member->left);
5471                         member = member->right;
5472                 }
5473                 if (!invalid) {
5474                         invalid = invalid_type(state, member);
5475                 }
5476                 break;
5477         default:
5478                 invalid = type;
5479                 break;
5480         }
5481         return invalid;
5482         
5483 }
5484
5485 #define MASK_UCHAR(X)    ((X) & ((ulong_t)0xff))
5486 #define MASK_USHORT(X)   ((X) & (((ulong_t)1 << (SIZEOF_SHORT)) - 1))
5487 static inline ulong_t mask_uint(ulong_t x)
5488 {
5489         if (SIZEOF_INT < SIZEOF_LONG) {
5490                 ulong_t mask = (((ulong_t)1) << ((ulong_t)(SIZEOF_INT))) -1;
5491                 x &= mask;
5492         }
5493         return x;
5494 }
5495 #define MASK_UINT(X)      (mask_uint(X))
5496 #define MASK_ULONG(X)    (X)
5497
5498 static struct type void_type    = { .type  = TYPE_VOID };
5499 static struct type char_type    = { .type  = TYPE_CHAR };
5500 static struct type uchar_type   = { .type  = TYPE_UCHAR };
5501 static struct type short_type   = { .type  = TYPE_SHORT };
5502 static struct type ushort_type  = { .type  = TYPE_USHORT };
5503 static struct type int_type     = { .type  = TYPE_INT };
5504 static struct type uint_type    = { .type  = TYPE_UINT };
5505 static struct type long_type    = { .type  = TYPE_LONG };
5506 static struct type ulong_type   = { .type  = TYPE_ULONG };
5507 static struct type unknown_type = { .type  = TYPE_UNKNOWN };
5508
5509 static struct type void_ptr_type  = {
5510         .type = TYPE_POINTER,
5511         .left = &void_type,
5512 };
5513
5514 static struct type void_func_type = { 
5515         .type  = TYPE_FUNCTION,
5516         .left  = &void_type,
5517         .right = &void_type,
5518 };
5519
5520 static size_t bits_to_bytes(size_t size)
5521 {
5522         return (size + SIZEOF_CHAR - 1)/SIZEOF_CHAR;
5523 }
5524
5525 static struct triple *variable(struct compile_state *state, struct type *type)
5526 {
5527         struct triple *result;
5528         if ((type->type & STOR_MASK) != STOR_PERM) {
5529                 result = triple(state, OP_ADECL, type, 0, 0);
5530                 generate_lhs_pieces(state, result);
5531         }
5532         else {
5533                 result = triple(state, OP_SDECL, type, 0, 0);
5534         }
5535         return result;
5536 }
5537
5538 static void stor_of(FILE *fp, struct type *type)
5539 {
5540         switch(type->type & STOR_MASK) {
5541         case STOR_AUTO:
5542                 fprintf(fp, "auto ");
5543                 break;
5544         case STOR_STATIC:
5545                 fprintf(fp, "static ");
5546                 break;
5547         case STOR_LOCAL:
5548                 fprintf(fp, "local ");
5549                 break;
5550         case STOR_EXTERN:
5551                 fprintf(fp, "extern ");
5552                 break;
5553         case STOR_REGISTER:
5554                 fprintf(fp, "register ");
5555                 break;
5556         case STOR_TYPEDEF:
5557                 fprintf(fp, "typedef ");
5558                 break;
5559         case STOR_INLINE | STOR_LOCAL:
5560                 fprintf(fp, "inline ");
5561                 break;
5562         case STOR_INLINE | STOR_STATIC:
5563                 fprintf(fp, "static inline");
5564                 break;
5565         case STOR_INLINE | STOR_EXTERN:
5566                 fprintf(fp, "extern inline");
5567                 break;
5568         default:
5569                 fprintf(fp, "stor:%x", type->type & STOR_MASK);
5570                 break;
5571         }
5572 }
5573 static void qual_of(FILE *fp, struct type *type)
5574 {
5575         if (type->type & QUAL_CONST) {
5576                 fprintf(fp, " const");
5577         }
5578         if (type->type & QUAL_VOLATILE) {
5579                 fprintf(fp, " volatile");
5580         }
5581         if (type->type & QUAL_RESTRICT) {
5582                 fprintf(fp, " restrict");
5583         }
5584 }
5585
5586 static void name_of(FILE *fp, struct type *type)
5587 {
5588         unsigned int base_type;
5589         base_type = type->type & TYPE_MASK;
5590         if ((base_type != TYPE_PRODUCT) && (base_type != TYPE_OVERLAP)) {
5591                 stor_of(fp, type);
5592         }
5593         switch(base_type) {
5594         case TYPE_VOID:
5595                 fprintf(fp, "void");
5596                 qual_of(fp, type);
5597                 break;
5598         case TYPE_CHAR:
5599                 fprintf(fp, "signed char");
5600                 qual_of(fp, type);
5601                 break;
5602         case TYPE_UCHAR:
5603                 fprintf(fp, "unsigned char");
5604                 qual_of(fp, type);
5605                 break;
5606         case TYPE_SHORT:
5607                 fprintf(fp, "signed short");
5608                 qual_of(fp, type);
5609                 break;
5610         case TYPE_USHORT:
5611                 fprintf(fp, "unsigned short");
5612                 qual_of(fp, type);
5613                 break;
5614         case TYPE_INT:
5615                 fprintf(fp, "signed int");
5616                 qual_of(fp, type);
5617                 break;
5618         case TYPE_UINT:
5619                 fprintf(fp, "unsigned int");
5620                 qual_of(fp, type);
5621                 break;
5622         case TYPE_LONG:
5623                 fprintf(fp, "signed long");
5624                 qual_of(fp, type);
5625                 break;
5626         case TYPE_ULONG:
5627                 fprintf(fp, "unsigned long");
5628                 qual_of(fp, type);
5629                 break;
5630         case TYPE_POINTER:
5631                 name_of(fp, type->left);
5632                 fprintf(fp, " * ");
5633                 qual_of(fp, type);
5634                 break;
5635         case TYPE_PRODUCT:
5636                 name_of(fp, type->left);
5637                 fprintf(fp, ", ");
5638                 name_of(fp, type->right);
5639                 break;
5640         case TYPE_OVERLAP:
5641                 name_of(fp, type->left);
5642                 fprintf(fp, ",| ");
5643                 name_of(fp, type->right);
5644                 break;
5645         case TYPE_ENUM:
5646                 fprintf(fp, "enum %s", 
5647                         (type->type_ident)? type->type_ident->name : "");
5648                 qual_of(fp, type);
5649                 break;
5650         case TYPE_STRUCT:
5651                 fprintf(fp, "struct %s { ", 
5652                         (type->type_ident)? type->type_ident->name : "");
5653                 name_of(fp, type->left);
5654                 fprintf(fp, " } ");
5655                 qual_of(fp, type);
5656                 break;
5657         case TYPE_UNION:
5658                 fprintf(fp, "union %s { ", 
5659                         (type->type_ident)? type->type_ident->name : "");
5660                 name_of(fp, type->left);
5661                 fprintf(fp, " } ");
5662                 qual_of(fp, type);
5663                 break;
5664         case TYPE_FUNCTION:
5665                 name_of(fp, type->left);
5666                 fprintf(fp, " (*)(");
5667                 name_of(fp, type->right);
5668                 fprintf(fp, ")");
5669                 break;
5670         case TYPE_ARRAY:
5671                 name_of(fp, type->left);
5672                 fprintf(fp, " [%ld]", (long)(type->elements));
5673                 break;
5674         case TYPE_TUPLE:
5675                 fprintf(fp, "tuple { "); 
5676                 name_of(fp, type->left);
5677                 fprintf(fp, " } ");
5678                 qual_of(fp, type);
5679                 break;
5680         case TYPE_JOIN:
5681                 fprintf(fp, "join { ");
5682                 name_of(fp, type->left);
5683                 fprintf(fp, " } ");
5684                 qual_of(fp, type);
5685                 break;
5686         case TYPE_BITFIELD:
5687                 name_of(fp, type->left);
5688                 fprintf(fp, " : %d ", type->elements);
5689                 qual_of(fp, type);
5690                 break;
5691         case TYPE_UNKNOWN:
5692                 fprintf(fp, "unknown_t");
5693                 break;
5694         default:
5695                 fprintf(fp, "????: %x", base_type);
5696                 break;
5697         }
5698         if (type->field_ident && type->field_ident->name) {
5699                 fprintf(fp, " .%s", type->field_ident->name);
5700         }
5701 }
5702
5703 static size_t align_of(struct compile_state *state, struct type *type)
5704 {
5705         size_t align;
5706         align = 0;
5707         switch(type->type & TYPE_MASK) {
5708         case TYPE_VOID:
5709                 align = 1;
5710                 break;
5711         case TYPE_BITFIELD:
5712                 align = 1;
5713                 break;
5714         case TYPE_CHAR:
5715         case TYPE_UCHAR:
5716                 align = ALIGNOF_CHAR;
5717                 break;
5718         case TYPE_SHORT:
5719         case TYPE_USHORT:
5720                 align = ALIGNOF_SHORT;
5721                 break;
5722         case TYPE_INT:
5723         case TYPE_UINT:
5724         case TYPE_ENUM:
5725                 align = ALIGNOF_INT;
5726                 break;
5727         case TYPE_LONG:
5728         case TYPE_ULONG:
5729                 align = ALIGNOF_LONG;
5730                 break;
5731         case TYPE_POINTER:
5732                 align = ALIGNOF_POINTER;
5733                 break;
5734         case TYPE_PRODUCT:
5735         case TYPE_OVERLAP:
5736         {
5737                 size_t left_align, right_align;
5738                 left_align  = align_of(state, type->left);
5739                 right_align = align_of(state, type->right);
5740                 align = (left_align >= right_align) ? left_align : right_align;
5741                 break;
5742         }
5743         case TYPE_ARRAY:
5744                 align = align_of(state, type->left);
5745                 break;
5746         case TYPE_STRUCT:
5747         case TYPE_TUPLE:
5748         case TYPE_UNION:
5749         case TYPE_JOIN:
5750                 align = align_of(state, type->left);
5751                 break;
5752         default:
5753                 error(state, 0, "alignof not yet defined for type\n");
5754                 break;
5755         }
5756         return align;
5757 }
5758
5759 static size_t reg_align_of(struct compile_state *state, struct type *type)
5760 {
5761         size_t align;
5762         align = 0;
5763         switch(type->type & TYPE_MASK) {
5764         case TYPE_VOID:
5765                 align = 1;
5766                 break;
5767         case TYPE_BITFIELD:
5768                 align = 1;
5769                 break;
5770         case TYPE_CHAR:
5771         case TYPE_UCHAR:
5772                 align = REG_ALIGNOF_CHAR;
5773                 break;
5774         case TYPE_SHORT:
5775         case TYPE_USHORT:
5776                 align = REG_ALIGNOF_SHORT;
5777                 break;
5778         case TYPE_INT:
5779         case TYPE_UINT:
5780         case TYPE_ENUM:
5781                 align = REG_ALIGNOF_INT;
5782                 break;
5783         case TYPE_LONG:
5784         case TYPE_ULONG:
5785                 align = REG_ALIGNOF_LONG;
5786                 break;
5787         case TYPE_POINTER:
5788                 align = REG_ALIGNOF_POINTER;
5789                 break;
5790         case TYPE_PRODUCT:
5791         case TYPE_OVERLAP:
5792         {
5793                 size_t left_align, right_align;
5794                 left_align  = reg_align_of(state, type->left);
5795                 right_align = reg_align_of(state, type->right);
5796                 align = (left_align >= right_align) ? left_align : right_align;
5797                 break;
5798         }
5799         case TYPE_ARRAY:
5800                 align = reg_align_of(state, type->left);
5801                 break;
5802         case TYPE_STRUCT:
5803         case TYPE_UNION:
5804         case TYPE_TUPLE:
5805         case TYPE_JOIN:
5806                 align = reg_align_of(state, type->left);
5807                 break;
5808         default:
5809                 error(state, 0, "alignof not yet defined for type\n");
5810                 break;
5811         }
5812         return align;
5813 }
5814
5815 static size_t align_of_in_bytes(struct compile_state *state, struct type *type)
5816 {
5817         return bits_to_bytes(align_of(state, type));
5818 }
5819 static size_t size_of(struct compile_state *state, struct type *type);
5820 static size_t reg_size_of(struct compile_state *state, struct type *type);
5821
5822 static size_t needed_padding(struct compile_state *state, 
5823         struct type *type, size_t offset)
5824 {
5825         size_t padding, align;
5826         align = align_of(state, type);
5827         /* Align to the next machine word if the bitfield does completely
5828          * fit into the current word.
5829          */
5830         if ((type->type & TYPE_MASK) == TYPE_BITFIELD) {
5831                 size_t size;
5832                 size = size_of(state, type);
5833                 if ((offset + type->elements)/size != offset/size) {
5834                         align = size;
5835                 }
5836         }
5837         padding = 0;
5838         if (offset % align) {
5839                 padding = align - (offset % align);
5840         }
5841         return padding;
5842 }
5843
5844 static size_t reg_needed_padding(struct compile_state *state, 
5845         struct type *type, size_t offset)
5846 {
5847         size_t padding, align;
5848         align = reg_align_of(state, type);
5849         /* Align to the next register word if the bitfield does completely
5850          * fit into the current register.
5851          */
5852         if (((type->type & TYPE_MASK) == TYPE_BITFIELD) &&
5853                 (((offset + type->elements)/REG_SIZEOF_REG) != (offset/REG_SIZEOF_REG))) 
5854         {
5855                 align = REG_SIZEOF_REG;
5856         }
5857         padding = 0;
5858         if (offset % align) {
5859                 padding = align - (offset % align);
5860         }
5861         return padding;
5862 }
5863
5864 static size_t size_of(struct compile_state *state, struct type *type)
5865 {
5866         size_t size;
5867         size = 0;
5868         switch(type->type & TYPE_MASK) {
5869         case TYPE_VOID:
5870                 size = 0;
5871                 break;
5872         case TYPE_BITFIELD:
5873                 size = type->elements;
5874                 break;
5875         case TYPE_CHAR:
5876         case TYPE_UCHAR:
5877                 size = SIZEOF_CHAR;
5878                 break;
5879         case TYPE_SHORT:
5880         case TYPE_USHORT:
5881                 size = SIZEOF_SHORT;
5882                 break;
5883         case TYPE_INT:
5884         case TYPE_UINT:
5885         case TYPE_ENUM:
5886                 size = SIZEOF_INT;
5887                 break;
5888         case TYPE_LONG:
5889         case TYPE_ULONG:
5890                 size = SIZEOF_LONG;
5891                 break;
5892         case TYPE_POINTER:
5893                 size = SIZEOF_POINTER;
5894                 break;
5895         case TYPE_PRODUCT:
5896         {
5897                 size_t pad;
5898                 size = 0;
5899                 while((type->type & TYPE_MASK) == TYPE_PRODUCT) {
5900                         pad = needed_padding(state, type->left, size);
5901                         size = size + pad + size_of(state, type->left);
5902                         type = type->right;
5903                 }
5904                 pad = needed_padding(state, type, size);
5905                 size = size + pad + size_of(state, type);
5906                 break;
5907         }
5908         case TYPE_OVERLAP:
5909         {
5910                 size_t size_left, size_right;
5911                 size_left = size_of(state, type->left);
5912                 size_right = size_of(state, type->right);
5913                 size = (size_left >= size_right)? size_left : size_right;
5914                 break;
5915         }
5916         case TYPE_ARRAY:
5917                 if (type->elements == ELEMENT_COUNT_UNSPECIFIED) {
5918                         internal_error(state, 0, "Invalid array type");
5919                 } else {
5920                         size = size_of(state, type->left) * type->elements;
5921                 }
5922                 break;
5923         case TYPE_STRUCT:
5924         case TYPE_TUPLE:
5925         {
5926                 size_t pad;
5927                 size = size_of(state, type->left);
5928                 /* Pad structures so their size is a multiples of their alignment */
5929                 pad = needed_padding(state, type, size);
5930                 size = size + pad;
5931                 break;
5932         }
5933         case TYPE_UNION:
5934         case TYPE_JOIN:
5935         {
5936                 size_t pad;
5937                 size = size_of(state, type->left);
5938                 /* Pad unions so their size is a multiple of their alignment */
5939                 pad = needed_padding(state, type, size);
5940                 size = size + pad;
5941                 break;
5942         }
5943         default:
5944                 internal_error(state, 0, "sizeof not yet defined for type");
5945                 break;
5946         }
5947         return size;
5948 }
5949
5950 static size_t reg_size_of(struct compile_state *state, struct type *type)
5951 {
5952         size_t size;
5953         size = 0;
5954         switch(type->type & TYPE_MASK) {
5955         case TYPE_VOID:
5956                 size = 0;
5957                 break;
5958         case TYPE_BITFIELD:
5959                 size = type->elements;
5960                 break;
5961         case TYPE_CHAR:
5962         case TYPE_UCHAR:
5963                 size = REG_SIZEOF_CHAR;
5964                 break;
5965         case TYPE_SHORT:
5966         case TYPE_USHORT:
5967                 size = REG_SIZEOF_SHORT;
5968                 break;
5969         case TYPE_INT:
5970         case TYPE_UINT:
5971         case TYPE_ENUM:
5972                 size = REG_SIZEOF_INT;
5973                 break;
5974         case TYPE_LONG:
5975         case TYPE_ULONG:
5976                 size = REG_SIZEOF_LONG;
5977                 break;
5978         case TYPE_POINTER:
5979                 size = REG_SIZEOF_POINTER;
5980                 break;
5981         case TYPE_PRODUCT:
5982         {
5983                 size_t pad;
5984                 size = 0;
5985                 while((type->type & TYPE_MASK) == TYPE_PRODUCT) {
5986                         pad = reg_needed_padding(state, type->left, size);
5987                         size = size + pad + reg_size_of(state, type->left);
5988                         type = type->right;
5989                 }
5990                 pad = reg_needed_padding(state, type, size);
5991                 size = size + pad + reg_size_of(state, type);
5992                 break;
5993         }
5994         case TYPE_OVERLAP:
5995         {
5996                 size_t size_left, size_right;
5997                 size_left  = reg_size_of(state, type->left);
5998                 size_right = reg_size_of(state, type->right);
5999                 size = (size_left >= size_right)? size_left : size_right;
6000                 break;
6001         }
6002         case TYPE_ARRAY:
6003                 if (type->elements == ELEMENT_COUNT_UNSPECIFIED) {
6004                         internal_error(state, 0, "Invalid array type");
6005                 } else {
6006                         size = reg_size_of(state, type->left) * type->elements;
6007                 }
6008                 break;
6009         case TYPE_STRUCT:
6010         case TYPE_TUPLE:
6011         {
6012                 size_t pad;
6013                 size = reg_size_of(state, type->left);
6014                 /* Pad structures so their size is a multiples of their alignment */
6015                 pad = reg_needed_padding(state, type, size);
6016                 size = size + pad;
6017                 break;
6018         }
6019         case TYPE_UNION:
6020         case TYPE_JOIN:
6021         {
6022                 size_t pad;
6023                 size = reg_size_of(state, type->left);
6024                 /* Pad unions so their size is a multiple of their alignment */
6025                 pad = reg_needed_padding(state, type, size);
6026                 size = size + pad;
6027                 break;
6028         }
6029         default:
6030                 internal_error(state, 0, "sizeof not yet defined for type");
6031                 break;
6032         }
6033         return size;
6034 }
6035
6036 static size_t registers_of(struct compile_state *state, struct type *type)
6037 {
6038         size_t registers;
6039         registers = reg_size_of(state, type);
6040         registers += REG_SIZEOF_REG - 1;
6041         registers /= REG_SIZEOF_REG;
6042         return registers;
6043 }
6044
6045 static size_t size_of_in_bytes(struct compile_state *state, struct type *type)
6046 {
6047         return bits_to_bytes(size_of(state, type));
6048 }
6049
6050 static size_t field_offset(struct compile_state *state, 
6051         struct type *type, struct hash_entry *field)
6052 {
6053         struct type *member;
6054         size_t size;
6055
6056         size = 0;
6057         member = 0;
6058         if ((type->type & TYPE_MASK) == TYPE_STRUCT) {
6059                 member = type->left;
6060                 while(member && ((member->type & TYPE_MASK) == TYPE_PRODUCT)) {
6061                         size += needed_padding(state, member->left, size);
6062                         if (member->left->field_ident == field) {
6063                                 member = member->left;
6064                                 break;
6065                         }
6066                         size += size_of(state, member->left);
6067                         member = member->right;
6068                 }
6069                 size += needed_padding(state, member, size);
6070         }
6071         else if ((type->type & TYPE_MASK) == TYPE_UNION) {
6072                 member = type->left;
6073                 while(member && ((member->type & TYPE_MASK) == TYPE_OVERLAP)) {
6074                         if (member->left->field_ident == field) {
6075                                 member = member->left;
6076                                 break;
6077                         }
6078                         member = member->right;
6079                 }
6080         }
6081         else {
6082                 internal_error(state, 0, "field_offset only works on structures and unions");
6083         }
6084
6085         if (!member || (member->field_ident != field)) {
6086                 error(state, 0, "member %s not present", field->name);
6087         }
6088         return size;
6089 }
6090
6091 static size_t field_reg_offset(struct compile_state *state, 
6092         struct type *type, struct hash_entry *field)
6093 {
6094         struct type *member;
6095         size_t size;
6096
6097         size = 0;
6098         member = 0;
6099         if ((type->type & TYPE_MASK) == TYPE_STRUCT) {
6100                 member = type->left;
6101                 while(member && ((member->type & TYPE_MASK) == TYPE_PRODUCT)) {
6102                         size += reg_needed_padding(state, member->left, size);
6103                         if (member->left->field_ident == field) {
6104                                 member = member->left;
6105                                 break;
6106                         }
6107                         size += reg_size_of(state, member->left);
6108                         member = member->right;
6109                 }
6110         }
6111         else if ((type->type & TYPE_MASK) == TYPE_UNION) {
6112                 member = type->left;
6113                 while(member && ((member->type & TYPE_MASK) == TYPE_OVERLAP)) {
6114                         if (member->left->field_ident == field) {
6115                                 member = member->left;
6116                                 break;
6117                         }
6118                         member = member->right;
6119                 }
6120         }
6121         else {
6122                 internal_error(state, 0, "field_reg_offset only works on structures and unions");
6123         }
6124
6125         size += reg_needed_padding(state, member, size);
6126         if (!member || (member->field_ident != field)) {
6127                 error(state, 0, "member %s not present", field->name);
6128         }
6129         return size;
6130 }
6131
6132 static struct type *field_type(struct compile_state *state, 
6133         struct type *type, struct hash_entry *field)
6134 {
6135         struct type *member;
6136
6137         member = 0;
6138         if ((type->type & TYPE_MASK) == TYPE_STRUCT) {
6139                 member = type->left;
6140                 while(member && ((member->type & TYPE_MASK) == TYPE_PRODUCT)) {
6141                         if (member->left->field_ident == field) {
6142                                 member = member->left;
6143                                 break;
6144                         }
6145                         member = member->right;
6146                 }
6147         }
6148         else if ((type->type & TYPE_MASK) == TYPE_UNION) {
6149                 member = type->left;
6150                 while(member && ((member->type & TYPE_MASK) == TYPE_OVERLAP)) {
6151                         if (member->left->field_ident == field) {
6152                                 member = member->left;
6153                                 break;
6154                         }
6155                         member = member->right;
6156                 }
6157         }
6158         else {
6159                 internal_error(state, 0, "field_type only works on structures and unions");
6160         }
6161         
6162         if (!member || (member->field_ident != field)) {
6163                 error(state, 0, "member %s not present", field->name);
6164         }
6165         return member;
6166 }
6167
6168 static size_t index_offset(struct compile_state *state, 
6169         struct type *type, ulong_t index)
6170 {
6171         struct type *member;
6172         size_t size;
6173         size = 0;
6174         if ((type->type & TYPE_MASK) == TYPE_ARRAY) {
6175                 size = size_of(state, type->left) * index;
6176         }
6177         else if ((type->type & TYPE_MASK) == TYPE_TUPLE) {
6178                 ulong_t i;
6179                 member = type->left;
6180                 i = 0;
6181                 while(member && ((member->type & TYPE_MASK) == TYPE_PRODUCT)) {
6182                         size += needed_padding(state, member->left, size);
6183                         if (i == index) {
6184                                 member = member->left;
6185                                 break;
6186                         }
6187                         size += size_of(state, member->left);
6188                         i++;
6189                         member = member->right;
6190                 }
6191                 size += needed_padding(state, member, size);
6192                 if (i != index) {
6193                         internal_error(state, 0, "Missing member index: %u", index);
6194                 }
6195         }
6196         else if ((type->type & TYPE_MASK) == TYPE_JOIN) {
6197                 ulong_t i;
6198                 size = 0;
6199                 member = type->left;
6200                 i = 0;
6201                 while(member && ((member->type & TYPE_MASK) == TYPE_OVERLAP)) {
6202                         if (i == index) {
6203                                 member = member->left;
6204                                 break;
6205                         }
6206                         i++;
6207                         member = member->right;
6208                 }
6209                 if (i != index) {
6210                         internal_error(state, 0, "Missing member index: %u", index);
6211                 }
6212         }
6213         else {
6214                 internal_error(state, 0, 
6215                         "request for index %u in something not an array, tuple or join",
6216                         index);
6217         }
6218         return size;
6219 }
6220
6221 static size_t index_reg_offset(struct compile_state *state, 
6222         struct type *type, ulong_t index)
6223 {
6224         struct type *member;
6225         size_t size;
6226         size = 0;
6227         if ((type->type & TYPE_MASK) == TYPE_ARRAY) {
6228                 size = reg_size_of(state, type->left) * index;
6229         }
6230         else if ((type->type & TYPE_MASK) == TYPE_TUPLE) {
6231                 ulong_t i;
6232                 member = type->left;
6233                 i = 0;
6234                 while(member && ((member->type & TYPE_MASK) == TYPE_PRODUCT)) {
6235                         size += reg_needed_padding(state, member->left, size);
6236                         if (i == index) {
6237                                 member = member->left;
6238                                 break;
6239                         }
6240                         size += reg_size_of(state, member->left);
6241                         i++;
6242                         member = member->right;
6243                 }
6244                 size += reg_needed_padding(state, member, size);
6245                 if (i != index) {
6246                         internal_error(state, 0, "Missing member index: %u", index);
6247                 }
6248                 
6249         }
6250         else if ((type->type & TYPE_MASK) == TYPE_JOIN) {
6251                 ulong_t i;
6252                 size = 0;
6253                 member = type->left;
6254                 i = 0;
6255                 while(member && ((member->type & TYPE_MASK) == TYPE_OVERLAP)) {
6256                         if (i == index) {
6257                                 member = member->left;
6258                                 break;
6259                         }
6260                         i++;
6261                         member = member->right;
6262                 }
6263                 if (i != index) {
6264                         internal_error(state, 0, "Missing member index: %u", index);
6265                 }
6266         }
6267         else {
6268                 internal_error(state, 0, 
6269                         "request for index %u in something not an array, tuple or join",
6270                         index);
6271         }
6272         return size;
6273 }
6274
6275 static struct type *index_type(struct compile_state *state,
6276         struct type *type, ulong_t index)
6277 {
6278         struct type *member;
6279         if (index >= type->elements) {
6280                 internal_error(state, 0, "Invalid element %u requested", index);
6281         }
6282         if ((type->type & TYPE_MASK) == TYPE_ARRAY) {
6283                 member = type->left;
6284         }
6285         else if ((type->type & TYPE_MASK) == TYPE_TUPLE) {
6286                 ulong_t i;
6287                 member = type->left;
6288                 i = 0;
6289                 while(member && ((member->type & TYPE_MASK) == TYPE_PRODUCT)) {
6290                         if (i == index) {
6291                                 member = member->left;
6292                                 break;
6293                         }
6294                         i++;
6295                         member = member->right;
6296                 }
6297                 if (i != index) {
6298                         internal_error(state, 0, "Missing member index: %u", index);
6299                 }
6300         }
6301         else if ((type->type & TYPE_MASK) == TYPE_JOIN) {
6302                 ulong_t i;
6303                 member = type->left;
6304                 i = 0;
6305                 while(member && ((member->type & TYPE_MASK) == TYPE_OVERLAP)) {
6306                         if (i == index) {
6307                                 member = member->left;
6308                                 break;
6309                         }
6310                         i++;
6311                         member = member->right;
6312                 }
6313                 if (i != index) {
6314                         internal_error(state, 0, "Missing member index: %u", index);
6315                 }
6316         }
6317         else {
6318                 member = 0;
6319                 internal_error(state, 0, 
6320                         "request for index %u in something not an array, tuple or join",
6321                         index);
6322         }
6323         return member;
6324 }
6325
6326 static struct type *unpack_type(struct compile_state *state, struct type *type)
6327 {
6328         /* If I have a single register compound type not a bit-field
6329          * find the real type.
6330          */
6331         struct type *start_type;
6332         size_t size;
6333         /* Get out early if I need multiple registers for this type */
6334         size = reg_size_of(state, type);
6335         if (size > REG_SIZEOF_REG) {
6336                 return type;
6337         }
6338         /* Get out early if I don't need any registers for this type */
6339         if (size == 0) {
6340                 return &void_type;
6341         }
6342         /* Loop until I have no more layers I can remove */
6343         do {
6344                 start_type = type;
6345                 switch(type->type & TYPE_MASK) {
6346                 case TYPE_ARRAY:
6347                         /* If I have a single element the unpacked type
6348                          * is that element.
6349                          */
6350                         if (type->elements == 1) {
6351                                 type = type->left;
6352                         }
6353                         break;
6354                 case TYPE_STRUCT:
6355                 case TYPE_TUPLE:
6356                         /* If I have a single element the unpacked type
6357                          * is that element.
6358                          */
6359                         if (type->elements == 1) {
6360                                 type = type->left;
6361                         }
6362                         /* If I have multiple elements the unpacked
6363                          * type is the non-void element.
6364                          */
6365                         else {
6366                                 struct type *next, *member;
6367                                 struct type *sub_type;
6368                                 sub_type = 0;
6369                                 next = type->left;
6370                                 while(next) {
6371                                         member = next;
6372                                         next = 0;
6373                                         if ((member->type & TYPE_MASK) == TYPE_PRODUCT) {
6374                                                 next = member->right;
6375                                                 member = member->left;
6376                                         }
6377                                         if (reg_size_of(state, member) > 0) {
6378                                                 if (sub_type) {
6379                                                         internal_error(state, 0, "true compound type in a register");
6380                                                 }
6381                                                 sub_type = member;
6382                                         }
6383                                 }
6384                                 if (sub_type) {
6385                                         type = sub_type;
6386                                 }
6387                         }
6388                         break;
6389
6390                 case TYPE_UNION:
6391                 case TYPE_JOIN:
6392                         /* If I have a single element the unpacked type
6393                          * is that element.
6394                          */
6395                         if (type->elements == 1) {
6396                                 type = type->left;
6397                         }
6398                         /* I can't in general unpack union types */
6399                         break;
6400                 default:
6401                         /* If I'm not a compound type I can't unpack it */
6402                         break;
6403                 }
6404         } while(start_type != type);
6405         switch(type->type & TYPE_MASK) {
6406         case TYPE_STRUCT:
6407         case TYPE_ARRAY:
6408         case TYPE_TUPLE:
6409                 internal_error(state, 0, "irredicible type?");
6410                 break;
6411         }
6412         return type;
6413 }
6414
6415 static int equiv_types(struct type *left, struct type *right);
6416 static int is_compound_type(struct type *type);
6417
6418 static struct type *reg_type(
6419         struct compile_state *state, struct type *type, int reg_offset)
6420 {
6421         struct type *member;
6422         size_t size;
6423 #if 1
6424         struct type *invalid;
6425         invalid = invalid_type(state, type);
6426         if (invalid) {
6427                 fprintf(state->errout, "type: ");
6428                 name_of(state->errout, type);
6429                 fprintf(state->errout, "\n");
6430                 fprintf(state->errout, "invalid: ");
6431                 name_of(state->errout, invalid);
6432                 fprintf(state->errout, "\n");
6433                 internal_error(state, 0, "bad input type?");
6434         }
6435 #endif
6436
6437         size = reg_size_of(state, type);
6438         if (reg_offset > size) {
6439                 member = 0;
6440                 fprintf(state->errout, "type: ");
6441                 name_of(state->errout, type);
6442                 fprintf(state->errout, "\n");
6443                 internal_error(state, 0, "offset outside of type");
6444         }
6445         else {
6446                 switch(type->type & TYPE_MASK) {
6447                         /* Don't do anything with the basic types */
6448                 case TYPE_VOID:
6449                 case TYPE_CHAR:         case TYPE_UCHAR:
6450                 case TYPE_SHORT:        case TYPE_USHORT:
6451                 case TYPE_INT:          case TYPE_UINT:
6452                 case TYPE_LONG:         case TYPE_ULONG:
6453                 case TYPE_LLONG:        case TYPE_ULLONG:
6454                 case TYPE_FLOAT:        case TYPE_DOUBLE:
6455                 case TYPE_LDOUBLE:
6456                 case TYPE_POINTER:
6457                 case TYPE_ENUM:
6458                 case TYPE_BITFIELD:
6459                         member = type;
6460                         break;
6461                 case TYPE_ARRAY:
6462                         member = type->left;
6463                         size = reg_size_of(state, member);
6464                         if (size > REG_SIZEOF_REG) {
6465                                 member = reg_type(state, member, reg_offset % size);
6466                         }
6467                         break;
6468                 case TYPE_STRUCT:
6469                 case TYPE_TUPLE:
6470                 {
6471                         size_t offset;
6472                         offset = 0;
6473                         member = type->left;
6474                         while(member && ((member->type & TYPE_MASK) == TYPE_PRODUCT)) {
6475                                 size = reg_size_of(state, member->left);
6476                                 offset += reg_needed_padding(state, member->left, offset);
6477                                 if ((offset + size) > reg_offset) {
6478                                         member = member->left;
6479                                         break;
6480                                 }
6481                                 offset += size;
6482                                 member = member->right;
6483                         }
6484                         offset += reg_needed_padding(state, member, offset);
6485                         member = reg_type(state, member, reg_offset - offset);
6486                         break;
6487                 }
6488                 case TYPE_UNION:
6489                 case TYPE_JOIN:
6490                 {
6491                         struct type *join, **jnext, *mnext;
6492                         join = new_type(TYPE_JOIN, 0, 0);
6493                         jnext = &join->left;
6494                         mnext = type->left;
6495                         while(mnext) {
6496                                 size_t size;
6497                                 member = mnext;
6498                                 mnext = 0;
6499                                 if ((member->type & TYPE_MASK) == TYPE_OVERLAP) {
6500                                         mnext = member->right;
6501                                         member = member->left;
6502                                 }
6503                                 size = reg_size_of(state, member);
6504                                 if (size > reg_offset) {
6505                                         struct type *part, *hunt;
6506                                         part = reg_type(state, member, reg_offset);
6507                                         /* See if this type is already in the union */
6508                                         hunt = join->left;
6509                                         while(hunt) {
6510                                                 struct type *test = hunt;
6511                                                 hunt = 0;
6512                                                 if ((test->type & TYPE_MASK) == TYPE_OVERLAP) {
6513                                                         hunt = test->right;
6514                                                         test = test->left;
6515                                                 }
6516                                                 if (equiv_types(part, test)) {
6517                                                         goto next;
6518                                                 }
6519                                         }
6520                                         /* Nope add it */
6521                                         if (!*jnext) {
6522                                                 *jnext = part;
6523                                         } else {
6524                                                 *jnext = new_type(TYPE_OVERLAP, *jnext, part);
6525                                                 jnext = &(*jnext)->right;
6526                                         }
6527                                         join->elements++;
6528                                 }
6529                         next:
6530                                 ;
6531                         }
6532                         if (join->elements == 0) {
6533                                 internal_error(state, 0, "No elements?");
6534                         }
6535                         member = join;
6536                         break;
6537                 }
6538                 default:
6539                         member = 0;
6540                         fprintf(state->errout, "type: ");
6541                         name_of(state->errout, type);
6542                         fprintf(state->errout, "\n");
6543                         internal_error(state, 0, "reg_type not yet defined for type");
6544                         
6545                 }
6546         }
6547         /* If I have a single register compound type not a bit-field
6548          * find the real type.
6549          */
6550         member = unpack_type(state, member);
6551                 ;
6552         size  = reg_size_of(state, member);
6553         if (size > REG_SIZEOF_REG) {
6554                 internal_error(state, 0, "Cannot find type of single register");
6555         }
6556 #if 1
6557         invalid = invalid_type(state, member);
6558         if (invalid) {
6559                 fprintf(state->errout, "type: ");
6560                 name_of(state->errout, member);
6561                 fprintf(state->errout, "\n");
6562                 fprintf(state->errout, "invalid: ");
6563                 name_of(state->errout, invalid);
6564                 fprintf(state->errout, "\n");
6565                 internal_error(state, 0, "returning bad type?");
6566         }
6567 #endif
6568         return member;
6569 }
6570
6571 static struct type *next_field(struct compile_state *state,
6572         struct type *type, struct type *prev_member) 
6573 {
6574         struct type *member;
6575         if ((type->type & TYPE_MASK) != TYPE_STRUCT) {
6576                 internal_error(state, 0, "next_field only works on structures");
6577         }
6578         member = type->left;
6579         while((member->type & TYPE_MASK) == TYPE_PRODUCT) {
6580                 if (!prev_member) {
6581                         member = member->left;
6582                         break;
6583                 }
6584                 if (member->left == prev_member) {
6585                         prev_member = 0;
6586                 }
6587                 member = member->right;
6588         }
6589         if (member == prev_member) {
6590                 prev_member = 0;
6591         }
6592         if (prev_member) {
6593                 internal_error(state, 0, "prev_member %s not present", 
6594                         prev_member->field_ident->name);
6595         }
6596         return member;
6597 }
6598
6599 typedef void (*walk_type_fields_cb_t)(struct compile_state *state, struct type *type, 
6600         size_t ret_offset, size_t mem_offset, void *arg);
6601
6602 static void walk_type_fields(struct compile_state *state,
6603         struct type *type, size_t reg_offset, size_t mem_offset,
6604         walk_type_fields_cb_t cb, void *arg);
6605
6606 static void walk_struct_fields(struct compile_state *state,
6607         struct type *type, size_t reg_offset, size_t mem_offset,
6608         walk_type_fields_cb_t cb, void *arg)
6609 {
6610         struct type *tptr;
6611         ulong_t i;
6612         if ((type->type & TYPE_MASK) != TYPE_STRUCT) {
6613                 internal_error(state, 0, "walk_struct_fields only works on structures");
6614         }
6615         tptr = type->left;
6616         for(i = 0; i < type->elements; i++) {
6617                 struct type *mtype;
6618                 mtype = tptr;
6619                 if ((mtype->type & TYPE_MASK) == TYPE_PRODUCT) {
6620                         mtype = mtype->left;
6621                 }
6622                 walk_type_fields(state, mtype, 
6623                         reg_offset + 
6624                         field_reg_offset(state, type, mtype->field_ident),
6625                         mem_offset + 
6626                         field_offset(state, type, mtype->field_ident),
6627                         cb, arg);
6628                 tptr = tptr->right;
6629         }
6630         
6631 }
6632
6633 static void walk_type_fields(struct compile_state *state,
6634         struct type *type, size_t reg_offset, size_t mem_offset,
6635         walk_type_fields_cb_t cb, void *arg)
6636 {
6637         switch(type->type & TYPE_MASK) {
6638         case TYPE_STRUCT:
6639                 walk_struct_fields(state, type, reg_offset, mem_offset, cb, arg);
6640                 break;
6641         case TYPE_CHAR:
6642         case TYPE_UCHAR:
6643         case TYPE_SHORT:
6644         case TYPE_USHORT:
6645         case TYPE_INT:
6646         case TYPE_UINT:
6647         case TYPE_LONG:
6648         case TYPE_ULONG:
6649                 cb(state, type, reg_offset, mem_offset, arg);
6650                 break;
6651         case TYPE_VOID:
6652                 break;
6653         default:
6654                 internal_error(state, 0, "walk_type_fields not yet implemented for type");
6655         }
6656 }
6657
6658 static void arrays_complete(struct compile_state *state, struct type *type)
6659 {
6660         if ((type->type & TYPE_MASK) == TYPE_ARRAY) {
6661                 if (type->elements == ELEMENT_COUNT_UNSPECIFIED) {
6662                         error(state, 0, "array size not specified");
6663                 }
6664                 arrays_complete(state, type->left);
6665         }
6666 }
6667
6668 static unsigned int get_basic_type(struct type *type)
6669 {
6670         unsigned int basic;
6671         basic = type->type & TYPE_MASK;
6672         /* Convert enums to ints */
6673         if (basic == TYPE_ENUM) {
6674                 basic = TYPE_INT;
6675         }
6676         /* Convert bitfields to standard types */
6677         else if (basic == TYPE_BITFIELD) {
6678                 if (type->elements <= SIZEOF_CHAR) {
6679                         basic = TYPE_CHAR;
6680                 }
6681                 else if (type->elements <= SIZEOF_SHORT) {
6682                         basic = TYPE_SHORT;
6683                 }
6684                 else if (type->elements <= SIZEOF_INT) {
6685                         basic = TYPE_INT;
6686                 }
6687                 else if (type->elements <= SIZEOF_LONG) {
6688                         basic = TYPE_LONG;
6689                 }
6690                 if (!TYPE_SIGNED(type->left->type)) {
6691                         basic += 1;
6692                 }
6693         }
6694         return basic;
6695 }
6696
6697 static unsigned int do_integral_promotion(unsigned int type)
6698 {
6699         if (TYPE_INTEGER(type) && (TYPE_RANK(type) < TYPE_RANK(TYPE_INT))) {
6700                 type = TYPE_INT;
6701         }
6702         return type;
6703 }
6704
6705 static unsigned int do_arithmetic_conversion(
6706         unsigned int left, unsigned int right)
6707 {
6708         if ((left == TYPE_LDOUBLE) || (right == TYPE_LDOUBLE)) {
6709                 return TYPE_LDOUBLE;
6710         }
6711         else if ((left == TYPE_DOUBLE) || (right == TYPE_DOUBLE)) {
6712                 return TYPE_DOUBLE;
6713         }
6714         else if ((left == TYPE_FLOAT) || (right == TYPE_FLOAT)) {
6715                 return TYPE_FLOAT;
6716         }
6717         left = do_integral_promotion(left);
6718         right = do_integral_promotion(right);
6719         /* If both operands have the same size done */
6720         if (left == right) {
6721                 return left;
6722         }
6723         /* If both operands have the same signedness pick the larger */
6724         else if (!!TYPE_UNSIGNED(left) == !!TYPE_UNSIGNED(right)) {
6725                 return (TYPE_RANK(left) >= TYPE_RANK(right)) ? left : right;
6726         }
6727         /* If the signed type can hold everything use it */
6728         else if (TYPE_SIGNED(left) && (TYPE_RANK(left) > TYPE_RANK(right))) {
6729                 return left;
6730         }
6731         else if (TYPE_SIGNED(right) && (TYPE_RANK(right) > TYPE_RANK(left))) {
6732                 return right;
6733         }
6734         /* Convert to the unsigned type with the same rank as the signed type */
6735         else if (TYPE_SIGNED(left)) {
6736                 return TYPE_MKUNSIGNED(left);
6737         }
6738         else {
6739                 return TYPE_MKUNSIGNED(right);
6740         }
6741 }
6742
6743 /* see if two types are the same except for qualifiers */
6744 static int equiv_types(struct type *left, struct type *right)
6745 {
6746         unsigned int type;
6747         /* Error if the basic types do not match */
6748         if ((left->type & TYPE_MASK) != (right->type & TYPE_MASK)) {
6749                 return 0;
6750         }
6751         type = left->type & TYPE_MASK;
6752         /* If the basic types match and it is a void type we are done */
6753         if (type == TYPE_VOID) {
6754                 return 1;
6755         }
6756         /* For bitfields we need to compare the sizes */
6757         else if (type == TYPE_BITFIELD) {
6758                 return (left->elements == right->elements) &&
6759                         (TYPE_SIGNED(left->left->type) == TYPE_SIGNED(right->left->type));
6760         }
6761         /* if the basic types match and it is an arithmetic type we are done */
6762         else if (TYPE_ARITHMETIC(type)) {
6763                 return 1;
6764         }
6765         /* If it is a pointer type recurse and keep testing */
6766         else if (type == TYPE_POINTER) {
6767                 return equiv_types(left->left, right->left);
6768         }
6769         else if (type == TYPE_ARRAY) {
6770                 return (left->elements == right->elements) &&
6771                         equiv_types(left->left, right->left);
6772         }
6773         /* test for struct equality */
6774         else if (type == TYPE_STRUCT) {
6775                 return left->type_ident == right->type_ident;
6776         }
6777         /* test for union equality */
6778         else if (type == TYPE_UNION) {
6779                 return left->type_ident == right->type_ident;
6780         }
6781         /* Test for equivalent functions */
6782         else if (type == TYPE_FUNCTION) {
6783                 return equiv_types(left->left, right->left) &&
6784                         equiv_types(left->right, right->right);
6785         }
6786         /* We only see TYPE_PRODUCT as part of function equivalence matching */
6787         /* We also see TYPE_PRODUCT as part of of tuple equivalence matchin */
6788         else if (type == TYPE_PRODUCT) {
6789                 return equiv_types(left->left, right->left) &&
6790                         equiv_types(left->right, right->right);
6791         }
6792         /* We should see TYPE_OVERLAP when comparing joins */
6793         else if (type == TYPE_OVERLAP) {
6794                 return equiv_types(left->left, right->left) &&
6795                         equiv_types(left->right, right->right);
6796         }
6797         /* Test for equivalence of tuples */
6798         else if (type == TYPE_TUPLE) {
6799                 return (left->elements == right->elements) &&
6800                         equiv_types(left->left, right->left);
6801         }
6802         /* Test for equivalence of joins */
6803         else if (type == TYPE_JOIN) {
6804                 return (left->elements == right->elements) &&
6805                         equiv_types(left->left, right->left);
6806         }
6807         else {
6808                 return 0;
6809         }
6810 }
6811
6812 static int equiv_ptrs(struct type *left, struct type *right)
6813 {
6814         if (((left->type & TYPE_MASK) != TYPE_POINTER) ||
6815                 ((right->type & TYPE_MASK) != TYPE_POINTER)) {
6816                 return 0;
6817         }
6818         return equiv_types(left->left, right->left);
6819 }
6820
6821 static struct type *compatible_types(struct type *left, struct type *right)
6822 {
6823         struct type *result;
6824         unsigned int type, qual_type;
6825         /* Error if the basic types do not match */
6826         if ((left->type & TYPE_MASK) != (right->type & TYPE_MASK)) {
6827                 return 0;
6828         }
6829         type = left->type & TYPE_MASK;
6830         qual_type = (left->type & ~STOR_MASK) | (right->type & ~STOR_MASK);
6831         result = 0;
6832         /* if the basic types match and it is an arithmetic type we are done */
6833         if (TYPE_ARITHMETIC(type)) {
6834                 result = new_type(qual_type, 0, 0);
6835         }
6836         /* If it is a pointer type recurse and keep testing */
6837         else if (type == TYPE_POINTER) {
6838                 result = compatible_types(left->left, right->left);
6839                 if (result) {
6840                         result = new_type(qual_type, result, 0);
6841                 }
6842         }
6843         /* test for struct equality */
6844         else if (type == TYPE_STRUCT) {
6845                 if (left->type_ident == right->type_ident) {
6846                         result = left;
6847                 }
6848         }
6849         /* test for union equality */
6850         else if (type == TYPE_UNION) {
6851                 if (left->type_ident == right->type_ident) {
6852                         result = left;
6853                 }
6854         }
6855         /* Test for equivalent functions */
6856         else if (type == TYPE_FUNCTION) {
6857                 struct type *lf, *rf;
6858                 lf = compatible_types(left->left, right->left);
6859                 rf = compatible_types(left->right, right->right);
6860                 if (lf && rf) {
6861                         result = new_type(qual_type, lf, rf);
6862                 }
6863         }
6864         /* We only see TYPE_PRODUCT as part of function equivalence matching */
6865         else if (type == TYPE_PRODUCT) {
6866                 struct type *lf, *rf;
6867                 lf = compatible_types(left->left, right->left);
6868                 rf = compatible_types(left->right, right->right);
6869                 if (lf && rf) {
6870                         result = new_type(qual_type, lf, rf);
6871                 }
6872         }
6873         else {
6874                 /* Nothing else is compatible */
6875         }
6876         return result;
6877 }
6878
6879 /* See if left is a equivalent to right or right is a union member of left */
6880 static int is_subset_type(struct type *left, struct type *right)
6881 {
6882         if (equiv_types(left, right)) {
6883                 return 1;
6884         }
6885         if ((left->type & TYPE_MASK) == TYPE_JOIN) {
6886                 struct type *member, *mnext;
6887                 mnext = left->left;
6888                 while(mnext) {
6889                         member = mnext;
6890                         mnext = 0;
6891                         if ((member->type & TYPE_MASK) == TYPE_OVERLAP) {
6892                                 mnext = member->right;
6893                                 member = member->left;
6894                         }
6895                         if (is_subset_type( member, right)) {
6896                                 return 1;
6897                         }
6898                 }
6899         }
6900         return 0;
6901 }
6902
6903 static struct type *compatible_ptrs(struct type *left, struct type *right)
6904 {
6905         struct type *result;
6906         if (((left->type & TYPE_MASK) != TYPE_POINTER) ||
6907                 ((right->type & TYPE_MASK) != TYPE_POINTER)) {
6908                 return 0;
6909         }
6910         result = compatible_types(left->left, right->left);
6911         if (result) {
6912                 unsigned int qual_type;
6913                 qual_type = (left->type & ~STOR_MASK) | (right->type & ~STOR_MASK);
6914                 result = new_type(qual_type, result, 0);
6915         }
6916         return result;
6917         
6918 }
6919 static struct triple *integral_promotion(
6920         struct compile_state *state, struct triple *def)
6921 {
6922         struct type *type;
6923         type = def->type;
6924         /* As all operations are carried out in registers
6925          * the values are converted on load I just convert
6926          * logical type of the operand.
6927          */
6928         if (TYPE_INTEGER(type->type)) {
6929                 unsigned int int_type;
6930                 int_type = type->type & ~TYPE_MASK;
6931                 int_type |= do_integral_promotion(get_basic_type(type));
6932                 if (int_type != type->type) {
6933                         if (def->op != OP_LOAD) {
6934                                 def->type = new_type(int_type, 0, 0);
6935                         }
6936                         else {
6937                                 def = triple(state, OP_CONVERT, 
6938                                         new_type(int_type, 0, 0), def, 0);
6939                         }
6940                 }
6941         }
6942         return def;
6943 }
6944
6945
6946 static void arithmetic(struct compile_state *state, struct triple *def)
6947 {
6948         if (!TYPE_ARITHMETIC(def->type->type)) {
6949                 error(state, 0, "arithmetic type expexted");
6950         }
6951 }
6952
6953 static void ptr_arithmetic(struct compile_state *state, struct triple *def)
6954 {
6955         if (!TYPE_PTR(def->type->type) && !TYPE_ARITHMETIC(def->type->type)) {
6956                 error(state, def, "pointer or arithmetic type expected");
6957         }
6958 }
6959
6960 static int is_integral(struct triple *ins)
6961 {
6962         return TYPE_INTEGER(ins->type->type);
6963 }
6964
6965 static void integral(struct compile_state *state, struct triple *def)
6966 {
6967         if (!is_integral(def)) {
6968                 error(state, 0, "integral type expected");
6969         }
6970 }
6971
6972
6973 static void bool(struct compile_state *state, struct triple *def)
6974 {
6975         if (!TYPE_ARITHMETIC(def->type->type) &&
6976                 ((def->type->type & TYPE_MASK) != TYPE_POINTER)) {
6977                 error(state, 0, "arithmetic or pointer type expected");
6978         }
6979 }
6980
6981 static int is_signed(struct type *type)
6982 {
6983         if ((type->type & TYPE_MASK) == TYPE_BITFIELD) {
6984                 type = type->left;
6985         }
6986         return !!TYPE_SIGNED(type->type);
6987 }
6988 static int is_compound_type(struct type *type)
6989 {
6990         int is_compound;
6991         switch((type->type & TYPE_MASK)) {
6992         case TYPE_ARRAY:
6993         case TYPE_STRUCT:
6994         case TYPE_TUPLE:
6995         case TYPE_UNION:
6996         case TYPE_JOIN: 
6997                 is_compound = 1;
6998                 break;
6999         default:
7000                 is_compound = 0;
7001                 break;
7002         }
7003         return is_compound;
7004 }
7005
7006 /* Is this value located in a register otherwise it must be in memory */
7007 static int is_in_reg(struct compile_state *state, struct triple *def)
7008 {
7009         int in_reg;
7010         if (def->op == OP_ADECL) {
7011                 in_reg = 1;
7012         }
7013         else if ((def->op == OP_SDECL) || (def->op == OP_DEREF)) {
7014                 in_reg = 0;
7015         }
7016         else if (triple_is_part(state, def)) {
7017                 in_reg = is_in_reg(state, MISC(def, 0));
7018         }
7019         else {
7020                 internal_error(state, def, "unknown expr storage location");
7021                 in_reg = -1;
7022         }
7023         return in_reg;
7024 }
7025
7026 /* Is this an auto or static variable location? Something that can
7027  * be assigned to.  Otherwise it must must be a pure value, a temporary.
7028  */
7029 static int is_lvalue(struct compile_state *state, struct triple *def)
7030 {
7031         int ret;
7032         ret = 0;
7033         if (!def) {
7034                 return 0;
7035         }
7036         if ((def->op == OP_ADECL) || 
7037                 (def->op == OP_SDECL) || 
7038                 (def->op == OP_DEREF) ||
7039                 (def->op == OP_BLOBCONST) ||
7040                 (def->op == OP_LIST)) {
7041                 ret = 1;
7042         }
7043         else if (triple_is_part(state, def)) {
7044                 ret = is_lvalue(state, MISC(def, 0));
7045         }
7046         return ret;
7047 }
7048
7049 static void clvalue(struct compile_state *state, struct triple *def)
7050 {
7051         if (!def) {
7052                 internal_error(state, def, "nothing where lvalue expected?");
7053         }
7054         if (!is_lvalue(state, def)) { 
7055                 error(state, def, "lvalue expected");
7056         }
7057 }
7058 static void lvalue(struct compile_state *state, struct triple *def)
7059 {
7060         clvalue(state, def);
7061         if (def->type->type & QUAL_CONST) {
7062                 error(state, def, "modifable lvalue expected");
7063         }
7064 }
7065
7066 static int is_pointer(struct triple *def)
7067 {
7068         return (def->type->type & TYPE_MASK) == TYPE_POINTER;
7069 }
7070
7071 static void pointer(struct compile_state *state, struct triple *def)
7072 {
7073         if (!is_pointer(def)) {
7074                 error(state, def, "pointer expected");
7075         }
7076 }
7077
7078 static struct triple *int_const(
7079         struct compile_state *state, struct type *type, ulong_t value)
7080 {
7081         struct triple *result;
7082         switch(type->type & TYPE_MASK) {
7083         case TYPE_CHAR:
7084         case TYPE_INT:   case TYPE_UINT:
7085         case TYPE_LONG:  case TYPE_ULONG:
7086                 break;
7087         default:
7088                 internal_error(state, 0, "constant for unknown type");
7089         }
7090         result = triple(state, OP_INTCONST, type, 0, 0);
7091         result->u.cval = value;
7092         return result;
7093 }
7094
7095
7096 static struct triple *read_expr(struct compile_state *state, struct triple *def);
7097
7098 static struct triple *do_mk_addr_expr(struct compile_state *state, 
7099         struct triple *expr, struct type *type, ulong_t offset)
7100 {
7101         struct triple *result;
7102         struct type *ptr_type;
7103         clvalue(state, expr);
7104
7105         ptr_type = new_type(TYPE_POINTER | (type->type & QUAL_MASK), type, 0);
7106
7107         
7108         result = 0;
7109         if (expr->op == OP_ADECL) {
7110                 error(state, expr, "address of auto variables not supported");
7111         }
7112         else if (expr->op == OP_SDECL) {
7113                 result = triple(state, OP_ADDRCONST, ptr_type, 0, 0);
7114                 MISC(result, 0) = expr;
7115                 result->u.cval = offset;
7116         }
7117         else if (expr->op == OP_DEREF) {
7118                 result = triple(state, OP_ADD, ptr_type,
7119                         RHS(expr, 0),
7120                         int_const(state, &ulong_type, offset));
7121         }
7122         else if (expr->op == OP_BLOBCONST) {
7123                 FINISHME();
7124                 internal_error(state, expr, "not yet implemented");
7125         }
7126         else if (expr->op == OP_LIST) {
7127                 error(state, 0, "Function addresses not supported");
7128         }
7129         else if (triple_is_part(state, expr)) {
7130                 struct triple *part;
7131                 part = expr;
7132                 expr = MISC(expr, 0);
7133                 if (part->op == OP_DOT) {
7134                         offset += bits_to_bytes(
7135                                 field_offset(state, expr->type, part->u.field));
7136                 }
7137                 else if (part->op == OP_INDEX) {
7138                         offset += bits_to_bytes(
7139                                 index_offset(state, expr->type, part->u.cval));
7140                 }
7141                 else {
7142                         internal_error(state, part, "unhandled part type");
7143                 }
7144                 result = do_mk_addr_expr(state, expr, type, offset);
7145         }
7146         if (!result) {
7147                 internal_error(state, expr, "cannot take address of expression");
7148         }
7149         return result;
7150 }
7151
7152 static struct triple *mk_addr_expr(
7153         struct compile_state *state, struct triple *expr, ulong_t offset)
7154 {
7155         return do_mk_addr_expr(state, expr, expr->type, offset);
7156 }
7157
7158 static struct triple *mk_deref_expr(
7159         struct compile_state *state, struct triple *expr)
7160 {
7161         struct type *base_type;
7162         pointer(state, expr);
7163         base_type = expr->type->left;
7164         return triple(state, OP_DEREF, base_type, expr, 0);
7165 }
7166
7167 /* lvalue conversions always apply except when certain operators
7168  * are applied.  So I apply apply it when I know no more
7169  * operators will be applied.
7170  */
7171 static struct triple *lvalue_conversion(struct compile_state *state, struct triple *def)
7172 {
7173         /* Tranform an array to a pointer to the first element */
7174         if ((def->type->type & TYPE_MASK) == TYPE_ARRAY) {
7175                 struct type *type;
7176                 type = new_type(
7177                         TYPE_POINTER | (def->type->type & QUAL_MASK),
7178                         def->type->left, 0);
7179                 if ((def->op == OP_SDECL) || IS_CONST_OP(def->op)) {
7180                         struct triple *addrconst;
7181                         if ((def->op != OP_SDECL) && (def->op != OP_BLOBCONST)) {
7182                                 internal_error(state, def, "bad array constant");
7183                         }
7184                         addrconst = triple(state, OP_ADDRCONST, type, 0, 0);
7185                         MISC(addrconst, 0) = def;
7186                         def = addrconst;
7187                 }
7188                 else {
7189                         def = triple(state, OP_CONVERT, type, def, 0);
7190                 }
7191         }
7192         /* Transform a function to a pointer to it */
7193         else if ((def->type->type & TYPE_MASK) == TYPE_FUNCTION) {
7194                 def = mk_addr_expr(state, def, 0);
7195         }
7196         return def;
7197 }
7198
7199 static struct triple *deref_field(
7200         struct compile_state *state, struct triple *expr, struct hash_entry *field)
7201 {
7202         struct triple *result;
7203         struct type *type, *member;
7204         ulong_t offset;
7205         if (!field) {
7206                 internal_error(state, 0, "No field passed to deref_field");
7207         }
7208         result = 0;
7209         type = expr->type;
7210         if (((type->type & TYPE_MASK) != TYPE_STRUCT) &&
7211                 ((type->type & TYPE_MASK) != TYPE_UNION)) {
7212                 error(state, 0, "request for member %s in something not a struct or union",
7213                         field->name);
7214         }
7215         member = field_type(state, type, field);
7216         if ((type->type & STOR_MASK) == STOR_PERM) {
7217                 /* Do the pointer arithmetic to get a deref the field */
7218                 offset = bits_to_bytes(field_offset(state, type, field));
7219                 result = do_mk_addr_expr(state, expr, member, offset);
7220                 result = mk_deref_expr(state, result);
7221         }
7222         else {
7223                 /* Find the variable for the field I want. */
7224                 result = triple(state, OP_DOT, member, expr, 0);
7225                 result->u.field = field;
7226         }
7227         return result;
7228 }
7229
7230 static struct triple *deref_index(
7231         struct compile_state *state, struct triple *expr, size_t index)
7232 {
7233         struct triple *result;
7234         struct type *type, *member;
7235         ulong_t offset;
7236
7237         result = 0;
7238         type = expr->type;
7239         member = index_type(state, type, index);
7240
7241         if ((type->type & STOR_MASK) == STOR_PERM) {
7242                 offset = bits_to_bytes(index_offset(state, type, index));
7243                 result = do_mk_addr_expr(state, expr, member, offset);
7244                 result = mk_deref_expr(state, result);
7245         }
7246         else {
7247                 result = triple(state, OP_INDEX, member, expr, 0);
7248                 result->u.cval = index;
7249         }
7250         return result;
7251 }
7252
7253 static struct triple *read_expr(struct compile_state *state, struct triple *def)
7254 {
7255         int op;
7256         if  (!def) {
7257                 return 0;
7258         }
7259 #warning "CHECK_ME is this the only place I need to do lvalue conversions?"
7260         /* Transform lvalues into something we can read */
7261         def = lvalue_conversion(state, def);
7262         if (!is_lvalue(state, def)) {
7263                 return def;
7264         }
7265         if (is_in_reg(state, def)) {
7266                 op = OP_READ;
7267         } else {
7268                 if (def->op == OP_SDECL) {
7269                         def = mk_addr_expr(state, def, 0);
7270                         def = mk_deref_expr(state, def);
7271                 }
7272                 op = OP_LOAD;
7273         }
7274         def = triple(state, op, def->type, def, 0);
7275         if (def->type->type & QUAL_VOLATILE) {
7276                 def->id |= TRIPLE_FLAG_VOLATILE;
7277         }
7278         return def;
7279 }
7280
7281 int is_write_compatible(struct compile_state *state, 
7282         struct type *dest, struct type *rval)
7283 {
7284         int compatible = 0;
7285         /* Both operands have arithmetic type */
7286         if (TYPE_ARITHMETIC(dest->type) && TYPE_ARITHMETIC(rval->type)) {
7287                 compatible = 1;
7288         }
7289         /* One operand is a pointer and the other is a pointer to void */
7290         else if (((dest->type & TYPE_MASK) == TYPE_POINTER) &&
7291                 ((rval->type & TYPE_MASK) == TYPE_POINTER) &&
7292                 (((dest->left->type & TYPE_MASK) == TYPE_VOID) ||
7293                         ((rval->left->type & TYPE_MASK) == TYPE_VOID))) {
7294                 compatible = 1;
7295         }
7296         /* If both types are the same without qualifiers we are good */
7297         else if (equiv_ptrs(dest, rval)) {
7298                 compatible = 1;
7299         }
7300         /* test for struct/union equality  */
7301         else if (equiv_types(dest, rval)) {
7302                 compatible = 1;
7303         }
7304         return compatible;
7305 }
7306
7307 static void write_compatible(struct compile_state *state,
7308         struct type *dest, struct type *rval)
7309 {
7310         if (!is_write_compatible(state, dest, rval)) {
7311                 FILE *fp = state->errout;
7312                 fprintf(fp, "dest: ");
7313                 name_of(fp, dest);
7314                 fprintf(fp,"\nrval: ");
7315                 name_of(fp, rval);
7316                 fprintf(fp, "\n");
7317                 error(state, 0, "Incompatible types in assignment");
7318         }
7319 }
7320
7321 static int is_init_compatible(struct compile_state *state,
7322         struct type *dest, struct type *rval)
7323 {
7324         int compatible = 0;
7325         if (is_write_compatible(state, dest, rval)) {
7326                 compatible = 1;
7327         }
7328         else if (equiv_types(dest, rval)) {
7329                 compatible = 1;
7330         }
7331         return compatible;
7332 }
7333
7334 static struct triple *write_expr(
7335         struct compile_state *state, struct triple *dest, struct triple *rval)
7336 {
7337         struct triple *def;
7338         int op;
7339
7340         def = 0;
7341         if (!rval) {
7342                 internal_error(state, 0, "missing rval");
7343         }
7344
7345         if (rval->op == OP_LIST) {
7346                 internal_error(state, 0, "expression of type OP_LIST?");
7347         }
7348         if (!is_lvalue(state, dest)) {
7349                 internal_error(state, 0, "writing to a non lvalue?");
7350         }
7351         if (dest->type->type & QUAL_CONST) {
7352                 internal_error(state, 0, "modifable lvalue expexted");
7353         }
7354
7355         write_compatible(state, dest->type, rval->type);
7356         if (!equiv_types(dest->type, rval->type)) {
7357                 rval = triple(state, OP_CONVERT, dest->type, rval, 0);
7358         }
7359
7360         /* Now figure out which assignment operator to use */
7361         op = -1;
7362         if (is_in_reg(state, dest)) {
7363                 def = triple(state, OP_WRITE, dest->type, rval, dest);
7364                 if (MISC(def, 0) != dest) {
7365                         internal_error(state, def, "huh?");
7366                 }
7367                 if (RHS(def, 0) != rval) {
7368                         internal_error(state, def, "huh?");
7369                 }
7370         } else {
7371                 def = triple(state, OP_STORE, dest->type, dest, rval);
7372         }
7373         if (def->type->type & QUAL_VOLATILE) {
7374                 def->id |= TRIPLE_FLAG_VOLATILE;
7375         }
7376         return def;
7377 }
7378
7379 static struct triple *init_expr(
7380         struct compile_state *state, struct triple *dest, struct triple *rval)
7381 {
7382         struct triple *def;
7383
7384         def = 0;
7385         if (!rval) {
7386                 internal_error(state, 0, "missing rval");
7387         }
7388         if ((dest->type->type & STOR_MASK) != STOR_PERM) {
7389                 rval = read_expr(state, rval);
7390                 def = write_expr(state, dest, rval);
7391         }
7392         else {
7393                 /* Fill in the array size if necessary */
7394                 if (((dest->type->type & TYPE_MASK) == TYPE_ARRAY) &&
7395                         ((rval->type->type & TYPE_MASK) == TYPE_ARRAY)) {
7396                         if (dest->type->elements == ELEMENT_COUNT_UNSPECIFIED) {
7397                                 dest->type->elements = rval->type->elements;
7398                         }
7399                 }
7400                 if (!equiv_types(dest->type, rval->type)) {
7401                         error(state, 0, "Incompatible types in inializer");
7402                 }
7403                 MISC(dest, 0) = rval;
7404                 insert_triple(state, dest, rval);
7405                 rval->id |= TRIPLE_FLAG_FLATTENED;
7406                 use_triple(MISC(dest, 0), dest);
7407         }
7408         return def;
7409 }
7410
7411 struct type *arithmetic_result(
7412         struct compile_state *state, struct triple *left, struct triple *right)
7413 {
7414         struct type *type;
7415         /* Sanity checks to ensure I am working with arithmetic types */
7416         arithmetic(state, left);
7417         arithmetic(state, right);
7418         type = new_type(
7419                 do_arithmetic_conversion(
7420                         get_basic_type(left->type),
7421                         get_basic_type(right->type)),
7422                 0, 0);
7423         return type;
7424 }
7425
7426 struct type *ptr_arithmetic_result(
7427         struct compile_state *state, struct triple *left, struct triple *right)
7428 {
7429         struct type *type;
7430         /* Sanity checks to ensure I am working with the proper types */
7431         ptr_arithmetic(state, left);
7432         arithmetic(state, right);
7433         if (TYPE_ARITHMETIC(left->type->type) && 
7434                 TYPE_ARITHMETIC(right->type->type)) {
7435                 type = arithmetic_result(state, left, right);
7436         }
7437         else if (TYPE_PTR(left->type->type)) {
7438                 type = left->type;
7439         }
7440         else {
7441                 internal_error(state, 0, "huh?");
7442                 type = 0;
7443         }
7444         return type;
7445 }
7446
7447 /* boolean helper function */
7448
7449 static struct triple *ltrue_expr(struct compile_state *state, 
7450         struct triple *expr)
7451 {
7452         switch(expr->op) {
7453         case OP_LTRUE:   case OP_LFALSE:  case OP_EQ:      case OP_NOTEQ:
7454         case OP_SLESS:   case OP_ULESS:   case OP_SMORE:   case OP_UMORE:
7455         case OP_SLESSEQ: case OP_ULESSEQ: case OP_SMOREEQ: case OP_UMOREEQ:
7456                 /* If the expression is already boolean do nothing */
7457                 break;
7458         default:
7459                 expr = triple(state, OP_LTRUE, &int_type, expr, 0);
7460                 break;
7461         }
7462         return expr;
7463 }
7464
7465 static struct triple *lfalse_expr(struct compile_state *state, 
7466         struct triple *expr)
7467 {
7468         return triple(state, OP_LFALSE, &int_type, expr, 0);
7469 }
7470
7471 static struct triple *mkland_expr(
7472         struct compile_state *state,
7473         struct triple *left, struct triple *right)
7474 {
7475         struct triple *def, *val, *var, *jmp, *mid, *end;
7476         struct triple *lstore, *rstore;
7477
7478         /* Generate some intermediate triples */
7479         end = label(state);
7480         var = variable(state, &int_type);
7481         
7482         /* Store the left hand side value */
7483         lstore = write_expr(state, var, left);
7484
7485         /* Jump if the value is false */
7486         jmp =  branch(state, end, 
7487                 lfalse_expr(state, read_expr(state, var)));
7488         mid = label(state);
7489         
7490         /* Store the right hand side value */
7491         rstore = write_expr(state, var, right);
7492
7493         /* An expression for the computed value */
7494         val = read_expr(state, var);
7495
7496         /* Generate the prog for a logical and */
7497         def = mkprog(state, var, lstore, jmp, mid, rstore, end, val, 0);
7498         
7499         return def;
7500 }
7501
7502 static struct triple *mklor_expr(
7503         struct compile_state *state,
7504         struct triple *left, struct triple *right)
7505 {
7506         struct triple *def, *val, *var, *jmp, *mid, *end;
7507
7508         /* Generate some intermediate triples */
7509         end = label(state);
7510         var = variable(state, &int_type);
7511         
7512         /* Store the left hand side value */
7513         left = write_expr(state, var, left);
7514         
7515         /* Jump if the value is true */
7516         jmp = branch(state, end, read_expr(state, var));
7517         mid = label(state);
7518         
7519         /* Store the right hand side value */
7520         right = write_expr(state, var, right);
7521                 
7522         /* An expression for the computed value*/
7523         val = read_expr(state, var);
7524
7525         /* Generate the prog for a logical or */
7526         def = mkprog(state, var, left, jmp, mid, right, end, val, 0);
7527
7528         return def;
7529 }
7530
7531 static struct triple *mkcond_expr(
7532         struct compile_state *state, 
7533         struct triple *test, struct triple *left, struct triple *right)
7534 {
7535         struct triple *def, *val, *var, *jmp1, *jmp2, *top, *mid, *end;
7536         struct type *result_type;
7537         unsigned int left_type, right_type;
7538         bool(state, test);
7539         left_type = left->type->type;
7540         right_type = right->type->type;
7541         result_type = 0;
7542         /* Both operands have arithmetic type */
7543         if (TYPE_ARITHMETIC(left_type) && TYPE_ARITHMETIC(right_type)) {
7544                 result_type = arithmetic_result(state, left, right);
7545         }
7546         /* Both operands have void type */
7547         else if (((left_type & TYPE_MASK) == TYPE_VOID) &&
7548                 ((right_type & TYPE_MASK) == TYPE_VOID)) {
7549                 result_type = &void_type;
7550         }
7551         /* pointers to the same type... */
7552         else if ((result_type = compatible_ptrs(left->type, right->type))) {
7553                 ;
7554         }
7555         /* Both operands are pointers and left is a pointer to void */
7556         else if (((left_type & TYPE_MASK) == TYPE_POINTER) &&
7557                 ((right_type & TYPE_MASK) == TYPE_POINTER) &&
7558                 ((left->type->left->type & TYPE_MASK) == TYPE_VOID)) {
7559                 result_type = right->type;
7560         }
7561         /* Both operands are pointers and right is a pointer to void */
7562         else if (((left_type & TYPE_MASK) == TYPE_POINTER) &&
7563                 ((right_type & TYPE_MASK) == TYPE_POINTER) &&
7564                 ((right->type->left->type & TYPE_MASK) == TYPE_VOID)) {
7565                 result_type = left->type;
7566         }
7567         if (!result_type) {
7568                 error(state, 0, "Incompatible types in conditional expression");
7569         }
7570         /* Generate some intermediate triples */
7571         mid = label(state);
7572         end = label(state);
7573         var = variable(state, result_type);
7574
7575         /* Branch if the test is false */
7576         jmp1 = branch(state, mid, lfalse_expr(state, read_expr(state, test)));
7577         top = label(state);
7578
7579         /* Store the left hand side value */
7580         left = write_expr(state, var, left);
7581
7582         /* Branch to the end */
7583         jmp2 = branch(state, end, 0);
7584
7585         /* Store the right hand side value */
7586         right = write_expr(state, var, right);
7587         
7588         /* An expression for the computed value */
7589         val = read_expr(state, var);
7590
7591         /* Generate the prog for a conditional expression */
7592         def = mkprog(state, var, jmp1, top, left, jmp2, mid, right, end, val, 0);
7593
7594         return def;
7595 }
7596
7597
7598 static int expr_depth(struct compile_state *state, struct triple *ins)
7599 {
7600 #warning "FIXME move optimal ordering of subexpressions into the optimizer"
7601         int count;
7602         count = 0;
7603         if (!ins || (ins->id & TRIPLE_FLAG_FLATTENED)) {
7604                 count = 0;
7605         }
7606         else if (ins->op == OP_DEREF) {
7607                 count = expr_depth(state, RHS(ins, 0)) - 1;
7608         }
7609         else if (ins->op == OP_VAL) {
7610                 count = expr_depth(state, RHS(ins, 0)) - 1;
7611         }
7612         else if (ins->op == OP_FCALL) {
7613                 /* Don't figure the depth of a call just guess it is huge */
7614                 count = 1000;
7615         }
7616         else {
7617                 struct triple **expr;
7618                 expr = triple_rhs(state, ins, 0);
7619                 for(;expr; expr = triple_rhs(state, ins, expr)) {
7620                         if (*expr) {
7621                                 int depth;
7622                                 depth = expr_depth(state, *expr);
7623                                 if (depth > count) {
7624                                         count = depth;
7625                                 }
7626                         }
7627                 }
7628         }
7629         return count + 1;
7630 }
7631
7632 static struct triple *flatten_generic(
7633         struct compile_state *state, struct triple *first, struct triple *ptr,
7634         int ignored)
7635 {
7636         struct rhs_vector {
7637                 int depth;
7638                 struct triple **ins;
7639         } vector[MAX_RHS];
7640         int i, rhs, lhs;
7641         /* Only operations with just a rhs and a lhs should come here */
7642         rhs = ptr->rhs;
7643         lhs = ptr->lhs;
7644         if (TRIPLE_SIZE(ptr) != lhs + rhs + ignored) {
7645                 internal_error(state, ptr, "unexpected args for: %d %s",
7646                         ptr->op, tops(ptr->op));
7647         }
7648         /* Find the depth of the rhs elements */
7649         for(i = 0; i < rhs; i++) {
7650                 vector[i].ins = &RHS(ptr, i);
7651                 vector[i].depth = expr_depth(state, *vector[i].ins);
7652         }
7653         /* Selection sort the rhs */
7654         for(i = 0; i < rhs; i++) {
7655                 int j, max = i;
7656                 for(j = i + 1; j < rhs; j++ ) {
7657                         if (vector[j].depth > vector[max].depth) {
7658                                 max = j;
7659                         }
7660                 }
7661                 if (max != i) {
7662                         struct rhs_vector tmp;
7663                         tmp = vector[i];
7664                         vector[i] = vector[max];
7665                         vector[max] = tmp;
7666                 }
7667         }
7668         /* Now flatten the rhs elements */
7669         for(i = 0; i < rhs; i++) {
7670                 *vector[i].ins = flatten(state, first, *vector[i].ins);
7671                 use_triple(*vector[i].ins, ptr);
7672         }
7673         if (lhs) {
7674                 insert_triple(state, first, ptr);
7675                 ptr->id |= TRIPLE_FLAG_FLATTENED;
7676                 ptr->id &= ~TRIPLE_FLAG_LOCAL;
7677                 
7678                 /* Now flatten the lhs elements */
7679                 for(i = 0; i < lhs; i++) {
7680                         struct triple **ins = &LHS(ptr, i);
7681                         *ins = flatten(state, first, *ins);
7682                         use_triple(*ins, ptr);
7683                 }
7684         }
7685         return ptr;
7686 }
7687
7688 static struct triple *flatten_prog(
7689         struct compile_state *state, struct triple *first, struct triple *ptr)
7690 {
7691         struct triple *head, *body, *val;
7692         head = RHS(ptr, 0);
7693         RHS(ptr, 0) = 0;
7694         val  = head->prev;
7695         body = head->next;
7696         release_triple(state, head);
7697         release_triple(state, ptr);
7698         val->next        = first;
7699         body->prev       = first->prev;
7700         body->prev->next = body;
7701         val->next->prev  = val;
7702
7703         if (triple_is_cbranch(state, body->prev) ||
7704                 triple_is_call(state, body->prev)) {
7705                 unuse_triple(first, body->prev);
7706                 use_triple(body, body->prev);
7707         }
7708         
7709         if (!(val->id & TRIPLE_FLAG_FLATTENED)) {
7710                 internal_error(state, val, "val not flattened?");
7711         }
7712
7713         return val;
7714 }
7715
7716
7717 static struct triple *flatten_part(
7718         struct compile_state *state, struct triple *first, struct triple *ptr)
7719 {
7720         if (!triple_is_part(state, ptr)) {
7721                 internal_error(state, ptr,  "not a part");
7722         }
7723         if (ptr->rhs || ptr->lhs || ptr->targ || (ptr->misc != 1)) {
7724                 internal_error(state, ptr, "unexpected args for: %d %s",
7725                         ptr->op, tops(ptr->op));
7726         }
7727         MISC(ptr, 0) = flatten(state, first, MISC(ptr, 0));
7728         use_triple(MISC(ptr, 0), ptr);
7729         return flatten_generic(state, first, ptr, 1);
7730 }
7731
7732 static struct triple *flatten(
7733         struct compile_state *state, struct triple *first, struct triple *ptr)
7734 {
7735         struct triple *orig_ptr;
7736         if (!ptr)
7737                 return 0;
7738         do {
7739                 orig_ptr = ptr;
7740                 /* Only flatten triples once */
7741                 if (ptr->id & TRIPLE_FLAG_FLATTENED) {
7742                         return ptr;
7743                 }
7744                 switch(ptr->op) {
7745                 case OP_VAL:
7746                         RHS(ptr, 0) = flatten(state, first, RHS(ptr, 0));
7747                         return MISC(ptr, 0);
7748                         break;
7749                 case OP_PROG:
7750                         ptr = flatten_prog(state, first, ptr);
7751                         break;
7752                 case OP_FCALL:
7753                         ptr = flatten_generic(state, first, ptr, 1);
7754                         insert_triple(state, first, ptr);
7755                         ptr->id |= TRIPLE_FLAG_FLATTENED;
7756                         ptr->id &= ~TRIPLE_FLAG_LOCAL;
7757                         if (ptr->next != ptr) {
7758                                 use_triple(ptr->next, ptr);
7759                         }
7760                         break;
7761                 case OP_READ:
7762                 case OP_LOAD:
7763                         RHS(ptr, 0) = flatten(state, first, RHS(ptr, 0));
7764                         use_triple(RHS(ptr, 0), ptr);
7765                         break;
7766                 case OP_WRITE:
7767                         ptr = flatten_generic(state, first, ptr, 1);
7768                         MISC(ptr, 0) = flatten(state, first, MISC(ptr, 0));
7769                         use_triple(MISC(ptr, 0), ptr);
7770                         break;
7771                 case OP_BRANCH:
7772                         use_triple(TARG(ptr, 0), ptr);
7773                         break;
7774                 case OP_CBRANCH:
7775                         RHS(ptr, 0) = flatten(state, first, RHS(ptr, 0));
7776                         use_triple(RHS(ptr, 0), ptr);
7777                         use_triple(TARG(ptr, 0), ptr);
7778                         insert_triple(state, first, ptr);
7779                         ptr->id |= TRIPLE_FLAG_FLATTENED;
7780                         ptr->id &= ~TRIPLE_FLAG_LOCAL;
7781                         if (ptr->next != ptr) {
7782                                 use_triple(ptr->next, ptr);
7783                         }
7784                         break;
7785                 case OP_CALL:
7786                         MISC(ptr, 0) = flatten(state, first, MISC(ptr, 0));
7787                         use_triple(MISC(ptr, 0), ptr);
7788                         use_triple(TARG(ptr, 0), ptr);
7789                         insert_triple(state, first, ptr);
7790                         ptr->id |= TRIPLE_FLAG_FLATTENED;
7791                         ptr->id &= ~TRIPLE_FLAG_LOCAL;
7792                         if (ptr->next != ptr) {
7793                                 use_triple(ptr->next, ptr);
7794                         }
7795                         break;
7796                 case OP_RET:
7797                         RHS(ptr, 0) = flatten(state, first, RHS(ptr, 0));
7798                         use_triple(RHS(ptr, 0), ptr);
7799                         break;
7800                 case OP_BLOBCONST:
7801                         insert_triple(state, state->global_pool, ptr);
7802                         ptr->id |= TRIPLE_FLAG_FLATTENED;
7803                         ptr->id &= ~TRIPLE_FLAG_LOCAL;
7804                         ptr = triple(state, OP_SDECL, ptr->type, ptr, 0);
7805                         use_triple(MISC(ptr, 0), ptr);
7806                         break;
7807                 case OP_DEREF:
7808                         /* Since OP_DEREF is just a marker delete it when I flatten it */
7809                         ptr = RHS(ptr, 0);
7810                         RHS(orig_ptr, 0) = 0;
7811                         free_triple(state, orig_ptr);
7812                         break;
7813                 case OP_DOT:
7814                         if (RHS(ptr, 0)->op == OP_DEREF) {
7815                                 struct triple *base, *left;
7816                                 ulong_t offset;
7817                                 base = MISC(ptr, 0);
7818                                 offset = bits_to_bytes(field_offset(state, base->type, ptr->u.field));
7819                                 left = RHS(base, 0);
7820                                 ptr = triple(state, OP_ADD, left->type, 
7821                                         read_expr(state, left),
7822                                         int_const(state, &ulong_type, offset));
7823                                 free_triple(state, base);
7824                         }
7825                         else {
7826                                 ptr = flatten_part(state, first, ptr);
7827                         }
7828                         break;
7829                 case OP_INDEX:
7830                         if (RHS(ptr, 0)->op == OP_DEREF) {
7831                                 struct triple *base, *left;
7832                                 ulong_t offset;
7833                                 base = MISC(ptr, 0);
7834                                 offset = bits_to_bytes(index_offset(state, base->type, ptr->u.cval));
7835                                 left = RHS(base, 0);
7836                                 ptr = triple(state, OP_ADD, left->type,
7837                                         read_expr(state, left),
7838                                         int_const(state, &long_type, offset));
7839                                 free_triple(state, base);
7840                         }
7841                         else {
7842                                 ptr = flatten_part(state, first, ptr);
7843                         }
7844                         break;
7845                 case OP_PIECE:
7846                         ptr = flatten_part(state, first, ptr);
7847                         use_triple(ptr, MISC(ptr, 0));
7848                         break;
7849                 case OP_ADDRCONST:
7850                         MISC(ptr, 0) = flatten(state, first, MISC(ptr, 0));
7851                         use_triple(MISC(ptr, 0), ptr);
7852                         break;
7853                 case OP_SDECL:
7854                         first = state->global_pool;
7855                         MISC(ptr, 0) = flatten(state, first, MISC(ptr, 0));
7856                         use_triple(MISC(ptr, 0), ptr);
7857                         insert_triple(state, first, ptr);
7858                         ptr->id |= TRIPLE_FLAG_FLATTENED;
7859                         ptr->id &= ~TRIPLE_FLAG_LOCAL;
7860                         return ptr;
7861                 case OP_ADECL:
7862                         ptr = flatten_generic(state, first, ptr, 0);
7863                         break;
7864                 default:
7865                         /* Flatten the easy cases we don't override */
7866                         ptr = flatten_generic(state, first, ptr, 0);
7867                         break;
7868                 }
7869         } while(ptr && (ptr != orig_ptr));
7870         if (ptr && !(ptr->id & TRIPLE_FLAG_FLATTENED)) {
7871                 insert_triple(state, first, ptr);
7872                 ptr->id |= TRIPLE_FLAG_FLATTENED;
7873                 ptr->id &= ~TRIPLE_FLAG_LOCAL;
7874         }
7875         return ptr;
7876 }
7877
7878 static void release_expr(struct compile_state *state, struct triple *expr)
7879 {
7880         struct triple *head;
7881         head = label(state);
7882         flatten(state, head, expr);
7883         while(head->next != head) {
7884                 release_triple(state, head->next);
7885         }
7886         free_triple(state, head);
7887 }
7888
7889 static int replace_rhs_use(struct compile_state *state,
7890         struct triple *orig, struct triple *new, struct triple *use)
7891 {
7892         struct triple **expr;
7893         int found;
7894         found = 0;
7895         expr = triple_rhs(state, use, 0);
7896         for(;expr; expr = triple_rhs(state, use, expr)) {
7897                 if (*expr == orig) {
7898                         *expr = new;
7899                         found = 1;
7900                 }
7901         }
7902         if (found) {
7903                 unuse_triple(orig, use);
7904                 use_triple(new, use);
7905         }
7906         return found;
7907 }
7908
7909 static int replace_lhs_use(struct compile_state *state,
7910         struct triple *orig, struct triple *new, struct triple *use)
7911 {
7912         struct triple **expr;
7913         int found;
7914         found = 0;
7915         expr = triple_lhs(state, use, 0);
7916         for(;expr; expr = triple_lhs(state, use, expr)) {
7917                 if (*expr == orig) {
7918                         *expr = new;
7919                         found = 1;
7920                 }
7921         }
7922         if (found) {
7923                 unuse_triple(orig, use);
7924                 use_triple(new, use);
7925         }
7926         return found;
7927 }
7928
7929 static int replace_misc_use(struct compile_state *state,
7930         struct triple *orig, struct triple *new, struct triple *use)
7931 {
7932         struct triple **expr;
7933         int found;
7934         found = 0;
7935         expr = triple_misc(state, use, 0);
7936         for(;expr; expr = triple_misc(state, use, expr)) {
7937                 if (*expr == orig) {
7938                         *expr = new;
7939                         found = 1;
7940                 }
7941         }
7942         if (found) {
7943                 unuse_triple(orig, use);
7944                 use_triple(new, use);
7945         }
7946         return found;
7947 }
7948
7949 static int replace_targ_use(struct compile_state *state,
7950         struct triple *orig, struct triple *new, struct triple *use)
7951 {
7952         struct triple **expr;
7953         int found;
7954         found = 0;
7955         expr = triple_targ(state, use, 0);
7956         for(;expr; expr = triple_targ(state, use, expr)) {
7957                 if (*expr == orig) {
7958                         *expr = new;
7959                         found = 1;
7960                 }
7961         }
7962         if (found) {
7963                 unuse_triple(orig, use);
7964                 use_triple(new, use);
7965         }
7966         return found;
7967 }
7968
7969 static void replace_use(struct compile_state *state,
7970         struct triple *orig, struct triple *new, struct triple *use)
7971 {
7972         int found;
7973         found = 0;
7974         found |= replace_rhs_use(state, orig, new, use);
7975         found |= replace_lhs_use(state, orig, new, use);
7976         found |= replace_misc_use(state, orig, new, use);
7977         found |= replace_targ_use(state, orig, new, use);
7978         if (!found) {
7979                 internal_error(state, use, "use without use");
7980         }
7981 }
7982
7983 static void propogate_use(struct compile_state *state,
7984         struct triple *orig, struct triple *new)
7985 {
7986         struct triple_set *user, *next;
7987         for(user = orig->use; user; user = next) {
7988                 /* Careful replace_use modifies the use chain and
7989                  * removes use.  So we must get a copy of the next
7990                  * entry early.
7991                  */
7992                 next = user->next;
7993                 replace_use(state, orig, new, user->member);
7994         }
7995         if (orig->use) {
7996                 internal_error(state, orig, "used after propogate_use");
7997         }
7998 }
7999
8000 /*
8001  * Code generators
8002  * ===========================
8003  */
8004
8005 static struct triple *mk_cast_expr(
8006         struct compile_state *state, struct type *type, struct triple *expr)
8007 {
8008         struct triple *def;
8009         def = read_expr(state, expr);
8010         def = triple(state, OP_CONVERT, type, def, 0);
8011         return def;
8012 }
8013
8014 static struct triple *mk_add_expr(
8015         struct compile_state *state, struct triple *left, struct triple *right)
8016 {
8017         struct type *result_type;
8018         /* Put pointer operands on the left */
8019         if (is_pointer(right)) {
8020                 struct triple *tmp;
8021                 tmp = left;
8022                 left = right;
8023                 right = tmp;
8024         }
8025         left  = read_expr(state, left);
8026         right = read_expr(state, right);
8027         result_type = ptr_arithmetic_result(state, left, right);
8028         if (is_pointer(left)) {
8029                 struct type *ptr_math;
8030                 int op;
8031                 if (is_signed(right->type)) {
8032                         ptr_math = &long_type;
8033                         op = OP_SMUL;
8034                 } else {
8035                         ptr_math = &ulong_type;
8036                         op = OP_UMUL;
8037                 }
8038                 if (!equiv_types(right->type, ptr_math)) {
8039                         right = mk_cast_expr(state, ptr_math, right);
8040                 }
8041                 right = triple(state, op, ptr_math, right, 
8042                         int_const(state, ptr_math, 
8043                                 size_of_in_bytes(state, left->type->left)));
8044         }
8045         return triple(state, OP_ADD, result_type, left, right);
8046 }
8047
8048 static struct triple *mk_sub_expr(
8049         struct compile_state *state, struct triple *left, struct triple *right)
8050 {
8051         struct type *result_type;
8052         result_type = ptr_arithmetic_result(state, left, right);
8053         left  = read_expr(state, left);
8054         right = read_expr(state, right);
8055         if (is_pointer(left)) {
8056                 struct type *ptr_math;
8057                 int op;
8058                 if (is_signed(right->type)) {
8059                         ptr_math = &long_type;
8060                         op = OP_SMUL;
8061                 } else {
8062                         ptr_math = &ulong_type;
8063                         op = OP_UMUL;
8064                 }
8065                 if (!equiv_types(right->type, ptr_math)) {
8066                         right = mk_cast_expr(state, ptr_math, right);
8067                 }
8068                 right = triple(state, op, ptr_math, right, 
8069                         int_const(state, ptr_math, 
8070                                 size_of_in_bytes(state, left->type->left)));
8071         }
8072         return triple(state, OP_SUB, result_type, left, right);
8073 }
8074
8075 static struct triple *mk_pre_inc_expr(
8076         struct compile_state *state, struct triple *def)
8077 {
8078         struct triple *val;
8079         lvalue(state, def);
8080         val = mk_add_expr(state, def, int_const(state, &int_type, 1));
8081         return triple(state, OP_VAL, def->type,
8082                 write_expr(state, def, val),
8083                 val);
8084 }
8085
8086 static struct triple *mk_pre_dec_expr(
8087         struct compile_state *state, struct triple *def)
8088 {
8089         struct triple *val;
8090         lvalue(state, def);
8091         val = mk_sub_expr(state, def, int_const(state, &int_type, 1));
8092         return triple(state, OP_VAL, def->type,
8093                 write_expr(state, def, val),
8094                 val);
8095 }
8096
8097 static struct triple *mk_post_inc_expr(
8098         struct compile_state *state, struct triple *def)
8099 {
8100         struct triple *val;
8101         lvalue(state, def);
8102         val = read_expr(state, def);
8103         return triple(state, OP_VAL, def->type,
8104                 write_expr(state, def,
8105                         mk_add_expr(state, val, int_const(state, &int_type, 1)))
8106                 , val);
8107 }
8108
8109 static struct triple *mk_post_dec_expr(
8110         struct compile_state *state, struct triple *def)
8111 {
8112         struct triple *val;
8113         lvalue(state, def);
8114         val = read_expr(state, def);
8115         return triple(state, OP_VAL, def->type, 
8116                 write_expr(state, def,
8117                         mk_sub_expr(state, val, int_const(state, &int_type, 1)))
8118                 , val);
8119 }
8120
8121 static struct triple *mk_subscript_expr(
8122         struct compile_state *state, struct triple *left, struct triple *right)
8123 {
8124         left  = read_expr(state, left);
8125         right = read_expr(state, right);
8126         if (!is_pointer(left) && !is_pointer(right)) {
8127                 error(state, left, "subscripted value is not a pointer");
8128         }
8129         return mk_deref_expr(state, mk_add_expr(state, left, right));
8130 }
8131
8132
8133 /*
8134  * Compile time evaluation
8135  * ===========================
8136  */
8137 static int is_const(struct triple *ins)
8138 {
8139         return IS_CONST_OP(ins->op);
8140 }
8141
8142 static int is_simple_const(struct triple *ins)
8143 {
8144         /* Is this a constant that u.cval has the value.
8145          * Or equivalently is this a constant that read_const
8146          * works on.
8147          * So far only OP_INTCONST qualifies.  
8148          */
8149         return (ins->op == OP_INTCONST);
8150 }
8151
8152 static int constants_equal(struct compile_state *state, 
8153         struct triple *left, struct triple *right)
8154 {
8155         int equal;
8156         if ((left->op == OP_UNKNOWNVAL) || (right->op == OP_UNKNOWNVAL)) {
8157                 equal = 0;
8158         }
8159         else if (!is_const(left) || !is_const(right)) {
8160                 equal = 0;
8161         }
8162         else if (left->op != right->op) {
8163                 equal = 0;
8164         }
8165         else if (!equiv_types(left->type, right->type)) {
8166                 equal = 0;
8167         }
8168         else {
8169                 equal = 0;
8170                 switch(left->op) {
8171                 case OP_INTCONST:
8172                         if (left->u.cval == right->u.cval) {
8173                                 equal = 1;
8174                         }
8175                         break;
8176                 case OP_BLOBCONST:
8177                 {
8178                         size_t lsize, rsize, bytes;
8179                         lsize = size_of(state, left->type);
8180                         rsize = size_of(state, right->type);
8181                         if (lsize != rsize) {
8182                                 break;
8183                         }
8184                         bytes = bits_to_bytes(lsize);
8185                         if (memcmp(left->u.blob, right->u.blob, bytes) == 0) {
8186                                 equal = 1;
8187                         }
8188                         break;
8189                 }
8190                 case OP_ADDRCONST:
8191                         if ((MISC(left, 0) == MISC(right, 0)) &&
8192                                 (left->u.cval == right->u.cval)) {
8193                                 equal = 1;
8194                         }
8195                         break;
8196                 default:
8197                         internal_error(state, left, "uknown constant type");
8198                         break;
8199                 }
8200         }
8201         return equal;
8202 }
8203
8204 static int is_zero(struct triple *ins)
8205 {
8206         return is_simple_const(ins) && (ins->u.cval == 0);
8207 }
8208
8209 static int is_one(struct triple *ins)
8210 {
8211         return is_simple_const(ins) && (ins->u.cval == 1);
8212 }
8213
8214 static long_t bit_count(ulong_t value)
8215 {
8216         int count;
8217         int i;
8218         count = 0;
8219         for(i = (sizeof(ulong_t)*8) -1; i >= 0; i--) {
8220                 ulong_t mask;
8221                 mask = 1;
8222                 mask <<= i;
8223                 if (value & mask) {
8224                         count++;
8225                 }
8226         }
8227         return count;
8228         
8229 }
8230 static long_t bsr(ulong_t value)
8231 {
8232         int i;
8233         for(i = (sizeof(ulong_t)*8) -1; i >= 0; i--) {
8234                 ulong_t mask;
8235                 mask = 1;
8236                 mask <<= i;
8237                 if (value & mask) {
8238                         return i;
8239                 }
8240         }
8241         return -1;
8242 }
8243
8244 static long_t bsf(ulong_t value)
8245 {
8246         int i;
8247         for(i = 0; i < (sizeof(ulong_t)*8); i++) {
8248                 ulong_t mask;
8249                 mask = 1;
8250                 mask <<= 1;
8251                 if (value & mask) {
8252                         return i;
8253                 }
8254         }
8255         return -1;
8256 }
8257
8258 static long_t log2(ulong_t value)
8259 {
8260         return bsr(value);
8261 }
8262
8263 static long_t tlog2(struct triple *ins)
8264 {
8265         return log2(ins->u.cval);
8266 }
8267
8268 static int is_pow2(struct triple *ins)
8269 {
8270         ulong_t value, mask;
8271         long_t log;
8272         if (!is_const(ins)) {
8273                 return 0;
8274         }
8275         value = ins->u.cval;
8276         log = log2(value);
8277         if (log == -1) {
8278                 return 0;
8279         }
8280         mask = 1;
8281         mask <<= log;
8282         return  ((value & mask) == value);
8283 }
8284
8285 static ulong_t read_const(struct compile_state *state,
8286         struct triple *ins, struct triple *rhs)
8287 {
8288         switch(rhs->type->type &TYPE_MASK) {
8289         case TYPE_CHAR:   
8290         case TYPE_SHORT:
8291         case TYPE_INT:
8292         case TYPE_LONG:
8293         case TYPE_UCHAR:   
8294         case TYPE_USHORT:  
8295         case TYPE_UINT:
8296         case TYPE_ULONG:
8297         case TYPE_POINTER:
8298         case TYPE_BITFIELD:
8299                 break;
8300         default:
8301                 fprintf(state->errout, "type: ");
8302                 name_of(state->errout, rhs->type);
8303                 fprintf(state->errout, "\n");
8304                 internal_warning(state, rhs, "bad type to read_const");
8305                 break;
8306         }
8307         if (!is_simple_const(rhs)) {
8308                 internal_error(state, rhs, "bad op to read_const");
8309         }
8310         return rhs->u.cval;
8311 }
8312
8313 static long_t read_sconst(struct compile_state *state,
8314         struct triple *ins, struct triple *rhs)
8315 {
8316         return (long_t)(rhs->u.cval);
8317 }
8318
8319 int const_ltrue(struct compile_state *state, struct triple *ins, struct triple *rhs)
8320 {
8321         if (!is_const(rhs)) {
8322                 internal_error(state, 0, "non const passed to const_true");
8323         }
8324         return !is_zero(rhs);
8325 }
8326
8327 int const_eq(struct compile_state *state, struct triple *ins,
8328         struct triple *left, struct triple *right)
8329 {
8330         int result;
8331         if (!is_const(left) || !is_const(right)) {
8332                 internal_warning(state, ins, "non const passed to const_eq");
8333                 result = -1;
8334         }
8335         else if (left == right) {
8336                 result = 1;
8337         }
8338         else if (is_simple_const(left) && is_simple_const(right)) {
8339                 ulong_t lval, rval;
8340                 lval = read_const(state, ins, left);
8341                 rval = read_const(state, ins, right);
8342                 result = (lval == rval);
8343         }
8344         else if ((left->op == OP_ADDRCONST) && 
8345                 (right->op == OP_ADDRCONST)) {
8346                 result = (MISC(left, 0) == MISC(right, 0)) &&
8347                         (left->u.cval == right->u.cval);
8348         }
8349         else {
8350                 internal_warning(state, ins, "incomparable constants passed to const_eq");
8351                 result = -1;
8352         }
8353         return result;
8354         
8355 }
8356
8357 int const_ucmp(struct compile_state *state, struct triple *ins,
8358         struct triple *left, struct triple *right)
8359 {
8360         int result;
8361         if (!is_const(left) || !is_const(right)) {
8362                 internal_warning(state, ins, "non const past to const_ucmp");
8363                 result = -2;
8364         }
8365         else if (left == right) {
8366                 result = 0;
8367         }
8368         else if (is_simple_const(left) && is_simple_const(right)) {
8369                 ulong_t lval, rval;
8370                 lval = read_const(state, ins, left);
8371                 rval = read_const(state, ins, right);
8372                 result = 0;
8373                 if (lval > rval) {
8374                         result = 1;
8375                 } else if (rval > lval) {
8376                         result = -1;
8377                 }
8378         }
8379         else if ((left->op == OP_ADDRCONST) && 
8380                 (right->op == OP_ADDRCONST) &&
8381                 (MISC(left, 0) == MISC(right, 0))) {
8382                 result = 0;
8383                 if (left->u.cval > right->u.cval) {
8384                         result = 1;
8385                 } else if (left->u.cval < right->u.cval) {
8386                         result = -1;
8387                 }
8388         }
8389         else {
8390                 internal_warning(state, ins, "incomparable constants passed to const_ucmp");
8391                 result = -2;
8392         }
8393         return result;
8394 }
8395
8396 int const_scmp(struct compile_state *state, struct triple *ins,
8397         struct triple *left, struct triple *right)
8398 {
8399         int result;
8400         if (!is_const(left) || !is_const(right)) {
8401                 internal_warning(state, ins, "non const past to ucmp_const");
8402                 result = -2;
8403         }
8404         else if (left == right) {
8405                 result = 0;
8406         }
8407         else if (is_simple_const(left) && is_simple_const(right)) {
8408                 long_t lval, rval;
8409                 lval = read_sconst(state, ins, left);
8410                 rval = read_sconst(state, ins, right);
8411                 result = 0;
8412                 if (lval > rval) {
8413                         result = 1;
8414                 } else if (rval > lval) {
8415                         result = -1;
8416                 }
8417         }
8418         else {
8419                 internal_warning(state, ins, "incomparable constants passed to const_scmp");
8420                 result = -2;
8421         }
8422         return result;
8423 }
8424
8425 static void unuse_rhs(struct compile_state *state, struct triple *ins)
8426 {
8427         struct triple **expr;
8428         expr = triple_rhs(state, ins, 0);
8429         for(;expr;expr = triple_rhs(state, ins, expr)) {
8430                 if (*expr) {
8431                         unuse_triple(*expr, ins);
8432                         *expr = 0;
8433                 }
8434         }
8435 }
8436
8437 static void unuse_lhs(struct compile_state *state, struct triple *ins)
8438 {
8439         struct triple **expr;
8440         expr = triple_lhs(state, ins, 0);
8441         for(;expr;expr = triple_lhs(state, ins, expr)) {
8442                 unuse_triple(*expr, ins);
8443                 *expr = 0;
8444         }
8445 }
8446
8447 static void unuse_misc(struct compile_state *state, struct triple *ins)
8448 {
8449         struct triple **expr;
8450         expr = triple_misc(state, ins, 0);
8451         for(;expr;expr = triple_misc(state, ins, expr)) {
8452                 unuse_triple(*expr, ins);
8453                 *expr = 0;
8454         }
8455 }
8456
8457 static void unuse_targ(struct compile_state *state, struct triple *ins)
8458 {
8459         int i;
8460         struct triple **slot;
8461         slot = &TARG(ins, 0);
8462         for(i = 0; i < ins->targ; i++) {
8463                 unuse_triple(slot[i], ins);
8464                 slot[i] = 0;
8465         }
8466 }
8467
8468 static void check_lhs(struct compile_state *state, struct triple *ins)
8469 {
8470         struct triple **expr;
8471         expr = triple_lhs(state, ins, 0);
8472         for(;expr;expr = triple_lhs(state, ins, expr)) {
8473                 internal_error(state, ins, "unexpected lhs");
8474         }
8475         
8476 }
8477
8478 static void check_misc(struct compile_state *state, struct triple *ins)
8479 {
8480         struct triple **expr;
8481         expr = triple_misc(state, ins, 0);
8482         for(;expr;expr = triple_misc(state, ins, expr)) {
8483                 if (*expr) {
8484                         internal_error(state, ins, "unexpected misc");
8485                 }
8486         }
8487 }
8488
8489 static void check_targ(struct compile_state *state, struct triple *ins)
8490 {
8491         struct triple **expr;
8492         expr = triple_targ(state, ins, 0);
8493         for(;expr;expr = triple_targ(state, ins, expr)) {
8494                 internal_error(state, ins, "unexpected targ");
8495         }
8496 }
8497
8498 static void wipe_ins(struct compile_state *state, struct triple *ins)
8499 {
8500         /* Becareful which instructions you replace the wiped
8501          * instruction with, as there are not enough slots
8502          * in all instructions to hold all others.
8503          */
8504         check_targ(state, ins);
8505         check_misc(state, ins);
8506         unuse_rhs(state, ins);
8507         unuse_lhs(state, ins);
8508         ins->lhs  = 0;
8509         ins->rhs  = 0;
8510         ins->misc = 0;
8511         ins->targ = 0;
8512 }
8513
8514 static void wipe_branch(struct compile_state *state, struct triple *ins)
8515 {
8516         /* Becareful which instructions you replace the wiped
8517          * instruction with, as there are not enough slots
8518          * in all instructions to hold all others.
8519          */
8520         unuse_rhs(state, ins);
8521         unuse_lhs(state, ins);
8522         unuse_misc(state, ins);
8523         unuse_targ(state, ins);
8524         ins->lhs  = 0;
8525         ins->rhs  = 0;
8526         ins->misc = 0;
8527         ins->targ = 0;
8528 }
8529
8530 static void mkcopy(struct compile_state *state, 
8531         struct triple *ins, struct triple *rhs)
8532 {
8533         struct block *block;
8534         if (!equiv_types(ins->type, rhs->type)) {
8535                 FILE *fp = state->errout;
8536                 fprintf(fp, "src type: ");
8537                 name_of(fp, rhs->type);
8538                 fprintf(fp, "\ndst type: ");
8539                 name_of(fp, ins->type);
8540                 fprintf(fp, "\n");
8541                 internal_error(state, ins, "mkcopy type mismatch");
8542         }
8543         block = block_of_triple(state, ins);
8544         wipe_ins(state, ins);
8545         ins->op = OP_COPY;
8546         ins->rhs  = 1;
8547         ins->u.block = block;
8548         RHS(ins, 0) = rhs;
8549         use_triple(RHS(ins, 0), ins);
8550 }
8551
8552 static void mkconst(struct compile_state *state, 
8553         struct triple *ins, ulong_t value)
8554 {
8555         if (!is_integral(ins) && !is_pointer(ins)) {
8556                 fprintf(state->errout, "type: ");
8557                 name_of(state->errout, ins->type);
8558                 fprintf(state->errout, "\n");
8559                 internal_error(state, ins, "unknown type to make constant value: %ld",
8560                         value);
8561         }
8562         wipe_ins(state, ins);
8563         ins->op = OP_INTCONST;
8564         ins->u.cval = value;
8565 }
8566
8567 static void mkaddr_const(struct compile_state *state,
8568         struct triple *ins, struct triple *sdecl, ulong_t value)
8569 {
8570         if ((sdecl->op != OP_SDECL) && (sdecl->op != OP_LABEL)) {
8571                 internal_error(state, ins, "bad base for addrconst");
8572         }
8573         wipe_ins(state, ins);
8574         ins->op = OP_ADDRCONST;
8575         ins->misc = 1;
8576         MISC(ins, 0) = sdecl;
8577         ins->u.cval = value;
8578         use_triple(sdecl, ins);
8579 }
8580
8581 #if DEBUG_DECOMPOSE_PRINT_TUPLES
8582 static void print_tuple(struct compile_state *state, 
8583         struct triple *ins, struct triple *tuple)
8584 {
8585         FILE *fp = state->dbgout;
8586         fprintf(fp, "%5s %p tuple: %p ", tops(ins->op), ins, tuple);
8587         name_of(fp, tuple->type);
8588         if (tuple->lhs > 0) {
8589                 fprintf(fp, " lhs: ");
8590                 name_of(fp, LHS(tuple, 0)->type);
8591         }
8592         fprintf(fp, "\n");
8593         
8594 }
8595 #endif
8596
8597 static struct triple *decompose_with_tuple(struct compile_state *state, 
8598         struct triple *ins, struct triple *tuple)
8599 {
8600         struct triple *next;
8601         next = ins->next;
8602         flatten(state, next, tuple);
8603 #if DEBUG_DECOMPOSE_PRINT_TUPLES
8604         print_tuple(state, ins, tuple);
8605 #endif
8606
8607         if (!is_compound_type(tuple->type) && (tuple->lhs > 0)) {
8608                 struct triple *tmp;
8609                 if (tuple->lhs != 1) {
8610                         internal_error(state, tuple, "plain type in multiple registers?");
8611                 }
8612                 tmp = LHS(tuple, 0);
8613                 release_triple(state, tuple);
8614                 tuple = tmp;
8615         }
8616
8617         propogate_use(state, ins, tuple);
8618         release_triple(state, ins);
8619         
8620         return next;
8621 }
8622
8623 static struct triple *decompose_unknownval(struct compile_state *state,
8624         struct triple *ins)
8625 {
8626         struct triple *tuple;
8627         ulong_t i;
8628
8629 #if DEBUG_DECOMPOSE_HIRES
8630         FILE *fp = state->dbgout;
8631         fprintf(fp, "unknown type: ");
8632         name_of(fp, ins->type);
8633         fprintf(fp, "\n");
8634 #endif
8635
8636         get_occurance(ins->occurance);
8637         tuple = alloc_triple(state, OP_TUPLE, ins->type, -1, -1, 
8638                 ins->occurance);
8639
8640         for(i = 0; i < tuple->lhs; i++) {
8641                 struct type *piece_type;
8642                 struct triple *unknown;
8643
8644                 piece_type = reg_type(state, ins->type, i * REG_SIZEOF_REG);
8645                 get_occurance(tuple->occurance);
8646                 unknown = alloc_triple(state, OP_UNKNOWNVAL, piece_type, 0, 0,
8647                         tuple->occurance);
8648                 LHS(tuple, i) = unknown;
8649         }
8650         return decompose_with_tuple(state, ins, tuple);
8651 }
8652
8653
8654 static struct triple *decompose_read(struct compile_state *state, 
8655         struct triple *ins)
8656 {
8657         struct triple *tuple, *lval;
8658         ulong_t i;
8659
8660         lval = RHS(ins, 0);
8661
8662         if (lval->op == OP_PIECE) {
8663                 return ins->next;
8664         }
8665         get_occurance(ins->occurance);
8666         tuple = alloc_triple(state, OP_TUPLE, lval->type, -1, -1,
8667                 ins->occurance);
8668
8669         if ((tuple->lhs != lval->lhs) &&
8670                 (!triple_is_def(state, lval) || (tuple->lhs != 1))) 
8671         {
8672                 internal_error(state, ins, "lhs size inconsistency?");
8673         }
8674         for(i = 0; i < tuple->lhs; i++) {
8675                 struct triple *piece, *read, *bitref;
8676                 if ((i != 0) || !triple_is_def(state, lval)) {
8677                         piece = LHS(lval, i);
8678                 } else {
8679                         piece = lval;
8680                 }
8681
8682                 /* See if the piece is really a bitref */
8683                 bitref = 0;
8684                 if (piece->op == OP_BITREF) {
8685                         bitref = piece;
8686                         piece = RHS(bitref, 0);
8687                 }
8688
8689                 get_occurance(tuple->occurance);
8690                 read = alloc_triple(state, OP_READ, piece->type, -1, -1, 
8691                         tuple->occurance);
8692                 RHS(read, 0) = piece;
8693
8694                 if (bitref) {
8695                         struct triple *extract;
8696                         int op;
8697                         if (is_signed(bitref->type->left)) {
8698                                 op = OP_SEXTRACT;
8699                         } else {
8700                                 op = OP_UEXTRACT;
8701                         }
8702                         get_occurance(tuple->occurance);
8703                         extract = alloc_triple(state, op, bitref->type, -1, -1,
8704                                 tuple->occurance);
8705                         RHS(extract, 0) = read;
8706                         extract->u.bitfield.size   = bitref->u.bitfield.size;
8707                         extract->u.bitfield.offset = bitref->u.bitfield.offset;
8708
8709                         read = extract;
8710                 }
8711
8712                 LHS(tuple, i) = read;
8713         }
8714         return decompose_with_tuple(state, ins, tuple);
8715 }
8716
8717 static struct triple *decompose_write(struct compile_state *state, 
8718         struct triple *ins)
8719 {
8720         struct triple *tuple, *lval, *val;
8721         ulong_t i;
8722         
8723         lval = MISC(ins, 0);
8724         val = RHS(ins, 0);
8725         get_occurance(ins->occurance);
8726         tuple = alloc_triple(state, OP_TUPLE, ins->type, -1, -1,
8727                 ins->occurance);
8728
8729         if ((tuple->lhs != lval->lhs) &&
8730                 (!triple_is_def(state, lval) || tuple->lhs != 1)) 
8731         {
8732                 internal_error(state, ins, "lhs size inconsistency?");
8733         }
8734         for(i = 0; i < tuple->lhs; i++) {
8735                 struct triple *piece, *write, *pval, *bitref;
8736                 if ((i != 0) || !triple_is_def(state, lval)) {
8737                         piece = LHS(lval, i);
8738                 } else {
8739                         piece = lval;
8740                 }
8741                 if ((i == 0) && (tuple->lhs == 1) && (val->lhs == 0)) {
8742                         pval = val;
8743                 }
8744                 else {
8745                         if (i > val->lhs) {
8746                                 internal_error(state, ins, "lhs size inconsistency?");
8747                         }
8748                         pval = LHS(val, i);
8749                 }
8750                 
8751                 /* See if the piece is really a bitref */
8752                 bitref = 0;
8753                 if (piece->op == OP_BITREF) {
8754                         struct triple *read, *deposit;
8755                         bitref = piece;
8756                         piece = RHS(bitref, 0);
8757
8758                         /* Read the destination register */
8759                         get_occurance(tuple->occurance);
8760                         read = alloc_triple(state, OP_READ, piece->type, -1, -1,
8761                                 tuple->occurance);
8762                         RHS(read, 0) = piece;
8763
8764                         /* Deposit the new bitfield value */
8765                         get_occurance(tuple->occurance);
8766                         deposit = alloc_triple(state, OP_DEPOSIT, piece->type, -1, -1,
8767                                 tuple->occurance);
8768                         RHS(deposit, 0) = read;
8769                         RHS(deposit, 1) = pval;
8770                         deposit->u.bitfield.size   = bitref->u.bitfield.size;
8771                         deposit->u.bitfield.offset = bitref->u.bitfield.offset;
8772
8773                         /* Now write the newly generated value */
8774                         pval = deposit;
8775                 }
8776
8777                 get_occurance(tuple->occurance);
8778                 write = alloc_triple(state, OP_WRITE, piece->type, -1, -1, 
8779                         tuple->occurance);
8780                 MISC(write, 0) = piece;
8781                 RHS(write, 0) = pval;
8782                 LHS(tuple, i) = write;
8783         }
8784         return decompose_with_tuple(state, ins, tuple);
8785 }
8786
8787 struct decompose_load_info {
8788         struct occurance *occurance;
8789         struct triple *lval;
8790         struct triple *tuple;
8791 };
8792 static void decompose_load_cb(struct compile_state *state,
8793         struct type *type, size_t reg_offset, size_t mem_offset, void *arg)
8794 {
8795         struct decompose_load_info *info = arg;
8796         struct triple *load;
8797         
8798         if (reg_offset > info->tuple->lhs) {
8799                 internal_error(state, info->tuple, "lhs to small?");
8800         }
8801         get_occurance(info->occurance);
8802         load = alloc_triple(state, OP_LOAD, type, -1, -1, info->occurance);
8803         RHS(load, 0) = mk_addr_expr(state, info->lval, mem_offset);
8804         LHS(info->tuple, reg_offset/REG_SIZEOF_REG) = load;
8805 }
8806
8807 static struct triple *decompose_load(struct compile_state *state, 
8808         struct triple *ins)
8809 {
8810         struct triple *tuple;
8811         struct decompose_load_info info;
8812
8813         if (!is_compound_type(ins->type)) {
8814                 return ins->next;
8815         }
8816         get_occurance(ins->occurance);
8817         tuple = alloc_triple(state, OP_TUPLE, ins->type, -1, -1,
8818                 ins->occurance);
8819
8820         info.occurance = ins->occurance;
8821         info.lval      = RHS(ins, 0);
8822         info.tuple     = tuple;
8823         walk_type_fields(state, ins->type, 0, 0, decompose_load_cb, &info);
8824
8825         return decompose_with_tuple(state, ins, tuple);
8826 }
8827
8828
8829 struct decompose_store_info {
8830         struct occurance *occurance;
8831         struct triple *lval;
8832         struct triple *val;
8833         struct triple *tuple;
8834 };
8835 static void decompose_store_cb(struct compile_state *state,
8836         struct type *type, size_t reg_offset, size_t mem_offset, void *arg)
8837 {
8838         struct decompose_store_info *info = arg;
8839         struct triple *store;
8840         
8841         if (reg_offset > info->tuple->lhs) {
8842                 internal_error(state, info->tuple, "lhs to small?");
8843         }
8844         get_occurance(info->occurance);
8845         store = alloc_triple(state, OP_STORE, type, -1, -1, info->occurance);
8846         RHS(store, 0) = mk_addr_expr(state, info->lval, mem_offset);
8847         RHS(store, 1) = LHS(info->val, reg_offset);
8848         LHS(info->tuple, reg_offset/REG_SIZEOF_REG) = store;
8849 }
8850
8851 static struct triple *decompose_store(struct compile_state *state, 
8852         struct triple *ins)
8853 {
8854         struct triple *tuple;
8855         struct decompose_store_info info;
8856
8857         if (!is_compound_type(ins->type)) {
8858                 return ins->next;
8859         }
8860         get_occurance(ins->occurance);
8861         tuple = alloc_triple(state, OP_TUPLE, ins->type, -1, -1,
8862                 ins->occurance);
8863
8864         info.occurance = ins->occurance;
8865         info.lval      = RHS(ins, 0);
8866         info.val       = RHS(ins, 1);
8867         info.tuple     = tuple;
8868         walk_type_fields(state, ins->type, 0, 0, decompose_store_cb, &info);
8869
8870         return decompose_with_tuple(state, ins, tuple);
8871 }
8872
8873 static struct triple *decompose_dot(struct compile_state *state, 
8874         struct triple *ins)
8875 {
8876         struct triple *tuple, *lval;
8877         struct type *type;
8878         size_t reg_offset;
8879         int i, idx;
8880
8881         lval = MISC(ins, 0);
8882         reg_offset = field_reg_offset(state, lval->type, ins->u.field);
8883         idx  = reg_offset/REG_SIZEOF_REG;
8884         type = field_type(state, lval->type, ins->u.field);
8885 #if DEBUG_DECOMPOSE_HIRES
8886         {
8887                 FILE *fp = state->dbgout;
8888                 fprintf(fp, "field type: ");
8889                 name_of(fp, type);
8890                 fprintf(fp, "\n");
8891         }
8892 #endif
8893
8894         get_occurance(ins->occurance);
8895         tuple = alloc_triple(state, OP_TUPLE, type, -1, -1, 
8896                 ins->occurance);
8897
8898         if (((ins->type->type & TYPE_MASK) == TYPE_BITFIELD) &&
8899                 (tuple->lhs != 1))
8900         {
8901                 internal_error(state, ins, "multi register bitfield?");
8902         }
8903
8904         for(i = 0; i < tuple->lhs; i++, idx++) {
8905                 struct triple *piece;
8906                 if (!triple_is_def(state, lval)) {
8907                         if (idx > lval->lhs) {
8908                                 internal_error(state, ins, "inconsistent lhs count");
8909                         }
8910                         piece = LHS(lval, idx);
8911                 } else {
8912                         if (idx != 0) {
8913                                 internal_error(state, ins, "bad reg_offset into def");
8914                         }
8915                         if (i != 0) {
8916                                 internal_error(state, ins, "bad reg count from def");
8917                         }
8918                         piece = lval;
8919                 }
8920
8921                 /* Remember the offset of the bitfield */
8922                 if ((type->type & TYPE_MASK) == TYPE_BITFIELD) {
8923                         get_occurance(ins->occurance);
8924                         piece = build_triple(state, OP_BITREF, type, piece, 0,
8925                                 ins->occurance);
8926                         piece->u.bitfield.size   = size_of(state, type);
8927                         piece->u.bitfield.offset = reg_offset % REG_SIZEOF_REG;
8928                 }
8929                 else if ((reg_offset % REG_SIZEOF_REG) != 0) {
8930                         internal_error(state, ins, 
8931                                 "request for a nonbitfield sub register?");
8932                 }
8933
8934                 LHS(tuple, i) = piece;
8935         }
8936
8937         return decompose_with_tuple(state, ins, tuple);
8938 }
8939
8940 static struct triple *decompose_index(struct compile_state *state, 
8941         struct triple *ins)
8942 {
8943         struct triple *tuple, *lval;
8944         struct type *type;
8945         int i, idx;
8946
8947         lval = MISC(ins, 0);
8948         idx = index_reg_offset(state, lval->type, ins->u.cval)/REG_SIZEOF_REG;
8949         type = index_type(state, lval->type, ins->u.cval);
8950 #if DEBUG_DECOMPOSE_HIRES
8951 {
8952         FILE *fp = state->dbgout;
8953         fprintf(fp, "index type: ");
8954         name_of(fp, type);
8955         fprintf(fp, "\n");
8956 }
8957 #endif
8958
8959         get_occurance(ins->occurance);
8960         tuple = alloc_triple(state, OP_TUPLE, type, -1, -1, 
8961                 ins->occurance);
8962
8963         for(i = 0; i < tuple->lhs; i++, idx++) {
8964                 struct triple *piece;
8965                 if (!triple_is_def(state, lval)) {
8966                         if (idx > lval->lhs) {
8967                                 internal_error(state, ins, "inconsistent lhs count");
8968                         }
8969                         piece = LHS(lval, idx);
8970                 } else {
8971                         if (idx != 0) {
8972                                 internal_error(state, ins, "bad reg_offset into def");
8973                         }
8974                         if (i != 0) {
8975                                 internal_error(state, ins, "bad reg count from def");
8976                         }
8977                         piece = lval;
8978                 }
8979                 LHS(tuple, i) = piece;
8980         }
8981
8982         return decompose_with_tuple(state, ins, tuple);
8983 }
8984
8985 static void decompose_compound_types(struct compile_state *state)
8986 {
8987         struct triple *ins, *next, *first;
8988         FILE *fp;
8989         fp = state->dbgout;
8990         first = state->first;
8991         ins = first;
8992
8993         /* Pass one expand compound values into pseudo registers.
8994          */
8995         next = first;
8996         do {
8997                 ins = next;
8998                 next = ins->next;
8999                 switch(ins->op) {
9000                 case OP_UNKNOWNVAL:
9001                         next = decompose_unknownval(state, ins);
9002                         break;
9003
9004                 case OP_READ:
9005                         next = decompose_read(state, ins);
9006                         break;
9007
9008                 case OP_WRITE:
9009                         next = decompose_write(state, ins);
9010                         break;
9011
9012
9013                 /* Be very careful with the load/store logic. These
9014                  * operations must convert from the in register layout
9015                  * to the in memory layout, which is nontrivial.
9016                  */
9017                 case OP_LOAD:
9018                         next = decompose_load(state, ins);
9019                         break;
9020                 case OP_STORE:
9021                         next = decompose_store(state, ins);
9022                         break;
9023
9024                 case OP_DOT:
9025                         next = decompose_dot(state, ins);
9026                         break;
9027                 case OP_INDEX:
9028                         next = decompose_index(state, ins);
9029                         break;
9030                         
9031                 }
9032 #if DEBUG_DECOMPOSE_HIRES
9033                 fprintf(fp, "decompose next: %p \n", next);
9034                 fflush(fp);
9035                 fprintf(fp, "next->op: %d %s\n",
9036                         next->op, tops(next->op));
9037                 /* High resolution debugging mode */
9038                 print_triples(state);
9039 #endif
9040         } while (next != first);
9041
9042         /* Pass two remove the tuples.
9043          */
9044         ins = first;
9045         do {
9046                 next = ins->next;
9047                 if (ins->op == OP_TUPLE) {
9048                         if (ins->use) {
9049                                 internal_error(state, ins, "tuple used");
9050                         }
9051                         else {
9052                                 release_triple(state, ins);
9053                         }
9054                 } 
9055                 ins = next;
9056         } while(ins != first);
9057         ins = first;
9058         do {
9059                 next = ins->next;
9060                 if (ins->op == OP_BITREF) {
9061                         if (ins->use) {
9062                                 internal_error(state, ins, "bitref used");
9063                         } 
9064                         else {
9065                                 release_triple(state, ins);
9066                         }
9067                 }
9068                 ins = next;
9069         } while(ins != first);
9070
9071         /* Pass three verify the state and set ->id to 0.
9072          */
9073         next = first;
9074         do {
9075                 ins = next;
9076                 next = ins->next;
9077                 ins->id &= ~TRIPLE_FLAG_FLATTENED;
9078                 if (triple_stores_block(state, ins)) {
9079                         ins->u.block = 0;
9080                 }
9081                 if (triple_is_def(state, ins)) {
9082                         if (reg_size_of(state, ins->type) > REG_SIZEOF_REG) {
9083                                 internal_error(state, ins, "multi register value remains?");
9084                         }
9085                 }
9086                 if (ins->op == OP_DOT) {
9087                         internal_error(state, ins, "OP_DOT remains?");
9088                 }
9089                 if (ins->op == OP_INDEX) {
9090                         internal_error(state, ins, "OP_INDEX remains?");
9091                 }
9092                 if (ins->op == OP_BITREF) {
9093                         internal_error(state, ins, "OP_BITREF remains?");
9094                 }
9095                 if (ins->op == OP_TUPLE) {
9096                         internal_error(state, ins, "OP_TUPLE remains?");
9097                 }
9098         } while(next != first);
9099 }
9100
9101 /* For those operations that cannot be simplified */
9102 static void simplify_noop(struct compile_state *state, struct triple *ins)
9103 {
9104         return;
9105 }
9106
9107 static void simplify_smul(struct compile_state *state, struct triple *ins)
9108 {
9109         if (is_const(RHS(ins, 0)) && !is_const(RHS(ins, 1))) {
9110                 struct triple *tmp;
9111                 tmp = RHS(ins, 0);
9112                 RHS(ins, 0) = RHS(ins, 1);
9113                 RHS(ins, 1) = tmp;
9114         }
9115         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
9116                 long_t left, right;
9117                 left  = read_sconst(state, ins, RHS(ins, 0));
9118                 right = read_sconst(state, ins, RHS(ins, 1));
9119                 mkconst(state, ins, left * right);
9120         }
9121         else if (is_zero(RHS(ins, 1))) {
9122                 mkconst(state, ins, 0);
9123         }
9124         else if (is_one(RHS(ins, 1))) {
9125                 mkcopy(state, ins, RHS(ins, 0));
9126         }
9127         else if (is_pow2(RHS(ins, 1))) {
9128                 struct triple *val;
9129                 val = int_const(state, ins->type, tlog2(RHS(ins, 1)));
9130                 ins->op = OP_SL;
9131                 insert_triple(state, state->global_pool, val);
9132                 unuse_triple(RHS(ins, 1), ins);
9133                 use_triple(val, ins);
9134                 RHS(ins, 1) = val;
9135         }
9136 }
9137
9138 static void simplify_umul(struct compile_state *state, struct triple *ins)
9139 {
9140         if (is_const(RHS(ins, 0)) && !is_const(RHS(ins, 1))) {
9141                 struct triple *tmp;
9142                 tmp = RHS(ins, 0);
9143                 RHS(ins, 0) = RHS(ins, 1);
9144                 RHS(ins, 1) = tmp;
9145         }
9146         if (is_simple_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9147                 ulong_t left, right;
9148                 left  = read_const(state, ins, RHS(ins, 0));
9149                 right = read_const(state, ins, RHS(ins, 1));
9150                 mkconst(state, ins, left * right);
9151         }
9152         else if (is_zero(RHS(ins, 1))) {
9153                 mkconst(state, ins, 0);
9154         }
9155         else if (is_one(RHS(ins, 1))) {
9156                 mkcopy(state, ins, RHS(ins, 0));
9157         }
9158         else if (is_pow2(RHS(ins, 1))) {
9159                 struct triple *val;
9160                 val = int_const(state, ins->type, tlog2(RHS(ins, 1)));
9161                 ins->op = OP_SL;
9162                 insert_triple(state, state->global_pool, val);
9163                 unuse_triple(RHS(ins, 1), ins);
9164                 use_triple(val, ins);
9165                 RHS(ins, 1) = val;
9166         }
9167 }
9168
9169 static void simplify_sdiv(struct compile_state *state, struct triple *ins)
9170 {
9171         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
9172                 long_t left, right;
9173                 left  = read_sconst(state, ins, RHS(ins, 0));
9174                 right = read_sconst(state, ins, RHS(ins, 1));
9175                 mkconst(state, ins, left / right);
9176         }
9177         else if (is_zero(RHS(ins, 0))) {
9178                 mkconst(state, ins, 0);
9179         }
9180         else if (is_zero(RHS(ins, 1))) {
9181                 error(state, ins, "division by zero");
9182         }
9183         else if (is_one(RHS(ins, 1))) {
9184                 mkcopy(state, ins, RHS(ins, 0));
9185         }
9186         else if (is_pow2(RHS(ins, 1))) {
9187                 struct triple *val;
9188                 val = int_const(state, ins->type, tlog2(RHS(ins, 1)));
9189                 ins->op = OP_SSR;
9190                 insert_triple(state, state->global_pool, val);
9191                 unuse_triple(RHS(ins, 1), ins);
9192                 use_triple(val, ins);
9193                 RHS(ins, 1) = val;
9194         }
9195 }
9196
9197 static void simplify_udiv(struct compile_state *state, struct triple *ins)
9198 {
9199         if (is_simple_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9200                 ulong_t left, right;
9201                 left  = read_const(state, ins, RHS(ins, 0));
9202                 right = read_const(state, ins, RHS(ins, 1));
9203                 mkconst(state, ins, left / right);
9204         }
9205         else if (is_zero(RHS(ins, 0))) {
9206                 mkconst(state, ins, 0);
9207         }
9208         else if (is_zero(RHS(ins, 1))) {
9209                 error(state, ins, "division by zero");
9210         }
9211         else if (is_one(RHS(ins, 1))) {
9212                 mkcopy(state, ins, RHS(ins, 0));
9213         }
9214         else if (is_pow2(RHS(ins, 1))) {
9215                 struct triple *val;
9216                 val = int_const(state, ins->type, tlog2(RHS(ins, 1)));
9217                 ins->op = OP_USR;
9218                 insert_triple(state, state->global_pool, val);
9219                 unuse_triple(RHS(ins, 1), ins);
9220                 use_triple(val, ins);
9221                 RHS(ins, 1) = val;
9222         }
9223 }
9224
9225 static void simplify_smod(struct compile_state *state, struct triple *ins)
9226 {
9227         if (is_simple_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9228                 long_t left, right;
9229                 left  = read_const(state, ins, RHS(ins, 0));
9230                 right = read_const(state, ins, RHS(ins, 1));
9231                 mkconst(state, ins, left % right);
9232         }
9233         else if (is_zero(RHS(ins, 0))) {
9234                 mkconst(state, ins, 0);
9235         }
9236         else if (is_zero(RHS(ins, 1))) {
9237                 error(state, ins, "division by zero");
9238         }
9239         else if (is_one(RHS(ins, 1))) {
9240                 mkconst(state, ins, 0);
9241         }
9242         else if (is_pow2(RHS(ins, 1))) {
9243                 struct triple *val;
9244                 val = int_const(state, ins->type, RHS(ins, 1)->u.cval - 1);
9245                 ins->op = OP_AND;
9246                 insert_triple(state, state->global_pool, val);
9247                 unuse_triple(RHS(ins, 1), ins);
9248                 use_triple(val, ins);
9249                 RHS(ins, 1) = val;
9250         }
9251 }
9252
9253 static void simplify_umod(struct compile_state *state, struct triple *ins)
9254 {
9255         if (is_simple_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9256                 ulong_t left, right;
9257                 left  = read_const(state, ins, RHS(ins, 0));
9258                 right = read_const(state, ins, RHS(ins, 1));
9259                 mkconst(state, ins, left % right);
9260         }
9261         else if (is_zero(RHS(ins, 0))) {
9262                 mkconst(state, ins, 0);
9263         }
9264         else if (is_zero(RHS(ins, 1))) {
9265                 error(state, ins, "division by zero");
9266         }
9267         else if (is_one(RHS(ins, 1))) {
9268                 mkconst(state, ins, 0);
9269         }
9270         else if (is_pow2(RHS(ins, 1))) {
9271                 struct triple *val;
9272                 val = int_const(state, ins->type, RHS(ins, 1)->u.cval - 1);
9273                 ins->op = OP_AND;
9274                 insert_triple(state, state->global_pool, val);
9275                 unuse_triple(RHS(ins, 1), ins);
9276                 use_triple(val, ins);
9277                 RHS(ins, 1) = val;
9278         }
9279 }
9280
9281 static void simplify_add(struct compile_state *state, struct triple *ins)
9282 {
9283         /* start with the pointer on the left */
9284         if (is_pointer(RHS(ins, 1))) {
9285                 struct triple *tmp;
9286                 tmp = RHS(ins, 0);
9287                 RHS(ins, 0) = RHS(ins, 1);
9288                 RHS(ins, 1) = tmp;
9289         }
9290         if (is_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9291                 if (RHS(ins, 0)->op == OP_INTCONST) {
9292                         ulong_t left, right;
9293                         left  = read_const(state, ins, RHS(ins, 0));
9294                         right = read_const(state, ins, RHS(ins, 1));
9295                         mkconst(state, ins, left + right);
9296                 }
9297                 else if (RHS(ins, 0)->op == OP_ADDRCONST) {
9298                         struct triple *sdecl;
9299                         ulong_t left, right;
9300                         sdecl = MISC(RHS(ins, 0), 0);
9301                         left  = RHS(ins, 0)->u.cval;
9302                         right = RHS(ins, 1)->u.cval;
9303                         mkaddr_const(state, ins, sdecl, left + right);
9304                 }
9305                 else {
9306                         internal_warning(state, ins, "Optimize me!");
9307                 }
9308         }
9309         else if (is_const(RHS(ins, 0)) && !is_const(RHS(ins, 1))) {
9310                 struct triple *tmp;
9311                 tmp = RHS(ins, 1);
9312                 RHS(ins, 1) = RHS(ins, 0);
9313                 RHS(ins, 0) = tmp;
9314         }
9315 }
9316
9317 static void simplify_sub(struct compile_state *state, struct triple *ins)
9318 {
9319         if (is_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9320                 if (RHS(ins, 0)->op == OP_INTCONST) {
9321                         ulong_t left, right;
9322                         left  = read_const(state, ins, RHS(ins, 0));
9323                         right = read_const(state, ins, RHS(ins, 1));
9324                         mkconst(state, ins, left - right);
9325                 }
9326                 else if (RHS(ins, 0)->op == OP_ADDRCONST) {
9327                         struct triple *sdecl;
9328                         ulong_t left, right;
9329                         sdecl = MISC(RHS(ins, 0), 0);
9330                         left  = RHS(ins, 0)->u.cval;
9331                         right = RHS(ins, 1)->u.cval;
9332                         mkaddr_const(state, ins, sdecl, left - right);
9333                 }
9334                 else {
9335                         internal_warning(state, ins, "Optimize me!");
9336                 }
9337         }
9338 }
9339
9340 static void simplify_sl(struct compile_state *state, struct triple *ins)
9341 {
9342         if (is_simple_const(RHS(ins, 1))) {
9343                 ulong_t right;
9344                 right = read_const(state, ins, RHS(ins, 1));
9345                 if (right >= (size_of(state, ins->type))) {
9346                         warning(state, ins, "left shift count >= width of type");
9347                 }
9348         }
9349         if (is_simple_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9350                 ulong_t left, right;
9351                 left  = read_const(state, ins, RHS(ins, 0));
9352                 right = read_const(state, ins, RHS(ins, 1));
9353                 mkconst(state, ins,  left << right);
9354         }
9355 }
9356
9357 static void simplify_usr(struct compile_state *state, struct triple *ins)
9358 {
9359         if (is_simple_const(RHS(ins, 1))) {
9360                 ulong_t right;
9361                 right = read_const(state, ins, RHS(ins, 1));
9362                 if (right >= (size_of(state, ins->type))) {
9363                         warning(state, ins, "right shift count >= width of type");
9364                 }
9365         }
9366         if (is_simple_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9367                 ulong_t left, right;
9368                 left  = read_const(state, ins, RHS(ins, 0));
9369                 right = read_const(state, ins, RHS(ins, 1));
9370                 mkconst(state, ins, left >> right);
9371         }
9372 }
9373
9374 static void simplify_ssr(struct compile_state *state, struct triple *ins)
9375 {
9376         if (is_simple_const(RHS(ins, 1))) {
9377                 ulong_t right;
9378                 right = read_const(state, ins, RHS(ins, 1));
9379                 if (right >= (size_of(state, ins->type))) {
9380                         warning(state, ins, "right shift count >= width of type");
9381                 }
9382         }
9383         if (is_simple_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9384                 long_t left, right;
9385                 left  = read_sconst(state, ins, RHS(ins, 0));
9386                 right = read_sconst(state, ins, RHS(ins, 1));
9387                 mkconst(state, ins, left >> right);
9388         }
9389 }
9390
9391 static void simplify_and(struct compile_state *state, struct triple *ins)
9392 {
9393         struct triple *left, *right;
9394         left = RHS(ins, 0);
9395         right = RHS(ins, 1);
9396
9397         if (is_simple_const(left) && is_simple_const(right)) {
9398                 ulong_t lval, rval;
9399                 lval = read_const(state, ins, left);
9400                 rval = read_const(state, ins, right);
9401                 mkconst(state, ins, lval & rval);
9402         }
9403         else if (is_zero(right) || is_zero(left)) {
9404                 mkconst(state, ins, 0);
9405         }
9406 }
9407
9408 static void simplify_or(struct compile_state *state, struct triple *ins)
9409 {
9410         struct triple *left, *right;
9411         left = RHS(ins, 0);
9412         right = RHS(ins, 1);
9413
9414         if (is_simple_const(left) && is_simple_const(right)) {
9415                 ulong_t lval, rval;
9416                 lval = read_const(state, ins, left);
9417                 rval = read_const(state, ins, right);
9418                 mkconst(state, ins, lval | rval);
9419         }
9420 #if 0 /* I need to handle type mismatches here... */
9421         else if (is_zero(right)) {
9422                 mkcopy(state, ins, left);
9423         }
9424         else if (is_zero(left)) {
9425                 mkcopy(state, ins, right);
9426         }
9427 #endif
9428 }
9429
9430 static void simplify_xor(struct compile_state *state, struct triple *ins)
9431 {
9432         if (is_simple_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9433                 ulong_t left, right;
9434                 left  = read_const(state, ins, RHS(ins, 0));
9435                 right = read_const(state, ins, RHS(ins, 1));
9436                 mkconst(state, ins, left ^ right);
9437         }
9438 }
9439
9440 static void simplify_pos(struct compile_state *state, struct triple *ins)
9441 {
9442         if (is_const(RHS(ins, 0))) {
9443                 mkconst(state, ins, RHS(ins, 0)->u.cval);
9444         }
9445         else {
9446                 mkcopy(state, ins, RHS(ins, 0));
9447         }
9448 }
9449
9450 static void simplify_neg(struct compile_state *state, struct triple *ins)
9451 {
9452         if (is_simple_const(RHS(ins, 0))) {
9453                 ulong_t left;
9454                 left = read_const(state, ins, RHS(ins, 0));
9455                 mkconst(state, ins, -left);
9456         }
9457         else if (RHS(ins, 0)->op == OP_NEG) {
9458                 mkcopy(state, ins, RHS(RHS(ins, 0), 0));
9459         }
9460 }
9461
9462 static void simplify_invert(struct compile_state *state, struct triple *ins)
9463 {
9464         if (is_simple_const(RHS(ins, 0))) {
9465                 ulong_t left;
9466                 left = read_const(state, ins, RHS(ins, 0));
9467                 mkconst(state, ins, ~left);
9468         }
9469 }
9470
9471 static void simplify_eq(struct compile_state *state, struct triple *ins)
9472 {
9473         struct triple *left, *right;
9474         left = RHS(ins, 0);
9475         right = RHS(ins, 1);
9476
9477         if (is_const(left) && is_const(right)) {
9478                 int val;
9479                 val = const_eq(state, ins, left, right);
9480                 if (val >= 0) {
9481                         mkconst(state, ins, val == 1);
9482                 }
9483         }
9484         else if (left == right) {
9485                 mkconst(state, ins, 1);
9486         }
9487 }
9488
9489 static void simplify_noteq(struct compile_state *state, struct triple *ins)
9490 {
9491         struct triple *left, *right;
9492         left = RHS(ins, 0);
9493         right = RHS(ins, 1);
9494
9495         if (is_const(left) && is_const(right)) {
9496                 int val;
9497                 val = const_eq(state, ins, left, right);
9498                 if (val >= 0) {
9499                         mkconst(state, ins, val != 1);
9500                 }
9501         }
9502         if (left == right) {
9503                 mkconst(state, ins, 0);
9504         }
9505 }
9506
9507 static void simplify_sless(struct compile_state *state, struct triple *ins)
9508 {
9509         struct triple *left, *right;
9510         left = RHS(ins, 0);
9511         right = RHS(ins, 1);
9512
9513         if (is_const(left) && is_const(right)) {
9514                 int val;
9515                 val = const_scmp(state, ins, left, right);
9516                 if ((val >= -1) && (val <= 1)) {
9517                         mkconst(state, ins, val < 0);
9518                 }
9519         }
9520         else if (left == right) {
9521                 mkconst(state, ins, 0);
9522         }
9523 }
9524
9525 static void simplify_uless(struct compile_state *state, struct triple *ins)
9526 {
9527         struct triple *left, *right;
9528         left = RHS(ins, 0);
9529         right = RHS(ins, 1);
9530
9531         if (is_const(left) && is_const(right)) {
9532                 int val;
9533                 val = const_ucmp(state, ins, left, right);
9534                 if ((val >= -1) && (val <= 1)) {
9535                         mkconst(state, ins, val < 0);
9536                 }
9537         }
9538         else if (is_zero(right)) {
9539                 mkconst(state, ins, 0);
9540         }
9541         else if (left == right) {
9542                 mkconst(state, ins, 0);
9543         }
9544 }
9545
9546 static void simplify_smore(struct compile_state *state, struct triple *ins)
9547 {
9548         struct triple *left, *right;
9549         left = RHS(ins, 0);
9550         right = RHS(ins, 1);
9551
9552         if (is_const(left) && is_const(right)) {
9553                 int val;
9554                 val = const_scmp(state, ins, left, right);
9555                 if ((val >= -1) && (val <= 1)) {
9556                         mkconst(state, ins, val > 0);
9557                 }
9558         }
9559         else if (left == right) {
9560                 mkconst(state, ins, 0);
9561         }
9562 }
9563
9564 static void simplify_umore(struct compile_state *state, struct triple *ins)
9565 {
9566         struct triple *left, *right;
9567         left = RHS(ins, 0);
9568         right = RHS(ins, 1);
9569
9570         if (is_const(left) && is_const(right)) {
9571                 int val;
9572                 val = const_ucmp(state, ins, left, right);
9573                 if ((val >= -1) && (val <= 1)) {
9574                         mkconst(state, ins, val > 0);
9575                 }
9576         }
9577         else if (is_zero(left)) {
9578                 mkconst(state, ins, 0);
9579         }
9580         else if (left == right) {
9581                 mkconst(state, ins, 0);
9582         }
9583 }
9584
9585
9586 static void simplify_slesseq(struct compile_state *state, struct triple *ins)
9587 {
9588         struct triple *left, *right;
9589         left = RHS(ins, 0);
9590         right = RHS(ins, 1);
9591
9592         if (is_const(left) && is_const(right)) {
9593                 int val;
9594                 val = const_scmp(state, ins, left, right);
9595                 if ((val >= -1) && (val <= 1)) {
9596                         mkconst(state, ins, val <= 0);
9597                 }
9598         }
9599         else if (left == right) {
9600                 mkconst(state, ins, 1);
9601         }
9602 }
9603
9604 static void simplify_ulesseq(struct compile_state *state, struct triple *ins)
9605 {
9606         struct triple *left, *right;
9607         left = RHS(ins, 0);
9608         right = RHS(ins, 1);
9609
9610         if (is_const(left) && is_const(right)) {
9611                 int val;
9612                 val = const_ucmp(state, ins, left, right);
9613                 if ((val >= -1) && (val <= 1)) {
9614                         mkconst(state, ins, val <= 0);
9615                 }
9616         }
9617         else if (is_zero(left)) {
9618                 mkconst(state, ins, 1);
9619         }
9620         else if (left == right) {
9621                 mkconst(state, ins, 1);
9622         }
9623 }
9624
9625 static void simplify_smoreeq(struct compile_state *state, struct triple *ins)
9626 {
9627         struct triple *left, *right;
9628         left = RHS(ins, 0);
9629         right = RHS(ins, 1);
9630
9631         if (is_const(left) && is_const(right)) {
9632                 int val;
9633                 val = const_scmp(state, ins, left, right);
9634                 if ((val >= -1) && (val <= 1)) {
9635                         mkconst(state, ins, val >= 0);
9636                 }
9637         }
9638         else if (left == right) {
9639                 mkconst(state, ins, 1);
9640         }
9641 }
9642
9643 static void simplify_umoreeq(struct compile_state *state, struct triple *ins)
9644 {
9645         struct triple *left, *right;
9646         left = RHS(ins, 0);
9647         right = RHS(ins, 1);
9648
9649         if (is_const(left) && is_const(right)) {
9650                 int val;
9651                 val = const_ucmp(state, ins, left, right);
9652                 if ((val >= -1) && (val <= 1)) {
9653                         mkconst(state, ins, val >= 0);
9654                 }
9655         }
9656         else if (is_zero(right)) {
9657                 mkconst(state, ins, 1);
9658         }
9659         else if (left == right) {
9660                 mkconst(state, ins, 1);
9661         }
9662 }
9663
9664 static void simplify_lfalse(struct compile_state *state, struct triple *ins)
9665 {
9666         struct triple *rhs;
9667         rhs = RHS(ins, 0);
9668
9669         if (is_const(rhs)) {
9670                 mkconst(state, ins, !const_ltrue(state, ins, rhs));
9671         }
9672         /* Otherwise if I am the only user... */
9673         else if ((rhs->use) &&
9674                 (rhs->use->member == ins) && (rhs->use->next == 0)) {
9675                 int need_copy = 1;
9676                 /* Invert a boolean operation */
9677                 switch(rhs->op) {
9678                 case OP_LTRUE:   rhs->op = OP_LFALSE;  break;
9679                 case OP_LFALSE:  rhs->op = OP_LTRUE;   break;
9680                 case OP_EQ:      rhs->op = OP_NOTEQ;   break;
9681                 case OP_NOTEQ:   rhs->op = OP_EQ;      break;
9682                 case OP_SLESS:   rhs->op = OP_SMOREEQ; break;
9683                 case OP_ULESS:   rhs->op = OP_UMOREEQ; break;
9684                 case OP_SMORE:   rhs->op = OP_SLESSEQ; break;
9685                 case OP_UMORE:   rhs->op = OP_ULESSEQ; break;
9686                 case OP_SLESSEQ: rhs->op = OP_SMORE;   break;
9687                 case OP_ULESSEQ: rhs->op = OP_UMORE;   break;
9688                 case OP_SMOREEQ: rhs->op = OP_SLESS;   break;
9689                 case OP_UMOREEQ: rhs->op = OP_ULESS;   break;
9690                 default:
9691                         need_copy = 0;
9692                         break;
9693                 }
9694                 if (need_copy) {
9695                         mkcopy(state, ins, rhs);
9696                 }
9697         }
9698 }
9699
9700 static void simplify_ltrue (struct compile_state *state, struct triple *ins)
9701 {
9702         struct triple *rhs;
9703         rhs = RHS(ins, 0);
9704
9705         if (is_const(rhs)) {
9706                 mkconst(state, ins, const_ltrue(state, ins, rhs));
9707         }
9708         else switch(rhs->op) {
9709         case OP_LTRUE:   case OP_LFALSE:  case OP_EQ:      case OP_NOTEQ:
9710         case OP_SLESS:   case OP_ULESS:   case OP_SMORE:   case OP_UMORE:
9711         case OP_SLESSEQ: case OP_ULESSEQ: case OP_SMOREEQ: case OP_UMOREEQ:
9712                 mkcopy(state, ins, rhs);
9713         }
9714
9715 }
9716
9717 static void simplify_load(struct compile_state *state, struct triple *ins)
9718 {
9719         struct triple *addr, *sdecl, *blob;
9720
9721         /* If I am doing a load with a constant pointer from a constant
9722          * table get the value.
9723          */
9724         addr = RHS(ins, 0);
9725         if ((addr->op == OP_ADDRCONST) && (sdecl = MISC(addr, 0)) &&
9726                 (sdecl->op == OP_SDECL) && (blob = MISC(sdecl, 0)) &&
9727                 (blob->op == OP_BLOBCONST)) {
9728                 unsigned char buffer[SIZEOF_WORD];
9729                 size_t reg_size, mem_size;
9730                 const char *src, *end;
9731                 ulong_t val;
9732                 reg_size = reg_size_of(state, ins->type);
9733                 if (reg_size > REG_SIZEOF_REG) {
9734                         internal_error(state, ins, "load size greater than register");
9735                 }
9736                 mem_size = size_of(state, ins->type);
9737                 end = blob->u.blob;
9738                 end += bits_to_bytes(size_of(state, sdecl->type));
9739                 src = blob->u.blob;
9740                 src += addr->u.cval;
9741
9742                 if (src > end) {
9743                         error(state, ins, "Load address out of bounds");
9744                 }
9745
9746                 memset(buffer, 0, sizeof(buffer));
9747                 memcpy(buffer, src, bits_to_bytes(mem_size));
9748
9749                 switch(mem_size) {
9750                 case SIZEOF_I8:  val = *((uint8_t *) buffer); break;
9751                 case SIZEOF_I16: val = *((uint16_t *)buffer); break;
9752                 case SIZEOF_I32: val = *((uint32_t *)buffer); break;
9753                 case SIZEOF_I64: val = *((uint64_t *)buffer); break;
9754                 default:
9755                         internal_error(state, ins, "mem_size: %d not handled",
9756                                 mem_size);
9757                         val = 0;
9758                         break;
9759                 }
9760                 mkconst(state, ins, val);
9761         }
9762 }
9763
9764 static void simplify_uextract(struct compile_state *state, struct triple *ins)
9765 {
9766         if (is_simple_const(RHS(ins, 0))) {
9767                 ulong_t val;
9768                 ulong_t mask;
9769                 val = read_const(state, ins, RHS(ins, 0));
9770                 mask = 1;
9771                 mask <<= ins->u.bitfield.size;
9772                 mask -= 1;
9773                 val >>= ins->u.bitfield.offset;
9774                 val &= mask;
9775                 mkconst(state, ins, val);
9776         }
9777 }
9778
9779 static void simplify_sextract(struct compile_state *state, struct triple *ins)
9780 {
9781         if (is_simple_const(RHS(ins, 0))) {
9782                 ulong_t val;
9783                 ulong_t mask;
9784                 long_t sval;
9785                 val = read_const(state, ins, RHS(ins, 0));
9786                 mask = 1;
9787                 mask <<= ins->u.bitfield.size;
9788                 mask -= 1;
9789                 val >>= ins->u.bitfield.offset;
9790                 val &= mask;
9791                 val <<= (SIZEOF_LONG - ins->u.bitfield.size);
9792                 sval = val;
9793                 sval >>= (SIZEOF_LONG - ins->u.bitfield.size); 
9794                 mkconst(state, ins, sval);
9795         }
9796 }
9797
9798 static void simplify_deposit(struct compile_state *state, struct triple *ins)
9799 {
9800         if (is_simple_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9801                 ulong_t targ, val;
9802                 ulong_t mask;
9803                 targ = read_const(state, ins, RHS(ins, 0));
9804                 val  = read_const(state, ins, RHS(ins, 1));
9805                 mask = 1;
9806                 mask <<= ins->u.bitfield.size;
9807                 mask -= 1;
9808                 mask <<= ins->u.bitfield.offset;
9809                 targ &= ~mask;
9810                 val <<= ins->u.bitfield.offset;
9811                 val &= mask;
9812                 targ |= val;
9813                 mkconst(state, ins, targ);
9814         }
9815 }
9816
9817 static void simplify_copy(struct compile_state *state, struct triple *ins)
9818 {
9819         struct triple *right;
9820         right = RHS(ins, 0);
9821         if (is_subset_type(ins->type, right->type)) {
9822                 ins->type = right->type;
9823         }
9824         if (equiv_types(ins->type, right->type)) {
9825                 ins->op = OP_COPY;/* I don't need to convert if the types match */
9826         } else {
9827                 if (ins->op == OP_COPY) {
9828                         internal_error(state, ins, "type mismatch on copy");
9829                 }
9830         }
9831         if (is_const(right) && (right->op == OP_ADDRCONST) && is_pointer(ins)) {
9832                 struct triple *sdecl;
9833                 ulong_t offset;
9834                 sdecl  = MISC(right, 0);
9835                 offset = right->u.cval;
9836                 mkaddr_const(state, ins, sdecl, offset);
9837         }
9838         else if (is_const(right) && is_write_compatible(state, ins->type, right->type)) {
9839                 switch(right->op) {
9840                 case OP_INTCONST:
9841                 {
9842                         ulong_t left;
9843                         left = read_const(state, ins, right);
9844                         /* Ensure I have not overflowed the destination. */
9845                         if (size_of(state, right->type) > size_of(state, ins->type)) {
9846                                 ulong_t mask;
9847                                 mask = 1;
9848                                 mask <<= size_of(state, ins->type);
9849                                 mask -= 1;
9850                                 left &= mask;
9851                         }
9852                         /* Ensure I am properly sign extended */
9853                         if (size_of(state, right->type) < size_of(state, ins->type) &&
9854                                 is_signed(right->type)) {
9855                                 long_t val;
9856                                 int shift;
9857                                 shift = SIZEOF_LONG - size_of(state, right->type);
9858                                 val = left;
9859                                 val <<= shift;
9860                                 val >>= shift;
9861                                 left = val;
9862                         }
9863                         mkconst(state, ins, left);
9864                         break;
9865                 }
9866                 default:
9867                         internal_error(state, ins, "uknown constant");
9868                         break;
9869                 }
9870         }
9871 }
9872
9873 static int phi_present(struct block *block)
9874 {
9875         struct triple *ptr;
9876         if (!block) {
9877                 return 0;
9878         }
9879         ptr = block->first;
9880         do {
9881                 if (ptr->op == OP_PHI) {
9882                         return 1;
9883                 }
9884                 ptr = ptr->next;
9885         } while(ptr != block->last);
9886         return 0;
9887 }
9888
9889 static int phi_dependency(struct block *block)
9890 {
9891         /* A block has a phi dependency if a phi function
9892          * depends on that block to exist, and makes a block
9893          * that is otherwise useless unsafe to remove.
9894          */
9895         if (block) {
9896                 struct block_set *edge;
9897                 for(edge = block->edges; edge; edge = edge->next) {
9898                         if (phi_present(edge->member)) {
9899                                 return 1;
9900                         }
9901                 }
9902         }
9903         return 0;
9904 }
9905
9906 static struct triple *branch_target(struct compile_state *state, struct triple *ins)
9907 {
9908         struct triple *targ;
9909         targ = TARG(ins, 0);
9910         /* During scc_transform temporary triples are allocated that
9911          * loop back onto themselves. If I see one don't advance the
9912          * target.
9913          */
9914         while(triple_is_structural(state, targ) && 
9915                 (targ->next != targ) && (targ->next != state->first)) {
9916                 targ = targ->next;
9917         }
9918         return targ;
9919 }
9920
9921
9922 static void simplify_branch(struct compile_state *state, struct triple *ins)
9923 {
9924         int simplified, loops;
9925         if ((ins->op != OP_BRANCH) && (ins->op != OP_CBRANCH)) {
9926                 internal_error(state, ins, "not branch");
9927         }
9928         if (ins->use != 0) {
9929                 internal_error(state, ins, "branch use");
9930         }
9931         /* The challenge here with simplify branch is that I need to 
9932          * make modifications to the control flow graph as well
9933          * as to the branch instruction itself.  That is handled
9934          * by rebuilding the basic blocks after simplify all is called.
9935          */
9936
9937         /* If we have a branch to an unconditional branch update
9938          * our target.  But watch out for dependencies from phi
9939          * functions.
9940          * Also only do this a limited number of times so
9941          * we don't get into an infinite loop.
9942          */
9943         loops = 0;
9944         do {
9945                 struct triple *targ;
9946                 simplified = 0;
9947                 targ = branch_target(state, ins);
9948                 if ((targ != ins) && (targ->op == OP_BRANCH) && 
9949                         !phi_dependency(targ->u.block))
9950                 {
9951                         unuse_triple(TARG(ins, 0), ins);
9952                         TARG(ins, 0) = TARG(targ, 0);
9953                         use_triple(TARG(ins, 0), ins);
9954                         simplified = 1;
9955                 }
9956         } while(simplified && (++loops < 20));
9957
9958         /* If we have a conditional branch with a constant condition
9959          * make it an unconditional branch.
9960          */
9961         if ((ins->op == OP_CBRANCH) && is_simple_const(RHS(ins, 0))) {
9962                 struct triple *targ;
9963                 ulong_t value;
9964                 value = read_const(state, ins, RHS(ins, 0));
9965                 unuse_triple(RHS(ins, 0), ins);
9966                 targ = TARG(ins, 0);
9967                 ins->rhs  = 0;
9968                 ins->targ = 1;
9969                 ins->op = OP_BRANCH;
9970                 if (value) {
9971                         unuse_triple(ins->next, ins);
9972                         TARG(ins, 0) = targ;
9973                 }
9974                 else {
9975                         unuse_triple(targ, ins);
9976                         TARG(ins, 0) = ins->next;
9977                 }
9978         }
9979
9980         /* If we have a branch to the next instruction,
9981          * make it a noop.
9982          */
9983         if (TARG(ins, 0) == ins->next) {
9984                 unuse_triple(TARG(ins, 0), ins);
9985                 if (ins->op == OP_CBRANCH) {
9986                         unuse_triple(RHS(ins, 0), ins);
9987                         unuse_triple(ins->next, ins);
9988                 }
9989                 ins->lhs = 0;
9990                 ins->rhs = 0;
9991                 ins->misc = 0;
9992                 ins->targ = 0;
9993                 ins->op = OP_NOOP;
9994                 if (ins->use) {
9995                         internal_error(state, ins, "noop use != 0");
9996                 }
9997         }
9998 }
9999
10000 static void simplify_label(struct compile_state *state, struct triple *ins)
10001 {
10002         /* Ignore volatile labels */
10003         if (!triple_is_pure(state, ins, ins->id)) {
10004                 return;
10005         }
10006         if (ins->use == 0) {
10007                 ins->op = OP_NOOP;
10008         }
10009         else if (ins->prev->op == OP_LABEL) {
10010                 /* In general it is not safe to merge one label that
10011                  * imediately follows another.  The problem is that the empty
10012                  * looking block may have phi functions that depend on it.
10013                  */
10014                 if (!phi_dependency(ins->prev->u.block)) {
10015                         struct triple_set *user, *next;
10016                         ins->op = OP_NOOP;
10017                         for(user = ins->use; user; user = next) {
10018                                 struct triple *use, **expr;
10019                                 next = user->next;
10020                                 use = user->member;
10021                                 expr = triple_targ(state, use, 0);
10022                                 for(;expr; expr = triple_targ(state, use, expr)) {
10023                                         if (*expr == ins) {
10024                                                 *expr = ins->prev;
10025                                                 unuse_triple(ins, use);
10026                                                 use_triple(ins->prev, use);
10027                                         }
10028                                         
10029                                 }
10030                         }
10031                         if (ins->use) {
10032                                 internal_error(state, ins, "noop use != 0");
10033                         }
10034                 }
10035         }
10036 }
10037
10038 static void simplify_phi(struct compile_state *state, struct triple *ins)
10039 {
10040         struct triple **slot;
10041         struct triple *value;
10042         int zrhs, i;
10043         ulong_t cvalue;
10044         slot = &RHS(ins, 0);
10045         zrhs = ins->rhs;
10046         if (zrhs == 0) {
10047                 return;
10048         }
10049         /* See if all of the rhs members of a phi have the same value */
10050         if (slot[0] && is_simple_const(slot[0])) {
10051                 cvalue = read_const(state, ins, slot[0]);
10052                 for(i = 1; i < zrhs; i++) {
10053                         if (    !slot[i] ||
10054                                 !is_simple_const(slot[i]) ||
10055                                 !equiv_types(slot[0]->type, slot[i]->type) ||
10056                                 (cvalue != read_const(state, ins, slot[i]))) {
10057                                 break;
10058                         }
10059                 }
10060                 if (i == zrhs) {
10061                         mkconst(state, ins, cvalue);
10062                         return;
10063                 }
10064         }
10065         
10066         /* See if all of rhs members of a phi are the same */
10067         value = slot[0];
10068         for(i = 1; i < zrhs; i++) {
10069                 if (slot[i] != value) {
10070                         break;
10071                 }
10072         }
10073         if (i == zrhs) {
10074                 /* If the phi has a single value just copy it */
10075                 if (!is_subset_type(ins->type, value->type)) {
10076                         internal_error(state, ins, "bad input type to phi");
10077                 }
10078                 /* Make the types match */
10079                 if (!equiv_types(ins->type, value->type)) {
10080                         ins->type = value->type;
10081                 }
10082                 /* Now make the actual copy */
10083                 mkcopy(state, ins, value);
10084                 return;
10085         }
10086 }
10087
10088
10089 static void simplify_bsf(struct compile_state *state, struct triple *ins)
10090 {
10091         if (is_simple_const(RHS(ins, 0))) {
10092                 ulong_t left;
10093                 left = read_const(state, ins, RHS(ins, 0));
10094                 mkconst(state, ins, bsf(left));
10095         }
10096 }
10097
10098 static void simplify_bsr(struct compile_state *state, struct triple *ins)
10099 {
10100         if (is_simple_const(RHS(ins, 0))) {
10101                 ulong_t left;
10102                 left = read_const(state, ins, RHS(ins, 0));
10103                 mkconst(state, ins, bsr(left));
10104         }
10105 }
10106
10107
10108 typedef void (*simplify_t)(struct compile_state *state, struct triple *ins);
10109 static const struct simplify_table {
10110         simplify_t func;
10111         unsigned long flag;
10112 } table_simplify[] = {
10113 #define simplify_sdivt    simplify_noop
10114 #define simplify_udivt    simplify_noop
10115 #define simplify_piece    simplify_noop
10116
10117 [OP_SDIVT      ] = { simplify_sdivt,    COMPILER_SIMPLIFY_ARITH },
10118 [OP_UDIVT      ] = { simplify_udivt,    COMPILER_SIMPLIFY_ARITH },
10119 [OP_SMUL       ] = { simplify_smul,     COMPILER_SIMPLIFY_ARITH },
10120 [OP_UMUL       ] = { simplify_umul,     COMPILER_SIMPLIFY_ARITH },
10121 [OP_SDIV       ] = { simplify_sdiv,     COMPILER_SIMPLIFY_ARITH },
10122 [OP_UDIV       ] = { simplify_udiv,     COMPILER_SIMPLIFY_ARITH },
10123 [OP_SMOD       ] = { simplify_smod,     COMPILER_SIMPLIFY_ARITH },
10124 [OP_UMOD       ] = { simplify_umod,     COMPILER_SIMPLIFY_ARITH },
10125 [OP_ADD        ] = { simplify_add,      COMPILER_SIMPLIFY_ARITH },
10126 [OP_SUB        ] = { simplify_sub,      COMPILER_SIMPLIFY_ARITH },
10127 [OP_SL         ] = { simplify_sl,       COMPILER_SIMPLIFY_SHIFT },
10128 [OP_USR        ] = { simplify_usr,      COMPILER_SIMPLIFY_SHIFT },
10129 [OP_SSR        ] = { simplify_ssr,      COMPILER_SIMPLIFY_SHIFT },
10130 [OP_AND        ] = { simplify_and,      COMPILER_SIMPLIFY_BITWISE },
10131 [OP_XOR        ] = { simplify_xor,      COMPILER_SIMPLIFY_BITWISE },
10132 [OP_OR         ] = { simplify_or,       COMPILER_SIMPLIFY_BITWISE },
10133 [OP_POS        ] = { simplify_pos,      COMPILER_SIMPLIFY_ARITH },
10134 [OP_NEG        ] = { simplify_neg,      COMPILER_SIMPLIFY_ARITH },
10135 [OP_INVERT     ] = { simplify_invert,   COMPILER_SIMPLIFY_BITWISE },
10136
10137 [OP_EQ         ] = { simplify_eq,       COMPILER_SIMPLIFY_LOGICAL },
10138 [OP_NOTEQ      ] = { simplify_noteq,    COMPILER_SIMPLIFY_LOGICAL },
10139 [OP_SLESS      ] = { simplify_sless,    COMPILER_SIMPLIFY_LOGICAL },
10140 [OP_ULESS      ] = { simplify_uless,    COMPILER_SIMPLIFY_LOGICAL },
10141 [OP_SMORE      ] = { simplify_smore,    COMPILER_SIMPLIFY_LOGICAL },
10142 [OP_UMORE      ] = { simplify_umore,    COMPILER_SIMPLIFY_LOGICAL },
10143 [OP_SLESSEQ    ] = { simplify_slesseq,  COMPILER_SIMPLIFY_LOGICAL },
10144 [OP_ULESSEQ    ] = { simplify_ulesseq,  COMPILER_SIMPLIFY_LOGICAL },
10145 [OP_SMOREEQ    ] = { simplify_smoreeq,  COMPILER_SIMPLIFY_LOGICAL },
10146 [OP_UMOREEQ    ] = { simplify_umoreeq,  COMPILER_SIMPLIFY_LOGICAL },
10147 [OP_LFALSE     ] = { simplify_lfalse,   COMPILER_SIMPLIFY_LOGICAL },
10148 [OP_LTRUE      ] = { simplify_ltrue,    COMPILER_SIMPLIFY_LOGICAL },
10149
10150 [OP_LOAD       ] = { simplify_load,     COMPILER_SIMPLIFY_OP },
10151 [OP_STORE      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10152
10153 [OP_UEXTRACT   ] = { simplify_uextract, COMPILER_SIMPLIFY_BITFIELD },
10154 [OP_SEXTRACT   ] = { simplify_sextract, COMPILER_SIMPLIFY_BITFIELD },
10155 [OP_DEPOSIT    ] = { simplify_deposit,  COMPILER_SIMPLIFY_BITFIELD },
10156
10157 [OP_NOOP       ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10158
10159 [OP_INTCONST   ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10160 [OP_BLOBCONST  ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10161 [OP_ADDRCONST  ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10162 [OP_UNKNOWNVAL ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10163
10164 [OP_WRITE      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10165 [OP_READ       ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10166 [OP_COPY       ] = { simplify_copy,     COMPILER_SIMPLIFY_COPY },
10167 [OP_CONVERT    ] = { simplify_copy,     COMPILER_SIMPLIFY_COPY },
10168 [OP_PIECE      ] = { simplify_piece,    COMPILER_SIMPLIFY_OP },
10169 [OP_ASM        ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10170
10171 [OP_DOT        ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10172 [OP_INDEX      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10173
10174 [OP_LIST       ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10175 [OP_BRANCH     ] = { simplify_branch,   COMPILER_SIMPLIFY_BRANCH },
10176 [OP_CBRANCH    ] = { simplify_branch,   COMPILER_SIMPLIFY_BRANCH },
10177 [OP_CALL       ] = { simplify_noop,     COMPILER_SIMPLIFY_BRANCH },
10178 [OP_RET        ] = { simplify_noop,     COMPILER_SIMPLIFY_BRANCH },
10179 [OP_LABEL      ] = { simplify_label,    COMPILER_SIMPLIFY_LABEL },
10180 [OP_ADECL      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10181 [OP_SDECL      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10182 [OP_PHI        ] = { simplify_phi,      COMPILER_SIMPLIFY_PHI },
10183
10184 [OP_INB        ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10185 [OP_INW        ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10186 [OP_INL        ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10187 [OP_OUTB       ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10188 [OP_OUTW       ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10189 [OP_OUTL       ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10190 [OP_BSF        ] = { simplify_bsf,      COMPILER_SIMPLIFY_OP },
10191 [OP_BSR        ] = { simplify_bsr,      COMPILER_SIMPLIFY_OP },
10192 [OP_RDMSR      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10193 [OP_WRMSR      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },               
10194 [OP_HLT        ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10195 };
10196
10197 static inline void debug_simplify(struct compile_state *state, 
10198         simplify_t do_simplify, struct triple *ins)
10199 {
10200 #if DEBUG_SIMPLIFY_HIRES
10201                 if (state->functions_joined && (do_simplify != simplify_noop)) {
10202                         /* High resolution debugging mode */
10203                         fprintf(state->dbgout, "simplifing: ");
10204                         display_triple(state->dbgout, ins);
10205                 }
10206 #endif
10207                 do_simplify(state, ins);
10208 #if DEBUG_SIMPLIFY_HIRES
10209                 if (state->functions_joined && (do_simplify != simplify_noop)) {
10210                         /* High resolution debugging mode */
10211                         fprintf(state->dbgout, "simplified: ");
10212                         display_triple(state->dbgout, ins);
10213                 }
10214 #endif
10215 }
10216 static void simplify(struct compile_state *state, struct triple *ins)
10217 {
10218         int op;
10219         simplify_t do_simplify;
10220         if (ins == &unknown_triple) {
10221                 internal_error(state, ins, "simplifying the unknown triple?");
10222         }
10223         do {
10224                 op = ins->op;
10225                 do_simplify = 0;
10226                 if ((op < 0) || (op > sizeof(table_simplify)/sizeof(table_simplify[0]))) {
10227                         do_simplify = 0;
10228                 }
10229                 else {
10230                         do_simplify = table_simplify[op].func;
10231                 }
10232                 if (do_simplify && 
10233                         !(state->compiler->flags & table_simplify[op].flag)) {
10234                         do_simplify = simplify_noop;
10235                 }
10236                 if (do_simplify && (ins->id & TRIPLE_FLAG_VOLATILE)) {
10237                         do_simplify = simplify_noop;
10238                 }
10239         
10240                 if (!do_simplify) {
10241                         internal_error(state, ins, "cannot simplify op: %d %s",
10242                                 op, tops(op));
10243                         return;
10244                 }
10245                 debug_simplify(state, do_simplify, ins);
10246         } while(ins->op != op);
10247 }
10248
10249 static void rebuild_ssa_form(struct compile_state *state);
10250
10251 static void simplify_all(struct compile_state *state)
10252 {
10253         struct triple *ins, *first;
10254         if (!(state->compiler->flags & COMPILER_SIMPLIFY)) {
10255                 return;
10256         }
10257         first = state->first;
10258         ins = first->prev;
10259         do {
10260                 simplify(state, ins);
10261                 ins = ins->prev;
10262         } while(ins != first->prev);
10263         ins = first;
10264         do {
10265                 simplify(state, ins);
10266                 ins = ins->next;
10267         }while(ins != first);
10268         rebuild_ssa_form(state);
10269
10270         print_blocks(state, __func__, state->dbgout);
10271 }
10272
10273 /*
10274  * Builtins....
10275  * ============================
10276  */
10277
10278 static void register_builtin_function(struct compile_state *state,
10279         const char *name, int op, struct type *rtype, ...)
10280 {
10281         struct type *ftype, *atype, *ctype, *crtype, *param, **next;
10282         struct triple *def, *arg, *result, *work, *last, *first, *retvar, *ret;
10283         struct hash_entry *ident;
10284         struct file_state file;
10285         int parameters;
10286         int name_len;
10287         va_list args;
10288         int i;
10289
10290         /* Dummy file state to get debug handling right */
10291         memset(&file, 0, sizeof(file));
10292         file.basename = "<built-in>";
10293         file.line = 1;
10294         file.report_line = 1;
10295         file.report_name = file.basename;
10296         file.prev = state->file;
10297         state->file = &file;
10298         state->function = name;
10299
10300         /* Find the Parameter count */
10301         valid_op(state, op);
10302         parameters = table_ops[op].rhs;
10303         if (parameters < 0 ) {
10304                 internal_error(state, 0, "Invalid builtin parameter count");
10305         }
10306
10307         /* Find the function type */
10308         ftype = new_type(TYPE_FUNCTION | STOR_INLINE | STOR_STATIC, rtype, 0);
10309         ftype->elements = parameters;
10310         next = &ftype->right;
10311         va_start(args, rtype);
10312         for(i = 0; i < parameters; i++) {
10313                 atype = va_arg(args, struct type *);
10314                 if (!*next) {
10315                         *next = atype;
10316                 } else {
10317                         *next = new_type(TYPE_PRODUCT, *next, atype);
10318                         next = &((*next)->right);
10319                 }
10320         }
10321         if (!*next) {
10322                 *next = &void_type;
10323         }
10324         va_end(args);
10325
10326         /* Get the initial closure type */
10327         ctype = new_type(TYPE_JOIN, &void_type, 0);
10328         ctype->elements = 1;
10329
10330         /* Get the return type */
10331         crtype = new_type(TYPE_TUPLE, new_type(TYPE_PRODUCT, ctype, rtype), 0);
10332         crtype->elements = 2;
10333
10334         /* Generate the needed triples */
10335         def = triple(state, OP_LIST, ftype, 0, 0);
10336         first = label(state);
10337         RHS(def, 0) = first;
10338         result = flatten(state, first, variable(state, crtype));
10339         retvar = flatten(state, first, variable(state, &void_ptr_type));
10340         ret = triple(state, OP_RET, &void_type, read_expr(state, retvar), 0);
10341
10342         /* Now string them together */
10343         param = ftype->right;
10344         for(i = 0; i < parameters; i++) {
10345                 if ((param->type & TYPE_MASK) == TYPE_PRODUCT) {
10346                         atype = param->left;
10347                 } else {
10348                         atype = param;
10349                 }
10350                 arg = flatten(state, first, variable(state, atype));
10351                 param = param->right;
10352         }
10353         work = new_triple(state, op, rtype, -1, parameters);
10354         generate_lhs_pieces(state, work);
10355         for(i = 0; i < parameters; i++) {
10356                 RHS(work, i) = read_expr(state, farg(state, def, i));
10357         }
10358         if ((rtype->type & TYPE_MASK) != TYPE_VOID) {
10359                 work = write_expr(state, deref_index(state, result, 1), work);
10360         }
10361         work = flatten(state, first, work);
10362         last = flatten(state, first, label(state));
10363         ret  = flatten(state, first, ret);
10364         name_len = strlen(name);
10365         ident = lookup(state, name, name_len);
10366         ftype->type_ident = ident;
10367         symbol(state, ident, &ident->sym_ident, def, ftype);
10368         
10369         state->file = file.prev;
10370         state->function = 0;
10371         state->main_function = 0;
10372
10373         if (!state->functions) {
10374                 state->functions = def;
10375         } else {
10376                 insert_triple(state, state->functions, def);
10377         }
10378         if (state->compiler->debug & DEBUG_INLINE) {
10379                 FILE *fp = state->dbgout;
10380                 fprintf(fp, "\n");
10381                 loc(fp, state, 0);
10382                 fprintf(fp, "\n__________ %s _________\n", __FUNCTION__);
10383                 display_func(state, fp, def);
10384                 fprintf(fp, "__________ %s _________ done\n\n", __FUNCTION__);
10385         }
10386 }
10387
10388 static struct type *partial_struct(struct compile_state *state,
10389         const char *field_name, struct type *type, struct type *rest)
10390 {
10391         struct hash_entry *field_ident;
10392         struct type *result;
10393         int field_name_len;
10394
10395         field_name_len = strlen(field_name);
10396         field_ident = lookup(state, field_name, field_name_len);
10397
10398         result = clone_type(0, type);
10399         result->field_ident = field_ident;
10400
10401         if (rest) {
10402                 result = new_type(TYPE_PRODUCT, result, rest);
10403         }
10404         return result;
10405 }
10406
10407 static struct type *register_builtin_type(struct compile_state *state,
10408         const char *name, struct type *type)
10409 {
10410         struct hash_entry *ident;
10411         int name_len;
10412
10413         name_len = strlen(name);
10414         ident = lookup(state, name, name_len);
10415         
10416         if ((type->type & TYPE_MASK) == TYPE_PRODUCT) {
10417                 ulong_t elements = 0;
10418                 struct type *field;
10419                 type = new_type(TYPE_STRUCT, type, 0);
10420                 field = type->left;
10421                 while((field->type & TYPE_MASK) == TYPE_PRODUCT) {
10422                         elements++;
10423                         field = field->right;
10424                 }
10425                 elements++;
10426                 symbol(state, ident, &ident->sym_tag, 0, type);
10427                 type->type_ident = ident;
10428                 type->elements = elements;
10429         }
10430         symbol(state, ident, &ident->sym_ident, 0, type);
10431         ident->tok = TOK_TYPE_NAME;
10432         return type;
10433 }
10434
10435
10436 static void register_builtins(struct compile_state *state)
10437 {
10438         struct type *div_type, *ldiv_type;
10439         struct type *udiv_type, *uldiv_type;
10440         struct type *msr_type;
10441
10442         div_type = register_builtin_type(state, "__builtin_div_t",
10443                 partial_struct(state, "quot", &int_type,
10444                 partial_struct(state, "rem",  &int_type, 0)));
10445         ldiv_type = register_builtin_type(state, "__builtin_ldiv_t",
10446                 partial_struct(state, "quot", &long_type,
10447                 partial_struct(state, "rem",  &long_type, 0)));
10448         udiv_type = register_builtin_type(state, "__builtin_udiv_t",
10449                 partial_struct(state, "quot", &uint_type,
10450                 partial_struct(state, "rem",  &uint_type, 0)));
10451         uldiv_type = register_builtin_type(state, "__builtin_uldiv_t",
10452                 partial_struct(state, "quot", &ulong_type,
10453                 partial_struct(state, "rem",  &ulong_type, 0)));
10454
10455         register_builtin_function(state, "__builtin_div",   OP_SDIVT, div_type,
10456                 &int_type, &int_type);
10457         register_builtin_function(state, "__builtin_ldiv",  OP_SDIVT, ldiv_type,
10458                 &long_type, &long_type);
10459         register_builtin_function(state, "__builtin_udiv",  OP_UDIVT, udiv_type,
10460                 &uint_type, &uint_type);
10461         register_builtin_function(state, "__builtin_uldiv", OP_UDIVT, uldiv_type,
10462                 &ulong_type, &ulong_type);
10463
10464         register_builtin_function(state, "__builtin_inb", OP_INB, &uchar_type, 
10465                 &ushort_type);
10466         register_builtin_function(state, "__builtin_inw", OP_INW, &ushort_type,
10467                 &ushort_type);
10468         register_builtin_function(state, "__builtin_inl", OP_INL, &uint_type,   
10469                 &ushort_type);
10470
10471         register_builtin_function(state, "__builtin_outb", OP_OUTB, &void_type, 
10472                 &uchar_type, &ushort_type);
10473         register_builtin_function(state, "__builtin_outw", OP_OUTW, &void_type, 
10474                 &ushort_type, &ushort_type);
10475         register_builtin_function(state, "__builtin_outl", OP_OUTL, &void_type, 
10476                 &uint_type, &ushort_type);
10477         
10478         register_builtin_function(state, "__builtin_bsf", OP_BSF, &int_type, 
10479                 &int_type);
10480         register_builtin_function(state, "__builtin_bsr", OP_BSR, &int_type, 
10481                 &int_type);
10482
10483         msr_type = register_builtin_type(state, "__builtin_msr_t",
10484                 partial_struct(state, "lo", &ulong_type,
10485                 partial_struct(state, "hi", &ulong_type, 0)));
10486
10487         register_builtin_function(state, "__builtin_rdmsr", OP_RDMSR, msr_type,
10488                 &ulong_type);
10489         register_builtin_function(state, "__builtin_wrmsr", OP_WRMSR, &void_type,
10490                 &ulong_type, &ulong_type, &ulong_type);
10491         
10492         register_builtin_function(state, "__builtin_hlt", OP_HLT, &void_type, 
10493                 &void_type);
10494 }
10495
10496 static struct type *declarator(
10497         struct compile_state *state, struct type *type, 
10498         struct hash_entry **ident, int need_ident);
10499 static void decl(struct compile_state *state, struct triple *first);
10500 static struct type *specifier_qualifier_list(struct compile_state *state);
10501 static int isdecl_specifier(int tok);
10502 static struct type *decl_specifiers(struct compile_state *state);
10503 static int istype(int tok);
10504 static struct triple *expr(struct compile_state *state);
10505 static struct triple *assignment_expr(struct compile_state *state);
10506 static struct type *type_name(struct compile_state *state);
10507 static void statement(struct compile_state *state, struct triple *first);
10508
10509 static struct triple *call_expr(
10510         struct compile_state *state, struct triple *func)
10511 {
10512         struct triple *def;
10513         struct type *param, *type;
10514         ulong_t pvals, index;
10515
10516         if ((func->type->type & TYPE_MASK) != TYPE_FUNCTION) {
10517                 error(state, 0, "Called object is not a function");
10518         }
10519         if (func->op != OP_LIST) {
10520                 internal_error(state, 0, "improper function");
10521         }
10522         eat(state, TOK_LPAREN);
10523         /* Find the return type without any specifiers */
10524         type = clone_type(0, func->type->left);
10525         /* Count the number of rhs entries for OP_FCALL */
10526         param = func->type->right;
10527         pvals = 0;
10528         while((param->type & TYPE_MASK) == TYPE_PRODUCT) {
10529                 pvals++;
10530                 param = param->right;
10531         }
10532         if ((param->type & TYPE_MASK) != TYPE_VOID) {
10533                 pvals++;
10534         }
10535         def = new_triple(state, OP_FCALL, type, -1, pvals);
10536         MISC(def, 0) = func;
10537
10538         param = func->type->right;
10539         for(index = 0; index < pvals; index++) {
10540                 struct triple *val;
10541                 struct type *arg_type;
10542                 val = read_expr(state, assignment_expr(state));
10543                 arg_type = param;
10544                 if ((param->type & TYPE_MASK) == TYPE_PRODUCT) {
10545                         arg_type = param->left;
10546                 }
10547                 write_compatible(state, arg_type, val->type);
10548                 RHS(def, index) = val;
10549                 if (index != (pvals - 1)) {
10550                         eat(state, TOK_COMMA);
10551                         param = param->right;
10552                 }
10553         }
10554         eat(state, TOK_RPAREN);
10555         return def;
10556 }
10557
10558
10559 static struct triple *character_constant(struct compile_state *state)
10560 {
10561         struct triple *def;
10562         struct token *tk;
10563         const signed char *str, *end;
10564         int c;
10565         int str_len;
10566         tk = eat(state, TOK_LIT_CHAR);
10567         str = tk->val.str + 1;
10568         str_len = tk->str_len - 2;
10569         if (str_len <= 0) {
10570                 error(state, 0, "empty character constant");
10571         }
10572         end = str + str_len;
10573         c = char_value(state, &str, end);
10574         if (str != end) {
10575                 error(state, 0, "multibyte character constant not supported");
10576         }
10577         def = int_const(state, &char_type, (ulong_t)((long_t)c));
10578         return def;
10579 }
10580
10581 static struct triple *string_constant(struct compile_state *state)
10582 {
10583         struct triple *def;
10584         struct token *tk;
10585         struct type *type;
10586         const signed char *str, *end;
10587         signed char *buf, *ptr;
10588         int str_len;
10589
10590         buf = 0;
10591         type = new_type(TYPE_ARRAY, &char_type, 0);
10592         type->elements = 0;
10593         /* The while loop handles string concatenation */
10594         do {
10595                 tk = eat(state, TOK_LIT_STRING);
10596                 str = tk->val.str + 1;
10597                 str_len = tk->str_len - 2;
10598                 if (str_len < 0) {
10599                         error(state, 0, "negative string constant length");
10600                 }
10601                 end = str + str_len;
10602                 ptr = buf;
10603                 buf = xmalloc(type->elements + str_len + 1, "string_constant");
10604                 memcpy(buf, ptr, type->elements);
10605                 ptr = buf + type->elements;
10606                 do {
10607                         *ptr++ = char_value(state, &str, end);
10608                 } while(str < end);
10609                 type->elements = ptr - buf;
10610         } while(peek(state) == TOK_LIT_STRING);
10611         *ptr = '\0';
10612         type->elements += 1;
10613         def = triple(state, OP_BLOBCONST, type, 0, 0);
10614         def->u.blob = buf;
10615
10616         return def;
10617 }
10618
10619
10620 static struct triple *integer_constant(struct compile_state *state)
10621 {
10622         struct triple *def;
10623         unsigned long val;
10624         struct token *tk;
10625         char *end;
10626         int u, l, decimal;
10627         struct type *type;
10628
10629         tk = eat(state, TOK_LIT_INT);
10630         errno = 0;
10631         decimal = (tk->val.str[0] != '0');
10632         val = strtoul(tk->val.str, &end, 0);
10633         if ((val > ULONG_T_MAX) || ((val == ULONG_MAX) && (errno == ERANGE))) {
10634                 error(state, 0, "Integer constant to large");
10635         }
10636         u = l = 0;
10637         if ((*end == 'u') || (*end == 'U')) {
10638                 u = 1;
10639                         end++;
10640         }
10641         if ((*end == 'l') || (*end == 'L')) {
10642                 l = 1;
10643                 end++;
10644         }
10645         if ((*end == 'u') || (*end == 'U')) {
10646                 u = 1;
10647                 end++;
10648         }
10649         if (*end) {
10650                 error(state, 0, "Junk at end of integer constant");
10651         }
10652         if (u && l)  {
10653                 type = &ulong_type;
10654         }
10655         else if (l) {
10656                 type = &long_type;
10657                 if (!decimal && (val > LONG_T_MAX)) {
10658                         type = &ulong_type;
10659                 }
10660         }
10661         else if (u) {
10662                 type = &uint_type;
10663                 if (val > UINT_T_MAX) {
10664                         type = &ulong_type;
10665                 }
10666         }
10667         else {
10668                 type = &int_type;
10669                 if (!decimal && (val > INT_T_MAX) && (val <= UINT_T_MAX)) {
10670                         type = &uint_type;
10671                 }
10672                 else if (!decimal && (val > LONG_T_MAX)) {
10673                         type = &ulong_type;
10674                 }
10675                 else if (val > INT_T_MAX) {
10676                         type = &long_type;
10677                 }
10678         }
10679         def = int_const(state, type, val);
10680         return def;
10681 }
10682
10683 static struct triple *primary_expr(struct compile_state *state)
10684 {
10685         struct triple *def;
10686         int tok;
10687         tok = peek(state);
10688         switch(tok) {
10689         case TOK_IDENT:
10690         {
10691                 struct hash_entry *ident;
10692                 /* Here ident is either:
10693                  * a varable name
10694                  * a function name
10695                  */
10696                 ident = eat(state, TOK_IDENT)->ident;
10697                 if (!ident->sym_ident) {
10698                         error(state, 0, "%s undeclared", ident->name);
10699                 }
10700                 def = ident->sym_ident->def;
10701                 break;
10702         }
10703         case TOK_ENUM_CONST:
10704         {
10705                 struct hash_entry *ident;
10706                 /* Here ident is an enumeration constant */
10707                 ident = eat(state, TOK_ENUM_CONST)->ident;
10708                 if (!ident->sym_ident) {
10709                         error(state, 0, "%s undeclared", ident->name);
10710                 }
10711                 def = ident->sym_ident->def;
10712                 break;
10713         }
10714         case TOK_MIDENT:
10715         {
10716                 struct hash_entry *ident;
10717                 ident = eat(state, TOK_MIDENT)->ident;
10718                 warning(state, 0, "Replacing undefined macro: %s with 0",
10719                         ident->name);
10720                 def = int_const(state, &int_type, 0);
10721                 break;
10722         }
10723         case TOK_LPAREN:
10724                 eat(state, TOK_LPAREN);
10725                 def = expr(state);
10726                 eat(state, TOK_RPAREN);
10727                 break;
10728         case TOK_LIT_INT:
10729                 def = integer_constant(state);
10730                 break;
10731         case TOK_LIT_FLOAT:
10732                 eat(state, TOK_LIT_FLOAT);
10733                 error(state, 0, "Floating point constants not supported");
10734                 def = 0;
10735                 FINISHME();
10736                 break;
10737         case TOK_LIT_CHAR:
10738                 def = character_constant(state);
10739                 break;
10740         case TOK_LIT_STRING:
10741                 def = string_constant(state);
10742                 break;
10743         default:
10744                 def = 0;
10745                 error(state, 0, "Unexpected token: %s\n", tokens[tok]);
10746         }
10747         return def;
10748 }
10749
10750 static struct triple *postfix_expr(struct compile_state *state)
10751 {
10752         struct triple *def;
10753         int postfix;
10754         def = primary_expr(state);
10755         do {
10756                 struct triple *left;
10757                 int tok;
10758                 postfix = 1;
10759                 left = def;
10760                 switch((tok = peek(state))) {
10761                 case TOK_LBRACKET:
10762                         eat(state, TOK_LBRACKET);
10763                         def = mk_subscript_expr(state, left, expr(state));
10764                         eat(state, TOK_RBRACKET);
10765                         break;
10766                 case TOK_LPAREN:
10767                         def = call_expr(state, def);
10768                         break;
10769                 case TOK_DOT:
10770                 {
10771                         struct hash_entry *field;
10772                         eat(state, TOK_DOT);
10773                         field = eat(state, TOK_IDENT)->ident;
10774                         def = deref_field(state, def, field);
10775                         break;
10776                 }
10777                 case TOK_ARROW:
10778                 {
10779                         struct hash_entry *field;
10780                         eat(state, TOK_ARROW);
10781                         field = eat(state, TOK_IDENT)->ident;
10782                         def = mk_deref_expr(state, read_expr(state, def));
10783                         def = deref_field(state, def, field);
10784                         break;
10785                 }
10786                 case TOK_PLUSPLUS:
10787                         eat(state, TOK_PLUSPLUS);
10788                         def = mk_post_inc_expr(state, left);
10789                         break;
10790                 case TOK_MINUSMINUS:
10791                         eat(state, TOK_MINUSMINUS);
10792                         def = mk_post_dec_expr(state, left);
10793                         break;
10794                 default:
10795                         postfix = 0;
10796                         break;
10797                 }
10798         } while(postfix);
10799         return def;
10800 }
10801
10802 static struct triple *cast_expr(struct compile_state *state);
10803
10804 static struct triple *unary_expr(struct compile_state *state)
10805 {
10806         struct triple *def, *right;
10807         int tok;
10808         switch((tok = peek(state))) {
10809         case TOK_PLUSPLUS:
10810                 eat(state, TOK_PLUSPLUS);
10811                 def = mk_pre_inc_expr(state, unary_expr(state));
10812                 break;
10813         case TOK_MINUSMINUS:
10814                 eat(state, TOK_MINUSMINUS);
10815                 def = mk_pre_dec_expr(state, unary_expr(state));
10816                 break;
10817         case TOK_AND:
10818                 eat(state, TOK_AND);
10819                 def = mk_addr_expr(state, cast_expr(state), 0);
10820                 break;
10821         case TOK_STAR:
10822                 eat(state, TOK_STAR);
10823                 def = mk_deref_expr(state, read_expr(state, cast_expr(state)));
10824                 break;
10825         case TOK_PLUS:
10826                 eat(state, TOK_PLUS);
10827                 right = read_expr(state, cast_expr(state));
10828                 arithmetic(state, right);
10829                 def = integral_promotion(state, right);
10830                 break;
10831         case TOK_MINUS:
10832                 eat(state, TOK_MINUS);
10833                 right = read_expr(state, cast_expr(state));
10834                 arithmetic(state, right);
10835                 def = integral_promotion(state, right);
10836                 def = triple(state, OP_NEG, def->type, def, 0);
10837                 break;
10838         case TOK_TILDE:
10839                 eat(state, TOK_TILDE);
10840                 right = read_expr(state, cast_expr(state));
10841                 integral(state, right);
10842                 def = integral_promotion(state, right);
10843                 def = triple(state, OP_INVERT, def->type, def, 0);
10844                 break;
10845         case TOK_BANG:
10846                 eat(state, TOK_BANG);
10847                 right = read_expr(state, cast_expr(state));
10848                 bool(state, right);
10849                 def = lfalse_expr(state, right);
10850                 break;
10851         case TOK_SIZEOF:
10852         {
10853                 struct type *type;
10854                 int tok1, tok2;
10855                 eat(state, TOK_SIZEOF);
10856                 tok1 = peek(state);
10857                 tok2 = peek2(state);
10858                 if ((tok1 == TOK_LPAREN) && istype(tok2)) {
10859                         eat(state, TOK_LPAREN);
10860                         type = type_name(state);
10861                         eat(state, TOK_RPAREN);
10862                 }
10863                 else {
10864                         struct triple *expr;
10865                         expr = unary_expr(state);
10866                         type = expr->type;
10867                         release_expr(state, expr);
10868                 }
10869                 def = int_const(state, &ulong_type, size_of_in_bytes(state, type));
10870                 break;
10871         }
10872         case TOK_ALIGNOF:
10873         {
10874                 struct type *type;
10875                 int tok1, tok2;
10876                 eat(state, TOK_ALIGNOF);
10877                 tok1 = peek(state);
10878                 tok2 = peek2(state);
10879                 if ((tok1 == TOK_LPAREN) && istype(tok2)) {
10880                         eat(state, TOK_LPAREN);
10881                         type = type_name(state);
10882                         eat(state, TOK_RPAREN);
10883                 }
10884                 else {
10885                         struct triple *expr;
10886                         expr = unary_expr(state);
10887                         type = expr->type;
10888                         release_expr(state, expr);
10889                 }
10890                 def = int_const(state, &ulong_type, align_of_in_bytes(state, type));
10891                 break;
10892         }
10893         case TOK_MDEFINED:
10894         {
10895                 /* We only come here if we are called from the preprocessor */
10896                 struct hash_entry *ident;
10897                 int parens;
10898                 eat(state, TOK_MDEFINED);
10899                 parens = 0;
10900                 if (cpp_peek(state) == TOK_LPAREN) {
10901                         cpp_eat(state, TOK_LPAREN);
10902                         parens = 1;
10903                 }
10904                 ident = cpp_eat(state, TOK_MIDENT)->ident;
10905                 if (parens) {
10906                         eat(state, TOK_RPAREN);
10907                 }
10908                 def = int_const(state, &int_type, ident->sym_define != 0);
10909                 break;
10910         }
10911         default:
10912                 def = postfix_expr(state);
10913                 break;
10914         }
10915         return def;
10916 }
10917
10918 static struct triple *cast_expr(struct compile_state *state)
10919 {
10920         struct triple *def;
10921         int tok1, tok2;
10922         tok1 = peek(state);
10923         tok2 = peek2(state);
10924         if ((tok1 == TOK_LPAREN) && istype(tok2)) {
10925                 struct type *type;
10926                 eat(state, TOK_LPAREN);
10927                 type = type_name(state);
10928                 eat(state, TOK_RPAREN);
10929                 def = mk_cast_expr(state, type, cast_expr(state));
10930         }
10931         else {
10932                 def = unary_expr(state);
10933         }
10934         return def;
10935 }
10936
10937 static struct triple *mult_expr(struct compile_state *state)
10938 {
10939         struct triple *def;
10940         int done;
10941         def = cast_expr(state);
10942         do {
10943                 struct triple *left, *right;
10944                 struct type *result_type;
10945                 int tok, op, sign;
10946                 done = 0;
10947                 switch(tok = (peek(state))) {
10948                 case TOK_STAR:
10949                 case TOK_DIV:
10950                 case TOK_MOD:
10951                         left = read_expr(state, def);
10952                         arithmetic(state, left);
10953
10954                         eat(state, tok);
10955
10956                         right = read_expr(state, cast_expr(state));
10957                         arithmetic(state, right);
10958
10959                         result_type = arithmetic_result(state, left, right);
10960                         sign = is_signed(result_type);
10961                         op = -1;
10962                         switch(tok) {
10963                         case TOK_STAR: op = sign? OP_SMUL : OP_UMUL; break;
10964                         case TOK_DIV:  op = sign? OP_SDIV : OP_UDIV; break;
10965                         case TOK_MOD:  op = sign? OP_SMOD : OP_UMOD; break;
10966                         }
10967                         def = triple(state, op, result_type, left, right);
10968                         break;
10969                 default:
10970                         done = 1;
10971                         break;
10972                 }
10973         } while(!done);
10974         return def;
10975 }
10976
10977 static struct triple *add_expr(struct compile_state *state)
10978 {
10979         struct triple *def;
10980         int done;
10981         def = mult_expr(state);
10982         do {
10983                 done = 0;
10984                 switch( peek(state)) {
10985                 case TOK_PLUS:
10986                         eat(state, TOK_PLUS);
10987                         def = mk_add_expr(state, def, mult_expr(state));
10988                         break;
10989                 case TOK_MINUS:
10990                         eat(state, TOK_MINUS);
10991                         def = mk_sub_expr(state, def, mult_expr(state));
10992                         break;
10993                 default:
10994                         done = 1;
10995                         break;
10996                 }
10997         } while(!done);
10998         return def;
10999 }
11000
11001 static struct triple *shift_expr(struct compile_state *state)
11002 {
11003         struct triple *def;
11004         int done;
11005         def = add_expr(state);
11006         do {
11007                 struct triple *left, *right;
11008                 int tok, op;
11009                 done = 0;
11010                 switch((tok = peek(state))) {
11011                 case TOK_SL:
11012                 case TOK_SR:
11013                         left = read_expr(state, def);
11014                         integral(state, left);
11015                         left = integral_promotion(state, left);
11016
11017                         eat(state, tok);
11018
11019                         right = read_expr(state, add_expr(state));
11020                         integral(state, right);
11021                         right = integral_promotion(state, right);
11022                         
11023                         op = (tok == TOK_SL)? OP_SL : 
11024                                 is_signed(left->type)? OP_SSR: OP_USR;
11025
11026                         def = triple(state, op, left->type, left, right);
11027                         break;
11028                 default:
11029                         done = 1;
11030                         break;
11031                 }
11032         } while(!done);
11033         return def;
11034 }
11035
11036 static struct triple *relational_expr(struct compile_state *state)
11037 {
11038 #warning "Extend relational exprs to work on more than arithmetic types"
11039         struct triple *def;
11040         int done;
11041         def = shift_expr(state);
11042         do {
11043                 struct triple *left, *right;
11044                 struct type *arg_type;
11045                 int tok, op, sign;
11046                 done = 0;
11047                 switch((tok = peek(state))) {
11048                 case TOK_LESS:
11049                 case TOK_MORE:
11050                 case TOK_LESSEQ:
11051                 case TOK_MOREEQ:
11052                         left = read_expr(state, def);
11053                         arithmetic(state, left);
11054
11055                         eat(state, tok);
11056
11057                         right = read_expr(state, shift_expr(state));
11058                         arithmetic(state, right);
11059
11060                         arg_type = arithmetic_result(state, left, right);
11061                         sign = is_signed(arg_type);
11062                         op = -1;
11063                         switch(tok) {
11064                         case TOK_LESS:   op = sign? OP_SLESS : OP_ULESS; break;
11065                         case TOK_MORE:   op = sign? OP_SMORE : OP_UMORE; break;
11066                         case TOK_LESSEQ: op = sign? OP_SLESSEQ : OP_ULESSEQ; break;
11067                         case TOK_MOREEQ: op = sign? OP_SMOREEQ : OP_UMOREEQ; break;
11068                         }
11069                         def = triple(state, op, &int_type, left, right);
11070                         break;
11071                 default:
11072                         done = 1;
11073                         break;
11074                 }
11075         } while(!done);
11076         return def;
11077 }
11078
11079 static struct triple *equality_expr(struct compile_state *state)
11080 {
11081 #warning "Extend equality exprs to work on more than arithmetic types"
11082         struct triple *def;
11083         int done;
11084         def = relational_expr(state);
11085         do {
11086                 struct triple *left, *right;
11087                 int tok, op;
11088                 done = 0;
11089                 switch((tok = peek(state))) {
11090                 case TOK_EQEQ:
11091                 case TOK_NOTEQ:
11092                         left = read_expr(state, def);
11093                         arithmetic(state, left);
11094                         eat(state, tok);
11095                         right = read_expr(state, relational_expr(state));
11096                         arithmetic(state, right);
11097                         op = (tok == TOK_EQEQ) ? OP_EQ: OP_NOTEQ;
11098                         def = triple(state, op, &int_type, left, right);
11099                         break;
11100                 default:
11101                         done = 1;
11102                         break;
11103                 }
11104         } while(!done);
11105         return def;
11106 }
11107
11108 static struct triple *and_expr(struct compile_state *state)
11109 {
11110         struct triple *def;
11111         def = equality_expr(state);
11112         while(peek(state) == TOK_AND) {
11113                 struct triple *left, *right;
11114                 struct type *result_type;
11115                 left = read_expr(state, def);
11116                 integral(state, left);
11117                 eat(state, TOK_AND);
11118                 right = read_expr(state, equality_expr(state));
11119                 integral(state, right);
11120                 result_type = arithmetic_result(state, left, right);
11121                 def = triple(state, OP_AND, result_type, left, right);
11122         }
11123         return def;
11124 }
11125
11126 static struct triple *xor_expr(struct compile_state *state)
11127 {
11128         struct triple *def;
11129         def = and_expr(state);
11130         while(peek(state) == TOK_XOR) {
11131                 struct triple *left, *right;
11132                 struct type *result_type;
11133                 left = read_expr(state, def);
11134                 integral(state, left);
11135                 eat(state, TOK_XOR);
11136                 right = read_expr(state, and_expr(state));
11137                 integral(state, right);
11138                 result_type = arithmetic_result(state, left, right);
11139                 def = triple(state, OP_XOR, result_type, left, right);
11140         }
11141         return def;
11142 }
11143
11144 static struct triple *or_expr(struct compile_state *state)
11145 {
11146         struct triple *def;
11147         def = xor_expr(state);
11148         while(peek(state) == TOK_OR) {
11149                 struct triple *left, *right;
11150                 struct type *result_type;
11151                 left = read_expr(state, def);
11152                 integral(state, left);
11153                 eat(state, TOK_OR);
11154                 right = read_expr(state, xor_expr(state));
11155                 integral(state, right);
11156                 result_type = arithmetic_result(state, left, right);
11157                 def = triple(state, OP_OR, result_type, left, right);
11158         }
11159         return def;
11160 }
11161
11162 static struct triple *land_expr(struct compile_state *state)
11163 {
11164         struct triple *def;
11165         def = or_expr(state);
11166         while(peek(state) == TOK_LOGAND) {
11167                 struct triple *left, *right;
11168                 left = read_expr(state, def);
11169                 bool(state, left);
11170                 eat(state, TOK_LOGAND);
11171                 right = read_expr(state, or_expr(state));
11172                 bool(state, right);
11173
11174                 def = mkland_expr(state,
11175                         ltrue_expr(state, left),
11176                         ltrue_expr(state, right));
11177         }
11178         return def;
11179 }
11180
11181 static struct triple *lor_expr(struct compile_state *state)
11182 {
11183         struct triple *def;
11184         def = land_expr(state);
11185         while(peek(state) == TOK_LOGOR) {
11186                 struct triple *left, *right;
11187                 left = read_expr(state, def);
11188                 bool(state, left);
11189                 eat(state, TOK_LOGOR);
11190                 right = read_expr(state, land_expr(state));
11191                 bool(state, right);
11192
11193                 def = mklor_expr(state, 
11194                         ltrue_expr(state, left),
11195                         ltrue_expr(state, right));
11196         }
11197         return def;
11198 }
11199
11200 static struct triple *conditional_expr(struct compile_state *state)
11201 {
11202         struct triple *def;
11203         def = lor_expr(state);
11204         if (peek(state) == TOK_QUEST) {
11205                 struct triple *test, *left, *right;
11206                 bool(state, def);
11207                 test = ltrue_expr(state, read_expr(state, def));
11208                 eat(state, TOK_QUEST);
11209                 left = read_expr(state, expr(state));
11210                 eat(state, TOK_COLON);
11211                 right = read_expr(state, conditional_expr(state));
11212
11213                 def = mkcond_expr(state, test, left, right);
11214         }
11215         return def;
11216 }
11217
11218 struct cv_triple {
11219         struct triple *val;
11220         int id;
11221 };
11222
11223 static void set_cv(struct compile_state *state, struct cv_triple *cv,
11224         struct triple *dest, struct triple *val)
11225 {
11226         if (cv[dest->id].val) {
11227                 free_triple(state, cv[dest->id].val);
11228         }
11229         cv[dest->id].val = val;
11230 }
11231 static struct triple *get_cv(struct compile_state *state, struct cv_triple *cv,
11232         struct triple *src)
11233 {
11234         return cv[src->id].val;
11235 }
11236
11237 static struct triple *eval_const_expr(
11238         struct compile_state *state, struct triple *expr)
11239 {
11240         struct triple *def;
11241         if (is_const(expr)) {
11242                 def = expr;
11243         }
11244         else {
11245                 /* If we don't start out as a constant simplify into one */
11246                 struct triple *head, *ptr;
11247                 struct cv_triple *cv;
11248                 int i, count;
11249                 head = label(state); /* dummy initial triple */
11250                 flatten(state, head, expr);
11251                 count = 1;
11252                 for(ptr = head->next; ptr != head; ptr = ptr->next) {
11253                         count++;
11254                 }
11255                 cv = xcmalloc(sizeof(struct cv_triple)*count, "const value vector");
11256                 i = 1;
11257                 for(ptr = head->next; ptr != head; ptr = ptr->next) {
11258                         cv[i].val = 0;
11259                         cv[i].id  = ptr->id;
11260                         ptr->id   = i;
11261                         i++;
11262                 }
11263                 ptr = head->next;
11264                 do {
11265                         valid_ins(state, ptr);
11266                         if ((ptr->op == OP_PHI) || (ptr->op == OP_LIST)) {
11267                                 internal_error(state, ptr, 
11268                                         "unexpected %s in constant expression",
11269                                         tops(ptr->op));
11270                         }
11271                         else if (ptr->op == OP_LIST) {
11272                         }
11273                         else if (triple_is_structural(state, ptr)) {
11274                                 ptr = ptr->next;
11275                         }
11276                         else if (triple_is_ubranch(state, ptr)) {
11277                                 ptr = TARG(ptr, 0);
11278                         }
11279                         else if (triple_is_cbranch(state, ptr)) {
11280                                 struct triple *cond_val;
11281                                 cond_val = get_cv(state, cv, RHS(ptr, 0));
11282                                 if (!cond_val || !is_const(cond_val) || 
11283                                         (cond_val->op != OP_INTCONST)) 
11284                                 {
11285                                         internal_error(state, ptr, "bad branch condition");
11286                                 }
11287                                 if (cond_val->u.cval == 0) {
11288                                         ptr = ptr->next;
11289                                 } else {
11290                                         ptr = TARG(ptr, 0);
11291                                 }
11292                         }
11293                         else if (triple_is_branch(state, ptr)) {
11294                                 error(state, ptr, "bad branch type in constant expression");
11295                         }
11296                         else if (ptr->op == OP_WRITE) {
11297                                 struct triple *val;
11298                                 val = get_cv(state, cv, RHS(ptr, 0));
11299                                 
11300                                 set_cv(state, cv, MISC(ptr, 0), 
11301                                         copy_triple(state, val));
11302                                 set_cv(state, cv, ptr, 
11303                                         copy_triple(state, val));
11304                                 ptr = ptr->next;
11305                         }
11306                         else if (ptr->op == OP_READ) {
11307                                 set_cv(state, cv, ptr, 
11308                                         copy_triple(state, 
11309                                                 get_cv(state, cv, RHS(ptr, 0))));
11310                                 ptr = ptr->next;
11311                         }
11312                         else if (triple_is_pure(state, ptr, cv[ptr->id].id)) {
11313                                 struct triple *val, **rhs;
11314                                 val = copy_triple(state, ptr);
11315                                 rhs = triple_rhs(state, val, 0);
11316                                 for(; rhs; rhs = triple_rhs(state, val, rhs)) {
11317                                         if (!*rhs) {
11318                                                 internal_error(state, ptr, "Missing rhs");
11319                                         }
11320                                         *rhs = get_cv(state, cv, *rhs);
11321                                 }
11322                                 simplify(state, val);
11323                                 set_cv(state, cv, ptr, val);
11324                                 ptr = ptr->next;
11325                         }
11326                         else {
11327                                 error(state, ptr, "impure operation in constant expression");
11328                         }
11329                         
11330                 } while(ptr != head);
11331
11332                 /* Get the result value */
11333                 def = get_cv(state, cv, head->prev);
11334                 cv[head->prev->id].val = 0;
11335
11336                 /* Free the temporary values */
11337                 for(i = 0; i < count; i++) {
11338                         if (cv[i].val) {
11339                                 free_triple(state, cv[i].val);
11340                                 cv[i].val = 0;
11341                         }
11342                 }
11343                 xfree(cv);
11344                 /* Free the intermediate expressions */
11345                 while(head->next != head) {
11346                         release_triple(state, head->next);
11347                 }
11348                 free_triple(state, head);
11349         }
11350         if (!is_const(def)) {
11351                 error(state, expr, "Not a constant expression");
11352         }
11353         return def;
11354 }
11355
11356 static struct triple *constant_expr(struct compile_state *state)
11357 {
11358         return eval_const_expr(state, conditional_expr(state));
11359 }
11360
11361 static struct triple *assignment_expr(struct compile_state *state)
11362 {
11363         struct triple *def, *left, *right;
11364         int tok, op, sign;
11365         /* The C grammer in K&R shows assignment expressions
11366          * only taking unary expressions as input on their
11367          * left hand side.  But specifies the precedence of
11368          * assignemnt as the lowest operator except for comma.
11369          *
11370          * Allowing conditional expressions on the left hand side
11371          * of an assignement results in a grammar that accepts
11372          * a larger set of statements than standard C.   As long
11373          * as the subset of the grammar that is standard C behaves
11374          * correctly this should cause no problems.
11375          * 
11376          * For the extra token strings accepted by the grammar
11377          * none of them should produce a valid lvalue, so they
11378          * should not produce functioning programs.
11379          *
11380          * GCC has this bug as well, so surprises should be minimal.
11381          */
11382         def = conditional_expr(state);
11383         left = def;
11384         switch((tok = peek(state))) {
11385         case TOK_EQ:
11386                 lvalue(state, left);
11387                 eat(state, TOK_EQ);
11388                 def = write_expr(state, left, 
11389                         read_expr(state, assignment_expr(state)));
11390                 break;
11391         case TOK_TIMESEQ:
11392         case TOK_DIVEQ:
11393         case TOK_MODEQ:
11394                 lvalue(state, left);
11395                 arithmetic(state, left);
11396                 eat(state, tok);
11397                 right = read_expr(state, assignment_expr(state));
11398                 arithmetic(state, right);
11399
11400                 sign = is_signed(left->type);
11401                 op = -1;
11402                 switch(tok) {
11403                 case TOK_TIMESEQ: op = sign? OP_SMUL : OP_UMUL; break;
11404                 case TOK_DIVEQ:   op = sign? OP_SDIV : OP_UDIV; break;
11405                 case TOK_MODEQ:   op = sign? OP_SMOD : OP_UMOD; break;
11406                 }
11407                 def = write_expr(state, left,
11408                         triple(state, op, left->type, 
11409                                 read_expr(state, left), right));
11410                 break;
11411         case TOK_PLUSEQ:
11412                 lvalue(state, left);
11413                 eat(state, TOK_PLUSEQ);
11414                 def = write_expr(state, left,
11415                         mk_add_expr(state, left, assignment_expr(state)));
11416                 break;
11417         case TOK_MINUSEQ:
11418                 lvalue(state, left);
11419                 eat(state, TOK_MINUSEQ);
11420                 def = write_expr(state, left,
11421                         mk_sub_expr(state, left, assignment_expr(state)));
11422                 break;
11423         case TOK_SLEQ:
11424         case TOK_SREQ:
11425         case TOK_ANDEQ:
11426         case TOK_XOREQ:
11427         case TOK_OREQ:
11428                 lvalue(state, left);
11429                 integral(state, left);
11430                 eat(state, tok);
11431                 right = read_expr(state, assignment_expr(state));
11432                 integral(state, right);
11433                 right = integral_promotion(state, right);
11434                 sign = is_signed(left->type);
11435                 op = -1;
11436                 switch(tok) {
11437                 case TOK_SLEQ:  op = OP_SL; break;
11438                 case TOK_SREQ:  op = sign? OP_SSR: OP_USR; break;
11439                 case TOK_ANDEQ: op = OP_AND; break;
11440                 case TOK_XOREQ: op = OP_XOR; break;
11441                 case TOK_OREQ:  op = OP_OR; break;
11442                 }
11443                 def = write_expr(state, left,
11444                         triple(state, op, left->type, 
11445                                 read_expr(state, left), right));
11446                 break;
11447         }
11448         return def;
11449 }
11450
11451 static struct triple *expr(struct compile_state *state)
11452 {
11453         struct triple *def;
11454         def = assignment_expr(state);
11455         while(peek(state) == TOK_COMMA) {
11456                 eat(state, TOK_COMMA);
11457                 def = mkprog(state, def, assignment_expr(state), 0);
11458         }
11459         return def;
11460 }
11461
11462 static void expr_statement(struct compile_state *state, struct triple *first)
11463 {
11464         if (peek(state) != TOK_SEMI) {
11465                 /* lvalue conversions always apply except when certian operators
11466                  * are applied.  I apply the lvalue conversions here
11467                  * as I know no more operators will be applied.
11468                  */
11469                 flatten(state, first, lvalue_conversion(state, expr(state)));
11470         }
11471         eat(state, TOK_SEMI);
11472 }
11473
11474 static void if_statement(struct compile_state *state, struct triple *first)
11475 {
11476         struct triple *test, *jmp1, *jmp2, *middle, *end;
11477
11478         jmp1 = jmp2 = middle = 0;
11479         eat(state, TOK_IF);
11480         eat(state, TOK_LPAREN);
11481         test = expr(state);
11482         bool(state, test);
11483         /* Cleanup and invert the test */
11484         test = lfalse_expr(state, read_expr(state, test));
11485         eat(state, TOK_RPAREN);
11486         /* Generate the needed pieces */
11487         middle = label(state);
11488         jmp1 = branch(state, middle, test);
11489         /* Thread the pieces together */
11490         flatten(state, first, test);
11491         flatten(state, first, jmp1);
11492         flatten(state, first, label(state));
11493         statement(state, first);
11494         if (peek(state) == TOK_ELSE) {
11495                 eat(state, TOK_ELSE);
11496                 /* Generate the rest of the pieces */
11497                 end = label(state);
11498                 jmp2 = branch(state, end, 0);
11499                 /* Thread them together */
11500                 flatten(state, first, jmp2);
11501                 flatten(state, first, middle);
11502                 statement(state, first);
11503                 flatten(state, first, end);
11504         }
11505         else {
11506                 flatten(state, first, middle);
11507         }
11508 }
11509
11510 static void for_statement(struct compile_state *state, struct triple *first)
11511 {
11512         struct triple *head, *test, *tail, *jmp1, *jmp2, *end;
11513         struct triple *label1, *label2, *label3;
11514         struct hash_entry *ident;
11515
11516         eat(state, TOK_FOR);
11517         eat(state, TOK_LPAREN);
11518         head = test = tail = jmp1 = jmp2 = 0;
11519         if (peek(state) != TOK_SEMI) {
11520                 head = expr(state);
11521         } 
11522         eat(state, TOK_SEMI);
11523         if (peek(state) != TOK_SEMI) {
11524                 test = expr(state);
11525                 bool(state, test);
11526                 test = ltrue_expr(state, read_expr(state, test));
11527         }
11528         eat(state, TOK_SEMI);
11529         if (peek(state) != TOK_RPAREN) {
11530                 tail = expr(state);
11531         }
11532         eat(state, TOK_RPAREN);
11533         /* Generate the needed pieces */
11534         label1 = label(state);
11535         label2 = label(state);
11536         label3 = label(state);
11537         if (test) {
11538                 jmp1 = branch(state, label3, 0);
11539                 jmp2 = branch(state, label1, test);
11540         }
11541         else {
11542                 jmp2 = branch(state, label1, 0);
11543         }
11544         end = label(state);
11545         /* Remember where break and continue go */
11546         start_scope(state);
11547         ident = state->i_break;
11548         symbol(state, ident, &ident->sym_ident, end, end->type);
11549         ident = state->i_continue;
11550         symbol(state, ident, &ident->sym_ident, label2, label2->type);
11551         /* Now include the body */
11552         flatten(state, first, head);
11553         flatten(state, first, jmp1);
11554         flatten(state, first, label1);
11555         statement(state, first);
11556         flatten(state, first, label2);
11557         flatten(state, first, tail);
11558         flatten(state, first, label3);
11559         flatten(state, first, test);
11560         flatten(state, first, jmp2);
11561         flatten(state, first, end);
11562         /* Cleanup the break/continue scope */
11563         end_scope(state);
11564 }
11565
11566 static void while_statement(struct compile_state *state, struct triple *first)
11567 {
11568         struct triple *label1, *test, *label2, *jmp1, *jmp2, *end;
11569         struct hash_entry *ident;
11570         eat(state, TOK_WHILE);
11571         eat(state, TOK_LPAREN);
11572         test = expr(state);
11573         bool(state, test);
11574         test = ltrue_expr(state, read_expr(state, test));
11575         eat(state, TOK_RPAREN);
11576         /* Generate the needed pieces */
11577         label1 = label(state);
11578         label2 = label(state);
11579         jmp1 = branch(state, label2, 0);
11580         jmp2 = branch(state, label1, test);
11581         end = label(state);
11582         /* Remember where break and continue go */
11583         start_scope(state);
11584         ident = state->i_break;
11585         symbol(state, ident, &ident->sym_ident, end, end->type);
11586         ident = state->i_continue;
11587         symbol(state, ident, &ident->sym_ident, label2, label2->type);
11588         /* Thread them together */
11589         flatten(state, first, jmp1);
11590         flatten(state, first, label1);
11591         statement(state, first);
11592         flatten(state, first, label2);
11593         flatten(state, first, test);
11594         flatten(state, first, jmp2);
11595         flatten(state, first, end);
11596         /* Cleanup the break/continue scope */
11597         end_scope(state);
11598 }
11599
11600 static void do_statement(struct compile_state *state, struct triple *first)
11601 {
11602         struct triple *label1, *label2, *test, *end;
11603         struct hash_entry *ident;
11604         eat(state, TOK_DO);
11605         /* Generate the needed pieces */
11606         label1 = label(state);
11607         label2 = label(state);
11608         end = label(state);
11609         /* Remember where break and continue go */
11610         start_scope(state);
11611         ident = state->i_break;
11612         symbol(state, ident, &ident->sym_ident, end, end->type);
11613         ident = state->i_continue;
11614         symbol(state, ident, &ident->sym_ident, label2, label2->type);
11615         /* Now include the body */
11616         flatten(state, first, label1);
11617         statement(state, first);
11618         /* Cleanup the break/continue scope */
11619         end_scope(state);
11620         /* Eat the rest of the loop */
11621         eat(state, TOK_WHILE);
11622         eat(state, TOK_LPAREN);
11623         test = read_expr(state, expr(state));
11624         bool(state, test);
11625         eat(state, TOK_RPAREN);
11626         eat(state, TOK_SEMI);
11627         /* Thread the pieces together */
11628         test = ltrue_expr(state, test);
11629         flatten(state, first, label2);
11630         flatten(state, first, test);
11631         flatten(state, first, branch(state, label1, test));
11632         flatten(state, first, end);
11633 }
11634
11635
11636 static void return_statement(struct compile_state *state, struct triple *first)
11637 {
11638         struct triple *jmp, *mv, *dest, *var, *val;
11639         int last;
11640         eat(state, TOK_RETURN);
11641
11642 #warning "FIXME implement a more general excess branch elimination"
11643         val = 0;
11644         /* If we have a return value do some more work */
11645         if (peek(state) != TOK_SEMI) {
11646                 val = read_expr(state, expr(state));
11647         }
11648         eat(state, TOK_SEMI);
11649
11650         /* See if this last statement in a function */
11651         last = ((peek(state) == TOK_RBRACE) && 
11652                 (state->scope_depth == GLOBAL_SCOPE_DEPTH +2));
11653
11654         /* Find the return variable */
11655         var = fresult(state, state->main_function);
11656
11657         /* Find the return destination */
11658         dest = state->i_return->sym_ident->def;
11659         mv = jmp = 0;
11660         /* If needed generate a jump instruction */
11661         if (!last) {
11662                 jmp = branch(state, dest, 0);
11663         }
11664         /* If needed generate an assignment instruction */
11665         if (val) {
11666                 mv = write_expr(state, deref_index(state, var, 1), val);
11667         }
11668         /* Now put the code together */
11669         if (mv) {
11670                 flatten(state, first, mv);
11671                 flatten(state, first, jmp);
11672         }
11673         else if (jmp) {
11674                 flatten(state, first, jmp);
11675         }
11676 }
11677
11678 static void break_statement(struct compile_state *state, struct triple *first)
11679 {
11680         struct triple *dest;
11681         eat(state, TOK_BREAK);
11682         eat(state, TOK_SEMI);
11683         if (!state->i_break->sym_ident) {
11684                 error(state, 0, "break statement not within loop or switch");
11685         }
11686         dest = state->i_break->sym_ident->def;
11687         flatten(state, first, branch(state, dest, 0));
11688 }
11689
11690 static void continue_statement(struct compile_state *state, struct triple *first)
11691 {
11692         struct triple *dest;
11693         eat(state, TOK_CONTINUE);
11694         eat(state, TOK_SEMI);
11695         if (!state->i_continue->sym_ident) {
11696                 error(state, 0, "continue statement outside of a loop");
11697         }
11698         dest = state->i_continue->sym_ident->def;
11699         flatten(state, first, branch(state, dest, 0));
11700 }
11701
11702 static void goto_statement(struct compile_state *state, struct triple *first)
11703 {
11704         struct hash_entry *ident;
11705         eat(state, TOK_GOTO);
11706         ident = eat(state, TOK_IDENT)->ident;
11707         if (!ident->sym_label) {
11708                 /* If this is a forward branch allocate the label now,
11709                  * it will be flattend in the appropriate location later.
11710                  */
11711                 struct triple *ins;
11712                 ins = label(state);
11713                 label_symbol(state, ident, ins, FUNCTION_SCOPE_DEPTH);
11714         }
11715         eat(state, TOK_SEMI);
11716
11717         flatten(state, first, branch(state, ident->sym_label->def, 0));
11718 }
11719
11720 static void labeled_statement(struct compile_state *state, struct triple *first)
11721 {
11722         struct triple *ins;
11723         struct hash_entry *ident;
11724
11725         ident = eat(state, TOK_IDENT)->ident;
11726         if (ident->sym_label && ident->sym_label->def) {
11727                 ins = ident->sym_label->def;
11728                 put_occurance(ins->occurance);
11729                 ins->occurance = new_occurance(state);
11730         }
11731         else {
11732                 ins = label(state);
11733                 label_symbol(state, ident, ins, FUNCTION_SCOPE_DEPTH);
11734         }
11735         if (ins->id & TRIPLE_FLAG_FLATTENED) {
11736                 error(state, 0, "label %s already defined", ident->name);
11737         }
11738         flatten(state, first, ins);
11739
11740         eat(state, TOK_COLON);
11741         statement(state, first);
11742 }
11743
11744 static void switch_statement(struct compile_state *state, struct triple *first)
11745 {
11746         struct triple *value, *top, *end, *dbranch;
11747         struct hash_entry *ident;
11748
11749         /* See if we have a valid switch statement */
11750         eat(state, TOK_SWITCH);
11751         eat(state, TOK_LPAREN);
11752         value = expr(state);
11753         integral(state, value);
11754         value = read_expr(state, value);
11755         eat(state, TOK_RPAREN);
11756         /* Generate the needed pieces */
11757         top = label(state);
11758         end = label(state);
11759         dbranch = branch(state, end, 0);
11760         /* Remember where case branches and break goes */
11761         start_scope(state);
11762         ident = state->i_switch;
11763         symbol(state, ident, &ident->sym_ident, value, value->type);
11764         ident = state->i_case;
11765         symbol(state, ident, &ident->sym_ident, top, top->type);
11766         ident = state->i_break;
11767         symbol(state, ident, &ident->sym_ident, end, end->type);
11768         ident = state->i_default;
11769         symbol(state, ident, &ident->sym_ident, dbranch, dbranch->type);
11770         /* Thread them together */
11771         flatten(state, first, value);
11772         flatten(state, first, top);
11773         flatten(state, first, dbranch);
11774         statement(state, first);
11775         flatten(state, first, end);
11776         /* Cleanup the switch scope */
11777         end_scope(state);
11778 }
11779
11780 static void case_statement(struct compile_state *state, struct triple *first)
11781 {
11782         struct triple *cvalue, *dest, *test, *jmp;
11783         struct triple *ptr, *value, *top, *dbranch;
11784
11785         /* See if w have a valid case statement */
11786         eat(state, TOK_CASE);
11787         cvalue = constant_expr(state);
11788         integral(state, cvalue);
11789         if (cvalue->op != OP_INTCONST) {
11790                 error(state, 0, "integer constant expected");
11791         }
11792         eat(state, TOK_COLON);
11793         if (!state->i_case->sym_ident) {
11794                 error(state, 0, "case statement not within a switch");
11795         }
11796
11797         /* Lookup the interesting pieces */
11798         top = state->i_case->sym_ident->def;
11799         value = state->i_switch->sym_ident->def;
11800         dbranch = state->i_default->sym_ident->def;
11801
11802         /* See if this case label has already been used */
11803         for(ptr = top; ptr != dbranch; ptr = ptr->next) {
11804                 if (ptr->op != OP_EQ) {
11805                         continue;
11806                 }
11807                 if (RHS(ptr, 1)->u.cval == cvalue->u.cval) {
11808                         error(state, 0, "duplicate case %d statement",
11809                                 cvalue->u.cval);
11810                 }
11811         }
11812         /* Generate the needed pieces */
11813         dest = label(state);
11814         test = triple(state, OP_EQ, &int_type, value, cvalue);
11815         jmp = branch(state, dest, test);
11816         /* Thread the pieces together */
11817         flatten(state, dbranch, test);
11818         flatten(state, dbranch, jmp);
11819         flatten(state, dbranch, label(state));
11820         flatten(state, first, dest);
11821         statement(state, first);
11822 }
11823
11824 static void default_statement(struct compile_state *state, struct triple *first)
11825 {
11826         struct triple *dest;
11827         struct triple *dbranch, *end;
11828
11829         /* See if we have a valid default statement */
11830         eat(state, TOK_DEFAULT);
11831         eat(state, TOK_COLON);
11832
11833         if (!state->i_case->sym_ident) {
11834                 error(state, 0, "default statement not within a switch");
11835         }
11836
11837         /* Lookup the interesting pieces */
11838         dbranch = state->i_default->sym_ident->def;
11839         end = state->i_break->sym_ident->def;
11840
11841         /* See if a default statement has already happened */
11842         if (TARG(dbranch, 0) != end) {
11843                 error(state, 0, "duplicate default statement");
11844         }
11845
11846         /* Generate the needed pieces */
11847         dest = label(state);
11848
11849         /* Blame the branch on the default statement */
11850         put_occurance(dbranch->occurance);
11851         dbranch->occurance = new_occurance(state);
11852
11853         /* Thread the pieces together */
11854         TARG(dbranch, 0) = dest;
11855         use_triple(dest, dbranch);
11856         flatten(state, first, dest);
11857         statement(state, first);
11858 }
11859
11860 static void asm_statement(struct compile_state *state, struct triple *first)
11861 {
11862         struct asm_info *info;
11863         struct {
11864                 struct triple *constraint;
11865                 struct triple *expr;
11866         } out_param[MAX_LHS], in_param[MAX_RHS], clob_param[MAX_LHS];
11867         struct triple *def, *asm_str;
11868         int out, in, clobbers, more, colons, i;
11869         int flags;
11870
11871         flags = 0;
11872         eat(state, TOK_ASM);
11873         /* For now ignore the qualifiers */
11874         switch(peek(state)) {
11875         case TOK_CONST:
11876                 eat(state, TOK_CONST);
11877                 break;
11878         case TOK_VOLATILE:
11879                 eat(state, TOK_VOLATILE);
11880                 flags |= TRIPLE_FLAG_VOLATILE;
11881                 break;
11882         }
11883         eat(state, TOK_LPAREN);
11884         asm_str = string_constant(state);
11885
11886         colons = 0;
11887         out = in = clobbers = 0;
11888         /* Outputs */
11889         if ((colons == 0) && (peek(state) == TOK_COLON)) {
11890                 eat(state, TOK_COLON);
11891                 colons++;
11892                 more = (peek(state) == TOK_LIT_STRING);
11893                 while(more) {
11894                         struct triple *var;
11895                         struct triple *constraint;
11896                         char *str;
11897                         more = 0;
11898                         if (out > MAX_LHS) {
11899                                 error(state, 0, "Maximum output count exceeded.");
11900                         }
11901                         constraint = string_constant(state);
11902                         str = constraint->u.blob;
11903                         if (str[0] != '=') {
11904                                 error(state, 0, "Output constraint does not start with =");
11905                         }
11906                         constraint->u.blob = str + 1;
11907                         eat(state, TOK_LPAREN);
11908                         var = conditional_expr(state);
11909                         eat(state, TOK_RPAREN);
11910
11911                         lvalue(state, var);
11912                         out_param[out].constraint = constraint;
11913                         out_param[out].expr       = var;
11914                         if (peek(state) == TOK_COMMA) {
11915                                 eat(state, TOK_COMMA);
11916                                 more = 1;
11917                         }
11918                         out++;
11919                 }
11920         }
11921         /* Inputs */
11922         if ((colons == 1) && (peek(state) == TOK_COLON)) {
11923                 eat(state, TOK_COLON);
11924                 colons++;
11925                 more = (peek(state) == TOK_LIT_STRING);
11926                 while(more) {
11927                         struct triple *val;
11928                         struct triple *constraint;
11929                         char *str;
11930                         more = 0;
11931                         if (in > MAX_RHS) {
11932                                 error(state, 0, "Maximum input count exceeded.");
11933                         }
11934                         constraint = string_constant(state);
11935                         str = constraint->u.blob;
11936                         if (digitp(str[0] && str[1] == '\0')) {
11937                                 int val;
11938                                 val = digval(str[0]);
11939                                 if ((val < 0) || (val >= out)) {
11940                                         error(state, 0, "Invalid input constraint %d", val);
11941                                 }
11942                         }
11943                         eat(state, TOK_LPAREN);
11944                         val = conditional_expr(state);
11945                         eat(state, TOK_RPAREN);
11946
11947                         in_param[in].constraint = constraint;
11948                         in_param[in].expr       = val;
11949                         if (peek(state) == TOK_COMMA) {
11950                                 eat(state, TOK_COMMA);
11951                                 more = 1;
11952                         }
11953                         in++;
11954                 }
11955         }
11956
11957         /* Clobber */
11958         if ((colons == 2) && (peek(state) == TOK_COLON)) {
11959                 eat(state, TOK_COLON);
11960                 colons++;
11961                 more = (peek(state) == TOK_LIT_STRING);
11962                 while(more) {
11963                         struct triple *clobber;
11964                         more = 0;
11965                         if ((clobbers + out) > MAX_LHS) {
11966                                 error(state, 0, "Maximum clobber limit exceeded.");
11967                         }
11968                         clobber = string_constant(state);
11969
11970                         clob_param[clobbers].constraint = clobber;
11971                         if (peek(state) == TOK_COMMA) {
11972                                 eat(state, TOK_COMMA);
11973                                 more = 1;
11974                         }
11975                         clobbers++;
11976                 }
11977         }
11978         eat(state, TOK_RPAREN);
11979         eat(state, TOK_SEMI);
11980
11981
11982         info = xcmalloc(sizeof(*info), "asm_info");
11983         info->str = asm_str->u.blob;
11984         free_triple(state, asm_str);
11985
11986         def = new_triple(state, OP_ASM, &void_type, clobbers + out, in);
11987         def->u.ainfo = info;
11988         def->id |= flags;
11989
11990         /* Find the register constraints */
11991         for(i = 0; i < out; i++) {
11992                 struct triple *constraint;
11993                 constraint = out_param[i].constraint;
11994                 info->tmpl.lhs[i] = arch_reg_constraint(state, 
11995                         out_param[i].expr->type, constraint->u.blob);
11996                 free_triple(state, constraint);
11997         }
11998         for(; i - out < clobbers; i++) {
11999                 struct triple *constraint;
12000                 constraint = clob_param[i - out].constraint;
12001                 info->tmpl.lhs[i] = arch_reg_clobber(state, constraint->u.blob);
12002                 free_triple(state, constraint);
12003         }
12004         for(i = 0; i < in; i++) {
12005                 struct triple *constraint;
12006                 const char *str;
12007                 constraint = in_param[i].constraint;
12008                 str = constraint->u.blob;
12009                 if (digitp(str[0]) && str[1] == '\0') {
12010                         struct reg_info cinfo;
12011                         int val;
12012                         val = digval(str[0]);
12013                         cinfo.reg = info->tmpl.lhs[val].reg;
12014                         cinfo.regcm = arch_type_to_regcm(state, in_param[i].expr->type);
12015                         cinfo.regcm &= info->tmpl.lhs[val].regcm;
12016                         if (cinfo.reg == REG_UNSET) {
12017                                 cinfo.reg = REG_VIRT0 + val;
12018                         }
12019                         if (cinfo.regcm == 0) {
12020                                 error(state, 0, "No registers for %d", val);
12021                         }
12022                         info->tmpl.lhs[val] = cinfo;
12023                         info->tmpl.rhs[i]   = cinfo;
12024                                 
12025                 } else {
12026                         info->tmpl.rhs[i] = arch_reg_constraint(state, 
12027                                 in_param[i].expr->type, str);
12028                 }
12029                 free_triple(state, constraint);
12030         }
12031
12032         /* Now build the helper expressions */
12033         for(i = 0; i < in; i++) {
12034                 RHS(def, i) = read_expr(state, in_param[i].expr);
12035         }
12036         flatten(state, first, def);
12037         for(i = 0; i < (out + clobbers); i++) {
12038                 struct type *type;
12039                 struct triple *piece;
12040                 if (i < out) {
12041                         type = out_param[i].expr->type;
12042                 } else {
12043                         size_t size = arch_reg_size(info->tmpl.lhs[i].reg);
12044                         if (size >= SIZEOF_LONG) {
12045                                 type = &ulong_type;
12046                         } 
12047                         else if (size >= SIZEOF_INT) {
12048                                 type = &uint_type;
12049                         }
12050                         else if (size >= SIZEOF_SHORT) {
12051                                 type = &ushort_type;
12052                         }
12053                         else {
12054                                 type = &uchar_type;
12055                         }
12056                 }
12057                 piece = triple(state, OP_PIECE, type, def, 0);
12058                 piece->u.cval = i;
12059                 LHS(def, i) = piece;
12060                 flatten(state, first, piece);
12061         }
12062         /* And write the helpers to their destinations */
12063         for(i = 0; i < out; i++) {
12064                 struct triple *piece;
12065                 piece = LHS(def, i);
12066                 flatten(state, first,
12067                         write_expr(state, out_param[i].expr, piece));
12068         }
12069 }
12070
12071
12072 static int isdecl(int tok)
12073 {
12074         switch(tok) {
12075         case TOK_AUTO:
12076         case TOK_REGISTER:
12077         case TOK_STATIC:
12078         case TOK_EXTERN:
12079         case TOK_TYPEDEF:
12080         case TOK_CONST:
12081         case TOK_RESTRICT:
12082         case TOK_VOLATILE:
12083         case TOK_VOID:
12084         case TOK_CHAR:
12085         case TOK_SHORT:
12086         case TOK_INT:
12087         case TOK_LONG:
12088         case TOK_FLOAT:
12089         case TOK_DOUBLE:
12090         case TOK_SIGNED:
12091         case TOK_UNSIGNED:
12092         case TOK_STRUCT:
12093         case TOK_UNION:
12094         case TOK_ENUM:
12095         case TOK_TYPE_NAME: /* typedef name */
12096                 return 1;
12097         default:
12098                 return 0;
12099         }
12100 }
12101
12102 static void compound_statement(struct compile_state *state, struct triple *first)
12103 {
12104         eat(state, TOK_LBRACE);
12105         start_scope(state);
12106
12107         /* statement-list opt */
12108         while (peek(state) != TOK_RBRACE) {
12109                 statement(state, first);
12110         }
12111         end_scope(state);
12112         eat(state, TOK_RBRACE);
12113 }
12114
12115 static void statement(struct compile_state *state, struct triple *first)
12116 {
12117         int tok;
12118         tok = peek(state);
12119         if (tok == TOK_LBRACE) {
12120                 compound_statement(state, first);
12121         }
12122         else if (tok == TOK_IF) {
12123                 if_statement(state, first); 
12124         }
12125         else if (tok == TOK_FOR) {
12126                 for_statement(state, first);
12127         }
12128         else if (tok == TOK_WHILE) {
12129                 while_statement(state, first);
12130         }
12131         else if (tok == TOK_DO) {
12132                 do_statement(state, first);
12133         }
12134         else if (tok == TOK_RETURN) {
12135                 return_statement(state, first);
12136         }
12137         else if (tok == TOK_BREAK) {
12138                 break_statement(state, first);
12139         }
12140         else if (tok == TOK_CONTINUE) {
12141                 continue_statement(state, first);
12142         }
12143         else if (tok == TOK_GOTO) {
12144                 goto_statement(state, first);
12145         }
12146         else if (tok == TOK_SWITCH) {
12147                 switch_statement(state, first);
12148         }
12149         else if (tok == TOK_ASM) {
12150                 asm_statement(state, first);
12151         }
12152         else if ((tok == TOK_IDENT) && (peek2(state) == TOK_COLON)) {
12153                 labeled_statement(state, first); 
12154         }
12155         else if (tok == TOK_CASE) {
12156                 case_statement(state, first);
12157         }
12158         else if (tok == TOK_DEFAULT) {
12159                 default_statement(state, first);
12160         }
12161         else if (isdecl(tok)) {
12162                 /* This handles C99 intermixing of statements and decls */
12163                 decl(state, first);
12164         }
12165         else {
12166                 expr_statement(state, first);
12167         }
12168 }
12169
12170 static struct type *param_decl(struct compile_state *state)
12171 {
12172         struct type *type;
12173         struct hash_entry *ident;
12174         /* Cheat so the declarator will know we are not global */
12175         start_scope(state); 
12176         ident = 0;
12177         type = decl_specifiers(state);
12178         type = declarator(state, type, &ident, 0);
12179         type->field_ident = ident;
12180         end_scope(state);
12181         return type;
12182 }
12183
12184 static struct type *param_type_list(struct compile_state *state, struct type *type)
12185 {
12186         struct type *ftype, **next;
12187         ftype = new_type(TYPE_FUNCTION | (type->type & STOR_MASK), type, param_decl(state));
12188         next = &ftype->right;
12189         ftype->elements = 1;
12190         while(peek(state) == TOK_COMMA) {
12191                 eat(state, TOK_COMMA);
12192                 if (peek(state) == TOK_DOTS) {
12193                         eat(state, TOK_DOTS);
12194                         error(state, 0, "variadic functions not supported");
12195                 }
12196                 else {
12197                         *next = new_type(TYPE_PRODUCT, *next, param_decl(state));
12198                         next = &((*next)->right);
12199                         ftype->elements++;
12200                 }
12201         }
12202         return ftype;
12203 }
12204
12205 static struct type *type_name(struct compile_state *state)
12206 {
12207         struct type *type;
12208         type = specifier_qualifier_list(state);
12209         /* abstract-declarator (may consume no tokens) */
12210         type = declarator(state, type, 0, 0);
12211         return type;
12212 }
12213
12214 static struct type *direct_declarator(
12215         struct compile_state *state, struct type *type, 
12216         struct hash_entry **pident, int need_ident)
12217 {
12218         struct hash_entry *ident;
12219         struct type *outer;
12220         int op;
12221         outer = 0;
12222         arrays_complete(state, type);
12223         switch(peek(state)) {
12224         case TOK_IDENT:
12225                 ident = eat(state, TOK_IDENT)->ident;
12226                 if (!ident) {
12227                         error(state, 0, "Unexpected identifier found");
12228                 }
12229                 /* The name of what we are declaring */
12230                 *pident = ident;
12231                 break;
12232         case TOK_LPAREN:
12233                 eat(state, TOK_LPAREN);
12234                 outer = declarator(state, type, pident, need_ident);
12235                 eat(state, TOK_RPAREN);
12236                 break;
12237         default:
12238                 if (need_ident) {
12239                         error(state, 0, "Identifier expected");
12240                 }
12241                 break;
12242         }
12243         do {
12244                 op = 1;
12245                 arrays_complete(state, type);
12246                 switch(peek(state)) {
12247                 case TOK_LPAREN:
12248                         eat(state, TOK_LPAREN);
12249                         type = param_type_list(state, type);
12250                         eat(state, TOK_RPAREN);
12251                         break;
12252                 case TOK_LBRACKET:
12253                 {
12254                         unsigned int qualifiers;
12255                         struct triple *value;
12256                         value = 0;
12257                         eat(state, TOK_LBRACKET);
12258                         if (peek(state) != TOK_RBRACKET) {
12259                                 value = constant_expr(state);
12260                                 integral(state, value);
12261                         }
12262                         eat(state, TOK_RBRACKET);
12263
12264                         qualifiers = type->type & (QUAL_MASK | STOR_MASK);
12265                         type = new_type(TYPE_ARRAY | qualifiers, type, 0);
12266                         if (value) {
12267                                 type->elements = value->u.cval;
12268                                 free_triple(state, value);
12269                         } else {
12270                                 type->elements = ELEMENT_COUNT_UNSPECIFIED;
12271                                 op = 0;
12272                         }
12273                 }
12274                         break;
12275                 default:
12276                         op = 0;
12277                         break;
12278                 }
12279         } while(op);
12280         if (outer) {
12281                 struct type *inner;
12282                 arrays_complete(state, type);
12283                 FINISHME();
12284                 for(inner = outer; inner->left; inner = inner->left)
12285                         ;
12286                 inner->left = type;
12287                 type = outer;
12288         }
12289         return type;
12290 }
12291
12292 static struct type *declarator(
12293         struct compile_state *state, struct type *type, 
12294         struct hash_entry **pident, int need_ident)
12295 {
12296         while(peek(state) == TOK_STAR) {
12297                 eat(state, TOK_STAR);
12298                 type = new_type(TYPE_POINTER | (type->type & STOR_MASK), type, 0);
12299         }
12300         type = direct_declarator(state, type, pident, need_ident);
12301         return type;
12302 }
12303
12304 static struct type *typedef_name(
12305         struct compile_state *state, unsigned int specifiers)
12306 {
12307         struct hash_entry *ident;
12308         struct type *type;
12309         ident = eat(state, TOK_TYPE_NAME)->ident;
12310         type = ident->sym_ident->type;
12311         specifiers |= type->type & QUAL_MASK;
12312         if ((specifiers & (STOR_MASK | QUAL_MASK)) != 
12313                 (type->type & (STOR_MASK | QUAL_MASK))) {
12314                 type = clone_type(specifiers, type);
12315         }
12316         return type;
12317 }
12318
12319 static struct type *enum_specifier(
12320         struct compile_state *state, unsigned int spec)
12321 {
12322         struct hash_entry *ident;
12323         ulong_t base;
12324         int tok;
12325         struct type *enum_type;
12326         enum_type = 0;
12327         ident = 0;
12328         eat(state, TOK_ENUM);
12329         tok = peek(state);
12330         if ((tok == TOK_IDENT) || (tok == TOK_ENUM_CONST) || (tok == TOK_TYPE_NAME)) {
12331                 ident = eat(state, tok)->ident;
12332         }
12333         base = 0;
12334         if (!ident || (peek(state) == TOK_LBRACE)) {
12335                 struct type **next;
12336                 eat(state, TOK_LBRACE);
12337                 enum_type = new_type(TYPE_ENUM | spec, 0, 0);
12338                 enum_type->type_ident = ident;
12339                 next = &enum_type->right;
12340                 do {
12341                         struct hash_entry *eident;
12342                         struct triple *value;
12343                         struct type *entry;
12344                         eident = eat(state, TOK_IDENT)->ident;
12345                         if (eident->sym_ident) {
12346                                 error(state, 0, "%s already declared", 
12347                                         eident->name);
12348                         }
12349                         eident->tok = TOK_ENUM_CONST;
12350                         if (peek(state) == TOK_EQ) {
12351                                 struct triple *val;
12352                                 eat(state, TOK_EQ);
12353                                 val = constant_expr(state);
12354                                 integral(state, val);
12355                                 base = val->u.cval;
12356                         }
12357                         value = int_const(state, &int_type, base);
12358                         symbol(state, eident, &eident->sym_ident, value, &int_type);
12359                         entry = new_type(TYPE_LIST, 0, 0);
12360                         entry->field_ident = eident;
12361                         *next = entry;
12362                         next = &entry->right;
12363                         base += 1;
12364                         if (peek(state) == TOK_COMMA) {
12365                                 eat(state, TOK_COMMA);
12366                         }
12367                 } while(peek(state) != TOK_RBRACE);
12368                 eat(state, TOK_RBRACE);
12369                 if (ident) {
12370                         symbol(state, ident, &ident->sym_tag, 0, enum_type);
12371                 }
12372         }
12373         if (ident && ident->sym_tag &&
12374                 ident->sym_tag->type &&
12375                 ((ident->sym_tag->type->type & TYPE_MASK) == TYPE_ENUM)) {
12376                 enum_type = clone_type(spec, ident->sym_tag->type);
12377         }
12378         else if (ident && !enum_type) {
12379                 error(state, 0, "enum %s undeclared", ident->name);
12380         }
12381         return enum_type;
12382 }
12383
12384 static struct type *struct_declarator(
12385         struct compile_state *state, struct type *type, struct hash_entry **ident)
12386 {
12387         if (peek(state) != TOK_COLON) {
12388                 type = declarator(state, type, ident, 1);
12389         }
12390         if (peek(state) == TOK_COLON) {
12391                 struct triple *value;
12392                 eat(state, TOK_COLON);
12393                 value = constant_expr(state);
12394                 if (value->op != OP_INTCONST) {
12395                         error(state, 0, "Invalid constant expression");
12396                 }
12397                 if (value->u.cval > size_of(state, type)) {
12398                         error(state, 0, "bitfield larger than base type");
12399                 }
12400                 if (!TYPE_INTEGER(type->type) || ((type->type & TYPE_MASK) == TYPE_BITFIELD)) {
12401                         error(state, 0, "bitfield base not an integer type");
12402                 }
12403                 type = new_type(TYPE_BITFIELD, type, 0);
12404                 type->elements = value->u.cval;
12405         }
12406         return type;
12407 }
12408
12409 static struct type *struct_or_union_specifier(
12410         struct compile_state *state, unsigned int spec)
12411 {
12412         struct type *struct_type;
12413         struct hash_entry *ident;
12414         unsigned int type_main;
12415         unsigned int type_join;
12416         int tok;
12417         struct_type = 0;
12418         ident = 0;
12419         switch(peek(state)) {
12420         case TOK_STRUCT:
12421                 eat(state, TOK_STRUCT);
12422                 type_main = TYPE_STRUCT;
12423                 type_join = TYPE_PRODUCT;
12424                 break;
12425         case TOK_UNION:
12426                 eat(state, TOK_UNION);
12427                 type_main = TYPE_UNION;
12428                 type_join = TYPE_OVERLAP;
12429                 break;
12430         default:
12431                 eat(state, TOK_STRUCT);
12432                 type_main = TYPE_STRUCT;
12433                 type_join = TYPE_PRODUCT;
12434                 break;
12435         }
12436         tok = peek(state);
12437         if ((tok == TOK_IDENT) || (tok == TOK_ENUM_CONST) || (tok == TOK_TYPE_NAME)) {
12438                 ident = eat(state, tok)->ident;
12439         }
12440         if (!ident || (peek(state) == TOK_LBRACE)) {
12441                 ulong_t elements;
12442                 struct type **next;
12443                 elements = 0;
12444                 eat(state, TOK_LBRACE);
12445                 next = &struct_type;
12446                 do {
12447                         struct type *base_type;
12448                         int done;
12449                         base_type = specifier_qualifier_list(state);
12450                         do {
12451                                 struct type *type;
12452                                 struct hash_entry *fident;
12453                                 done = 1;
12454                                 type = struct_declarator(state, base_type, &fident);
12455                                 elements++;
12456                                 if (peek(state) == TOK_COMMA) {
12457                                         done = 0;
12458                                         eat(state, TOK_COMMA);
12459                                 }
12460                                 type = clone_type(0, type);
12461                                 type->field_ident = fident;
12462                                 if (*next) {
12463                                         *next = new_type(type_join, *next, type);
12464                                         next = &((*next)->right);
12465                                 } else {
12466                                         *next = type;
12467                                 }
12468                         } while(!done);
12469                         eat(state, TOK_SEMI);
12470                 } while(peek(state) != TOK_RBRACE);
12471                 eat(state, TOK_RBRACE);
12472                 struct_type = new_type(type_main | spec, struct_type, 0);
12473                 struct_type->type_ident = ident;
12474                 struct_type->elements = elements;
12475                 if (ident) {
12476                         symbol(state, ident, &ident->sym_tag, 0, struct_type);
12477                 }
12478         }
12479         if (ident && ident->sym_tag && 
12480                 ident->sym_tag->type && 
12481                 ((ident->sym_tag->type->type & TYPE_MASK) == type_main)) {
12482                 struct_type = clone_type(spec, ident->sym_tag->type);
12483         }
12484         else if (ident && !struct_type) {
12485                 error(state, 0, "%s %s undeclared", 
12486                         (type_main == TYPE_STRUCT)?"struct" : "union",
12487                         ident->name);
12488         }
12489         return struct_type;
12490 }
12491
12492 static unsigned int storage_class_specifier_opt(struct compile_state *state)
12493 {
12494         unsigned int specifiers;
12495         switch(peek(state)) {
12496         case TOK_AUTO:
12497                 eat(state, TOK_AUTO);
12498                 specifiers = STOR_AUTO;
12499                 break;
12500         case TOK_REGISTER:
12501                 eat(state, TOK_REGISTER);
12502                 specifiers = STOR_REGISTER;
12503                 break;
12504         case TOK_STATIC:
12505                 eat(state, TOK_STATIC);
12506                 specifiers = STOR_STATIC;
12507                 break;
12508         case TOK_EXTERN:
12509                 eat(state, TOK_EXTERN);
12510                 specifiers = STOR_EXTERN;
12511                 break;
12512         case TOK_TYPEDEF:
12513                 eat(state, TOK_TYPEDEF);
12514                 specifiers = STOR_TYPEDEF;
12515                 break;
12516         default:
12517                 if (state->scope_depth <= GLOBAL_SCOPE_DEPTH) {
12518                         specifiers = STOR_LOCAL;
12519                 }
12520                 else {
12521                         specifiers = STOR_AUTO;
12522                 }
12523         }
12524         return specifiers;
12525 }
12526
12527 static unsigned int function_specifier_opt(struct compile_state *state)
12528 {
12529         /* Ignore the inline keyword */
12530         unsigned int specifiers;
12531         specifiers = 0;
12532         switch(peek(state)) {
12533         case TOK_INLINE:
12534                 eat(state, TOK_INLINE);
12535                 specifiers = STOR_INLINE;
12536         }
12537         return specifiers;
12538 }
12539
12540 static unsigned int attrib(struct compile_state *state, unsigned int attributes)
12541 {
12542         int tok = peek(state);
12543         switch(tok) {
12544         case TOK_COMMA:
12545         case TOK_LPAREN:
12546                 /* The empty attribute ignore it */
12547                 break;
12548         case TOK_IDENT:
12549         case TOK_ENUM_CONST:
12550         case TOK_TYPE_NAME:
12551         {
12552                 struct hash_entry *ident;
12553                 ident = eat(state, TOK_IDENT)->ident;
12554
12555                 if (ident == state->i_noinline) {
12556                         if (attributes & ATTRIB_ALWAYS_INLINE) {
12557                                 error(state, 0, "both always_inline and noinline attribtes");
12558                         }
12559                         attributes |= ATTRIB_NOINLINE;
12560                 }
12561                 else if (ident == state->i_always_inline) {
12562                         if (attributes & ATTRIB_NOINLINE) {
12563                                 error(state, 0, "both noinline and always_inline attribtes");
12564                         }
12565                         attributes |= ATTRIB_ALWAYS_INLINE;
12566                 }
12567                 else {
12568                         error(state, 0, "Unknown attribute:%s", ident->name);
12569                 }
12570                 break;
12571         }
12572         default:
12573                 error(state, 0, "Unexpected token: %s\n", tokens[tok]);
12574                 break;
12575         }
12576         return attributes;
12577 }
12578
12579 static unsigned int attribute_list(struct compile_state *state, unsigned type)
12580 {
12581         type = attrib(state, type);
12582         while(peek(state) == TOK_COMMA) {
12583                 eat(state, TOK_COMMA);
12584                 type = attrib(state, type);
12585         }
12586         return type;
12587 }
12588
12589 static unsigned int attributes_opt(struct compile_state *state, unsigned type)
12590 {
12591         if (peek(state) == TOK_ATTRIBUTE) {
12592                 eat(state, TOK_ATTRIBUTE);
12593                 eat(state, TOK_LPAREN);
12594                 eat(state, TOK_LPAREN);
12595                 type = attribute_list(state, type);
12596                 eat(state, TOK_RPAREN);
12597                 eat(state, TOK_RPAREN);
12598         }
12599         return type;
12600 }
12601
12602 static unsigned int type_qualifiers(struct compile_state *state)
12603 {
12604         unsigned int specifiers;
12605         int done;
12606         done = 0;
12607         specifiers = QUAL_NONE;
12608         do {
12609                 switch(peek(state)) {
12610                 case TOK_CONST:
12611                         eat(state, TOK_CONST);
12612                         specifiers |= QUAL_CONST;
12613                         break;
12614                 case TOK_VOLATILE:
12615                         eat(state, TOK_VOLATILE);
12616                         specifiers |= QUAL_VOLATILE;
12617                         break;
12618                 case TOK_RESTRICT:
12619                         eat(state, TOK_RESTRICT);
12620                         specifiers |= QUAL_RESTRICT;
12621                         break;
12622                 default:
12623                         done = 1;
12624                         break;
12625                 }
12626         } while(!done);
12627         return specifiers;
12628 }
12629
12630 static struct type *type_specifier(
12631         struct compile_state *state, unsigned int spec)
12632 {
12633         struct type *type;
12634         int tok;
12635         type = 0;
12636         switch((tok = peek(state))) {
12637         case TOK_VOID:
12638                 eat(state, TOK_VOID);
12639                 type = new_type(TYPE_VOID | spec, 0, 0);
12640                 break;
12641         case TOK_CHAR:
12642                 eat(state, TOK_CHAR);
12643                 type = new_type(TYPE_CHAR | spec, 0, 0);
12644                 break;
12645         case TOK_SHORT:
12646                 eat(state, TOK_SHORT);
12647                 if (peek(state) == TOK_INT) {
12648                         eat(state, TOK_INT);
12649                 }
12650                 type = new_type(TYPE_SHORT | spec, 0, 0);
12651                 break;
12652         case TOK_INT:
12653                 eat(state, TOK_INT);
12654                 type = new_type(TYPE_INT | spec, 0, 0);
12655                 break;
12656         case TOK_LONG:
12657                 eat(state, TOK_LONG);
12658                 switch(peek(state)) {
12659                 case TOK_LONG:
12660                         eat(state, TOK_LONG);
12661                         error(state, 0, "long long not supported");
12662                         break;
12663                 case TOK_DOUBLE:
12664                         eat(state, TOK_DOUBLE);
12665                         error(state, 0, "long double not supported");
12666                         break;
12667                 case TOK_INT:
12668                         eat(state, TOK_INT);
12669                         type = new_type(TYPE_LONG | spec, 0, 0);
12670                         break;
12671                 default:
12672                         type = new_type(TYPE_LONG | spec, 0, 0);
12673                         break;
12674                 }
12675                 break;
12676         case TOK_FLOAT:
12677                 eat(state, TOK_FLOAT);
12678                 error(state, 0, "type float not supported");
12679                 break;
12680         case TOK_DOUBLE:
12681                 eat(state, TOK_DOUBLE);
12682                 error(state, 0, "type double not supported");
12683                 break;
12684         case TOK_SIGNED:
12685                 eat(state, TOK_SIGNED);
12686                 switch(peek(state)) {
12687                 case TOK_LONG:
12688                         eat(state, TOK_LONG);
12689                         switch(peek(state)) {
12690                         case TOK_LONG:
12691                                 eat(state, TOK_LONG);
12692                                 error(state, 0, "type long long not supported");
12693                                 break;
12694                         case TOK_INT:
12695                                 eat(state, TOK_INT);
12696                                 type = new_type(TYPE_LONG | spec, 0, 0);
12697                                 break;
12698                         default:
12699                                 type = new_type(TYPE_LONG | spec, 0, 0);
12700                                 break;
12701                         }
12702                         break;
12703                 case TOK_INT:
12704                         eat(state, TOK_INT);
12705                         type = new_type(TYPE_INT | spec, 0, 0);
12706                         break;
12707                 case TOK_SHORT:
12708                         eat(state, TOK_SHORT);
12709                         type = new_type(TYPE_SHORT | spec, 0, 0);
12710                         break;
12711                 case TOK_CHAR:
12712                         eat(state, TOK_CHAR);
12713                         type = new_type(TYPE_CHAR | spec, 0, 0);
12714                         break;
12715                 default:
12716                         type = new_type(TYPE_INT | spec, 0, 0);
12717                         break;
12718                 }
12719                 break;
12720         case TOK_UNSIGNED:
12721                 eat(state, TOK_UNSIGNED);
12722                 switch(peek(state)) {
12723                 case TOK_LONG:
12724                         eat(state, TOK_LONG);
12725                         switch(peek(state)) {
12726                         case TOK_LONG:
12727                                 eat(state, TOK_LONG);
12728                                 error(state, 0, "unsigned long long not supported");
12729                                 break;
12730                         case TOK_INT:
12731                                 eat(state, TOK_INT);
12732                                 type = new_type(TYPE_ULONG | spec, 0, 0);
12733                                 break;
12734                         default:
12735                                 type = new_type(TYPE_ULONG | spec, 0, 0);
12736                                 break;
12737                         }
12738                         break;
12739                 case TOK_INT:
12740                         eat(state, TOK_INT);
12741                         type = new_type(TYPE_UINT | spec, 0, 0);
12742                         break;
12743                 case TOK_SHORT:
12744                         eat(state, TOK_SHORT);
12745                         type = new_type(TYPE_USHORT | spec, 0, 0);
12746                         break;
12747                 case TOK_CHAR:
12748                         eat(state, TOK_CHAR);
12749                         type = new_type(TYPE_UCHAR | spec, 0, 0);
12750                         break;
12751                 default:
12752                         type = new_type(TYPE_UINT | spec, 0, 0);
12753                         break;
12754                 }
12755                 break;
12756                 /* struct or union specifier */
12757         case TOK_STRUCT:
12758         case TOK_UNION:
12759                 type = struct_or_union_specifier(state, spec);
12760                 break;
12761                 /* enum-spefifier */
12762         case TOK_ENUM:
12763                 type = enum_specifier(state, spec);
12764                 break;
12765                 /* typedef name */
12766         case TOK_TYPE_NAME:
12767                 type = typedef_name(state, spec);
12768                 break;
12769         default:
12770                 error(state, 0, "bad type specifier %s", 
12771                         tokens[tok]);
12772                 break;
12773         }
12774         return type;
12775 }
12776
12777 static int istype(int tok)
12778 {
12779         switch(tok) {
12780         case TOK_CONST:
12781         case TOK_RESTRICT:
12782         case TOK_VOLATILE:
12783         case TOK_VOID:
12784         case TOK_CHAR:
12785         case TOK_SHORT:
12786         case TOK_INT:
12787         case TOK_LONG:
12788         case TOK_FLOAT:
12789         case TOK_DOUBLE:
12790         case TOK_SIGNED:
12791         case TOK_UNSIGNED:
12792         case TOK_STRUCT:
12793         case TOK_UNION:
12794         case TOK_ENUM:
12795         case TOK_TYPE_NAME:
12796                 return 1;
12797         default:
12798                 return 0;
12799         }
12800 }
12801
12802
12803 static struct type *specifier_qualifier_list(struct compile_state *state)
12804 {
12805         struct type *type;
12806         unsigned int specifiers = 0;
12807
12808         /* type qualifiers */
12809         specifiers |= type_qualifiers(state);
12810
12811         /* type specifier */
12812         type = type_specifier(state, specifiers);
12813
12814         return type;
12815 }
12816
12817 static int isdecl_specifier(int tok)
12818 {
12819         switch(tok) {
12820                 /* storage class specifier */
12821         case TOK_AUTO:
12822         case TOK_REGISTER:
12823         case TOK_STATIC:
12824         case TOK_EXTERN:
12825         case TOK_TYPEDEF:
12826                 /* type qualifier */
12827         case TOK_CONST:
12828         case TOK_RESTRICT:
12829         case TOK_VOLATILE:
12830                 /* type specifiers */
12831         case TOK_VOID:
12832         case TOK_CHAR:
12833         case TOK_SHORT:
12834         case TOK_INT:
12835         case TOK_LONG:
12836         case TOK_FLOAT:
12837         case TOK_DOUBLE:
12838         case TOK_SIGNED:
12839         case TOK_UNSIGNED:
12840                 /* struct or union specifier */
12841         case TOK_STRUCT:
12842         case TOK_UNION:
12843                 /* enum-spefifier */
12844         case TOK_ENUM:
12845                 /* typedef name */
12846         case TOK_TYPE_NAME:
12847                 /* function specifiers */
12848         case TOK_INLINE:
12849                 return 1;
12850         default:
12851                 return 0;
12852         }
12853 }
12854
12855 static struct type *decl_specifiers(struct compile_state *state)
12856 {
12857         struct type *type;
12858         unsigned int specifiers;
12859         /* I am overly restrictive in the arragement of specifiers supported.
12860          * C is overly flexible in this department it makes interpreting
12861          * the parse tree difficult.
12862          */
12863         specifiers = 0;
12864
12865         /* storage class specifier */
12866         specifiers |= storage_class_specifier_opt(state);
12867
12868         /* function-specifier */
12869         specifiers |= function_specifier_opt(state);
12870
12871         /* attributes */
12872         specifiers |= attributes_opt(state, 0);
12873
12874         /* type qualifier */
12875         specifiers |= type_qualifiers(state);
12876
12877         /* type specifier */
12878         type = type_specifier(state, specifiers);
12879         return type;
12880 }
12881
12882 struct field_info {
12883         struct type *type;
12884         size_t offset;
12885 };
12886
12887 static struct field_info designator(struct compile_state *state, struct type *type)
12888 {
12889         int tok;
12890         struct field_info info;
12891         info.offset = ~0U;
12892         info.type = 0;
12893         do {
12894                 switch(peek(state)) {
12895                 case TOK_LBRACKET:
12896                 {
12897                         struct triple *value;
12898                         if ((type->type & TYPE_MASK) != TYPE_ARRAY) {
12899                                 error(state, 0, "Array designator not in array initializer");
12900                         }
12901                         eat(state, TOK_LBRACKET);
12902                         value = constant_expr(state);
12903                         eat(state, TOK_RBRACKET);
12904
12905                         info.type = type->left;
12906                         info.offset = value->u.cval * size_of(state, info.type);
12907                         break;
12908                 }
12909                 case TOK_DOT:
12910                 {
12911                         struct hash_entry *field;
12912                         if (((type->type & TYPE_MASK) != TYPE_STRUCT) &&
12913                                 ((type->type & TYPE_MASK) != TYPE_UNION))
12914                         {
12915                                 error(state, 0, "Struct designator not in struct initializer");
12916                         }
12917                         eat(state, TOK_DOT);
12918                         field = eat(state, TOK_IDENT)->ident;
12919                         info.offset = field_offset(state, type, field);
12920                         info.type   = field_type(state, type, field);
12921                         break;
12922                 }
12923                 default:
12924                         error(state, 0, "Invalid designator");
12925                 }
12926                 tok = peek(state);
12927         } while((tok == TOK_LBRACKET) || (tok == TOK_DOT));
12928         eat(state, TOK_EQ);
12929         return info;
12930 }
12931
12932 static struct triple *initializer(
12933         struct compile_state *state, struct type *type)
12934 {
12935         struct triple *result;
12936 #warning "FIXME more consistent initializer handling (where should eval_const_expr go?"
12937         if (peek(state) != TOK_LBRACE) {
12938                 result = assignment_expr(state);
12939                 if (((type->type & TYPE_MASK) == TYPE_ARRAY) &&
12940                         (type->elements == ELEMENT_COUNT_UNSPECIFIED) &&
12941                         ((result->type->type & TYPE_MASK) == TYPE_ARRAY) &&
12942                         (result->type->elements != ELEMENT_COUNT_UNSPECIFIED) &&
12943                         (equiv_types(type->left, result->type->left))) {
12944                         type->elements = result->type->elements;
12945                 }
12946                 if (is_lvalue(state, result) && 
12947                         ((result->type->type & TYPE_MASK) == TYPE_ARRAY) &&
12948                         (type->type & TYPE_MASK) != TYPE_ARRAY)
12949                 {
12950                         result = lvalue_conversion(state, result);
12951                 }
12952                 if (!is_init_compatible(state, type, result->type)) {
12953                         error(state, 0, "Incompatible types in initializer");
12954                 }
12955                 if (!equiv_types(type, result->type)) {
12956                         result = mk_cast_expr(state, type, result);
12957                 }
12958         }
12959         else {
12960                 int comma;
12961                 size_t max_offset;
12962                 struct field_info info;
12963                 void *buf;
12964                 if (((type->type & TYPE_MASK) != TYPE_ARRAY) &&
12965                         ((type->type & TYPE_MASK) != TYPE_STRUCT)) {
12966                         internal_error(state, 0, "unknown initializer type");
12967                 }
12968                 info.offset = 0;
12969                 info.type = type->left;
12970                 if ((type->type & TYPE_MASK) == TYPE_STRUCT) {
12971                         info.type = next_field(state, type, 0);
12972                 }
12973                 if (type->elements == ELEMENT_COUNT_UNSPECIFIED) {
12974                         max_offset = 0;
12975                 } else {
12976                         max_offset = size_of(state, type);
12977                 }
12978                 buf = xcmalloc(bits_to_bytes(max_offset), "initializer");
12979                 eat(state, TOK_LBRACE);
12980                 do {
12981                         struct triple *value;
12982                         struct type *value_type;
12983                         size_t value_size;
12984                         void *dest;
12985                         int tok;
12986                         comma = 0;
12987                         tok = peek(state);
12988                         if ((tok == TOK_LBRACKET) || (tok == TOK_DOT)) {
12989                                 info = designator(state, type);
12990                         }
12991                         if ((type->elements != ELEMENT_COUNT_UNSPECIFIED) &&
12992                                 (info.offset >= max_offset)) {
12993                                 error(state, 0, "element beyond bounds");
12994                         }
12995                         value_type = info.type;
12996                         value = eval_const_expr(state, initializer(state, value_type));
12997                         value_size = size_of(state, value_type);
12998                         if (((type->type & TYPE_MASK) == TYPE_ARRAY) &&
12999                                 (type->elements == ELEMENT_COUNT_UNSPECIFIED) &&
13000                                 (max_offset <= info.offset)) {
13001                                 void *old_buf;
13002                                 size_t old_size;
13003                                 old_buf = buf;
13004                                 old_size = max_offset;
13005                                 max_offset = info.offset + value_size;
13006                                 buf = xmalloc(bits_to_bytes(max_offset), "initializer");
13007                                 memcpy(buf, old_buf, bits_to_bytes(old_size));
13008                                 xfree(old_buf);
13009                         }
13010                         dest = ((char *)buf) + bits_to_bytes(info.offset);
13011 #if DEBUG_INITIALIZER
13012                         fprintf(state->errout, "dest = buf + %d max_offset: %d value_size: %d op: %d\n", 
13013                                 dest - buf,
13014                                 bits_to_bytes(max_offset),
13015                                 bits_to_bytes(value_size),
13016                                 value->op);
13017 #endif
13018                         if (value->op == OP_BLOBCONST) {
13019                                 memcpy(dest, value->u.blob, bits_to_bytes(value_size));
13020                         }
13021                         else if ((value->op == OP_INTCONST) && (value_size == SIZEOF_I8)) {
13022 #if DEBUG_INITIALIZER
13023                                 fprintf(state->errout, "byte: %02x\n", value->u.cval & 0xff);
13024 #endif
13025                                 *((uint8_t *)dest) = value->u.cval & 0xff;
13026                         }
13027                         else if ((value->op == OP_INTCONST) && (value_size == SIZEOF_I16)) {
13028                                 *((uint16_t *)dest) = value->u.cval & 0xffff;
13029                         }
13030                         else if ((value->op == OP_INTCONST) && (value_size == SIZEOF_I32)) {
13031                                 *((uint32_t *)dest) = value->u.cval & 0xffffffff;
13032                         }
13033                         else {
13034                                 internal_error(state, 0, "unhandled constant initializer");
13035                         }
13036                         free_triple(state, value);
13037                         if (peek(state) == TOK_COMMA) {
13038                                 eat(state, TOK_COMMA);
13039                                 comma = 1;
13040                         }
13041                         info.offset += value_size;
13042                         if ((type->type & TYPE_MASK) == TYPE_STRUCT) {
13043                                 info.type = next_field(state, type, info.type);
13044                                 info.offset = field_offset(state, type, 
13045                                         info.type->field_ident);
13046                         }
13047                 } while(comma && (peek(state) != TOK_RBRACE));
13048                 if ((type->elements == ELEMENT_COUNT_UNSPECIFIED) &&
13049                         ((type->type & TYPE_MASK) == TYPE_ARRAY)) {
13050                         type->elements = max_offset / size_of(state, type->left);
13051                 }
13052                 eat(state, TOK_RBRACE);
13053                 result = triple(state, OP_BLOBCONST, type, 0, 0);
13054                 result->u.blob = buf;
13055         }
13056         return result;
13057 }
13058
13059 static void resolve_branches(struct compile_state *state, struct triple *first)
13060 {
13061         /* Make a second pass and finish anything outstanding
13062          * with respect to branches.  The only outstanding item
13063          * is to see if there are goto to labels that have not
13064          * been defined and to error about them.
13065          */
13066         int i;
13067         struct triple *ins;
13068         /* Also error on branches that do not use their targets */
13069         ins = first;
13070         do {
13071                 if (!triple_is_ret(state, ins)) {
13072                         struct triple **expr ;
13073                         struct triple_set *set;
13074                         expr = triple_targ(state, ins, 0);
13075                         for(; expr; expr = triple_targ(state, ins, expr)) {
13076                                 struct triple *targ;
13077                                 targ = *expr;
13078                                 for(set = targ?targ->use:0; set; set = set->next) {
13079                                         if (set->member == ins) {
13080                                                 break;
13081                                         }
13082                                 }
13083                                 if (!set) {
13084                                         internal_error(state, ins, "targ not used");
13085                                 }
13086                         }
13087                 }
13088                 ins = ins->next;
13089         } while(ins != first);
13090         /* See if there are goto to labels that have not been defined */
13091         for(i = 0; i < HASH_TABLE_SIZE; i++) {
13092                 struct hash_entry *entry;
13093                 for(entry = state->hash_table[i]; entry; entry = entry->next) {
13094                         struct triple *ins;
13095                         if (!entry->sym_label) {
13096                                 continue;
13097                         }
13098                         ins = entry->sym_label->def;
13099                         if (!(ins->id & TRIPLE_FLAG_FLATTENED)) {
13100                                 error(state, ins, "label `%s' used but not defined",
13101                                         entry->name);
13102                         }
13103                 }
13104         }
13105 }
13106
13107 static struct triple *function_definition(
13108         struct compile_state *state, struct type *type)
13109 {
13110         struct triple *def, *tmp, *first, *end, *retvar, *result, *ret;
13111         struct triple *fname;
13112         struct type *fname_type;
13113         struct hash_entry *ident;
13114         struct type *param, *crtype, *ctype;
13115         int i;
13116         if ((type->type &TYPE_MASK) != TYPE_FUNCTION) {
13117                 error(state, 0, "Invalid function header");
13118         }
13119
13120         /* Verify the function type */
13121         if (((type->right->type & TYPE_MASK) != TYPE_VOID)  &&
13122                 ((type->right->type & TYPE_MASK) != TYPE_PRODUCT) &&
13123                 (type->right->field_ident == 0)) {
13124                 error(state, 0, "Invalid function parameters");
13125         }
13126         param = type->right;
13127         i = 0;
13128         while((param->type & TYPE_MASK) == TYPE_PRODUCT) {
13129                 i++;
13130                 if (!param->left->field_ident) {
13131                         error(state, 0, "No identifier for parameter %d\n", i);
13132                 }
13133                 param = param->right;
13134         }
13135         i++;
13136         if (((param->type & TYPE_MASK) != TYPE_VOID) && !param->field_ident) {
13137                 error(state, 0, "No identifier for paramter %d\n", i);
13138         }
13139         
13140         /* Get a list of statements for this function. */
13141         def = triple(state, OP_LIST, type, 0, 0);
13142
13143         /* Start a new scope for the passed parameters */
13144         start_scope(state);
13145
13146         /* Put a label at the very start of a function */
13147         first = label(state);
13148         RHS(def, 0) = first;
13149
13150         /* Put a label at the very end of a function */
13151         end = label(state);
13152         flatten(state, first, end);
13153         /* Remember where return goes */
13154         ident = state->i_return;
13155         symbol(state, ident, &ident->sym_ident, end, end->type);
13156
13157         /* Get the initial closure type */
13158         ctype = new_type(TYPE_JOIN, &void_type, 0);
13159         ctype->elements = 1;
13160
13161         /* Add a variable for the return value */
13162         crtype = new_type(TYPE_TUPLE, 
13163                 /* Remove all type qualifiers from the return type */
13164                 new_type(TYPE_PRODUCT, ctype, clone_type(0, type->left)), 0);
13165         crtype->elements = 2;
13166         result = flatten(state, end, variable(state, crtype));
13167
13168         /* Allocate a variable for the return address */
13169         retvar = flatten(state, end, variable(state, &void_ptr_type));
13170
13171         /* Add in the return instruction */
13172         ret = triple(state, OP_RET, &void_type, read_expr(state, retvar), 0);
13173         ret = flatten(state, first, ret);
13174
13175         /* Walk through the parameters and create symbol table entries
13176          * for them.
13177          */
13178         param = type->right;
13179         while((param->type & TYPE_MASK) == TYPE_PRODUCT) {
13180                 ident = param->left->field_ident;
13181                 tmp = variable(state, param->left);
13182                 var_symbol(state, ident, tmp);
13183                 flatten(state, end, tmp);
13184                 param = param->right;
13185         }
13186         if ((param->type & TYPE_MASK) != TYPE_VOID) {
13187                 /* And don't forget the last parameter */
13188                 ident = param->field_ident;
13189                 tmp = variable(state, param);
13190                 symbol(state, ident, &ident->sym_ident, tmp, tmp->type);
13191                 flatten(state, end, tmp);
13192         }
13193
13194         /* Add the declaration static const char __func__ [] = "func-name"  */
13195         fname_type = new_type(TYPE_ARRAY, 
13196                 clone_type(QUAL_CONST | STOR_STATIC, &char_type), 0);
13197         fname_type->type |= QUAL_CONST | STOR_STATIC;
13198         fname_type->elements = strlen(state->function) + 1;
13199
13200         fname = triple(state, OP_BLOBCONST, fname_type, 0, 0);
13201         fname->u.blob = (void *)state->function;
13202         fname = flatten(state, end, fname);
13203
13204         ident = state->i___func__;
13205         symbol(state, ident, &ident->sym_ident, fname, fname_type);
13206
13207         /* Remember which function I am compiling.
13208          * Also assume the last defined function is the main function.
13209          */
13210         state->main_function = def;
13211
13212         /* Now get the actual function definition */
13213         compound_statement(state, end);
13214
13215         /* Finish anything unfinished with branches */
13216         resolve_branches(state, first);
13217
13218         /* Remove the parameter scope */
13219         end_scope(state);
13220
13221
13222         /* Remember I have defined a function */
13223         if (!state->functions) {
13224                 state->functions = def;
13225         } else {
13226                 insert_triple(state, state->functions, def);
13227         }
13228         if (state->compiler->debug & DEBUG_INLINE) {
13229                 FILE *fp = state->dbgout;
13230                 fprintf(fp, "\n");
13231                 loc(fp, state, 0);
13232                 fprintf(fp, "\n__________ %s _________\n", __FUNCTION__);
13233                 display_func(state, fp, def);
13234                 fprintf(fp, "__________ %s _________ done\n\n", __FUNCTION__);
13235         }
13236
13237         return def;
13238 }
13239
13240 static struct triple *do_decl(struct compile_state *state, 
13241         struct type *type, struct hash_entry *ident)
13242 {
13243         struct triple *def;
13244         def = 0;
13245         /* Clean up the storage types used */
13246         switch (type->type & STOR_MASK) {
13247         case STOR_AUTO:
13248         case STOR_STATIC:
13249                 /* These are the good types I am aiming for */
13250                 break;
13251         case STOR_REGISTER:
13252                 type->type &= ~STOR_MASK;
13253                 type->type |= STOR_AUTO;
13254                 break;
13255         case STOR_LOCAL:
13256         case STOR_EXTERN:
13257                 type->type &= ~STOR_MASK;
13258                 type->type |= STOR_STATIC;
13259                 break;
13260         case STOR_TYPEDEF:
13261                 if (!ident) {
13262                         error(state, 0, "typedef without name");
13263                 }
13264                 symbol(state, ident, &ident->sym_ident, 0, type);
13265                 ident->tok = TOK_TYPE_NAME;
13266                 return 0;
13267                 break;
13268         default:
13269                 internal_error(state, 0, "Undefined storage class");
13270         }
13271         if ((type->type & TYPE_MASK) == TYPE_FUNCTION) {
13272                 error(state, 0, "Function prototypes not supported");
13273         }
13274         if (ident && 
13275                 ((type->type & STOR_MASK) == STOR_STATIC) &&
13276                 ((type->type & QUAL_CONST) == 0)) {
13277                 error(state, 0, "non const static variables not supported");
13278         }
13279         if (ident) {
13280                 def = variable(state, type);
13281                 var_symbol(state, ident, def);
13282         }
13283         return def;
13284 }
13285
13286 static void decl(struct compile_state *state, struct triple *first)
13287 {
13288         struct type *base_type, *type;
13289         struct hash_entry *ident;
13290         struct triple *def;
13291         int global;
13292         global = (state->scope_depth <= GLOBAL_SCOPE_DEPTH);
13293         base_type = decl_specifiers(state);
13294         ident = 0;
13295         type = declarator(state, base_type, &ident, 0);
13296         type->type = attributes_opt(state, type->type);
13297         if (global && ident && (peek(state) == TOK_LBRACE)) {
13298                 /* function */
13299                 type->type_ident = ident;
13300                 state->function = ident->name;
13301                 def = function_definition(state, type);
13302                 symbol(state, ident, &ident->sym_ident, def, type);
13303                 state->function = 0;
13304         }
13305         else {
13306                 int done;
13307                 flatten(state, first, do_decl(state, type, ident));
13308                 /* type or variable definition */
13309                 do {
13310                         done = 1;
13311                         if (peek(state) == TOK_EQ) {
13312                                 if (!ident) {
13313                                         error(state, 0, "cannot assign to a type");
13314                                 }
13315                                 eat(state, TOK_EQ);
13316                                 flatten(state, first,
13317                                         init_expr(state, 
13318                                                 ident->sym_ident->def, 
13319                                                 initializer(state, type)));
13320                         }
13321                         arrays_complete(state, type);
13322                         if (peek(state) == TOK_COMMA) {
13323                                 eat(state, TOK_COMMA);
13324                                 ident = 0;
13325                                 type = declarator(state, base_type, &ident, 0);
13326                                 flatten(state, first, do_decl(state, type, ident));
13327                                 done = 0;
13328                         }
13329                 } while(!done);
13330                 eat(state, TOK_SEMI);
13331         }
13332 }
13333
13334 static void decls(struct compile_state *state)
13335 {
13336         struct triple *list;
13337         int tok;
13338         list = label(state);
13339         while(1) {
13340                 tok = peek(state);
13341                 if (tok == TOK_EOF) {
13342                         return;
13343                 }
13344                 if (tok == TOK_SPACE) {
13345                         eat(state, TOK_SPACE);
13346                 }
13347                 decl(state, list);
13348                 if (list->next != list) {
13349                         error(state, 0, "global variables not supported");
13350                 }
13351         }
13352 }
13353
13354 /* 
13355  * Function inlining
13356  */
13357 struct triple_reg_set {
13358         struct triple_reg_set *next;
13359         struct triple *member;
13360         struct triple *new;
13361 };
13362 struct reg_block {
13363         struct block *block;
13364         struct triple_reg_set *in;
13365         struct triple_reg_set *out;
13366         int vertex;
13367 };
13368 static void setup_basic_blocks(struct compile_state *, struct basic_blocks *bb);
13369 static void analyze_basic_blocks(struct compile_state *state, struct basic_blocks *bb);
13370 static void free_basic_blocks(struct compile_state *, struct basic_blocks *bb);
13371 static int tdominates(struct compile_state *state, struct triple *dom, struct triple *sub);
13372 static void walk_blocks(struct compile_state *state, struct basic_blocks *bb,
13373         void (*cb)(struct compile_state *state, struct block *block, void *arg),
13374         void *arg);
13375 static void print_block(
13376         struct compile_state *state, struct block *block, void *arg);
13377 static int do_triple_set(struct triple_reg_set **head, 
13378         struct triple *member, struct triple *new_member);
13379 static void do_triple_unset(struct triple_reg_set **head, struct triple *member);
13380 static struct reg_block *compute_variable_lifetimes(
13381         struct compile_state *state, struct basic_blocks *bb);
13382 static void free_variable_lifetimes(struct compile_state *state, 
13383         struct basic_blocks *bb, struct reg_block *blocks);
13384 static void print_live_variables(struct compile_state *state, 
13385         struct basic_blocks *bb, struct reg_block *rb, FILE *fp);
13386
13387
13388 static struct triple *call(struct compile_state *state,
13389         struct triple *retvar, struct triple *ret_addr, 
13390         struct triple *targ, struct triple *ret)
13391 {
13392         struct triple *call;
13393
13394         if (!retvar || !is_lvalue(state, retvar)) {
13395                 internal_error(state, 0, "writing to a non lvalue?");
13396         }
13397         write_compatible(state, retvar->type, &void_ptr_type);
13398
13399         call = new_triple(state, OP_CALL, &void_type, 1, 0);
13400         TARG(call, 0) = targ;
13401         MISC(call, 0) = ret;
13402         if (!targ || (targ->op != OP_LABEL)) {
13403                 internal_error(state, 0, "call not to a label");
13404         }
13405         if (!ret || (ret->op != OP_RET)) {
13406                 internal_error(state, 0, "call not matched with return");
13407         }
13408         return call;
13409 }
13410
13411 static void walk_functions(struct compile_state *state,
13412         void (*cb)(struct compile_state *state, struct triple *func, void *arg),
13413         void *arg)
13414 {
13415         struct triple *func, *first;
13416         func = first = state->functions;
13417         do {
13418                 cb(state, func, arg);
13419                 func = func->next;
13420         } while(func != first);
13421 }
13422
13423 static void reverse_walk_functions(struct compile_state *state,
13424         void (*cb)(struct compile_state *state, struct triple *func, void *arg),
13425         void *arg)
13426 {
13427         struct triple *func, *first;
13428         func = first = state->functions;
13429         do {
13430                 func = func->prev;
13431                 cb(state, func, arg);
13432         } while(func != first);
13433 }
13434
13435
13436 static void mark_live(struct compile_state *state, struct triple *func, void *arg)
13437 {
13438         struct triple *ptr, *first;
13439         if (func->u.cval == 0) {
13440                 return;
13441         }
13442         ptr = first = RHS(func, 0);
13443         do {
13444                 if (ptr->op == OP_FCALL) {
13445                         struct triple *called_func;
13446                         called_func = MISC(ptr, 0);
13447                         /* Mark the called function as used */
13448                         if (!(func->id & TRIPLE_FLAG_FLATTENED)) {
13449                                 called_func->u.cval++;
13450                         }
13451                         /* Remove the called function from the list */
13452                         called_func->prev->next = called_func->next;
13453                         called_func->next->prev = called_func->prev;
13454
13455                         /* Place the called function before me on the list */
13456                         called_func->next       = func;
13457                         called_func->prev       = func->prev;
13458                         called_func->prev->next = called_func;
13459                         called_func->next->prev = called_func;
13460                 }
13461                 ptr = ptr->next;
13462         } while(ptr != first);
13463         func->id |= TRIPLE_FLAG_FLATTENED;
13464 }
13465
13466 static void mark_live_functions(struct compile_state *state)
13467 {
13468         /* Ensure state->main_function is the last function in 
13469          * the list of functions.
13470          */
13471         if ((state->main_function->next != state->functions) ||
13472                 (state->functions->prev != state->main_function)) {
13473                 internal_error(state, 0, 
13474                         "state->main_function is not at the end of the function list ");
13475         }
13476         state->main_function->u.cval = 1;
13477         reverse_walk_functions(state, mark_live, 0);
13478 }
13479
13480 static int local_triple(struct compile_state *state, 
13481         struct triple *func, struct triple *ins)
13482 {
13483         int local = (ins->id & TRIPLE_FLAG_LOCAL);
13484 #if 0
13485         if (!local) {
13486                 FILE *fp = state->errout;
13487                 fprintf(fp, "global: ");
13488                 display_triple(fp, ins);
13489         }
13490 #endif
13491         return local;
13492 }
13493
13494 struct triple *copy_func(struct compile_state *state, struct triple *ofunc, 
13495         struct occurance *base_occurance)
13496 {
13497         struct triple *nfunc;
13498         struct triple *nfirst, *ofirst;
13499         struct triple *new, *old;
13500
13501         if (state->compiler->debug & DEBUG_INLINE) {
13502                 FILE *fp = state->dbgout;
13503                 fprintf(fp, "\n");
13504                 loc(fp, state, 0);
13505                 fprintf(fp, "\n__________ %s _________\n", __FUNCTION__);
13506                 display_func(state, fp, ofunc);
13507                 fprintf(fp, "__________ %s _________ done\n\n", __FUNCTION__);
13508         }
13509
13510         /* Make a new copy of the old function */
13511         nfunc = triple(state, OP_LIST, ofunc->type, 0, 0);
13512         nfirst = 0;
13513         ofirst = old = RHS(ofunc, 0);
13514         do {
13515                 struct triple *new;
13516                 struct occurance *occurance;
13517                 int old_lhs, old_rhs;
13518                 old_lhs = old->lhs;
13519                 old_rhs = old->rhs;
13520                 occurance = inline_occurance(state, base_occurance, old->occurance);
13521                 if (ofunc->u.cval && (old->op == OP_FCALL)) {
13522                         MISC(old, 0)->u.cval += 1;
13523                 }
13524                 new = alloc_triple(state, old->op, old->type, old_lhs, old_rhs,
13525                         occurance);
13526                 if (!triple_stores_block(state, new)) {
13527                         memcpy(&new->u, &old->u, sizeof(new->u));
13528                 }
13529                 if (!nfirst) {
13530                         RHS(nfunc, 0) = nfirst = new;
13531                 }
13532                 else {
13533                         insert_triple(state, nfirst, new);
13534                 }
13535                 new->id |= TRIPLE_FLAG_FLATTENED;
13536                 new->id |= old->id & TRIPLE_FLAG_COPY;
13537                 
13538                 /* During the copy remember new as user of old */
13539                 use_triple(old, new);
13540
13541                 /* Remember which instructions are local */
13542                 old->id |= TRIPLE_FLAG_LOCAL;
13543                 old = old->next;
13544         } while(old != ofirst);
13545
13546         /* Make a second pass to fix up any unresolved references */
13547         old = ofirst;
13548         new = nfirst;
13549         do {
13550                 struct triple **oexpr, **nexpr;
13551                 int count, i;
13552                 /* Lookup where the copy is, to join pointers */
13553                 count = TRIPLE_SIZE(old);
13554                 for(i = 0; i < count; i++) {
13555                         oexpr = &old->param[i];
13556                         nexpr = &new->param[i];
13557                         if (*oexpr && !*nexpr) {
13558                                 if (!local_triple(state, ofunc, *oexpr)) {
13559                                         *nexpr = *oexpr;
13560                                 }
13561                                 else if ((*oexpr)->use) {
13562                                         *nexpr = (*oexpr)->use->member;
13563                                 }
13564                                 if (*nexpr == old) {
13565                                         internal_error(state, 0, "new == old?");
13566                                 }
13567                                 use_triple(*nexpr, new);
13568                         }
13569                         if (!*nexpr && *oexpr) {
13570                                 internal_error(state, 0, "Could not copy %d", i);
13571                         }
13572                 }
13573                 old = old->next;
13574                 new = new->next;
13575         } while((old != ofirst) && (new != nfirst));
13576         
13577         /* Make a third pass to cleanup the extra useses */
13578         old = ofirst;
13579         new = nfirst;
13580         do {
13581                 unuse_triple(old, new);
13582                 /* Forget which instructions are local */
13583                 old->id &= ~TRIPLE_FLAG_LOCAL;
13584                 old = old->next;
13585                 new = new->next;
13586         } while ((old != ofirst) && (new != nfirst));
13587         return nfunc;
13588 }
13589
13590 static void expand_inline_call(
13591         struct compile_state *state, struct triple *me, struct triple *fcall)
13592 {
13593         /* Inline the function call */
13594         struct type *ptype;
13595         struct triple *ofunc, *nfunc, *nfirst, *result, *retvar, *ins;
13596         struct triple *end, *nend;
13597         int pvals, i;
13598
13599         /* Find the triples */
13600         ofunc = MISC(fcall, 0);
13601         if (ofunc->op != OP_LIST) {
13602                 internal_error(state, 0, "improper function");
13603         }
13604         nfunc = copy_func(state, ofunc, fcall->occurance);
13605         /* Prepend the parameter reading into the new function list */
13606         ptype = nfunc->type->right;
13607         pvals = fcall->rhs;
13608         for(i = 0; i < pvals; i++) {
13609                 struct type *atype;
13610                 struct triple *arg, *param;
13611                 atype = ptype;
13612                 if ((ptype->type & TYPE_MASK) == TYPE_PRODUCT) {
13613                         atype = ptype->left;
13614                 }
13615                 param = farg(state, nfunc, i);
13616                 if ((param->type->type & TYPE_MASK) != (atype->type & TYPE_MASK)) {
13617                         internal_error(state, fcall, "param %d type mismatch", i);
13618                 }
13619                 arg = RHS(fcall, i);
13620                 flatten(state, fcall, write_expr(state, param, arg));
13621                 ptype = ptype->right;
13622         }
13623         result = 0;
13624         if ((nfunc->type->left->type & TYPE_MASK) != TYPE_VOID) {
13625                 result = read_expr(state, 
13626                         deref_index(state, fresult(state, nfunc), 1));
13627         }
13628         if (state->compiler->debug & DEBUG_INLINE) {
13629                 FILE *fp = state->dbgout;
13630                 fprintf(fp, "\n");
13631                 loc(fp, state, 0);
13632                 fprintf(fp, "\n__________ %s _________\n", __FUNCTION__);
13633                 display_func(state, fp, nfunc);
13634                 fprintf(fp, "__________ %s _________ done\n\n", __FUNCTION__);
13635         }
13636
13637         /* 
13638          * Get rid of the extra triples 
13639          */
13640         /* Remove the read of the return address */
13641         ins = RHS(nfunc, 0)->prev->prev;
13642         if ((ins->op != OP_READ) || (RHS(ins, 0) != fretaddr(state, nfunc))) {
13643                 internal_error(state, ins, "Not return addres read?");
13644         }
13645         release_triple(state, ins);
13646         /* Remove the return instruction */
13647         ins = RHS(nfunc, 0)->prev;
13648         if (ins->op != OP_RET) {
13649                 internal_error(state, ins, "Not return?");
13650         }
13651         release_triple(state, ins);
13652         /* Remove the retaddres variable */
13653         retvar = fretaddr(state, nfunc);
13654         if ((retvar->lhs != 1) || 
13655                 (retvar->op != OP_ADECL) ||
13656                 (retvar->next->op != OP_PIECE) ||
13657                 (MISC(retvar->next, 0) != retvar)) {
13658                 internal_error(state, retvar, "Not the return address?");
13659         }
13660         release_triple(state, retvar->next);
13661         release_triple(state, retvar);
13662
13663         /* Remove the label at the start of the function */
13664         ins = RHS(nfunc, 0);
13665         if (ins->op != OP_LABEL) {
13666                 internal_error(state, ins, "Not label?");
13667         }
13668         nfirst = ins->next;
13669         free_triple(state, ins);
13670         /* Release the new function header */
13671         RHS(nfunc, 0) = 0;
13672         free_triple(state, nfunc);
13673
13674         /* Append the new function list onto the return list */
13675         end = fcall->prev;
13676         nend = nfirst->prev;
13677         end->next    = nfirst;
13678         nfirst->prev = end;
13679         nend->next   = fcall;
13680         fcall->prev  = nend;
13681
13682         /* Now the result reading code */
13683         if (result) {
13684                 result = flatten(state, fcall, result);
13685                 propogate_use(state, fcall, result);
13686         }
13687
13688         /* Release the original fcall instruction */
13689         release_triple(state, fcall);
13690
13691         return;
13692 }
13693
13694 /*
13695  *
13696  * Type of the result variable.
13697  * 
13698  *                                     result
13699  *                                        |
13700  *                             +----------+------------+
13701  *                             |                       |
13702  *                     union of closures         result_type
13703  *                             |
13704  *          +------------------+---------------+
13705  *          |                                  |
13706  *       closure1                    ...   closuerN
13707  *          |                                  | 
13708  *  +----+--+-+--------+-----+       +----+----+---+-----+
13709  *  |    |    |        |     |       |    |        |     |
13710  * var1 var2 var3 ... varN result   var1 var2 ... varN result
13711  *                           |
13712  *                  +--------+---------+
13713  *                  |                  |
13714  *          union of closures     result_type
13715  *                  |
13716  *            +-----+-------------------+
13717  *            |                         |
13718  *         closure1            ...  closureN
13719  *            |                         |
13720  *  +-----+---+----+----+      +----+---+----+-----+
13721  *  |     |        |    |      |    |        |     |
13722  * var1 var2 ... varN result  var1 var2 ... varN result
13723  */
13724
13725 static int add_closure_type(struct compile_state *state, 
13726         struct triple *func, struct type *closure_type)
13727 {
13728         struct type *type, *ctype, **next;
13729         struct triple *var, *new_var;
13730         int i;
13731
13732 #if 0
13733         FILE *fp = state->errout;
13734         fprintf(fp, "original_type: ");
13735         name_of(fp, fresult(state, func)->type);
13736         fprintf(fp, "\n");
13737 #endif
13738         /* find the original type */
13739         var = fresult(state, func);
13740         type = var->type;
13741         if (type->elements != 2) {
13742                 internal_error(state, var, "bad return type");
13743         }
13744
13745         /* Find the complete closure type and update it */
13746         ctype = type->left->left;
13747         next = &ctype->left;
13748         while(((*next)->type & TYPE_MASK) == TYPE_OVERLAP) {
13749                 next = &(*next)->right;
13750         }
13751         *next = new_type(TYPE_OVERLAP, *next, dup_type(state, closure_type));
13752         ctype->elements += 1;
13753
13754 #if 0
13755         fprintf(fp, "new_type: ");
13756         name_of(fp, type);
13757         fprintf(fp, "\n");
13758         fprintf(fp, "ctype: %p %d bits: %d ", 
13759                 ctype, ctype->elements, reg_size_of(state, ctype));
13760         name_of(fp, ctype);
13761         fprintf(fp, "\n");
13762 #endif
13763         
13764         /* Regenerate the variable with the new type definition */
13765         new_var = pre_triple(state, var, OP_ADECL, type, 0, 0);
13766         new_var->id |= TRIPLE_FLAG_FLATTENED;
13767         for(i = 0; i < new_var->lhs; i++) {
13768                 LHS(new_var, i)->id |= TRIPLE_FLAG_FLATTENED;
13769         }
13770         
13771         /* Point everyone at the new variable */
13772         propogate_use(state, var, new_var);
13773
13774         /* Release the original variable */
13775         for(i = 0; i < var->lhs; i++) {
13776                 release_triple(state, LHS(var, i));
13777         }
13778         release_triple(state, var);
13779         
13780         /* Return the index of the added closure type */
13781         return ctype->elements - 1;
13782 }
13783
13784 static struct triple *closure_expr(struct compile_state *state,
13785         struct triple *func, int closure_idx, int var_idx)
13786 {
13787         return deref_index(state,
13788                 deref_index(state,
13789                         deref_index(state, fresult(state, func), 0),
13790                         closure_idx),
13791                 var_idx);
13792 }
13793
13794
13795 static void insert_triple_set(
13796         struct triple_reg_set **head, struct triple *member)
13797 {
13798         struct triple_reg_set *new;
13799         new = xcmalloc(sizeof(*new), "triple_set");
13800         new->member = member;
13801         new->new    = 0;
13802         new->next   = *head;
13803         *head       = new;
13804 }
13805
13806 static int ordered_triple_set(
13807         struct triple_reg_set **head, struct triple *member)
13808 {
13809         struct triple_reg_set **ptr;
13810         if (!member)
13811                 return 0;
13812         ptr = head;
13813         while(*ptr) {
13814                 if (member == (*ptr)->member) {
13815                         return 0;
13816                 }
13817                 /* keep the list ordered */
13818                 if (member->id < (*ptr)->member->id) {
13819                         break;
13820                 }
13821                 ptr = &(*ptr)->next;
13822         }
13823         insert_triple_set(ptr, member);
13824         return 1;
13825 }
13826
13827
13828 static void free_closure_variables(struct compile_state *state,
13829         struct triple_reg_set **enclose)
13830 {
13831         struct triple_reg_set *entry, *next;
13832         for(entry = *enclose; entry; entry = next) {
13833                 next = entry->next;
13834                 do_triple_unset(enclose, entry->member);
13835         }
13836 }
13837
13838 static int lookup_closure_index(struct compile_state *state,
13839         struct triple *me, struct triple *val)
13840 {
13841         struct triple *first, *ins, *next;
13842         first = RHS(me, 0);
13843         ins = next = first;
13844         do {
13845                 struct triple *result;
13846                 struct triple *index0, *index1, *index2, *read, *write;
13847                 ins = next;
13848                 next = ins->next;
13849                 if (ins->op != OP_CALL) {
13850                         continue;
13851                 }
13852                 /* I am at a previous call point examine it closely */
13853                 if (ins->next->op != OP_LABEL) {
13854                         internal_error(state, ins, "call not followed by label");
13855                 }
13856                 /* Does this call does not enclose any variables? */
13857                 if ((ins->next->next->op != OP_INDEX) ||
13858                         (ins->next->next->u.cval != 0) ||
13859                         (result = MISC(ins->next->next, 0)) ||
13860                         (result->id & TRIPLE_FLAG_LOCAL)) {
13861                         continue;
13862                 }
13863                 index0 = ins->next->next;
13864                 /* The pattern is:
13865                  * 0 index result < 0 >
13866                  * 1 index 0 < ? >
13867                  * 2 index 1 < ? >
13868                  * 3 read  2
13869                  * 4 write 3 var
13870                  */
13871                 for(index0 = ins->next->next;
13872                         (index0->op == OP_INDEX) &&
13873                                 (MISC(index0, 0) == result) &&
13874                                 (index0->u.cval == 0) ; 
13875                         index0 = write->next)
13876                 {
13877                         index1 = index0->next;
13878                         index2 = index1->next;
13879                         read   = index2->next;
13880                         write  = read->next;
13881                         if ((index0->op != OP_INDEX) ||
13882                                 (index1->op != OP_INDEX) ||
13883                                 (index2->op != OP_INDEX) ||
13884                                 (read->op != OP_READ) ||
13885                                 (write->op != OP_WRITE) ||
13886                                 (MISC(index1, 0) != index0) ||
13887                                 (MISC(index2, 0) != index1) ||
13888                                 (RHS(read, 0) != index2) ||
13889                                 (RHS(write, 0) != read)) {
13890                                 internal_error(state, index0, "bad var read");
13891                         }
13892                         if (MISC(write, 0) == val) {
13893                                 return index2->u.cval;
13894                         }
13895                 }
13896         } while(next != first);
13897         return -1;
13898 }
13899
13900 static inline int enclose_triple(struct triple *ins)
13901 {
13902         return (ins && ((ins->type->type & TYPE_MASK) != TYPE_VOID));
13903 }
13904
13905 static void compute_closure_variables(struct compile_state *state,
13906         struct triple *me, struct triple *fcall, struct triple_reg_set **enclose)
13907 {
13908         struct triple_reg_set *set, *vars, **last_var;
13909         struct basic_blocks bb;
13910         struct reg_block *rb;
13911         struct block *block;
13912         struct triple *old_result, *first, *ins;
13913         size_t count, idx;
13914         unsigned long used_indicies;
13915         int i, max_index;
13916 #define MAX_INDICIES (sizeof(used_indicies)*CHAR_BIT)
13917 #define ID_BITS(X) ((X) & (TRIPLE_FLAG_LOCAL -1))
13918         struct { 
13919                 unsigned id;
13920                 int index;
13921         } *info;
13922
13923         
13924         /* Find the basic blocks of this function */
13925         bb.func = me;
13926         bb.first = RHS(me, 0);
13927         old_result = 0;
13928         if (!triple_is_ret(state, bb.first->prev)) {
13929                 bb.func = 0;
13930         } else {
13931                 old_result = fresult(state, me);
13932         }
13933         analyze_basic_blocks(state, &bb);
13934
13935         /* Find which variables are currently alive in a given block */
13936         rb = compute_variable_lifetimes(state, &bb);
13937
13938         /* Find the variables that are currently alive */
13939         block = block_of_triple(state, fcall);
13940         if (!block || (block->vertex <= 0) || (block->vertex > bb.last_vertex)) {
13941                 internal_error(state, fcall, "No reg block? block: %p", block);
13942         }
13943
13944 #if DEBUG_EXPLICIT_CLOSURES
13945         print_live_variables(state, &bb, rb, state->dbgout);
13946         fflush(state->dbgout);
13947 #endif
13948
13949         /* Count the number of triples in the function */
13950         first = RHS(me, 0);
13951         ins = first;
13952         count = 0;
13953         do {
13954                 count++;
13955                 ins = ins->next;
13956         } while(ins != first);
13957
13958         /* Allocate some memory to temorary hold the id info */
13959         info = xcmalloc(sizeof(*info) * (count +1), "info");
13960
13961         /* Mark the local function */
13962         first = RHS(me, 0);
13963         ins = first;
13964         idx = 1;
13965         do {
13966                 info[idx].id = ins->id;
13967                 ins->id = TRIPLE_FLAG_LOCAL | idx;
13968                 idx++;
13969                 ins = ins->next;
13970         } while(ins != first);
13971
13972         /* 
13973          * Build the list of variables to enclose.
13974          *
13975          * A target it to put the same variable in the
13976          * same slot for ever call of a given function.
13977          * After coloring this removes all of the variable
13978          * manipulation code.
13979          *
13980          * The list of variables to enclose is built ordered
13981          * program order because except in corner cases this
13982          * gives me the stability of assignment I need.
13983          *
13984          * To gurantee that stability I lookup the variables
13985          * to see where they have been used before and
13986          * I build my final list with the assigned indicies.
13987          */
13988         vars = 0;
13989         if (enclose_triple(old_result)) {
13990                 ordered_triple_set(&vars, old_result);
13991         }
13992         for(set = rb[block->vertex].out; set; set = set->next) {
13993                 if (!enclose_triple(set->member)) {
13994                         continue;
13995                 }
13996                 if ((set->member == fcall) || (set->member == old_result)) {
13997                         continue;
13998                 }
13999                 if (!local_triple(state, me, set->member)) {
14000                         internal_error(state, set->member, "not local?");
14001                 }
14002                 ordered_triple_set(&vars, set->member);
14003         }
14004
14005         /* Lookup the current indicies of the live varialbe */
14006         used_indicies = 0;
14007         max_index = -1;
14008         for(set = vars; set ; set = set->next) {
14009                 struct triple *ins;
14010                 int index;
14011                 ins = set->member;
14012                 index  = lookup_closure_index(state, me, ins);
14013                 info[ID_BITS(ins->id)].index = index;
14014                 if (index < 0) {
14015                         continue;
14016                 }
14017                 if (index >= MAX_INDICIES) {
14018                         internal_error(state, ins, "index unexpectedly large");
14019                 }
14020                 if (used_indicies & (1 << index)) {
14021                         internal_error(state, ins, "index previously used?");
14022                 }
14023                 /* Remember which indicies have been used */
14024                 used_indicies |= (1 << index);
14025                 if (index > max_index) {
14026                         max_index = index;
14027                 }
14028         }
14029
14030         /* Walk through the live variables and make certain
14031          * everything is assigned an index.
14032          */
14033         for(set = vars; set; set = set->next) {
14034                 struct triple *ins;
14035                 int index;
14036                 ins = set->member;
14037                 index = info[ID_BITS(ins->id)].index;
14038                 if (index >= 0) {
14039                         continue;
14040                 }
14041                 /* Find the lowest unused index value */
14042                 for(index = 0; index < MAX_INDICIES; index++) {
14043                         if (!(used_indicies & (1 << index))) {
14044                                 break;
14045                         }
14046                 }
14047                 if (index == MAX_INDICIES) {
14048                         internal_error(state, ins, "no free indicies?");
14049                 }
14050                 info[ID_BITS(ins->id)].index = index;
14051                 /* Remember which indicies have been used */
14052                 used_indicies |= (1 << index);
14053                 if (index > max_index) {
14054                         max_index = index;
14055                 }
14056         }
14057
14058         /* Build the return list of variables with positions matching
14059          * their indicies.
14060          */
14061         *enclose = 0;
14062         last_var = enclose;
14063         for(i = 0; i <= max_index; i++) {
14064                 struct triple *var;
14065                 var = 0;
14066                 if (used_indicies & (1 << i)) {
14067                         for(set = vars; set; set = set->next) {
14068                                 int index;
14069                                 index = info[ID_BITS(set->member->id)].index;
14070                                 if (index == i) {
14071                                         var = set->member;
14072                                         break;
14073                                 }
14074                         }
14075                         if (!var) {
14076                                 internal_error(state, me, "missing variable");
14077                         }
14078                 }
14079                 insert_triple_set(last_var, var);
14080                 last_var = &(*last_var)->next;
14081         }
14082
14083 #if DEBUG_EXPLICIT_CLOSURES
14084         /* Print out the variables to be enclosed */
14085         loc(state->dbgout, state, fcall);
14086         fprintf(state->dbgout, "Alive: \n");
14087         for(set = *enclose; set; set = set->next) {
14088                 display_triple(state->dbgout, set->member);
14089         }
14090         fflush(state->dbgout);
14091 #endif
14092
14093         /* Clear the marks */
14094         ins = first;
14095         do {
14096                 ins->id = info[ID_BITS(ins->id)].id;
14097                 ins = ins->next;
14098         } while(ins != first);
14099
14100         /* Release the ordered list of live variables */
14101         free_closure_variables(state, &vars);
14102
14103         /* Release the storage of the old ids */
14104         xfree(info);
14105
14106         /* Release the variable lifetime information */
14107         free_variable_lifetimes(state, &bb, rb);
14108
14109         /* Release the basic blocks of this function */
14110         free_basic_blocks(state, &bb);
14111 }
14112
14113 static void expand_function_call(
14114         struct compile_state *state, struct triple *me, struct triple *fcall)
14115 {
14116         /* Generate an ordinary function call */
14117         struct type *closure_type, **closure_next;
14118         struct triple *func, *func_first, *func_last, *retvar;
14119         struct triple *first;
14120         struct type *ptype, *rtype;
14121         struct triple *jmp;
14122         struct triple *ret_addr, *ret_loc, *ret_set;
14123         struct triple_reg_set *enclose, *set;
14124         int closure_idx, pvals, i;
14125
14126 #if DEBUG_EXPLICIT_CLOSURES
14127         FILE *fp = state->dbgout;
14128         fprintf(fp, "\ndisplay_func(me) ptr: %p\n", fcall);
14129         display_func(state, fp, MISC(fcall, 0));
14130         display_func(state, fp, me);
14131         fprintf(fp, "__________ %s _________ done\n\n", __FUNCTION__);
14132 #endif
14133
14134         /* Find the triples */
14135         func = MISC(fcall, 0);
14136         func_first = RHS(func, 0);
14137         retvar = fretaddr(state, func);
14138         func_last  = func_first->prev;
14139         first = fcall->next;
14140
14141         /* Find what I need to enclose */
14142         compute_closure_variables(state, me, fcall, &enclose);
14143
14144         /* Compute the closure type */
14145         closure_type = new_type(TYPE_TUPLE, 0, 0);
14146         closure_type->elements = 0;
14147         closure_next = &closure_type->left;
14148         for(set = enclose; set ; set = set->next) {
14149                 struct type *type;
14150                 type = &void_type;
14151                 if (set->member) {
14152                         type = set->member->type;
14153                 }
14154                 if (!*closure_next) {
14155                         *closure_next = type;
14156                 } else {
14157                         *closure_next = new_type(TYPE_PRODUCT, *closure_next, 
14158                                 type);
14159                         closure_next = &(*closure_next)->right;
14160                 }
14161                 closure_type->elements += 1;
14162         }
14163         if (closure_type->elements == 0) {
14164                 closure_type->type = TYPE_VOID;
14165         }
14166
14167
14168 #if DEBUG_EXPLICIT_CLOSURES
14169         fprintf(state->dbgout, "closure type: ");
14170         name_of(state->dbgout, closure_type);
14171         fprintf(state->dbgout, "\n");
14172 #endif
14173
14174         /* Update the called functions closure variable */
14175         closure_idx = add_closure_type(state, func, closure_type);
14176
14177         /* Generate some needed triples */
14178         ret_loc = label(state);
14179         ret_addr = triple(state, OP_ADDRCONST, &void_ptr_type, ret_loc, 0);
14180
14181         /* Pass the parameters to the new function */
14182         ptype = func->type->right;
14183         pvals = fcall->rhs;
14184         for(i = 0; i < pvals; i++) {
14185                 struct type *atype;
14186                 struct triple *arg, *param;
14187                 atype = ptype;
14188                 if ((ptype->type & TYPE_MASK) == TYPE_PRODUCT) {
14189                         atype = ptype->left;
14190                 }
14191                 param = farg(state, func, i);
14192                 if ((param->type->type & TYPE_MASK) != (atype->type & TYPE_MASK)) {
14193                         internal_error(state, fcall, "param type mismatch");
14194                 }
14195                 arg = RHS(fcall, i);
14196                 flatten(state, first, write_expr(state, param, arg));
14197                 ptype = ptype->right;
14198         }
14199         rtype = func->type->left;
14200
14201         /* Thread the triples together */
14202         ret_loc       = flatten(state, first, ret_loc);
14203
14204         /* Save the active variables in the result variable */
14205         for(i = 0, set = enclose; set ; set = set->next, i++) {
14206                 if (!set->member) {
14207                         continue;
14208                 }
14209                 flatten(state, ret_loc,
14210                         write_expr(state,
14211                                 closure_expr(state, func, closure_idx, i),
14212                                 read_expr(state, set->member)));
14213         }
14214
14215         /* Initialize the return value */
14216         if ((rtype->type & TYPE_MASK) != TYPE_VOID) {
14217                 flatten(state, ret_loc, 
14218                         write_expr(state, 
14219                                 deref_index(state, fresult(state, func), 1),
14220                                 new_triple(state, OP_UNKNOWNVAL, rtype,  0, 0)));
14221         }
14222
14223         ret_addr      = flatten(state, ret_loc, ret_addr);
14224         ret_set       = flatten(state, ret_loc, write_expr(state, retvar, ret_addr));
14225         jmp           = flatten(state, ret_loc, 
14226                 call(state, retvar, ret_addr, func_first, func_last));
14227
14228         /* Find the result */
14229         if ((rtype->type & TYPE_MASK) != TYPE_VOID) {
14230                 struct triple * result;
14231                 result = flatten(state, first, 
14232                         read_expr(state, 
14233                                 deref_index(state, fresult(state, func), 1)));
14234
14235                 propogate_use(state, fcall, result);
14236         }
14237
14238         /* Release the original fcall instruction */
14239         release_triple(state, fcall);
14240
14241         /* Restore the active variables from the result variable */
14242         for(i = 0, set = enclose; set ; set = set->next, i++) {
14243                 struct triple_set *use, *next;
14244                 struct triple *new;
14245                 struct basic_blocks bb;
14246                 if (!set->member || (set->member == fcall)) {
14247                         continue;
14248                 }
14249                 /* Generate an expression for the value */
14250                 new = flatten(state, first,
14251                         read_expr(state, 
14252                                 closure_expr(state, func, closure_idx, i)));
14253
14254
14255                 /* If the original is an lvalue restore the preserved value */
14256                 if (is_lvalue(state, set->member)) {
14257                         flatten(state, first,
14258                                 write_expr(state, set->member, new));
14259                         continue;
14260                 }
14261                 /*
14262                  * If the original is a value update the dominated uses.
14263                  */
14264                 
14265                 /* Analyze the basic blocks so I can see who dominates whom */
14266                 bb.func = me;
14267                 bb.first = RHS(me, 0);
14268                 if (!triple_is_ret(state, bb.first->prev)) {
14269                         bb.func = 0;
14270                 }
14271                 analyze_basic_blocks(state, &bb);
14272                 
14273
14274 #if DEBUG_EXPLICIT_CLOSURES
14275                 fprintf(state->errout, "Updating domindated uses: %p -> %p\n",
14276                         set->member, new);
14277 #endif
14278                 /* If fcall dominates the use update the expression */
14279                 for(use = set->member->use; use; use = next) {
14280                         /* Replace use modifies the use chain and 
14281                          * removes use, so I must take a copy of the
14282                          * next entry early.
14283                          */
14284                         next = use->next;
14285                         if (!tdominates(state, fcall, use->member)) {
14286                                 continue;
14287                         }
14288                         replace_use(state, set->member, new, use->member);
14289                 }
14290
14291                 /* Release the basic blocks, the instructions will be
14292                  * different next time, and flatten/insert_triple does
14293                  * not update the block values so I can't cache the analysis.
14294                  */
14295                 free_basic_blocks(state, &bb);
14296         }
14297
14298         /* Release the closure variable list */
14299         free_closure_variables(state, &enclose);
14300
14301         if (state->compiler->debug & DEBUG_INLINE) {
14302                 FILE *fp = state->dbgout;
14303                 fprintf(fp, "\n");
14304                 loc(fp, state, 0);
14305                 fprintf(fp, "\n__________ %s _________\n", __FUNCTION__);
14306                 display_func(state, fp, func);
14307                 display_func(state, fp, me);
14308                 fprintf(fp, "__________ %s _________ done\n\n", __FUNCTION__);
14309         }
14310
14311         return;
14312 }
14313
14314 static int do_inline(struct compile_state *state, struct triple *func)
14315 {
14316         int do_inline;
14317         int policy;
14318
14319         policy = state->compiler->flags & COMPILER_INLINE_MASK;
14320         switch(policy) {
14321         case COMPILER_INLINE_ALWAYS:
14322                 do_inline = 1;
14323                 if (func->type->type & ATTRIB_NOINLINE) {
14324                         error(state, func, "noinline with always_inline compiler option");
14325                 }
14326                 break;
14327         case COMPILER_INLINE_NEVER:
14328                 do_inline = 0;
14329                 if (func->type->type & ATTRIB_ALWAYS_INLINE) {
14330                         error(state, func, "always_inline with noinline compiler option");
14331                 }
14332                 break;
14333         case COMPILER_INLINE_DEFAULTON:
14334                 switch(func->type->type & STOR_MASK) {
14335                 case STOR_STATIC | STOR_INLINE:
14336                 case STOR_LOCAL  | STOR_INLINE:
14337                 case STOR_EXTERN | STOR_INLINE:
14338                         do_inline = 1;
14339                         break;
14340                 default:
14341                         do_inline = 1;
14342                         break;
14343                 }
14344                 break;
14345         case COMPILER_INLINE_DEFAULTOFF:
14346                 switch(func->type->type & STOR_MASK) {
14347                 case STOR_STATIC | STOR_INLINE:
14348                 case STOR_LOCAL  | STOR_INLINE:
14349                 case STOR_EXTERN | STOR_INLINE:
14350                         do_inline = 1;
14351                         break;
14352                 default:
14353                         do_inline = 0;
14354                         break;
14355                 }
14356                 break;
14357         case COMPILER_INLINE_NOPENALTY:
14358                 switch(func->type->type & STOR_MASK) {
14359                 case STOR_STATIC | STOR_INLINE:
14360                 case STOR_LOCAL  | STOR_INLINE:
14361                 case STOR_EXTERN | STOR_INLINE:
14362                         do_inline = 1;
14363                         break;
14364                 default:
14365                         do_inline = (func->u.cval == 1);
14366                         break;
14367                 }
14368                 break;
14369         default:
14370                 do_inline = 0;
14371                 internal_error(state, 0, "Unimplemented inline policy");
14372                 break;
14373         }
14374         /* Force inlining */
14375         if (func->type->type & ATTRIB_NOINLINE) {
14376                 do_inline = 0;
14377         }
14378         if (func->type->type & ATTRIB_ALWAYS_INLINE) {
14379                 do_inline = 1;
14380         }
14381         return do_inline;
14382 }
14383
14384 static void inline_function(struct compile_state *state, struct triple *me, void *arg)
14385 {
14386         struct triple *first, *ptr, *next;
14387         /* If the function is not used don't bother */
14388         if (me->u.cval <= 0) {
14389                 return;
14390         }
14391         if (state->compiler->debug & DEBUG_CALLS2) {
14392                 FILE *fp = state->dbgout;
14393                 fprintf(fp, "in: %s\n",
14394                         me->type->type_ident->name);
14395         }
14396
14397         first = RHS(me, 0);
14398         ptr = next = first;
14399         do {
14400                 struct triple *func, *prev;
14401                 ptr = next;
14402                 prev = ptr->prev;
14403                 next = ptr->next;
14404                 if (ptr->op != OP_FCALL) {
14405                         continue;
14406                 }
14407                 func = MISC(ptr, 0);
14408                 /* See if the function should be inlined */
14409                 if (!do_inline(state, func)) {
14410                         /* Put a label after the fcall */
14411                         post_triple(state, ptr, OP_LABEL, &void_type, 0, 0);
14412                         continue;
14413                 }
14414                 if (state->compiler->debug & DEBUG_CALLS) {
14415                         FILE *fp = state->dbgout;
14416                         if (state->compiler->debug & DEBUG_CALLS2) {
14417                                 loc(fp, state, ptr);
14418                         }
14419                         fprintf(fp, "inlining %s\n",
14420                                 func->type->type_ident->name);
14421                         fflush(fp);
14422                 }
14423
14424                 /* Update the function use counts */
14425                 func->u.cval -= 1;
14426
14427                 /* Replace the fcall with the called function */
14428                 expand_inline_call(state, me, ptr);
14429
14430                 next = prev->next;
14431         } while (next != first);
14432
14433         ptr = next = first;
14434         do {
14435                 struct triple *prev, *func;
14436                 ptr = next;
14437                 prev = ptr->prev;
14438                 next = ptr->next;
14439                 if (ptr->op != OP_FCALL) {
14440                         continue;
14441                 }
14442                 func = MISC(ptr, 0);
14443                 if (state->compiler->debug & DEBUG_CALLS) {
14444                         FILE *fp = state->dbgout;
14445                         if (state->compiler->debug & DEBUG_CALLS2) {
14446                                 loc(fp, state, ptr);
14447                         }
14448                         fprintf(fp, "calling %s\n",
14449                                 func->type->type_ident->name);
14450                         fflush(fp);
14451                 }
14452                 /* Replace the fcall with the instruction sequence
14453                  * needed to make the call.
14454                  */
14455                 expand_function_call(state, me, ptr);
14456                 next = prev->next;
14457         } while(next != first);
14458 }
14459
14460 static void inline_functions(struct compile_state *state, struct triple *func)
14461 {
14462         inline_function(state, func, 0);
14463         reverse_walk_functions(state, inline_function, 0);
14464 }
14465
14466 static void insert_function(struct compile_state *state,
14467         struct triple *func, void *arg)
14468 {
14469         struct triple *first, *end, *ffirst, *fend;
14470
14471         if (state->compiler->debug & DEBUG_INLINE) {
14472                 FILE *fp = state->errout;
14473                 fprintf(fp, "%s func count: %d\n", 
14474                         func->type->type_ident->name, func->u.cval);
14475         }
14476         if (func->u.cval == 0) {
14477                 return;
14478         }
14479
14480         /* Find the end points of the lists */
14481         first  = arg;
14482         end    = first->prev;
14483         ffirst = RHS(func, 0);
14484         fend   = ffirst->prev;
14485
14486         /* splice the lists together */
14487         end->next    = ffirst;
14488         ffirst->prev = end;
14489         fend->next   = first;
14490         first->prev  = fend;
14491 }
14492
14493 struct triple *input_asm(struct compile_state *state)
14494 {
14495         struct asm_info *info;
14496         struct triple *def;
14497         int i, out;
14498         
14499         info = xcmalloc(sizeof(*info), "asm_info");
14500         info->str = "";
14501
14502         out = sizeof(arch_input_regs)/sizeof(arch_input_regs[0]);
14503         memcpy(&info->tmpl.lhs, arch_input_regs, sizeof(arch_input_regs));
14504
14505         def = new_triple(state, OP_ASM, &void_type, out, 0);
14506         def->u.ainfo = info;
14507         def->id |= TRIPLE_FLAG_VOLATILE;
14508         
14509         for(i = 0; i < out; i++) {
14510                 struct triple *piece;
14511                 piece = triple(state, OP_PIECE, &int_type, def, 0);
14512                 piece->u.cval = i;
14513                 LHS(def, i) = piece;
14514         }
14515
14516         return def;
14517 }
14518
14519 struct triple *output_asm(struct compile_state *state)
14520 {
14521         struct asm_info *info;
14522         struct triple *def;
14523         int in;
14524         
14525         info = xcmalloc(sizeof(*info), "asm_info");
14526         info->str = "";
14527
14528         in = sizeof(arch_output_regs)/sizeof(arch_output_regs[0]);
14529         memcpy(&info->tmpl.rhs, arch_output_regs, sizeof(arch_output_regs));
14530
14531         def = new_triple(state, OP_ASM, &void_type, 0, in);
14532         def->u.ainfo = info;
14533         def->id |= TRIPLE_FLAG_VOLATILE;
14534         
14535         return def;
14536 }
14537
14538 static void join_functions(struct compile_state *state)
14539 {
14540         struct triple *jmp, *start, *end, *call, *in, *out, *func;
14541         struct file_state file;
14542         struct type *pnext, *param;
14543         struct type *result_type, *args_type;
14544         int idx;
14545
14546         /* Be clear the functions have not been joined yet */
14547         state->functions_joined = 0;
14548
14549         /* Dummy file state to get debug handing right */
14550         memset(&file, 0, sizeof(file));
14551         file.basename = "";
14552         file.line = 0;
14553         file.report_line = 0;
14554         file.report_name = file.basename;
14555         file.prev = state->file;
14556         state->file = &file;
14557         state->function = "";
14558
14559         if (!state->main_function) {
14560                 error(state, 0, "No functions to compile\n");
14561         }
14562
14563         /* The type of arguments */
14564         args_type   = state->main_function->type->right;
14565         /* The return type without any specifiers */
14566         result_type = clone_type(0, state->main_function->type->left);
14567
14568
14569         /* Verify the external arguments */
14570         if (registers_of(state, args_type) > ARCH_INPUT_REGS) {
14571                 error(state, state->main_function, 
14572                         "Too many external input arguments");
14573         }
14574         if (registers_of(state, result_type) > ARCH_OUTPUT_REGS) {
14575                 error(state, state->main_function, 
14576                         "Too many external output arguments");
14577         }
14578
14579         /* Lay down the basic program structure */
14580         end           = label(state);
14581         start         = label(state);
14582         start         = flatten(state, state->first, start);
14583         end           = flatten(state, state->first, end);
14584         in            = input_asm(state);
14585         out           = output_asm(state);
14586         call          = new_triple(state, OP_FCALL, result_type, -1, registers_of(state, args_type));
14587         MISC(call, 0) = state->main_function;
14588         in            = flatten(state, state->first, in);
14589         call          = flatten(state, state->first, call);
14590         out           = flatten(state, state->first, out);
14591
14592
14593         /* Read the external input arguments */
14594         pnext = args_type;
14595         idx = 0;
14596         while(pnext && ((pnext->type & TYPE_MASK) != TYPE_VOID)) {
14597                 struct triple *expr;
14598                 param = pnext;
14599                 pnext = 0;
14600                 if ((param->type & TYPE_MASK) == TYPE_PRODUCT) {
14601                         pnext = param->right;
14602                         param = param->left;
14603                 }
14604                 if (registers_of(state, param) != 1) {
14605                         error(state, state->main_function, 
14606                                 "Arg: %d %s requires multiple registers", 
14607                                 idx + 1, param->field_ident->name);
14608                 }
14609                 expr = read_expr(state, LHS(in, idx));
14610                 RHS(call, idx) = expr;
14611                 expr = flatten(state, call, expr);
14612                 use_triple(expr, call);
14613
14614                 idx++;  
14615         }
14616
14617
14618         /* Write the external output arguments */
14619         pnext = result_type;
14620         if ((pnext->type & TYPE_MASK) == TYPE_STRUCT) {
14621                 pnext = result_type->left;
14622         }
14623         for(idx = 0; idx < out->rhs; idx++) {
14624                 struct triple *expr;
14625                 param = pnext;
14626                 pnext = 0;
14627                 if (param && ((param->type & TYPE_MASK) == TYPE_PRODUCT)) {
14628                         pnext = param->right;
14629                         param = param->left;
14630                 }
14631                 if (param && ((param->type & TYPE_MASK) == TYPE_VOID)) {
14632                         param = 0;
14633                 }
14634                 if (param) {
14635                         if (registers_of(state, param) != 1) {
14636                                 error(state, state->main_function,
14637                                         "Result: %d %s requires multiple registers",
14638                                         idx, param->field_ident->name);
14639                         }
14640                         expr = read_expr(state, call);
14641                         if ((result_type->type & TYPE_MASK) == TYPE_STRUCT) {
14642                                 expr = deref_field(state, expr, param->field_ident);
14643                         }
14644                 } else {
14645                         expr = triple(state, OP_UNKNOWNVAL, &int_type, 0, 0);
14646                 }
14647                 flatten(state, out, expr);
14648                 RHS(out, idx) = expr;
14649                 use_triple(expr, out);
14650         }
14651
14652         /* Allocate a dummy containing function */
14653         func = triple(state, OP_LIST, 
14654                 new_type(TYPE_FUNCTION, &void_type, &void_type), 0, 0);
14655         func->type->type_ident = lookup(state, "", 0);
14656         RHS(func, 0) = state->first;
14657         func->u.cval = 1;
14658
14659         /* See which functions are called, and how often */
14660         mark_live_functions(state);
14661         inline_functions(state, func);
14662         walk_functions(state, insert_function, end);
14663
14664         if (start->next != end) {
14665                 jmp = flatten(state, start, branch(state, end, 0));
14666         }
14667
14668         /* OK now the functions have been joined. */
14669         state->functions_joined = 1;
14670
14671         /* Done now cleanup */
14672         state->file = file.prev;
14673         state->function = 0;
14674 }
14675
14676 /*
14677  * Data structurs for optimation.
14678  */
14679
14680
14681 static int do_use_block(
14682         struct block *used, struct block_set **head, struct block *user, 
14683         int front)
14684 {
14685         struct block_set **ptr, *new;
14686         if (!used)
14687                 return 0;
14688         if (!user)
14689                 return 0;
14690         ptr = head;
14691         while(*ptr) {
14692                 if ((*ptr)->member == user) {
14693                         return 0;
14694                 }
14695                 ptr = &(*ptr)->next;
14696         }
14697         new = xcmalloc(sizeof(*new), "block_set");
14698         new->member = user;
14699         if (front) {
14700                 new->next = *head;
14701                 *head = new;
14702         }
14703         else {
14704                 new->next = 0;
14705                 *ptr = new;
14706         }
14707         return 1;
14708 }
14709 static int do_unuse_block(
14710         struct block *used, struct block_set **head, struct block *unuser)
14711 {
14712         struct block_set *use, **ptr;
14713         int count;
14714         count = 0;
14715         ptr = head;
14716         while(*ptr) {
14717                 use = *ptr;
14718                 if (use->member == unuser) {
14719                         *ptr = use->next;
14720                         memset(use, -1, sizeof(*use));
14721                         xfree(use);
14722                         count += 1;
14723                 }
14724                 else {
14725                         ptr = &use->next;
14726                 }
14727         }
14728         return count;
14729 }
14730
14731 static void use_block(struct block *used, struct block *user)
14732 {
14733         int count;
14734         /* Append new to the head of the list, print_block
14735          * depends on this.
14736          */
14737         count = do_use_block(used, &used->use, user, 1); 
14738         used->users += count;
14739 }
14740 static void unuse_block(struct block *used, struct block *unuser)
14741 {
14742         int count;
14743         count = do_unuse_block(used, &used->use, unuser); 
14744         used->users -= count;
14745 }
14746
14747 static void add_block_edge(struct block *block, struct block *edge, int front)
14748 {
14749         int count;
14750         count = do_use_block(block, &block->edges, edge, front);
14751         block->edge_count += count;
14752 }
14753
14754 static void remove_block_edge(struct block *block, struct block *edge)
14755 {
14756         int count;
14757         count = do_unuse_block(block, &block->edges, edge);
14758         block->edge_count -= count;
14759 }
14760
14761 static void idom_block(struct block *idom, struct block *user)
14762 {
14763         do_use_block(idom, &idom->idominates, user, 0);
14764 }
14765
14766 static void unidom_block(struct block *idom, struct block *unuser)
14767 {
14768         do_unuse_block(idom, &idom->idominates, unuser);
14769 }
14770
14771 static void domf_block(struct block *block, struct block *domf)
14772 {
14773         do_use_block(block, &block->domfrontier, domf, 0);
14774 }
14775
14776 static void undomf_block(struct block *block, struct block *undomf)
14777 {
14778         do_unuse_block(block, &block->domfrontier, undomf);
14779 }
14780
14781 static void ipdom_block(struct block *ipdom, struct block *user)
14782 {
14783         do_use_block(ipdom, &ipdom->ipdominates, user, 0);
14784 }
14785
14786 static void unipdom_block(struct block *ipdom, struct block *unuser)
14787 {
14788         do_unuse_block(ipdom, &ipdom->ipdominates, unuser);
14789 }
14790
14791 static void ipdomf_block(struct block *block, struct block *ipdomf)
14792 {
14793         do_use_block(block, &block->ipdomfrontier, ipdomf, 0);
14794 }
14795
14796 static void unipdomf_block(struct block *block, struct block *unipdomf)
14797 {
14798         do_unuse_block(block, &block->ipdomfrontier, unipdomf);
14799 }
14800
14801 static int walk_triples(
14802         struct compile_state *state, 
14803         int (*cb)(struct compile_state *state, struct triple *ptr, void *arg),
14804         void *arg)
14805 {
14806         struct triple *ptr;
14807         int result;
14808         ptr = state->first;
14809         do {
14810                 result = cb(state, ptr, arg);
14811                 if (ptr->next->prev != ptr) {
14812                         internal_error(state, ptr->next, "bad prev");
14813                 }
14814                 ptr = ptr->next;
14815         } while((result == 0) && (ptr != state->first));
14816         return result;
14817 }
14818
14819 #define PRINT_LIST 1
14820 static int do_print_triple(struct compile_state *state, struct triple *ins, void *arg)
14821 {
14822         FILE *fp = arg;
14823         int op;
14824         op = ins->op;
14825         if (op == OP_LIST) {
14826 #if !PRINT_LIST
14827                 return 0;
14828 #endif
14829         }
14830         if ((op == OP_LABEL) && (ins->use)) {
14831                 fprintf(fp, "\n%p:\n", ins);
14832         }
14833         display_triple(fp, ins);
14834
14835         if (triple_is_branch(state, ins) && ins->use && 
14836                 (ins->op != OP_RET) && (ins->op != OP_FCALL)) {
14837                 internal_error(state, ins, "branch used?");
14838         }
14839         if (triple_is_branch(state, ins)) {
14840                 fprintf(fp, "\n");
14841         }
14842         return 0;
14843 }
14844
14845 static void print_triples(struct compile_state *state)
14846 {
14847         if (state->compiler->debug & DEBUG_TRIPLES) {
14848                 FILE *fp = state->dbgout;
14849                 fprintf(fp, "--------------- triples ---------------\n");
14850                 walk_triples(state, do_print_triple, fp);
14851                 fprintf(fp, "\n");
14852         }
14853 }
14854
14855 struct cf_block {
14856         struct block *block;
14857 };
14858 static void find_cf_blocks(struct cf_block *cf, struct block *block)
14859 {
14860         struct block_set *edge;
14861         if (!block || (cf[block->vertex].block == block)) {
14862                 return;
14863         }
14864         cf[block->vertex].block = block;
14865         for(edge = block->edges; edge; edge = edge->next) {
14866                 find_cf_blocks(cf, edge->member);
14867         }
14868 }
14869
14870 static void print_control_flow(struct compile_state *state,
14871         FILE *fp, struct basic_blocks *bb)
14872 {
14873         struct cf_block *cf;
14874         int i;
14875         fprintf(fp, "\ncontrol flow\n");
14876         cf = xcmalloc(sizeof(*cf) * (bb->last_vertex + 1), "cf_block");
14877         find_cf_blocks(cf, bb->first_block);
14878
14879         for(i = 1; i <= bb->last_vertex; i++) {
14880                 struct block *block;
14881                 struct block_set *edge;
14882                 block = cf[i].block;
14883                 if (!block)
14884                         continue;
14885                 fprintf(fp, "(%p) %d:", block, block->vertex);
14886                 for(edge = block->edges; edge; edge = edge->next) {
14887                         fprintf(fp, " %d", edge->member->vertex);
14888                 }
14889                 fprintf(fp, "\n");
14890         }
14891
14892         xfree(cf);
14893 }
14894
14895 static void free_basic_block(struct compile_state *state, struct block *block)
14896 {
14897         struct block_set *edge, *entry;
14898         struct block *child;
14899         if (!block) {
14900                 return;
14901         }
14902         if (block->vertex == -1) {
14903                 return;
14904         }
14905         block->vertex = -1;
14906         for(edge = block->edges; edge; edge = edge->next) {
14907                 if (edge->member) {
14908                         unuse_block(edge->member, block);
14909                 }
14910         }
14911         if (block->idom) {
14912                 unidom_block(block->idom, block);
14913         }
14914         block->idom = 0;
14915         if (block->ipdom) {
14916                 unipdom_block(block->ipdom, block);
14917         }
14918         block->ipdom = 0;
14919         while((entry = block->use)) {
14920                 child = entry->member;
14921                 unuse_block(block, child);
14922                 if (child && (child->vertex != -1)) {
14923                         for(edge = child->edges; edge; edge = edge->next) {
14924                                 edge->member = 0;
14925                         }
14926                 }
14927         }
14928         while((entry = block->idominates)) {
14929                 child = entry->member;
14930                 unidom_block(block, child);
14931                 if (child && (child->vertex != -1)) {
14932                         child->idom = 0;
14933                 }
14934         }
14935         while((entry = block->domfrontier)) {
14936                 child = entry->member;
14937                 undomf_block(block, child);
14938         }
14939         while((entry = block->ipdominates)) {
14940                 child = entry->member;
14941                 unipdom_block(block, child);
14942                 if (child && (child->vertex != -1)) {
14943                         child->ipdom = 0;
14944                 }
14945         }
14946         while((entry = block->ipdomfrontier)) {
14947                 child = entry->member;
14948                 unipdomf_block(block, child);
14949         }
14950         if (block->users != 0) {
14951                 internal_error(state, 0, "block still has users");
14952         }
14953         while((edge = block->edges)) {
14954                 child = edge->member;
14955                 remove_block_edge(block, child);
14956                 
14957                 if (child && (child->vertex != -1)) {
14958                         free_basic_block(state, child);
14959                 }
14960         }
14961         memset(block, -1, sizeof(*block));
14962         xfree(block);
14963 }
14964
14965 static void free_basic_blocks(struct compile_state *state, 
14966         struct basic_blocks *bb)
14967 {
14968         struct triple *first, *ins;
14969         free_basic_block(state, bb->first_block);
14970         bb->last_vertex = 0;
14971         bb->first_block = bb->last_block = 0;
14972         first = bb->first;
14973         ins = first;
14974         do {
14975                 if (triple_stores_block(state, ins)) {
14976                         ins->u.block = 0;
14977                 }
14978                 ins = ins->next;
14979         } while(ins != first);
14980         
14981 }
14982
14983 static struct block *basic_block(struct compile_state *state, 
14984         struct basic_blocks *bb, struct triple *first)
14985 {
14986         struct block *block;
14987         struct triple *ptr;
14988         if (!triple_is_label(state, first)) {
14989                 internal_error(state, first, "block does not start with a label");
14990         }
14991         /* See if this basic block has already been setup */
14992         if (first->u.block != 0) {
14993                 return first->u.block;
14994         }
14995         /* Allocate another basic block structure */
14996         bb->last_vertex += 1;
14997         block = xcmalloc(sizeof(*block), "block");
14998         block->first = block->last = first;
14999         block->vertex = bb->last_vertex;
15000         ptr = first;
15001         do {
15002                 if ((ptr != first) && triple_is_label(state, ptr) && (ptr->use)) { 
15003                         break;
15004                 }
15005                 block->last = ptr;
15006                 /* If ptr->u is not used remember where the baic block is */
15007                 if (triple_stores_block(state, ptr)) {
15008                         ptr->u.block = block;
15009                 }
15010                 if (triple_is_branch(state, ptr)) {
15011                         break;
15012                 }
15013                 ptr = ptr->next;
15014         } while (ptr != bb->first);
15015         if ((ptr == bb->first) ||
15016                 ((ptr->next == bb->first) && (
15017                         triple_is_end(state, ptr) || 
15018                         triple_is_ret(state, ptr))))
15019         {
15020                 /* The block has no outflowing edges */
15021         }
15022         else if (triple_is_label(state, ptr)) {
15023                 struct block *next;
15024                 next = basic_block(state, bb, ptr);
15025                 add_block_edge(block, next, 0);
15026                 use_block(next, block);
15027         }
15028         else if (triple_is_branch(state, ptr)) {
15029                 struct triple **expr, *first;
15030                 struct block *child;
15031                 /* Find the branch targets.
15032                  * I special case the first branch as that magically
15033                  * avoids some difficult cases for the register allocator.
15034                  */
15035                 expr = triple_edge_targ(state, ptr, 0);
15036                 if (!expr) {
15037                         internal_error(state, ptr, "branch without targets");
15038                 }
15039                 first = *expr;
15040                 expr = triple_edge_targ(state, ptr, expr);
15041                 for(; expr; expr = triple_edge_targ(state, ptr, expr)) {
15042                         if (!*expr) continue;
15043                         child = basic_block(state, bb, *expr);
15044                         use_block(child, block);
15045                         add_block_edge(block, child, 0);
15046                 }
15047                 if (first) {
15048                         child = basic_block(state, bb, first);
15049                         use_block(child, block);
15050                         add_block_edge(block, child, 1);
15051
15052                         /* Be certain the return block of a call is
15053                          * in a basic block.  When it is not find
15054                          * start of the block, insert a label if
15055                          * necessary and build the basic block.
15056                          * Then add a fake edge from the start block
15057                          * to the return block of the function.
15058                          */
15059                         if (state->functions_joined && triple_is_call(state, ptr)
15060                                 && !block_of_triple(state, MISC(ptr, 0))) {
15061                                 struct block *tail;
15062                                 struct triple *start;
15063                                 start = triple_to_block_start(state, MISC(ptr, 0));
15064                                 if (!triple_is_label(state, start)) {
15065                                         start = pre_triple(state,
15066                                                 start, OP_LABEL, &void_type, 0, 0);
15067                                 }
15068                                 tail = basic_block(state, bb, start);
15069                                 add_block_edge(child, tail, 0);
15070                                 use_block(tail, child);
15071                         }
15072                 }
15073         }
15074         else {
15075                 internal_error(state, 0, "Bad basic block split");
15076         }
15077 #if 0
15078 {
15079         struct block_set *edge;
15080         FILE *fp = state->errout;
15081         fprintf(fp, "basic_block: %10p [%2d] ( %10p - %10p )",
15082                 block, block->vertex, 
15083                 block->first, block->last);
15084         for(edge = block->edges; edge; edge = edge->next) {
15085                 fprintf(fp, " %10p [%2d]",
15086                         edge->member ? edge->member->first : 0,
15087                         edge->member ? edge->member->vertex : -1);
15088         }
15089         fprintf(fp, "\n");
15090 }
15091 #endif
15092         return block;
15093 }
15094
15095
15096 static void walk_blocks(struct compile_state *state, struct basic_blocks *bb,
15097         void (*cb)(struct compile_state *state, struct block *block, void *arg),
15098         void *arg)
15099 {
15100         struct triple *ptr, *first;
15101         struct block *last_block;
15102         last_block = 0;
15103         first = bb->first;
15104         ptr = first;
15105         do {
15106                 if (triple_stores_block(state, ptr)) {
15107                         struct block *block;
15108                         block = ptr->u.block;
15109                         if (block && (block != last_block)) {
15110                                 cb(state, block, arg);
15111                         }
15112                         last_block = block;
15113                 }
15114                 ptr = ptr->next;
15115         } while(ptr != first);
15116 }
15117
15118 static void print_block(
15119         struct compile_state *state, struct block *block, void *arg)
15120 {
15121         struct block_set *user, *edge;
15122         struct triple *ptr;
15123         FILE *fp = arg;
15124
15125         fprintf(fp, "\nblock: %p (%d) ",
15126                 block, 
15127                 block->vertex);
15128
15129         for(edge = block->edges; edge; edge = edge->next) {
15130                 fprintf(fp, " %p<-%p",
15131                         edge->member,
15132                         (edge->member && edge->member->use)?
15133                         edge->member->use->member : 0);
15134         }
15135         fprintf(fp, "\n");
15136         if (block->first->op == OP_LABEL) {
15137                 fprintf(fp, "%p:\n", block->first);
15138         }
15139         for(ptr = block->first; ; ) {
15140                 display_triple(fp, ptr);
15141                 if (ptr == block->last)
15142                         break;
15143                 ptr = ptr->next;
15144                 if (ptr == block->first) {
15145                         internal_error(state, 0, "missing block last?");
15146                 }
15147         }
15148         fprintf(fp, "users %d: ", block->users);
15149         for(user = block->use; user; user = user->next) {
15150                 fprintf(fp, "%p (%d) ", 
15151                         user->member,
15152                         user->member->vertex);
15153         }
15154         fprintf(fp,"\n\n");
15155 }
15156
15157
15158 static void romcc_print_blocks(struct compile_state *state, FILE *fp)
15159 {
15160         fprintf(fp, "--------------- blocks ---------------\n");
15161         walk_blocks(state, &state->bb, print_block, fp);
15162 }
15163 static void print_blocks(struct compile_state *state, const char *func, FILE *fp)
15164 {
15165         static void print_dominators(struct compile_state *state, FILE *fp, struct basic_blocks *bb);
15166         static void print_dominance_frontiers(struct compile_state *state, FILE *fp, struct basic_blocks *bb);
15167         if (state->compiler->debug & DEBUG_BASIC_BLOCKS) {
15168                 fprintf(fp, "After %s\n", func);
15169                 romcc_print_blocks(state, fp);
15170                 if (state->compiler->debug & DEBUG_FDOMINATORS) {
15171                         print_dominators(state, fp, &state->bb);
15172                         print_dominance_frontiers(state, fp, &state->bb);
15173                 }
15174                 print_control_flow(state, fp, &state->bb);
15175         }
15176 }
15177
15178 static void prune_nonblock_triples(struct compile_state *state, 
15179         struct basic_blocks *bb)
15180 {
15181         struct block *block;
15182         struct triple *first, *ins, *next;
15183         /* Delete the triples not in a basic block */
15184         block = 0;
15185         first = bb->first;
15186         ins = first;
15187         do {
15188                 next = ins->next;
15189                 if (ins->op == OP_LABEL) {
15190                         block = ins->u.block;
15191                 }
15192                 if (!block) {
15193                         struct triple_set *use;
15194                         for(use = ins->use; use; use = use->next) {
15195                                 struct block *block;
15196                                 block = block_of_triple(state, use->member);
15197                                 if (block != 0) {
15198                                         internal_error(state, ins, "pruning used ins?");
15199                                 }
15200                         }
15201                         release_triple(state, ins);
15202                 }
15203                 if (block && block->last == ins) {
15204                         block = 0;
15205                 }
15206                 ins = next;
15207         } while(ins != first);
15208 }
15209
15210 static void setup_basic_blocks(struct compile_state *state, 
15211         struct basic_blocks *bb)
15212 {
15213         if (!triple_stores_block(state, bb->first)) {
15214                 internal_error(state, 0, "ins will not store block?");
15215         }
15216         /* Initialize the state */
15217         bb->first_block = bb->last_block = 0;
15218         bb->last_vertex = 0;
15219         free_basic_blocks(state, bb);
15220
15221         /* Find the basic blocks */
15222         bb->first_block = basic_block(state, bb, bb->first);
15223
15224         /* Be certain the last instruction of a function, or the
15225          * entire program is in a basic block.  When it is not find 
15226          * the start of the block, insert a label if necessary and build 
15227          * basic block.  Then add a fake edge from the start block
15228          * to the final block.
15229          */
15230         if (!block_of_triple(state, bb->first->prev)) {
15231                 struct triple *start;
15232                 struct block *tail;
15233                 start = triple_to_block_start(state, bb->first->prev);
15234                 if (!triple_is_label(state, start)) {
15235                         start = pre_triple(state,
15236                                 start, OP_LABEL, &void_type, 0, 0);
15237                 }
15238                 tail = basic_block(state, bb, start);
15239                 add_block_edge(bb->first_block, tail, 0);
15240                 use_block(tail, bb->first_block);
15241         }
15242         
15243         /* Find the last basic block.
15244          */
15245         bb->last_block = block_of_triple(state, bb->first->prev);
15246
15247         /* Delete the triples not in a basic block */
15248         prune_nonblock_triples(state, bb);
15249
15250 #if 0
15251         /* If we are debugging print what I have just done */
15252         if (state->compiler->debug & DEBUG_BASIC_BLOCKS) {
15253                 print_blocks(state, state->dbgout);
15254                 print_control_flow(state, bb);
15255         }
15256 #endif
15257 }
15258
15259
15260 struct sdom_block {
15261         struct block *block;
15262         struct sdom_block *sdominates;
15263         struct sdom_block *sdom_next;
15264         struct sdom_block *sdom;
15265         struct sdom_block *label;
15266         struct sdom_block *parent;
15267         struct sdom_block *ancestor;
15268         int vertex;
15269 };
15270
15271
15272 static void unsdom_block(struct sdom_block *block)
15273 {
15274         struct sdom_block **ptr;
15275         if (!block->sdom_next) {
15276                 return;
15277         }
15278         ptr = &block->sdom->sdominates;
15279         while(*ptr) {
15280                 if ((*ptr) == block) {
15281                         *ptr = block->sdom_next;
15282                         return;
15283                 }
15284                 ptr = &(*ptr)->sdom_next;
15285         }
15286 }
15287
15288 static void sdom_block(struct sdom_block *sdom, struct sdom_block *block)
15289 {
15290         unsdom_block(block);
15291         block->sdom = sdom;
15292         block->sdom_next = sdom->sdominates;
15293         sdom->sdominates = block;
15294 }
15295
15296
15297
15298 static int initialize_sdblock(struct sdom_block *sd,
15299         struct block *parent, struct block *block, int vertex)
15300 {
15301         struct block_set *edge;
15302         if (!block || (sd[block->vertex].block == block)) {
15303                 return vertex;
15304         }
15305         vertex += 1;
15306         /* Renumber the blocks in a convinient fashion */
15307         block->vertex = vertex;
15308         sd[vertex].block    = block;
15309         sd[vertex].sdom     = &sd[vertex];
15310         sd[vertex].label    = &sd[vertex];
15311         sd[vertex].parent   = parent? &sd[parent->vertex] : 0;
15312         sd[vertex].ancestor = 0;
15313         sd[vertex].vertex   = vertex;
15314         for(edge = block->edges; edge; edge = edge->next) {
15315                 vertex = initialize_sdblock(sd, block, edge->member, vertex);
15316         }
15317         return vertex;
15318 }
15319
15320 static int initialize_spdblock(
15321         struct compile_state *state, struct sdom_block *sd,
15322         struct block *parent, struct block *block, int vertex)
15323 {
15324         struct block_set *user;
15325         if (!block || (sd[block->vertex].block == block)) {
15326                 return vertex;
15327         }
15328         vertex += 1;
15329         /* Renumber the blocks in a convinient fashion */
15330         block->vertex = vertex;
15331         sd[vertex].block    = block;
15332         sd[vertex].sdom     = &sd[vertex];
15333         sd[vertex].label    = &sd[vertex];
15334         sd[vertex].parent   = parent? &sd[parent->vertex] : 0;
15335         sd[vertex].ancestor = 0;
15336         sd[vertex].vertex   = vertex;
15337         for(user = block->use; user; user = user->next) {
15338                 vertex = initialize_spdblock(state, sd, block, user->member, vertex);
15339         }
15340         return vertex;
15341 }
15342
15343 static int setup_spdblocks(struct compile_state *state, 
15344         struct basic_blocks *bb, struct sdom_block *sd)
15345 {
15346         struct block *block;
15347         int vertex;
15348         /* Setup as many sdpblocks as possible without using fake edges */
15349         vertex = initialize_spdblock(state, sd, 0, bb->last_block, 0);
15350
15351         /* Walk through the graph and find unconnected blocks.  Add a
15352          * fake edge from the unconnected blocks to the end of the
15353          * graph. 
15354          */
15355         block = bb->first_block->last->next->u.block;
15356         for(; block && block != bb->first_block; block = block->last->next->u.block) {
15357                 if (sd[block->vertex].block == block) {
15358                         continue;
15359                 }
15360 #if DEBUG_SDP_BLOCKS
15361                 {
15362                         FILE *fp = state->errout;
15363                         fprintf(fp, "Adding %d\n", vertex +1);
15364                 }
15365 #endif
15366                 add_block_edge(block, bb->last_block, 0);
15367                 use_block(bb->last_block, block);
15368
15369                 vertex = initialize_spdblock(state, sd, bb->last_block, block, vertex);
15370         }
15371         return vertex;
15372 }
15373
15374 static void compress_ancestors(struct sdom_block *v)
15375 {
15376         /* This procedure assumes ancestor(v) != 0 */
15377         /* if (ancestor(ancestor(v)) != 0) {
15378          *      compress(ancestor(ancestor(v)));
15379          *      if (semi(label(ancestor(v))) < semi(label(v))) {
15380          *              label(v) = label(ancestor(v));
15381          *      }
15382          *      ancestor(v) = ancestor(ancestor(v));
15383          * }
15384          */
15385         if (!v->ancestor) {
15386                 return;
15387         }
15388         if (v->ancestor->ancestor) {
15389                 compress_ancestors(v->ancestor->ancestor);
15390                 if (v->ancestor->label->sdom->vertex < v->label->sdom->vertex) {
15391                         v->label = v->ancestor->label;
15392                 }
15393                 v->ancestor = v->ancestor->ancestor;
15394         }
15395 }
15396
15397 static void compute_sdom(struct compile_state *state, 
15398         struct basic_blocks *bb, struct sdom_block *sd)
15399 {
15400         int i;
15401         /* // step 2 
15402          *  for each v <= pred(w) {
15403          *      u = EVAL(v);
15404          *      if (semi[u] < semi[w] { 
15405          *              semi[w] = semi[u]; 
15406          *      } 
15407          * }
15408          * add w to bucket(vertex(semi[w]));
15409          * LINK(parent(w), w);
15410          *
15411          * // step 3
15412          * for each v <= bucket(parent(w)) {
15413          *      delete v from bucket(parent(w));
15414          *      u = EVAL(v);
15415          *      dom(v) = (semi[u] < semi[v]) ? u : parent(w);
15416          * }
15417          */
15418         for(i = bb->last_vertex; i >= 2; i--) {
15419                 struct sdom_block *v, *parent, *next;
15420                 struct block_set *user;
15421                 struct block *block;
15422                 block = sd[i].block;
15423                 parent = sd[i].parent;
15424                 /* Step 2 */
15425                 for(user = block->use; user; user = user->next) {
15426                         struct sdom_block *v, *u;
15427                         v = &sd[user->member->vertex];
15428                         u = !(v->ancestor)? v : (compress_ancestors(v), v->label);
15429                         if (u->sdom->vertex < sd[i].sdom->vertex) {
15430                                 sd[i].sdom = u->sdom;
15431                         }
15432                 }
15433                 sdom_block(sd[i].sdom, &sd[i]);
15434                 sd[i].ancestor = parent;
15435                 /* Step 3 */
15436                 for(v = parent->sdominates; v; v = next) {
15437                         struct sdom_block *u;
15438                         next = v->sdom_next;
15439                         unsdom_block(v);
15440                         u = (!v->ancestor) ? v : (compress_ancestors(v), v->label);
15441                         v->block->idom = (u->sdom->vertex < v->sdom->vertex)? 
15442                                 u->block : parent->block;
15443                 }
15444         }
15445 }
15446
15447 static void compute_spdom(struct compile_state *state, 
15448         struct basic_blocks *bb, struct sdom_block *sd)
15449 {
15450         int i;
15451         /* // step 2 
15452          *  for each v <= pred(w) {
15453          *      u = EVAL(v);
15454          *      if (semi[u] < semi[w] { 
15455          *              semi[w] = semi[u]; 
15456          *      } 
15457          * }
15458          * add w to bucket(vertex(semi[w]));
15459          * LINK(parent(w), w);
15460          *
15461          * // step 3
15462          * for each v <= bucket(parent(w)) {
15463          *      delete v from bucket(parent(w));
15464          *      u = EVAL(v);
15465          *      dom(v) = (semi[u] < semi[v]) ? u : parent(w);
15466          * }
15467          */
15468         for(i = bb->last_vertex; i >= 2; i--) {
15469                 struct sdom_block *u, *v, *parent, *next;
15470                 struct block_set *edge;
15471                 struct block *block;
15472                 block = sd[i].block;
15473                 parent = sd[i].parent;
15474                 /* Step 2 */
15475                 for(edge = block->edges; edge; edge = edge->next) {
15476                         v = &sd[edge->member->vertex];
15477                         u = !(v->ancestor)? v : (compress_ancestors(v), v->label);
15478                         if (u->sdom->vertex < sd[i].sdom->vertex) {
15479                                 sd[i].sdom = u->sdom;
15480                         }
15481                 }
15482                 sdom_block(sd[i].sdom, &sd[i]);
15483                 sd[i].ancestor = parent;
15484                 /* Step 3 */
15485                 for(v = parent->sdominates; v; v = next) {
15486                         struct sdom_block *u;
15487                         next = v->sdom_next;
15488                         unsdom_block(v);
15489                         u = (!v->ancestor) ? v : (compress_ancestors(v), v->label);
15490                         v->block->ipdom = (u->sdom->vertex < v->sdom->vertex)? 
15491                                 u->block : parent->block;
15492                 }
15493         }
15494 }
15495
15496 static void compute_idom(struct compile_state *state, 
15497         struct basic_blocks *bb, struct sdom_block *sd)
15498 {
15499         int i;
15500         for(i = 2; i <= bb->last_vertex; i++) {
15501                 struct block *block;
15502                 block = sd[i].block;
15503                 if (block->idom->vertex != sd[i].sdom->vertex) {
15504                         block->idom = block->idom->idom;
15505                 }
15506                 idom_block(block->idom, block);
15507         }
15508         sd[1].block->idom = 0;
15509 }
15510
15511 static void compute_ipdom(struct compile_state *state, 
15512         struct basic_blocks *bb, struct sdom_block *sd)
15513 {
15514         int i;
15515         for(i = 2; i <= bb->last_vertex; i++) {
15516                 struct block *block;
15517                 block = sd[i].block;
15518                 if (block->ipdom->vertex != sd[i].sdom->vertex) {
15519                         block->ipdom = block->ipdom->ipdom;
15520                 }
15521                 ipdom_block(block->ipdom, block);
15522         }
15523         sd[1].block->ipdom = 0;
15524 }
15525
15526         /* Theorem 1:
15527          *   Every vertex of a flowgraph G = (V, E, r) except r has
15528          *   a unique immediate dominator.  
15529          *   The edges {(idom(w), w) |w <= V - {r}} form a directed tree
15530          *   rooted at r, called the dominator tree of G, such that 
15531          *   v dominates w if and only if v is a proper ancestor of w in
15532          *   the dominator tree.
15533          */
15534         /* Lemma 1:  
15535          *   If v and w are vertices of G such that v <= w,
15536          *   than any path from v to w must contain a common ancestor
15537          *   of v and w in T.
15538          */
15539         /* Lemma 2:  For any vertex w != r, idom(w) -> w */
15540         /* Lemma 3:  For any vertex w != r, sdom(w) -> w */
15541         /* Lemma 4:  For any vertex w != r, idom(w) -> sdom(w) */
15542         /* Theorem 2:
15543          *   Let w != r.  Suppose every u for which sdom(w) -> u -> w satisfies
15544          *   sdom(u) >= sdom(w).  Then idom(w) = sdom(w).
15545          */
15546         /* Theorem 3:
15547          *   Let w != r and let u be a vertex for which sdom(u) is 
15548          *   minimum amoung vertices u satisfying sdom(w) -> u -> w.
15549          *   Then sdom(u) <= sdom(w) and idom(u) = idom(w).
15550          */
15551         /* Lemma 5:  Let vertices v,w satisfy v -> w.
15552          *           Then v -> idom(w) or idom(w) -> idom(v)
15553          */
15554
15555 static void find_immediate_dominators(struct compile_state *state,
15556         struct basic_blocks *bb)
15557 {
15558         struct sdom_block *sd;
15559         /* w->sdom = min{v| there is a path v = v0,v1,...,vk = w such that:
15560          *           vi > w for (1 <= i <= k - 1}
15561          */
15562         /* Theorem 4:
15563          *   For any vertex w != r.
15564          *   sdom(w) = min(
15565          *                 {v|(v,w) <= E  and v < w } U 
15566          *                 {sdom(u) | u > w and there is an edge (v, w) such that u -> v})
15567          */
15568         /* Corollary 1:
15569          *   Let w != r and let u be a vertex for which sdom(u) is 
15570          *   minimum amoung vertices u satisfying sdom(w) -> u -> w.
15571          *   Then:
15572          *                   { sdom(w) if sdom(w) = sdom(u),
15573          *        idom(w) = {
15574          *                   { idom(u) otherwise
15575          */
15576         /* The algorithm consists of the following 4 steps.
15577          * Step 1.  Carry out a depth-first search of the problem graph.  
15578          *    Number the vertices from 1 to N as they are reached during
15579          *    the search.  Initialize the variables used in succeeding steps.
15580          * Step 2.  Compute the semidominators of all vertices by applying
15581          *    theorem 4.   Carry out the computation vertex by vertex in
15582          *    decreasing order by number.
15583          * Step 3.  Implicitly define the immediate dominator of each vertex
15584          *    by applying Corollary 1.
15585          * Step 4.  Explicitly define the immediate dominator of each vertex,
15586          *    carrying out the computation vertex by vertex in increasing order
15587          *    by number.
15588          */
15589         /* Step 1 initialize the basic block information */
15590         sd = xcmalloc(sizeof(*sd) * (bb->last_vertex + 1), "sdom_state");
15591         initialize_sdblock(sd, 0, bb->first_block, 0);
15592 #if 0
15593         sd[1].size  = 0;
15594         sd[1].label = 0;
15595         sd[1].sdom  = 0;
15596 #endif
15597         /* Step 2 compute the semidominators */
15598         /* Step 3 implicitly define the immediate dominator of each vertex */
15599         compute_sdom(state, bb, sd);
15600         /* Step 4 explicitly define the immediate dominator of each vertex */
15601         compute_idom(state, bb, sd);
15602         xfree(sd);
15603 }
15604
15605 static void find_post_dominators(struct compile_state *state,
15606         struct basic_blocks *bb)
15607 {
15608         struct sdom_block *sd;
15609         int vertex;
15610         /* Step 1 initialize the basic block information */
15611         sd = xcmalloc(sizeof(*sd) * (bb->last_vertex + 1), "sdom_state");
15612
15613         vertex = setup_spdblocks(state, bb, sd);
15614         if (vertex != bb->last_vertex) {
15615                 internal_error(state, 0, "missing %d blocks",
15616                         bb->last_vertex - vertex);
15617         }
15618
15619         /* Step 2 compute the semidominators */
15620         /* Step 3 implicitly define the immediate dominator of each vertex */
15621         compute_spdom(state, bb, sd);
15622         /* Step 4 explicitly define the immediate dominator of each vertex */
15623         compute_ipdom(state, bb, sd);
15624         xfree(sd);
15625 }
15626
15627
15628
15629 static void find_block_domf(struct compile_state *state, struct block *block)
15630 {
15631         struct block *child;
15632         struct block_set *user, *edge;
15633         if (block->domfrontier != 0) {
15634                 internal_error(state, block->first, "domfrontier present?");
15635         }
15636         for(user = block->idominates; user; user = user->next) {
15637                 child = user->member;
15638                 if (child->idom != block) {
15639                         internal_error(state, block->first, "bad idom");
15640                 }
15641                 find_block_domf(state, child);
15642         }
15643         for(edge = block->edges; edge; edge = edge->next) {
15644                 if (edge->member->idom != block) {
15645                         domf_block(block, edge->member);
15646                 }
15647         }
15648         for(user = block->idominates; user; user = user->next) {
15649                 struct block_set *frontier;
15650                 child = user->member;
15651                 for(frontier = child->domfrontier; frontier; frontier = frontier->next) {
15652                         if (frontier->member->idom != block) {
15653                                 domf_block(block, frontier->member);
15654                         }
15655                 }
15656         }
15657 }
15658
15659 static void find_block_ipdomf(struct compile_state *state, struct block *block)
15660 {
15661         struct block *child;
15662         struct block_set *user;
15663         if (block->ipdomfrontier != 0) {
15664                 internal_error(state, block->first, "ipdomfrontier present?");
15665         }
15666         for(user = block->ipdominates; user; user = user->next) {
15667                 child = user->member;
15668                 if (child->ipdom != block) {
15669                         internal_error(state, block->first, "bad ipdom");
15670                 }
15671                 find_block_ipdomf(state, child);
15672         }
15673         for(user = block->use; user; user = user->next) {
15674                 if (user->member->ipdom != block) {
15675                         ipdomf_block(block, user->member);
15676                 }
15677         }
15678         for(user = block->ipdominates; user; user = user->next) {
15679                 struct block_set *frontier;
15680                 child = user->member;
15681                 for(frontier = child->ipdomfrontier; frontier; frontier = frontier->next) {
15682                         if (frontier->member->ipdom != block) {
15683                                 ipdomf_block(block, frontier->member);
15684                         }
15685                 }
15686         }
15687 }
15688
15689 static void print_dominated(
15690         struct compile_state *state, struct block *block, void *arg)
15691 {
15692         struct block_set *user;
15693         FILE *fp = arg;
15694
15695         fprintf(fp, "%d:", block->vertex);
15696         for(user = block->idominates; user; user = user->next) {
15697                 fprintf(fp, " %d", user->member->vertex);
15698                 if (user->member->idom != block) {
15699                         internal_error(state, user->member->first, "bad idom");
15700                 }
15701         }
15702         fprintf(fp,"\n");
15703 }
15704
15705 static void print_dominated2(
15706         struct compile_state *state, FILE *fp, int depth, struct block *block)
15707 {
15708         struct block_set *user;
15709         struct triple *ins;
15710         struct occurance *ptr, *ptr2;
15711         const char *filename1, *filename2;
15712         int equal_filenames;
15713         int i;
15714         for(i = 0; i < depth; i++) {
15715                 fprintf(fp, "   ");
15716         }
15717         fprintf(fp, "%3d: %p (%p - %p) @", 
15718                 block->vertex, block, block->first, block->last);
15719         ins = block->first;
15720         while(ins != block->last && (ins->occurance->line == 0)) {
15721                 ins = ins->next;
15722         }
15723         ptr = ins->occurance;
15724         ptr2 = block->last->occurance;
15725         filename1 = ptr->filename? ptr->filename : "";
15726         filename2 = ptr2->filename? ptr2->filename : "";
15727         equal_filenames = (strcmp(filename1, filename2) == 0);
15728         if ((ptr == ptr2) || (equal_filenames && ptr->line == ptr2->line)) {
15729                 fprintf(fp, " %s:%d", ptr->filename, ptr->line);
15730         } else if (equal_filenames) {
15731                 fprintf(fp, " %s:(%d - %d)",
15732                         ptr->filename, ptr->line, ptr2->line);
15733         } else {
15734                 fprintf(fp, " (%s:%d - %s:%d)",
15735                         ptr->filename, ptr->line,
15736                         ptr2->filename, ptr2->line);
15737         }
15738         fprintf(fp, "\n");
15739         for(user = block->idominates; user; user = user->next) {
15740                 print_dominated2(state, fp, depth + 1, user->member);
15741         }
15742 }
15743
15744 static void print_dominators(struct compile_state *state, FILE *fp, struct basic_blocks *bb)
15745 {
15746         fprintf(fp, "\ndominates\n");
15747         walk_blocks(state, bb, print_dominated, fp);
15748         fprintf(fp, "dominates\n");
15749         print_dominated2(state, fp, 0, bb->first_block);
15750 }
15751
15752
15753 static int print_frontiers(
15754         struct compile_state *state, FILE *fp, struct block *block, int vertex)
15755 {
15756         struct block_set *user, *edge;
15757
15758         if (!block || (block->vertex != vertex + 1)) {
15759                 return vertex;
15760         }
15761         vertex += 1;
15762
15763         fprintf(fp, "%d:", block->vertex);
15764         for(user = block->domfrontier; user; user = user->next) {
15765                 fprintf(fp, " %d", user->member->vertex);
15766         }
15767         fprintf(fp, "\n");
15768         
15769         for(edge = block->edges; edge; edge = edge->next) {
15770                 vertex = print_frontiers(state, fp, edge->member, vertex);
15771         }
15772         return vertex;
15773 }
15774 static void print_dominance_frontiers(struct compile_state *state,
15775         FILE *fp, struct basic_blocks *bb)
15776 {
15777         fprintf(fp, "\ndominance frontiers\n");
15778         print_frontiers(state, fp, bb->first_block, 0);
15779         
15780 }
15781
15782 static void analyze_idominators(struct compile_state *state, struct basic_blocks *bb)
15783 {
15784         /* Find the immediate dominators */
15785         find_immediate_dominators(state, bb);
15786         /* Find the dominance frontiers */
15787         find_block_domf(state, bb->first_block);
15788         /* If debuging print the print what I have just found */
15789         if (state->compiler->debug & DEBUG_FDOMINATORS) {
15790                 print_dominators(state, state->dbgout, bb);
15791                 print_dominance_frontiers(state, state->dbgout, bb);
15792                 print_control_flow(state, state->dbgout, bb);
15793         }
15794 }
15795
15796
15797 static void print_ipdominated(
15798         struct compile_state *state, struct block *block, void *arg)
15799 {
15800         struct block_set *user;
15801         FILE *fp = arg;
15802
15803         fprintf(fp, "%d:", block->vertex);
15804         for(user = block->ipdominates; user; user = user->next) {
15805                 fprintf(fp, " %d", user->member->vertex);
15806                 if (user->member->ipdom != block) {
15807                         internal_error(state, user->member->first, "bad ipdom");
15808                 }
15809         }
15810         fprintf(fp, "\n");
15811 }
15812
15813 static void print_ipdominators(struct compile_state *state, FILE *fp,
15814         struct basic_blocks *bb)
15815 {
15816         fprintf(fp, "\nipdominates\n");
15817         walk_blocks(state, bb, print_ipdominated, fp);
15818 }
15819
15820 static int print_pfrontiers(
15821         struct compile_state *state, FILE *fp, struct block *block, int vertex)
15822 {
15823         struct block_set *user;
15824
15825         if (!block || (block->vertex != vertex + 1)) {
15826                 return vertex;
15827         }
15828         vertex += 1;
15829
15830         fprintf(fp, "%d:", block->vertex);
15831         for(user = block->ipdomfrontier; user; user = user->next) {
15832                 fprintf(fp, " %d", user->member->vertex);
15833         }
15834         fprintf(fp, "\n");
15835         for(user = block->use; user; user = user->next) {
15836                 vertex = print_pfrontiers(state, fp, user->member, vertex);
15837         }
15838         return vertex;
15839 }
15840 static void print_ipdominance_frontiers(struct compile_state *state,
15841         FILE *fp, struct basic_blocks *bb)
15842 {
15843         fprintf(fp, "\nipdominance frontiers\n");
15844         print_pfrontiers(state, fp, bb->last_block, 0);
15845         
15846 }
15847
15848 static void analyze_ipdominators(struct compile_state *state,
15849         struct basic_blocks *bb)
15850 {
15851         /* Find the post dominators */
15852         find_post_dominators(state, bb);
15853         /* Find the control dependencies (post dominance frontiers) */
15854         find_block_ipdomf(state, bb->last_block);
15855         /* If debuging print the print what I have just found */
15856         if (state->compiler->debug & DEBUG_RDOMINATORS) {
15857                 print_ipdominators(state, state->dbgout, bb);
15858                 print_ipdominance_frontiers(state, state->dbgout, bb);
15859                 print_control_flow(state, state->dbgout, bb);
15860         }
15861 }
15862
15863 static int bdominates(struct compile_state *state,
15864         struct block *dom, struct block *sub)
15865 {
15866         while(sub && (sub != dom)) {
15867                 sub = sub->idom;
15868         }
15869         return sub == dom;
15870 }
15871
15872 static int tdominates(struct compile_state *state,
15873         struct triple *dom, struct triple *sub)
15874 {
15875         struct block *bdom, *bsub;
15876         int result;
15877         bdom = block_of_triple(state, dom);
15878         bsub = block_of_triple(state, sub);
15879         if (bdom != bsub) {
15880                 result = bdominates(state, bdom, bsub);
15881         } 
15882         else {
15883                 struct triple *ins;
15884                 if (!bdom || !bsub) {
15885                         internal_error(state, dom, "huh?");
15886                 }
15887                 ins = sub;
15888                 while((ins != bsub->first) && (ins != dom)) {
15889                         ins = ins->prev;
15890                 }
15891                 result = (ins == dom);
15892         }
15893         return result;
15894 }
15895
15896 static void analyze_basic_blocks(
15897         struct compile_state *state, struct basic_blocks *bb)
15898 {
15899         setup_basic_blocks(state, bb);
15900         analyze_idominators(state, bb);
15901         analyze_ipdominators(state, bb);
15902 }
15903
15904 static void insert_phi_operations(struct compile_state *state)
15905 {
15906         size_t size;
15907         struct triple *first;
15908         int *has_already, *work;
15909         struct block *work_list, **work_list_tail;
15910         int iter;
15911         struct triple *var, *vnext;
15912
15913         size = sizeof(int) * (state->bb.last_vertex + 1);
15914         has_already = xcmalloc(size, "has_already");
15915         work =        xcmalloc(size, "work");
15916         iter = 0;
15917
15918         first = state->first;
15919         for(var = first->next; var != first ; var = vnext) {
15920                 struct block *block;
15921                 struct triple_set *user, *unext;
15922                 vnext = var->next;
15923
15924                 if (!triple_is_auto_var(state, var) || !var->use) {
15925                         continue;
15926                 }
15927                         
15928                 iter += 1;
15929                 work_list = 0;
15930                 work_list_tail = &work_list;
15931                 for(user = var->use; user; user = unext) {
15932                         unext = user->next;
15933                         if (MISC(var, 0) == user->member) {
15934                                 continue;
15935                         }
15936                         if (user->member->op == OP_READ) {
15937                                 continue;
15938                         }
15939                         if (user->member->op != OP_WRITE) {
15940                                 internal_error(state, user->member, 
15941                                         "bad variable access");
15942                         }
15943                         block = user->member->u.block;
15944                         if (!block) {
15945                                 warning(state, user->member, "dead code");
15946                                 release_triple(state, user->member);
15947                                 continue;
15948                         }
15949                         if (work[block->vertex] >= iter) {
15950                                 continue;
15951                         }
15952                         work[block->vertex] = iter;
15953                         *work_list_tail = block;
15954                         block->work_next = 0;
15955                         work_list_tail = &block->work_next;
15956                 }
15957                 for(block = work_list; block; block = block->work_next) {
15958                         struct block_set *df;
15959                         for(df = block->domfrontier; df; df = df->next) {
15960                                 struct triple *phi;
15961                                 struct block *front;
15962                                 int in_edges;
15963                                 front = df->member;
15964
15965                                 if (has_already[front->vertex] >= iter) {
15966                                         continue;
15967                                 }
15968                                 /* Count how many edges flow into this block */
15969                                 in_edges = front->users;
15970                                 /* Insert a phi function for this variable */
15971                                 get_occurance(var->occurance);
15972                                 phi = alloc_triple(
15973                                         state, OP_PHI, var->type, -1, in_edges, 
15974                                         var->occurance);
15975                                 phi->u.block = front;
15976                                 MISC(phi, 0) = var;
15977                                 use_triple(var, phi);
15978 #if 1
15979                                 if (phi->rhs != in_edges) {
15980                                         internal_error(state, phi, "phi->rhs: %d != in_edges: %d",
15981                                                 phi->rhs, in_edges);
15982                                 }
15983 #endif
15984                                 /* Insert the phi functions immediately after the label */
15985                                 insert_triple(state, front->first->next, phi);
15986                                 if (front->first == front->last) {
15987                                         front->last = front->first->next;
15988                                 }
15989                                 has_already[front->vertex] = iter;
15990                                 transform_to_arch_instruction(state, phi);
15991
15992                                 /* If necessary plan to visit the basic block */
15993                                 if (work[front->vertex] >= iter) {
15994                                         continue;
15995                                 }
15996                                 work[front->vertex] = iter;
15997                                 *work_list_tail = front;
15998                                 front->work_next = 0;
15999                                 work_list_tail = &front->work_next;
16000                         }
16001                 }
16002         }
16003         xfree(has_already);
16004         xfree(work);
16005 }
16006
16007
16008 struct stack {
16009         struct triple_set *top;
16010         unsigned orig_id;
16011 };
16012
16013 static int count_auto_vars(struct compile_state *state)
16014 {
16015         struct triple *first, *ins;
16016         int auto_vars = 0;
16017         first = state->first;
16018         ins = first;
16019         do {
16020                 if (triple_is_auto_var(state, ins)) {
16021                         auto_vars += 1;
16022                 }
16023                 ins = ins->next;
16024         } while(ins != first);
16025         return auto_vars;
16026 }
16027
16028 static void number_auto_vars(struct compile_state *state, struct stack *stacks)
16029 {
16030         struct triple *first, *ins;
16031         int auto_vars = 0;
16032         first = state->first;
16033         ins = first;
16034         do {
16035                 if (triple_is_auto_var(state, ins)) {
16036                         auto_vars += 1;
16037                         stacks[auto_vars].orig_id = ins->id;
16038                         ins->id = auto_vars;
16039                 }
16040                 ins = ins->next;
16041         } while(ins != first);
16042 }
16043
16044 static void restore_auto_vars(struct compile_state *state, struct stack *stacks)
16045 {
16046         struct triple *first, *ins;
16047         first = state->first;
16048         ins = first;
16049         do {
16050                 if (triple_is_auto_var(state, ins)) {
16051                         ins->id = stacks[ins->id].orig_id;
16052                 }
16053                 ins = ins->next;
16054         } while(ins != first);
16055 }
16056
16057 static struct triple *peek_triple(struct stack *stacks, struct triple *var)
16058 {
16059         struct triple_set *head;
16060         struct triple *top_val;
16061         top_val = 0;
16062         head = stacks[var->id].top;
16063         if (head) {
16064                 top_val = head->member;
16065         }
16066         return top_val;
16067 }
16068
16069 static void push_triple(struct stack *stacks, struct triple *var, struct triple *val)
16070 {
16071         struct triple_set *new;
16072         /* Append new to the head of the list,
16073          * it's the only sensible behavoir for a stack.
16074          */
16075         new = xcmalloc(sizeof(*new), "triple_set");
16076         new->member = val;
16077         new->next   = stacks[var->id].top;
16078         stacks[var->id].top = new;
16079 }
16080
16081 static void pop_triple(struct stack *stacks, struct triple *var, struct triple *oldval)
16082 {
16083         struct triple_set *set, **ptr;
16084         ptr = &stacks[var->id].top;
16085         while(*ptr) {
16086                 set = *ptr;
16087                 if (set->member == oldval) {
16088                         *ptr = set->next;
16089                         xfree(set);
16090                         /* Only free one occurance from the stack */
16091                         return;
16092                 }
16093                 else {
16094                         ptr = &set->next;
16095                 }
16096         }
16097 }
16098
16099 /*
16100  * C(V)
16101  * S(V)
16102  */
16103 static void fixup_block_phi_variables(
16104         struct compile_state *state, struct stack *stacks, struct block *parent, struct block *block)
16105 {
16106         struct block_set *set;
16107         struct triple *ptr;
16108         int edge;
16109         if (!parent || !block)
16110                 return;
16111         /* Find the edge I am coming in on */
16112         edge = 0;
16113         for(set = block->use; set; set = set->next, edge++) {
16114                 if (set->member == parent) {
16115                         break;
16116                 }
16117         }
16118         if (!set) {
16119                 internal_error(state, 0, "phi input is not on a control predecessor");
16120         }
16121         for(ptr = block->first; ; ptr = ptr->next) {
16122                 if (ptr->op == OP_PHI) {
16123                         struct triple *var, *val, **slot;
16124                         var = MISC(ptr, 0);
16125                         if (!var) {
16126                                 internal_error(state, ptr, "no var???");
16127                         }
16128                         /* Find the current value of the variable */
16129                         val = peek_triple(stacks, var);
16130                         if (val && ((val->op == OP_WRITE) || (val->op == OP_READ))) {
16131                                 internal_error(state, val, "bad value in phi");
16132                         }
16133                         if (edge >= ptr->rhs) {
16134                                 internal_error(state, ptr, "edges > phi rhs");
16135                         }
16136                         slot = &RHS(ptr, edge);
16137                         if ((*slot != 0) && (*slot != val)) {
16138                                 internal_error(state, ptr, "phi already bound on this edge");
16139                         }
16140                         *slot = val;
16141                         use_triple(val, ptr);
16142                 }
16143                 if (ptr == block->last) {
16144                         break;
16145                 }
16146         }
16147 }
16148
16149
16150 static void rename_block_variables(
16151         struct compile_state *state, struct stack *stacks, struct block *block)
16152 {
16153         struct block_set *user, *edge;
16154         struct triple *ptr, *next, *last;
16155         int done;
16156         if (!block)
16157                 return;
16158         last = block->first;
16159         done = 0;
16160         for(ptr = block->first; !done; ptr = next) {
16161                 next = ptr->next;
16162                 if (ptr == block->last) {
16163                         done = 1;
16164                 }
16165                 /* RHS(A) */
16166                 if (ptr->op == OP_READ) {
16167                         struct triple *var, *val;
16168                         var = RHS(ptr, 0);
16169                         if (!triple_is_auto_var(state, var)) {
16170                                 internal_error(state, ptr, "read of non auto var!");
16171                         }
16172                         unuse_triple(var, ptr);
16173                         /* Find the current value of the variable */
16174                         val = peek_triple(stacks, var);
16175                         if (!val) {
16176                                 /* Let the optimizer at variables that are not initially
16177                                  * set.  But give it a bogus value so things seem to
16178                                  * work by accident.  This is useful for bitfields because
16179                                  * setting them always involves a read-modify-write.
16180                                  */
16181                                 if (TYPE_ARITHMETIC(ptr->type->type)) {
16182                                         val = pre_triple(state, ptr, OP_INTCONST, ptr->type, 0, 0);
16183                                         val->u.cval = 0xdeadbeaf;
16184                                 } else {
16185                                         val = pre_triple(state, ptr, OP_UNKNOWNVAL, ptr->type, 0, 0);
16186                                 }
16187                         }
16188                         if (!val) {
16189                                 error(state, ptr, "variable used without being set");
16190                         }
16191                         if ((val->op == OP_WRITE) || (val->op == OP_READ)) {
16192                                 internal_error(state, val, "bad value in read");
16193                         }
16194                         propogate_use(state, ptr, val);
16195                         release_triple(state, ptr);
16196                         continue;
16197                 }
16198                 /* LHS(A) */
16199                 if (ptr->op == OP_WRITE) {
16200                         struct triple *var, *val, *tval;
16201                         var = MISC(ptr, 0);
16202                         if (!triple_is_auto_var(state, var)) {
16203                                 internal_error(state, ptr, "write to non auto var!");
16204                         }
16205                         tval = val = RHS(ptr, 0);
16206                         if ((val->op == OP_WRITE) || (val->op == OP_READ) ||
16207                                 triple_is_auto_var(state, val)) {
16208                                 internal_error(state, ptr, "bad value in write");
16209                         }
16210                         /* Insert a cast if the types differ */
16211                         if (!is_subset_type(ptr->type, val->type)) {
16212                                 if (val->op == OP_INTCONST) {
16213                                         tval = pre_triple(state, ptr, OP_INTCONST, ptr->type, 0, 0);
16214                                         tval->u.cval = val->u.cval;
16215                                 }
16216                                 else {
16217                                         tval = pre_triple(state, ptr, OP_CONVERT, ptr->type, val, 0);
16218                                         use_triple(val, tval);
16219                                 }
16220                                 transform_to_arch_instruction(state, tval);
16221                                 unuse_triple(val, ptr);
16222                                 RHS(ptr, 0) = tval;
16223                                 use_triple(tval, ptr);
16224                         }
16225                         propogate_use(state, ptr, tval);
16226                         unuse_triple(var, ptr);
16227                         /* Push OP_WRITE ptr->right onto a stack of variable uses */
16228                         push_triple(stacks, var, tval);
16229                 }
16230                 if (ptr->op == OP_PHI) {
16231                         struct triple *var;
16232                         var = MISC(ptr, 0);
16233                         if (!triple_is_auto_var(state, var)) {
16234                                 internal_error(state, ptr, "phi references non auto var!");
16235                         }
16236                         /* Push OP_PHI onto a stack of variable uses */
16237                         push_triple(stacks, var, ptr);
16238                 }
16239                 last = ptr;
16240         }
16241         block->last = last;
16242
16243         /* Fixup PHI functions in the cf successors */
16244         for(edge = block->edges; edge; edge = edge->next) {
16245                 fixup_block_phi_variables(state, stacks, block, edge->member);
16246         }
16247         /* rename variables in the dominated nodes */
16248         for(user = block->idominates; user; user = user->next) {
16249                 rename_block_variables(state, stacks, user->member);
16250         }
16251         /* pop the renamed variable stack */
16252         last = block->first;
16253         done = 0;
16254         for(ptr = block->first; !done ; ptr = next) {
16255                 next = ptr->next;
16256                 if (ptr == block->last) {
16257                         done = 1;
16258                 }
16259                 if (ptr->op == OP_WRITE) {
16260                         struct triple *var;
16261                         var = MISC(ptr, 0);
16262                         /* Pop OP_WRITE ptr->right from the stack of variable uses */
16263                         pop_triple(stacks, var, RHS(ptr, 0));
16264                         release_triple(state, ptr);
16265                         continue;
16266                 }
16267                 if (ptr->op == OP_PHI) {
16268                         struct triple *var;
16269                         var = MISC(ptr, 0);
16270                         /* Pop OP_WRITE ptr->right from the stack of variable uses */
16271                         pop_triple(stacks, var, ptr);
16272                 }
16273                 last = ptr;
16274         }
16275         block->last = last;
16276 }
16277
16278 static void rename_variables(struct compile_state *state)
16279 {
16280         struct stack *stacks;
16281         int auto_vars;
16282
16283         /* Allocate stacks for the Variables */
16284         auto_vars = count_auto_vars(state);
16285         stacks = xcmalloc(sizeof(stacks[0])*(auto_vars + 1), "auto var stacks");
16286
16287         /* Give each auto_var a stack */
16288         number_auto_vars(state, stacks);
16289
16290         /* Rename the variables */
16291         rename_block_variables(state, stacks, state->bb.first_block);
16292
16293         /* Remove the stacks from the auto_vars */
16294         restore_auto_vars(state, stacks);
16295         xfree(stacks);
16296 }
16297
16298 static void prune_block_variables(struct compile_state *state,
16299         struct block *block)
16300 {
16301         struct block_set *user;
16302         struct triple *next, *ptr;
16303         int done;
16304
16305         done = 0;
16306         for(ptr = block->first; !done; ptr = next) {
16307                 /* Be extremely careful I am deleting the list
16308                  * as I walk trhough it.
16309                  */
16310                 next = ptr->next;
16311                 if (ptr == block->last) {
16312                         done = 1;
16313                 }
16314                 if (triple_is_auto_var(state, ptr)) {
16315                         struct triple_set *user, *next;
16316                         for(user = ptr->use; user; user = next) {
16317                                 struct triple *use;
16318                                 next = user->next;
16319                                 use = user->member;
16320                                 if (MISC(ptr, 0) == user->member) {
16321                                         continue;
16322                                 }
16323                                 if (use->op != OP_PHI) {
16324                                         internal_error(state, use, "decl still used");
16325                                 }
16326                                 if (MISC(use, 0) != ptr) {
16327                                         internal_error(state, use, "bad phi use of decl");
16328                                 }
16329                                 unuse_triple(ptr, use);
16330                                 MISC(use, 0) = 0;
16331                         }
16332                         if ((ptr->u.cval == 0) && (MISC(ptr, 0)->lhs == 1)) {
16333                                 /* Delete the adecl */
16334                                 release_triple(state, MISC(ptr, 0));
16335                                 /* And the piece */
16336                                 release_triple(state, ptr);
16337                         }
16338                         continue;
16339                 }
16340         }
16341         for(user = block->idominates; user; user = user->next) {
16342                 prune_block_variables(state, user->member);
16343         }
16344 }
16345
16346 struct phi_triple {
16347         struct triple *phi;
16348         unsigned orig_id;
16349         int alive;
16350 };
16351
16352 static void keep_phi(struct compile_state *state, struct phi_triple *live, struct triple *phi)
16353 {
16354         struct triple **slot;
16355         int zrhs, i;
16356         if (live[phi->id].alive) {
16357                 return;
16358         }
16359         live[phi->id].alive = 1;
16360         zrhs = phi->rhs;
16361         slot = &RHS(phi, 0);
16362         for(i = 0; i < zrhs; i++) {
16363                 struct triple *used;
16364                 used = slot[i];
16365                 if (used && (used->op == OP_PHI)) {
16366                         keep_phi(state, live, used);
16367                 }
16368         }
16369 }
16370
16371 static void prune_unused_phis(struct compile_state *state)
16372 {
16373         struct triple *first, *phi;
16374         struct phi_triple *live;
16375         int phis, i;
16376         
16377         /* Find the first instruction */
16378         first = state->first;
16379
16380         /* Count how many phi functions I need to process */
16381         phis = 0;
16382         for(phi = first->next; phi != first; phi = phi->next) {
16383                 if (phi->op == OP_PHI) {
16384                         phis += 1;
16385                 }
16386         }
16387         
16388         /* Mark them all dead */
16389         live = xcmalloc(sizeof(*live) * (phis + 1), "phi_triple");
16390         phis = 0;
16391         for(phi = first->next; phi != first; phi = phi->next) {
16392                 if (phi->op != OP_PHI) {
16393                         continue;
16394                 }
16395                 live[phis].alive   = 0;
16396                 live[phis].orig_id = phi->id;
16397                 live[phis].phi     = phi;
16398                 phi->id = phis;
16399                 phis += 1;
16400         }
16401         
16402         /* Mark phis alive that are used by non phis */
16403         for(i = 0; i < phis; i++) {
16404                 struct triple_set *set;
16405                 for(set = live[i].phi->use; !live[i].alive && set; set = set->next) {
16406                         if (set->member->op != OP_PHI) {
16407                                 keep_phi(state, live, live[i].phi);
16408                                 break;
16409                         }
16410                 }
16411         }
16412
16413         /* Delete the extraneous phis */
16414         for(i = 0; i < phis; i++) {
16415                 struct triple **slot;
16416                 int zrhs, j;
16417                 if (!live[i].alive) {
16418                         release_triple(state, live[i].phi);
16419                         continue;
16420                 }
16421                 phi = live[i].phi;
16422                 slot = &RHS(phi, 0);
16423                 zrhs = phi->rhs;
16424                 for(j = 0; j < zrhs; j++) {
16425                         if(!slot[j]) {
16426                                 struct triple *unknown;
16427                                 get_occurance(phi->occurance);
16428                                 unknown = flatten(state, state->global_pool,
16429                                         alloc_triple(state, OP_UNKNOWNVAL,
16430                                                 phi->type, 0, 0, phi->occurance));
16431                                 slot[j] = unknown;
16432                                 use_triple(unknown, phi);
16433                                 transform_to_arch_instruction(state, unknown);
16434 #if 0                           
16435                                 warning(state, phi, "variable not set at index %d on all paths to use", j);
16436 #endif
16437                         }
16438                 }
16439         }
16440         xfree(live);
16441 }
16442
16443 static void transform_to_ssa_form(struct compile_state *state)
16444 {
16445         insert_phi_operations(state);
16446         rename_variables(state);
16447
16448         prune_block_variables(state, state->bb.first_block);
16449         prune_unused_phis(state);
16450
16451         print_blocks(state, __func__, state->dbgout);
16452 }
16453
16454
16455 static void clear_vertex(
16456         struct compile_state *state, struct block *block, void *arg)
16457 {
16458         /* Clear the current blocks vertex and the vertex of all
16459          * of the current blocks neighbors in case there are malformed
16460          * blocks with now instructions at this point.
16461          */
16462         struct block_set *user, *edge;
16463         block->vertex = 0;
16464         for(edge = block->edges; edge; edge = edge->next) {
16465                 edge->member->vertex = 0;
16466         }
16467         for(user = block->use; user; user = user->next) {
16468                 user->member->vertex = 0;
16469         }
16470 }
16471
16472 static void mark_live_block(
16473         struct compile_state *state, struct block *block, int *next_vertex)
16474 {
16475         /* See if this is a block that has not been marked */
16476         if (block->vertex != 0) {
16477                 return;
16478         }
16479         block->vertex = *next_vertex;
16480         *next_vertex += 1;
16481         if (triple_is_branch(state, block->last)) {
16482                 struct triple **targ;
16483                 targ = triple_edge_targ(state, block->last, 0);
16484                 for(; targ; targ = triple_edge_targ(state, block->last, targ)) {
16485                         if (!*targ) {
16486                                 continue;
16487                         }
16488                         if (!triple_stores_block(state, *targ)) {
16489                                 internal_error(state, 0, "bad targ");
16490                         }
16491                         mark_live_block(state, (*targ)->u.block, next_vertex);
16492                 }
16493                 /* Ensure the last block of a function remains alive */
16494                 if (triple_is_call(state, block->last)) {
16495                         mark_live_block(state, MISC(block->last, 0)->u.block, next_vertex);
16496                 }
16497         }
16498         else if (block->last->next != state->first) {
16499                 struct triple *ins;
16500                 ins = block->last->next;
16501                 if (!triple_stores_block(state, ins)) {
16502                         internal_error(state, 0, "bad block start");
16503                 }
16504                 mark_live_block(state, ins->u.block, next_vertex);
16505         }
16506 }
16507
16508 static void transform_from_ssa_form(struct compile_state *state)
16509 {
16510         /* To get out of ssa form we insert moves on the incoming
16511          * edges to blocks containting phi functions.
16512          */
16513         struct triple *first;
16514         struct triple *phi, *var, *next;
16515         int next_vertex;
16516
16517         /* Walk the control flow to see which blocks remain alive */
16518         walk_blocks(state, &state->bb, clear_vertex, 0);
16519         next_vertex = 1;
16520         mark_live_block(state, state->bb.first_block, &next_vertex);
16521
16522         /* Walk all of the operations to find the phi functions */
16523         first = state->first;
16524         for(phi = first->next; phi != first ; phi = next) {
16525                 struct block_set *set;
16526                 struct block *block;
16527                 struct triple **slot;
16528                 struct triple *var;
16529                 struct triple_set *use, *use_next;
16530                 int edge, writers, readers;
16531                 next = phi->next;
16532                 if (phi->op != OP_PHI) {
16533                         continue;
16534                 }
16535
16536                 block = phi->u.block;
16537                 slot  = &RHS(phi, 0);
16538
16539                 /* If this phi is in a dead block just forget it */
16540                 if (block->vertex == 0) {
16541                         release_triple(state, phi);
16542                         continue;
16543                 }
16544
16545                 /* Forget uses from code in dead blocks */
16546                 for(use = phi->use; use; use = use_next) {
16547                         struct block *ublock;
16548                         struct triple **expr;
16549                         use_next = use->next;
16550                         ublock = block_of_triple(state, use->member);
16551                         if ((use->member == phi) || (ublock->vertex != 0)) {
16552                                 continue;
16553                         }
16554                         expr = triple_rhs(state, use->member, 0);
16555                         for(; expr; expr = triple_rhs(state, use->member, expr)) {
16556                                 if (*expr == phi) {
16557                                         *expr = 0;
16558                                 }
16559                         }
16560                         unuse_triple(phi, use->member);
16561                 }
16562                 /* A variable to replace the phi function */
16563                 if (registers_of(state, phi->type) != 1) {
16564                         internal_error(state, phi, "phi->type does not fit in a single register!");
16565                 }
16566                 var = post_triple(state, phi, OP_ADECL, phi->type, 0, 0);
16567                 var = var->next; /* point at the var */
16568                         
16569                 /* Replaces use of phi with var */
16570                 propogate_use(state, phi, var);
16571
16572                 /* Count the readers */
16573                 readers = 0;
16574                 for(use = var->use; use; use = use->next) {
16575                         if (use->member != MISC(var, 0)) {
16576                                 readers++;
16577                         }
16578                 }
16579
16580                 /* Walk all of the incoming edges/blocks and insert moves.
16581                  */
16582                 writers = 0;
16583                 for(edge = 0, set = block->use; set; set = set->next, edge++) {
16584                         struct block *eblock, *vblock;
16585                         struct triple *move;
16586                         struct triple *val, *base;
16587                         eblock = set->member;
16588                         val = slot[edge];
16589                         slot[edge] = 0;
16590                         unuse_triple(val, phi);
16591                         vblock = block_of_triple(state, val);
16592
16593                         /* If we don't have a value that belongs in an OP_WRITE
16594                          * continue on.
16595                          */
16596                         if (!val || (val == &unknown_triple) || (val == phi)
16597                                 || (vblock && (vblock->vertex == 0))) {
16598                                 continue;
16599                         }
16600                         /* If the value should never occur error */
16601                         if (!vblock) {
16602                                 internal_error(state, val, "no vblock?");
16603                                 continue;
16604                         }
16605
16606                         /* If the value occurs in a dead block see if a replacement
16607                          * block can be found.
16608                          */
16609                         while(eblock && (eblock->vertex == 0)) {
16610                                 eblock = eblock->idom;
16611                         }
16612                         /* If not continue on with the next value. */
16613                         if (!eblock || (eblock->vertex == 0)) {
16614                                 continue;
16615                         }
16616
16617                         /* If we have an empty incoming block ignore it. */
16618                         if (!eblock->first) {
16619                                 internal_error(state, 0, "empty block?");
16620                         }
16621                         
16622                         /* Make certain the write is placed in the edge block... */
16623                         /* Walk through the edge block backwards to find an
16624                          * appropriate location for the OP_WRITE.
16625                          */
16626                         for(base = eblock->last; base != eblock->first; base = base->prev) {
16627                                 struct triple **expr;
16628                                 if (base->op == OP_PIECE) {
16629                                         base = MISC(base, 0);
16630                                 }
16631                                 if ((base == var) || (base == val)) {
16632                                         goto out;
16633                                 }
16634                                 expr = triple_lhs(state, base, 0);
16635                                 for(; expr; expr = triple_lhs(state, base, expr)) {
16636                                         if ((*expr) == val) {
16637                                                 goto out;
16638                                         }
16639                                 }
16640                                 expr = triple_rhs(state, base, 0);
16641                                 for(; expr; expr = triple_rhs(state, base, expr)) {
16642                                         if ((*expr) == var) {
16643                                                 goto out;
16644                                         }
16645                                 }
16646                         }
16647                 out:
16648                         if (triple_is_branch(state, base)) {
16649                                 internal_error(state, base,
16650                                         "Could not insert write to phi");
16651                         }
16652                         move = post_triple(state, base, OP_WRITE, var->type, val, var);
16653                         use_triple(val, move);
16654                         use_triple(var, move);
16655                         writers++;
16656                 }
16657                 if (!writers && readers) {
16658                         internal_error(state, var, "no value written to in use phi?");
16659                 }
16660                 /* If var is not used free it */
16661                 if (!writers) {
16662                         release_triple(state, MISC(var, 0));
16663                         release_triple(state, var);
16664                 }
16665                 /* Release the phi function */
16666                 release_triple(state, phi);
16667         }
16668         
16669         /* Walk all of the operations to find the adecls */
16670         for(var = first->next; var != first ; var = var->next) {
16671                 struct triple_set *use, *use_next;
16672                 if (!triple_is_auto_var(state, var)) {
16673                         continue;
16674                 }
16675
16676                 /* Walk through all of the rhs uses of var and
16677                  * replace them with read of var.
16678                  */
16679                 for(use = var->use; use; use = use_next) {
16680                         struct triple *read, *user;
16681                         struct triple **slot;
16682                         int zrhs, i, used;
16683                         use_next = use->next;
16684                         user = use->member;
16685                         
16686                         /* Generate a read of var */
16687                         read = pre_triple(state, user, OP_READ, var->type, var, 0);
16688                         use_triple(var, read);
16689
16690                         /* Find the rhs uses and see if they need to be replaced */
16691                         used = 0;
16692                         zrhs = user->rhs;
16693                         slot = &RHS(user, 0);
16694                         for(i = 0; i < zrhs; i++) {
16695                                 if (slot[i] == var) {
16696                                         slot[i] = read;
16697                                         used = 1;
16698                                 }
16699                         }
16700                         /* If we did use it cleanup the uses */
16701                         if (used) {
16702                                 unuse_triple(var, user);
16703                                 use_triple(read, user);
16704                         } 
16705                         /* If we didn't use it release the extra triple */
16706                         else {
16707                                 release_triple(state, read);
16708                         }
16709                 }
16710         }
16711 }
16712
16713 #define HI() if (state->compiler->debug & DEBUG_REBUILD_SSA_FORM) { \
16714         FILE *fp = state->dbgout; \
16715         fprintf(fp, "@ %s:%d\n", __FILE__, __LINE__); romcc_print_blocks(state, fp); \
16716         } 
16717
16718 static void rebuild_ssa_form(struct compile_state *state)
16719 {
16720 HI();
16721         transform_from_ssa_form(state);
16722 HI();
16723         state->bb.first = state->first;
16724         free_basic_blocks(state, &state->bb);
16725         analyze_basic_blocks(state, &state->bb);
16726 HI();
16727         insert_phi_operations(state);
16728 HI();
16729         rename_variables(state);
16730 HI();
16731         
16732         prune_block_variables(state, state->bb.first_block);
16733 HI();
16734         prune_unused_phis(state);
16735 HI();
16736 }
16737 #undef HI
16738
16739 /* 
16740  * Register conflict resolution
16741  * =========================================================
16742  */
16743
16744 static struct reg_info find_def_color(
16745         struct compile_state *state, struct triple *def)
16746 {
16747         struct triple_set *set;
16748         struct reg_info info;
16749         info.reg = REG_UNSET;
16750         info.regcm = 0;
16751         if (!triple_is_def(state, def)) {
16752                 return info;
16753         }
16754         info = arch_reg_lhs(state, def, 0);
16755         if (info.reg >= MAX_REGISTERS) {
16756                 info.reg = REG_UNSET;
16757         }
16758         for(set = def->use; set; set = set->next) {
16759                 struct reg_info tinfo;
16760                 int i;
16761                 i = find_rhs_use(state, set->member, def);
16762                 if (i < 0) {
16763                         continue;
16764                 }
16765                 tinfo = arch_reg_rhs(state, set->member, i);
16766                 if (tinfo.reg >= MAX_REGISTERS) {
16767                         tinfo.reg = REG_UNSET;
16768                 }
16769                 if ((tinfo.reg != REG_UNSET) && 
16770                         (info.reg != REG_UNSET) &&
16771                         (tinfo.reg != info.reg)) {
16772                         internal_error(state, def, "register conflict");
16773                 }
16774                 if ((info.regcm & tinfo.regcm) == 0) {
16775                         internal_error(state, def, "regcm conflict %x & %x == 0",
16776                                 info.regcm, tinfo.regcm);
16777                 }
16778                 if (info.reg == REG_UNSET) {
16779                         info.reg = tinfo.reg;
16780                 }
16781                 info.regcm &= tinfo.regcm;
16782         }
16783         if (info.reg >= MAX_REGISTERS) {
16784                 internal_error(state, def, "register out of range");
16785         }
16786         return info;
16787 }
16788
16789 static struct reg_info find_lhs_pre_color(
16790         struct compile_state *state, struct triple *ins, int index)
16791 {
16792         struct reg_info info;
16793         int zlhs, zrhs, i;
16794         zrhs = ins->rhs;
16795         zlhs = ins->lhs;
16796         if (!zlhs && triple_is_def(state, ins)) {
16797                 zlhs = 1;
16798         }
16799         if (index >= zlhs) {
16800                 internal_error(state, ins, "Bad lhs %d", index);
16801         }
16802         info = arch_reg_lhs(state, ins, index);
16803         for(i = 0; i < zrhs; i++) {
16804                 struct reg_info rinfo;
16805                 rinfo = arch_reg_rhs(state, ins, i);
16806                 if ((info.reg == rinfo.reg) &&
16807                         (rinfo.reg >= MAX_REGISTERS)) {
16808                         struct reg_info tinfo;
16809                         tinfo = find_lhs_pre_color(state, RHS(ins, index), 0);
16810                         info.reg = tinfo.reg;
16811                         info.regcm &= tinfo.regcm;
16812                         break;
16813                 }
16814         }
16815         if (info.reg >= MAX_REGISTERS) {
16816                 info.reg = REG_UNSET;
16817         }
16818         return info;
16819 }
16820
16821 static struct reg_info find_rhs_post_color(
16822         struct compile_state *state, struct triple *ins, int index);
16823
16824 static struct reg_info find_lhs_post_color(
16825         struct compile_state *state, struct triple *ins, int index)
16826 {
16827         struct triple_set *set;
16828         struct reg_info info;
16829         struct triple *lhs;
16830 #if DEBUG_TRIPLE_COLOR
16831         fprintf(state->errout, "find_lhs_post_color(%p, %d)\n",
16832                 ins, index);
16833 #endif
16834         if ((index == 0) && triple_is_def(state, ins)) {
16835                 lhs = ins;
16836         }
16837         else if (index < ins->lhs) {
16838                 lhs = LHS(ins, index);
16839         }
16840         else {
16841                 internal_error(state, ins, "Bad lhs %d", index);
16842                 lhs = 0;
16843         }
16844         info = arch_reg_lhs(state, ins, index);
16845         if (info.reg >= MAX_REGISTERS) {
16846                 info.reg = REG_UNSET;
16847         }
16848         for(set = lhs->use; set; set = set->next) {
16849                 struct reg_info rinfo;
16850                 struct triple *user;
16851                 int zrhs, i;
16852                 user = set->member;
16853                 zrhs = user->rhs;
16854                 for(i = 0; i < zrhs; i++) {
16855                         if (RHS(user, i) != lhs) {
16856                                 continue;
16857                         }
16858                         rinfo = find_rhs_post_color(state, user, i);
16859                         if ((info.reg != REG_UNSET) &&
16860                                 (rinfo.reg != REG_UNSET) &&
16861                                 (info.reg != rinfo.reg)) {
16862                                 internal_error(state, ins, "register conflict");
16863                         }
16864                         if ((info.regcm & rinfo.regcm) == 0) {
16865                                 internal_error(state, ins, "regcm conflict %x & %x == 0",
16866                                         info.regcm, rinfo.regcm);
16867                         }
16868                         if (info.reg == REG_UNSET) {
16869                                 info.reg = rinfo.reg;
16870                         }
16871                         info.regcm &= rinfo.regcm;
16872                 }
16873         }
16874 #if DEBUG_TRIPLE_COLOR
16875         fprintf(state->errout, "find_lhs_post_color(%p, %d) -> ( %d, %x)\n",
16876                 ins, index, info.reg, info.regcm);
16877 #endif
16878         return info;
16879 }
16880
16881 static struct reg_info find_rhs_post_color(
16882         struct compile_state *state, struct triple *ins, int index)
16883 {
16884         struct reg_info info, rinfo;
16885         int zlhs, i;
16886 #if DEBUG_TRIPLE_COLOR
16887         fprintf(state->errout, "find_rhs_post_color(%p, %d)\n",
16888                 ins, index);
16889 #endif
16890         rinfo = arch_reg_rhs(state, ins, index);
16891         zlhs = ins->lhs;
16892         if (!zlhs && triple_is_def(state, ins)) {
16893                 zlhs = 1;
16894         }
16895         info = rinfo;
16896         if (info.reg >= MAX_REGISTERS) {
16897                 info.reg = REG_UNSET;
16898         }
16899         for(i = 0; i < zlhs; i++) {
16900                 struct reg_info linfo;
16901                 linfo = arch_reg_lhs(state, ins, i);
16902                 if ((linfo.reg == rinfo.reg) &&
16903                         (linfo.reg >= MAX_REGISTERS)) {
16904                         struct reg_info tinfo;
16905                         tinfo = find_lhs_post_color(state, ins, i);
16906                         if (tinfo.reg >= MAX_REGISTERS) {
16907                                 tinfo.reg = REG_UNSET;
16908                         }
16909                         info.regcm &= linfo.regcm;
16910                         info.regcm &= tinfo.regcm;
16911                         if (info.reg != REG_UNSET) {
16912                                 internal_error(state, ins, "register conflict");
16913                         }
16914                         if (info.regcm == 0) {
16915                                 internal_error(state, ins, "regcm conflict");
16916                         }
16917                         info.reg = tinfo.reg;
16918                 }
16919         }
16920 #if DEBUG_TRIPLE_COLOR
16921         fprintf(state->errout, "find_rhs_post_color(%p, %d) -> ( %d, %x)\n",
16922                 ins, index, info.reg, info.regcm);
16923 #endif
16924         return info;
16925 }
16926
16927 static struct reg_info find_lhs_color(
16928         struct compile_state *state, struct triple *ins, int index)
16929 {
16930         struct reg_info pre, post, info;
16931 #if DEBUG_TRIPLE_COLOR
16932         fprintf(state->errout, "find_lhs_color(%p, %d)\n",
16933                 ins, index);
16934 #endif
16935         pre = find_lhs_pre_color(state, ins, index);
16936         post = find_lhs_post_color(state, ins, index);
16937         if ((pre.reg != post.reg) &&
16938                 (pre.reg != REG_UNSET) &&
16939                 (post.reg != REG_UNSET)) {
16940                 internal_error(state, ins, "register conflict");
16941         }
16942         info.regcm = pre.regcm & post.regcm;
16943         info.reg = pre.reg;
16944         if (info.reg == REG_UNSET) {
16945                 info.reg = post.reg;
16946         }
16947 #if DEBUG_TRIPLE_COLOR
16948         fprintf(state->errout, "find_lhs_color(%p, %d) -> ( %d, %x) ... (%d, %x) (%d, %x)\n",
16949                 ins, index, info.reg, info.regcm,
16950                 pre.reg, pre.regcm, post.reg, post.regcm);
16951 #endif
16952         return info;
16953 }
16954
16955 static struct triple *post_copy(struct compile_state *state, struct triple *ins)
16956 {
16957         struct triple_set *entry, *next;
16958         struct triple *out;
16959         struct reg_info info, rinfo;
16960
16961         info = arch_reg_lhs(state, ins, 0);
16962         out = post_triple(state, ins, OP_COPY, ins->type, ins, 0);
16963         use_triple(RHS(out, 0), out);
16964         /* Get the users of ins to use out instead */
16965         for(entry = ins->use; entry; entry = next) {
16966                 int i;
16967                 next = entry->next;
16968                 if (entry->member == out) {
16969                         continue;
16970                 }
16971                 i = find_rhs_use(state, entry->member, ins);
16972                 if (i < 0) {
16973                         continue;
16974                 }
16975                 rinfo = arch_reg_rhs(state, entry->member, i);
16976                 if ((info.reg == REG_UNNEEDED) && (rinfo.reg == REG_UNNEEDED)) {
16977                         continue;
16978                 }
16979                 replace_rhs_use(state, ins, out, entry->member);
16980         }
16981         transform_to_arch_instruction(state, out);
16982         return out;
16983 }
16984
16985 static struct triple *typed_pre_copy(
16986         struct compile_state *state, struct type *type, struct triple *ins, int index)
16987 {
16988         /* Carefully insert enough operations so that I can
16989          * enter any operation with a GPR32.
16990          */
16991         struct triple *in;
16992         struct triple **expr;
16993         unsigned classes;
16994         struct reg_info info;
16995         int op;
16996         if (ins->op == OP_PHI) {
16997                 internal_error(state, ins, "pre_copy on a phi?");
16998         }
16999         classes = arch_type_to_regcm(state, type);
17000         info = arch_reg_rhs(state, ins, index);
17001         expr = &RHS(ins, index);
17002         if ((info.regcm & classes) == 0) {
17003                 FILE *fp = state->errout;
17004                 fprintf(fp, "src_type: ");
17005                 name_of(fp, ins->type);
17006                 fprintf(fp, "\ndst_type: ");
17007                 name_of(fp, type);
17008                 fprintf(fp, "\n");
17009                 internal_error(state, ins, "pre_copy with no register classes");
17010         }
17011         op = OP_COPY;
17012         if (!equiv_types(type, (*expr)->type)) {
17013                 op = OP_CONVERT;
17014         }
17015         in = pre_triple(state, ins, op, type, *expr, 0);
17016         unuse_triple(*expr, ins);
17017         *expr = in;
17018         use_triple(RHS(in, 0), in);
17019         use_triple(in, ins);
17020         transform_to_arch_instruction(state, in);
17021         return in;
17022         
17023 }
17024 static struct triple *pre_copy(
17025         struct compile_state *state, struct triple *ins, int index)
17026 {
17027         return typed_pre_copy(state, RHS(ins, index)->type, ins, index);
17028 }
17029
17030
17031 static void insert_copies_to_phi(struct compile_state *state)
17032 {
17033         /* To get out of ssa form we insert moves on the incoming
17034          * edges to blocks containting phi functions.
17035          */
17036         struct triple *first;
17037         struct triple *phi;
17038
17039         /* Walk all of the operations to find the phi functions */
17040         first = state->first;
17041         for(phi = first->next; phi != first ; phi = phi->next) {
17042                 struct block_set *set;
17043                 struct block *block;
17044                 struct triple **slot, *copy;
17045                 int edge;
17046                 if (phi->op != OP_PHI) {
17047                         continue;
17048                 }
17049                 phi->id |= TRIPLE_FLAG_POST_SPLIT;
17050                 block = phi->u.block;
17051                 slot  = &RHS(phi, 0);
17052                 /* Phi's that feed into mandatory live range joins
17053                  * cause nasty complications.  Insert a copy of
17054                  * the phi value so I never have to deal with
17055                  * that in the rest of the code.
17056                  */
17057                 copy = post_copy(state, phi);
17058                 copy->id |= TRIPLE_FLAG_PRE_SPLIT;
17059                 /* Walk all of the incoming edges/blocks and insert moves.
17060                  */
17061                 for(edge = 0, set = block->use; set; set = set->next, edge++) {
17062                         struct block *eblock;
17063                         struct triple *move;
17064                         struct triple *val;
17065                         struct triple *ptr;
17066                         eblock = set->member;
17067                         val = slot[edge];
17068
17069                         if (val == phi) {
17070                                 continue;
17071                         }
17072
17073                         get_occurance(val->occurance);
17074                         move = build_triple(state, OP_COPY, val->type, val, 0,
17075                                 val->occurance);
17076                         move->u.block = eblock;
17077                         move->id |= TRIPLE_FLAG_PRE_SPLIT;
17078                         use_triple(val, move);
17079                         
17080                         slot[edge] = move;
17081                         unuse_triple(val, phi);
17082                         use_triple(move, phi);
17083
17084                         /* Walk up the dominator tree until I have found the appropriate block */
17085                         while(eblock && !tdominates(state, val, eblock->last)) {
17086                                 eblock = eblock->idom;
17087                         }
17088                         if (!eblock) {
17089                                 internal_error(state, phi, "Cannot find block dominated by %p",
17090                                         val);
17091                         }
17092
17093                         /* Walk through the block backwards to find
17094                          * an appropriate location for the OP_COPY.
17095                          */
17096                         for(ptr = eblock->last; ptr != eblock->first; ptr = ptr->prev) {
17097                                 struct triple **expr;
17098                                 if (ptr->op == OP_PIECE) {
17099                                         ptr = MISC(ptr, 0);
17100                                 }
17101                                 if ((ptr == phi) || (ptr == val)) {
17102                                         goto out;
17103                                 }
17104                                 expr = triple_lhs(state, ptr, 0);
17105                                 for(;expr; expr = triple_lhs(state, ptr, expr)) {
17106                                         if ((*expr) == val) {
17107                                                 goto out;
17108                                         }
17109                                 }
17110                                 expr = triple_rhs(state, ptr, 0);
17111                                 for(;expr; expr = triple_rhs(state, ptr, expr)) {
17112                                         if ((*expr) == phi) {
17113                                                 goto out;
17114                                         }
17115                                 }
17116                         }
17117                 out:
17118                         if (triple_is_branch(state, ptr)) {
17119                                 internal_error(state, ptr,
17120                                         "Could not insert write to phi");
17121                         }
17122                         insert_triple(state, after_lhs(state, ptr), move);
17123                         if (eblock->last == after_lhs(state, ptr)->prev) {
17124                                 eblock->last = move;
17125                         }
17126                         transform_to_arch_instruction(state, move);
17127                 }
17128         }
17129         print_blocks(state, __func__, state->dbgout);
17130 }
17131
17132 struct triple_reg_set;
17133 struct reg_block;
17134
17135
17136 static int do_triple_set(struct triple_reg_set **head, 
17137         struct triple *member, struct triple *new_member)
17138 {
17139         struct triple_reg_set **ptr, *new;
17140         if (!member)
17141                 return 0;
17142         ptr = head;
17143         while(*ptr) {
17144                 if ((*ptr)->member == member) {
17145                         return 0;
17146                 }
17147                 ptr = &(*ptr)->next;
17148         }
17149         new = xcmalloc(sizeof(*new), "triple_set");
17150         new->member = member;
17151         new->new    = new_member;
17152         new->next   = *head;
17153         *head       = new;
17154         return 1;
17155 }
17156
17157 static void do_triple_unset(struct triple_reg_set **head, struct triple *member)
17158 {
17159         struct triple_reg_set *entry, **ptr;
17160         ptr = head;
17161         while(*ptr) {
17162                 entry = *ptr;
17163                 if (entry->member == member) {
17164                         *ptr = entry->next;
17165                         xfree(entry);
17166                         return;
17167                 }
17168                 else {
17169                         ptr = &entry->next;
17170                 }
17171         }
17172 }
17173
17174 static int in_triple(struct reg_block *rb, struct triple *in)
17175 {
17176         return do_triple_set(&rb->in, in, 0);
17177 }
17178 static void unin_triple(struct reg_block *rb, struct triple *unin)
17179 {
17180         do_triple_unset(&rb->in, unin);
17181 }
17182
17183 static int out_triple(struct reg_block *rb, struct triple *out)
17184 {
17185         return do_triple_set(&rb->out, out, 0);
17186 }
17187 static void unout_triple(struct reg_block *rb, struct triple *unout)
17188 {
17189         do_triple_unset(&rb->out, unout);
17190 }
17191
17192 static int initialize_regblock(struct reg_block *blocks,
17193         struct block *block, int vertex)
17194 {
17195         struct block_set *user;
17196         if (!block || (blocks[block->vertex].block == block)) {
17197                 return vertex;
17198         }
17199         vertex += 1;
17200         /* Renumber the blocks in a convinient fashion */
17201         block->vertex = vertex;
17202         blocks[vertex].block    = block;
17203         blocks[vertex].vertex   = vertex;
17204         for(user = block->use; user; user = user->next) {
17205                 vertex = initialize_regblock(blocks, user->member, vertex);
17206         }
17207         return vertex;
17208 }
17209
17210 static struct triple *part_to_piece(struct compile_state *state, struct triple *ins)
17211 {
17212 /* Part to piece is a best attempt and it cannot be correct all by
17213  * itself.  If various values are read as different sizes in different
17214  * parts of the code this function cannot work.  Or rather it cannot
17215  * work in conjunction with compute_variable_liftimes.  As the
17216  * analysis will get confused.
17217  */
17218         struct triple *base;
17219         unsigned reg;
17220         if (!is_lvalue(state, ins)) {
17221                 return ins;
17222         }
17223         base = 0;
17224         reg = 0;
17225         while(ins && triple_is_part(state, ins) && (ins->op != OP_PIECE)) {
17226                 base = MISC(ins, 0);
17227                 switch(ins->op) {
17228                 case OP_INDEX:
17229                         reg += index_reg_offset(state, base->type, ins->u.cval)/REG_SIZEOF_REG;
17230                         break;
17231                 case OP_DOT:
17232                         reg += field_reg_offset(state, base->type, ins->u.field)/REG_SIZEOF_REG;
17233                         break;
17234                 default:
17235                         internal_error(state, ins, "unhandled part");
17236                         break;
17237                 }
17238                 ins = base;
17239         }
17240         if (base) {
17241                 if (reg > base->lhs) {
17242                         internal_error(state, base, "part out of range?");
17243                 }
17244                 ins = LHS(base, reg);
17245         }
17246         return ins;
17247 }
17248
17249 static int this_def(struct compile_state *state, 
17250         struct triple *ins, struct triple *other)
17251 {
17252         if (ins == other) {
17253                 return 1;
17254         }
17255         if (ins->op == OP_WRITE) {
17256                 ins = part_to_piece(state, MISC(ins, 0));
17257         }
17258         return ins == other;
17259 }
17260
17261 static int phi_in(struct compile_state *state, struct reg_block *blocks,
17262         struct reg_block *rb, struct block *suc)
17263 {
17264         /* Read the conditional input set of a successor block
17265          * (i.e. the input to the phi nodes) and place it in the
17266          * current blocks output set.
17267          */
17268         struct block_set *set;
17269         struct triple *ptr;
17270         int edge;
17271         int done, change;
17272         change = 0;
17273         /* Find the edge I am coming in on */
17274         for(edge = 0, set = suc->use; set; set = set->next, edge++) {
17275                 if (set->member == rb->block) {
17276                         break;
17277                 }
17278         }
17279         if (!set) {
17280                 internal_error(state, 0, "Not coming on a control edge?");
17281         }
17282         for(done = 0, ptr = suc->first; !done; ptr = ptr->next) {
17283                 struct triple **slot, *expr, *ptr2;
17284                 int out_change, done2;
17285                 done = (ptr == suc->last);
17286                 if (ptr->op != OP_PHI) {
17287                         continue;
17288                 }
17289                 slot = &RHS(ptr, 0);
17290                 expr = slot[edge];
17291                 out_change = out_triple(rb, expr);
17292                 if (!out_change) {
17293                         continue;
17294                 }
17295                 /* If we don't define the variable also plast it
17296                  * in the current blocks input set.
17297                  */
17298                 ptr2 = rb->block->first;
17299                 for(done2 = 0; !done2; ptr2 = ptr2->next) {
17300                         if (this_def(state, ptr2, expr)) {
17301                                 break;
17302                         }
17303                         done2 = (ptr2 == rb->block->last);
17304                 }
17305                 if (!done2) {
17306                         continue;
17307                 }
17308                 change |= in_triple(rb, expr);
17309         }
17310         return change;
17311 }
17312
17313 static int reg_in(struct compile_state *state, struct reg_block *blocks,
17314         struct reg_block *rb, struct block *suc)
17315 {
17316         struct triple_reg_set *in_set;
17317         int change;
17318         change = 0;
17319         /* Read the input set of a successor block
17320          * and place it in the current blocks output set.
17321          */
17322         in_set = blocks[suc->vertex].in;
17323         for(; in_set; in_set = in_set->next) {
17324                 int out_change, done;
17325                 struct triple *first, *last, *ptr;
17326                 out_change = out_triple(rb, in_set->member);
17327                 if (!out_change) {
17328                         continue;
17329                 }
17330                 /* If we don't define the variable also place it
17331                  * in the current blocks input set.
17332                  */
17333                 first = rb->block->first;
17334                 last = rb->block->last;
17335                 done = 0;
17336                 for(ptr = first; !done; ptr = ptr->next) {
17337                         if (this_def(state, ptr, in_set->member)) {
17338                                 break;
17339                         }
17340                         done = (ptr == last);
17341                 }
17342                 if (!done) {
17343                         continue;
17344                 }
17345                 change |= in_triple(rb, in_set->member);
17346         }
17347         change |= phi_in(state, blocks, rb, suc);
17348         return change;
17349 }
17350
17351 static int use_in(struct compile_state *state, struct reg_block *rb)
17352 {
17353         /* Find the variables we use but don't define and add
17354          * it to the current blocks input set.
17355          */
17356 #warning "FIXME is this O(N^2) algorithm bad?"
17357         struct block *block;
17358         struct triple *ptr;
17359         int done;
17360         int change;
17361         block = rb->block;
17362         change = 0;
17363         for(done = 0, ptr = block->last; !done; ptr = ptr->prev) {
17364                 struct triple **expr;
17365                 done = (ptr == block->first);
17366                 /* The variable a phi function uses depends on the
17367                  * control flow, and is handled in phi_in, not
17368                  * here.
17369                  */
17370                 if (ptr->op == OP_PHI) {
17371                         continue;
17372                 }
17373                 expr = triple_rhs(state, ptr, 0);
17374                 for(;expr; expr = triple_rhs(state, ptr, expr)) {
17375                         struct triple *rhs, *test;
17376                         int tdone;
17377                         rhs = part_to_piece(state, *expr);
17378                         if (!rhs) {
17379                                 continue;
17380                         }
17381
17382                         /* See if rhs is defined in this block.
17383                          * A write counts as a definition.
17384                          */
17385                         for(tdone = 0, test = ptr; !tdone; test = test->prev) {
17386                                 tdone = (test == block->first);
17387                                 if (this_def(state, test, rhs)) {
17388                                         rhs = 0;
17389                                         break;
17390                                 }
17391                         }
17392                         /* If I still have a valid rhs add it to in */
17393                         change |= in_triple(rb, rhs);
17394                 }
17395         }
17396         return change;
17397 }
17398
17399 static struct reg_block *compute_variable_lifetimes(
17400         struct compile_state *state, struct basic_blocks *bb)
17401 {
17402         struct reg_block *blocks;
17403         int change;
17404         blocks = xcmalloc(
17405                 sizeof(*blocks)*(bb->last_vertex + 1), "reg_block");
17406         initialize_regblock(blocks, bb->last_block, 0);
17407         do {
17408                 int i;
17409                 change = 0;
17410                 for(i = 1; i <= bb->last_vertex; i++) {
17411                         struct block_set *edge;
17412                         struct reg_block *rb;
17413                         rb = &blocks[i];
17414                         /* Add the all successor's input set to in */
17415                         for(edge = rb->block->edges; edge; edge = edge->next) {
17416                                 change |= reg_in(state, blocks, rb, edge->member);
17417                         }
17418                         /* Add use to in... */
17419                         change |= use_in(state, rb);
17420                 }
17421         } while(change);
17422         return blocks;
17423 }
17424
17425 static void free_variable_lifetimes(struct compile_state *state, 
17426         struct basic_blocks *bb, struct reg_block *blocks)
17427 {
17428         int i;
17429         /* free in_set && out_set on each block */
17430         for(i = 1; i <= bb->last_vertex; i++) {
17431                 struct triple_reg_set *entry, *next;
17432                 struct reg_block *rb;
17433                 rb = &blocks[i];
17434                 for(entry = rb->in; entry ; entry = next) {
17435                         next = entry->next;
17436                         do_triple_unset(&rb->in, entry->member);
17437                 }
17438                 for(entry = rb->out; entry; entry = next) {
17439                         next = entry->next;
17440                         do_triple_unset(&rb->out, entry->member);
17441                 }
17442         }
17443         xfree(blocks);
17444
17445 }
17446
17447 typedef void (*wvl_cb_t)(
17448         struct compile_state *state, 
17449         struct reg_block *blocks, struct triple_reg_set *live, 
17450         struct reg_block *rb, struct triple *ins, void *arg);
17451
17452 static void walk_variable_lifetimes(struct compile_state *state,
17453         struct basic_blocks *bb, struct reg_block *blocks, 
17454         wvl_cb_t cb, void *arg)
17455 {
17456         int i;
17457         
17458         for(i = 1; i <= state->bb.last_vertex; i++) {
17459                 struct triple_reg_set *live;
17460                 struct triple_reg_set *entry, *next;
17461                 struct triple *ptr, *prev;
17462                 struct reg_block *rb;
17463                 struct block *block;
17464                 int done;
17465
17466                 /* Get the blocks */
17467                 rb = &blocks[i];
17468                 block = rb->block;
17469
17470                 /* Copy out into live */
17471                 live = 0;
17472                 for(entry = rb->out; entry; entry = next) {
17473                         next = entry->next;
17474                         do_triple_set(&live, entry->member, entry->new);
17475                 }
17476                 /* Walk through the basic block calculating live */
17477                 for(done = 0, ptr = block->last; !done; ptr = prev) {
17478                         struct triple **expr;
17479
17480                         prev = ptr->prev;
17481                         done = (ptr == block->first);
17482
17483                         /* Ensure the current definition is in live */
17484                         if (triple_is_def(state, ptr)) {
17485                                 do_triple_set(&live, ptr, 0);
17486                         }
17487
17488                         /* Inform the callback function of what is
17489                          * going on.
17490                          */
17491                          cb(state, blocks, live, rb, ptr, arg);
17492                         
17493                         /* Remove the current definition from live */
17494                         do_triple_unset(&live, ptr);
17495
17496                         /* Add the current uses to live.
17497                          *
17498                          * It is safe to skip phi functions because they do
17499                          * not have any block local uses, and the block
17500                          * output sets already properly account for what
17501                          * control flow depedent uses phi functions do have.
17502                          */
17503                         if (ptr->op == OP_PHI) {
17504                                 continue;
17505                         }
17506                         expr = triple_rhs(state, ptr, 0);
17507                         for(;expr; expr = triple_rhs(state, ptr, expr)) {
17508                                 /* If the triple is not a definition skip it. */
17509                                 if (!*expr || !triple_is_def(state, *expr)) {
17510                                         continue;
17511                                 }
17512                                 do_triple_set(&live, *expr, 0);
17513                         }
17514                 }
17515                 /* Free live */
17516                 for(entry = live; entry; entry = next) {
17517                         next = entry->next;
17518                         do_triple_unset(&live, entry->member);
17519                 }
17520         }
17521 }
17522
17523 struct print_live_variable_info {
17524         struct reg_block *rb;
17525         FILE *fp;
17526 };
17527 static void print_live_variables_block(
17528         struct compile_state *state, struct block *block, void *arg)
17529
17530 {
17531         struct print_live_variable_info *info = arg;
17532         struct block_set *edge;
17533         FILE *fp = info->fp;
17534         struct reg_block *rb;
17535         struct triple *ptr;
17536         int phi_present;
17537         int done;
17538         rb = &info->rb[block->vertex];
17539
17540         fprintf(fp, "\nblock: %p (%d),",
17541                 block,  block->vertex);
17542         for(edge = block->edges; edge; edge = edge->next) {
17543                 fprintf(fp, " %p<-%p",
17544                         edge->member, 
17545                         edge->member && edge->member->use?edge->member->use->member : 0);
17546         }
17547         fprintf(fp, "\n");
17548         if (rb->in) {
17549                 struct triple_reg_set *in_set;
17550                 fprintf(fp, "        in:");
17551                 for(in_set = rb->in; in_set; in_set = in_set->next) {
17552                         fprintf(fp, " %-10p", in_set->member);
17553                 }
17554                 fprintf(fp, "\n");
17555         }
17556         phi_present = 0;
17557         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
17558                 done = (ptr == block->last);
17559                 if (ptr->op == OP_PHI) {
17560                         phi_present = 1;
17561                         break;
17562                 }
17563         }
17564         if (phi_present) {
17565                 int edge;
17566                 for(edge = 0; edge < block->users; edge++) {
17567                         fprintf(fp, "     in(%d):", edge);
17568                         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
17569                                 struct triple **slot;
17570                                 done = (ptr == block->last);
17571                                 if (ptr->op != OP_PHI) {
17572                                         continue;
17573                                 }
17574                                 slot = &RHS(ptr, 0);
17575                                 fprintf(fp, " %-10p", slot[edge]);
17576                         }
17577                         fprintf(fp, "\n");
17578                 }
17579         }
17580         if (block->first->op == OP_LABEL) {
17581                 fprintf(fp, "%p:\n", block->first);
17582         }
17583         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
17584                 done = (ptr == block->last);
17585                 display_triple(fp, ptr);
17586         }
17587         if (rb->out) {
17588                 struct triple_reg_set *out_set;
17589                 fprintf(fp, "       out:");
17590                 for(out_set = rb->out; out_set; out_set = out_set->next) {
17591                         fprintf(fp, " %-10p", out_set->member);
17592                 }
17593                 fprintf(fp, "\n");
17594         }
17595         fprintf(fp, "\n");
17596 }
17597
17598 static void print_live_variables(struct compile_state *state, 
17599         struct basic_blocks *bb, struct reg_block *rb, FILE *fp)
17600 {
17601         struct print_live_variable_info info;
17602         info.rb = rb;
17603         info.fp = fp;
17604         fprintf(fp, "\nlive variables by block\n");
17605         walk_blocks(state, bb, print_live_variables_block, &info);
17606
17607 }
17608
17609
17610 static int count_triples(struct compile_state *state)
17611 {
17612         struct triple *first, *ins;
17613         int triples = 0;
17614         first = state->first;
17615         ins = first;
17616         do {
17617                 triples++;
17618                 ins = ins->next;
17619         } while (ins != first);
17620         return triples;
17621 }
17622
17623
17624 struct dead_triple {
17625         struct triple *triple;
17626         struct dead_triple *work_next;
17627         struct block *block;
17628         int old_id;
17629         int flags;
17630 #define TRIPLE_FLAG_ALIVE 1
17631 #define TRIPLE_FLAG_FREE  1
17632 };
17633
17634 static void print_dead_triples(struct compile_state *state, 
17635         struct dead_triple *dtriple)
17636 {
17637         struct triple *first, *ins;
17638         struct dead_triple *dt;
17639         FILE *fp;
17640         if (!(state->compiler->debug & DEBUG_TRIPLES)) {
17641                 return;
17642         }
17643         fp = state->dbgout;
17644         fprintf(fp, "--------------- dtriples ---------------\n");
17645         first = state->first;
17646         ins = first;
17647         do {
17648                 dt = &dtriple[ins->id];
17649                 if ((ins->op == OP_LABEL) && (ins->use)) {
17650                         fprintf(fp, "\n%p:\n", ins);
17651                 }
17652                 fprintf(fp, "%c", 
17653                         (dt->flags & TRIPLE_FLAG_ALIVE)?' ': '-');
17654                 display_triple(fp, ins);
17655                 if (triple_is_branch(state, ins)) {
17656                         fprintf(fp, "\n");
17657                 }
17658                 ins = ins->next;
17659         } while(ins != first);
17660         fprintf(fp, "\n");
17661 }
17662
17663
17664 static void awaken(
17665         struct compile_state *state,
17666         struct dead_triple *dtriple, struct triple **expr,
17667         struct dead_triple ***work_list_tail)
17668 {
17669         struct triple *triple;
17670         struct dead_triple *dt;
17671         if (!expr) {
17672                 return;
17673         }
17674         triple = *expr;
17675         if (!triple) {
17676                 return;
17677         }
17678         if (triple->id <= 0)  {
17679                 internal_error(state, triple, "bad triple id: %d",
17680                         triple->id);
17681         }
17682         if (triple->op == OP_NOOP) {
17683                 internal_error(state, triple, "awakening noop?");
17684                 return;
17685         }
17686         dt = &dtriple[triple->id];
17687         if (!(dt->flags & TRIPLE_FLAG_ALIVE)) {
17688                 dt->flags |= TRIPLE_FLAG_ALIVE;
17689                 if (!dt->work_next) {
17690                         **work_list_tail = dt;
17691                         *work_list_tail = &dt->work_next;
17692                 }
17693         }
17694 }
17695
17696 static void eliminate_inefectual_code(struct compile_state *state)
17697 {
17698         struct block *block;
17699         struct dead_triple *dtriple, *work_list, **work_list_tail, *dt;
17700         int triples, i;
17701         struct triple *first, *final, *ins;
17702
17703         if (!(state->compiler->flags & COMPILER_ELIMINATE_INEFECTUAL_CODE)) {
17704                 return;
17705         }
17706
17707         /* Setup the work list */
17708         work_list = 0;
17709         work_list_tail = &work_list;
17710
17711         first = state->first;
17712         final = state->first->prev;
17713
17714         /* Count how many triples I have */
17715         triples = count_triples(state);
17716
17717         /* Now put then in an array and mark all of the triples dead */
17718         dtriple = xcmalloc(sizeof(*dtriple) * (triples + 1), "dtriples");
17719         
17720         ins = first;
17721         i = 1;
17722         block = 0;
17723         do {
17724                 dtriple[i].triple = ins;
17725                 dtriple[i].block  = block_of_triple(state, ins);
17726                 dtriple[i].flags  = 0;
17727                 dtriple[i].old_id = ins->id;
17728                 ins->id = i;
17729                 /* See if it is an operation we always keep */
17730                 if (!triple_is_pure(state, ins, dtriple[i].old_id)) {
17731                         awaken(state, dtriple, &ins, &work_list_tail);
17732                 }
17733                 i++;
17734                 ins = ins->next;
17735         } while(ins != first);
17736         while(work_list) {
17737                 struct block *block;
17738                 struct dead_triple *dt;
17739                 struct block_set *user;
17740                 struct triple **expr;
17741                 dt = work_list;
17742                 work_list = dt->work_next;
17743                 if (!work_list) {
17744                         work_list_tail = &work_list;
17745                 }
17746                 /* Make certain the block the current instruction is in lives */
17747                 block = block_of_triple(state, dt->triple);
17748                 awaken(state, dtriple, &block->first, &work_list_tail);
17749                 if (triple_is_branch(state, block->last)) {
17750                         awaken(state, dtriple, &block->last, &work_list_tail);
17751                 } else {
17752                         awaken(state, dtriple, &block->last->next, &work_list_tail);
17753                 }
17754
17755                 /* Wake up the data depencencies of this triple */
17756                 expr = 0;
17757                 do {
17758                         expr = triple_rhs(state, dt->triple, expr);
17759                         awaken(state, dtriple, expr, &work_list_tail);
17760                 } while(expr);
17761                 do {
17762                         expr = triple_lhs(state, dt->triple, expr);
17763                         awaken(state, dtriple, expr, &work_list_tail);
17764                 } while(expr);
17765                 do {
17766                         expr = triple_misc(state, dt->triple, expr);
17767                         awaken(state, dtriple, expr, &work_list_tail);
17768                 } while(expr);
17769                 /* Wake up the forward control dependencies */
17770                 do {
17771                         expr = triple_targ(state, dt->triple, expr);
17772                         awaken(state, dtriple, expr, &work_list_tail);
17773                 } while(expr);
17774                 /* Wake up the reverse control dependencies of this triple */
17775                 for(user = dt->block->ipdomfrontier; user; user = user->next) {
17776                         struct triple *last;
17777                         last = user->member->last;
17778                         while((last->op == OP_NOOP) && (last != user->member->first)) {
17779                                 internal_warning(state, last, "awakening noop?");
17780                                 last = last->prev;
17781                         }
17782                         awaken(state, dtriple, &last, &work_list_tail);
17783                 }
17784         }
17785         print_dead_triples(state, dtriple);
17786         for(dt = &dtriple[1]; dt <= &dtriple[triples]; dt++) {
17787                 if ((dt->triple->op == OP_NOOP) && 
17788                         (dt->flags & TRIPLE_FLAG_ALIVE)) {
17789                         internal_error(state, dt->triple, "noop effective?");
17790                 }
17791                 dt->triple->id = dt->old_id;    /* Restore the color */
17792                 if (!(dt->flags & TRIPLE_FLAG_ALIVE)) {
17793                         release_triple(state, dt->triple);
17794                 }
17795         }
17796         xfree(dtriple);
17797
17798         rebuild_ssa_form(state);
17799
17800         print_blocks(state, __func__, state->dbgout);
17801 }
17802
17803
17804 static void insert_mandatory_copies(struct compile_state *state)
17805 {
17806         struct triple *ins, *first;
17807
17808         /* The object is with a minimum of inserted copies,
17809          * to resolve in fundamental register conflicts between
17810          * register value producers and consumers.
17811          * Theoretically we may be greater than minimal when we
17812          * are inserting copies before instructions but that
17813          * case should be rare.
17814          */
17815         first = state->first;
17816         ins = first;
17817         do {
17818                 struct triple_set *entry, *next;
17819                 struct triple *tmp;
17820                 struct reg_info info;
17821                 unsigned reg, regcm;
17822                 int do_post_copy, do_pre_copy;
17823                 tmp = 0;
17824                 if (!triple_is_def(state, ins)) {
17825                         goto next;
17826                 }
17827                 /* Find the architecture specific color information */
17828                 info = find_lhs_pre_color(state, ins, 0);
17829                 if (info.reg >= MAX_REGISTERS) {
17830                         info.reg = REG_UNSET;
17831                 }
17832
17833                 reg = REG_UNSET;
17834                 regcm = arch_type_to_regcm(state, ins->type);
17835                 do_post_copy = do_pre_copy = 0;
17836
17837                 /* Walk through the uses of ins and check for conflicts */
17838                 for(entry = ins->use; entry; entry = next) {
17839                         struct reg_info rinfo;
17840                         int i;
17841                         next = entry->next;
17842                         i = find_rhs_use(state, entry->member, ins);
17843                         if (i < 0) {
17844                                 continue;
17845                         }
17846                         
17847                         /* Find the users color requirements */
17848                         rinfo = arch_reg_rhs(state, entry->member, i);
17849                         if (rinfo.reg >= MAX_REGISTERS) {
17850                                 rinfo.reg = REG_UNSET;
17851                         }
17852                         
17853                         /* See if I need a pre_copy */
17854                         if (rinfo.reg != REG_UNSET) {
17855                                 if ((reg != REG_UNSET) && (reg != rinfo.reg)) {
17856                                         do_pre_copy = 1;
17857                                 }
17858                                 reg = rinfo.reg;
17859                         }
17860                         regcm &= rinfo.regcm;
17861                         regcm = arch_regcm_normalize(state, regcm);
17862                         if (regcm == 0) {
17863                                 do_pre_copy = 1;
17864                         }
17865                         /* Always use pre_copies for constants.
17866                          * They do not take up any registers until a
17867                          * copy places them in one.
17868                          */
17869                         if ((info.reg == REG_UNNEEDED) && 
17870                                 (rinfo.reg != REG_UNNEEDED)) {
17871                                 do_pre_copy = 1;
17872                         }
17873                 }
17874                 do_post_copy =
17875                         !do_pre_copy &&
17876                         (((info.reg != REG_UNSET) && 
17877                                 (reg != REG_UNSET) &&
17878                                 (info.reg != reg)) ||
17879                         ((info.regcm & regcm) == 0));
17880
17881                 reg = info.reg;
17882                 regcm = info.regcm;
17883                 /* Walk through the uses of ins and do a pre_copy or see if a post_copy is warranted */
17884                 for(entry = ins->use; entry; entry = next) {
17885                         struct reg_info rinfo;
17886                         int i;
17887                         next = entry->next;
17888                         i = find_rhs_use(state, entry->member, ins);
17889                         if (i < 0) {
17890                                 continue;
17891                         }
17892                         
17893                         /* Find the users color requirements */
17894                         rinfo = arch_reg_rhs(state, entry->member, i);
17895                         if (rinfo.reg >= MAX_REGISTERS) {
17896                                 rinfo.reg = REG_UNSET;
17897                         }
17898
17899                         /* Now see if it is time to do the pre_copy */
17900                         if (rinfo.reg != REG_UNSET) {
17901                                 if (((reg != REG_UNSET) && (reg != rinfo.reg)) ||
17902                                         ((regcm & rinfo.regcm) == 0) ||
17903                                         /* Don't let a mandatory coalesce sneak
17904                                          * into a operation that is marked to prevent
17905                                          * coalescing.
17906                                          */
17907                                         ((reg != REG_UNNEEDED) &&
17908                                         ((ins->id & TRIPLE_FLAG_POST_SPLIT) ||
17909                                         (entry->member->id & TRIPLE_FLAG_PRE_SPLIT)))
17910                                         ) {
17911                                         if (do_pre_copy) {
17912                                                 struct triple *user;
17913                                                 user = entry->member;
17914                                                 if (RHS(user, i) != ins) {
17915                                                         internal_error(state, user, "bad rhs");
17916                                                 }
17917                                                 tmp = pre_copy(state, user, i);
17918                                                 tmp->id |= TRIPLE_FLAG_PRE_SPLIT;
17919                                                 continue;
17920                                         } else {
17921                                                 do_post_copy = 1;
17922                                         }
17923                                 }
17924                                 reg = rinfo.reg;
17925                         }
17926                         if ((regcm & rinfo.regcm) == 0) {
17927                                 if (do_pre_copy) {
17928                                         struct triple *user;
17929                                         user = entry->member;
17930                                         if (RHS(user, i) != ins) {
17931                                                 internal_error(state, user, "bad rhs");
17932                                         }
17933                                         tmp = pre_copy(state, user, i);
17934                                         tmp->id |= TRIPLE_FLAG_PRE_SPLIT;
17935                                         continue;
17936                                 } else {
17937                                         do_post_copy = 1;
17938                                 }
17939                         }
17940                         regcm &= rinfo.regcm;
17941                         
17942                 }
17943                 if (do_post_copy) {
17944                         struct reg_info pre, post;
17945                         tmp = post_copy(state, ins);
17946                         tmp->id |= TRIPLE_FLAG_PRE_SPLIT;
17947                         pre = arch_reg_lhs(state, ins, 0);
17948                         post = arch_reg_lhs(state, tmp, 0);
17949                         if ((pre.reg == post.reg) && (pre.regcm == post.regcm)) {
17950                                 internal_error(state, tmp, "useless copy");
17951                         }
17952                 }
17953         next:
17954                 ins = ins->next;
17955         } while(ins != first);
17956
17957         print_blocks(state, __func__, state->dbgout);
17958 }
17959
17960
17961 struct live_range_edge;
17962 struct live_range_def;
17963 struct live_range {
17964         struct live_range_edge *edges;
17965         struct live_range_def *defs;
17966 /* Note. The list pointed to by defs is kept in order.
17967  * That is baring splits in the flow control
17968  * defs dominates defs->next wich dominates defs->next->next
17969  * etc.
17970  */
17971         unsigned color;
17972         unsigned classes;
17973         unsigned degree;
17974         unsigned length;
17975         struct live_range *group_next, **group_prev;
17976 };
17977
17978 struct live_range_edge {
17979         struct live_range_edge *next;
17980         struct live_range *node;
17981 };
17982
17983 struct live_range_def {
17984         struct live_range_def *next;
17985         struct live_range_def *prev;
17986         struct live_range *lr;
17987         struct triple *def;
17988         unsigned orig_id;
17989 };
17990
17991 #define LRE_HASH_SIZE 2048
17992 struct lre_hash {
17993         struct lre_hash *next;
17994         struct live_range *left;
17995         struct live_range *right;
17996 };
17997
17998
17999 struct reg_state {
18000         struct lre_hash *hash[LRE_HASH_SIZE];
18001         struct reg_block *blocks;
18002         struct live_range_def *lrd;
18003         struct live_range *lr;
18004         struct live_range *low, **low_tail;
18005         struct live_range *high, **high_tail;
18006         unsigned defs;
18007         unsigned ranges;
18008         int passes, max_passes;
18009 };
18010
18011
18012 struct print_interference_block_info {
18013         struct reg_state *rstate;
18014         FILE *fp;
18015         int need_edges;
18016 };
18017 static void print_interference_block(
18018         struct compile_state *state, struct block *block, void *arg)
18019
18020 {
18021         struct print_interference_block_info *info = arg;
18022         struct reg_state *rstate = info->rstate;
18023         struct block_set *edge;
18024         FILE *fp = info->fp;
18025         struct reg_block *rb;
18026         struct triple *ptr;
18027         int phi_present;
18028         int done;
18029         rb = &rstate->blocks[block->vertex];
18030
18031         fprintf(fp, "\nblock: %p (%d),",
18032                 block,  block->vertex);
18033         for(edge = block->edges; edge; edge = edge->next) {
18034                 fprintf(fp, " %p<-%p",
18035                         edge->member, 
18036                         edge->member && edge->member->use?edge->member->use->member : 0);
18037         }
18038         fprintf(fp, "\n");
18039         if (rb->in) {
18040                 struct triple_reg_set *in_set;
18041                 fprintf(fp, "        in:");
18042                 for(in_set = rb->in; in_set; in_set = in_set->next) {
18043                         fprintf(fp, " %-10p", in_set->member);
18044                 }
18045                 fprintf(fp, "\n");
18046         }
18047         phi_present = 0;
18048         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
18049                 done = (ptr == block->last);
18050                 if (ptr->op == OP_PHI) {
18051                         phi_present = 1;
18052                         break;
18053                 }
18054         }
18055         if (phi_present) {
18056                 int edge;
18057                 for(edge = 0; edge < block->users; edge++) {
18058                         fprintf(fp, "     in(%d):", edge);
18059                         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
18060                                 struct triple **slot;
18061                                 done = (ptr == block->last);
18062                                 if (ptr->op != OP_PHI) {
18063                                         continue;
18064                                 }
18065                                 slot = &RHS(ptr, 0);
18066                                 fprintf(fp, " %-10p", slot[edge]);
18067                         }
18068                         fprintf(fp, "\n");
18069                 }
18070         }
18071         if (block->first->op == OP_LABEL) {
18072                 fprintf(fp, "%p:\n", block->first);
18073         }
18074         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
18075                 struct live_range *lr;
18076                 unsigned id;
18077                 int op;
18078                 op = ptr->op;
18079                 done = (ptr == block->last);
18080                 lr = rstate->lrd[ptr->id].lr;
18081                 
18082                 id = ptr->id;
18083                 ptr->id = rstate->lrd[id].orig_id;
18084                 SET_REG(ptr->id, lr->color);
18085                 display_triple(fp, ptr);
18086                 ptr->id = id;
18087
18088                 if (triple_is_def(state, ptr) && (lr->defs == 0)) {
18089                         internal_error(state, ptr, "lr has no defs!");
18090                 }
18091                 if (info->need_edges) {
18092                         if (lr->defs) {
18093                                 struct live_range_def *lrd;
18094                                 fprintf(fp, "       range:");
18095                                 lrd = lr->defs;
18096                                 do {
18097                                         fprintf(fp, " %-10p", lrd->def);
18098                                         lrd = lrd->next;
18099                                 } while(lrd != lr->defs);
18100                                 fprintf(fp, "\n");
18101                         }
18102                         if (lr->edges > 0) {
18103                                 struct live_range_edge *edge;
18104                                 fprintf(fp, "       edges:");
18105                                 for(edge = lr->edges; edge; edge = edge->next) {
18106                                         struct live_range_def *lrd;
18107                                         lrd = edge->node->defs;
18108                                         do {
18109                                                 fprintf(fp, " %-10p", lrd->def);
18110                                                 lrd = lrd->next;
18111                                         } while(lrd != edge->node->defs);
18112                                         fprintf(fp, "|");
18113                                 }
18114                                 fprintf(fp, "\n");
18115                         }
18116                 }
18117                 /* Do a bunch of sanity checks */
18118                 valid_ins(state, ptr);
18119                 if ((ptr->id < 0) || (ptr->id > rstate->defs)) {
18120                         internal_error(state, ptr, "Invalid triple id: %d",
18121                                 ptr->id);
18122                 }
18123         }
18124         if (rb->out) {
18125                 struct triple_reg_set *out_set;
18126                 fprintf(fp, "       out:");
18127                 for(out_set = rb->out; out_set; out_set = out_set->next) {
18128                         fprintf(fp, " %-10p", out_set->member);
18129                 }
18130                 fprintf(fp, "\n");
18131         }
18132         fprintf(fp, "\n");
18133 }
18134
18135 static void print_interference_blocks(
18136         struct compile_state *state, struct reg_state *rstate, FILE *fp, int need_edges)
18137 {
18138         struct print_interference_block_info info;
18139         info.rstate = rstate;
18140         info.fp = fp;
18141         info.need_edges = need_edges;
18142         fprintf(fp, "\nlive variables by block\n");
18143         walk_blocks(state, &state->bb, print_interference_block, &info);
18144
18145 }
18146
18147 static unsigned regc_max_size(struct compile_state *state, int classes)
18148 {
18149         unsigned max_size;
18150         int i;
18151         max_size = 0;
18152         for(i = 0; i < MAX_REGC; i++) {
18153                 if (classes & (1 << i)) {
18154                         unsigned size;
18155                         size = arch_regc_size(state, i);
18156                         if (size > max_size) {
18157                                 max_size = size;
18158                         }
18159                 }
18160         }
18161         return max_size;
18162 }
18163
18164 static int reg_is_reg(struct compile_state *state, int reg1, int reg2)
18165 {
18166         unsigned equivs[MAX_REG_EQUIVS];
18167         int i;
18168         if ((reg1 < 0) || (reg1 >= MAX_REGISTERS)) {
18169                 internal_error(state, 0, "invalid register");
18170         }
18171         if ((reg2 < 0) || (reg2 >= MAX_REGISTERS)) {
18172                 internal_error(state, 0, "invalid register");
18173         }
18174         arch_reg_equivs(state, equivs, reg1);
18175         for(i = 0; (i < MAX_REG_EQUIVS) && equivs[i] != REG_UNSET; i++) {
18176                 if (equivs[i] == reg2) {
18177                         return 1;
18178                 }
18179         }
18180         return 0;
18181 }
18182
18183 static void reg_fill_used(struct compile_state *state, char *used, int reg)
18184 {
18185         unsigned equivs[MAX_REG_EQUIVS];
18186         int i;
18187         if (reg == REG_UNNEEDED) {
18188                 return;
18189         }
18190         arch_reg_equivs(state, equivs, reg);
18191         for(i = 0; (i < MAX_REG_EQUIVS) && equivs[i] != REG_UNSET; i++) {
18192                 used[equivs[i]] = 1;
18193         }
18194         return;
18195 }
18196
18197 static void reg_inc_used(struct compile_state *state, char *used, int reg)
18198 {
18199         unsigned equivs[MAX_REG_EQUIVS];
18200         int i;
18201         if (reg == REG_UNNEEDED) {
18202                 return;
18203         }
18204         arch_reg_equivs(state, equivs, reg);
18205         for(i = 0; (i < MAX_REG_EQUIVS) && equivs[i] != REG_UNSET; i++) {
18206                 used[equivs[i]] += 1;
18207         }
18208         return;
18209 }
18210
18211 static unsigned int hash_live_edge(
18212         struct live_range *left, struct live_range *right)
18213 {
18214         unsigned int hash, val;
18215         unsigned long lval, rval;
18216         lval = ((unsigned long)left)/sizeof(struct live_range);
18217         rval = ((unsigned long)right)/sizeof(struct live_range);
18218         hash = 0;
18219         while(lval) {
18220                 val = lval & 0xff;
18221                 lval >>= 8;
18222                 hash = (hash *263) + val;
18223         }
18224         while(rval) {
18225                 val = rval & 0xff;
18226                 rval >>= 8;
18227                 hash = (hash *263) + val;
18228         }
18229         hash = hash & (LRE_HASH_SIZE - 1);
18230         return hash;
18231 }
18232
18233 static struct lre_hash **lre_probe(struct reg_state *rstate,
18234         struct live_range *left, struct live_range *right)
18235 {
18236         struct lre_hash **ptr;
18237         unsigned int index;
18238         /* Ensure left <= right */
18239         if (left > right) {
18240                 struct live_range *tmp;
18241                 tmp = left;
18242                 left = right;
18243                 right = tmp;
18244         }
18245         index = hash_live_edge(left, right);
18246         
18247         ptr = &rstate->hash[index];
18248         while(*ptr) {
18249                 if (((*ptr)->left == left) && ((*ptr)->right == right)) {
18250                         break;
18251                 }
18252                 ptr = &(*ptr)->next;
18253         }
18254         return ptr;
18255 }
18256
18257 static int interfere(struct reg_state *rstate,
18258         struct live_range *left, struct live_range *right)
18259 {
18260         struct lre_hash **ptr;
18261         ptr = lre_probe(rstate, left, right);
18262         return ptr && *ptr;
18263 }
18264
18265 static void add_live_edge(struct reg_state *rstate, 
18266         struct live_range *left, struct live_range *right)
18267 {
18268         /* FIXME the memory allocation overhead is noticeable here... */
18269         struct lre_hash **ptr, *new_hash;
18270         struct live_range_edge *edge;
18271
18272         if (left == right) {
18273                 return;
18274         }
18275         if ((left == &rstate->lr[0]) || (right == &rstate->lr[0])) {
18276                 return;
18277         }
18278         /* Ensure left <= right */
18279         if (left > right) {
18280                 struct live_range *tmp;
18281                 tmp = left;
18282                 left = right;
18283                 right = tmp;
18284         }
18285         ptr = lre_probe(rstate, left, right);
18286         if (*ptr) {
18287                 return;
18288         }
18289 #if 0
18290         fprintf(state->errout, "new_live_edge(%p, %p)\n",
18291                 left, right);
18292 #endif
18293         new_hash = xmalloc(sizeof(*new_hash), "lre_hash");
18294         new_hash->next  = *ptr;
18295         new_hash->left  = left;
18296         new_hash->right = right;
18297         *ptr = new_hash;
18298
18299         edge = xmalloc(sizeof(*edge), "live_range_edge");
18300         edge->next   = left->edges;
18301         edge->node   = right;
18302         left->edges  = edge;
18303         left->degree += 1;
18304         
18305         edge = xmalloc(sizeof(*edge), "live_range_edge");
18306         edge->next    = right->edges;
18307         edge->node    = left;
18308         right->edges  = edge;
18309         right->degree += 1;
18310 }
18311
18312 static void remove_live_edge(struct reg_state *rstate,
18313         struct live_range *left, struct live_range *right)
18314 {
18315         struct live_range_edge *edge, **ptr;
18316         struct lre_hash **hptr, *entry;
18317         hptr = lre_probe(rstate, left, right);
18318         if (!hptr || !*hptr) {
18319                 return;
18320         }
18321         entry = *hptr;
18322         *hptr = entry->next;
18323         xfree(entry);
18324
18325         for(ptr = &left->edges; *ptr; ptr = &(*ptr)->next) {
18326                 edge = *ptr;
18327                 if (edge->node == right) {
18328                         *ptr = edge->next;
18329                         memset(edge, 0, sizeof(*edge));
18330                         xfree(edge);
18331                         right->degree--;
18332                         break;
18333                 }
18334         }
18335         for(ptr = &right->edges; *ptr; ptr = &(*ptr)->next) {
18336                 edge = *ptr;
18337                 if (edge->node == left) {
18338                         *ptr = edge->next;
18339                         memset(edge, 0, sizeof(*edge));
18340                         xfree(edge);
18341                         left->degree--;
18342                         break;
18343                 }
18344         }
18345 }
18346
18347 static void remove_live_edges(struct reg_state *rstate, struct live_range *range)
18348 {
18349         struct live_range_edge *edge, *next;
18350         for(edge = range->edges; edge; edge = next) {
18351                 next = edge->next;
18352                 remove_live_edge(rstate, range, edge->node);
18353         }
18354 }
18355
18356 static void transfer_live_edges(struct reg_state *rstate, 
18357         struct live_range *dest, struct live_range *src)
18358 {
18359         struct live_range_edge *edge, *next;
18360         for(edge = src->edges; edge; edge = next) {
18361                 struct live_range *other;
18362                 next = edge->next;
18363                 other = edge->node;
18364                 remove_live_edge(rstate, src, other);
18365                 add_live_edge(rstate, dest, other);
18366         }
18367 }
18368
18369
18370 /* Interference graph...
18371  * 
18372  * new(n) --- Return a graph with n nodes but no edges.
18373  * add(g,x,y) --- Return a graph including g with an between x and y
18374  * interfere(g, x, y) --- Return true if there exists an edge between the nodes
18375  *                x and y in the graph g
18376  * degree(g, x) --- Return the degree of the node x in the graph g
18377  * neighbors(g, x, f) --- Apply function f to each neighbor of node x in the graph g
18378  *
18379  * Implement with a hash table && a set of adjcency vectors.
18380  * The hash table supports constant time implementations of add and interfere.
18381  * The adjacency vectors support an efficient implementation of neighbors.
18382  */
18383
18384 /* 
18385  *     +---------------------------------------------------+
18386  *     |         +--------------+                          |
18387  *     v         v              |                          |
18388  * renumber -> build graph -> colalesce -> spill_costs -> simplify -> select 
18389  *
18390  * -- In simplify implment optimistic coloring... (No backtracking)
18391  * -- Implement Rematerialization it is the only form of spilling we can perform
18392  *    Essentially this means dropping a constant from a register because
18393  *    we can regenerate it later.
18394  *
18395  * --- Very conservative colalescing (don't colalesce just mark the opportunities)
18396  *     coalesce at phi points...
18397  * --- Bias coloring if at all possible do the coalesing a compile time.
18398  *
18399  *
18400  */
18401
18402 static void different_colored(
18403         struct compile_state *state, struct reg_state *rstate, 
18404         struct triple *parent, struct triple *ins)
18405 {
18406         struct live_range *lr;
18407         struct triple **expr;
18408         lr = rstate->lrd[ins->id].lr;
18409         expr = triple_rhs(state, ins, 0);
18410         for(;expr; expr = triple_rhs(state, ins, expr)) {
18411                 struct live_range *lr2;
18412                 if (!*expr || (*expr == parent) || (*expr == ins)) {
18413                         continue;
18414                 }
18415                 lr2 = rstate->lrd[(*expr)->id].lr;
18416                 if (lr->color == lr2->color) {
18417                         internal_error(state, ins, "live range too big");
18418                 }
18419         }
18420 }
18421
18422
18423 static struct live_range *coalesce_ranges(
18424         struct compile_state *state, struct reg_state *rstate,
18425         struct live_range *lr1, struct live_range *lr2)
18426 {
18427         struct live_range_def *head, *mid1, *mid2, *end, *lrd;
18428         unsigned color;
18429         unsigned classes;
18430         if (lr1 == lr2) {
18431                 return lr1;
18432         }
18433         if (!lr1->defs || !lr2->defs) {
18434                 internal_error(state, 0,
18435                         "cannot coalese dead live ranges");
18436         }
18437         if ((lr1->color == REG_UNNEEDED) ||
18438                 (lr2->color == REG_UNNEEDED)) {
18439                 internal_error(state, 0, 
18440                         "cannot coalesce live ranges without a possible color");
18441         }
18442         if ((lr1->color != lr2->color) &&
18443                 (lr1->color != REG_UNSET) &&
18444                 (lr2->color != REG_UNSET)) {
18445                 internal_error(state, lr1->defs->def, 
18446                         "cannot coalesce live ranges of different colors");
18447         }
18448         color = lr1->color;
18449         if (color == REG_UNSET) {
18450                 color = lr2->color;
18451         }
18452         classes = lr1->classes & lr2->classes;
18453         if (!classes) {
18454                 internal_error(state, lr1->defs->def,
18455                         "cannot coalesce live ranges with dissimilar register classes");
18456         }
18457         if (state->compiler->debug & DEBUG_COALESCING) {
18458                 FILE *fp = state->errout;
18459                 fprintf(fp, "coalescing:");
18460                 lrd = lr1->defs;
18461                 do {
18462                         fprintf(fp, " %p", lrd->def);
18463                         lrd = lrd->next;
18464                 } while(lrd != lr1->defs);
18465                 fprintf(fp, " |");
18466                 lrd = lr2->defs;
18467                 do {
18468                         fprintf(fp, " %p", lrd->def);
18469                         lrd = lrd->next;
18470                 } while(lrd != lr2->defs);
18471                 fprintf(fp, "\n");
18472         }
18473         /* If there is a clear dominate live range put it in lr1,
18474          * For purposes of this test phi functions are
18475          * considered dominated by the definitions that feed into
18476          * them. 
18477          */
18478         if ((lr1->defs->prev->def->op == OP_PHI) ||
18479                 ((lr2->defs->prev->def->op != OP_PHI) &&
18480                 tdominates(state, lr2->defs->def, lr1->defs->def))) {
18481                 struct live_range *tmp;
18482                 tmp = lr1;
18483                 lr1 = lr2;
18484                 lr2 = tmp;
18485         }
18486 #if 0
18487         if (lr1->defs->orig_id  & TRIPLE_FLAG_POST_SPLIT) {
18488                 fprintf(state->errout, "lr1 post\n");
18489         }
18490         if (lr1->defs->orig_id & TRIPLE_FLAG_PRE_SPLIT) {
18491                 fprintf(state->errout, "lr1 pre\n");
18492         }
18493         if (lr2->defs->orig_id  & TRIPLE_FLAG_POST_SPLIT) {
18494                 fprintf(state->errout, "lr2 post\n");
18495         }
18496         if (lr2->defs->orig_id & TRIPLE_FLAG_PRE_SPLIT) {
18497                 fprintf(state->errout, "lr2 pre\n");
18498         }
18499 #endif
18500 #if 0
18501         fprintf(state->errout, "coalesce color1(%p): %3d color2(%p) %3d\n",
18502                 lr1->defs->def,
18503                 lr1->color,
18504                 lr2->defs->def,
18505                 lr2->color);
18506 #endif
18507         
18508         /* Append lr2 onto lr1 */
18509 #warning "FIXME should this be a merge instead of a splice?"
18510         /* This FIXME item applies to the correctness of live_range_end 
18511          * and to the necessity of making multiple passes of coalesce_live_ranges.
18512          * A failure to find some coalesce opportunities in coaleace_live_ranges
18513          * does not impact the correct of the compiler just the efficiency with
18514          * which registers are allocated.
18515          */
18516         head = lr1->defs;
18517         mid1 = lr1->defs->prev;
18518         mid2 = lr2->defs;
18519         end  = lr2->defs->prev;
18520         
18521         head->prev = end;
18522         end->next  = head;
18523
18524         mid1->next = mid2;
18525         mid2->prev = mid1;
18526
18527         /* Fixup the live range in the added live range defs */
18528         lrd = head;
18529         do {
18530                 lrd->lr = lr1;
18531                 lrd = lrd->next;
18532         } while(lrd != head);
18533
18534         /* Mark lr2 as free. */
18535         lr2->defs = 0;
18536         lr2->color = REG_UNNEEDED;
18537         lr2->classes = 0;
18538
18539         if (!lr1->defs) {
18540                 internal_error(state, 0, "lr1->defs == 0 ?");
18541         }
18542
18543         lr1->color   = color;
18544         lr1->classes = classes;
18545
18546         /* Keep the graph in sync by transfering the edges from lr2 to lr1 */
18547         transfer_live_edges(rstate, lr1, lr2);
18548
18549         return lr1;
18550 }
18551
18552 static struct live_range_def *live_range_head(
18553         struct compile_state *state, struct live_range *lr,
18554         struct live_range_def *last)
18555 {
18556         struct live_range_def *result;
18557         result = 0;
18558         if (last == 0) {
18559                 result = lr->defs;
18560         }
18561         else if (!tdominates(state, lr->defs->def, last->next->def)) {
18562                 result = last->next;
18563         }
18564         return result;
18565 }
18566
18567 static struct live_range_def *live_range_end(
18568         struct compile_state *state, struct live_range *lr,
18569         struct live_range_def *last)
18570 {
18571         struct live_range_def *result;
18572         result = 0;
18573         if (last == 0) {
18574                 result = lr->defs->prev;
18575         }
18576         else if (!tdominates(state, last->prev->def, lr->defs->prev->def)) {
18577                 result = last->prev;
18578         }
18579         return result;
18580 }
18581
18582
18583 static void initialize_live_ranges(
18584         struct compile_state *state, struct reg_state *rstate)
18585 {
18586         struct triple *ins, *first;
18587         size_t count, size;
18588         int i, j;
18589
18590         first = state->first;
18591         /* First count how many instructions I have.
18592          */
18593         count = count_triples(state);
18594         /* Potentially I need one live range definitions for each
18595          * instruction.
18596          */
18597         rstate->defs = count;
18598         /* Potentially I need one live range for each instruction
18599          * plus an extra for the dummy live range.
18600          */
18601         rstate->ranges = count + 1;
18602         size = sizeof(rstate->lrd[0]) * rstate->defs;
18603         rstate->lrd = xcmalloc(size, "live_range_def");
18604         size = sizeof(rstate->lr[0]) * rstate->ranges;
18605         rstate->lr  = xcmalloc(size, "live_range");
18606
18607         /* Setup the dummy live range */
18608         rstate->lr[0].classes = 0;
18609         rstate->lr[0].color = REG_UNSET;
18610         rstate->lr[0].defs = 0;
18611         i = j = 0;
18612         ins = first;
18613         do {
18614                 /* If the triple is a variable give it a live range */
18615                 if (triple_is_def(state, ins)) {
18616                         struct reg_info info;
18617                         /* Find the architecture specific color information */
18618                         info = find_def_color(state, ins);
18619                         i++;
18620                         rstate->lr[i].defs    = &rstate->lrd[j];
18621                         rstate->lr[i].color   = info.reg;
18622                         rstate->lr[i].classes = info.regcm;
18623                         rstate->lr[i].degree  = 0;
18624                         rstate->lrd[j].lr = &rstate->lr[i];
18625                 } 
18626                 /* Otherwise give the triple the dummy live range. */
18627                 else {
18628                         rstate->lrd[j].lr = &rstate->lr[0];
18629                 }
18630
18631                 /* Initalize the live_range_def */
18632                 rstate->lrd[j].next    = &rstate->lrd[j];
18633                 rstate->lrd[j].prev    = &rstate->lrd[j];
18634                 rstate->lrd[j].def     = ins;
18635                 rstate->lrd[j].orig_id = ins->id;
18636                 ins->id = j;
18637
18638                 j++;
18639                 ins = ins->next;
18640         } while(ins != first);
18641         rstate->ranges = i;
18642
18643         /* Make a second pass to handle achitecture specific register
18644          * constraints.
18645          */
18646         ins = first;
18647         do {
18648                 int zlhs, zrhs, i, j;
18649                 if (ins->id > rstate->defs) {
18650                         internal_error(state, ins, "bad id");
18651                 }
18652                 
18653                 /* Walk through the template of ins and coalesce live ranges */
18654                 zlhs = ins->lhs;
18655                 if ((zlhs == 0) && triple_is_def(state, ins)) {
18656                         zlhs = 1;
18657                 }
18658                 zrhs = ins->rhs;
18659
18660                 if (state->compiler->debug & DEBUG_COALESCING2) {
18661                         fprintf(state->errout, "mandatory coalesce: %p %d %d\n",
18662                                 ins, zlhs, zrhs);
18663                 }
18664
18665                 for(i = 0; i < zlhs; i++) {
18666                         struct reg_info linfo;
18667                         struct live_range_def *lhs;
18668                         linfo = arch_reg_lhs(state, ins, i);
18669                         if (linfo.reg < MAX_REGISTERS) {
18670                                 continue;
18671                         }
18672                         if (triple_is_def(state, ins)) {
18673                                 lhs = &rstate->lrd[ins->id];
18674                         } else {
18675                                 lhs = &rstate->lrd[LHS(ins, i)->id];
18676                         }
18677
18678                         if (state->compiler->debug & DEBUG_COALESCING2) {
18679                                 fprintf(state->errout, "coalesce lhs(%d): %p %d\n",
18680                                         i, lhs, linfo.reg);
18681                         }
18682
18683                         for(j = 0; j < zrhs; j++) {
18684                                 struct reg_info rinfo;
18685                                 struct live_range_def *rhs;
18686                                 rinfo = arch_reg_rhs(state, ins, j);
18687                                 if (rinfo.reg < MAX_REGISTERS) {
18688                                         continue;
18689                                 }
18690                                 rhs = &rstate->lrd[RHS(ins, j)->id];
18691
18692                                 if (state->compiler->debug & DEBUG_COALESCING2) {
18693                                         fprintf(state->errout, "coalesce rhs(%d): %p %d\n",
18694                                                 j, rhs, rinfo.reg);
18695                                 }
18696
18697                                 if (rinfo.reg == linfo.reg) {
18698                                         coalesce_ranges(state, rstate, 
18699                                                 lhs->lr, rhs->lr);
18700                                 }
18701                         }
18702                 }
18703                 ins = ins->next;
18704         } while(ins != first);
18705 }
18706
18707 static void graph_ins(
18708         struct compile_state *state, 
18709         struct reg_block *blocks, struct triple_reg_set *live, 
18710         struct reg_block *rb, struct triple *ins, void *arg)
18711 {
18712         struct reg_state *rstate = arg;
18713         struct live_range *def;
18714         struct triple_reg_set *entry;
18715
18716         /* If the triple is not a definition
18717          * we do not have a definition to add to
18718          * the interference graph.
18719          */
18720         if (!triple_is_def(state, ins)) {
18721                 return;
18722         }
18723         def = rstate->lrd[ins->id].lr;
18724         
18725         /* Create an edge between ins and everything that is
18726          * alive, unless the live_range cannot share
18727          * a physical register with ins.
18728          */
18729         for(entry = live; entry; entry = entry->next) {
18730                 struct live_range *lr;
18731                 if ((entry->member->id < 0) || (entry->member->id > rstate->defs)) {
18732                         internal_error(state, 0, "bad entry?");
18733                 }
18734                 lr = rstate->lrd[entry->member->id].lr;
18735                 if (def == lr) {
18736                         continue;
18737                 }
18738                 if (!arch_regcm_intersect(def->classes, lr->classes)) {
18739                         continue;
18740                 }
18741                 add_live_edge(rstate, def, lr);
18742         }
18743         return;
18744 }
18745
18746 static struct live_range *get_verify_live_range(
18747         struct compile_state *state, struct reg_state *rstate, struct triple *ins)
18748 {
18749         struct live_range *lr;
18750         struct live_range_def *lrd;
18751         int ins_found;
18752         if ((ins->id < 0) || (ins->id > rstate->defs)) {
18753                 internal_error(state, ins, "bad ins?");
18754         }
18755         lr = rstate->lrd[ins->id].lr;
18756         ins_found = 0;
18757         lrd = lr->defs;
18758         do {
18759                 if (lrd->def == ins) {
18760                         ins_found = 1;
18761                 }
18762                 lrd = lrd->next;
18763         } while(lrd != lr->defs);
18764         if (!ins_found) {
18765                 internal_error(state, ins, "ins not in live range");
18766         }
18767         return lr;
18768 }
18769
18770 static void verify_graph_ins(
18771         struct compile_state *state, 
18772         struct reg_block *blocks, struct triple_reg_set *live, 
18773         struct reg_block *rb, struct triple *ins, void *arg)
18774 {
18775         struct reg_state *rstate = arg;
18776         struct triple_reg_set *entry1, *entry2;
18777
18778
18779         /* Compare live against edges and make certain the code is working */
18780         for(entry1 = live; entry1; entry1 = entry1->next) {
18781                 struct live_range *lr1;
18782                 lr1 = get_verify_live_range(state, rstate, entry1->member);
18783                 for(entry2 = live; entry2; entry2 = entry2->next) {
18784                         struct live_range *lr2;
18785                         struct live_range_edge *edge2;
18786                         int lr1_found;
18787                         int lr2_degree;
18788                         if (entry2 == entry1) {
18789                                 continue;
18790                         }
18791                         lr2 = get_verify_live_range(state, rstate, entry2->member);
18792                         if (lr1 == lr2) {
18793                                 internal_error(state, entry2->member, 
18794                                         "live range with 2 values simultaneously alive");
18795                         }
18796                         if (!arch_regcm_intersect(lr1->classes, lr2->classes)) {
18797                                 continue;
18798                         }
18799                         if (!interfere(rstate, lr1, lr2)) {
18800                                 internal_error(state, entry2->member, 
18801                                         "edges don't interfere?");
18802                         }
18803                                 
18804                         lr1_found = 0;
18805                         lr2_degree = 0;
18806                         for(edge2 = lr2->edges; edge2; edge2 = edge2->next) {
18807                                 lr2_degree++;
18808                                 if (edge2->node == lr1) {
18809                                         lr1_found = 1;
18810                                 }
18811                         }
18812                         if (lr2_degree != lr2->degree) {
18813                                 internal_error(state, entry2->member,
18814                                         "computed degree: %d does not match reported degree: %d\n",
18815                                         lr2_degree, lr2->degree);
18816                         }
18817                         if (!lr1_found) {
18818                                 internal_error(state, entry2->member, "missing edge");
18819                         }
18820                 }
18821         }
18822         return;
18823 }
18824
18825
18826 static void print_interference_ins(
18827         struct compile_state *state, 
18828         struct reg_block *blocks, struct triple_reg_set *live, 
18829         struct reg_block *rb, struct triple *ins, void *arg)
18830 {
18831         struct reg_state *rstate = arg;
18832         struct live_range *lr;
18833         unsigned id;
18834         FILE *fp = state->dbgout;
18835
18836         lr = rstate->lrd[ins->id].lr;
18837         id = ins->id;
18838         ins->id = rstate->lrd[id].orig_id;
18839         SET_REG(ins->id, lr->color);
18840         display_triple(state->dbgout, ins);
18841         ins->id = id;
18842
18843         if (lr->defs) {
18844                 struct live_range_def *lrd;
18845                 fprintf(fp, "       range:");
18846                 lrd = lr->defs;
18847                 do {
18848                         fprintf(fp, " %-10p", lrd->def);
18849                         lrd = lrd->next;
18850                 } while(lrd != lr->defs);
18851                 fprintf(fp, "\n");
18852         }
18853         if (live) {
18854                 struct triple_reg_set *entry;
18855                 fprintf(fp, "        live:");
18856                 for(entry = live; entry; entry = entry->next) {
18857                         fprintf(fp, " %-10p", entry->member);
18858                 }
18859                 fprintf(fp, "\n");
18860         }
18861         if (lr->edges) {
18862                 struct live_range_edge *entry;
18863                 fprintf(fp, "       edges:");
18864                 for(entry = lr->edges; entry; entry = entry->next) {
18865                         struct live_range_def *lrd;
18866                         lrd = entry->node->defs;
18867                         do {
18868                                 fprintf(fp, " %-10p", lrd->def);
18869                                 lrd = lrd->next;
18870                         } while(lrd != entry->node->defs);
18871                         fprintf(fp, "|");
18872                 }
18873                 fprintf(fp, "\n");
18874         }
18875         if (triple_is_branch(state, ins)) {
18876                 fprintf(fp, "\n");
18877         }
18878         return;
18879 }
18880
18881 static int coalesce_live_ranges(
18882         struct compile_state *state, struct reg_state *rstate)
18883 {
18884         /* At the point where a value is moved from one
18885          * register to another that value requires two
18886          * registers, thus increasing register pressure.
18887          * Live range coaleescing reduces the register
18888          * pressure by keeping a value in one register
18889          * longer.
18890          *
18891          * In the case of a phi function all paths leading
18892          * into it must be allocated to the same register
18893          * otherwise the phi function may not be removed.
18894          *
18895          * Forcing a value to stay in a single register
18896          * for an extended period of time does have
18897          * limitations when applied to non homogenous
18898          * register pool.  
18899          *
18900          * The two cases I have identified are:
18901          * 1) Two forced register assignments may
18902          *    collide.
18903          * 2) Registers may go unused because they
18904          *    are only good for storing the value
18905          *    and not manipulating it.
18906          *
18907          * Because of this I need to split live ranges,
18908          * even outside of the context of coalesced live
18909          * ranges.  The need to split live ranges does
18910          * impose some constraints on live range coalescing.
18911          *
18912          * - Live ranges may not be coalesced across phi
18913          *   functions.  This creates a 2 headed live
18914          *   range that cannot be sanely split.
18915          *
18916          * - phi functions (coalesced in initialize_live_ranges) 
18917          *   are handled as pre split live ranges so we will
18918          *   never attempt to split them.
18919          */
18920         int coalesced;
18921         int i;
18922
18923         coalesced = 0;
18924         for(i = 0; i <= rstate->ranges; i++) {
18925                 struct live_range *lr1;
18926                 struct live_range_def *lrd1;
18927                 lr1 = &rstate->lr[i];
18928                 if (!lr1->defs) {
18929                         continue;
18930                 }
18931                 lrd1 = live_range_end(state, lr1, 0);
18932                 for(; lrd1; lrd1 = live_range_end(state, lr1, lrd1)) {
18933                         struct triple_set *set;
18934                         if (lrd1->def->op != OP_COPY) {
18935                                 continue;
18936                         }
18937                         /* Skip copies that are the result of a live range split. */
18938                         if (lrd1->orig_id & TRIPLE_FLAG_POST_SPLIT) {
18939                                 continue;
18940                         }
18941                         for(set = lrd1->def->use; set; set = set->next) {
18942                                 struct live_range_def *lrd2;
18943                                 struct live_range *lr2, *res;
18944
18945                                 lrd2 = &rstate->lrd[set->member->id];
18946
18947                                 /* Don't coalesce with instructions
18948                                  * that are the result of a live range
18949                                  * split.
18950                                  */
18951                                 if (lrd2->orig_id & TRIPLE_FLAG_PRE_SPLIT) {
18952                                         continue;
18953                                 }
18954                                 lr2 = rstate->lrd[set->member->id].lr;
18955                                 if (lr1 == lr2) {
18956                                         continue;
18957                                 }
18958                                 if ((lr1->color != lr2->color) &&
18959                                         (lr1->color != REG_UNSET) &&
18960                                         (lr2->color != REG_UNSET)) {
18961                                         continue;
18962                                 }
18963                                 if ((lr1->classes & lr2->classes) == 0) {
18964                                         continue;
18965                                 }
18966                                 
18967                                 if (interfere(rstate, lr1, lr2)) {
18968                                         continue;
18969                                 }
18970
18971                                 res = coalesce_ranges(state, rstate, lr1, lr2);
18972                                 coalesced += 1;
18973                                 if (res != lr1) {
18974                                         goto next;
18975                                 }
18976                         }
18977                 }
18978         next:
18979                 ;
18980         }
18981         return coalesced;
18982 }
18983
18984
18985 static void fix_coalesce_conflicts(struct compile_state *state,
18986         struct reg_block *blocks, struct triple_reg_set *live,
18987         struct reg_block *rb, struct triple *ins, void *arg)
18988 {
18989         int *conflicts = arg;
18990         int zlhs, zrhs, i, j;
18991
18992         /* See if we have a mandatory coalesce operation between
18993          * a lhs and a rhs value.  If so and the rhs value is also
18994          * alive then this triple needs to be pre copied.  Otherwise
18995          * we would have two definitions in the same live range simultaneously
18996          * alive.
18997          */
18998         zlhs = ins->lhs;
18999         if ((zlhs == 0) && triple_is_def(state, ins)) {
19000                 zlhs = 1;
19001         }
19002         zrhs = ins->rhs;
19003         for(i = 0; i < zlhs; i++) {
19004                 struct reg_info linfo;
19005                 linfo = arch_reg_lhs(state, ins, i);
19006                 if (linfo.reg < MAX_REGISTERS) {
19007                         continue;
19008                 }
19009                 for(j = 0; j < zrhs; j++) {
19010                         struct reg_info rinfo;
19011                         struct triple *rhs;
19012                         struct triple_reg_set *set;
19013                         int found;
19014                         found = 0;
19015                         rinfo = arch_reg_rhs(state, ins, j);
19016                         if (rinfo.reg != linfo.reg) {
19017                                 continue;
19018                         }
19019                         rhs = RHS(ins, j);
19020                         for(set = live; set && !found; set = set->next) {
19021                                 if (set->member == rhs) {
19022                                         found = 1;
19023                                 }
19024                         }
19025                         if (found) {
19026                                 struct triple *copy;
19027                                 copy = pre_copy(state, ins, j);
19028                                 copy->id |= TRIPLE_FLAG_PRE_SPLIT;
19029                                 (*conflicts)++;
19030                         }
19031                 }
19032         }
19033         return;
19034 }
19035
19036 static int correct_coalesce_conflicts(
19037         struct compile_state *state, struct reg_block *blocks)
19038 {
19039         int conflicts;
19040         conflicts = 0;
19041         walk_variable_lifetimes(state, &state->bb, blocks, 
19042                 fix_coalesce_conflicts, &conflicts);
19043         return conflicts;
19044 }
19045
19046 static void replace_set_use(struct compile_state *state,
19047         struct triple_reg_set *head, struct triple *orig, struct triple *new)
19048 {
19049         struct triple_reg_set *set;
19050         for(set = head; set; set = set->next) {
19051                 if (set->member == orig) {
19052                         set->member = new;
19053                 }
19054         }
19055 }
19056
19057 static void replace_block_use(struct compile_state *state, 
19058         struct reg_block *blocks, struct triple *orig, struct triple *new)
19059 {
19060         int i;
19061 #warning "WISHLIST visit just those blocks that need it *"
19062         for(i = 1; i <= state->bb.last_vertex; i++) {
19063                 struct reg_block *rb;
19064                 rb = &blocks[i];
19065                 replace_set_use(state, rb->in, orig, new);
19066                 replace_set_use(state, rb->out, orig, new);
19067         }
19068 }
19069
19070 static void color_instructions(struct compile_state *state)
19071 {
19072         struct triple *ins, *first;
19073         first = state->first;
19074         ins = first;
19075         do {
19076                 if (triple_is_def(state, ins)) {
19077                         struct reg_info info;
19078                         info = find_lhs_color(state, ins, 0);
19079                         if (info.reg >= MAX_REGISTERS) {
19080                                 info.reg = REG_UNSET;
19081                         }
19082                         SET_INFO(ins->id, info);
19083                 }
19084                 ins = ins->next;
19085         } while(ins != first);
19086 }
19087
19088 static struct reg_info read_lhs_color(
19089         struct compile_state *state, struct triple *ins, int index)
19090 {
19091         struct reg_info info;
19092         if ((index == 0) && triple_is_def(state, ins)) {
19093                 info.reg   = ID_REG(ins->id);
19094                 info.regcm = ID_REGCM(ins->id);
19095         }
19096         else if (index < ins->lhs) {
19097                 info = read_lhs_color(state, LHS(ins, index), 0);
19098         }
19099         else {
19100                 internal_error(state, ins, "Bad lhs %d", index);
19101                 info.reg = REG_UNSET;
19102                 info.regcm = 0;
19103         }
19104         return info;
19105 }
19106
19107 static struct triple *resolve_tangle(
19108         struct compile_state *state, struct triple *tangle)
19109 {
19110         struct reg_info info, uinfo;
19111         struct triple_set *set, *next;
19112         struct triple *copy;
19113
19114 #warning "WISHLIST recalculate all affected instructions colors"
19115         info = find_lhs_color(state, tangle, 0);
19116         for(set = tangle->use; set; set = next) {
19117                 struct triple *user;
19118                 int i, zrhs;
19119                 next = set->next;
19120                 user = set->member;
19121                 zrhs = user->rhs;
19122                 for(i = 0; i < zrhs; i++) {
19123                         if (RHS(user, i) != tangle) {
19124                                 continue;
19125                         }
19126                         uinfo = find_rhs_post_color(state, user, i);
19127                         if (uinfo.reg == info.reg) {
19128                                 copy = pre_copy(state, user, i);
19129                                 copy->id |= TRIPLE_FLAG_PRE_SPLIT;
19130                                 SET_INFO(copy->id, uinfo);
19131                         }
19132                 }
19133         }
19134         copy = 0;
19135         uinfo = find_lhs_pre_color(state, tangle, 0);
19136         if (uinfo.reg == info.reg) {
19137                 struct reg_info linfo;
19138                 copy = post_copy(state, tangle);
19139                 copy->id |= TRIPLE_FLAG_PRE_SPLIT;
19140                 linfo = find_lhs_color(state, copy, 0);
19141                 SET_INFO(copy->id, linfo);
19142         }
19143         info = find_lhs_color(state, tangle, 0);
19144         SET_INFO(tangle->id, info);
19145         
19146         return copy;
19147 }
19148
19149
19150 static void fix_tangles(struct compile_state *state,
19151         struct reg_block *blocks, struct triple_reg_set *live,
19152         struct reg_block *rb, struct triple *ins, void *arg)
19153 {
19154         int *tangles = arg;
19155         struct triple *tangle;
19156         do {
19157                 char used[MAX_REGISTERS];
19158                 struct triple_reg_set *set;
19159                 tangle = 0;
19160
19161                 /* Find out which registers have multiple uses at this point */
19162                 memset(used, 0, sizeof(used));
19163                 for(set = live; set; set = set->next) {
19164                         struct reg_info info;
19165                         info = read_lhs_color(state, set->member, 0);
19166                         if (info.reg == REG_UNSET) {
19167                                 continue;
19168                         }
19169                         reg_inc_used(state, used, info.reg);
19170                 }
19171                 
19172                 /* Now find the least dominated definition of a register in
19173                  * conflict I have seen so far.
19174                  */
19175                 for(set = live; set; set = set->next) {
19176                         struct reg_info info;
19177                         info = read_lhs_color(state, set->member, 0);
19178                         if (used[info.reg] < 2) {
19179                                 continue;
19180                         }
19181                         /* Changing copies that feed into phi functions
19182                          * is incorrect.
19183                          */
19184                         if (set->member->use && 
19185                                 (set->member->use->member->op == OP_PHI)) {
19186                                 continue;
19187                         }
19188                         if (!tangle || tdominates(state, set->member, tangle)) {
19189                                 tangle = set->member;
19190                         }
19191                 }
19192                 /* If I have found a tangle resolve it */
19193                 if (tangle) {
19194                         struct triple *post_copy;
19195                         (*tangles)++;
19196                         post_copy = resolve_tangle(state, tangle);
19197                         if (post_copy) {
19198                                 replace_block_use(state, blocks, tangle, post_copy);
19199                         }
19200                         if (post_copy && (tangle != ins)) {
19201                                 replace_set_use(state, live, tangle, post_copy);
19202                         }
19203                 }
19204         } while(tangle);
19205         return;
19206 }
19207
19208 static int correct_tangles(
19209         struct compile_state *state, struct reg_block *blocks)
19210 {
19211         int tangles;
19212         tangles = 0;
19213         color_instructions(state);
19214         walk_variable_lifetimes(state, &state->bb, blocks, 
19215                 fix_tangles, &tangles);
19216         return tangles;
19217 }
19218
19219
19220 static void ids_from_rstate(struct compile_state *state, struct reg_state *rstate);
19221 static void cleanup_rstate(struct compile_state *state, struct reg_state *rstate);
19222
19223 struct triple *find_constrained_def(
19224         struct compile_state *state, struct live_range *range, struct triple *constrained)
19225 {
19226         struct live_range_def *lrd, *lrd_next;
19227         lrd_next = range->defs;
19228         do {
19229                 struct reg_info info;
19230                 unsigned regcm;
19231
19232                 lrd = lrd_next;
19233                 lrd_next = lrd->next;
19234
19235                 regcm = arch_type_to_regcm(state, lrd->def->type);
19236                 info = find_lhs_color(state, lrd->def, 0);
19237                 regcm      = arch_regcm_reg_normalize(state, regcm);
19238                 info.regcm = arch_regcm_reg_normalize(state, info.regcm);
19239                 /* If the 2 register class masks are equal then
19240                  * the current register class is not constrained.
19241                  */
19242                 if (regcm == info.regcm) {
19243                         continue;
19244                 }
19245                 
19246                 /* If there is just one use.
19247                  * That use cannot accept a larger register class.
19248                  * There are no intervening definitions except
19249                  * definitions that feed into that use.
19250                  * Then a triple is not constrained.
19251                  * FIXME handle this case!
19252                  */
19253 #warning "FIXME ignore cases that cannot be fixed (a definition followed by a use)"
19254                 
19255
19256                 /* Of the constrained live ranges deal with the
19257                  * least dominated one first.
19258                  */
19259                 if (state->compiler->debug & DEBUG_RANGE_CONFLICTS) {
19260                         fprintf(state->errout, "canidate: %p %-8s regcm: %x %x\n",
19261                                 lrd->def, tops(lrd->def->op), regcm, info.regcm);
19262                 }
19263                 if (!constrained || 
19264                         tdominates(state, lrd->def, constrained))
19265                 {
19266                         constrained = lrd->def;
19267                 }
19268         } while(lrd_next != range->defs);
19269         return constrained;
19270 }
19271
19272 static int split_constrained_ranges(
19273         struct compile_state *state, struct reg_state *rstate, 
19274         struct live_range *range)
19275 {
19276         /* Walk through the edges in conflict and our current live
19277          * range, and find definitions that are more severly constrained
19278          * than they type of data they contain require.
19279          * 
19280          * Then pick one of those ranges and relax the constraints.
19281          */
19282         struct live_range_edge *edge;
19283         struct triple *constrained;
19284
19285         constrained = 0;
19286         for(edge = range->edges; edge; edge = edge->next) {
19287                 constrained = find_constrained_def(state, edge->node, constrained);
19288         }
19289 #warning "FIXME should I call find_constrained_def here only if no previous constrained def was found?"
19290         if (!constrained) {
19291                 constrained = find_constrained_def(state, range, constrained);
19292         }
19293
19294         if (state->compiler->debug & DEBUG_RANGE_CONFLICTS) {
19295                 fprintf(state->errout, "constrained: ");
19296                 display_triple(state->errout, constrained);
19297         }
19298         if (constrained) {
19299                 ids_from_rstate(state, rstate);
19300                 cleanup_rstate(state, rstate);
19301                 resolve_tangle(state, constrained);
19302         }
19303         return !!constrained;
19304 }
19305         
19306 static int split_ranges(
19307         struct compile_state *state, struct reg_state *rstate,
19308         char *used, struct live_range *range)
19309 {
19310         int split;
19311         if (state->compiler->debug & DEBUG_RANGE_CONFLICTS) {
19312                 fprintf(state->errout, "split_ranges %d %s %p\n", 
19313                         rstate->passes, tops(range->defs->def->op), range->defs->def);
19314         }
19315         if ((range->color == REG_UNNEEDED) ||
19316                 (rstate->passes >= rstate->max_passes)) {
19317                 return 0;
19318         }
19319         split = split_constrained_ranges(state, rstate, range);
19320
19321         /* Ideally I would split the live range that will not be used
19322          * for the longest period of time in hopes that this will 
19323          * (a) allow me to spill a register or
19324          * (b) allow me to place a value in another register.
19325          *
19326          * So far I don't have a test case for this, the resolving
19327          * of mandatory constraints has solved all of my
19328          * know issues.  So I have choosen not to write any
19329          * code until I cat get a better feel for cases where
19330          * it would be useful to have.
19331          *
19332          */
19333 #warning "WISHLIST implement live range splitting..."
19334         
19335         if (!split && (state->compiler->debug & DEBUG_RANGE_CONFLICTS2)) {
19336                 FILE *fp = state->errout;
19337                 print_interference_blocks(state, rstate, fp, 0);
19338                 print_dominators(state, fp, &state->bb);
19339         }
19340         return split;
19341 }
19342
19343 static FILE *cgdebug_fp(struct compile_state *state)
19344 {
19345         FILE *fp;
19346         fp = 0;
19347         if (!fp && (state->compiler->debug & DEBUG_COLOR_GRAPH2)) {
19348                 fp = state->errout;
19349         }
19350         if (!fp && (state->compiler->debug & DEBUG_COLOR_GRAPH)) {
19351                 fp = state->dbgout;
19352         }
19353         return fp;
19354 }
19355
19356 static void cgdebug_printf(struct compile_state *state, const char *fmt, ...)
19357 {
19358         FILE *fp;
19359         fp = cgdebug_fp(state);
19360         if (fp) {
19361                 va_list args;
19362                 va_start(args, fmt);
19363                 vfprintf(fp, fmt, args);
19364                 va_end(args);
19365         }
19366 }
19367
19368 static void cgdebug_flush(struct compile_state *state)
19369 {
19370         FILE *fp;
19371         fp = cgdebug_fp(state);
19372         if (fp) {
19373                 fflush(fp);
19374         }
19375 }
19376
19377 static void cgdebug_loc(struct compile_state *state, struct triple *ins)
19378 {
19379         FILE *fp;
19380         fp = cgdebug_fp(state);
19381         if (fp) {
19382                 loc(fp, state, ins);
19383         }
19384 }
19385
19386 static int select_free_color(struct compile_state *state, 
19387         struct reg_state *rstate, struct live_range *range)
19388 {
19389         struct triple_set *entry;
19390         struct live_range_def *lrd;
19391         struct live_range_def *phi;
19392         struct live_range_edge *edge;
19393         char used[MAX_REGISTERS];
19394         struct triple **expr;
19395
19396         /* Instead of doing just the trivial color select here I try
19397          * a few extra things because a good color selection will help reduce
19398          * copies.
19399          */
19400
19401         /* Find the registers currently in use */
19402         memset(used, 0, sizeof(used));
19403         for(edge = range->edges; edge; edge = edge->next) {
19404                 if (edge->node->color == REG_UNSET) {
19405                         continue;
19406                 }
19407                 reg_fill_used(state, used, edge->node->color);
19408         }
19409
19410         if (state->compiler->debug & DEBUG_COLOR_GRAPH2) {
19411                 int i;
19412                 i = 0;
19413                 for(edge = range->edges; edge; edge = edge->next) {
19414                         i++;
19415                 }
19416                 cgdebug_printf(state, "\n%s edges: %d", 
19417                         tops(range->defs->def->op), i);
19418                 cgdebug_loc(state, range->defs->def);
19419                 cgdebug_printf(state, "\n");
19420                 for(i = 0; i < MAX_REGISTERS; i++) {
19421                         if (used[i]) {
19422                                 cgdebug_printf(state, "used: %s\n",
19423                                         arch_reg_str(i));
19424                         }
19425                 }
19426         }       
19427
19428         /* If a color is already assigned see if it will work */
19429         if (range->color != REG_UNSET) {
19430                 struct live_range_def *lrd;
19431                 if (!used[range->color]) {
19432                         return 1;
19433                 }
19434                 for(edge = range->edges; edge; edge = edge->next) {
19435                         if (edge->node->color != range->color) {
19436                                 continue;
19437                         }
19438                         warning(state, edge->node->defs->def, "edge: ");
19439                         lrd = edge->node->defs;
19440                         do {
19441                                 warning(state, lrd->def, " %p %s",
19442                                         lrd->def, tops(lrd->def->op));
19443                                 lrd = lrd->next;
19444                         } while(lrd != edge->node->defs);
19445                 }
19446                 lrd = range->defs;
19447                 warning(state, range->defs->def, "def: ");
19448                 do {
19449                         warning(state, lrd->def, " %p %s",
19450                                 lrd->def, tops(lrd->def->op));
19451                         lrd = lrd->next;
19452                 } while(lrd != range->defs);
19453                 internal_error(state, range->defs->def,
19454                         "live range with already used color %s",
19455                         arch_reg_str(range->color));
19456         }
19457
19458         /* If I feed into an expression reuse it's color.
19459          * This should help remove copies in the case of 2 register instructions
19460          * and phi functions.
19461          */
19462         phi = 0;
19463         lrd = live_range_end(state, range, 0);
19464         for(; (range->color == REG_UNSET) && lrd ; lrd = live_range_end(state, range, lrd)) {
19465                 entry = lrd->def->use;
19466                 for(;(range->color == REG_UNSET) && entry; entry = entry->next) {
19467                         struct live_range_def *insd;
19468                         unsigned regcm;
19469                         insd = &rstate->lrd[entry->member->id];
19470                         if (insd->lr->defs == 0) {
19471                                 continue;
19472                         }
19473                         if (!phi && (insd->def->op == OP_PHI) &&
19474                                 !interfere(rstate, range, insd->lr)) {
19475                                 phi = insd;
19476                         }
19477                         if (insd->lr->color == REG_UNSET) {
19478                                 continue;
19479                         }
19480                         regcm = insd->lr->classes;
19481                         if (((regcm & range->classes) == 0) ||
19482                                 (used[insd->lr->color])) {
19483                                 continue;
19484                         }
19485                         if (interfere(rstate, range, insd->lr)) {
19486                                 continue;
19487                         }
19488                         range->color = insd->lr->color;
19489                 }
19490         }
19491         /* If I feed into a phi function reuse it's color or the color
19492          * of something else that feeds into the phi function.
19493          */
19494         if (phi) {
19495                 if (phi->lr->color != REG_UNSET) {
19496                         if (used[phi->lr->color]) {
19497                                 range->color = phi->lr->color;
19498                         }
19499                 }
19500                 else {
19501                         expr = triple_rhs(state, phi->def, 0);
19502                         for(; expr; expr = triple_rhs(state, phi->def, expr)) {
19503                                 struct live_range *lr;
19504                                 unsigned regcm;
19505                                 if (!*expr) {
19506                                         continue;
19507                                 }
19508                                 lr = rstate->lrd[(*expr)->id].lr;
19509                                 if (lr->color == REG_UNSET) {
19510                                         continue;
19511                                 }
19512                                 regcm = lr->classes;
19513                                 if (((regcm & range->classes) == 0) ||
19514                                         (used[lr->color])) {
19515                                         continue;
19516                                 }
19517                                 if (interfere(rstate, range, lr)) {
19518                                         continue;
19519                                 }
19520                                 range->color = lr->color;
19521                         }
19522                 }
19523         }
19524         /* If I don't interfere with a rhs node reuse it's color */
19525         lrd = live_range_head(state, range, 0);
19526         for(; (range->color == REG_UNSET) && lrd ; lrd = live_range_head(state, range, lrd)) {
19527                 expr = triple_rhs(state, lrd->def, 0);
19528                 for(; expr; expr = triple_rhs(state, lrd->def, expr)) {
19529                         struct live_range *lr;
19530                         unsigned regcm;
19531                         if (!*expr) {
19532                                 continue;
19533                         }
19534                         lr = rstate->lrd[(*expr)->id].lr;
19535                         if (lr->color == REG_UNSET) {
19536                                 continue;
19537                         }
19538                         regcm = lr->classes;
19539                         if (((regcm & range->classes) == 0) ||
19540                                 (used[lr->color])) {
19541                                 continue;
19542                         }
19543                         if (interfere(rstate, range, lr)) {
19544                                 continue;
19545                         }
19546                         range->color = lr->color;
19547                         break;
19548                 }
19549         }
19550         /* If I have not opportunitically picked a useful color
19551          * pick the first color that is free.
19552          */
19553         if (range->color == REG_UNSET) {
19554                 range->color = 
19555                         arch_select_free_register(state, used, range->classes);
19556         }
19557         if (range->color == REG_UNSET) {
19558                 struct live_range_def *lrd;
19559                 int i;
19560                 if (split_ranges(state, rstate, used, range)) {
19561                         return 0;
19562                 }
19563                 for(edge = range->edges; edge; edge = edge->next) {
19564                         warning(state, edge->node->defs->def, "edge reg %s",
19565                                 arch_reg_str(edge->node->color));
19566                         lrd = edge->node->defs;
19567                         do {
19568                                 warning(state, lrd->def, " %s %p",
19569                                         tops(lrd->def->op), lrd->def);
19570                                 lrd = lrd->next;
19571                         } while(lrd != edge->node->defs);
19572                 }
19573                 warning(state, range->defs->def, "range: ");
19574                 lrd = range->defs;
19575                 do {
19576                         warning(state, lrd->def, " %s %p",
19577                                 tops(lrd->def->op), lrd->def);
19578                         lrd = lrd->next;
19579                 } while(lrd != range->defs);
19580                         
19581                 warning(state, range->defs->def, "classes: %x",
19582                         range->classes);
19583                 for(i = 0; i < MAX_REGISTERS; i++) {
19584                         if (used[i]) {
19585                                 warning(state, range->defs->def, "used: %s",
19586                                         arch_reg_str(i));
19587                         }
19588                 }
19589                 error(state, range->defs->def, "too few registers");
19590         }
19591         range->classes &= arch_reg_regcm(state, range->color);
19592         if ((range->color == REG_UNSET) || (range->classes == 0)) {
19593                 internal_error(state, range->defs->def, "select_free_color did not?");
19594         }
19595         return 1;
19596 }
19597
19598 static int color_graph(struct compile_state *state, struct reg_state *rstate)
19599 {
19600         int colored;
19601         struct live_range_edge *edge;
19602         struct live_range *range;
19603         if (rstate->low) {
19604                 cgdebug_printf(state, "Lo: ");
19605                 range = rstate->low;
19606                 if (*range->group_prev != range) {
19607                         internal_error(state, 0, "lo: *prev != range?");
19608                 }
19609                 *range->group_prev = range->group_next;
19610                 if (range->group_next) {
19611                         range->group_next->group_prev = range->group_prev;
19612                 }
19613                 if (&range->group_next == rstate->low_tail) {
19614                         rstate->low_tail = range->group_prev;
19615                 }
19616                 if (rstate->low == range) {
19617                         internal_error(state, 0, "low: next != prev?");
19618                 }
19619         }
19620         else if (rstate->high) {
19621                 cgdebug_printf(state, "Hi: ");
19622                 range = rstate->high;
19623                 if (*range->group_prev != range) {
19624                         internal_error(state, 0, "hi: *prev != range?");
19625                 }
19626                 *range->group_prev = range->group_next;
19627                 if (range->group_next) {
19628                         range->group_next->group_prev = range->group_prev;
19629                 }
19630                 if (&range->group_next == rstate->high_tail) {
19631                         rstate->high_tail = range->group_prev;
19632                 }
19633                 if (rstate->high == range) {
19634                         internal_error(state, 0, "high: next != prev?");
19635                 }
19636         }
19637         else {
19638                 return 1;
19639         }
19640         cgdebug_printf(state, " %d\n", range - rstate->lr);
19641         range->group_prev = 0;
19642         for(edge = range->edges; edge; edge = edge->next) {
19643                 struct live_range *node;
19644                 node = edge->node;
19645                 /* Move nodes from the high to the low list */
19646                 if (node->group_prev && (node->color == REG_UNSET) &&
19647                         (node->degree == regc_max_size(state, node->classes))) {
19648                         if (*node->group_prev != node) {
19649                                 internal_error(state, 0, "move: *prev != node?");
19650                         }
19651                         *node->group_prev = node->group_next;
19652                         if (node->group_next) {
19653                                 node->group_next->group_prev = node->group_prev;
19654                         }
19655                         if (&node->group_next == rstate->high_tail) {
19656                                 rstate->high_tail = node->group_prev;
19657                         }
19658                         cgdebug_printf(state, "Moving...%d to low\n", node - rstate->lr);
19659                         node->group_prev  = rstate->low_tail;
19660                         node->group_next  = 0;
19661                         *rstate->low_tail = node;
19662                         rstate->low_tail  = &node->group_next;
19663                         if (*node->group_prev != node) {
19664                                 internal_error(state, 0, "move2: *prev != node?");
19665                         }
19666                 }
19667                 node->degree -= 1;
19668         }
19669         colored = color_graph(state, rstate);
19670         if (colored) {
19671                 cgdebug_printf(state, "Coloring %d @", range - rstate->lr);
19672                 cgdebug_loc(state, range->defs->def);
19673                 cgdebug_flush(state);
19674                 colored = select_free_color(state, rstate, range);
19675                 if (colored) {
19676                         cgdebug_printf(state, " %s\n", arch_reg_str(range->color));
19677                 }
19678         }
19679         return colored;
19680 }
19681
19682 static void verify_colors(struct compile_state *state, struct reg_state *rstate)
19683 {
19684         struct live_range *lr;
19685         struct live_range_edge *edge;
19686         struct triple *ins, *first;
19687         char used[MAX_REGISTERS];
19688         first = state->first;
19689         ins = first;
19690         do {
19691                 if (triple_is_def(state, ins)) {
19692                         if ((ins->id < 0) || (ins->id > rstate->defs)) {
19693                                 internal_error(state, ins, 
19694                                         "triple without a live range def");
19695                         }
19696                         lr = rstate->lrd[ins->id].lr;
19697                         if (lr->color == REG_UNSET) {
19698                                 internal_error(state, ins,
19699                                         "triple without a color");
19700                         }
19701                         /* Find the registers used by the edges */
19702                         memset(used, 0, sizeof(used));
19703                         for(edge = lr->edges; edge; edge = edge->next) {
19704                                 if (edge->node->color == REG_UNSET) {
19705                                         internal_error(state, 0,
19706                                                 "live range without a color");
19707                         }
19708                                 reg_fill_used(state, used, edge->node->color);
19709                         }
19710                         if (used[lr->color]) {
19711                                 internal_error(state, ins,
19712                                         "triple with already used color");
19713                         }
19714                 }
19715                 ins = ins->next;
19716         } while(ins != first);
19717 }
19718
19719 static void color_triples(struct compile_state *state, struct reg_state *rstate)
19720 {
19721         struct live_range_def *lrd;
19722         struct live_range *lr;
19723         struct triple *first, *ins;
19724         first = state->first;
19725         ins = first;
19726         do {
19727                 if ((ins->id < 0) || (ins->id > rstate->defs)) {
19728                         internal_error(state, ins, 
19729                                 "triple without a live range");
19730                 }
19731                 lrd = &rstate->lrd[ins->id];
19732                 lr = lrd->lr;
19733                 ins->id = lrd->orig_id;
19734                 SET_REG(ins->id, lr->color);
19735                 ins = ins->next;
19736         } while (ins != first);
19737 }
19738
19739 static struct live_range *merge_sort_lr(
19740         struct live_range *first, struct live_range *last)
19741 {
19742         struct live_range *mid, *join, **join_tail, *pick;
19743         size_t size;
19744         size = (last - first) + 1;
19745         if (size >= 2) {
19746                 mid = first + size/2;
19747                 first = merge_sort_lr(first, mid -1);
19748                 mid   = merge_sort_lr(mid, last);
19749                 
19750                 join = 0;
19751                 join_tail = &join;
19752                 /* merge the two lists */
19753                 while(first && mid) {
19754                         if ((first->degree < mid->degree) ||
19755                                 ((first->degree == mid->degree) &&
19756                                         (first->length < mid->length))) {
19757                                 pick = first;
19758                                 first = first->group_next;
19759                                 if (first) {
19760                                         first->group_prev = 0;
19761                                 }
19762                         }
19763                         else {
19764                                 pick = mid;
19765                                 mid = mid->group_next;
19766                                 if (mid) {
19767                                         mid->group_prev = 0;
19768                                 }
19769                         }
19770                         pick->group_next = 0;
19771                         pick->group_prev = join_tail;
19772                         *join_tail = pick;
19773                         join_tail = &pick->group_next;
19774                 }
19775                 /* Splice the remaining list */
19776                 pick = (first)? first : mid;
19777                 *join_tail = pick;
19778                 if (pick) { 
19779                         pick->group_prev = join_tail;
19780                 }
19781         }
19782         else {
19783                 if (!first->defs) {
19784                         first = 0;
19785                 }
19786                 join = first;
19787         }
19788         return join;
19789 }
19790
19791 static void ids_from_rstate(struct compile_state *state, 
19792         struct reg_state *rstate)
19793 {
19794         struct triple *ins, *first;
19795         if (!rstate->defs) {
19796                 return;
19797         }
19798         /* Display the graph if desired */
19799         if (state->compiler->debug & DEBUG_INTERFERENCE) {
19800                 FILE *fp = state->dbgout;
19801                 print_interference_blocks(state, rstate, fp, 0);
19802                 print_control_flow(state, fp, &state->bb);
19803                 fflush(fp);
19804         }
19805         first = state->first;
19806         ins = first;
19807         do {
19808                 if (ins->id) {
19809                         struct live_range_def *lrd;
19810                         lrd = &rstate->lrd[ins->id];
19811                         ins->id = lrd->orig_id;
19812                 }
19813                 ins = ins->next;
19814         } while(ins != first);
19815 }
19816
19817 static void cleanup_live_edges(struct reg_state *rstate)
19818 {
19819         int i;
19820         /* Free the edges on each node */
19821         for(i = 1; i <= rstate->ranges; i++) {
19822                 remove_live_edges(rstate, &rstate->lr[i]);
19823         }
19824 }
19825
19826 static void cleanup_rstate(struct compile_state *state, struct reg_state *rstate)
19827 {
19828         cleanup_live_edges(rstate);
19829         xfree(rstate->lrd);
19830         xfree(rstate->lr);
19831
19832         /* Free the variable lifetime information */
19833         if (rstate->blocks) {
19834                 free_variable_lifetimes(state, &state->bb, rstate->blocks);
19835         }
19836         rstate->defs = 0;
19837         rstate->ranges = 0;
19838         rstate->lrd = 0;
19839         rstate->lr = 0;
19840         rstate->blocks = 0;
19841 }
19842
19843 static void verify_consistency(struct compile_state *state);
19844 static void allocate_registers(struct compile_state *state)
19845 {
19846         struct reg_state rstate;
19847         int colored;
19848
19849         /* Clear out the reg_state */
19850         memset(&rstate, 0, sizeof(rstate));
19851         rstate.max_passes = state->compiler->max_allocation_passes;
19852
19853         do {
19854                 struct live_range **point, **next;
19855                 int conflicts;
19856                 int tangles;
19857                 int coalesced;
19858
19859                 if (state->compiler->debug & DEBUG_RANGE_CONFLICTS) {
19860                         FILE *fp = state->errout;
19861                         fprintf(fp, "pass: %d\n", rstate.passes);
19862                         fflush(fp);
19863                 }
19864
19865                 /* Restore ids */
19866                 ids_from_rstate(state, &rstate);
19867
19868                 /* Cleanup the temporary data structures */
19869                 cleanup_rstate(state, &rstate);
19870
19871                 /* Compute the variable lifetimes */
19872                 rstate.blocks = compute_variable_lifetimes(state, &state->bb);
19873
19874                 /* Fix invalid mandatory live range coalesce conflicts */
19875                 conflicts = correct_coalesce_conflicts(state, rstate.blocks);
19876
19877                 /* Fix two simultaneous uses of the same register.
19878                  * In a few pathlogical cases a partial untangle moves
19879                  * the tangle to a part of the graph we won't revisit.
19880                  * So we keep looping until we have no more tangle fixes
19881                  * to apply.
19882                  */
19883                 do {
19884                         tangles = correct_tangles(state, rstate.blocks);
19885                 } while(tangles);
19886
19887                 
19888                 print_blocks(state, "resolve_tangles", state->dbgout);
19889                 verify_consistency(state);
19890                 
19891                 /* Allocate and initialize the live ranges */
19892                 initialize_live_ranges(state, &rstate);
19893
19894                 /* Note currently doing coalescing in a loop appears to 
19895                  * buys me nothing.  The code is left this way in case
19896                  * there is some value in it.  Or if a future bugfix
19897                  * yields some benefit.
19898                  */
19899                 do {
19900                         if (state->compiler->debug & DEBUG_COALESCING) {
19901                                 fprintf(state->errout, "coalescing\n");
19902                         }
19903
19904                         /* Remove any previous live edge calculations */
19905                         cleanup_live_edges(&rstate);
19906
19907                         /* Compute the interference graph */
19908                         walk_variable_lifetimes(
19909                                 state, &state->bb, rstate.blocks, 
19910                                 graph_ins, &rstate);
19911                         
19912                         /* Display the interference graph if desired */
19913                         if (state->compiler->debug & DEBUG_INTERFERENCE) {
19914                                 print_interference_blocks(state, &rstate, state->dbgout, 1);
19915                                 fprintf(state->dbgout, "\nlive variables by instruction\n");
19916                                 walk_variable_lifetimes(
19917                                         state, &state->bb, rstate.blocks, 
19918                                         print_interference_ins, &rstate);
19919                         }
19920                         
19921                         coalesced = coalesce_live_ranges(state, &rstate);
19922
19923                         if (state->compiler->debug & DEBUG_COALESCING) {
19924                                 fprintf(state->errout, "coalesced: %d\n", coalesced);
19925                         }
19926                 } while(coalesced);
19927
19928 #if DEBUG_CONSISTENCY > 1
19929 # if 0
19930                 fprintf(state->errout, "verify_graph_ins...\n");
19931 # endif
19932                 /* Verify the interference graph */
19933                 walk_variable_lifetimes(
19934                         state, &state->bb, rstate.blocks, 
19935                         verify_graph_ins, &rstate);
19936 # if 0
19937                 fprintf(state->errout, "verify_graph_ins done\n");
19938 #endif
19939 #endif
19940                         
19941                 /* Build the groups low and high.  But with the nodes
19942                  * first sorted by degree order.
19943                  */
19944                 rstate.low_tail  = &rstate.low;
19945                 rstate.high_tail = &rstate.high;
19946                 rstate.high = merge_sort_lr(&rstate.lr[1], &rstate.lr[rstate.ranges]);
19947                 if (rstate.high) {
19948                         rstate.high->group_prev = &rstate.high;
19949                 }
19950                 for(point = &rstate.high; *point; point = &(*point)->group_next)
19951                         ;
19952                 rstate.high_tail = point;
19953                 /* Walk through the high list and move everything that needs
19954                  * to be onto low.
19955                  */
19956                 for(point = &rstate.high; *point; point = next) {
19957                         struct live_range *range;
19958                         next = &(*point)->group_next;
19959                         range = *point;
19960                         
19961                         /* If it has a low degree or it already has a color
19962                          * place the node in low.
19963                          */
19964                         if ((range->degree < regc_max_size(state, range->classes)) ||
19965                                 (range->color != REG_UNSET)) {
19966                                 cgdebug_printf(state, "Lo: %5d degree %5d%s\n", 
19967                                         range - rstate.lr, range->degree,
19968                                         (range->color != REG_UNSET) ? " (colored)": "");
19969                                 *range->group_prev = range->group_next;
19970                                 if (range->group_next) {
19971                                         range->group_next->group_prev = range->group_prev;
19972                                 }
19973                                 if (&range->group_next == rstate.high_tail) {
19974                                         rstate.high_tail = range->group_prev;
19975                                 }
19976                                 range->group_prev  = rstate.low_tail;
19977                                 range->group_next  = 0;
19978                                 *rstate.low_tail   = range;
19979                                 rstate.low_tail    = &range->group_next;
19980                                 next = point;
19981                         }
19982                         else {
19983                                 cgdebug_printf(state, "hi: %5d degree %5d%s\n", 
19984                                         range - rstate.lr, range->degree,
19985                                         (range->color != REG_UNSET) ? " (colored)": "");
19986                         }
19987                 }
19988                 /* Color the live_ranges */
19989                 colored = color_graph(state, &rstate);
19990                 rstate.passes++;
19991         } while (!colored);
19992
19993         /* Verify the graph was properly colored */
19994         verify_colors(state, &rstate);
19995
19996         /* Move the colors from the graph to the triples */
19997         color_triples(state, &rstate);
19998
19999         /* Cleanup the temporary data structures */
20000         cleanup_rstate(state, &rstate);
20001
20002         /* Display the new graph */
20003         print_blocks(state, __func__, state->dbgout);
20004 }
20005
20006 /* Sparce Conditional Constant Propogation
20007  * =========================================
20008  */
20009 struct ssa_edge;
20010 struct flow_block;
20011 struct lattice_node {
20012         unsigned old_id;
20013         struct triple *def;
20014         struct ssa_edge *out;
20015         struct flow_block *fblock;
20016         struct triple *val;
20017         /* lattice high   val == def
20018          * lattice const  is_const(val)
20019          * lattice low    other
20020          */
20021 };
20022 struct ssa_edge {
20023         struct lattice_node *src;
20024         struct lattice_node *dst;
20025         struct ssa_edge *work_next;
20026         struct ssa_edge *work_prev;
20027         struct ssa_edge *out_next;
20028 };
20029 struct flow_edge {
20030         struct flow_block *src;
20031         struct flow_block *dst;
20032         struct flow_edge *work_next;
20033         struct flow_edge *work_prev;
20034         struct flow_edge *in_next;
20035         struct flow_edge *out_next;
20036         int executable;
20037 };
20038 #define MAX_FLOW_BLOCK_EDGES 3
20039 struct flow_block {
20040         struct block *block;
20041         struct flow_edge *in;
20042         struct flow_edge *out;
20043         struct flow_edge *edges;
20044 };
20045
20046 struct scc_state {
20047         int ins_count;
20048         struct lattice_node *lattice;
20049         struct ssa_edge     *ssa_edges;
20050         struct flow_block   *flow_blocks;
20051         struct flow_edge    *flow_work_list;
20052         struct ssa_edge     *ssa_work_list;
20053 };
20054
20055
20056 static int is_scc_const(struct compile_state *state, struct triple *ins)
20057 {
20058         return ins && (triple_is_ubranch(state, ins) || is_const(ins));
20059 }
20060
20061 static int is_lattice_hi(struct compile_state *state, struct lattice_node *lnode)
20062 {
20063         return !is_scc_const(state, lnode->val) && (lnode->val == lnode->def);
20064 }
20065
20066 static int is_lattice_const(struct compile_state *state, struct lattice_node *lnode)
20067 {
20068         return is_scc_const(state, lnode->val);
20069 }
20070
20071 static int is_lattice_lo(struct compile_state *state, struct lattice_node *lnode)
20072 {
20073         return (lnode->val != lnode->def) && !is_scc_const(state, lnode->val);
20074 }
20075
20076 static void scc_add_fedge(struct compile_state *state, struct scc_state *scc, 
20077         struct flow_edge *fedge)
20078 {
20079         if (state->compiler->debug & DEBUG_SCC_TRANSFORM2) {
20080                 fprintf(state->errout, "adding fedge: %p (%4d -> %5d)\n",
20081                         fedge,
20082                         fedge->src->block?fedge->src->block->last->id: 0,
20083                         fedge->dst->block?fedge->dst->block->first->id: 0);
20084         }
20085         if ((fedge == scc->flow_work_list) ||
20086                 (fedge->work_next != fedge) ||
20087                 (fedge->work_prev != fedge)) {
20088
20089                 if (state->compiler->debug & DEBUG_SCC_TRANSFORM2) {
20090                         fprintf(state->errout, "dupped fedge: %p\n",
20091                                 fedge);
20092                 }
20093                 return;
20094         }
20095         if (!scc->flow_work_list) {
20096                 scc->flow_work_list = fedge;
20097                 fedge->work_next = fedge->work_prev = fedge;
20098         }
20099         else {
20100                 struct flow_edge *ftail;
20101                 ftail = scc->flow_work_list->work_prev;
20102                 fedge->work_next = ftail->work_next;
20103                 fedge->work_prev = ftail;
20104                 fedge->work_next->work_prev = fedge;
20105                 fedge->work_prev->work_next = fedge;
20106         }
20107 }
20108
20109 static struct flow_edge *scc_next_fedge(
20110         struct compile_state *state, struct scc_state *scc)
20111 {
20112         struct flow_edge *fedge;
20113         fedge = scc->flow_work_list;
20114         if (fedge) {
20115                 fedge->work_next->work_prev = fedge->work_prev;
20116                 fedge->work_prev->work_next = fedge->work_next;
20117                 if (fedge->work_next != fedge) {
20118                         scc->flow_work_list = fedge->work_next;
20119                 } else {
20120                         scc->flow_work_list = 0;
20121                 }
20122                 fedge->work_next = fedge->work_prev = fedge;
20123         }
20124         return fedge;
20125 }
20126
20127 static void scc_add_sedge(struct compile_state *state, struct scc_state *scc,
20128         struct ssa_edge *sedge)
20129 {
20130         if (state->compiler->debug & DEBUG_SCC_TRANSFORM2) {
20131                 fprintf(state->errout, "adding sedge: %5d (%4d -> %5d)\n",
20132                         sedge - scc->ssa_edges,
20133                         sedge->src->def->id,
20134                         sedge->dst->def->id);
20135         }
20136         if ((sedge == scc->ssa_work_list) ||
20137                 (sedge->work_next != sedge) ||
20138                 (sedge->work_prev != sedge)) {
20139
20140                 if (state->compiler->debug & DEBUG_SCC_TRANSFORM2) {
20141                         fprintf(state->errout, "dupped sedge: %5d\n",
20142                                 sedge - scc->ssa_edges);
20143                 }
20144                 return;
20145         }
20146         if (!scc->ssa_work_list) {
20147                 scc->ssa_work_list = sedge;
20148                 sedge->work_next = sedge->work_prev = sedge;
20149         }
20150         else {
20151                 struct ssa_edge *stail;
20152                 stail = scc->ssa_work_list->work_prev;
20153                 sedge->work_next = stail->work_next;
20154                 sedge->work_prev = stail;
20155                 sedge->work_next->work_prev = sedge;
20156                 sedge->work_prev->work_next = sedge;
20157         }
20158 }
20159
20160 static struct ssa_edge *scc_next_sedge(
20161         struct compile_state *state, struct scc_state *scc)
20162 {
20163         struct ssa_edge *sedge;
20164         sedge = scc->ssa_work_list;
20165         if (sedge) {
20166                 sedge->work_next->work_prev = sedge->work_prev;
20167                 sedge->work_prev->work_next = sedge->work_next;
20168                 if (sedge->work_next != sedge) {
20169                         scc->ssa_work_list = sedge->work_next;
20170                 } else {
20171                         scc->ssa_work_list = 0;
20172                 }
20173                 sedge->work_next = sedge->work_prev = sedge;
20174         }
20175         return sedge;
20176 }
20177
20178 static void initialize_scc_state(
20179         struct compile_state *state, struct scc_state *scc)
20180 {
20181         int ins_count, ssa_edge_count;
20182         int ins_index, ssa_edge_index, fblock_index;
20183         struct triple *first, *ins;
20184         struct block *block;
20185         struct flow_block *fblock;
20186
20187         memset(scc, 0, sizeof(*scc));
20188
20189         /* Inialize pass zero find out how much memory we need */
20190         first = state->first;
20191         ins = first;
20192         ins_count = ssa_edge_count = 0;
20193         do {
20194                 struct triple_set *edge;
20195                 ins_count += 1;
20196                 for(edge = ins->use; edge; edge = edge->next) {
20197                         ssa_edge_count++;
20198                 }
20199                 ins = ins->next;
20200         } while(ins != first);
20201         if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
20202                 fprintf(state->errout, "ins_count: %d ssa_edge_count: %d vertex_count: %d\n",
20203                         ins_count, ssa_edge_count, state->bb.last_vertex);
20204         }
20205         scc->ins_count   = ins_count;
20206         scc->lattice     = 
20207                 xcmalloc(sizeof(*scc->lattice)*(ins_count + 1), "lattice");
20208         scc->ssa_edges   = 
20209                 xcmalloc(sizeof(*scc->ssa_edges)*(ssa_edge_count + 1), "ssa_edges");
20210         scc->flow_blocks = 
20211                 xcmalloc(sizeof(*scc->flow_blocks)*(state->bb.last_vertex + 1), 
20212                         "flow_blocks");
20213
20214         /* Initialize pass one collect up the nodes */
20215         fblock = 0;
20216         block = 0;
20217         ins_index = ssa_edge_index = fblock_index = 0;
20218         ins = first;
20219         do {
20220                 if ((ins->op == OP_LABEL) && (block != ins->u.block)) {
20221                         block = ins->u.block;
20222                         if (!block) {
20223                                 internal_error(state, ins, "label without block");
20224                         }
20225                         fblock_index += 1;
20226                         block->vertex = fblock_index;
20227                         fblock = &scc->flow_blocks[fblock_index];
20228                         fblock->block = block;
20229                         fblock->edges = xcmalloc(sizeof(*fblock->edges)*block->edge_count,
20230                                 "flow_edges");
20231                 }
20232                 {
20233                         struct lattice_node *lnode;
20234                         ins_index += 1;
20235                         lnode = &scc->lattice[ins_index];
20236                         lnode->def = ins;
20237                         lnode->out = 0;
20238                         lnode->fblock = fblock;
20239                         lnode->val = ins; /* LATTICE HIGH */
20240                         if (lnode->val->op == OP_UNKNOWNVAL) {
20241                                 lnode->val = 0; /* LATTICE LOW by definition */
20242                         }
20243                         lnode->old_id = ins->id;
20244                         ins->id = ins_index;
20245                 }
20246                 ins = ins->next;
20247         } while(ins != first);
20248         /* Initialize pass two collect up the edges */
20249         block = 0;
20250         fblock = 0;
20251         ins = first;
20252         do {
20253                 {
20254                         struct triple_set *edge;
20255                         struct ssa_edge **stail;
20256                         struct lattice_node *lnode;
20257                         lnode = &scc->lattice[ins->id];
20258                         lnode->out = 0;
20259                         stail = &lnode->out;
20260                         for(edge = ins->use; edge; edge = edge->next) {
20261                                 struct ssa_edge *sedge;
20262                                 ssa_edge_index += 1;
20263                                 sedge = &scc->ssa_edges[ssa_edge_index];
20264                                 *stail = sedge;
20265                                 stail = &sedge->out_next;
20266                                 sedge->src = lnode;
20267                                 sedge->dst = &scc->lattice[edge->member->id];
20268                                 sedge->work_next = sedge->work_prev = sedge;
20269                                 sedge->out_next = 0;
20270                         }
20271                 }
20272                 if ((ins->op == OP_LABEL) && (block != ins->u.block)) {
20273                         struct flow_edge *fedge, **ftail;
20274                         struct block_set *bedge;
20275                         block = ins->u.block;
20276                         fblock = &scc->flow_blocks[block->vertex];
20277                         fblock->in = 0;
20278                         fblock->out = 0;
20279                         ftail = &fblock->out;
20280
20281                         fedge = fblock->edges;
20282                         bedge = block->edges;
20283                         for(; bedge; bedge = bedge->next, fedge++) {
20284                                 fedge->dst = &scc->flow_blocks[bedge->member->vertex];
20285                                 if (fedge->dst->block != bedge->member) {
20286                                         internal_error(state, 0, "block mismatch");
20287                                 }
20288                                 *ftail = fedge;
20289                                 ftail = &fedge->out_next;
20290                                 fedge->out_next = 0;
20291                         }
20292                         for(fedge = fblock->out; fedge; fedge = fedge->out_next) {
20293                                 fedge->src = fblock;
20294                                 fedge->work_next = fedge->work_prev = fedge;
20295                                 fedge->executable = 0;
20296                         }
20297                 }
20298                 ins = ins->next;
20299         } while (ins != first);
20300         block = 0;
20301         fblock = 0;
20302         ins = first;
20303         do {
20304                 if ((ins->op  == OP_LABEL) && (block != ins->u.block)) {
20305                         struct flow_edge **ftail;
20306                         struct block_set *bedge;
20307                         block = ins->u.block;
20308                         fblock = &scc->flow_blocks[block->vertex];
20309                         ftail = &fblock->in;
20310                         for(bedge = block->use; bedge; bedge = bedge->next) {
20311                                 struct block *src_block;
20312                                 struct flow_block *sfblock;
20313                                 struct flow_edge *sfedge;
20314                                 src_block = bedge->member;
20315                                 sfblock = &scc->flow_blocks[src_block->vertex];
20316                                 for(sfedge = sfblock->out; sfedge; sfedge = sfedge->out_next) {
20317                                         if (sfedge->dst == fblock) {
20318                                                 break;
20319                                         }
20320                                 }
20321                                 if (!sfedge) {
20322                                         internal_error(state, 0, "edge mismatch");
20323                                 }
20324                                 *ftail = sfedge;
20325                                 ftail = &sfedge->in_next;
20326                                 sfedge->in_next = 0;
20327                         }
20328                 }
20329                 ins = ins->next;
20330         } while(ins != first);
20331         /* Setup a dummy block 0 as a node above the start node */
20332         {
20333                 struct flow_block *fblock, *dst;
20334                 struct flow_edge *fedge;
20335                 fblock = &scc->flow_blocks[0];
20336                 fblock->block = 0;
20337                 fblock->edges = xcmalloc(sizeof(*fblock->edges)*1, "flow_edges");
20338                 fblock->in = 0;
20339                 fblock->out = fblock->edges;
20340                 dst = &scc->flow_blocks[state->bb.first_block->vertex];
20341                 fedge = fblock->edges;
20342                 fedge->src        = fblock;
20343                 fedge->dst        = dst;
20344                 fedge->work_next  = fedge;
20345                 fedge->work_prev  = fedge;
20346                 fedge->in_next    = fedge->dst->in;
20347                 fedge->out_next   = 0;
20348                 fedge->executable = 0;
20349                 fedge->dst->in = fedge;
20350                 
20351                 /* Initialize the work lists */
20352                 scc->flow_work_list = 0;
20353                 scc->ssa_work_list  = 0;
20354                 scc_add_fedge(state, scc, fedge);
20355         }
20356         if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
20357                 fprintf(state->errout, "ins_index: %d ssa_edge_index: %d fblock_index: %d\n",
20358                         ins_index, ssa_edge_index, fblock_index);
20359         }
20360 }
20361
20362         
20363 static void free_scc_state(
20364         struct compile_state *state, struct scc_state *scc)
20365 {
20366         int i;
20367         for(i = 0; i < state->bb.last_vertex + 1; i++) {
20368                 struct flow_block *fblock;
20369                 fblock = &scc->flow_blocks[i];
20370                 if (fblock->edges) {
20371                         xfree(fblock->edges);
20372                         fblock->edges = 0;
20373                 }
20374         }
20375         xfree(scc->flow_blocks);
20376         xfree(scc->ssa_edges);
20377         xfree(scc->lattice);
20378         
20379 }
20380
20381 static struct lattice_node *triple_to_lattice(
20382         struct compile_state *state, struct scc_state *scc, struct triple *ins)
20383 {
20384         if (ins->id <= 0) {
20385                 internal_error(state, ins, "bad id");
20386         }
20387         return &scc->lattice[ins->id];
20388 }
20389
20390 static struct triple *preserve_lval(
20391         struct compile_state *state, struct lattice_node *lnode)
20392 {
20393         struct triple *old;
20394         /* Preserve the original value */
20395         if (lnode->val) {
20396                 old = dup_triple(state, lnode->val);
20397                 if (lnode->val != lnode->def) {
20398                         xfree(lnode->val);
20399                 }
20400                 lnode->val = 0;
20401         } else {
20402                 old = 0;
20403         }
20404         return old;
20405 }
20406
20407 static int lval_changed(struct compile_state *state, 
20408         struct triple *old, struct lattice_node *lnode)
20409 {
20410         int changed;
20411         /* See if the lattice value has changed */
20412         changed = 1;
20413         if (!old && !lnode->val) {
20414                 changed = 0;
20415         }
20416         if (changed &&
20417                 lnode->val && old &&
20418                 (memcmp(lnode->val->param, old->param,
20419                         TRIPLE_SIZE(lnode->val) * sizeof(lnode->val->param[0])) == 0) &&
20420                 (memcmp(&lnode->val->u, &old->u, sizeof(old->u)) == 0)) {
20421                 changed = 0;
20422         }
20423         if (old) {
20424                 xfree(old);
20425         }
20426         return changed;
20427
20428 }
20429
20430 static void scc_debug_lnode(
20431         struct compile_state *state, struct scc_state *scc,
20432         struct lattice_node *lnode, int changed)
20433 {
20434         if ((state->compiler->debug & DEBUG_SCC_TRANSFORM2) && lnode->val) {
20435                 display_triple_changes(state->errout, lnode->val, lnode->def);
20436         }
20437         if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
20438                 FILE *fp = state->errout;
20439                 struct triple *val, **expr;
20440                 val = lnode->val? lnode->val : lnode->def;
20441                 fprintf(fp, "%p %s %3d %10s (",
20442                         lnode->def, 
20443                         ((lnode->def->op == OP_PHI)? "phi: ": "expr:"),
20444                         lnode->def->id,
20445                         tops(lnode->def->op));
20446                 expr = triple_rhs(state, lnode->def, 0);
20447                 for(;expr;expr = triple_rhs(state, lnode->def, expr)) {
20448                         if (*expr) {
20449                                 fprintf(fp, " %d", (*expr)->id);
20450                         }
20451                 }
20452                 if (val->op == OP_INTCONST) {
20453                         fprintf(fp, " <0x%08lx>", (unsigned long)(val->u.cval));
20454                 }
20455                 fprintf(fp, " ) -> %s %s\n",
20456                         (is_lattice_hi(state, lnode)? "hi":
20457                                 is_lattice_const(state, lnode)? "const" : "lo"),
20458                         changed? "changed" : ""
20459                         );
20460         }
20461 }
20462
20463 static int compute_lnode_val(struct compile_state *state, struct scc_state *scc,
20464         struct lattice_node *lnode)
20465 {
20466         int changed;
20467         struct triple *old, *scratch;
20468         struct triple **dexpr, **vexpr;
20469         int count, i;
20470         
20471         /* Store the original value */
20472         old = preserve_lval(state, lnode);
20473
20474         /* Reinitialize the value */
20475         lnode->val = scratch = dup_triple(state, lnode->def);
20476         scratch->id = lnode->old_id;
20477         scratch->next     = scratch;
20478         scratch->prev     = scratch;
20479         scratch->use      = 0;
20480
20481         count = TRIPLE_SIZE(scratch);
20482         for(i = 0; i < count; i++) {
20483                 dexpr = &lnode->def->param[i];
20484                 vexpr = &scratch->param[i];
20485                 *vexpr = *dexpr;
20486                 if (((i < TRIPLE_MISC_OFF(scratch)) ||
20487                         (i >= TRIPLE_TARG_OFF(scratch))) &&
20488                         *dexpr) {
20489                         struct lattice_node *tmp;
20490                         tmp = triple_to_lattice(state, scc, *dexpr);
20491                         *vexpr = (tmp->val)? tmp->val : tmp->def;
20492                 }
20493         }
20494         if (triple_is_branch(state, scratch)) {
20495                 scratch->next = lnode->def->next;
20496         }
20497         /* Recompute the value */
20498 #warning "FIXME see if simplify does anything bad"
20499         /* So far it looks like only the strength reduction
20500          * optimization are things I need to worry about.
20501          */
20502         simplify(state, scratch);
20503         /* Cleanup my value */
20504         if (scratch->use) {
20505                 internal_error(state, lnode->def, "scratch used?");
20506         }
20507         if ((scratch->prev != scratch) ||
20508                 ((scratch->next != scratch) &&
20509                         (!triple_is_branch(state, lnode->def) ||
20510                                 (scratch->next != lnode->def->next)))) {
20511                 internal_error(state, lnode->def, "scratch in list?");
20512         }
20513         /* undo any uses... */
20514         count = TRIPLE_SIZE(scratch);
20515         for(i = 0; i < count; i++) {
20516                 vexpr = &scratch->param[i];
20517                 if (*vexpr) {
20518                         unuse_triple(*vexpr, scratch);
20519                 }
20520         }
20521         if (lnode->val->op == OP_UNKNOWNVAL) {
20522                 lnode->val = 0; /* Lattice low by definition */
20523         }
20524         /* Find the case when I am lattice high */
20525         if (lnode->val && 
20526                 (lnode->val->op == lnode->def->op) &&
20527                 (memcmp(lnode->val->param, lnode->def->param, 
20528                         count * sizeof(lnode->val->param[0])) == 0) &&
20529                 (memcmp(&lnode->val->u, &lnode->def->u, sizeof(lnode->def->u)) == 0)) {
20530                 lnode->val = lnode->def;
20531         }
20532         /* Only allow lattice high when all of my inputs
20533          * are also lattice high.  Occassionally I can
20534          * have constants with a lattice low input, so
20535          * I do not need to check that case.
20536          */
20537         if (is_lattice_hi(state, lnode)) {
20538                 struct lattice_node *tmp;
20539                 int rhs;
20540                 rhs = lnode->val->rhs;
20541                 for(i = 0; i < rhs; i++) {
20542                         tmp = triple_to_lattice(state, scc, RHS(lnode->val, i));
20543                         if (!is_lattice_hi(state, tmp)) {
20544                                 lnode->val = 0;
20545                                 break;
20546                         }
20547                 }
20548         }
20549         /* Find the cases that are always lattice lo */
20550         if (lnode->val && 
20551                 triple_is_def(state, lnode->val) &&
20552                 !triple_is_pure(state, lnode->val, lnode->old_id)) {
20553                 lnode->val = 0;
20554         }
20555         /* See if the lattice value has changed */
20556         changed = lval_changed(state, old, lnode);
20557         /* See if this value should not change */
20558         if ((lnode->val != lnode->def) && 
20559                 ((      !triple_is_def(state, lnode->def)  &&
20560                         !triple_is_cbranch(state, lnode->def)) ||
20561                         (lnode->def->op == OP_PIECE))) {
20562 #warning "FIXME constant propogate through expressions with multiple left hand sides"
20563                 if (changed) {
20564                         internal_warning(state, lnode->def, "non def changes value?");
20565                 }
20566                 lnode->val = 0;
20567         }
20568
20569         /* See if we need to free the scratch value */
20570         if (lnode->val != scratch) {
20571                 xfree(scratch);
20572         }
20573         
20574         return changed;
20575 }
20576
20577
20578 static void scc_visit_cbranch(struct compile_state *state, struct scc_state *scc,
20579         struct lattice_node *lnode)
20580 {
20581         struct lattice_node *cond;
20582         struct flow_edge *left, *right;
20583         int changed;
20584
20585         /* Update the branch value */
20586         changed = compute_lnode_val(state, scc, lnode);
20587         scc_debug_lnode(state, scc, lnode, changed);
20588
20589         /* This only applies to conditional branches */
20590         if (!triple_is_cbranch(state, lnode->def)) {
20591                 internal_error(state, lnode->def, "not a conditional branch");
20592         }
20593
20594         if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
20595                 struct flow_edge *fedge;
20596                 FILE *fp = state->errout;
20597                 fprintf(fp, "%s: %d (",
20598                         tops(lnode->def->op),
20599                         lnode->def->id);
20600                 
20601                 for(fedge = lnode->fblock->out; fedge; fedge = fedge->out_next) {
20602                         fprintf(fp, " %d", fedge->dst->block->vertex);
20603                 }
20604                 fprintf(fp, " )");
20605                 if (lnode->def->rhs > 0) {
20606                         fprintf(fp, " <- %d",
20607                                 RHS(lnode->def, 0)->id);
20608                 }
20609                 fprintf(fp, "\n");
20610         }
20611         cond = triple_to_lattice(state, scc, RHS(lnode->def,0));
20612         for(left = cond->fblock->out; left; left = left->out_next) {
20613                 if (left->dst->block->first == lnode->def->next) {
20614                         break;
20615                 }
20616         }
20617         if (!left) {
20618                 internal_error(state, lnode->def, "Cannot find left branch edge");
20619         }
20620         for(right = cond->fblock->out; right; right = right->out_next) {
20621                 if (right->dst->block->first == TARG(lnode->def, 0)) {
20622                         break;
20623                 }
20624         }
20625         if (!right) {
20626                 internal_error(state, lnode->def, "Cannot find right branch edge");
20627         }
20628         /* I should only come here if the controlling expressions value
20629          * has changed, which means it must be either a constant or lo.
20630          */
20631         if (is_lattice_hi(state, cond)) {
20632                 internal_error(state, cond->def, "condition high?");
20633                 return;
20634         }
20635         if (is_lattice_lo(state, cond)) {
20636                 scc_add_fedge(state, scc, left);
20637                 scc_add_fedge(state, scc, right);
20638         }
20639         else if (cond->val->u.cval) {
20640                 scc_add_fedge(state, scc, right);
20641         } else {
20642                 scc_add_fedge(state, scc, left);
20643         }
20644
20645 }
20646
20647
20648 static void scc_add_sedge_dst(struct compile_state *state, 
20649         struct scc_state *scc, struct ssa_edge *sedge)
20650 {
20651         if (triple_is_cbranch(state, sedge->dst->def)) {
20652                 scc_visit_cbranch(state, scc, sedge->dst);
20653         }
20654         else if (triple_is_def(state, sedge->dst->def)) {
20655                 scc_add_sedge(state, scc, sedge);
20656         }
20657 }
20658
20659 static void scc_visit_phi(struct compile_state *state, struct scc_state *scc, 
20660         struct lattice_node *lnode)
20661 {
20662         struct lattice_node *tmp;
20663         struct triple **slot, *old;
20664         struct flow_edge *fedge;
20665         int changed;
20666         int index;
20667         if (lnode->def->op != OP_PHI) {
20668                 internal_error(state, lnode->def, "not phi");
20669         }
20670         /* Store the original value */
20671         old = preserve_lval(state, lnode);
20672
20673         /* default to lattice high */
20674         lnode->val = lnode->def;
20675         slot = &RHS(lnode->def, 0);
20676         index = 0;
20677         for(fedge = lnode->fblock->in; fedge; index++, fedge = fedge->in_next) {
20678                 if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
20679                         fprintf(state->errout, "Examining edge: %d vertex: %d executable: %d\n", 
20680                                 index,
20681                                 fedge->dst->block->vertex,
20682                                 fedge->executable
20683                                 );
20684                 }
20685                 if (!fedge->executable) {
20686                         continue;
20687                 }
20688                 if (!slot[index]) {
20689                         internal_error(state, lnode->def, "no phi value");
20690                 }
20691                 tmp = triple_to_lattice(state, scc, slot[index]);
20692                 /* meet(X, lattice low) = lattice low */
20693                 if (is_lattice_lo(state, tmp)) {
20694                         lnode->val = 0;
20695                 }
20696                 /* meet(X, lattice high) = X */
20697                 else if (is_lattice_hi(state, tmp)) {
20698                         lnode->val = lnode->val;
20699                 }
20700                 /* meet(lattice high, X) = X */
20701                 else if (is_lattice_hi(state, lnode)) {
20702                         lnode->val = dup_triple(state, tmp->val);
20703                         /* Only change the type if necessary */
20704                         if (!is_subset_type(lnode->def->type, tmp->val->type)) {
20705                                 lnode->val->type = lnode->def->type;
20706                         }
20707                 }
20708                 /* meet(const, const) = const or lattice low */
20709                 else if (!constants_equal(state, lnode->val, tmp->val)) {
20710                         lnode->val = 0;
20711                 }
20712
20713                 /* meet(lattice low, X) = lattice low */
20714                 if (is_lattice_lo(state, lnode)) {
20715                         lnode->val = 0;
20716                         break;
20717                 }
20718         }
20719         changed = lval_changed(state, old, lnode);
20720         scc_debug_lnode(state, scc, lnode, changed);
20721
20722         /* If the lattice value has changed update the work lists. */
20723         if (changed) {
20724                 struct ssa_edge *sedge;
20725                 for(sedge = lnode->out; sedge; sedge = sedge->out_next) {
20726                         scc_add_sedge_dst(state, scc, sedge);
20727                 }
20728         }
20729 }
20730
20731
20732 static void scc_visit_expr(struct compile_state *state, struct scc_state *scc,
20733         struct lattice_node *lnode)
20734 {
20735         int changed;
20736
20737         if (!triple_is_def(state, lnode->def)) {
20738                 internal_warning(state, lnode->def, "not visiting an expression?");
20739         }
20740         changed = compute_lnode_val(state, scc, lnode);
20741         scc_debug_lnode(state, scc, lnode, changed);
20742
20743         if (changed) {
20744                 struct ssa_edge *sedge;
20745                 for(sedge = lnode->out; sedge; sedge = sedge->out_next) {
20746                         scc_add_sedge_dst(state, scc, sedge);
20747                 }
20748         }
20749 }
20750
20751 static void scc_writeback_values(
20752         struct compile_state *state, struct scc_state *scc)
20753 {
20754         struct triple *first, *ins;
20755         first = state->first;
20756         ins = first;
20757         do {
20758                 struct lattice_node *lnode;
20759                 lnode = triple_to_lattice(state, scc, ins);
20760                 if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
20761                         if (is_lattice_hi(state, lnode) &&
20762                                 (lnode->val->op != OP_NOOP))
20763                         {
20764                                 struct flow_edge *fedge;
20765                                 int executable;
20766                                 executable = 0;
20767                                 for(fedge = lnode->fblock->in; 
20768                                     !executable && fedge; fedge = fedge->in_next) {
20769                                         executable |= fedge->executable;
20770                                 }
20771                                 if (executable) {
20772                                         internal_warning(state, lnode->def,
20773                                                 "lattice node %d %s->%s still high?",
20774                                                 ins->id, 
20775                                                 tops(lnode->def->op),
20776                                                 tops(lnode->val->op));
20777                                 }
20778                         }
20779                 }
20780
20781                 /* Restore id */
20782                 ins->id = lnode->old_id;
20783                 if (lnode->val && (lnode->val != ins)) {
20784                         /* See if it something I know how to write back */
20785                         switch(lnode->val->op) {
20786                         case OP_INTCONST:
20787                                 mkconst(state, ins, lnode->val->u.cval);
20788                                 break;
20789                         case OP_ADDRCONST:
20790                                 mkaddr_const(state, ins, 
20791                                         MISC(lnode->val, 0), lnode->val->u.cval);
20792                                 break;
20793                         default:
20794                                 /* By default don't copy the changes,
20795                                  * recompute them in place instead.
20796                                  */
20797                                 simplify(state, ins);
20798                                 break;
20799                         }
20800                         if (is_const(lnode->val) &&
20801                                 !constants_equal(state, lnode->val, ins)) {
20802                                 internal_error(state, 0, "constants not equal");
20803                         }
20804                         /* Free the lattice nodes */
20805                         xfree(lnode->val);
20806                         lnode->val = 0;
20807                 }
20808                 ins = ins->next;
20809         } while(ins != first);
20810 }
20811
20812 static void scc_transform(struct compile_state *state)
20813 {
20814         struct scc_state scc;
20815         if (!(state->compiler->flags & COMPILER_SCC_TRANSFORM)) {
20816                 return;
20817         }
20818
20819         initialize_scc_state(state, &scc);
20820
20821         while(scc.flow_work_list || scc.ssa_work_list) {
20822                 struct flow_edge *fedge;
20823                 struct ssa_edge *sedge;
20824                 struct flow_edge *fptr;
20825                 while((fedge = scc_next_fedge(state, &scc))) {
20826                         struct block *block;
20827                         struct triple *ptr;
20828                         struct flow_block *fblock;
20829                         int reps;
20830                         int done;
20831                         if (fedge->executable) {
20832                                 continue;
20833                         }
20834                         if (!fedge->dst) {
20835                                 internal_error(state, 0, "fedge without dst");
20836                         }
20837                         if (!fedge->src) {
20838                                 internal_error(state, 0, "fedge without src");
20839                         }
20840                         fedge->executable = 1;
20841                         fblock = fedge->dst;
20842                         block = fblock->block;
20843                         reps = 0;
20844                         for(fptr = fblock->in; fptr; fptr = fptr->in_next) {
20845                                 if (fptr->executable) {
20846                                         reps++;
20847                                 }
20848                         }
20849                         
20850                         if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
20851                                 fprintf(state->errout, "vertex: %d reps: %d\n", 
20852                                         block->vertex, reps);
20853                         }
20854
20855                         done = 0;
20856                         for(ptr = block->first; !done; ptr = ptr->next) {
20857                                 struct lattice_node *lnode;
20858                                 done = (ptr == block->last);
20859                                 lnode = &scc.lattice[ptr->id];
20860                                 if (ptr->op == OP_PHI) {
20861                                         scc_visit_phi(state, &scc, lnode);
20862                                 }
20863                                 else if ((reps == 1) && triple_is_def(state, ptr))
20864                                 {
20865                                         scc_visit_expr(state, &scc, lnode);
20866                                 }
20867                         }
20868                         /* Add unconditional branch edges */
20869                         if (!triple_is_cbranch(state, fblock->block->last)) {
20870                                 struct flow_edge *out;
20871                                 for(out = fblock->out; out; out = out->out_next) {
20872                                         scc_add_fedge(state, &scc, out);
20873                                 }
20874                         }
20875                 }
20876                 while((sedge = scc_next_sedge(state, &scc))) {
20877                         struct lattice_node *lnode;
20878                         struct flow_block *fblock;
20879                         lnode = sedge->dst;
20880                         fblock = lnode->fblock;
20881
20882                         if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
20883                                 fprintf(state->errout, "sedge: %5d (%5d -> %5d)\n",
20884                                         sedge - scc.ssa_edges,
20885                                         sedge->src->def->id,
20886                                         sedge->dst->def->id);
20887                         }
20888
20889                         if (lnode->def->op == OP_PHI) {
20890                                 scc_visit_phi(state, &scc, lnode);
20891                         }
20892                         else {
20893                                 for(fptr = fblock->in; fptr; fptr = fptr->in_next) {
20894                                         if (fptr->executable) {
20895                                                 break;
20896                                         }
20897                                 }
20898                                 if (fptr) {
20899                                         scc_visit_expr(state, &scc, lnode);
20900                                 }
20901                         }
20902                 }
20903         }
20904         
20905         scc_writeback_values(state, &scc);
20906         free_scc_state(state, &scc);
20907         rebuild_ssa_form(state);
20908         
20909         print_blocks(state, __func__, state->dbgout);
20910 }
20911
20912
20913 static void transform_to_arch_instructions(struct compile_state *state)
20914 {
20915         struct triple *ins, *first;
20916         first = state->first;
20917         ins = first;
20918         do {
20919                 ins = transform_to_arch_instruction(state, ins);
20920         } while(ins != first);
20921         
20922         print_blocks(state, __func__, state->dbgout);
20923 }
20924
20925 #if DEBUG_CONSISTENCY
20926 static void verify_uses(struct compile_state *state)
20927 {
20928         struct triple *first, *ins;
20929         struct triple_set *set;
20930         first = state->first;
20931         ins = first;
20932         do {
20933                 struct triple **expr;
20934                 expr = triple_rhs(state, ins, 0);
20935                 for(; expr; expr = triple_rhs(state, ins, expr)) {
20936                         struct triple *rhs;
20937                         rhs = *expr;
20938                         for(set = rhs?rhs->use:0; set; set = set->next) {
20939                                 if (set->member == ins) {
20940                                         break;
20941                                 }
20942                         }
20943                         if (!set) {
20944                                 internal_error(state, ins, "rhs not used");
20945                         }
20946                 }
20947                 expr = triple_lhs(state, ins, 0);
20948                 for(; expr; expr = triple_lhs(state, ins, expr)) {
20949                         struct triple *lhs;
20950                         lhs = *expr;
20951                         for(set =  lhs?lhs->use:0; set; set = set->next) {
20952                                 if (set->member == ins) {
20953                                         break;
20954                                 }
20955                         }
20956                         if (!set) {
20957                                 internal_error(state, ins, "lhs not used");
20958                         }
20959                 }
20960                 expr = triple_misc(state, ins, 0);
20961                 if (ins->op != OP_PHI) {
20962                         for(; expr; expr = triple_targ(state, ins, expr)) {
20963                                 struct triple *misc;
20964                                 misc = *expr;
20965                                 for(set = misc?misc->use:0; set; set = set->next) {
20966                                         if (set->member == ins) {
20967                                                 break;
20968                                         }
20969                                 }
20970                                 if (!set) {
20971                                         internal_error(state, ins, "misc not used");
20972                                 }
20973                         }
20974                 }
20975                 if (!triple_is_ret(state, ins)) {
20976                         expr = triple_targ(state, ins, 0);
20977                         for(; expr; expr = triple_targ(state, ins, expr)) {
20978                                 struct triple *targ;
20979                                 targ = *expr;
20980                                 for(set = targ?targ->use:0; set; set = set->next) {
20981                                         if (set->member == ins) {
20982                                                 break;
20983                                         }
20984                                 }
20985                                 if (!set) {
20986                                         internal_error(state, ins, "targ not used");
20987                                 }
20988                         }
20989                 }
20990                 ins = ins->next;
20991         } while(ins != first);
20992         
20993 }
20994 static void verify_blocks_present(struct compile_state *state)
20995 {
20996         struct triple *first, *ins;
20997         if (!state->bb.first_block) {
20998                 return;
20999         }
21000         first = state->first;
21001         ins = first;
21002         do {
21003                 valid_ins(state, ins);
21004                 if (triple_stores_block(state, ins)) {
21005                         if (!ins->u.block) {
21006                                 internal_error(state, ins, 
21007                                         "%p not in a block?", ins);
21008                         }
21009                 }
21010                 ins = ins->next;
21011         } while(ins != first);
21012         
21013         
21014 }
21015
21016 static int edge_present(struct compile_state *state, struct block *block, struct triple *edge)
21017 {
21018         struct block_set *bedge;
21019         struct block *targ;
21020         targ = block_of_triple(state, edge);
21021         for(bedge = block->edges; bedge; bedge = bedge->next) {
21022                 if (bedge->member == targ) {
21023                         return 1;
21024                 }
21025         }
21026         return 0;
21027 }
21028
21029 static void verify_blocks(struct compile_state *state)
21030 {
21031         struct triple *ins;
21032         struct block *block;
21033         int blocks;
21034         block = state->bb.first_block;
21035         if (!block) {
21036                 return;
21037         }
21038         blocks = 0;
21039         do {
21040                 int users;
21041                 struct block_set *user, *edge;
21042                 blocks++;
21043                 for(ins = block->first; ins != block->last->next; ins = ins->next) {
21044                         if (triple_stores_block(state, ins) && (ins->u.block != block)) {
21045                                 internal_error(state, ins, "inconsitent block specified");
21046                         }
21047                         valid_ins(state, ins);
21048                 }
21049                 users = 0;
21050                 for(user = block->use; user; user = user->next) {
21051                         users++;
21052                         if (!user->member->first) {
21053                                 internal_error(state, block->first, "user is empty");
21054                         }
21055                         if ((block == state->bb.last_block) &&
21056                                 (user->member == state->bb.first_block)) {
21057                                 continue;
21058                         }
21059                         for(edge = user->member->edges; edge; edge = edge->next) {
21060                                 if (edge->member == block) {
21061                                         break;
21062                                 }
21063                         }
21064                         if (!edge) {
21065                                 internal_error(state, user->member->first,
21066                                         "user does not use block");
21067                         }
21068                 }
21069                 if (triple_is_branch(state, block->last)) {
21070                         struct triple **expr;
21071                         expr = triple_edge_targ(state, block->last, 0);
21072                         for(;expr; expr = triple_edge_targ(state, block->last, expr)) {
21073                                 if (*expr && !edge_present(state, block, *expr)) {
21074                                         internal_error(state, block->last, "no edge to targ");
21075                                 }
21076                         }
21077                 }
21078                 if (!triple_is_ubranch(state, block->last) &&
21079                         (block != state->bb.last_block) &&
21080                         !edge_present(state, block, block->last->next)) {
21081                         internal_error(state, block->last, "no edge to block->last->next");
21082                 }
21083                 for(edge = block->edges; edge; edge = edge->next) {
21084                         for(user = edge->member->use; user; user = user->next) {
21085                                 if (user->member == block) {
21086                                         break;
21087                                 }
21088                         }
21089                         if (!user || user->member != block) {
21090                                 internal_error(state, block->first,
21091                                         "block does not use edge");
21092                         }
21093                         if (!edge->member->first) {
21094                                 internal_error(state, block->first, "edge block is empty");
21095                         }
21096                 }
21097                 if (block->users != users) {
21098                         internal_error(state, block->first, 
21099                                 "computed users %d != stored users %d",
21100                                 users, block->users);
21101                 }
21102                 if (!triple_stores_block(state, block->last->next)) {
21103                         internal_error(state, block->last->next, 
21104                                 "cannot find next block");
21105                 }
21106                 block = block->last->next->u.block;
21107                 if (!block) {
21108                         internal_error(state, block->last->next,
21109                                 "bad next block");
21110                 }
21111         } while(block != state->bb.first_block);
21112         if (blocks != state->bb.last_vertex) {
21113                 internal_error(state, 0, "computed blocks: %d != stored blocks %d",
21114                         blocks, state->bb.last_vertex);
21115         }
21116 }
21117
21118 static void verify_domination(struct compile_state *state)
21119 {
21120         struct triple *first, *ins;
21121         struct triple_set *set;
21122         if (!state->bb.first_block) {
21123                 return;
21124         }
21125         
21126         first = state->first;
21127         ins = first;
21128         do {
21129                 for(set = ins->use; set; set = set->next) {
21130                         struct triple **slot;
21131                         struct triple *use_point;
21132                         int i, zrhs;
21133                         use_point = 0;
21134                         zrhs = set->member->rhs;
21135                         slot = &RHS(set->member, 0);
21136                         /* See if the use is on the right hand side */
21137                         for(i = 0; i < zrhs; i++) {
21138                                 if (slot[i] == ins) {
21139                                         break;
21140                                 }
21141                         }
21142                         if (i < zrhs) {
21143                                 use_point = set->member;
21144                                 if (set->member->op == OP_PHI) {
21145                                         struct block_set *bset;
21146                                         int edge;
21147                                         bset = set->member->u.block->use;
21148                                         for(edge = 0; bset && (edge < i); edge++) {
21149                                                 bset = bset->next;
21150                                         }
21151                                         if (!bset) {
21152                                                 internal_error(state, set->member, 
21153                                                         "no edge for phi rhs %d", i);
21154                                         }
21155                                         use_point = bset->member->last;
21156                                 }
21157                         }
21158                         if (use_point &&
21159                                 !tdominates(state, ins, use_point)) {
21160                                 if (is_const(ins)) {
21161                                         internal_warning(state, ins, 
21162                                         "non dominated rhs use point %p?", use_point);
21163                                 }
21164                                 else {
21165                                         internal_error(state, ins, 
21166                                                 "non dominated rhs use point %p?", use_point);
21167                                 }
21168                         }
21169                 }
21170                 ins = ins->next;
21171         } while(ins != first);
21172 }
21173
21174 static void verify_rhs(struct compile_state *state)
21175 {
21176         struct triple *first, *ins;
21177         first = state->first;
21178         ins = first;
21179         do {
21180                 struct triple **slot;
21181                 int zrhs, i;
21182                 zrhs = ins->rhs;
21183                 slot = &RHS(ins, 0);
21184                 for(i = 0; i < zrhs; i++) {
21185                         if (slot[i] == 0) {
21186                                 internal_error(state, ins,
21187                                         "missing rhs %d on %s",
21188                                         i, tops(ins->op));
21189                         }
21190                         if ((ins->op != OP_PHI) && (slot[i] == ins)) {
21191                                 internal_error(state, ins,
21192                                         "ins == rhs[%d] on %s",
21193                                         i, tops(ins->op));
21194                         }
21195                 }
21196                 ins = ins->next;
21197         } while(ins != first);
21198 }
21199
21200 static void verify_piece(struct compile_state *state)
21201 {
21202         struct triple *first, *ins;
21203         first = state->first;
21204         ins = first;
21205         do {
21206                 struct triple *ptr;
21207                 int lhs, i;
21208                 lhs = ins->lhs;
21209                 for(ptr = ins->next, i = 0; i < lhs; i++, ptr = ptr->next) {
21210                         if (ptr != LHS(ins, i)) {
21211                                 internal_error(state, ins, "malformed lhs on %s",
21212                                         tops(ins->op));
21213                         }
21214                         if (ptr->op != OP_PIECE) {
21215                                 internal_error(state, ins, "bad lhs op %s at %d on %s",
21216                                         tops(ptr->op), i, tops(ins->op));
21217                         }
21218                         if (ptr->u.cval != i) {
21219                                 internal_error(state, ins, "bad u.cval of %d %d expected",
21220                                         ptr->u.cval, i);
21221                         }
21222                 }
21223                 ins = ins->next;
21224         } while(ins != first);
21225 }
21226
21227 static void verify_ins_colors(struct compile_state *state)
21228 {
21229         struct triple *first, *ins;
21230         
21231         first = state->first;
21232         ins = first;
21233         do {
21234                 ins = ins->next;
21235         } while(ins != first);
21236 }
21237
21238 static void verify_unknown(struct compile_state *state)
21239 {
21240         struct triple *first, *ins;
21241         if (    (unknown_triple.next != &unknown_triple) ||
21242                 (unknown_triple.prev != &unknown_triple) ||
21243 #if 0
21244                 (unknown_triple.use != 0) ||
21245 #endif
21246                 (unknown_triple.op != OP_UNKNOWNVAL) ||
21247                 (unknown_triple.lhs != 0) ||
21248                 (unknown_triple.rhs != 0) ||
21249                 (unknown_triple.misc != 0) ||
21250                 (unknown_triple.targ != 0) ||
21251                 (unknown_triple.template_id != 0) ||
21252                 (unknown_triple.id != -1) ||
21253                 (unknown_triple.type != &unknown_type) ||
21254                 (unknown_triple.occurance != &dummy_occurance) ||
21255                 (unknown_triple.param[0] != 0) ||
21256                 (unknown_triple.param[1] != 0)) {
21257                 internal_error(state, &unknown_triple, "unknown_triple corrupted!");
21258         }
21259         if (    (dummy_occurance.count != 2) ||
21260                 (strcmp(dummy_occurance.filename, __FILE__) != 0) ||
21261                 (strcmp(dummy_occurance.function, "") != 0) ||
21262                 (dummy_occurance.col != 0) ||
21263                 (dummy_occurance.parent != 0)) {
21264                 internal_error(state, &unknown_triple, "dummy_occurance corrupted!");
21265         }
21266         if (    (unknown_type.type != TYPE_UNKNOWN)) {
21267                 internal_error(state, &unknown_triple, "unknown_type corrupted!");
21268         }
21269         first = state->first;
21270         ins = first;
21271         do {
21272                 int params, i;
21273                 if (ins == &unknown_triple) {
21274                         internal_error(state, ins, "unknown triple in list");
21275                 }
21276                 params = TRIPLE_SIZE(ins);
21277                 for(i = 0; i < params; i++) {
21278                         if (ins->param[i] == &unknown_triple) {
21279                                 internal_error(state, ins, "unknown triple used!");
21280                         }
21281                 }
21282                 ins = ins->next;
21283         } while(ins != first);
21284 }
21285
21286 static void verify_types(struct compile_state *state)
21287 {
21288         struct triple *first, *ins;
21289         first = state->first;
21290         ins = first;
21291         do {
21292                 struct type *invalid;
21293                 invalid = invalid_type(state, ins->type);
21294                 if (invalid) {
21295                         FILE *fp = state->errout;
21296                         fprintf(fp, "type: ");
21297                         name_of(fp, ins->type);
21298                         fprintf(fp, "\n");
21299                         fprintf(fp, "invalid type: ");
21300                         name_of(fp, invalid);
21301                         fprintf(fp, "\n");
21302                         internal_error(state, ins, "invalid ins type");
21303                 }
21304         } while(ins != first);
21305 }
21306
21307 static void verify_copy(struct compile_state *state)
21308 {
21309         struct triple *first, *ins, *next;
21310         first = state->first;
21311         next = ins = first;
21312         do {
21313                 ins = next;
21314                 next = ins->next;
21315                 if (ins->op != OP_COPY) {
21316                         continue;
21317                 }
21318                 if (!equiv_types(ins->type, RHS(ins, 0)->type)) {
21319                         FILE *fp = state->errout;
21320                         fprintf(fp, "src type: ");
21321                         name_of(fp, RHS(ins, 0)->type);
21322                         fprintf(fp, "\n");
21323                         fprintf(fp, "dst type: ");
21324                         name_of(fp, ins->type);
21325                         fprintf(fp, "\n");
21326                         internal_error(state, ins, "type mismatch in copy");
21327                 }
21328         } while(next != first);
21329 }
21330
21331 static void verify_consistency(struct compile_state *state)
21332 {
21333         verify_unknown(state);
21334         verify_uses(state);
21335         verify_blocks_present(state);
21336         verify_blocks(state);
21337         verify_domination(state);
21338         verify_rhs(state);
21339         verify_piece(state);
21340         verify_ins_colors(state);
21341         verify_types(state);
21342         verify_copy(state);
21343         if (state->compiler->debug & DEBUG_VERIFICATION) {
21344                 fprintf(state->dbgout, "consistency verified\n");
21345         }
21346 }
21347 #else 
21348 static void verify_consistency(struct compile_state *state) {}
21349 #endif /* DEBUG_CONSISTENCY */
21350
21351 static void optimize(struct compile_state *state)
21352 {
21353         /* Join all of the functions into one giant function */
21354         join_functions(state);
21355
21356         /* Dump what the instruction graph intially looks like */
21357         print_triples(state);
21358
21359         /* Replace structures with simpler data types */
21360         decompose_compound_types(state);
21361         print_triples(state);
21362
21363         verify_consistency(state);
21364         /* Analyze the intermediate code */
21365         state->bb.first = state->first;
21366         analyze_basic_blocks(state, &state->bb);
21367
21368         /* Transform the code to ssa form. */
21369         /*
21370          * The transformation to ssa form puts a phi function
21371          * on each of edge of a dominance frontier where that
21372          * phi function might be needed.  At -O2 if we don't
21373          * eleminate the excess phi functions we can get an
21374          * exponential code size growth.  So I kill the extra
21375          * phi functions early and I kill them often.
21376          */
21377         transform_to_ssa_form(state);
21378         verify_consistency(state);
21379
21380         /* Remove dead code */
21381         eliminate_inefectual_code(state);
21382         verify_consistency(state);
21383
21384         /* Do strength reduction and simple constant optimizations */
21385         simplify_all(state);
21386         verify_consistency(state);
21387         /* Propogate constants throughout the code */
21388         scc_transform(state);
21389         verify_consistency(state);
21390 #warning "WISHLIST implement single use constants (least possible register pressure)"
21391 #warning "WISHLIST implement induction variable elimination"
21392         /* Select architecture instructions and an initial partial
21393          * coloring based on architecture constraints.
21394          */
21395         transform_to_arch_instructions(state);
21396         verify_consistency(state);
21397
21398         /* Remove dead code */
21399         eliminate_inefectual_code(state);
21400         verify_consistency(state);
21401
21402         /* Color all of the variables to see if they will fit in registers */
21403         insert_copies_to_phi(state);
21404         verify_consistency(state);
21405
21406         insert_mandatory_copies(state);
21407         verify_consistency(state);
21408
21409         allocate_registers(state);
21410         verify_consistency(state);
21411
21412         /* Remove the optimization information.
21413          * This is more to check for memory consistency than to free memory.
21414          */
21415         free_basic_blocks(state, &state->bb);
21416 }
21417
21418 static void print_op_asm(struct compile_state *state,
21419         struct triple *ins, FILE *fp)
21420 {
21421         struct asm_info *info;
21422         const char *ptr;
21423         unsigned lhs, rhs, i;
21424         info = ins->u.ainfo;
21425         lhs = ins->lhs;
21426         rhs = ins->rhs;
21427         /* Don't count the clobbers in lhs */
21428         for(i = 0; i < lhs; i++) {
21429                 if (LHS(ins, i)->type == &void_type) {
21430                         break;
21431                 }
21432         }
21433         lhs = i;
21434         fprintf(fp, "#ASM\n");
21435         fputc('\t', fp);
21436         for(ptr = info->str; *ptr; ptr++) {
21437                 char *next;
21438                 unsigned long param;
21439                 struct triple *piece;
21440                 if (*ptr != '%') {
21441                         fputc(*ptr, fp);
21442                         continue;
21443                 }
21444                 ptr++;
21445                 if (*ptr == '%') {
21446                         fputc('%', fp);
21447                         continue;
21448                 }
21449                 param = strtoul(ptr, &next, 10);
21450                 if (ptr == next) {
21451                         error(state, ins, "Invalid asm template");
21452                 }
21453                 if (param >= (lhs + rhs)) {
21454                         error(state, ins, "Invalid param %%%u in asm template",
21455                                 param);
21456                 }
21457                 piece = (param < lhs)? LHS(ins, param) : RHS(ins, param - lhs);
21458                 fprintf(fp, "%s", 
21459                         arch_reg_str(ID_REG(piece->id)));
21460                 ptr = next -1;
21461         }
21462         fprintf(fp, "\n#NOT ASM\n");
21463 }
21464
21465
21466 /* Only use the low x86 byte registers.  This allows me
21467  * allocate the entire register when a byte register is used.
21468  */
21469 #define X86_4_8BIT_GPRS 1
21470
21471 /* x86 featrues */
21472 #define X86_MMX_REGS  (1<<0)
21473 #define X86_XMM_REGS  (1<<1)
21474 #define X86_NOOP_COPY (1<<2)
21475
21476 /* The x86 register classes */
21477 #define REGC_FLAGS       0
21478 #define REGC_GPR8        1
21479 #define REGC_GPR16       2
21480 #define REGC_GPR32       3
21481 #define REGC_DIVIDEND64  4
21482 #define REGC_DIVIDEND32  5
21483 #define REGC_MMX         6
21484 #define REGC_XMM         7
21485 #define REGC_GPR32_8     8
21486 #define REGC_GPR16_8     9
21487 #define REGC_GPR8_LO    10
21488 #define REGC_IMM32      11
21489 #define REGC_IMM16      12
21490 #define REGC_IMM8       13
21491 #define LAST_REGC  REGC_IMM8
21492 #if LAST_REGC >= MAX_REGC
21493 #error "MAX_REGC is to low"
21494 #endif
21495
21496 /* Register class masks */
21497 #define REGCM_FLAGS      (1 << REGC_FLAGS)
21498 #define REGCM_GPR8       (1 << REGC_GPR8)
21499 #define REGCM_GPR16      (1 << REGC_GPR16)
21500 #define REGCM_GPR32      (1 << REGC_GPR32)
21501 #define REGCM_DIVIDEND64 (1 << REGC_DIVIDEND64)
21502 #define REGCM_DIVIDEND32 (1 << REGC_DIVIDEND32)
21503 #define REGCM_MMX        (1 << REGC_MMX)
21504 #define REGCM_XMM        (1 << REGC_XMM)
21505 #define REGCM_GPR32_8    (1 << REGC_GPR32_8)
21506 #define REGCM_GPR16_8    (1 << REGC_GPR16_8)
21507 #define REGCM_GPR8_LO    (1 << REGC_GPR8_LO)
21508 #define REGCM_IMM32      (1 << REGC_IMM32)
21509 #define REGCM_IMM16      (1 << REGC_IMM16)
21510 #define REGCM_IMM8       (1 << REGC_IMM8)
21511 #define REGCM_ALL        ((1 << (LAST_REGC + 1)) - 1)
21512 #define REGCM_IMMALL    (REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8)
21513
21514 /* The x86 registers */
21515 #define REG_EFLAGS  2
21516 #define REGC_FLAGS_FIRST REG_EFLAGS
21517 #define REGC_FLAGS_LAST  REG_EFLAGS
21518 #define REG_AL      3
21519 #define REG_BL      4
21520 #define REG_CL      5
21521 #define REG_DL      6
21522 #define REG_AH      7
21523 #define REG_BH      8
21524 #define REG_CH      9
21525 #define REG_DH      10
21526 #define REGC_GPR8_LO_FIRST REG_AL
21527 #define REGC_GPR8_LO_LAST  REG_DL
21528 #define REGC_GPR8_FIRST  REG_AL
21529 #define REGC_GPR8_LAST   REG_DH
21530 #define REG_AX     11
21531 #define REG_BX     12
21532 #define REG_CX     13
21533 #define REG_DX     14
21534 #define REG_SI     15
21535 #define REG_DI     16
21536 #define REG_BP     17
21537 #define REG_SP     18
21538 #define REGC_GPR16_FIRST REG_AX
21539 #define REGC_GPR16_LAST  REG_SP
21540 #define REG_EAX    19
21541 #define REG_EBX    20
21542 #define REG_ECX    21
21543 #define REG_EDX    22
21544 #define REG_ESI    23
21545 #define REG_EDI    24
21546 #define REG_EBP    25
21547 #define REG_ESP    26
21548 #define REGC_GPR32_FIRST REG_EAX
21549 #define REGC_GPR32_LAST  REG_ESP
21550 #define REG_EDXEAX 27
21551 #define REGC_DIVIDEND64_FIRST REG_EDXEAX
21552 #define REGC_DIVIDEND64_LAST  REG_EDXEAX
21553 #define REG_DXAX   28
21554 #define REGC_DIVIDEND32_FIRST REG_DXAX
21555 #define REGC_DIVIDEND32_LAST  REG_DXAX
21556 #define REG_MMX0   29
21557 #define REG_MMX1   30
21558 #define REG_MMX2   31
21559 #define REG_MMX3   32
21560 #define REG_MMX4   33
21561 #define REG_MMX5   34
21562 #define REG_MMX6   35
21563 #define REG_MMX7   36
21564 #define REGC_MMX_FIRST REG_MMX0
21565 #define REGC_MMX_LAST  REG_MMX7
21566 #define REG_XMM0   37
21567 #define REG_XMM1   38
21568 #define REG_XMM2   39
21569 #define REG_XMM3   40
21570 #define REG_XMM4   41
21571 #define REG_XMM5   42
21572 #define REG_XMM6   43
21573 #define REG_XMM7   44
21574 #define REGC_XMM_FIRST REG_XMM0
21575 #define REGC_XMM_LAST  REG_XMM7
21576 #warning "WISHLIST figure out how to use pinsrw and pextrw to better use extended regs"
21577 #define LAST_REG   REG_XMM7
21578
21579 #define REGC_GPR32_8_FIRST REG_EAX
21580 #define REGC_GPR32_8_LAST  REG_EDX
21581 #define REGC_GPR16_8_FIRST REG_AX
21582 #define REGC_GPR16_8_LAST  REG_DX
21583
21584 #define REGC_IMM8_FIRST    -1
21585 #define REGC_IMM8_LAST     -1
21586 #define REGC_IMM16_FIRST   -2
21587 #define REGC_IMM16_LAST    -1
21588 #define REGC_IMM32_FIRST   -4
21589 #define REGC_IMM32_LAST    -1
21590
21591 #if LAST_REG >= MAX_REGISTERS
21592 #error "MAX_REGISTERS to low"
21593 #endif
21594
21595
21596 static unsigned regc_size[LAST_REGC +1] = {
21597         [REGC_FLAGS]      = REGC_FLAGS_LAST      - REGC_FLAGS_FIRST + 1,
21598         [REGC_GPR8]       = REGC_GPR8_LAST       - REGC_GPR8_FIRST + 1,
21599         [REGC_GPR16]      = REGC_GPR16_LAST      - REGC_GPR16_FIRST + 1,
21600         [REGC_GPR32]      = REGC_GPR32_LAST      - REGC_GPR32_FIRST + 1,
21601         [REGC_DIVIDEND64] = REGC_DIVIDEND64_LAST - REGC_DIVIDEND64_FIRST + 1,
21602         [REGC_DIVIDEND32] = REGC_DIVIDEND32_LAST - REGC_DIVIDEND32_FIRST + 1,
21603         [REGC_MMX]        = REGC_MMX_LAST        - REGC_MMX_FIRST + 1,
21604         [REGC_XMM]        = REGC_XMM_LAST        - REGC_XMM_FIRST + 1,
21605         [REGC_GPR32_8]    = REGC_GPR32_8_LAST    - REGC_GPR32_8_FIRST + 1,
21606         [REGC_GPR16_8]    = REGC_GPR16_8_LAST    - REGC_GPR16_8_FIRST + 1,
21607         [REGC_GPR8_LO]    = REGC_GPR8_LO_LAST    - REGC_GPR8_LO_FIRST + 1,
21608         [REGC_IMM32]      = 0,
21609         [REGC_IMM16]      = 0,
21610         [REGC_IMM8]       = 0,
21611 };
21612
21613 static const struct {
21614         int first, last;
21615 } regcm_bound[LAST_REGC + 1] = {
21616         [REGC_FLAGS]      = { REGC_FLAGS_FIRST,      REGC_FLAGS_LAST },
21617         [REGC_GPR8]       = { REGC_GPR8_FIRST,       REGC_GPR8_LAST },
21618         [REGC_GPR16]      = { REGC_GPR16_FIRST,      REGC_GPR16_LAST },
21619         [REGC_GPR32]      = { REGC_GPR32_FIRST,      REGC_GPR32_LAST },
21620         [REGC_DIVIDEND64] = { REGC_DIVIDEND64_FIRST, REGC_DIVIDEND64_LAST },
21621         [REGC_DIVIDEND32] = { REGC_DIVIDEND32_FIRST, REGC_DIVIDEND32_LAST },
21622         [REGC_MMX]        = { REGC_MMX_FIRST,        REGC_MMX_LAST },
21623         [REGC_XMM]        = { REGC_XMM_FIRST,        REGC_XMM_LAST },
21624         [REGC_GPR32_8]    = { REGC_GPR32_8_FIRST,    REGC_GPR32_8_LAST },
21625         [REGC_GPR16_8]    = { REGC_GPR16_8_FIRST,    REGC_GPR16_8_LAST },
21626         [REGC_GPR8_LO]    = { REGC_GPR8_LO_FIRST,    REGC_GPR8_LO_LAST },
21627         [REGC_IMM32]      = { REGC_IMM32_FIRST,      REGC_IMM32_LAST },
21628         [REGC_IMM16]      = { REGC_IMM16_FIRST,      REGC_IMM16_LAST },
21629         [REGC_IMM8]       = { REGC_IMM8_FIRST,       REGC_IMM8_LAST },
21630 };
21631
21632 #if ARCH_INPUT_REGS != 4
21633 #error ARCH_INPUT_REGS size mismatch
21634 #endif
21635 static const struct reg_info arch_input_regs[ARCH_INPUT_REGS] = {
21636         { .reg = REG_EAX, .regcm = REGCM_GPR32 },
21637         { .reg = REG_EBX, .regcm = REGCM_GPR32 },
21638         { .reg = REG_ECX, .regcm = REGCM_GPR32 },
21639         { .reg = REG_EDX, .regcm = REGCM_GPR32 },
21640 };
21641
21642 #if ARCH_OUTPUT_REGS != 4
21643 #error ARCH_INPUT_REGS size mismatch
21644 #endif
21645 static const struct reg_info arch_output_regs[ARCH_OUTPUT_REGS] = {
21646         { .reg = REG_EAX, .regcm = REGCM_GPR32 },
21647         { .reg = REG_EBX, .regcm = REGCM_GPR32 },
21648         { .reg = REG_ECX, .regcm = REGCM_GPR32 },
21649         { .reg = REG_EDX, .regcm = REGCM_GPR32 },
21650 };
21651
21652 static void init_arch_state(struct arch_state *arch)
21653 {
21654         memset(arch, 0, sizeof(*arch));
21655         arch->features = 0;
21656 }
21657
21658 static const struct compiler_flag arch_flags[] = {
21659         { "mmx",       X86_MMX_REGS },
21660         { "sse",       X86_XMM_REGS },
21661         { "noop-copy", X86_NOOP_COPY },
21662         { 0,     0 },
21663 };
21664 static const struct compiler_flag arch_cpus[] = {
21665         { "i386", 0 },
21666         { "p2",   X86_MMX_REGS },
21667         { "p3",   X86_MMX_REGS | X86_XMM_REGS },
21668         { "p4",   X86_MMX_REGS | X86_XMM_REGS },
21669         { "k7",   X86_MMX_REGS },
21670         { "k8",   X86_MMX_REGS | X86_XMM_REGS },
21671         { "c3",   X86_MMX_REGS },
21672         { "c3-2", X86_MMX_REGS | X86_XMM_REGS }, /* Nehemiah */
21673         {  0,     0 }
21674 };
21675 static int arch_encode_flag(struct arch_state *arch, const char *flag)
21676 {
21677         int result;
21678         int act;
21679
21680         act = 1;
21681         result = -1;
21682         if (strncmp(flag, "no-", 3) == 0) {
21683                 flag += 3;
21684                 act = 0;
21685         }
21686         if (act && strncmp(flag, "cpu=", 4) == 0) {
21687                 flag += 4;
21688                 result = set_flag(arch_cpus, &arch->features, 1, flag);
21689         }
21690         else {
21691                 result = set_flag(arch_flags, &arch->features, act, flag);
21692         }
21693         return result;
21694 }
21695
21696 static void arch_usage(FILE *fp)
21697 {
21698         flag_usage(fp, arch_flags, "-m", "-mno-");
21699         flag_usage(fp, arch_cpus, "-mcpu=", 0);
21700 }
21701
21702 static unsigned arch_regc_size(struct compile_state *state, int class)
21703 {
21704         if ((class < 0) || (class > LAST_REGC)) {
21705                 return 0;
21706         }
21707         return regc_size[class];
21708 }
21709
21710 static int arch_regcm_intersect(unsigned regcm1, unsigned regcm2)
21711 {
21712         /* See if two register classes may have overlapping registers */
21713         unsigned gpr_mask = REGCM_GPR8 | REGCM_GPR8_LO | REGCM_GPR16_8 | REGCM_GPR16 |
21714                 REGCM_GPR32_8 | REGCM_GPR32 | 
21715                 REGCM_DIVIDEND32 | REGCM_DIVIDEND64;
21716
21717         /* Special case for the immediates */
21718         if ((regcm1 & (REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8)) &&
21719                 ((regcm1 & ~(REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8)) == 0) &&
21720                 (regcm2 & (REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8)) &&
21721                 ((regcm2 & ~(REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8)) == 0)) { 
21722                 return 0;
21723         }
21724         return (regcm1 & regcm2) ||
21725                 ((regcm1 & gpr_mask) && (regcm2 & gpr_mask));
21726 }
21727
21728 static void arch_reg_equivs(
21729         struct compile_state *state, unsigned *equiv, int reg)
21730 {
21731         if ((reg < 0) || (reg > LAST_REG)) {
21732                 internal_error(state, 0, "invalid register");
21733         }
21734         *equiv++ = reg;
21735         switch(reg) {
21736         case REG_AL:
21737 #if X86_4_8BIT_GPRS
21738                 *equiv++ = REG_AH;
21739 #endif
21740                 *equiv++ = REG_AX;
21741                 *equiv++ = REG_EAX;
21742                 *equiv++ = REG_DXAX;
21743                 *equiv++ = REG_EDXEAX;
21744                 break;
21745         case REG_AH:
21746 #if X86_4_8BIT_GPRS
21747                 *equiv++ = REG_AL;
21748 #endif
21749                 *equiv++ = REG_AX;
21750                 *equiv++ = REG_EAX;
21751                 *equiv++ = REG_DXAX;
21752                 *equiv++ = REG_EDXEAX;
21753                 break;
21754         case REG_BL:  
21755 #if X86_4_8BIT_GPRS
21756                 *equiv++ = REG_BH;
21757 #endif
21758                 *equiv++ = REG_BX;
21759                 *equiv++ = REG_EBX;
21760                 break;
21761
21762         case REG_BH:
21763 #if X86_4_8BIT_GPRS
21764                 *equiv++ = REG_BL;
21765 #endif
21766                 *equiv++ = REG_BX;
21767                 *equiv++ = REG_EBX;
21768                 break;
21769         case REG_CL:
21770 #if X86_4_8BIT_GPRS
21771                 *equiv++ = REG_CH;
21772 #endif
21773                 *equiv++ = REG_CX;
21774                 *equiv++ = REG_ECX;
21775                 break;
21776
21777         case REG_CH:
21778 #if X86_4_8BIT_GPRS
21779                 *equiv++ = REG_CL;
21780 #endif
21781                 *equiv++ = REG_CX;
21782                 *equiv++ = REG_ECX;
21783                 break;
21784         case REG_DL:
21785 #if X86_4_8BIT_GPRS
21786                 *equiv++ = REG_DH;
21787 #endif
21788                 *equiv++ = REG_DX;
21789                 *equiv++ = REG_EDX;
21790                 *equiv++ = REG_DXAX;
21791                 *equiv++ = REG_EDXEAX;
21792                 break;
21793         case REG_DH:
21794 #if X86_4_8BIT_GPRS
21795                 *equiv++ = REG_DL;
21796 #endif
21797                 *equiv++ = REG_DX;
21798                 *equiv++ = REG_EDX;
21799                 *equiv++ = REG_DXAX;
21800                 *equiv++ = REG_EDXEAX;
21801                 break;
21802         case REG_AX:
21803                 *equiv++ = REG_AL;
21804                 *equiv++ = REG_AH;
21805                 *equiv++ = REG_EAX;
21806                 *equiv++ = REG_DXAX;
21807                 *equiv++ = REG_EDXEAX;
21808                 break;
21809         case REG_BX:
21810                 *equiv++ = REG_BL;
21811                 *equiv++ = REG_BH;
21812                 *equiv++ = REG_EBX;
21813                 break;
21814         case REG_CX:  
21815                 *equiv++ = REG_CL;
21816                 *equiv++ = REG_CH;
21817                 *equiv++ = REG_ECX;
21818                 break;
21819         case REG_DX:  
21820                 *equiv++ = REG_DL;
21821                 *equiv++ = REG_DH;
21822                 *equiv++ = REG_EDX;
21823                 *equiv++ = REG_DXAX;
21824                 *equiv++ = REG_EDXEAX;
21825                 break;
21826         case REG_SI:  
21827                 *equiv++ = REG_ESI;
21828                 break;
21829         case REG_DI:
21830                 *equiv++ = REG_EDI;
21831                 break;
21832         case REG_BP:
21833                 *equiv++ = REG_EBP;
21834                 break;
21835         case REG_SP:
21836                 *equiv++ = REG_ESP;
21837                 break;
21838         case REG_EAX:
21839                 *equiv++ = REG_AL;
21840                 *equiv++ = REG_AH;
21841                 *equiv++ = REG_AX;
21842                 *equiv++ = REG_DXAX;
21843                 *equiv++ = REG_EDXEAX;
21844                 break;
21845         case REG_EBX:
21846                 *equiv++ = REG_BL;
21847                 *equiv++ = REG_BH;
21848                 *equiv++ = REG_BX;
21849                 break;
21850         case REG_ECX:
21851                 *equiv++ = REG_CL;
21852                 *equiv++ = REG_CH;
21853                 *equiv++ = REG_CX;
21854                 break;
21855         case REG_EDX:
21856                 *equiv++ = REG_DL;
21857                 *equiv++ = REG_DH;
21858                 *equiv++ = REG_DX;
21859                 *equiv++ = REG_DXAX;
21860                 *equiv++ = REG_EDXEAX;
21861                 break;
21862         case REG_ESI: 
21863                 *equiv++ = REG_SI;
21864                 break;
21865         case REG_EDI: 
21866                 *equiv++ = REG_DI;
21867                 break;
21868         case REG_EBP: 
21869                 *equiv++ = REG_BP;
21870                 break;
21871         case REG_ESP: 
21872                 *equiv++ = REG_SP;
21873                 break;
21874         case REG_DXAX: 
21875                 *equiv++ = REG_AL;
21876                 *equiv++ = REG_AH;
21877                 *equiv++ = REG_DL;
21878                 *equiv++ = REG_DH;
21879                 *equiv++ = REG_AX;
21880                 *equiv++ = REG_DX;
21881                 *equiv++ = REG_EAX;
21882                 *equiv++ = REG_EDX;
21883                 *equiv++ = REG_EDXEAX;
21884                 break;
21885         case REG_EDXEAX: 
21886                 *equiv++ = REG_AL;
21887                 *equiv++ = REG_AH;
21888                 *equiv++ = REG_DL;
21889                 *equiv++ = REG_DH;
21890                 *equiv++ = REG_AX;
21891                 *equiv++ = REG_DX;
21892                 *equiv++ = REG_EAX;
21893                 *equiv++ = REG_EDX;
21894                 *equiv++ = REG_DXAX;
21895                 break;
21896         }
21897         *equiv++ = REG_UNSET; 
21898 }
21899
21900 static unsigned arch_avail_mask(struct compile_state *state)
21901 {
21902         unsigned avail_mask;
21903         /* REGCM_GPR8 is not available */
21904         avail_mask = REGCM_GPR8_LO | REGCM_GPR16_8 | REGCM_GPR16 | 
21905                 REGCM_GPR32 | REGCM_GPR32_8 | 
21906                 REGCM_DIVIDEND32 | REGCM_DIVIDEND64 |
21907                 REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8 | REGCM_FLAGS;
21908         if (state->arch->features & X86_MMX_REGS) {
21909                 avail_mask |= REGCM_MMX;
21910         }
21911         if (state->arch->features & X86_XMM_REGS) {
21912                 avail_mask |= REGCM_XMM;
21913         }
21914         return avail_mask;
21915 }
21916
21917 static unsigned arch_regcm_normalize(struct compile_state *state, unsigned regcm)
21918 {
21919         unsigned mask, result;
21920         int class, class2;
21921         result = regcm;
21922
21923         for(class = 0, mask = 1; mask; mask <<= 1, class++) {
21924                 if ((result & mask) == 0) {
21925                         continue;
21926                 }
21927                 if (class > LAST_REGC) {
21928                         result &= ~mask;
21929                 }
21930                 for(class2 = 0; class2 <= LAST_REGC; class2++) {
21931                         if ((regcm_bound[class2].first >= regcm_bound[class].first) &&
21932                                 (regcm_bound[class2].last <= regcm_bound[class].last)) {
21933                                 result |= (1 << class2);
21934                         }
21935                 }
21936         }
21937         result &= arch_avail_mask(state);
21938         return result;
21939 }
21940
21941 static unsigned arch_regcm_reg_normalize(struct compile_state *state, unsigned regcm)
21942 {
21943         /* Like arch_regcm_normalize except immediate register classes are excluded */
21944         regcm = arch_regcm_normalize(state, regcm);
21945         /* Remove the immediate register classes */
21946         regcm &= ~(REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8);
21947         return regcm;
21948         
21949 }
21950
21951 static unsigned arch_reg_regcm(struct compile_state *state, int reg)
21952 {
21953         unsigned mask;
21954         int class;
21955         mask = 0;
21956         for(class = 0; class <= LAST_REGC; class++) {
21957                 if ((reg >= regcm_bound[class].first) &&
21958                         (reg <= regcm_bound[class].last)) {
21959                         mask |= (1 << class);
21960                 }
21961         }
21962         if (!mask) {
21963                 internal_error(state, 0, "reg %d not in any class", reg);
21964         }
21965         return mask;
21966 }
21967
21968 static struct reg_info arch_reg_constraint(
21969         struct compile_state *state, struct type *type, const char *constraint)
21970 {
21971         static const struct {
21972                 char class;
21973                 unsigned int mask;
21974                 unsigned int reg;
21975         } constraints[] = {
21976                 { 'r', REGCM_GPR32,   REG_UNSET },
21977                 { 'g', REGCM_GPR32,   REG_UNSET },
21978                 { 'p', REGCM_GPR32,   REG_UNSET },
21979                 { 'q', REGCM_GPR8_LO, REG_UNSET },
21980                 { 'Q', REGCM_GPR32_8, REG_UNSET },
21981                 { 'x', REGCM_XMM,     REG_UNSET },
21982                 { 'y', REGCM_MMX,     REG_UNSET },
21983                 { 'a', REGCM_GPR32,   REG_EAX },
21984                 { 'b', REGCM_GPR32,   REG_EBX },
21985                 { 'c', REGCM_GPR32,   REG_ECX },
21986                 { 'd', REGCM_GPR32,   REG_EDX },
21987                 { 'D', REGCM_GPR32,   REG_EDI },
21988                 { 'S', REGCM_GPR32,   REG_ESI },
21989                 { '\0', 0, REG_UNSET },
21990         };
21991         unsigned int regcm;
21992         unsigned int mask, reg;
21993         struct reg_info result;
21994         const char *ptr;
21995         regcm = arch_type_to_regcm(state, type);
21996         reg = REG_UNSET;
21997         mask = 0;
21998         for(ptr = constraint; *ptr; ptr++) {
21999                 int i;
22000                 if (*ptr ==  ' ') {
22001                         continue;
22002                 }
22003                 for(i = 0; constraints[i].class != '\0'; i++) {
22004                         if (constraints[i].class == *ptr) {
22005                                 break;
22006                         }
22007                 }
22008                 if (constraints[i].class == '\0') {
22009                         error(state, 0, "invalid register constraint ``%c''", *ptr);
22010                         break;
22011                 }
22012                 if ((constraints[i].mask & regcm) == 0) {
22013                         error(state, 0, "invalid register class %c specified",
22014                                 *ptr);
22015                 }
22016                 mask |= constraints[i].mask;
22017                 if (constraints[i].reg != REG_UNSET) {
22018                         if ((reg != REG_UNSET) && (reg != constraints[i].reg)) {
22019                                 error(state, 0, "Only one register may be specified");
22020                         }
22021                         reg = constraints[i].reg;
22022                 }
22023         }
22024         result.reg = reg;
22025         result.regcm = mask;
22026         return result;
22027 }
22028
22029 static struct reg_info arch_reg_clobber(
22030         struct compile_state *state, const char *clobber)
22031 {
22032         struct reg_info result;
22033         if (strcmp(clobber, "memory") == 0) {
22034                 result.reg = REG_UNSET;
22035                 result.regcm = 0;
22036         }
22037         else if (strcmp(clobber, "eax") == 0) {
22038                 result.reg = REG_EAX;
22039                 result.regcm = REGCM_GPR32;
22040         }
22041         else if (strcmp(clobber, "ebx") == 0) {
22042                 result.reg = REG_EBX;
22043                 result.regcm = REGCM_GPR32;
22044         }
22045         else if (strcmp(clobber, "ecx") == 0) {
22046                 result.reg = REG_ECX;
22047                 result.regcm = REGCM_GPR32;
22048         }
22049         else if (strcmp(clobber, "edx") == 0) {
22050                 result.reg = REG_EDX;
22051                 result.regcm = REGCM_GPR32;
22052         }
22053         else if (strcmp(clobber, "esi") == 0) {
22054                 result.reg = REG_ESI;
22055                 result.regcm = REGCM_GPR32;
22056         }
22057         else if (strcmp(clobber, "edi") == 0) {
22058                 result.reg = REG_EDI;
22059                 result.regcm = REGCM_GPR32;
22060         }
22061         else if (strcmp(clobber, "ebp") == 0) {
22062                 result.reg = REG_EBP;
22063                 result.regcm = REGCM_GPR32;
22064         }
22065         else if (strcmp(clobber, "esp") == 0) {
22066                 result.reg = REG_ESP;
22067                 result.regcm = REGCM_GPR32;
22068         }
22069         else if (strcmp(clobber, "cc") == 0) {
22070                 result.reg = REG_EFLAGS;
22071                 result.regcm = REGCM_FLAGS;
22072         }
22073         else if ((strncmp(clobber, "xmm", 3) == 0)  &&
22074                 octdigitp(clobber[3]) && (clobber[4] == '\0')) {
22075                 result.reg = REG_XMM0 + octdigval(clobber[3]);
22076                 result.regcm = REGCM_XMM;
22077         }
22078         else if ((strncmp(clobber, "mm", 2) == 0) &&
22079                 octdigitp(clobber[3]) && (clobber[4] == '\0')) {
22080                 result.reg = REG_MMX0 + octdigval(clobber[3]);
22081                 result.regcm = REGCM_MMX;
22082         }
22083         else {
22084                 error(state, 0, "unknown register name `%s' in asm",
22085                         clobber);
22086                 result.reg = REG_UNSET;
22087                 result.regcm = 0;
22088         }
22089         return result;
22090 }
22091
22092 static int do_select_reg(struct compile_state *state, 
22093         char *used, int reg, unsigned classes)
22094 {
22095         unsigned mask;
22096         if (used[reg]) {
22097                 return REG_UNSET;
22098         }
22099         mask = arch_reg_regcm(state, reg);
22100         return (classes & mask) ? reg : REG_UNSET;
22101 }
22102
22103 static int arch_select_free_register(
22104         struct compile_state *state, char *used, int classes)
22105 {
22106         /* Live ranges with the most neighbors are colored first.
22107          *
22108          * Generally it does not matter which colors are given
22109          * as the register allocator attempts to color live ranges
22110          * in an order where you are guaranteed not to run out of colors.
22111          *
22112          * Occasionally the register allocator cannot find an order
22113          * of register selection that will find a free color.  To
22114          * increase the odds the register allocator will work when
22115          * it guesses first give out registers from register classes
22116          * least likely to run out of registers.
22117          * 
22118          */
22119         int i, reg;
22120         reg = REG_UNSET;
22121         for(i = REGC_XMM_FIRST; (reg == REG_UNSET) && (i <= REGC_XMM_LAST); i++) {
22122                 reg = do_select_reg(state, used, i, classes);
22123         }
22124         for(i = REGC_MMX_FIRST; (reg == REG_UNSET) && (i <= REGC_MMX_LAST); i++) {
22125                 reg = do_select_reg(state, used, i, classes);
22126         }
22127         for(i = REGC_GPR32_LAST; (reg == REG_UNSET) && (i >= REGC_GPR32_FIRST); i--) {
22128                 reg = do_select_reg(state, used, i, classes);
22129         }
22130         for(i = REGC_GPR16_FIRST; (reg == REG_UNSET) && (i <= REGC_GPR16_LAST); i++) {
22131                 reg = do_select_reg(state, used, i, classes);
22132         }
22133         for(i = REGC_GPR8_FIRST; (reg == REG_UNSET) && (i <= REGC_GPR8_LAST); i++) {
22134                 reg = do_select_reg(state, used, i, classes);
22135         }
22136         for(i = REGC_GPR8_LO_FIRST; (reg == REG_UNSET) && (i <= REGC_GPR8_LO_LAST); i++) {
22137                 reg = do_select_reg(state, used, i, classes);
22138         }
22139         for(i = REGC_DIVIDEND32_FIRST; (reg == REG_UNSET) && (i <= REGC_DIVIDEND32_LAST); i++) {
22140                 reg = do_select_reg(state, used, i, classes);
22141         }
22142         for(i = REGC_DIVIDEND64_FIRST; (reg == REG_UNSET) && (i <= REGC_DIVIDEND64_LAST); i++) {
22143                 reg = do_select_reg(state, used, i, classes);
22144         }
22145         for(i = REGC_FLAGS_FIRST; (reg == REG_UNSET) && (i <= REGC_FLAGS_LAST); i++) {
22146                 reg = do_select_reg(state, used, i, classes);
22147         }
22148         return reg;
22149 }
22150
22151
22152 static unsigned arch_type_to_regcm(struct compile_state *state, struct type *type) 
22153 {
22154 #warning "FIXME force types smaller (if legal) before I get here"
22155         unsigned mask;
22156         mask = 0;
22157         switch(type->type & TYPE_MASK) {
22158         case TYPE_ARRAY:
22159         case TYPE_VOID: 
22160                 mask = 0; 
22161                 break;
22162         case TYPE_CHAR:
22163         case TYPE_UCHAR:
22164                 mask = REGCM_GPR8 | REGCM_GPR8_LO |
22165                         REGCM_GPR16 | REGCM_GPR16_8 | 
22166                         REGCM_GPR32 | REGCM_GPR32_8 |
22167                         REGCM_DIVIDEND32 | REGCM_DIVIDEND64 |
22168                         REGCM_MMX | REGCM_XMM |
22169                         REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8;
22170                 break;
22171         case TYPE_SHORT:
22172         case TYPE_USHORT:
22173                 mask =  REGCM_GPR16 | REGCM_GPR16_8 |
22174                         REGCM_GPR32 | REGCM_GPR32_8 |
22175                         REGCM_DIVIDEND32 | REGCM_DIVIDEND64 |
22176                         REGCM_MMX | REGCM_XMM |
22177                         REGCM_IMM32 | REGCM_IMM16;
22178                 break;
22179         case TYPE_ENUM:
22180         case TYPE_INT:
22181         case TYPE_UINT:
22182         case TYPE_LONG:
22183         case TYPE_ULONG:
22184         case TYPE_POINTER:
22185                 mask =  REGCM_GPR32 | REGCM_GPR32_8 |
22186                         REGCM_DIVIDEND32 | REGCM_DIVIDEND64 |
22187                         REGCM_MMX | REGCM_XMM |
22188                         REGCM_IMM32;
22189                 break;
22190         case TYPE_JOIN:
22191         case TYPE_UNION:
22192                 mask = arch_type_to_regcm(state, type->left);
22193                 break;
22194         case TYPE_OVERLAP:
22195                 mask = arch_type_to_regcm(state, type->left) &
22196                         arch_type_to_regcm(state, type->right);
22197                 break;
22198         case TYPE_BITFIELD:
22199                 mask = arch_type_to_regcm(state, type->left);
22200                 break;
22201         default:
22202                 fprintf(state->errout, "type: ");
22203                 name_of(state->errout, type);
22204                 fprintf(state->errout, "\n");
22205                 internal_error(state, 0, "no register class for type");
22206                 break;
22207         }
22208         mask = arch_regcm_normalize(state, mask);
22209         return mask;
22210 }
22211
22212 static int is_imm32(struct triple *imm)
22213 {
22214         return ((imm->op == OP_INTCONST) && (imm->u.cval <= 0xffffffffUL)) ||
22215                 (imm->op == OP_ADDRCONST);
22216         
22217 }
22218 static int is_imm16(struct triple *imm)
22219 {
22220         return ((imm->op == OP_INTCONST) && (imm->u.cval <= 0xffff));
22221 }
22222 static int is_imm8(struct triple *imm)
22223 {
22224         return ((imm->op == OP_INTCONST) && (imm->u.cval <= 0xff));
22225 }
22226
22227 static int get_imm32(struct triple *ins, struct triple **expr)
22228 {
22229         struct triple *imm;
22230         imm = *expr;
22231         while(imm->op == OP_COPY) {
22232                 imm = RHS(imm, 0);
22233         }
22234         if (!is_imm32(imm)) {
22235                 return 0;
22236         }
22237         unuse_triple(*expr, ins);
22238         use_triple(imm, ins);
22239         *expr = imm;
22240         return 1;
22241 }
22242
22243 static int get_imm8(struct triple *ins, struct triple **expr)
22244 {
22245         struct triple *imm;
22246         imm = *expr;
22247         while(imm->op == OP_COPY) {
22248                 imm = RHS(imm, 0);
22249         }
22250         if (!is_imm8(imm)) {
22251                 return 0;
22252         }
22253         unuse_triple(*expr, ins);
22254         use_triple(imm, ins);
22255         *expr = imm;
22256         return 1;
22257 }
22258
22259 #define TEMPLATE_NOP           0
22260 #define TEMPLATE_INTCONST8     1
22261 #define TEMPLATE_INTCONST32    2
22262 #define TEMPLATE_UNKNOWNVAL    3
22263 #define TEMPLATE_COPY8_REG     5
22264 #define TEMPLATE_COPY16_REG    6
22265 #define TEMPLATE_COPY32_REG    7
22266 #define TEMPLATE_COPY_IMM8     8
22267 #define TEMPLATE_COPY_IMM16    9
22268 #define TEMPLATE_COPY_IMM32   10
22269 #define TEMPLATE_PHI8         11
22270 #define TEMPLATE_PHI16        12
22271 #define TEMPLATE_PHI32        13
22272 #define TEMPLATE_STORE8       14
22273 #define TEMPLATE_STORE16      15
22274 #define TEMPLATE_STORE32      16
22275 #define TEMPLATE_LOAD8        17
22276 #define TEMPLATE_LOAD16       18
22277 #define TEMPLATE_LOAD32       19
22278 #define TEMPLATE_BINARY8_REG  20
22279 #define TEMPLATE_BINARY16_REG 21
22280 #define TEMPLATE_BINARY32_REG 22
22281 #define TEMPLATE_BINARY8_IMM  23
22282 #define TEMPLATE_BINARY16_IMM 24
22283 #define TEMPLATE_BINARY32_IMM 25
22284 #define TEMPLATE_SL8_CL       26
22285 #define TEMPLATE_SL16_CL      27
22286 #define TEMPLATE_SL32_CL      28
22287 #define TEMPLATE_SL8_IMM      29
22288 #define TEMPLATE_SL16_IMM     30
22289 #define TEMPLATE_SL32_IMM     31
22290 #define TEMPLATE_UNARY8       32
22291 #define TEMPLATE_UNARY16      33
22292 #define TEMPLATE_UNARY32      34
22293 #define TEMPLATE_CMP8_REG     35
22294 #define TEMPLATE_CMP16_REG    36
22295 #define TEMPLATE_CMP32_REG    37
22296 #define TEMPLATE_CMP8_IMM     38
22297 #define TEMPLATE_CMP16_IMM    39
22298 #define TEMPLATE_CMP32_IMM    40
22299 #define TEMPLATE_TEST8        41
22300 #define TEMPLATE_TEST16       42
22301 #define TEMPLATE_TEST32       43
22302 #define TEMPLATE_SET          44
22303 #define TEMPLATE_JMP          45
22304 #define TEMPLATE_RET          46
22305 #define TEMPLATE_INB_DX       47
22306 #define TEMPLATE_INB_IMM      48
22307 #define TEMPLATE_INW_DX       49
22308 #define TEMPLATE_INW_IMM      50
22309 #define TEMPLATE_INL_DX       51
22310 #define TEMPLATE_INL_IMM      52
22311 #define TEMPLATE_OUTB_DX      53
22312 #define TEMPLATE_OUTB_IMM     54
22313 #define TEMPLATE_OUTW_DX      55
22314 #define TEMPLATE_OUTW_IMM     56
22315 #define TEMPLATE_OUTL_DX      57
22316 #define TEMPLATE_OUTL_IMM     58
22317 #define TEMPLATE_BSF          59
22318 #define TEMPLATE_RDMSR        60
22319 #define TEMPLATE_WRMSR        61
22320 #define TEMPLATE_UMUL8        62
22321 #define TEMPLATE_UMUL16       63
22322 #define TEMPLATE_UMUL32       64
22323 #define TEMPLATE_DIV8         65
22324 #define TEMPLATE_DIV16        66
22325 #define TEMPLATE_DIV32        67
22326 #define LAST_TEMPLATE       TEMPLATE_DIV32
22327 #if LAST_TEMPLATE >= MAX_TEMPLATES
22328 #error "MAX_TEMPLATES to low"
22329 #endif
22330
22331 #define COPY8_REGCM     (REGCM_DIVIDEND64 | REGCM_DIVIDEND32 | REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO | REGCM_MMX | REGCM_XMM)
22332 #define COPY16_REGCM    (REGCM_DIVIDEND64 | REGCM_DIVIDEND32 | REGCM_GPR32 | REGCM_GPR16 | REGCM_MMX | REGCM_XMM)  
22333 #define COPY32_REGCM    (REGCM_DIVIDEND64 | REGCM_DIVIDEND32 | REGCM_GPR32 | REGCM_MMX | REGCM_XMM)
22334
22335
22336 static struct ins_template templates[] = {
22337         [TEMPLATE_NOP]      = {
22338                 .lhs = { 
22339                         [ 0] = { REG_UNNEEDED, REGCM_IMMALL },
22340                         [ 1] = { REG_UNNEEDED, REGCM_IMMALL },
22341                         [ 2] = { REG_UNNEEDED, REGCM_IMMALL },
22342                         [ 3] = { REG_UNNEEDED, REGCM_IMMALL },
22343                         [ 4] = { REG_UNNEEDED, REGCM_IMMALL },
22344                         [ 5] = { REG_UNNEEDED, REGCM_IMMALL },
22345                         [ 6] = { REG_UNNEEDED, REGCM_IMMALL },
22346                         [ 7] = { REG_UNNEEDED, REGCM_IMMALL },
22347                         [ 8] = { REG_UNNEEDED, REGCM_IMMALL },
22348                         [ 9] = { REG_UNNEEDED, REGCM_IMMALL },
22349                         [10] = { REG_UNNEEDED, REGCM_IMMALL },
22350                         [11] = { REG_UNNEEDED, REGCM_IMMALL },
22351                         [12] = { REG_UNNEEDED, REGCM_IMMALL },
22352                         [13] = { REG_UNNEEDED, REGCM_IMMALL },
22353                         [14] = { REG_UNNEEDED, REGCM_IMMALL },
22354                         [15] = { REG_UNNEEDED, REGCM_IMMALL },
22355                         [16] = { REG_UNNEEDED, REGCM_IMMALL },
22356                         [17] = { REG_UNNEEDED, REGCM_IMMALL },
22357                         [18] = { REG_UNNEEDED, REGCM_IMMALL },
22358                         [19] = { REG_UNNEEDED, REGCM_IMMALL },
22359                         [20] = { REG_UNNEEDED, REGCM_IMMALL },
22360                         [21] = { REG_UNNEEDED, REGCM_IMMALL },
22361                         [22] = { REG_UNNEEDED, REGCM_IMMALL },
22362                         [23] = { REG_UNNEEDED, REGCM_IMMALL },
22363                         [24] = { REG_UNNEEDED, REGCM_IMMALL },
22364                         [25] = { REG_UNNEEDED, REGCM_IMMALL },
22365                         [26] = { REG_UNNEEDED, REGCM_IMMALL },
22366                         [27] = { REG_UNNEEDED, REGCM_IMMALL },
22367                         [28] = { REG_UNNEEDED, REGCM_IMMALL },
22368                         [29] = { REG_UNNEEDED, REGCM_IMMALL },
22369                         [30] = { REG_UNNEEDED, REGCM_IMMALL },
22370                         [31] = { REG_UNNEEDED, REGCM_IMMALL },
22371                         [32] = { REG_UNNEEDED, REGCM_IMMALL },
22372                         [33] = { REG_UNNEEDED, REGCM_IMMALL },
22373                         [34] = { REG_UNNEEDED, REGCM_IMMALL },
22374                         [35] = { REG_UNNEEDED, REGCM_IMMALL },
22375                         [36] = { REG_UNNEEDED, REGCM_IMMALL },
22376                         [37] = { REG_UNNEEDED, REGCM_IMMALL },
22377                         [38] = { REG_UNNEEDED, REGCM_IMMALL },
22378                         [39] = { REG_UNNEEDED, REGCM_IMMALL },
22379                         [40] = { REG_UNNEEDED, REGCM_IMMALL },
22380                         [41] = { REG_UNNEEDED, REGCM_IMMALL },
22381                         [42] = { REG_UNNEEDED, REGCM_IMMALL },
22382                         [43] = { REG_UNNEEDED, REGCM_IMMALL },
22383                         [44] = { REG_UNNEEDED, REGCM_IMMALL },
22384                         [45] = { REG_UNNEEDED, REGCM_IMMALL },
22385                         [46] = { REG_UNNEEDED, REGCM_IMMALL },
22386                         [47] = { REG_UNNEEDED, REGCM_IMMALL },
22387                         [48] = { REG_UNNEEDED, REGCM_IMMALL },
22388                         [49] = { REG_UNNEEDED, REGCM_IMMALL },
22389                         [50] = { REG_UNNEEDED, REGCM_IMMALL },
22390                         [51] = { REG_UNNEEDED, REGCM_IMMALL },
22391                         [52] = { REG_UNNEEDED, REGCM_IMMALL },
22392                         [53] = { REG_UNNEEDED, REGCM_IMMALL },
22393                         [54] = { REG_UNNEEDED, REGCM_IMMALL },
22394                         [55] = { REG_UNNEEDED, REGCM_IMMALL },
22395                         [56] = { REG_UNNEEDED, REGCM_IMMALL },
22396                         [57] = { REG_UNNEEDED, REGCM_IMMALL },
22397                         [58] = { REG_UNNEEDED, REGCM_IMMALL },
22398                         [59] = { REG_UNNEEDED, REGCM_IMMALL },
22399                         [60] = { REG_UNNEEDED, REGCM_IMMALL },
22400                         [61] = { REG_UNNEEDED, REGCM_IMMALL },
22401                         [62] = { REG_UNNEEDED, REGCM_IMMALL },
22402                         [63] = { REG_UNNEEDED, REGCM_IMMALL },
22403                 },
22404         },
22405         [TEMPLATE_INTCONST8] = { 
22406                 .lhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
22407         },
22408         [TEMPLATE_INTCONST32] = { 
22409                 .lhs = { [0] = { REG_UNNEEDED, REGCM_IMM32 } },
22410         },
22411         [TEMPLATE_UNKNOWNVAL] = {
22412                 .lhs = { [0] = { REG_UNSET, COPY32_REGCM } },
22413         },
22414         [TEMPLATE_COPY8_REG] = {
22415                 .lhs = { [0] = { REG_UNSET, COPY8_REGCM } },
22416                 .rhs = { [0] = { REG_UNSET, COPY8_REGCM }  },
22417         },
22418         [TEMPLATE_COPY16_REG] = {
22419                 .lhs = { [0] = { REG_UNSET, COPY16_REGCM } },
22420                 .rhs = { [0] = { REG_UNSET, COPY16_REGCM }  },
22421         },
22422         [TEMPLATE_COPY32_REG] = {
22423                 .lhs = { [0] = { REG_UNSET, COPY32_REGCM } },
22424                 .rhs = { [0] = { REG_UNSET, COPY32_REGCM }  },
22425         },
22426         [TEMPLATE_COPY_IMM8] = {
22427                 .lhs = { [0] = { REG_UNSET, COPY8_REGCM } },
22428                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
22429         },
22430         [TEMPLATE_COPY_IMM16] = {
22431                 .lhs = { [0] = { REG_UNSET, COPY16_REGCM } },
22432                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM16 | REGCM_IMM8 } },
22433         },
22434         [TEMPLATE_COPY_IMM32] = {
22435                 .lhs = { [0] = { REG_UNSET, COPY32_REGCM } },
22436                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8 } },
22437         },
22438         [TEMPLATE_PHI8] = { 
22439                 .lhs = { [0] = { REG_VIRT0, COPY8_REGCM } },
22440                 .rhs = { [0] = { REG_VIRT0, COPY8_REGCM } },
22441         },
22442         [TEMPLATE_PHI16] = { 
22443                 .lhs = { [0] = { REG_VIRT0, COPY16_REGCM } },
22444                 .rhs = { [0] = { REG_VIRT0, COPY16_REGCM } }, 
22445         },
22446         [TEMPLATE_PHI32] = { 
22447                 .lhs = { [0] = { REG_VIRT0, COPY32_REGCM } },
22448                 .rhs = { [0] = { REG_VIRT0, COPY32_REGCM } }, 
22449         },
22450         [TEMPLATE_STORE8] = {
22451                 .rhs = { 
22452                         [0] = { REG_UNSET, REGCM_GPR32 },
22453                         [1] = { REG_UNSET, REGCM_GPR8_LO },
22454                 },
22455         },
22456         [TEMPLATE_STORE16] = {
22457                 .rhs = { 
22458                         [0] = { REG_UNSET, REGCM_GPR32 },
22459                         [1] = { REG_UNSET, REGCM_GPR16 },
22460                 },
22461         },
22462         [TEMPLATE_STORE32] = {
22463                 .rhs = { 
22464                         [0] = { REG_UNSET, REGCM_GPR32 },
22465                         [1] = { REG_UNSET, REGCM_GPR32 },
22466                 },
22467         },
22468         [TEMPLATE_LOAD8] = {
22469                 .lhs = { [0] = { REG_UNSET, REGCM_GPR8_LO } },
22470                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
22471         },
22472         [TEMPLATE_LOAD16] = {
22473                 .lhs = { [0] = { REG_UNSET, REGCM_GPR16 } },
22474                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
22475         },
22476         [TEMPLATE_LOAD32] = {
22477                 .lhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
22478                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
22479         },
22480         [TEMPLATE_BINARY8_REG] = {
22481                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
22482                 .rhs = { 
22483                         [0] = { REG_VIRT0, REGCM_GPR8_LO },
22484                         [1] = { REG_UNSET, REGCM_GPR8_LO },
22485                 },
22486         },
22487         [TEMPLATE_BINARY16_REG] = {
22488                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
22489                 .rhs = { 
22490                         [0] = { REG_VIRT0, REGCM_GPR16 },
22491                         [1] = { REG_UNSET, REGCM_GPR16 },
22492                 },
22493         },
22494         [TEMPLATE_BINARY32_REG] = {
22495                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
22496                 .rhs = { 
22497                         [0] = { REG_VIRT0, REGCM_GPR32 },
22498                         [1] = { REG_UNSET, REGCM_GPR32 },
22499                 },
22500         },
22501         [TEMPLATE_BINARY8_IMM] = {
22502                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
22503                 .rhs = { 
22504                         [0] = { REG_VIRT0,    REGCM_GPR8_LO },
22505                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
22506                 },
22507         },
22508         [TEMPLATE_BINARY16_IMM] = {
22509                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
22510                 .rhs = { 
22511                         [0] = { REG_VIRT0,    REGCM_GPR16 },
22512                         [1] = { REG_UNNEEDED, REGCM_IMM16 },
22513                 },
22514         },
22515         [TEMPLATE_BINARY32_IMM] = {
22516                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
22517                 .rhs = { 
22518                         [0] = { REG_VIRT0,    REGCM_GPR32 },
22519                         [1] = { REG_UNNEEDED, REGCM_IMM32 },
22520                 },
22521         },
22522         [TEMPLATE_SL8_CL] = {
22523                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
22524                 .rhs = { 
22525                         [0] = { REG_VIRT0, REGCM_GPR8_LO },
22526                         [1] = { REG_CL, REGCM_GPR8_LO },
22527                 },
22528         },
22529         [TEMPLATE_SL16_CL] = {
22530                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
22531                 .rhs = { 
22532                         [0] = { REG_VIRT0, REGCM_GPR16 },
22533                         [1] = { REG_CL, REGCM_GPR8_LO },
22534                 },
22535         },
22536         [TEMPLATE_SL32_CL] = {
22537                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
22538                 .rhs = { 
22539                         [0] = { REG_VIRT0, REGCM_GPR32 },
22540                         [1] = { REG_CL, REGCM_GPR8_LO },
22541                 },
22542         },
22543         [TEMPLATE_SL8_IMM] = {
22544                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
22545                 .rhs = { 
22546                         [0] = { REG_VIRT0,    REGCM_GPR8_LO },
22547                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
22548                 },
22549         },
22550         [TEMPLATE_SL16_IMM] = {
22551                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
22552                 .rhs = { 
22553                         [0] = { REG_VIRT0,    REGCM_GPR16 },
22554                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
22555                 },
22556         },
22557         [TEMPLATE_SL32_IMM] = {
22558                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
22559                 .rhs = { 
22560                         [0] = { REG_VIRT0,    REGCM_GPR32 },
22561                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
22562                 },
22563         },
22564         [TEMPLATE_UNARY8] = {
22565                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
22566                 .rhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
22567         },
22568         [TEMPLATE_UNARY16] = {
22569                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
22570                 .rhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
22571         },
22572         [TEMPLATE_UNARY32] = {
22573                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
22574                 .rhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
22575         },
22576         [TEMPLATE_CMP8_REG] = {
22577                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22578                 .rhs = {
22579                         [0] = { REG_UNSET, REGCM_GPR8_LO },
22580                         [1] = { REG_UNSET, REGCM_GPR8_LO },
22581                 },
22582         },
22583         [TEMPLATE_CMP16_REG] = {
22584                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22585                 .rhs = {
22586                         [0] = { REG_UNSET, REGCM_GPR16 },
22587                         [1] = { REG_UNSET, REGCM_GPR16 },
22588                 },
22589         },
22590         [TEMPLATE_CMP32_REG] = {
22591                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22592                 .rhs = {
22593                         [0] = { REG_UNSET, REGCM_GPR32 },
22594                         [1] = { REG_UNSET, REGCM_GPR32 },
22595                 },
22596         },
22597         [TEMPLATE_CMP8_IMM] = {
22598                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22599                 .rhs = {
22600                         [0] = { REG_UNSET, REGCM_GPR8_LO },
22601                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
22602                 },
22603         },
22604         [TEMPLATE_CMP16_IMM] = {
22605                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22606                 .rhs = {
22607                         [0] = { REG_UNSET, REGCM_GPR16 },
22608                         [1] = { REG_UNNEEDED, REGCM_IMM16 },
22609                 },
22610         },
22611         [TEMPLATE_CMP32_IMM] = {
22612                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22613                 .rhs = {
22614                         [0] = { REG_UNSET, REGCM_GPR32 },
22615                         [1] = { REG_UNNEEDED, REGCM_IMM32 },
22616                 },
22617         },
22618         [TEMPLATE_TEST8] = {
22619                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22620                 .rhs = { [0] = { REG_UNSET, REGCM_GPR8_LO } },
22621         },
22622         [TEMPLATE_TEST16] = {
22623                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22624                 .rhs = { [0] = { REG_UNSET, REGCM_GPR16 } },
22625         },
22626         [TEMPLATE_TEST32] = {
22627                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22628                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
22629         },
22630         [TEMPLATE_SET] = {
22631                 .lhs = { [0] = { REG_UNSET, REGCM_GPR8_LO } },
22632                 .rhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22633         },
22634         [TEMPLATE_JMP] = {
22635                 .rhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22636         },
22637         [TEMPLATE_RET] = {
22638                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
22639         },
22640         [TEMPLATE_INB_DX] = {
22641                 .lhs = { [0] = { REG_AL,  REGCM_GPR8_LO } },  
22642                 .rhs = { [0] = { REG_DX, REGCM_GPR16 } },
22643         },
22644         [TEMPLATE_INB_IMM] = {
22645                 .lhs = { [0] = { REG_AL,  REGCM_GPR8_LO } },  
22646                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
22647         },
22648         [TEMPLATE_INW_DX]  = { 
22649                 .lhs = { [0] = { REG_AX,  REGCM_GPR16 } }, 
22650                 .rhs = { [0] = { REG_DX, REGCM_GPR16 } },
22651         },
22652         [TEMPLATE_INW_IMM] = { 
22653                 .lhs = { [0] = { REG_AX,  REGCM_GPR16 } }, 
22654                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
22655         },
22656         [TEMPLATE_INL_DX]  = {
22657                 .lhs = { [0] = { REG_EAX, REGCM_GPR32 } },
22658                 .rhs = { [0] = { REG_DX, REGCM_GPR16 } },
22659         },
22660         [TEMPLATE_INL_IMM] = {
22661                 .lhs = { [0] = { REG_EAX, REGCM_GPR32 } },
22662                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
22663         },
22664         [TEMPLATE_OUTB_DX] = { 
22665                 .rhs = {
22666                         [0] = { REG_AL,  REGCM_GPR8_LO },
22667                         [1] = { REG_DX, REGCM_GPR16 },
22668                 },
22669         },
22670         [TEMPLATE_OUTB_IMM] = { 
22671                 .rhs = {
22672                         [0] = { REG_AL,  REGCM_GPR8_LO },  
22673                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
22674                 },
22675         },
22676         [TEMPLATE_OUTW_DX] = { 
22677                 .rhs = {
22678                         [0] = { REG_AX,  REGCM_GPR16 },
22679                         [1] = { REG_DX, REGCM_GPR16 },
22680                 },
22681         },
22682         [TEMPLATE_OUTW_IMM] = {
22683                 .rhs = {
22684                         [0] = { REG_AX,  REGCM_GPR16 }, 
22685                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
22686                 },
22687         },
22688         [TEMPLATE_OUTL_DX] = { 
22689                 .rhs = {
22690                         [0] = { REG_EAX, REGCM_GPR32 },
22691                         [1] = { REG_DX, REGCM_GPR16 },
22692                 },
22693         },
22694         [TEMPLATE_OUTL_IMM] = { 
22695                 .rhs = {
22696                         [0] = { REG_EAX, REGCM_GPR32 }, 
22697                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
22698                 },
22699         },
22700         [TEMPLATE_BSF] = {
22701                 .lhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
22702                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
22703         },
22704         [TEMPLATE_RDMSR] = {
22705                 .lhs = { 
22706                         [0] = { REG_EAX, REGCM_GPR32 },
22707                         [1] = { REG_EDX, REGCM_GPR32 },
22708                 },
22709                 .rhs = { [0] = { REG_ECX, REGCM_GPR32 } },
22710         },
22711         [TEMPLATE_WRMSR] = {
22712                 .rhs = {
22713                         [0] = { REG_ECX, REGCM_GPR32 },
22714                         [1] = { REG_EAX, REGCM_GPR32 },
22715                         [2] = { REG_EDX, REGCM_GPR32 },
22716                 },
22717         },
22718         [TEMPLATE_UMUL8] = {
22719                 .lhs = { [0] = { REG_AX, REGCM_GPR16 } },
22720                 .rhs = { 
22721                         [0] = { REG_AL, REGCM_GPR8_LO },
22722                         [1] = { REG_UNSET, REGCM_GPR8_LO },
22723                 },
22724         },
22725         [TEMPLATE_UMUL16] = {
22726                 .lhs = { [0] = { REG_DXAX, REGCM_DIVIDEND32 } },
22727                 .rhs = { 
22728                         [0] = { REG_AX, REGCM_GPR16 },
22729                         [1] = { REG_UNSET, REGCM_GPR16 },
22730                 },
22731         },
22732         [TEMPLATE_UMUL32] = {
22733                 .lhs = { [0] = { REG_EDXEAX, REGCM_DIVIDEND64 } },
22734                 .rhs = { 
22735                         [0] = { REG_EAX, REGCM_GPR32 },
22736                         [1] = { REG_UNSET, REGCM_GPR32 },
22737                 },
22738         },
22739         [TEMPLATE_DIV8] = {
22740                 .lhs = { 
22741                         [0] = { REG_AL, REGCM_GPR8_LO },
22742                         [1] = { REG_AH, REGCM_GPR8 },
22743                 },
22744                 .rhs = {
22745                         [0] = { REG_AX, REGCM_GPR16 },
22746                         [1] = { REG_UNSET, REGCM_GPR8_LO },
22747                 },
22748         },
22749         [TEMPLATE_DIV16] = {
22750                 .lhs = { 
22751                         [0] = { REG_AX, REGCM_GPR16 },
22752                         [1] = { REG_DX, REGCM_GPR16 },
22753                 },
22754                 .rhs = {
22755                         [0] = { REG_DXAX, REGCM_DIVIDEND32 },
22756                         [1] = { REG_UNSET, REGCM_GPR16 },
22757                 },
22758         },
22759         [TEMPLATE_DIV32] = {
22760                 .lhs = { 
22761                         [0] = { REG_EAX, REGCM_GPR32 },
22762                         [1] = { REG_EDX, REGCM_GPR32 },
22763                 },
22764                 .rhs = {
22765                         [0] = { REG_EDXEAX, REGCM_DIVIDEND64 },
22766                         [1] = { REG_UNSET, REGCM_GPR32 },
22767                 },
22768         },
22769 };
22770
22771 static void fixup_branch(struct compile_state *state,
22772         struct triple *branch, int jmp_op, int cmp_op, struct type *cmp_type,
22773         struct triple *left, struct triple *right)
22774 {
22775         struct triple *test;
22776         if (!left) {
22777                 internal_error(state, branch, "no branch test?");
22778         }
22779         test = pre_triple(state, branch,
22780                 cmp_op, cmp_type, left, right);
22781         test->template_id = TEMPLATE_TEST32; 
22782         if (cmp_op == OP_CMP) {
22783                 test->template_id = TEMPLATE_CMP32_REG;
22784                 if (get_imm32(test, &RHS(test, 1))) {
22785                         test->template_id = TEMPLATE_CMP32_IMM;
22786                 }
22787         }
22788         use_triple(RHS(test, 0), test);
22789         use_triple(RHS(test, 1), test);
22790         unuse_triple(RHS(branch, 0), branch);
22791         RHS(branch, 0) = test;
22792         branch->op = jmp_op;
22793         branch->template_id = TEMPLATE_JMP;
22794         use_triple(RHS(branch, 0), branch);
22795 }
22796
22797 static void fixup_branches(struct compile_state *state,
22798         struct triple *cmp, struct triple *use, int jmp_op)
22799 {
22800         struct triple_set *entry, *next;
22801         for(entry = use->use; entry; entry = next) {
22802                 next = entry->next;
22803                 if (entry->member->op == OP_COPY) {
22804                         fixup_branches(state, cmp, entry->member, jmp_op);
22805                 }
22806                 else if (entry->member->op == OP_CBRANCH) {
22807                         struct triple *branch;
22808                         struct triple *left, *right;
22809                         left = right = 0;
22810                         left = RHS(cmp, 0);
22811                         if (cmp->rhs > 1) {
22812                                 right = RHS(cmp, 1);
22813                         }
22814                         branch = entry->member;
22815                         fixup_branch(state, branch, jmp_op, 
22816                                 cmp->op, cmp->type, left, right);
22817                 }
22818         }
22819 }
22820
22821 static void bool_cmp(struct compile_state *state, 
22822         struct triple *ins, int cmp_op, int jmp_op, int set_op)
22823 {
22824         struct triple_set *entry, *next;
22825         struct triple *set, *convert;
22826
22827         /* Put a barrier up before the cmp which preceeds the
22828          * copy instruction.  If a set actually occurs this gives
22829          * us a chance to move variables in registers out of the way.
22830          */
22831
22832         /* Modify the comparison operator */
22833         ins->op = cmp_op;
22834         ins->template_id = TEMPLATE_TEST32;
22835         if (cmp_op == OP_CMP) {
22836                 ins->template_id = TEMPLATE_CMP32_REG;
22837                 if (get_imm32(ins, &RHS(ins, 1))) {
22838                         ins->template_id =  TEMPLATE_CMP32_IMM;
22839                 }
22840         }
22841         /* Generate the instruction sequence that will transform the
22842          * result of the comparison into a logical value.
22843          */
22844         set = post_triple(state, ins, set_op, &uchar_type, ins, 0);
22845         use_triple(ins, set);
22846         set->template_id = TEMPLATE_SET;
22847
22848         convert = set;
22849         if (!equiv_types(ins->type, set->type)) {
22850                 convert = post_triple(state, set, OP_CONVERT, ins->type, set, 0);
22851                 use_triple(set, convert);
22852                 convert->template_id = TEMPLATE_COPY32_REG;
22853         }
22854
22855         for(entry = ins->use; entry; entry = next) {
22856                 next = entry->next;
22857                 if (entry->member == set) {
22858                         continue;
22859                 }
22860                 replace_rhs_use(state, ins, convert, entry->member);
22861         }
22862         fixup_branches(state, ins, convert, jmp_op);
22863 }
22864
22865 struct reg_info arch_reg_lhs(struct compile_state *state, struct triple *ins, int index)
22866 {
22867         struct ins_template *template;
22868         struct reg_info result;
22869         int zlhs;
22870         if (ins->op == OP_PIECE) {
22871                 index = ins->u.cval;
22872                 ins = MISC(ins, 0);
22873         }
22874         zlhs = ins->lhs;
22875         if (triple_is_def(state, ins)) {
22876                 zlhs = 1;
22877         }
22878         if (index >= zlhs) {
22879                 internal_error(state, ins, "index %d out of range for %s",
22880                         index, tops(ins->op));
22881         }
22882         switch(ins->op) {
22883         case OP_ASM:
22884                 template = &ins->u.ainfo->tmpl;
22885                 break;
22886         default:
22887                 if (ins->template_id > LAST_TEMPLATE) {
22888                         internal_error(state, ins, "bad template number %d", 
22889                                 ins->template_id);
22890                 }
22891                 template = &templates[ins->template_id];
22892                 break;
22893         }
22894         result = template->lhs[index];
22895         result.regcm = arch_regcm_normalize(state, result.regcm);
22896         if (result.reg != REG_UNNEEDED) {
22897                 result.regcm &= ~(REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8);
22898         }
22899         if (result.regcm == 0) {
22900                 internal_error(state, ins, "lhs %d regcm == 0", index);
22901         }
22902         return result;
22903 }
22904
22905 struct reg_info arch_reg_rhs(struct compile_state *state, struct triple *ins, int index)
22906 {
22907         struct reg_info result;
22908         struct ins_template *template;
22909         if ((index > ins->rhs) ||
22910                 (ins->op == OP_PIECE)) {
22911                 internal_error(state, ins, "index %d out of range for %s\n",
22912                         index, tops(ins->op));
22913         }
22914         switch(ins->op) {
22915         case OP_ASM:
22916                 template = &ins->u.ainfo->tmpl;
22917                 break;
22918         case OP_PHI:
22919                 index = 0;
22920                 /* Fall through */
22921         default:
22922                 if (ins->template_id > LAST_TEMPLATE) {
22923                         internal_error(state, ins, "bad template number %d", 
22924                                 ins->template_id);
22925                 }
22926                 template = &templates[ins->template_id];
22927                 break;
22928         }
22929         result = template->rhs[index];
22930         result.regcm = arch_regcm_normalize(state, result.regcm);
22931         if (result.regcm == 0) {
22932                 internal_error(state, ins, "rhs %d regcm == 0", index);
22933         }
22934         return result;
22935 }
22936
22937 static struct triple *mod_div(struct compile_state *state,
22938         struct triple *ins, int div_op, int index)
22939 {
22940         struct triple *div, *piece0, *piece1;
22941         
22942         /* Generate the appropriate division instruction */
22943         div = post_triple(state, ins, div_op, ins->type, 0, 0);
22944         RHS(div, 0) = RHS(ins, 0);
22945         RHS(div, 1) = RHS(ins, 1);
22946         piece0 = LHS(div, 0);
22947         piece1 = LHS(div, 1);
22948         div->template_id  = TEMPLATE_DIV32;
22949         use_triple(RHS(div, 0), div);
22950         use_triple(RHS(div, 1), div);
22951         use_triple(LHS(div, 0), div);
22952         use_triple(LHS(div, 1), div);
22953
22954         /* Replate uses of ins with the appropriate piece of the div */
22955         propogate_use(state, ins, LHS(div, index));
22956         release_triple(state, ins);
22957
22958         /* Return the address of the next instruction */
22959         return piece1->next;
22960 }
22961
22962 static int noop_adecl(struct triple *adecl)
22963 {
22964         struct triple_set *use;
22965         /* It's a noop if it doesn't specify stoorage */
22966         if (adecl->lhs == 0) {
22967                 return 1;
22968         }
22969         /* Is the adecl used? If not it's a noop */
22970         for(use = adecl->use; use ; use = use->next) {
22971                 if ((use->member->op != OP_PIECE) ||
22972                         (MISC(use->member, 0) != adecl)) {
22973                         return 0;
22974                 }
22975         }
22976         return 1;
22977 }
22978
22979 static struct triple *x86_deposit(struct compile_state *state, struct triple *ins)
22980 {
22981         struct triple *mask, *nmask, *shift;
22982         struct triple *val, *val_mask, *val_shift;
22983         struct triple *targ, *targ_mask;
22984         struct triple *new;
22985         ulong_t the_mask, the_nmask;
22986
22987         targ = RHS(ins, 0);
22988         val = RHS(ins, 1);
22989
22990         /* Get constant for the mask value */
22991         the_mask = 1;
22992         the_mask <<= ins->u.bitfield.size;
22993         the_mask -= 1;
22994         the_mask <<= ins->u.bitfield.offset;
22995         mask = pre_triple(state, ins, OP_INTCONST, &uint_type, 0, 0);
22996         mask->u.cval = the_mask;
22997
22998         /* Get the inverted mask value */
22999         the_nmask = ~the_mask;
23000         nmask = pre_triple(state, ins, OP_INTCONST, &uint_type, 0, 0);
23001         nmask->u.cval = the_nmask;
23002
23003         /* Get constant for the shift value */
23004         shift = pre_triple(state, ins, OP_INTCONST, &uint_type, 0, 0);
23005         shift->u.cval = ins->u.bitfield.offset;
23006
23007         /* Shift and mask the source value */
23008         val_shift = val;
23009         if (shift->u.cval != 0) {
23010                 val_shift = pre_triple(state, ins, OP_SL, val->type, val, shift);
23011                 use_triple(val, val_shift);
23012                 use_triple(shift, val_shift);
23013         }
23014         val_mask = val_shift;
23015         if (is_signed(val->type)) {
23016                 val_mask = pre_triple(state, ins, OP_AND, val->type, val_shift, mask);
23017                 use_triple(val_shift, val_mask);
23018                 use_triple(mask, val_mask);
23019         }
23020
23021         /* Mask the target value */
23022         targ_mask = pre_triple(state, ins, OP_AND, targ->type, targ, nmask);
23023         use_triple(targ, targ_mask);
23024         use_triple(nmask, targ_mask);
23025
23026         /* Now combined them together */
23027         new = pre_triple(state, ins, OP_OR, targ->type, targ_mask, val_mask);
23028         use_triple(targ_mask, new);
23029         use_triple(val_mask, new);
23030
23031         /* Move all of the users over to the new expression */
23032         propogate_use(state, ins, new);
23033
23034         /* Delete the original triple */
23035         release_triple(state, ins);
23036
23037         /* Restart the transformation at mask */
23038         return mask;
23039 }
23040
23041 static struct triple *x86_extract(struct compile_state *state, struct triple *ins)
23042 {
23043         struct triple *mask, *shift;
23044         struct triple *val, *val_mask, *val_shift;
23045         ulong_t the_mask;
23046
23047         val = RHS(ins, 0);
23048
23049         /* Get constant for the mask value */
23050         the_mask = 1;
23051         the_mask <<= ins->u.bitfield.size;
23052         the_mask -= 1;
23053         mask = pre_triple(state, ins, OP_INTCONST, &int_type, 0, 0);
23054         mask->u.cval = the_mask;
23055
23056         /* Get constant for the right shift value */
23057         shift = pre_triple(state, ins, OP_INTCONST, &int_type, 0, 0);
23058         shift->u.cval = ins->u.bitfield.offset;
23059
23060         /* Shift arithmetic right, to correct the sign */
23061         val_shift = val;
23062         if (shift->u.cval != 0) {
23063                 int op;
23064                 if (ins->op == OP_SEXTRACT) {
23065                         op = OP_SSR;
23066                 } else {
23067                         op = OP_USR;
23068                 }
23069                 val_shift = pre_triple(state, ins, op, val->type, val, shift);
23070                 use_triple(val, val_shift);
23071                 use_triple(shift, val_shift);
23072         }
23073
23074         /* Finally mask the value */
23075         val_mask = pre_triple(state, ins, OP_AND, ins->type, val_shift, mask);
23076         use_triple(val_shift, val_mask);
23077         use_triple(mask,      val_mask);
23078
23079         /* Move all of the users over to the new expression */
23080         propogate_use(state, ins, val_mask);
23081
23082         /* Release the original instruction */
23083         release_triple(state, ins);
23084
23085         return mask;
23086
23087 }
23088
23089 static struct triple *transform_to_arch_instruction(
23090         struct compile_state *state, struct triple *ins)
23091 {
23092         /* Transform from generic 3 address instructions
23093          * to archtecture specific instructions.
23094          * And apply architecture specific constraints to instructions.
23095          * Copies are inserted to preserve the register flexibility
23096          * of 3 address instructions.
23097          */
23098         struct triple *next, *value;
23099         size_t size;
23100         next = ins->next;
23101         switch(ins->op) {
23102         case OP_INTCONST:
23103                 ins->template_id = TEMPLATE_INTCONST32;
23104                 if (ins->u.cval < 256) {
23105                         ins->template_id = TEMPLATE_INTCONST8;
23106                 }
23107                 break;
23108         case OP_ADDRCONST:
23109                 ins->template_id = TEMPLATE_INTCONST32;
23110                 break;
23111         case OP_UNKNOWNVAL:
23112                 ins->template_id = TEMPLATE_UNKNOWNVAL;
23113                 break;
23114         case OP_NOOP:
23115         case OP_SDECL:
23116         case OP_BLOBCONST:
23117         case OP_LABEL:
23118                 ins->template_id = TEMPLATE_NOP;
23119                 break;
23120         case OP_COPY:
23121         case OP_CONVERT:
23122                 size = size_of(state, ins->type);
23123                 value = RHS(ins, 0);
23124                 if (is_imm8(value) && (size <= SIZEOF_I8)) {
23125                         ins->template_id = TEMPLATE_COPY_IMM8;
23126                 }
23127                 else if (is_imm16(value) && (size <= SIZEOF_I16)) {
23128                         ins->template_id = TEMPLATE_COPY_IMM16;
23129                 }
23130                 else if (is_imm32(value) && (size <= SIZEOF_I32)) {
23131                         ins->template_id = TEMPLATE_COPY_IMM32;
23132                 }
23133                 else if (is_const(value)) {
23134                         internal_error(state, ins, "bad constant passed to copy");
23135                 }
23136                 else if (size <= SIZEOF_I8) {
23137                         ins->template_id = TEMPLATE_COPY8_REG;
23138                 }
23139                 else if (size <= SIZEOF_I16) {
23140                         ins->template_id = TEMPLATE_COPY16_REG;
23141                 }
23142                 else if (size <= SIZEOF_I32) {
23143                         ins->template_id = TEMPLATE_COPY32_REG;
23144                 }
23145                 else {
23146                         internal_error(state, ins, "bad type passed to copy");
23147                 }
23148                 break;
23149         case OP_PHI:
23150                 size = size_of(state, ins->type);
23151                 if (size <= SIZEOF_I8) {
23152                         ins->template_id = TEMPLATE_PHI8;
23153                 }
23154                 else if (size <= SIZEOF_I16) {
23155                         ins->template_id = TEMPLATE_PHI16;
23156                 }
23157                 else if (size <= SIZEOF_I32) {
23158                         ins->template_id = TEMPLATE_PHI32;
23159                 }
23160                 else {
23161                         internal_error(state, ins, "bad type passed to phi");
23162                 }
23163                 break;
23164         case OP_ADECL:
23165                 /* Adecls should always be treated as dead code and
23166                  * removed.  If we are not optimizing they may linger.
23167                  */
23168                 if (!noop_adecl(ins)) {
23169                         internal_error(state, ins, "adecl remains?");
23170                 }
23171                 ins->template_id = TEMPLATE_NOP;
23172                 next = after_lhs(state, ins);
23173                 break;
23174         case OP_STORE:
23175                 switch(ins->type->type & TYPE_MASK) {
23176                 case TYPE_CHAR:    case TYPE_UCHAR:
23177                         ins->template_id = TEMPLATE_STORE8;
23178                         break;
23179                 case TYPE_SHORT:   case TYPE_USHORT:
23180                         ins->template_id = TEMPLATE_STORE16;
23181                         break;
23182                 case TYPE_INT:     case TYPE_UINT:
23183                 case TYPE_LONG:    case TYPE_ULONG:
23184                 case TYPE_POINTER:
23185                         ins->template_id = TEMPLATE_STORE32;
23186                         break;
23187                 default:
23188                         internal_error(state, ins, "unknown type in store");
23189                         break;
23190                 }
23191                 break;
23192         case OP_LOAD:
23193                 switch(ins->type->type & TYPE_MASK) {
23194                 case TYPE_CHAR:   case TYPE_UCHAR:
23195                 case TYPE_SHORT:  case TYPE_USHORT:
23196                 case TYPE_INT:    case TYPE_UINT:
23197                 case TYPE_LONG:   case TYPE_ULONG:
23198                 case TYPE_POINTER:
23199                         break;
23200                 default:
23201                         internal_error(state, ins, "unknown type in load");
23202                         break;
23203                 }
23204                 ins->template_id = TEMPLATE_LOAD32;
23205                 break;
23206         case OP_ADD:
23207         case OP_SUB:
23208         case OP_AND:
23209         case OP_XOR:
23210         case OP_OR:
23211         case OP_SMUL:
23212                 ins->template_id = TEMPLATE_BINARY32_REG;
23213                 if (get_imm32(ins, &RHS(ins, 1))) {
23214                         ins->template_id = TEMPLATE_BINARY32_IMM;
23215                 }
23216                 break;
23217         case OP_SDIVT:
23218         case OP_UDIVT:
23219                 ins->template_id = TEMPLATE_DIV32;
23220                 next = after_lhs(state, ins);
23221                 break;
23222         case OP_UMUL:
23223                 ins->template_id = TEMPLATE_UMUL32;
23224                 break;
23225         case OP_UDIV:
23226                 next = mod_div(state, ins, OP_UDIVT, 0);
23227                 break;
23228         case OP_SDIV:
23229                 next = mod_div(state, ins, OP_SDIVT, 0);
23230                 break;
23231         case OP_UMOD:
23232                 next = mod_div(state, ins, OP_UDIVT, 1);
23233                 break;
23234         case OP_SMOD:
23235                 next = mod_div(state, ins, OP_SDIVT, 1);
23236                 break;
23237         case OP_SL:
23238         case OP_SSR:
23239         case OP_USR:
23240                 ins->template_id = TEMPLATE_SL32_CL;
23241                 if (get_imm8(ins, &RHS(ins, 1))) {
23242                         ins->template_id = TEMPLATE_SL32_IMM;
23243                 } else if (size_of(state, RHS(ins, 1)->type) > SIZEOF_CHAR) {
23244                         typed_pre_copy(state, &uchar_type, ins, 1);
23245                 }
23246                 break;
23247         case OP_INVERT:
23248         case OP_NEG:
23249                 ins->template_id = TEMPLATE_UNARY32;
23250                 break;
23251         case OP_EQ: 
23252                 bool_cmp(state, ins, OP_CMP, OP_JMP_EQ, OP_SET_EQ); 
23253                 break;
23254         case OP_NOTEQ:
23255                 bool_cmp(state, ins, OP_CMP, OP_JMP_NOTEQ, OP_SET_NOTEQ);
23256                 break;
23257         case OP_SLESS:
23258                 bool_cmp(state, ins, OP_CMP, OP_JMP_SLESS, OP_SET_SLESS);
23259                 break;
23260         case OP_ULESS:
23261                 bool_cmp(state, ins, OP_CMP, OP_JMP_ULESS, OP_SET_ULESS);
23262                 break;
23263         case OP_SMORE:
23264                 bool_cmp(state, ins, OP_CMP, OP_JMP_SMORE, OP_SET_SMORE);
23265                 break;
23266         case OP_UMORE:
23267                 bool_cmp(state, ins, OP_CMP, OP_JMP_UMORE, OP_SET_UMORE);
23268                 break;
23269         case OP_SLESSEQ:
23270                 bool_cmp(state, ins, OP_CMP, OP_JMP_SLESSEQ, OP_SET_SLESSEQ);
23271                 break;
23272         case OP_ULESSEQ:
23273                 bool_cmp(state, ins, OP_CMP, OP_JMP_ULESSEQ, OP_SET_ULESSEQ);
23274                 break;
23275         case OP_SMOREEQ:
23276                 bool_cmp(state, ins, OP_CMP, OP_JMP_SMOREEQ, OP_SET_SMOREEQ);
23277                 break;
23278         case OP_UMOREEQ:
23279                 bool_cmp(state, ins, OP_CMP, OP_JMP_UMOREEQ, OP_SET_UMOREEQ);
23280                 break;
23281         case OP_LTRUE:
23282                 bool_cmp(state, ins, OP_TEST, OP_JMP_NOTEQ, OP_SET_NOTEQ);
23283                 break;
23284         case OP_LFALSE:
23285                 bool_cmp(state, ins, OP_TEST, OP_JMP_EQ, OP_SET_EQ);
23286                 break;
23287         case OP_BRANCH:
23288                 ins->op = OP_JMP;
23289                 ins->template_id = TEMPLATE_NOP;
23290                 break;
23291         case OP_CBRANCH:
23292                 fixup_branch(state, ins, OP_JMP_NOTEQ, OP_TEST, 
23293                         RHS(ins, 0)->type, RHS(ins, 0), 0);
23294                 break;
23295         case OP_CALL:
23296                 ins->template_id = TEMPLATE_NOP;
23297                 break;
23298         case OP_RET:
23299                 ins->template_id = TEMPLATE_RET;
23300                 break;
23301         case OP_INB:
23302         case OP_INW:
23303         case OP_INL:
23304                 switch(ins->op) {
23305                 case OP_INB: ins->template_id = TEMPLATE_INB_DX; break;
23306                 case OP_INW: ins->template_id = TEMPLATE_INW_DX; break;
23307                 case OP_INL: ins->template_id = TEMPLATE_INL_DX; break;
23308                 }
23309                 if (get_imm8(ins, &RHS(ins, 0))) {
23310                         ins->template_id += 1;
23311                 }
23312                 break;
23313         case OP_OUTB:
23314         case OP_OUTW:
23315         case OP_OUTL:
23316                 switch(ins->op) {
23317                 case OP_OUTB: ins->template_id = TEMPLATE_OUTB_DX; break;
23318                 case OP_OUTW: ins->template_id = TEMPLATE_OUTW_DX; break;
23319                 case OP_OUTL: ins->template_id = TEMPLATE_OUTL_DX; break;
23320                 }
23321                 if (get_imm8(ins, &RHS(ins, 1))) {
23322                         ins->template_id += 1;
23323                 }
23324                 break;
23325         case OP_BSF:
23326         case OP_BSR:
23327                 ins->template_id = TEMPLATE_BSF;
23328                 break;
23329         case OP_RDMSR:
23330                 ins->template_id = TEMPLATE_RDMSR;
23331                 next = after_lhs(state, ins);
23332                 break;
23333         case OP_WRMSR:
23334                 ins->template_id = TEMPLATE_WRMSR;
23335                 break;
23336         case OP_HLT:
23337                 ins->template_id = TEMPLATE_NOP;
23338                 break;
23339         case OP_ASM:
23340                 ins->template_id = TEMPLATE_NOP;
23341                 next = after_lhs(state, ins);
23342                 break;
23343                 /* Already transformed instructions */
23344         case OP_TEST:
23345                 ins->template_id = TEMPLATE_TEST32;
23346                 break;
23347         case OP_CMP:
23348                 ins->template_id = TEMPLATE_CMP32_REG;
23349                 if (get_imm32(ins, &RHS(ins, 1))) {
23350                         ins->template_id = TEMPLATE_CMP32_IMM;
23351                 }
23352                 break;
23353         case OP_JMP:
23354                 ins->template_id = TEMPLATE_NOP;
23355                 break;
23356         case OP_JMP_EQ:      case OP_JMP_NOTEQ:
23357         case OP_JMP_SLESS:   case OP_JMP_ULESS:
23358         case OP_JMP_SMORE:   case OP_JMP_UMORE:
23359         case OP_JMP_SLESSEQ: case OP_JMP_ULESSEQ:
23360         case OP_JMP_SMOREEQ: case OP_JMP_UMOREEQ:
23361                 ins->template_id = TEMPLATE_JMP;
23362                 break;
23363         case OP_SET_EQ:      case OP_SET_NOTEQ:
23364         case OP_SET_SLESS:   case OP_SET_ULESS:
23365         case OP_SET_SMORE:   case OP_SET_UMORE:
23366         case OP_SET_SLESSEQ: case OP_SET_ULESSEQ:
23367         case OP_SET_SMOREEQ: case OP_SET_UMOREEQ:
23368                 ins->template_id = TEMPLATE_SET;
23369                 break;
23370         case OP_DEPOSIT:
23371                 next = x86_deposit(state, ins);
23372                 break;
23373         case OP_SEXTRACT:
23374         case OP_UEXTRACT:
23375                 next = x86_extract(state, ins);
23376                 break;
23377                 /* Unhandled instructions */
23378         case OP_PIECE:
23379         default:
23380                 internal_error(state, ins, "unhandled ins: %d %s",
23381                         ins->op, tops(ins->op));
23382                 break;
23383         }
23384         return next;
23385 }
23386
23387 static long next_label(struct compile_state *state)
23388 {
23389         static long label_counter = 1000;
23390         return ++label_counter;
23391 }
23392 static void generate_local_labels(struct compile_state *state)
23393 {
23394         struct triple *first, *label;
23395         first = state->first;
23396         label = first;
23397         do {
23398                 if ((label->op == OP_LABEL) || 
23399                         (label->op == OP_SDECL)) {
23400                         if (label->use) {
23401                                 label->u.cval = next_label(state);
23402                         } else {
23403                                 label->u.cval = 0;
23404                         }
23405                         
23406                 }
23407                 label = label->next;
23408         } while(label != first);
23409 }
23410
23411 static int check_reg(struct compile_state *state, 
23412         struct triple *triple, int classes)
23413 {
23414         unsigned mask;
23415         int reg;
23416         reg = ID_REG(triple->id);
23417         if (reg == REG_UNSET) {
23418                 internal_error(state, triple, "register not set");
23419         }
23420         mask = arch_reg_regcm(state, reg);
23421         if (!(classes & mask)) {
23422                 internal_error(state, triple, "reg %d in wrong class",
23423                         reg);
23424         }
23425         return reg;
23426 }
23427
23428
23429 #if REG_XMM7 != 44
23430 #error "Registers have renumberd fix arch_reg_str"
23431 #endif
23432 static const char *arch_regs[] = {
23433         "%unset",
23434         "%unneeded",
23435         "%eflags",
23436         "%al", "%bl", "%cl", "%dl", "%ah", "%bh", "%ch", "%dh",
23437         "%ax", "%bx", "%cx", "%dx", "%si", "%di", "%bp", "%sp",
23438         "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi", "%ebp", "%esp",
23439         "%edx:%eax",
23440         "%dx:%ax",
23441         "%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7",
23442         "%xmm0", "%xmm1", "%xmm2", "%xmm3", 
23443         "%xmm4", "%xmm5", "%xmm6", "%xmm7",
23444 };
23445 static const char *arch_reg_str(int reg)
23446 {
23447         if (!((reg >= REG_EFLAGS) && (reg <= REG_XMM7))) {
23448                 reg = 0;
23449         }
23450         return arch_regs[reg];
23451 }
23452
23453 static const char *reg(struct compile_state *state, struct triple *triple,
23454         int classes)
23455 {
23456         int reg;
23457         reg = check_reg(state, triple, classes);
23458         return arch_reg_str(reg);
23459 }
23460
23461 static int arch_reg_size(int reg)
23462 {
23463         int size;
23464         size = 0;
23465         if (reg == REG_EFLAGS) {
23466                 size = 32;
23467         }
23468         else if ((reg >= REG_AL) && (reg <= REG_DH)) {
23469                 size = 8;
23470         }
23471         else if ((reg >= REG_AX) && (reg <= REG_SP)) {
23472                 size = 16;
23473         }
23474         else if ((reg >= REG_EAX) && (reg <= REG_ESP)) {
23475                 size = 32;
23476         }
23477         else if (reg == REG_EDXEAX) {
23478                 size = 64;
23479         }
23480         else if (reg == REG_DXAX) {
23481                 size = 32;
23482         }
23483         else if ((reg >= REG_MMX0) && (reg <= REG_MMX7)) {
23484                 size = 64;
23485         }
23486         else if ((reg >= REG_XMM0) && (reg <= REG_XMM7)) {
23487                 size = 128;
23488         }
23489         return size;
23490 }
23491
23492 static int reg_size(struct compile_state *state, struct triple *ins)
23493 {
23494         int reg;
23495         reg = ID_REG(ins->id);
23496         if (reg == REG_UNSET) {
23497                 internal_error(state, ins, "register not set");
23498         }
23499         return arch_reg_size(reg);
23500 }
23501         
23502
23503
23504 const char *type_suffix(struct compile_state *state, struct type *type)
23505 {
23506         const char *suffix;
23507         switch(size_of(state, type)) {
23508         case SIZEOF_I8:  suffix = "b"; break;
23509         case SIZEOF_I16: suffix = "w"; break;
23510         case SIZEOF_I32: suffix = "l"; break;
23511         default:
23512                 internal_error(state, 0, "unknown suffix");
23513                 suffix = 0;
23514                 break;
23515         }
23516         return suffix;
23517 }
23518
23519 static void print_const_val(
23520         struct compile_state *state, struct triple *ins, FILE *fp)
23521 {
23522         switch(ins->op) {
23523         case OP_INTCONST:
23524                 fprintf(fp, " $%ld ", 
23525                         (long)(ins->u.cval));
23526                 break;
23527         case OP_ADDRCONST:
23528                 if ((MISC(ins, 0)->op != OP_SDECL) &&
23529                         (MISC(ins, 0)->op != OP_LABEL))
23530                 {
23531                         internal_error(state, ins, "bad base for addrconst");
23532                 }
23533                 if (MISC(ins, 0)->u.cval <= 0) {
23534                         internal_error(state, ins, "unlabeled constant");
23535                 }
23536                 fprintf(fp, " $L%s%lu+%lu ",
23537                         state->compiler->label_prefix, 
23538                         (unsigned long)(MISC(ins, 0)->u.cval),
23539                         (unsigned long)(ins->u.cval));
23540                 break;
23541         default:
23542                 internal_error(state, ins, "unknown constant type");
23543                 break;
23544         }
23545 }
23546
23547 static void print_const(struct compile_state *state,
23548         struct triple *ins, FILE *fp)
23549 {
23550         switch(ins->op) {
23551         case OP_INTCONST:
23552                 switch(ins->type->type & TYPE_MASK) {
23553                 case TYPE_CHAR:
23554                 case TYPE_UCHAR:
23555                         fprintf(fp, ".byte 0x%02lx\n", 
23556                                 (unsigned long)(ins->u.cval));
23557                         break;
23558                 case TYPE_SHORT:
23559                 case TYPE_USHORT:
23560                         fprintf(fp, ".short 0x%04lx\n", 
23561                                 (unsigned long)(ins->u.cval));
23562                         break;
23563                 case TYPE_INT:
23564                 case TYPE_UINT:
23565                 case TYPE_LONG:
23566                 case TYPE_ULONG:
23567                 case TYPE_POINTER:
23568                         fprintf(fp, ".int %lu\n", 
23569                                 (unsigned long)(ins->u.cval));
23570                         break;
23571                 default:
23572                         fprintf(state->errout, "type: ");
23573                         name_of(state->errout, ins->type);
23574                         fprintf(state->errout, "\n");
23575                         internal_error(state, ins, "Unknown constant type. Val: %lu",
23576                                 (unsigned long)(ins->u.cval));
23577                 }
23578                 
23579                 break;
23580         case OP_ADDRCONST:
23581                 if ((MISC(ins, 0)->op != OP_SDECL) &&
23582                         (MISC(ins, 0)->op != OP_LABEL)) {
23583                         internal_error(state, ins, "bad base for addrconst");
23584                 }
23585                 if (MISC(ins, 0)->u.cval <= 0) {
23586                         internal_error(state, ins, "unlabeled constant");
23587                 }
23588                 fprintf(fp, ".int L%s%lu+%lu\n",
23589                         state->compiler->label_prefix,
23590                         (unsigned long)(MISC(ins, 0)->u.cval),
23591                         (unsigned long)(ins->u.cval));
23592                 break;
23593         case OP_BLOBCONST:
23594         {
23595                 unsigned char *blob;
23596                 size_t size, i;
23597                 size = size_of_in_bytes(state, ins->type);
23598                 blob = ins->u.blob;
23599                 for(i = 0; i < size; i++) {
23600                         fprintf(fp, ".byte 0x%02x\n",
23601                                 blob[i]);
23602                 }
23603                 break;
23604         }
23605         default:
23606                 internal_error(state, ins, "Unknown constant type");
23607                 break;
23608         }
23609 }
23610
23611 #define TEXT_SECTION ".rom.text"
23612 #define DATA_SECTION ".rom.data"
23613
23614 static long get_const_pool_ref(
23615         struct compile_state *state, struct triple *ins, size_t size, FILE *fp)
23616 {
23617         size_t fill_bytes;
23618         long ref;
23619         ref = next_label(state);
23620         fprintf(fp, ".section \"" DATA_SECTION "\"\n");
23621         fprintf(fp, ".balign %d\n", align_of_in_bytes(state, ins->type));
23622         fprintf(fp, "L%s%lu:\n", state->compiler->label_prefix, ref);
23623         print_const(state, ins, fp);
23624         fill_bytes = bits_to_bytes(size - size_of(state, ins->type));
23625         if (fill_bytes) {
23626                 fprintf(fp, ".fill %d, 1, 0\n", fill_bytes);
23627         }
23628         fprintf(fp, ".section \"" TEXT_SECTION "\"\n");
23629         return ref;
23630 }
23631
23632 static long get_mask_pool_ref(
23633         struct compile_state *state, struct triple *ins, unsigned long mask, FILE *fp)
23634 {
23635         long ref;
23636         if (mask == 0xff) {
23637                 ref = 1;
23638         }
23639         else if (mask == 0xffff) {
23640                 ref = 2;
23641         }
23642         else {
23643                 ref = 0;
23644                 internal_error(state, ins, "unhandled mask value");
23645         }
23646         return ref;
23647 }
23648
23649 static void print_binary_op(struct compile_state *state,
23650         const char *op, struct triple *ins, FILE *fp) 
23651 {
23652         unsigned mask;
23653         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO;
23654         if (ID_REG(RHS(ins, 0)->id) != ID_REG(ins->id)) {
23655                 internal_error(state, ins, "invalid register assignment");
23656         }
23657         if (is_const(RHS(ins, 1))) {
23658                 fprintf(fp, "\t%s ", op);
23659                 print_const_val(state, RHS(ins, 1), fp);
23660                 fprintf(fp, ", %s\n",
23661                         reg(state, RHS(ins, 0), mask));
23662         }
23663         else {
23664                 unsigned lmask, rmask;
23665                 int lreg, rreg;
23666                 lreg = check_reg(state, RHS(ins, 0), mask);
23667                 rreg = check_reg(state, RHS(ins, 1), mask);
23668                 lmask = arch_reg_regcm(state, lreg);
23669                 rmask = arch_reg_regcm(state, rreg);
23670                 mask = lmask & rmask;
23671                 fprintf(fp, "\t%s %s, %s\n",
23672                         op,
23673                         reg(state, RHS(ins, 1), mask),
23674                         reg(state, RHS(ins, 0), mask));
23675         }
23676 }
23677 static void print_unary_op(struct compile_state *state, 
23678         const char *op, struct triple *ins, FILE *fp)
23679 {
23680         unsigned mask;
23681         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO;
23682         fprintf(fp, "\t%s %s\n",
23683                 op,
23684                 reg(state, RHS(ins, 0), mask));
23685 }
23686
23687 static void print_op_shift(struct compile_state *state,
23688         const char *op, struct triple *ins, FILE *fp)
23689 {
23690         unsigned mask;
23691         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO;
23692         if (ID_REG(RHS(ins, 0)->id) != ID_REG(ins->id)) {
23693                 internal_error(state, ins, "invalid register assignment");
23694         }
23695         if (is_const(RHS(ins, 1))) {
23696                 fprintf(fp, "\t%s ", op);
23697                 print_const_val(state, RHS(ins, 1), fp);
23698                 fprintf(fp, ", %s\n",
23699                         reg(state, RHS(ins, 0), mask));
23700         }
23701         else {
23702                 fprintf(fp, "\t%s %s, %s\n",
23703                         op,
23704                         reg(state, RHS(ins, 1), REGCM_GPR8_LO),
23705                         reg(state, RHS(ins, 0), mask));
23706         }
23707 }
23708
23709 static void print_op_in(struct compile_state *state, struct triple *ins, FILE *fp)
23710 {
23711         const char *op;
23712         int mask;
23713         int dreg;
23714         mask = 0;
23715         switch(ins->op) {
23716         case OP_INB: op = "inb", mask = REGCM_GPR8_LO; break;
23717         case OP_INW: op = "inw", mask = REGCM_GPR16; break;
23718         case OP_INL: op = "inl", mask = REGCM_GPR32; break;
23719         default:
23720                 internal_error(state, ins, "not an in operation");
23721                 op = 0;
23722                 break;
23723         }
23724         dreg = check_reg(state, ins, mask);
23725         if (!reg_is_reg(state, dreg, REG_EAX)) {
23726                 internal_error(state, ins, "dst != %%eax");
23727         }
23728         if (is_const(RHS(ins, 0))) {
23729                 fprintf(fp, "\t%s ", op);
23730                 print_const_val(state, RHS(ins, 0), fp);
23731                 fprintf(fp, ", %s\n",
23732                         reg(state, ins, mask));
23733         }
23734         else {
23735                 int addr_reg;
23736                 addr_reg = check_reg(state, RHS(ins, 0), REGCM_GPR16);
23737                 if (!reg_is_reg(state, addr_reg, REG_DX)) {
23738                         internal_error(state, ins, "src != %%dx");
23739                 }
23740                 fprintf(fp, "\t%s %s, %s\n",
23741                         op, 
23742                         reg(state, RHS(ins, 0), REGCM_GPR16),
23743                         reg(state, ins, mask));
23744         }
23745 }
23746
23747 static void print_op_out(struct compile_state *state, struct triple *ins, FILE *fp)
23748 {
23749         const char *op;
23750         int mask;
23751         int lreg;
23752         mask = 0;
23753         switch(ins->op) {
23754         case OP_OUTB: op = "outb", mask = REGCM_GPR8_LO; break;
23755         case OP_OUTW: op = "outw", mask = REGCM_GPR16; break;
23756         case OP_OUTL: op = "outl", mask = REGCM_GPR32; break;
23757         default:
23758                 internal_error(state, ins, "not an out operation");
23759                 op = 0;
23760                 break;
23761         }
23762         lreg = check_reg(state, RHS(ins, 0), mask);
23763         if (!reg_is_reg(state, lreg, REG_EAX)) {
23764                 internal_error(state, ins, "src != %%eax");
23765         }
23766         if (is_const(RHS(ins, 1))) {
23767                 fprintf(fp, "\t%s %s,", 
23768                         op, reg(state, RHS(ins, 0), mask));
23769                 print_const_val(state, RHS(ins, 1), fp);
23770                 fprintf(fp, "\n");
23771         }
23772         else {
23773                 int addr_reg;
23774                 addr_reg = check_reg(state, RHS(ins, 1), REGCM_GPR16);
23775                 if (!reg_is_reg(state, addr_reg, REG_DX)) {
23776                         internal_error(state, ins, "dst != %%dx");
23777                 }
23778                 fprintf(fp, "\t%s %s, %s\n",
23779                         op, 
23780                         reg(state, RHS(ins, 0), mask),
23781                         reg(state, RHS(ins, 1), REGCM_GPR16));
23782         }
23783 }
23784
23785 static void print_op_move(struct compile_state *state,
23786         struct triple *ins, FILE *fp)
23787 {
23788         /* op_move is complex because there are many types
23789          * of registers we can move between.
23790          * Because OP_COPY will be introduced in arbitrary locations
23791          * OP_COPY must not affect flags.
23792          * OP_CONVERT can change the flags and it is the only operation
23793          * where it is expected the types in the registers can change.
23794          */
23795         int omit_copy = 1; /* Is it o.k. to omit a noop copy? */
23796         struct triple *dst, *src;
23797         if (state->arch->features & X86_NOOP_COPY) {
23798                 omit_copy = 0;
23799         }
23800         if ((ins->op == OP_COPY) || (ins->op == OP_CONVERT)) {
23801                 src = RHS(ins, 0);
23802                 dst = ins;
23803         }
23804         else {
23805                 internal_error(state, ins, "unknown move operation");
23806                 src = dst = 0;
23807         }
23808         if (reg_size(state, dst) < size_of(state, dst->type)) {
23809                 internal_error(state, ins, "Invalid destination register");
23810         }
23811         if (!equiv_types(src->type, dst->type) && (dst->op == OP_COPY)) {
23812                 fprintf(state->errout, "src type: ");
23813                 name_of(state->errout, src->type);
23814                 fprintf(state->errout, "\n");
23815                 fprintf(state->errout, "dst type: ");
23816                 name_of(state->errout, dst->type);
23817                 fprintf(state->errout, "\n");
23818                 internal_error(state, ins, "Type mismatch for OP_COPY");
23819         }
23820
23821         if (!is_const(src)) {
23822                 int src_reg, dst_reg;
23823                 int src_regcm, dst_regcm;
23824                 src_reg   = ID_REG(src->id);
23825                 dst_reg   = ID_REG(dst->id);
23826                 src_regcm = arch_reg_regcm(state, src_reg);
23827                 dst_regcm = arch_reg_regcm(state, dst_reg);
23828                 /* If the class is the same just move the register */
23829                 if (src_regcm & dst_regcm & 
23830                         (REGCM_GPR8_LO | REGCM_GPR16 | REGCM_GPR32)) {
23831                         if ((src_reg != dst_reg) || !omit_copy) {
23832                                 fprintf(fp, "\tmov %s, %s\n",
23833                                         reg(state, src, src_regcm),
23834                                         reg(state, dst, dst_regcm));
23835                         }
23836                 }
23837                 /* Move 32bit to 16bit */
23838                 else if ((src_regcm & REGCM_GPR32) &&
23839                         (dst_regcm & REGCM_GPR16)) {
23840                         src_reg = (src_reg - REGC_GPR32_FIRST) + REGC_GPR16_FIRST;
23841                         if ((src_reg != dst_reg) || !omit_copy) {
23842                                 fprintf(fp, "\tmovw %s, %s\n",
23843                                         arch_reg_str(src_reg), 
23844                                         arch_reg_str(dst_reg));
23845                         }
23846                 }
23847                 /* Move from 32bit gprs to 16bit gprs */
23848                 else if ((src_regcm & REGCM_GPR32) &&
23849                         (dst_regcm & REGCM_GPR16)) {
23850                         dst_reg = (dst_reg - REGC_GPR16_FIRST) + REGC_GPR32_FIRST;
23851                         if ((src_reg != dst_reg) || !omit_copy) {
23852                                 fprintf(fp, "\tmov %s, %s\n",
23853                                         arch_reg_str(src_reg),
23854                                         arch_reg_str(dst_reg));
23855                         }
23856                 }
23857                 /* Move 32bit to 8bit */
23858                 else if ((src_regcm & REGCM_GPR32_8) &&
23859                         (dst_regcm & REGCM_GPR8_LO))
23860                 {
23861                         src_reg = (src_reg - REGC_GPR32_8_FIRST) + REGC_GPR8_FIRST;
23862                         if ((src_reg != dst_reg) || !omit_copy) {
23863                                 fprintf(fp, "\tmovb %s, %s\n",
23864                                         arch_reg_str(src_reg),
23865                                         arch_reg_str(dst_reg));
23866                         }
23867                 }
23868                 /* Move 16bit to 8bit */
23869                 else if ((src_regcm & REGCM_GPR16_8) &&
23870                         (dst_regcm & REGCM_GPR8_LO))
23871                 {
23872                         src_reg = (src_reg - REGC_GPR16_8_FIRST) + REGC_GPR8_FIRST;
23873                         if ((src_reg != dst_reg) || !omit_copy) {
23874                                 fprintf(fp, "\tmovb %s, %s\n",
23875                                         arch_reg_str(src_reg),
23876                                         arch_reg_str(dst_reg));
23877                         }
23878                 }
23879                 /* Move 8/16bit to 16/32bit */
23880                 else if ((src_regcm & (REGCM_GPR8_LO | REGCM_GPR16)) && 
23881                         (dst_regcm & (REGCM_GPR16 | REGCM_GPR32))) {
23882                         const char *op;
23883                         op = is_signed(src->type)? "movsx": "movzx";
23884                         fprintf(fp, "\t%s %s, %s\n",
23885                                 op,
23886                                 reg(state, src, src_regcm),
23887                                 reg(state, dst, dst_regcm));
23888                 }
23889                 /* Move between sse registers */
23890                 else if ((src_regcm & dst_regcm & REGCM_XMM)) {
23891                         if ((src_reg != dst_reg) || !omit_copy) {
23892                                 fprintf(fp, "\tmovdqa %s, %s\n",
23893                                         reg(state, src, src_regcm),
23894                                         reg(state, dst, dst_regcm));
23895                         }
23896                 }
23897                 /* Move between mmx registers */
23898                 else if ((src_regcm & dst_regcm & REGCM_MMX)) {
23899                         if ((src_reg != dst_reg) || !omit_copy) {
23900                                 fprintf(fp, "\tmovq %s, %s\n",
23901                                         reg(state, src, src_regcm),
23902                                         reg(state, dst, dst_regcm));
23903                         }
23904                 }
23905                 /* Move from sse to mmx registers */
23906                 else if ((src_regcm & REGCM_XMM) && (dst_regcm & REGCM_MMX)) {
23907                         fprintf(fp, "\tmovdq2q %s, %s\n",
23908                                 reg(state, src, src_regcm),
23909                                 reg(state, dst, dst_regcm));
23910                 }
23911                 /* Move from mmx to sse registers */
23912                 else if ((src_regcm & REGCM_MMX) && (dst_regcm & REGCM_XMM)) {
23913                         fprintf(fp, "\tmovq2dq %s, %s\n",
23914                                 reg(state, src, src_regcm),
23915                                 reg(state, dst, dst_regcm));
23916                 }
23917                 /* Move between 32bit gprs & mmx/sse registers */
23918                 else if ((src_regcm & (REGCM_GPR32 | REGCM_MMX | REGCM_XMM)) &&
23919                         (dst_regcm & (REGCM_GPR32 | REGCM_MMX | REGCM_XMM))) {
23920                         fprintf(fp, "\tmovd %s, %s\n",
23921                                 reg(state, src, src_regcm),
23922                                 reg(state, dst, dst_regcm));
23923                 }
23924                 /* Move from 16bit gprs &  mmx/sse registers */
23925                 else if ((src_regcm & REGCM_GPR16) &&
23926                         (dst_regcm & (REGCM_MMX | REGCM_XMM))) {
23927                         const char *op;
23928                         int mid_reg;
23929                         op = is_signed(src->type)? "movsx":"movzx";
23930                         mid_reg = (src_reg - REGC_GPR16_FIRST) + REGC_GPR32_FIRST;
23931                         fprintf(fp, "\t%s %s, %s\n\tmovd %s, %s\n",
23932                                 op,
23933                                 arch_reg_str(src_reg),
23934                                 arch_reg_str(mid_reg),
23935                                 arch_reg_str(mid_reg),
23936                                 arch_reg_str(dst_reg));
23937                 }
23938                 /* Move from mmx/sse registers to 16bit gprs */
23939                 else if ((src_regcm & (REGCM_MMX | REGCM_XMM)) &&
23940                         (dst_regcm & REGCM_GPR16)) {
23941                         dst_reg = (dst_reg - REGC_GPR16_FIRST) + REGC_GPR32_FIRST;
23942                         fprintf(fp, "\tmovd %s, %s\n",
23943                                 arch_reg_str(src_reg),
23944                                 arch_reg_str(dst_reg));
23945                 }
23946                 /* Move from gpr to 64bit dividend */
23947                 else if ((src_regcm & (REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO))  &&
23948                         (dst_regcm & REGCM_DIVIDEND64)) {
23949                         const char *extend;
23950                         extend = is_signed(src->type)? "cltd":"movl $0, %edx";
23951                         fprintf(fp, "\tmov %s, %%eax\n\t%s\n",
23952                                 arch_reg_str(src_reg), 
23953                                 extend);
23954                 }
23955                 /* Move from 64bit gpr to gpr */
23956                 else if ((src_regcm & REGCM_DIVIDEND64) &&
23957                         (dst_regcm & (REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO))) {
23958                         if (dst_regcm & REGCM_GPR32) {
23959                                 src_reg = REG_EAX;
23960                         } 
23961                         else if (dst_regcm & REGCM_GPR16) {
23962                                 src_reg = REG_AX;
23963                         }
23964                         else if (dst_regcm & REGCM_GPR8_LO) {
23965                                 src_reg = REG_AL;
23966                         }
23967                         fprintf(fp, "\tmov %s, %s\n",
23968                                 arch_reg_str(src_reg),
23969                                 arch_reg_str(dst_reg));
23970                 }
23971                 /* Move from mmx/sse registers to 64bit gpr */
23972                 else if ((src_regcm & (REGCM_MMX | REGCM_XMM)) &&
23973                         (dst_regcm & REGCM_DIVIDEND64)) {
23974                         const char *extend;
23975                         extend = is_signed(src->type)? "cltd": "movl $0, %edx";
23976                         fprintf(fp, "\tmovd %s, %%eax\n\t%s\n",
23977                                 arch_reg_str(src_reg),
23978                                 extend);
23979                 }
23980                 /* Move from 64bit gpr to mmx/sse register */
23981                 else if ((src_regcm & REGCM_DIVIDEND64) &&
23982                         (dst_regcm & (REGCM_XMM | REGCM_MMX))) {
23983                         fprintf(fp, "\tmovd %%eax, %s\n",
23984                                 arch_reg_str(dst_reg));
23985                 }
23986 #if X86_4_8BIT_GPRS
23987                 /* Move from 8bit gprs to  mmx/sse registers */
23988                 else if ((src_regcm & REGCM_GPR8_LO) && (src_reg <= REG_DL) &&
23989                         (dst_regcm & (REGCM_MMX | REGCM_XMM))) {
23990                         const char *op;
23991                         int mid_reg;
23992                         op = is_signed(src->type)? "movsx":"movzx";
23993                         mid_reg = (src_reg - REGC_GPR8_FIRST) + REGC_GPR32_FIRST;
23994                         fprintf(fp, "\t%s %s, %s\n\tmovd %s, %s\n",
23995                                 op,
23996                                 reg(state, src, src_regcm),
23997                                 arch_reg_str(mid_reg),
23998                                 arch_reg_str(mid_reg),
23999                                 reg(state, dst, dst_regcm));
24000                 }
24001                 /* Move from mmx/sse registers and 8bit gprs */
24002                 else if ((src_regcm & (REGCM_MMX | REGCM_XMM)) &&
24003                         (dst_regcm & REGCM_GPR8_LO) && (dst_reg <= REG_DL)) {
24004                         int mid_reg;
24005                         mid_reg = (dst_reg - REGC_GPR8_FIRST) + REGC_GPR32_FIRST;
24006                         fprintf(fp, "\tmovd %s, %s\n",
24007                                 reg(state, src, src_regcm),
24008                                 arch_reg_str(mid_reg));
24009                 }
24010                 /* Move from 32bit gprs to 8bit gprs */
24011                 else if ((src_regcm & REGCM_GPR32) &&
24012                         (dst_regcm & REGCM_GPR8_LO)) {
24013                         dst_reg = (dst_reg - REGC_GPR8_FIRST) + REGC_GPR32_FIRST;
24014                         if ((src_reg != dst_reg) || !omit_copy) {
24015                                 fprintf(fp, "\tmov %s, %s\n",
24016                                         arch_reg_str(src_reg),
24017                                         arch_reg_str(dst_reg));
24018                         }
24019                 }
24020                 /* Move from 16bit gprs to 8bit gprs */
24021                 else if ((src_regcm & REGCM_GPR16) &&
24022                         (dst_regcm & REGCM_GPR8_LO)) {
24023                         dst_reg = (dst_reg - REGC_GPR8_FIRST) + REGC_GPR16_FIRST;
24024                         if ((src_reg != dst_reg) || !omit_copy) {
24025                                 fprintf(fp, "\tmov %s, %s\n",
24026                                         arch_reg_str(src_reg),
24027                                         arch_reg_str(dst_reg));
24028                         }
24029                 }
24030 #endif /* X86_4_8BIT_GPRS */
24031                 /* Move from %eax:%edx to %eax:%edx */
24032                 else if ((src_regcm & REGCM_DIVIDEND64) &&
24033                         (dst_regcm & REGCM_DIVIDEND64) &&
24034                         (src_reg == dst_reg)) {
24035                         if (!omit_copy) {
24036                                 fprintf(fp, "\t/*mov %s, %s*/\n",
24037                                         arch_reg_str(src_reg),
24038                                         arch_reg_str(dst_reg));
24039                         }
24040                 }
24041                 else {
24042                         if ((src_regcm & ~REGCM_FLAGS) == 0) {
24043                                 internal_error(state, ins, "attempt to copy from %%eflags!");
24044                         }
24045                         internal_error(state, ins, "unknown copy type");
24046                 }
24047         }
24048         else {
24049                 size_t dst_size;
24050                 int dst_reg;
24051                 int dst_regcm;
24052                 dst_size = size_of(state, dst->type);
24053                 dst_reg = ID_REG(dst->id);
24054                 dst_regcm = arch_reg_regcm(state, dst_reg);
24055                 if (dst_regcm & (REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO)) {
24056                         fprintf(fp, "\tmov ");
24057                         print_const_val(state, src, fp);
24058                         fprintf(fp, ", %s\n",
24059                                 reg(state, dst, REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO));
24060                 }
24061                 else if (dst_regcm & REGCM_DIVIDEND64) {
24062                         if (dst_size > SIZEOF_I32) {
24063                                 internal_error(state, ins, "%dbit constant...", dst_size);
24064                         }
24065                         fprintf(fp, "\tmov $0, %%edx\n");
24066                         fprintf(fp, "\tmov ");
24067                         print_const_val(state, src, fp);
24068                         fprintf(fp, ", %%eax\n");
24069                 }
24070                 else if (dst_regcm & REGCM_DIVIDEND32) {
24071                         if (dst_size > SIZEOF_I16) {
24072                                 internal_error(state, ins, "%dbit constant...", dst_size);
24073                         }
24074                         fprintf(fp, "\tmov $0, %%dx\n");
24075                         fprintf(fp, "\tmov ");
24076                         print_const_val(state, src, fp);
24077                         fprintf(fp, ", %%ax");
24078                 }
24079                 else if (dst_regcm & (REGCM_XMM | REGCM_MMX)) {
24080                         long ref;
24081                         if (dst_size > SIZEOF_I32) {
24082                                 internal_error(state, ins, "%d bit constant...", dst_size);
24083                         }
24084                         ref = get_const_pool_ref(state, src, SIZEOF_I32, fp);
24085                         fprintf(fp, "\tmovd L%s%lu, %s\n",
24086                                 state->compiler->label_prefix, ref,
24087                                 reg(state, dst, (REGCM_XMM | REGCM_MMX)));
24088                 }
24089                 else {
24090                         internal_error(state, ins, "unknown copy immediate type");
24091                 }
24092         }
24093         /* Leave now if this is not a type conversion */
24094         if (ins->op != OP_CONVERT) {
24095                 return;
24096         }
24097         /* Now make certain I have not logically overflowed the destination */
24098         if ((size_of(state, src->type) > size_of(state, dst->type)) &&
24099                 (size_of(state, dst->type) < reg_size(state, dst)))
24100         {
24101                 unsigned long mask;
24102                 int dst_reg;
24103                 int dst_regcm;
24104                 if (size_of(state, dst->type) >= 32) {
24105                         fprintf(state->errout, "dst type: ");
24106                         name_of(state->errout, dst->type);
24107                         fprintf(state->errout, "\n");
24108                         internal_error(state, dst, "unhandled dst type size");
24109                 }
24110                 mask = 1;
24111                 mask <<= size_of(state, dst->type);
24112                 mask -= 1;
24113
24114                 dst_reg = ID_REG(dst->id);
24115                 dst_regcm = arch_reg_regcm(state, dst_reg);
24116
24117                 if (dst_regcm & (REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO)) {
24118                         fprintf(fp, "\tand $0x%lx, %s\n",
24119                                 mask, reg(state, dst, REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO));
24120                 }
24121                 else if (dst_regcm & REGCM_MMX) {
24122                         long ref;
24123                         ref = get_mask_pool_ref(state, dst, mask, fp);
24124                         fprintf(fp, "\tpand L%s%lu, %s\n",
24125                                 state->compiler->label_prefix, ref,
24126                                 reg(state, dst, REGCM_MMX));
24127                 }
24128                 else if (dst_regcm & REGCM_XMM) {
24129                         long ref;
24130                         ref = get_mask_pool_ref(state, dst, mask, fp);
24131                         fprintf(fp, "\tpand L%s%lu, %s\n",
24132                                 state->compiler->label_prefix, ref,
24133                                 reg(state, dst, REGCM_XMM));
24134                 }
24135                 else {
24136                         fprintf(state->errout, "dst type: ");
24137                         name_of(state->errout, dst->type);
24138                         fprintf(state->errout, "\n");
24139                         fprintf(state->errout, "dst: %s\n", reg(state, dst, REGCM_ALL));
24140                         internal_error(state, dst, "failed to trunc value: mask %lx", mask);
24141                 }
24142         }
24143         /* Make certain I am properly sign extended */
24144         if ((size_of(state, src->type) < size_of(state, dst->type)) &&
24145                 (is_signed(src->type)))
24146         {
24147                 int bits, reg_bits, shift_bits;
24148                 int dst_reg;
24149                 int dst_regcm;
24150
24151                 bits = size_of(state, src->type);
24152                 reg_bits = reg_size(state, dst);
24153                 if (reg_bits > 32) {
24154                         reg_bits = 32;
24155                 }
24156                 shift_bits = reg_bits - size_of(state, src->type);
24157                 dst_reg = ID_REG(dst->id);
24158                 dst_regcm = arch_reg_regcm(state, dst_reg);
24159
24160                 if (shift_bits < 0) {
24161                         internal_error(state, dst, "negative shift?");
24162                 }
24163
24164                 if (dst_regcm & (REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO)) {
24165                         fprintf(fp, "\tshl $%d, %s\n", 
24166                                 shift_bits, 
24167                                 reg(state, dst, REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO));
24168                         fprintf(fp, "\tsar $%d, %s\n", 
24169                                 shift_bits, 
24170                                 reg(state, dst, REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO));
24171                 }
24172                 else if (dst_regcm & (REGCM_MMX | REGCM_XMM)) {
24173                         fprintf(fp, "\tpslld $%d, %s\n",
24174                                 shift_bits, 
24175                                 reg(state, dst, REGCM_MMX | REGCM_XMM));
24176                         fprintf(fp, "\tpsrad $%d, %s\n",
24177                                 shift_bits, 
24178                                 reg(state, dst, REGCM_MMX | REGCM_XMM));
24179                 }
24180                 else {
24181                         fprintf(state->errout, "dst type: ");
24182                         name_of(state->errout, dst->type);
24183                         fprintf(state->errout, "\n");
24184                         fprintf(state->errout, "dst: %s\n", reg(state, dst, REGCM_ALL));
24185                         internal_error(state, dst, "failed to signed extend value");
24186                 }
24187         }
24188 }
24189
24190 static void print_op_load(struct compile_state *state,
24191         struct triple *ins, FILE *fp)
24192 {
24193         struct triple *dst, *src;
24194         const char *op;
24195         dst = ins;
24196         src = RHS(ins, 0);
24197         if (is_const(src) || is_const(dst)) {
24198                 internal_error(state, ins, "unknown load operation");
24199         }
24200         switch(ins->type->type & TYPE_MASK) {
24201         case TYPE_CHAR:   op = "movsbl"; break;
24202         case TYPE_UCHAR:  op = "movzbl"; break;
24203         case TYPE_SHORT:  op = "movswl"; break;
24204         case TYPE_USHORT: op = "movzwl"; break;
24205         case TYPE_INT:    case TYPE_UINT:
24206         case TYPE_LONG:   case TYPE_ULONG:
24207         case TYPE_POINTER:
24208                 op = "movl"; 
24209                 break;
24210         default:
24211                 internal_error(state, ins, "unknown type in load");
24212                 op = "<invalid opcode>";
24213                 break;
24214         }
24215         fprintf(fp, "\t%s (%s), %s\n",
24216                 op, 
24217                 reg(state, src, REGCM_GPR32),
24218                 reg(state, dst, REGCM_GPR32));
24219 }
24220
24221
24222 static void print_op_store(struct compile_state *state,
24223         struct triple *ins, FILE *fp)
24224 {
24225         struct triple *dst, *src;
24226         dst = RHS(ins, 0);
24227         src = RHS(ins, 1);
24228         if (is_const(src) && (src->op == OP_INTCONST)) {
24229                 long_t value;
24230                 value = (long_t)(src->u.cval);
24231                 fprintf(fp, "\tmov%s $%ld, (%s)\n",
24232                         type_suffix(state, src->type),
24233                         (long)(value),
24234                         reg(state, dst, REGCM_GPR32));
24235         }
24236         else if (is_const(dst) && (dst->op == OP_INTCONST)) {
24237                 fprintf(fp, "\tmov%s %s, 0x%08lx\n",
24238                         type_suffix(state, src->type),
24239                         reg(state, src, REGCM_GPR8_LO | REGCM_GPR16 | REGCM_GPR32),
24240                         (unsigned long)(dst->u.cval));
24241         }
24242         else {
24243                 if (is_const(src) || is_const(dst)) {
24244                         internal_error(state, ins, "unknown store operation");
24245                 }
24246                 fprintf(fp, "\tmov%s %s, (%s)\n",
24247                         type_suffix(state, src->type),
24248                         reg(state, src, REGCM_GPR8_LO | REGCM_GPR16 | REGCM_GPR32),
24249                         reg(state, dst, REGCM_GPR32));
24250         }
24251         
24252         
24253 }
24254
24255 static void print_op_smul(struct compile_state *state,
24256         struct triple *ins, FILE *fp)
24257 {
24258         if (!is_const(RHS(ins, 1))) {
24259                 fprintf(fp, "\timul %s, %s\n",
24260                         reg(state, RHS(ins, 1), REGCM_GPR32),
24261                         reg(state, RHS(ins, 0), REGCM_GPR32));
24262         }
24263         else {
24264                 fprintf(fp, "\timul ");
24265                 print_const_val(state, RHS(ins, 1), fp);
24266                 fprintf(fp, ", %s\n", reg(state, RHS(ins, 0), REGCM_GPR32));
24267         }
24268 }
24269
24270 static void print_op_cmp(struct compile_state *state,
24271         struct triple *ins, FILE *fp)
24272 {
24273         unsigned mask;
24274         int dreg;
24275         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO;
24276         dreg = check_reg(state, ins, REGCM_FLAGS);
24277         if (!reg_is_reg(state, dreg, REG_EFLAGS)) {
24278                 internal_error(state, ins, "bad dest register for cmp");
24279         }
24280         if (is_const(RHS(ins, 1))) {
24281                 fprintf(fp, "\tcmp ");
24282                 print_const_val(state, RHS(ins, 1), fp);
24283                 fprintf(fp, ", %s\n", reg(state, RHS(ins, 0), mask));
24284         }
24285         else {
24286                 unsigned lmask, rmask;
24287                 int lreg, rreg;
24288                 lreg = check_reg(state, RHS(ins, 0), mask);
24289                 rreg = check_reg(state, RHS(ins, 1), mask);
24290                 lmask = arch_reg_regcm(state, lreg);
24291                 rmask = arch_reg_regcm(state, rreg);
24292                 mask = lmask & rmask;
24293                 fprintf(fp, "\tcmp %s, %s\n",
24294                         reg(state, RHS(ins, 1), mask),
24295                         reg(state, RHS(ins, 0), mask));
24296         }
24297 }
24298
24299 static void print_op_test(struct compile_state *state,
24300         struct triple *ins, FILE *fp)
24301 {
24302         unsigned mask;
24303         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO;
24304         fprintf(fp, "\ttest %s, %s\n",
24305                 reg(state, RHS(ins, 0), mask),
24306                 reg(state, RHS(ins, 0), mask));
24307 }
24308
24309 static void print_op_branch(struct compile_state *state,
24310         struct triple *branch, FILE *fp)
24311 {
24312         const char *bop = "j";
24313         if ((branch->op == OP_JMP) || (branch->op == OP_CALL)) {
24314                 if (branch->rhs != 0) {
24315                         internal_error(state, branch, "jmp with condition?");
24316                 }
24317                 bop = "jmp";
24318         }
24319         else {
24320                 struct triple *ptr;
24321                 if (branch->rhs != 1) {
24322                         internal_error(state, branch, "jmpcc without condition?");
24323                 }
24324                 check_reg(state, RHS(branch, 0), REGCM_FLAGS);
24325                 if ((RHS(branch, 0)->op != OP_CMP) &&
24326                         (RHS(branch, 0)->op != OP_TEST)) {
24327                         internal_error(state, branch, "bad branch test");
24328                 }
24329 #warning "FIXME I have observed instructions between the test and branch instructions"
24330                 ptr = RHS(branch, 0);
24331                 for(ptr = RHS(branch, 0)->next; ptr != branch; ptr = ptr->next) {
24332                         if (ptr->op != OP_COPY) {
24333                                 internal_error(state, branch, "branch does not follow test");
24334                         }
24335                 }
24336                 switch(branch->op) {
24337                 case OP_JMP_EQ:       bop = "jz";  break;
24338                 case OP_JMP_NOTEQ:    bop = "jnz"; break;
24339                 case OP_JMP_SLESS:    bop = "jl";  break;
24340                 case OP_JMP_ULESS:    bop = "jb";  break;
24341                 case OP_JMP_SMORE:    bop = "jg";  break;
24342                 case OP_JMP_UMORE:    bop = "ja";  break;
24343                 case OP_JMP_SLESSEQ:  bop = "jle"; break;
24344                 case OP_JMP_ULESSEQ:  bop = "jbe"; break;
24345                 case OP_JMP_SMOREEQ:  bop = "jge"; break;
24346                 case OP_JMP_UMOREEQ:  bop = "jae"; break;
24347                 default:
24348                         internal_error(state, branch, "Invalid branch op");
24349                         break;
24350                 }
24351                 
24352         }
24353 #if 1
24354         if (branch->op == OP_CALL) {
24355                 fprintf(fp, "\t/* call */\n");
24356         }
24357 #endif
24358         fprintf(fp, "\t%s L%s%lu\n",
24359                 bop, 
24360                 state->compiler->label_prefix,
24361                 (unsigned long)(TARG(branch, 0)->u.cval));
24362 }
24363
24364 static void print_op_ret(struct compile_state *state,
24365         struct triple *branch, FILE *fp)
24366 {
24367         fprintf(fp, "\tjmp *%s\n",
24368                 reg(state, RHS(branch, 0), REGCM_GPR32));
24369 }
24370
24371 static void print_op_set(struct compile_state *state,
24372         struct triple *set, FILE *fp)
24373 {
24374         const char *sop = "set";
24375         if (set->rhs != 1) {
24376                 internal_error(state, set, "setcc without condition?");
24377         }
24378         check_reg(state, RHS(set, 0), REGCM_FLAGS);
24379         if ((RHS(set, 0)->op != OP_CMP) &&
24380                 (RHS(set, 0)->op != OP_TEST)) {
24381                 internal_error(state, set, "bad set test");
24382         }
24383         if (RHS(set, 0)->next != set) {
24384                 internal_error(state, set, "set does not follow test");
24385         }
24386         switch(set->op) {
24387         case OP_SET_EQ:       sop = "setz";  break;
24388         case OP_SET_NOTEQ:    sop = "setnz"; break;
24389         case OP_SET_SLESS:    sop = "setl";  break;
24390         case OP_SET_ULESS:    sop = "setb";  break;
24391         case OP_SET_SMORE:    sop = "setg";  break;
24392         case OP_SET_UMORE:    sop = "seta";  break;
24393         case OP_SET_SLESSEQ:  sop = "setle"; break;
24394         case OP_SET_ULESSEQ:  sop = "setbe"; break;
24395         case OP_SET_SMOREEQ:  sop = "setge"; break;
24396         case OP_SET_UMOREEQ:  sop = "setae"; break;
24397         default:
24398                 internal_error(state, set, "Invalid set op");
24399                 break;
24400         }
24401         fprintf(fp, "\t%s %s\n",
24402                 sop, reg(state, set, REGCM_GPR8_LO));
24403 }
24404
24405 static void print_op_bit_scan(struct compile_state *state, 
24406         struct triple *ins, FILE *fp) 
24407 {
24408         const char *op;
24409         switch(ins->op) {
24410         case OP_BSF: op = "bsf"; break;
24411         case OP_BSR: op = "bsr"; break;
24412         default: 
24413                 internal_error(state, ins, "unknown bit scan");
24414                 op = 0;
24415                 break;
24416         }
24417         fprintf(fp, 
24418                 "\t%s %s, %s\n"
24419                 "\tjnz 1f\n"
24420                 "\tmovl $-1, %s\n"
24421                 "1:\n",
24422                 op,
24423                 reg(state, RHS(ins, 0), REGCM_GPR32),
24424                 reg(state, ins, REGCM_GPR32),
24425                 reg(state, ins, REGCM_GPR32));
24426 }
24427
24428
24429 static void print_sdecl(struct compile_state *state,
24430         struct triple *ins, FILE *fp)
24431 {
24432         fprintf(fp, ".section \"" DATA_SECTION "\"\n");
24433         fprintf(fp, ".balign %d\n", align_of_in_bytes(state, ins->type));
24434         fprintf(fp, "L%s%lu:\n", 
24435                 state->compiler->label_prefix, (unsigned long)(ins->u.cval));
24436         print_const(state, MISC(ins, 0), fp);
24437         fprintf(fp, ".section \"" TEXT_SECTION "\"\n");
24438                 
24439 }
24440
24441 static void print_instruction(struct compile_state *state,
24442         struct triple *ins, FILE *fp)
24443 {
24444         /* Assumption: after I have exted the register allocator
24445          * everything is in a valid register. 
24446          */
24447         switch(ins->op) {
24448         case OP_ASM:
24449                 print_op_asm(state, ins, fp);
24450                 break;
24451         case OP_ADD:    print_binary_op(state, "add", ins, fp); break;
24452         case OP_SUB:    print_binary_op(state, "sub", ins, fp); break;
24453         case OP_AND:    print_binary_op(state, "and", ins, fp); break;
24454         case OP_XOR:    print_binary_op(state, "xor", ins, fp); break;
24455         case OP_OR:     print_binary_op(state, "or",  ins, fp); break;
24456         case OP_SL:     print_op_shift(state, "shl", ins, fp); break;
24457         case OP_USR:    print_op_shift(state, "shr", ins, fp); break;
24458         case OP_SSR:    print_op_shift(state, "sar", ins, fp); break;
24459         case OP_POS:    break;
24460         case OP_NEG:    print_unary_op(state, "neg", ins, fp); break;
24461         case OP_INVERT: print_unary_op(state, "not", ins, fp); break;
24462         case OP_NOOP:
24463         case OP_INTCONST:
24464         case OP_ADDRCONST:
24465         case OP_BLOBCONST:
24466                 /* Don't generate anything here for constants */
24467         case OP_PHI:
24468                 /* Don't generate anything for variable declarations. */
24469                 break;
24470         case OP_UNKNOWNVAL:
24471                 fprintf(fp, " /* unknown %s */\n",
24472                         reg(state, ins, REGCM_ALL));
24473                 break;
24474         case OP_SDECL:
24475                 print_sdecl(state, ins, fp);
24476                 break;
24477         case OP_COPY:   
24478         case OP_CONVERT:
24479                 print_op_move(state, ins, fp);
24480                 break;
24481         case OP_LOAD:
24482                 print_op_load(state, ins, fp);
24483                 break;
24484         case OP_STORE:
24485                 print_op_store(state, ins, fp);
24486                 break;
24487         case OP_SMUL:
24488                 print_op_smul(state, ins, fp);
24489                 break;
24490         case OP_CMP:    print_op_cmp(state, ins, fp); break;
24491         case OP_TEST:   print_op_test(state, ins, fp); break;
24492         case OP_JMP:
24493         case OP_JMP_EQ:      case OP_JMP_NOTEQ:
24494         case OP_JMP_SLESS:   case OP_JMP_ULESS:
24495         case OP_JMP_SMORE:   case OP_JMP_UMORE:
24496         case OP_JMP_SLESSEQ: case OP_JMP_ULESSEQ:
24497         case OP_JMP_SMOREEQ: case OP_JMP_UMOREEQ:
24498         case OP_CALL:
24499                 print_op_branch(state, ins, fp);
24500                 break;
24501         case OP_RET:
24502                 print_op_ret(state, ins, fp);
24503                 break;
24504         case OP_SET_EQ:      case OP_SET_NOTEQ:
24505         case OP_SET_SLESS:   case OP_SET_ULESS:
24506         case OP_SET_SMORE:   case OP_SET_UMORE:
24507         case OP_SET_SLESSEQ: case OP_SET_ULESSEQ:
24508         case OP_SET_SMOREEQ: case OP_SET_UMOREEQ:
24509                 print_op_set(state, ins, fp);
24510                 break;
24511         case OP_INB:  case OP_INW:  case OP_INL:
24512                 print_op_in(state, ins, fp); 
24513                 break;
24514         case OP_OUTB: case OP_OUTW: case OP_OUTL:
24515                 print_op_out(state, ins, fp); 
24516                 break;
24517         case OP_BSF:
24518         case OP_BSR:
24519                 print_op_bit_scan(state, ins, fp);
24520                 break;
24521         case OP_RDMSR:
24522                 after_lhs(state, ins);
24523                 fprintf(fp, "\trdmsr\n");
24524                 break;
24525         case OP_WRMSR:
24526                 fprintf(fp, "\twrmsr\n");
24527                 break;
24528         case OP_HLT:
24529                 fprintf(fp, "\thlt\n");
24530                 break;
24531         case OP_SDIVT:
24532                 fprintf(fp, "\tidiv %s\n", reg(state, RHS(ins, 1), REGCM_GPR32));
24533                 break;
24534         case OP_UDIVT:
24535                 fprintf(fp, "\tdiv %s\n", reg(state, RHS(ins, 1), REGCM_GPR32));
24536                 break;
24537         case OP_UMUL:
24538                 fprintf(fp, "\tmul %s\n", reg(state, RHS(ins, 1), REGCM_GPR32));
24539                 break;
24540         case OP_LABEL:
24541                 if (!ins->use) {
24542                         return;
24543                 }
24544                 fprintf(fp, "L%s%lu:\n", 
24545                         state->compiler->label_prefix, (unsigned long)(ins->u.cval));
24546                 break;
24547         case OP_ADECL:
24548                 /* Ignore adecls with no registers error otherwise */
24549                 if (!noop_adecl(ins)) {
24550                         internal_error(state, ins, "adecl remains?");
24551                 }
24552                 break;
24553                 /* Ignore OP_PIECE */
24554         case OP_PIECE:
24555                 break;
24556                 /* Operations that should never get here */
24557         case OP_SDIV: case OP_UDIV:
24558         case OP_SMOD: case OP_UMOD:
24559         case OP_LTRUE:   case OP_LFALSE:  case OP_EQ:      case OP_NOTEQ:
24560         case OP_SLESS:   case OP_ULESS:   case OP_SMORE:   case OP_UMORE:
24561         case OP_SLESSEQ: case OP_ULESSEQ: case OP_SMOREEQ: case OP_UMOREEQ:
24562         default:
24563                 internal_error(state, ins, "unknown op: %d %s",
24564                         ins->op, tops(ins->op));
24565                 break;
24566         }
24567 }
24568
24569 static void print_instructions(struct compile_state *state)
24570 {
24571         struct triple *first, *ins;
24572         int print_location;
24573         struct occurance *last_occurance;
24574         FILE *fp;
24575         int max_inline_depth;
24576         max_inline_depth = 0;
24577         print_location = 1;
24578         last_occurance = 0;
24579         fp = state->output;
24580         /* Masks for common sizes */
24581         fprintf(fp, ".section \"" DATA_SECTION "\"\n");
24582         fprintf(fp, ".balign 16\n");
24583         fprintf(fp, "L%s1:\n", state->compiler->label_prefix);
24584         fprintf(fp, ".int 0xff, 0, 0, 0\n");
24585         fprintf(fp, "L%s2:\n", state->compiler->label_prefix);
24586         fprintf(fp, ".int 0xffff, 0, 0, 0\n");
24587         fprintf(fp, ".section \"" TEXT_SECTION "\"\n");
24588         first = state->first;
24589         ins = first;
24590         do {
24591                 if (print_location && 
24592                         last_occurance != ins->occurance) {
24593                         if (!ins->occurance->parent) {
24594                                 fprintf(fp, "\t/* %s,%s:%d.%d */\n",
24595                                         ins->occurance->function,
24596                                         ins->occurance->filename,
24597                                         ins->occurance->line,
24598                                         ins->occurance->col);
24599                         }
24600                         else {
24601                                 struct occurance *ptr;
24602                                 int inline_depth;
24603                                 fprintf(fp, "\t/*\n");
24604                                 inline_depth = 0;
24605                                 for(ptr = ins->occurance; ptr; ptr = ptr->parent) {
24606                                         inline_depth++;
24607                                         fprintf(fp, "\t * %s,%s:%d.%d\n",
24608                                                 ptr->function,
24609                                                 ptr->filename,
24610                                                 ptr->line,
24611                                                 ptr->col);
24612                                 }
24613                                 fprintf(fp, "\t */\n");
24614                                 if (inline_depth > max_inline_depth) {
24615                                         max_inline_depth = inline_depth;
24616                                 }
24617                         }
24618                         if (last_occurance) {
24619                                 put_occurance(last_occurance);
24620                         }
24621                         get_occurance(ins->occurance);
24622                         last_occurance = ins->occurance;
24623                 }
24624
24625                 print_instruction(state, ins, fp);
24626                 ins = ins->next;
24627         } while(ins != first);
24628         if (print_location) {
24629                 fprintf(fp, "/* max inline depth %d */\n",
24630                         max_inline_depth);
24631         }
24632 }
24633
24634 static void generate_code(struct compile_state *state)
24635 {
24636         generate_local_labels(state);
24637         print_instructions(state);
24638         
24639 }
24640
24641 static void print_preprocessed_tokens(struct compile_state *state)
24642 {
24643         int tok;
24644         FILE *fp;
24645         int line;
24646         const char *filename;
24647         fp = state->output;
24648         filename = 0;
24649         line = 0;
24650         for(;;) {
24651                 struct file_state *file;
24652                 struct token *tk;
24653                 const char *token_str;
24654                 tok = peek(state);
24655                 if (tok == TOK_EOF) {
24656                         break;
24657                 }
24658                 tk = eat(state, tok);
24659                 token_str = 
24660                         tk->ident ? tk->ident->name :
24661                         tk->str_len ? tk->val.str :
24662                         tokens[tk->tok];
24663                 
24664
24665                 file = state->file;
24666                 while(file->macro && file->prev) {
24667                         file = file->prev;
24668                 }
24669                 if (!file->macro && 
24670                         ((file->line != line) || (file->basename != filename))) 
24671                 {
24672                         int i, col;
24673                         if ((file->basename == filename) &&
24674                                 (line < file->line)) {
24675                                 while(line < file->line) {
24676                                         fprintf(fp, "\n");
24677                                         line++;
24678                                 }
24679                         }
24680                         else {
24681                                 fprintf(fp, "\n#line %d \"%s\"\n",
24682                                         file->line, file->basename);
24683                         }
24684                         line = file->line;
24685                         filename = file->basename;
24686                         col = get_col(file) - strlen(token_str);
24687                         for(i = 0; i < col; i++) {
24688                                 fprintf(fp, " ");
24689                         }
24690                 }
24691                 
24692                 fprintf(fp, "%s ", token_str);
24693                 
24694                 if (state->compiler->debug & DEBUG_TOKENS) {
24695                         loc(state->dbgout, state, 0);
24696                         fprintf(state->dbgout, "%s <- `%s'\n",
24697                                 tokens[tok], token_str);
24698                 }
24699         }
24700 }
24701
24702 static void compile(const char *filename, 
24703         struct compiler_state *compiler, struct arch_state *arch)
24704 {
24705         int i;
24706         struct compile_state state;
24707         struct triple *ptr;
24708         memset(&state, 0, sizeof(state));
24709         state.compiler = compiler;
24710         state.arch     = arch;
24711         state.file = 0;
24712         for(i = 0; i < sizeof(state.token)/sizeof(state.token[0]); i++) {
24713                 memset(&state.token[i], 0, sizeof(state.token[i]));
24714                 state.token[i].tok = -1;
24715         }
24716         /* Remember the output descriptors */
24717         state.errout = stderr;
24718         state.dbgout = stdout;
24719         /* Remember the output filename */
24720         state.output    = fopen(state.compiler->ofilename, "w");
24721         if (!state.output) {
24722                 error(&state, 0, "Cannot open output file %s\n",
24723                         state.compiler->ofilename);
24724         }
24725         /* Make certain a good cleanup happens */
24726         exit_state = &state;
24727         atexit(exit_cleanup);
24728
24729         /* Prep the preprocessor */
24730         state.if_depth = 0;
24731         memset(state.if_bytes, 0, sizeof(state.if_bytes));
24732         /* register the C keywords */
24733         register_keywords(&state);
24734         /* register the keywords the macro preprocessor knows */
24735         register_macro_keywords(&state);
24736         /* generate some builtin macros */
24737         register_builtin_macros(&state);
24738         /* Memorize where some special keywords are. */
24739         state.i_switch        = lookup(&state, "switch", 6);
24740         state.i_case          = lookup(&state, "case", 4);
24741         state.i_continue      = lookup(&state, "continue", 8);
24742         state.i_break         = lookup(&state, "break", 5);
24743         state.i_default       = lookup(&state, "default", 7);
24744         state.i_return        = lookup(&state, "return", 6);
24745         /* Memorize where predefined macros are. */
24746         state.i___VA_ARGS__   = lookup(&state, "__VA_ARGS__", 11);
24747         state.i___FILE__      = lookup(&state, "__FILE__", 8);
24748         state.i___LINE__      = lookup(&state, "__LINE__", 8);
24749         /* Memorize where predefined identifiers are. */
24750         state.i___func__      = lookup(&state, "__func__", 8);
24751         /* Memorize where some attribute keywords are. */
24752         state.i_noinline      = lookup(&state, "noinline", 8);
24753         state.i_always_inline = lookup(&state, "always_inline", 13);
24754
24755         /* Process the command line macros */
24756         process_cmdline_macros(&state);
24757
24758         /* Allocate beginning bounding labels for the function list */
24759         state.first = label(&state);
24760         state.first->id |= TRIPLE_FLAG_VOLATILE;
24761         use_triple(state.first, state.first);
24762         ptr = label(&state);
24763         ptr->id |= TRIPLE_FLAG_VOLATILE;
24764         use_triple(ptr, ptr);
24765         flatten(&state, state.first, ptr);
24766
24767         /* Allocate a label for the pool of global variables */
24768         state.global_pool = label(&state);
24769         state.global_pool->id |= TRIPLE_FLAG_VOLATILE;
24770         flatten(&state, state.first, state.global_pool);
24771
24772         /* Enter the globl definition scope */
24773         start_scope(&state);
24774         register_builtins(&state);
24775         compile_file(&state, filename, 1);
24776
24777         /* Stop if all we want is preprocessor output */
24778         if (state.compiler->flags & COMPILER_CPP_ONLY) {
24779                 print_preprocessed_tokens(&state);
24780                 return;
24781         }
24782
24783         decls(&state);
24784
24785         /* Exit the global definition scope */
24786         end_scope(&state);
24787
24788         /* Now that basic compilation has happened 
24789          * optimize the intermediate code 
24790          */
24791         optimize(&state);
24792
24793         generate_code(&state);
24794         if (state.compiler->debug) {
24795                 fprintf(state.errout, "done\n");
24796         }
24797         exit_state = 0;
24798 }
24799
24800 static void version(FILE *fp)
24801 {
24802         fprintf(fp, "romcc " VERSION " released " RELEASE_DATE "\n");
24803 }
24804
24805 static void usage(void)
24806 {
24807         FILE *fp = stdout;
24808         version(fp);
24809         fprintf(fp,
24810                 "\nUsage: romcc [options] <source>.c\n"
24811                 "Compile a C source file generating a binary that does not implicilty use RAM\n"
24812                 "Options: \n"
24813                 "-o <output file name>\n"
24814                 "-f<option>            Specify a generic compiler option\n"
24815                 "-m<option>            Specify a arch dependent option\n"
24816                 "--                    Specify this is the last option\n"
24817                 "\nGeneric compiler options:\n"
24818         );
24819         compiler_usage(fp);
24820         fprintf(fp,
24821                 "\nArchitecture compiler options:\n"
24822         );
24823         arch_usage(fp);
24824         fprintf(fp,
24825                 "\n"
24826         );
24827 }
24828
24829 static void arg_error(char *fmt, ...)
24830 {
24831         va_list args;
24832         va_start(args, fmt);
24833         vfprintf(stderr, fmt, args);
24834         va_end(args);
24835         usage();
24836         exit(1);
24837 }
24838
24839 int main(int argc, char **argv)
24840 {
24841         const char *filename;
24842         struct compiler_state compiler;
24843         struct arch_state arch;
24844         int all_opts;
24845         
24846         
24847         /* I don't want any surprises */
24848         setlocale(LC_ALL, "C");
24849
24850         init_compiler_state(&compiler);
24851         init_arch_state(&arch);
24852         filename = 0;
24853         all_opts = 0;
24854         while(argc > 1) {
24855                 if (!all_opts && (strcmp(argv[1], "-o") == 0) && (argc > 2)) {
24856                         compiler.ofilename = argv[2];
24857                         argv += 2;
24858                         argc -= 2;
24859                 }
24860                 else if (!all_opts && argv[1][0] == '-') {
24861                         int result;
24862                         result = -1;
24863                         if (strcmp(argv[1], "--") == 0) {
24864                                 result = 0;
24865                                 all_opts = 1;
24866                         }
24867                         else if (strncmp(argv[1], "-E", 2) == 0) {
24868                                 result = compiler_encode_flag(&compiler, argv[1]);
24869                         }
24870                         else if (strncmp(argv[1], "-O", 2) == 0) {
24871                                 result = compiler_encode_flag(&compiler, argv[1]);
24872                         }
24873                         else if (strncmp(argv[1], "-I", 2) == 0) {
24874                                 result = compiler_encode_flag(&compiler, argv[1]);
24875                         }
24876                         else if (strncmp(argv[1], "-D", 2) == 0) {
24877                                 result = compiler_encode_flag(&compiler, argv[1]);
24878                         }
24879                         else if (strncmp(argv[1], "-U", 2) == 0) {
24880                                 result = compiler_encode_flag(&compiler, argv[1]);
24881                         }
24882                         else if (strncmp(argv[1], "--label-prefix=", 15) == 0) {
24883                                 result = compiler_encode_flag(&compiler, argv[1]+2);
24884                         }
24885                         else if (strncmp(argv[1], "-f", 2) == 0) {
24886                                 result = compiler_encode_flag(&compiler, argv[1]+2);
24887                         }
24888                         else if (strncmp(argv[1], "-m", 2) == 0) {
24889                                 result = arch_encode_flag(&arch, argv[1]+2);
24890                         }
24891                         if (result < 0) {
24892                                 arg_error("Invalid option specified: %s\n",
24893                                         argv[1]);
24894                         }
24895                         argv++;
24896                         argc--;
24897                 }
24898                 else {
24899                         if (filename) {
24900                                 arg_error("Only one filename may be specified\n");
24901                         }
24902                         filename = argv[1];
24903                         argv++;
24904                         argc--;
24905                 }
24906         }
24907         if (!filename) {
24908                 arg_error("No filename specified\n");
24909         }
24910         compile(filename, &compiler, &arch);
24911
24912         return 0;
24913 }