fix romcc preprocessor bug
[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 "69"
7 #define RELEASE_DATE "02 December 2006"
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         const 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         int trigraphs  : 1;
341         int join_lines : 1;
342 };
343 struct hash_entry;
344 struct token {
345         int tok;
346         struct hash_entry *ident;
347         const char *pos;
348         int str_len;
349         union {
350                 ulong_t integer;
351                 const char *str;
352                 int notmacro;
353         } val;
354 };
355
356 /* I have two classes of types:
357  * Operational types.
358  * Logical types.  (The type the C standard says the operation is of)
359  *
360  * The operational types are:
361  * chars
362  * shorts
363  * ints
364  * longs
365  *
366  * floats
367  * doubles
368  * long doubles
369  *
370  * pointer
371  */
372
373
374 /* Machine model.
375  * No memory is useable by the compiler.
376  * There is no floating point support.
377  * All operations take place in general purpose registers.
378  * There is one type of general purpose register.
379  * Unsigned longs are stored in that general purpose register.
380  */
381
382 /* Operations on general purpose registers.
383  */
384
385 #define OP_SDIVT      0
386 #define OP_UDIVT      1
387 #define OP_SMUL       2
388 #define OP_UMUL       3
389 #define OP_SDIV       4
390 #define OP_UDIV       5
391 #define OP_SMOD       6
392 #define OP_UMOD       7
393 #define OP_ADD        8
394 #define OP_SUB        9
395 #define OP_SL        10
396 #define OP_USR       11
397 #define OP_SSR       12 
398 #define OP_AND       13 
399 #define OP_XOR       14
400 #define OP_OR        15
401 #define OP_POS       16 /* Dummy positive operator don't use it */
402 #define OP_NEG       17
403 #define OP_INVERT    18
404                      
405 #define OP_EQ        20
406 #define OP_NOTEQ     21
407 #define OP_SLESS     22
408 #define OP_ULESS     23
409 #define OP_SMORE     24
410 #define OP_UMORE     25
411 #define OP_SLESSEQ   26
412 #define OP_ULESSEQ   27
413 #define OP_SMOREEQ   28
414 #define OP_UMOREEQ   29
415                      
416 #define OP_LFALSE    30  /* Test if the expression is logically false */
417 #define OP_LTRUE     31  /* Test if the expression is logcially true */
418
419 #define OP_LOAD      32
420 #define OP_STORE     33
421 /* For OP_STORE ->type holds the type
422  * RHS(0) holds the destination address
423  * RHS(1) holds the value to store.
424  */
425
426 #define OP_UEXTRACT  34
427 /* OP_UEXTRACT extracts an unsigned bitfield from a pseudo register
428  * RHS(0) holds the psuedo register to extract from
429  * ->type holds the size of the bitfield.
430  * ->u.bitfield.size holds the size of the bitfield.
431  * ->u.bitfield.offset holds the offset to extract from
432  */
433 #define OP_SEXTRACT  35
434 /* OP_SEXTRACT extracts a signed bitfield from a pseudo register
435  * RHS(0) holds the psuedo register to extract from
436  * ->type holds the size of the bitfield.
437  * ->u.bitfield.size holds the size of the bitfield.
438  * ->u.bitfield.offset holds the offset to extract from
439  */
440 #define OP_DEPOSIT   36
441 /* OP_DEPOSIT replaces a bitfield with a new value.
442  * RHS(0) holds the value to replace a bitifield in.
443  * RHS(1) holds the replacement value
444  * ->u.bitfield.size holds the size of the bitfield.
445  * ->u.bitfield.offset holds the deposit into
446  */
447
448 #define OP_NOOP      37
449
450 #define OP_MIN_CONST 50
451 #define OP_MAX_CONST 58
452 #define IS_CONST_OP(X) (((X) >= OP_MIN_CONST) && ((X) <= OP_MAX_CONST))
453 #define OP_INTCONST  50
454 /* For OP_INTCONST ->type holds the type.
455  * ->u.cval holds the constant value.
456  */
457 #define OP_BLOBCONST 51
458 /* For OP_BLOBCONST ->type holds the layout and size
459  * information.  u.blob holds a pointer to the raw binary
460  * data for the constant initializer.
461  */
462 #define OP_ADDRCONST 52
463 /* For OP_ADDRCONST ->type holds the type.
464  * MISC(0) holds the reference to the static variable.
465  * ->u.cval holds an offset from that value.
466  */
467 #define OP_UNKNOWNVAL 59
468 /* For OP_UNKNOWNAL ->type holds the type.
469  * For some reason we don't know what value this type has.
470  * This allows for variables that have don't have values
471  * assigned yet, or variables whose value we simply do not know.
472  */
473
474 #define OP_WRITE     60 
475 /* OP_WRITE moves one pseudo register to another.
476  * MISC(0) holds the destination pseudo register, which must be an OP_DECL.
477  * RHS(0) holds the psuedo to move.
478  */
479
480 #define OP_READ      61
481 /* OP_READ reads the value of a variable and makes
482  * it available for the pseudo operation.
483  * Useful for things like def-use chains.
484  * RHS(0) holds points to the triple to read from.
485  */
486 #define OP_COPY      62
487 /* OP_COPY makes a copy of the pseudo register or constant in RHS(0).
488  */
489 #define OP_CONVERT   63
490 /* OP_CONVERT makes a copy of the pseudo register or constant in RHS(0).
491  * And then the type is converted appropriately.
492  */
493 #define OP_PIECE     64
494 /* OP_PIECE returns one piece of a instruction that returns a structure.
495  * MISC(0) is the instruction
496  * u.cval is the LHS piece of the instruction to return.
497  */
498 #define OP_ASM       65
499 /* OP_ASM holds a sequence of assembly instructions, the result
500  * of a C asm directive.
501  * RHS(x) holds input value x to the assembly sequence.
502  * LHS(x) holds the output value x from the assembly sequence.
503  * u.blob holds the string of assembly instructions.
504  */
505
506 #define OP_DEREF     66
507 /* OP_DEREF generates an lvalue from a pointer.
508  * RHS(0) holds the pointer value.
509  * OP_DEREF serves as a place holder to indicate all necessary
510  * checks have been done to indicate a value is an lvalue.
511  */
512 #define OP_DOT       67
513 /* OP_DOT references a submember of a structure lvalue.
514  * MISC(0) holds the lvalue.
515  * ->u.field holds the name of the field we want.
516  *
517  * Not seen after structures are flattened.
518  */
519 #define OP_INDEX     68
520 /* OP_INDEX references a submember of a tuple or array lvalue.
521  * MISC(0) holds the lvalue.
522  * ->u.cval holds the index into the lvalue.
523  *
524  * Not seen after structures are flattened.
525  */
526 #define OP_VAL       69
527 /* OP_VAL returns the value of a subexpression of the current expression.
528  * Useful for operators that have side effects.
529  * RHS(0) holds the expression.
530  * MISC(0) holds the subexpression of RHS(0) that is the
531  * value of the expression.
532  *
533  * Not seen outside of expressions.
534  */
535
536 #define OP_TUPLE     70
537 /* OP_TUPLE is an array of triples that are either variable
538  * or values for a structure or an array.  It is used as
539  * a place holder when flattening compound types.
540  * The value represented by an OP_TUPLE is held in N registers.
541  * LHS(0..N-1) refer to those registers.
542  * ->use is a list of statements that use the value.
543  * 
544  * Although OP_TUPLE always has register sized pieces they are not
545  * used until structures are flattened/decomposed into their register
546  * components. 
547  * ???? registers ????
548  */
549
550 #define OP_BITREF    71
551 /* OP_BITREF describes a bitfield as an lvalue.
552  * RHS(0) holds the register value.
553  * ->type holds the type of the bitfield.
554  * ->u.bitfield.size holds the size of the bitfield.
555  * ->u.bitfield.offset holds the offset of the bitfield in the register
556  */
557
558
559 #define OP_FCALL     72
560 /* OP_FCALL performs a procedure call. 
561  * MISC(0) holds a pointer to the OP_LIST of a function
562  * RHS(x) holds argument x of a function
563  * 
564  * Currently not seen outside of expressions.
565  */
566 #define OP_PROG      73
567 /* OP_PROG is an expression that holds a list of statements, or
568  * expressions.  The final expression is the value of the expression.
569  * RHS(0) holds the start of the list.
570  */
571
572 /* statements */
573 #define OP_LIST      80
574 /* OP_LIST Holds a list of statements that compose a function, and a result value.
575  * RHS(0) holds the list of statements.
576  * A list of all functions is maintained.
577  */
578
579 #define OP_BRANCH    81 /* an unconditional branch */
580 /* For branch instructions
581  * TARG(0) holds the branch target.
582  * ->next holds where to branch to if the branch is not taken.
583  * The branch target can only be a label
584  */
585
586 #define OP_CBRANCH   82 /* a conditional branch */
587 /* For conditional branch instructions
588  * RHS(0) holds the branch condition.
589  * TARG(0) holds the branch target.
590  * ->next holds where to branch to if the branch is not taken.
591  * The branch target can only be a label
592  */
593
594 #define OP_CALL      83 /* an uncontional branch that will return */
595 /* For call instructions
596  * MISC(0) holds the OP_RET that returns from the branch
597  * TARG(0) holds the branch target.
598  * ->next holds where to branch to if the branch is not taken.
599  * The branch target can only be a label
600  */
601
602 #define OP_RET       84 /* an uncontinonal branch through a variable back to an OP_CALL */
603 /* For call instructions
604  * RHS(0) holds the variable with the return address
605  * The branch target can only be a label
606  */
607
608 #define OP_LABEL     86
609 /* OP_LABEL is a triple that establishes an target for branches.
610  * ->use is the list of all branches that use this label.
611  */
612
613 #define OP_ADECL     87 
614 /* OP_ADECL is a triple that establishes an lvalue for assignments.
615  * A variable takes N registers to contain.
616  * LHS(0..N-1) refer to an OP_PIECE triple that represents
617  * the Xth register that the variable is stored in.
618  * ->use is a list of statements that use the variable.
619  * 
620  * Although OP_ADECL always has register sized pieces they are not
621  * used until structures are flattened/decomposed into their register
622  * components. 
623  */
624
625 #define OP_SDECL     88
626 /* OP_SDECL is a triple that establishes a variable of static
627  * storage duration.
628  * ->use is a list of statements that use the variable.
629  * MISC(0) holds the initializer expression.
630  */
631
632
633 #define OP_PHI       89
634 /* OP_PHI is a triple used in SSA form code.  
635  * It is used when multiple code paths merge and a variable needs
636  * a single assignment from any of those code paths.
637  * The operation is a cross between OP_DECL and OP_WRITE, which
638  * is what OP_PHI is generated from.
639  * 
640  * RHS(x) points to the value from code path x
641  * The number of RHS entries is the number of control paths into the block
642  * in which OP_PHI resides.  The elements of the array point to point
643  * to the variables OP_PHI is derived from.
644  *
645  * MISC(0) holds a pointer to the orginal OP_DECL node.
646  */
647
648 #if 0
649 /* continuation helpers
650  */
651 #define OP_CPS_BRANCH    90 /* an unconditional branch */
652 /* OP_CPS_BRANCH calls a continuation 
653  * RHS(x) holds argument x of the function
654  * TARG(0) holds OP_CPS_START target
655  */
656 #define OP_CPS_CBRANCH   91  /* a conditional branch */
657 /* OP_CPS_CBRANCH conditionally calls one of two continuations 
658  * RHS(0) holds the branch condition
659  * RHS(x + 1) holds argument x of the function
660  * TARG(0) holds the OP_CPS_START to jump to when true
661  * ->next holds the OP_CPS_START to jump to when false
662  */
663 #define OP_CPS_CALL      92  /* an uncontional branch that will return */
664 /* For OP_CPS_CALL instructions
665  * RHS(x) holds argument x of the function
666  * MISC(0) holds the OP_CPS_RET that returns from the branch
667  * TARG(0) holds the branch target.
668  * ->next holds where the OP_CPS_RET will return to.
669  */
670 #define OP_CPS_RET       93
671 /* OP_CPS_RET conditionally calls one of two continuations 
672  * RHS(0) holds the variable with the return function address
673  * RHS(x + 1) holds argument x of the function
674  * The branch target may be any OP_CPS_START
675  */
676 #define OP_CPS_END       94
677 /* OP_CPS_END is the triple at the end of the program.
678  * For most practical purposes it is a branch.
679  */
680 #define OP_CPS_START     95
681 /* OP_CPS_START is a triple at the start of a continuation
682  * The arguments variables takes N registers to contain.
683  * LHS(0..N-1) refer to an OP_PIECE triple that represents
684  * the Xth register that the arguments are stored in.
685  */
686 #endif
687
688 /* Architecture specific instructions */
689 #define OP_CMP         100
690 #define OP_TEST        101
691 #define OP_SET_EQ      102
692 #define OP_SET_NOTEQ   103
693 #define OP_SET_SLESS   104
694 #define OP_SET_ULESS   105
695 #define OP_SET_SMORE   106
696 #define OP_SET_UMORE   107
697 #define OP_SET_SLESSEQ 108
698 #define OP_SET_ULESSEQ 109
699 #define OP_SET_SMOREEQ 110
700 #define OP_SET_UMOREEQ 111
701
702 #define OP_JMP         112
703 #define OP_JMP_EQ      113
704 #define OP_JMP_NOTEQ   114
705 #define OP_JMP_SLESS   115
706 #define OP_JMP_ULESS   116
707 #define OP_JMP_SMORE   117
708 #define OP_JMP_UMORE   118
709 #define OP_JMP_SLESSEQ 119
710 #define OP_JMP_ULESSEQ 120
711 #define OP_JMP_SMOREEQ 121
712 #define OP_JMP_UMOREEQ 122
713
714 /* Builtin operators that it is just simpler to use the compiler for */
715 #define OP_INB         130
716 #define OP_INW         131
717 #define OP_INL         132
718 #define OP_OUTB        133
719 #define OP_OUTW        134
720 #define OP_OUTL        135
721 #define OP_BSF         136
722 #define OP_BSR         137
723 #define OP_RDMSR       138
724 #define OP_WRMSR       139
725 #define OP_HLT         140
726
727 struct op_info {
728         const char *name;
729         unsigned flags;
730 #define PURE       0x001 /* Triple has no side effects */
731 #define IMPURE     0x002 /* Triple has side effects */
732 #define PURE_BITS(FLAGS) ((FLAGS) & 0x3)
733 #define DEF        0x004 /* Triple is a variable definition */
734 #define BLOCK      0x008 /* Triple stores the current block */
735 #define STRUCTURAL 0x010 /* Triple does not generate a machine instruction */
736 #define BRANCH_BITS(FLAGS) ((FLAGS) & 0xe0 )
737 #define UBRANCH    0x020 /* Triple is an unconditional branch instruction */
738 #define CBRANCH    0x040 /* Triple is a conditional branch instruction */
739 #define RETBRANCH  0x060 /* Triple is a return instruction */
740 #define CALLBRANCH 0x080 /* Triple is a call instruction */
741 #define ENDBRANCH  0x0a0 /* Triple is an end instruction */
742 #define PART       0x100 /* Triple is really part of another triple */
743 #define BITFIELD   0x200 /* Triple manipulates a bitfield */
744         signed char lhs, rhs, misc, targ;
745 };
746
747 #define OP(LHS, RHS, MISC, TARG, FLAGS, NAME) { \
748         .name = (NAME), \
749         .flags = (FLAGS), \
750         .lhs = (LHS), \
751         .rhs = (RHS), \
752         .misc = (MISC), \
753         .targ = (TARG), \
754          }
755 static const struct op_info table_ops[] = {
756 [OP_SDIVT      ] = OP( 2,  2, 0, 0, PURE | BLOCK , "sdivt"),
757 [OP_UDIVT      ] = OP( 2,  2, 0, 0, PURE | BLOCK , "udivt"),
758 [OP_SMUL       ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "smul"),
759 [OP_UMUL       ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "umul"),
760 [OP_SDIV       ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "sdiv"),
761 [OP_UDIV       ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "udiv"),
762 [OP_SMOD       ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "smod"),
763 [OP_UMOD       ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "umod"),
764 [OP_ADD        ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "add"),
765 [OP_SUB        ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "sub"),
766 [OP_SL         ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "sl"),
767 [OP_USR        ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "usr"),
768 [OP_SSR        ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "ssr"),
769 [OP_AND        ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "and"),
770 [OP_XOR        ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "xor"),
771 [OP_OR         ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "or"),
772 [OP_POS        ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK , "pos"),
773 [OP_NEG        ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK , "neg"),
774 [OP_INVERT     ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK , "invert"),
775
776 [OP_EQ         ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "eq"),
777 [OP_NOTEQ      ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "noteq"),
778 [OP_SLESS      ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "sless"),
779 [OP_ULESS      ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "uless"),
780 [OP_SMORE      ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "smore"),
781 [OP_UMORE      ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "umore"),
782 [OP_SLESSEQ    ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "slesseq"),
783 [OP_ULESSEQ    ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "ulesseq"),
784 [OP_SMOREEQ    ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "smoreeq"),
785 [OP_UMOREEQ    ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK , "umoreeq"),
786 [OP_LFALSE     ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK , "lfalse"),
787 [OP_LTRUE      ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK , "ltrue"),
788
789 [OP_LOAD       ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "load"),
790 [OP_STORE      ] = OP( 0,  2, 0, 0, PURE | BLOCK , "store"),
791
792 [OP_UEXTRACT   ] = OP( 0,  1, 0, 0, PURE | DEF | BITFIELD, "uextract"),
793 [OP_SEXTRACT   ] = OP( 0,  1, 0, 0, PURE | DEF | BITFIELD, "sextract"),
794 [OP_DEPOSIT    ] = OP( 0,  2, 0, 0, PURE | DEF | BITFIELD, "deposit"),
795
796 [OP_NOOP       ] = OP( 0,  0, 0, 0, PURE | BLOCK | STRUCTURAL, "noop"),
797
798 [OP_INTCONST   ] = OP( 0,  0, 0, 0, PURE | DEF, "intconst"),
799 [OP_BLOBCONST  ] = OP( 0,  0, 0, 0, PURE , "blobconst"),
800 [OP_ADDRCONST  ] = OP( 0,  0, 1, 0, PURE | DEF, "addrconst"),
801 [OP_UNKNOWNVAL ] = OP( 0,  0, 0, 0, PURE | DEF, "unknown"),
802
803 #warning "FIXME is it correct for OP_WRITE to be a def?  I currently use it as one..."
804 [OP_WRITE      ] = OP( 0,  1, 1, 0, PURE | DEF | BLOCK, "write"),
805 [OP_READ       ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "read"),
806 [OP_COPY       ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "copy"),
807 [OP_CONVERT    ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "convert"),
808 [OP_PIECE      ] = OP( 0,  0, 1, 0, PURE | DEF | STRUCTURAL | PART, "piece"),
809 [OP_ASM        ] = OP(-1, -1, 0, 0, PURE, "asm"),
810 [OP_DEREF      ] = OP( 0,  1, 0, 0, 0 | DEF | BLOCK, "deref"), 
811 [OP_DOT        ] = OP( 0,  0, 1, 0, PURE | DEF | PART, "dot"),
812 [OP_INDEX      ] = OP( 0,  0, 1, 0, PURE | DEF | PART, "index"),
813
814 [OP_VAL        ] = OP( 0,  1, 1, 0, 0 | DEF | BLOCK, "val"),
815 [OP_TUPLE      ] = OP(-1,  0, 0, 0, 0 | PURE | BLOCK | STRUCTURAL, "tuple"),
816 [OP_BITREF     ] = OP( 0,  1, 0, 0, 0 | DEF | PURE | STRUCTURAL | BITFIELD, "bitref"),
817 /* Call is special most it can stand in for anything so it depends on context */
818 [OP_FCALL      ] = OP( 0, -1, 1, 0, 0 | BLOCK | CALLBRANCH, "fcall"),
819 [OP_PROG       ] = OP( 0,  1, 0, 0, 0 | IMPURE | BLOCK | STRUCTURAL, "prog"),
820 /* The sizes of OP_FCALL depends upon context */
821
822 [OP_LIST       ] = OP( 0,  1, 1, 0, 0 | DEF | STRUCTURAL, "list"),
823 [OP_BRANCH     ] = OP( 0,  0, 0, 1, PURE | BLOCK | UBRANCH, "branch"),
824 [OP_CBRANCH    ] = OP( 0,  1, 0, 1, PURE | BLOCK | CBRANCH, "cbranch"),
825 [OP_CALL       ] = OP( 0,  0, 1, 1, PURE | BLOCK | CALLBRANCH, "call"),
826 [OP_RET        ] = OP( 0,  1, 0, 0, PURE | BLOCK | RETBRANCH, "ret"),
827 [OP_LABEL      ] = OP( 0,  0, 0, 0, PURE | BLOCK | STRUCTURAL, "label"),
828 [OP_ADECL      ] = OP( 0,  0, 0, 0, PURE | BLOCK | STRUCTURAL, "adecl"),
829 [OP_SDECL      ] = OP( 0,  0, 1, 0, PURE | BLOCK | STRUCTURAL, "sdecl"),
830 /* The number of RHS elements of OP_PHI depend upon context */
831 [OP_PHI        ] = OP( 0, -1, 1, 0, PURE | DEF | BLOCK, "phi"),
832
833 #if 0
834 [OP_CPS_BRANCH ] = OP( 0, -1, 0, 1, PURE | BLOCK | UBRANCH,     "cps_branch"),
835 [OP_CPS_CBRANCH] = OP( 0, -1, 0, 1, PURE | BLOCK | CBRANCH,     "cps_cbranch"),
836 [OP_CPS_CALL   ] = OP( 0, -1, 1, 1, PURE | BLOCK | CALLBRANCH,  "cps_call"),
837 [OP_CPS_RET    ] = OP( 0, -1, 0, 0, PURE | BLOCK | RETBRANCH,   "cps_ret"),
838 [OP_CPS_END    ] = OP( 0, -1, 0, 0, IMPURE | BLOCK | ENDBRANCH, "cps_end"),
839 [OP_CPS_START  ] = OP( -1, 0, 0, 0, PURE | BLOCK | STRUCTURAL,  "cps_start"),
840 #endif
841
842 [OP_CMP        ] = OP( 0,  2, 0, 0, PURE | DEF | BLOCK, "cmp"),
843 [OP_TEST       ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "test"),
844 [OP_SET_EQ     ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_eq"),
845 [OP_SET_NOTEQ  ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_noteq"),
846 [OP_SET_SLESS  ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_sless"),
847 [OP_SET_ULESS  ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_uless"),
848 [OP_SET_SMORE  ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_smore"),
849 [OP_SET_UMORE  ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_umore"),
850 [OP_SET_SLESSEQ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_slesseq"),
851 [OP_SET_ULESSEQ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_ulesseq"),
852 [OP_SET_SMOREEQ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_smoreq"),
853 [OP_SET_UMOREEQ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "set_umoreq"),
854 [OP_JMP        ] = OP( 0,  0, 0, 1, PURE | BLOCK | UBRANCH, "jmp"),
855 [OP_JMP_EQ     ] = OP( 0,  1, 0, 1, PURE | BLOCK | CBRANCH, "jmp_eq"),
856 [OP_JMP_NOTEQ  ] = OP( 0,  1, 0, 1, PURE | BLOCK | CBRANCH, "jmp_noteq"),
857 [OP_JMP_SLESS  ] = OP( 0,  1, 0, 1, PURE | BLOCK | CBRANCH, "jmp_sless"),
858 [OP_JMP_ULESS  ] = OP( 0,  1, 0, 1, PURE | BLOCK | CBRANCH, "jmp_uless"),
859 [OP_JMP_SMORE  ] = OP( 0,  1, 0, 1, PURE | BLOCK | CBRANCH, "jmp_smore"),
860 [OP_JMP_UMORE  ] = OP( 0,  1, 0, 1, PURE | BLOCK | CBRANCH, "jmp_umore"),
861 [OP_JMP_SLESSEQ] = OP( 0,  1, 0, 1, PURE | BLOCK | CBRANCH, "jmp_slesseq"),
862 [OP_JMP_ULESSEQ] = OP( 0,  1, 0, 1, PURE | BLOCK | CBRANCH, "jmp_ulesseq"),
863 [OP_JMP_SMOREEQ] = OP( 0,  1, 0, 1, PURE | BLOCK | CBRANCH, "jmp_smoreq"),
864 [OP_JMP_UMOREEQ] = OP( 0,  1, 0, 1, PURE | BLOCK | CBRANCH, "jmp_umoreq"),
865
866 [OP_INB        ] = OP( 0,  1, 0, 0, IMPURE | DEF | BLOCK, "__inb"),
867 [OP_INW        ] = OP( 0,  1, 0, 0, IMPURE | DEF | BLOCK, "__inw"),
868 [OP_INL        ] = OP( 0,  1, 0, 0, IMPURE | DEF | BLOCK, "__inl"),
869 [OP_OUTB       ] = OP( 0,  2, 0, 0, IMPURE| BLOCK, "__outb"),
870 [OP_OUTW       ] = OP( 0,  2, 0, 0, IMPURE| BLOCK, "__outw"),
871 [OP_OUTL       ] = OP( 0,  2, 0, 0, IMPURE| BLOCK, "__outl"),
872 [OP_BSF        ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "__bsf"),
873 [OP_BSR        ] = OP( 0,  1, 0, 0, PURE | DEF | BLOCK, "__bsr"),
874 [OP_RDMSR      ] = OP( 2,  1, 0, 0, IMPURE | BLOCK, "__rdmsr"),
875 [OP_WRMSR      ] = OP( 0,  3, 0, 0, IMPURE | BLOCK, "__wrmsr"),
876 [OP_HLT        ] = OP( 0,  0, 0, 0, IMPURE | BLOCK, "__hlt"),
877 };
878 #undef OP
879 #define OP_MAX      (sizeof(table_ops)/sizeof(table_ops[0]))
880
881 static const char *tops(int index) 
882 {
883         static const char unknown[] = "unknown op";
884         if (index < 0) {
885                 return unknown;
886         }
887         if (index > OP_MAX) {
888                 return unknown;
889         }
890         return table_ops[index].name;
891 }
892
893 struct asm_info;
894 struct triple;
895 struct block;
896 struct triple_set {
897         struct triple_set *next;
898         struct triple *member;
899 };
900
901 #define MAX_LHS  63
902 #define MAX_RHS  127
903 #define MAX_MISC 3
904 #define MAX_TARG 1
905
906 struct occurance {
907         int count;
908         const char *filename;
909         const char *function;
910         int line;
911         int col;
912         struct occurance *parent;
913 };
914 struct bitfield {
915         ulong_t size : 8;
916         ulong_t offset : 24;
917 };
918 struct triple {
919         struct triple *next, *prev;
920         struct triple_set *use;
921         struct type *type;
922         unsigned int op : 8;
923         unsigned int template_id : 7;
924         unsigned int lhs  : 6;
925         unsigned int rhs  : 7;
926         unsigned int misc : 2;
927         unsigned int targ : 1;
928 #define TRIPLE_SIZE(TRIPLE) \
929         ((TRIPLE)->lhs + (TRIPLE)->rhs + (TRIPLE)->misc + (TRIPLE)->targ)
930 #define TRIPLE_LHS_OFF(PTR)  (0)
931 #define TRIPLE_RHS_OFF(PTR)  (TRIPLE_LHS_OFF(PTR) + (PTR)->lhs)
932 #define TRIPLE_MISC_OFF(PTR) (TRIPLE_RHS_OFF(PTR) + (PTR)->rhs)
933 #define TRIPLE_TARG_OFF(PTR) (TRIPLE_MISC_OFF(PTR) + (PTR)->misc)
934 #define LHS(PTR,INDEX) ((PTR)->param[TRIPLE_LHS_OFF(PTR) + (INDEX)])
935 #define RHS(PTR,INDEX) ((PTR)->param[TRIPLE_RHS_OFF(PTR) + (INDEX)])
936 #define TARG(PTR,INDEX) ((PTR)->param[TRIPLE_TARG_OFF(PTR) + (INDEX)])
937 #define MISC(PTR,INDEX) ((PTR)->param[TRIPLE_MISC_OFF(PTR) + (INDEX)])
938         unsigned id; /* A scratch value and finally the register */
939 #define TRIPLE_FLAG_FLATTENED   (1 << 31)
940 #define TRIPLE_FLAG_PRE_SPLIT   (1 << 30)
941 #define TRIPLE_FLAG_POST_SPLIT  (1 << 29)
942 #define TRIPLE_FLAG_VOLATILE    (1 << 28)
943 #define TRIPLE_FLAG_INLINE      (1 << 27) /* ???? */
944 #define TRIPLE_FLAG_LOCAL       (1 << 26)
945
946 #define TRIPLE_FLAG_COPY TRIPLE_FLAG_VOLATILE
947         struct occurance *occurance;
948         union {
949                 ulong_t cval;
950                 struct bitfield bitfield;
951                 struct block  *block;
952                 void *blob;
953                 struct hash_entry *field;
954                 struct asm_info *ainfo;
955                 struct triple *func;
956                 struct symbol *symbol;
957         } u;
958         struct triple *param[2];
959 };
960
961 struct reg_info {
962         unsigned reg;
963         unsigned regcm;
964 };
965 struct ins_template {
966         struct reg_info lhs[MAX_LHS + 1], rhs[MAX_RHS + 1];
967 };
968
969 struct asm_info {
970         struct ins_template tmpl;
971         char *str;
972 };
973
974 struct block_set {
975         struct block_set *next;
976         struct block *member;
977 };
978 struct block {
979         struct block *work_next;
980         struct triple *first, *last;
981         int edge_count;
982         struct block_set *edges;
983         int users;
984         struct block_set *use;
985         struct block_set *idominates;
986         struct block_set *domfrontier;
987         struct block *idom;
988         struct block_set *ipdominates;
989         struct block_set *ipdomfrontier;
990         struct block *ipdom;
991         int vertex;
992         
993 };
994
995 struct symbol {
996         struct symbol *next;
997         struct hash_entry *ident;
998         struct triple *def;
999         struct type *type;
1000         int scope_depth;
1001 };
1002
1003 struct macro_arg {
1004         struct macro_arg *next;
1005         struct hash_entry *ident;
1006 };
1007 struct macro {
1008         struct hash_entry *ident;
1009         const char *buf;
1010         int buf_len;
1011         struct macro_arg *args;
1012         int argc;
1013 };
1014
1015 struct hash_entry {
1016         struct hash_entry *next;
1017         const char *name;
1018         int name_len;
1019         int tok;
1020         struct macro *sym_define;
1021         struct symbol *sym_label;
1022         struct symbol *sym_tag;
1023         struct symbol *sym_ident;
1024 };
1025
1026 #define HASH_TABLE_SIZE 2048
1027
1028 struct compiler_state {
1029         const char *label_prefix;
1030         const char *ofilename;
1031         unsigned long flags;
1032         unsigned long debug;
1033         unsigned long max_allocation_passes;
1034
1035         size_t include_path_count;
1036         const char **include_paths;
1037
1038         size_t define_count;
1039         const char **defines;
1040
1041         size_t undef_count;
1042         const char **undefs;
1043 };
1044 struct arch_state {
1045         unsigned long features;
1046 };
1047 struct basic_blocks {
1048         struct triple *func;
1049         struct triple *first;
1050         struct block *first_block, *last_block;
1051         int last_vertex;
1052 };
1053 #define MAX_PP_IF_DEPTH 63
1054 struct compile_state {
1055         struct compiler_state *compiler;
1056         struct arch_state *arch;
1057         FILE *output;
1058         FILE *errout;
1059         FILE *dbgout;
1060         struct file_state *file;
1061         struct occurance *last_occurance;
1062         const char *function;
1063         int    token_base;
1064         struct token token[6];
1065         struct hash_entry *hash_table[HASH_TABLE_SIZE];
1066         struct hash_entry *i_switch;
1067         struct hash_entry *i_case;
1068         struct hash_entry *i_continue;
1069         struct hash_entry *i_break;
1070         struct hash_entry *i_default;
1071         struct hash_entry *i_return;
1072         /* Additional hash entries for predefined macros */
1073         struct hash_entry *i_defined;
1074         struct hash_entry *i___VA_ARGS__;
1075         struct hash_entry *i___FILE__;
1076         struct hash_entry *i___LINE__;
1077         /* Additional hash entries for predefined identifiers */
1078         struct hash_entry *i___func__;
1079         /* Additional hash entries for attributes */
1080         struct hash_entry *i_noinline;
1081         struct hash_entry *i_always_inline;
1082         int scope_depth;
1083         unsigned char if_bytes[(MAX_PP_IF_DEPTH + CHAR_BIT -1)/CHAR_BIT];
1084         int if_depth;
1085         int eat_depth, eat_targ;
1086         struct file_state *macro_file;
1087         struct triple *functions;
1088         struct triple *main_function;
1089         struct triple *first;
1090         struct triple *global_pool;
1091         struct basic_blocks bb;
1092         int functions_joined;
1093 };
1094
1095 /* visibility global/local */
1096 /* static/auto duration */
1097 /* typedef, register, inline */
1098 #define STOR_SHIFT         0
1099 #define STOR_MASK     0x001f
1100 /* Visibility */
1101 #define STOR_GLOBAL   0x0001
1102 /* Duration */
1103 #define STOR_PERM     0x0002
1104 /* Definition locality */
1105 #define STOR_NONLOCAL 0x0004  /* The definition is not in this translation unit */
1106 /* Storage specifiers */
1107 #define STOR_AUTO     0x0000
1108 #define STOR_STATIC   0x0002
1109 #define STOR_LOCAL    0x0003
1110 #define STOR_EXTERN   0x0007
1111 #define STOR_INLINE   0x0008
1112 #define STOR_REGISTER 0x0010
1113 #define STOR_TYPEDEF  0x0018
1114
1115 #define QUAL_SHIFT         5
1116 #define QUAL_MASK     0x00e0
1117 #define QUAL_NONE     0x0000
1118 #define QUAL_CONST    0x0020
1119 #define QUAL_VOLATILE 0x0040
1120 #define QUAL_RESTRICT 0x0080
1121
1122 #define TYPE_SHIFT         8
1123 #define TYPE_MASK     0x1f00
1124 #define TYPE_INTEGER(TYPE)    ((((TYPE) >= TYPE_CHAR) && ((TYPE) <= TYPE_ULLONG)) || ((TYPE) == TYPE_ENUM) || ((TYPE) == TYPE_BITFIELD))
1125 #define TYPE_ARITHMETIC(TYPE) ((((TYPE) >= TYPE_CHAR) && ((TYPE) <= TYPE_LDOUBLE)) || ((TYPE) == TYPE_ENUM) || ((TYPE) == TYPE_BITFIELD))
1126 #define TYPE_UNSIGNED(TYPE)   ((TYPE) & 0x0100)
1127 #define TYPE_SIGNED(TYPE)     (!TYPE_UNSIGNED(TYPE))
1128 #define TYPE_MKUNSIGNED(TYPE) (((TYPE) & ~0xF000) | 0x0100)
1129 #define TYPE_RANK(TYPE)       ((TYPE) & ~0xF1FF)
1130 #define TYPE_PTR(TYPE)        (((TYPE) & TYPE_MASK) == TYPE_POINTER)
1131 #define TYPE_DEFAULT  0x0000
1132 #define TYPE_VOID     0x0100
1133 #define TYPE_CHAR     0x0200
1134 #define TYPE_UCHAR    0x0300
1135 #define TYPE_SHORT    0x0400
1136 #define TYPE_USHORT   0x0500
1137 #define TYPE_INT      0x0600
1138 #define TYPE_UINT     0x0700
1139 #define TYPE_LONG     0x0800
1140 #define TYPE_ULONG    0x0900
1141 #define TYPE_LLONG    0x0a00 /* long long */
1142 #define TYPE_ULLONG   0x0b00
1143 #define TYPE_FLOAT    0x0c00
1144 #define TYPE_DOUBLE   0x0d00
1145 #define TYPE_LDOUBLE  0x0e00 /* long double */
1146
1147 /* Note: TYPE_ENUM is chosen very carefully so TYPE_RANK works */
1148 #define TYPE_ENUM     0x1600
1149 #define TYPE_LIST     0x1700
1150 /* TYPE_LIST is a basic building block when defining enumerations
1151  * type->field_ident holds the name of this enumeration entry.
1152  * type->right holds the entry in the list.
1153  */
1154
1155 #define TYPE_STRUCT   0x1000
1156 /* For TYPE_STRUCT
1157  * type->left holds the link list of TYPE_PRODUCT entries that
1158  * make up the structure.
1159  * type->elements hold the length of the linked list
1160  */
1161 #define TYPE_UNION    0x1100
1162 /* For TYPE_UNION
1163  * type->left holds the link list of TYPE_OVERLAP entries that
1164  * make up the union.
1165  * type->elements hold the length of the linked list
1166  */
1167 #define TYPE_POINTER  0x1200 
1168 /* For TYPE_POINTER:
1169  * type->left holds the type pointed to.
1170  */
1171 #define TYPE_FUNCTION 0x1300 
1172 /* For TYPE_FUNCTION:
1173  * type->left holds the return type.
1174  * type->right holds the type of the arguments
1175  * type->elements holds the count of the arguments
1176  */
1177 #define TYPE_PRODUCT  0x1400
1178 /* TYPE_PRODUCT is a basic building block when defining structures
1179  * type->left holds the type that appears first in memory.
1180  * type->right holds the type that appears next in memory.
1181  */
1182 #define TYPE_OVERLAP  0x1500
1183 /* TYPE_OVERLAP is a basic building block when defining unions
1184  * type->left and type->right holds to types that overlap
1185  * each other in memory.
1186  */
1187 #define TYPE_ARRAY    0x1800
1188 /* TYPE_ARRAY is a basic building block when definitng arrays.
1189  * type->left holds the type we are an array of.
1190  * type->elements holds the number of elements.
1191  */
1192 #define TYPE_TUPLE    0x1900
1193 /* TYPE_TUPLE is a basic building block when defining 
1194  * positionally reference type conglomerations. (i.e. closures)
1195  * In essence it is a wrapper for TYPE_PRODUCT, like TYPE_STRUCT
1196  * except it has no field names.
1197  * type->left holds the liked list of TYPE_PRODUCT entries that
1198  * make up the closure type.
1199  * type->elements hold the number of elements in the closure.
1200  */
1201 #define TYPE_JOIN     0x1a00
1202 /* TYPE_JOIN is a basic building block when defining 
1203  * positionally reference type conglomerations. (i.e. closures)
1204  * In essence it is a wrapper for TYPE_OVERLAP, like TYPE_UNION
1205  * except it has no field names.
1206  * type->left holds the liked list of TYPE_OVERLAP entries that
1207  * make up the closure type.
1208  * type->elements hold the number of elements in the closure.
1209  */
1210 #define TYPE_BITFIELD 0x1b00
1211 /* TYPE_BITFIED is the type of a bitfield.
1212  * type->left holds the type basic type TYPE_BITFIELD is derived from.
1213  * type->elements holds the number of bits in the bitfield.
1214  */
1215 #define TYPE_UNKNOWN  0x1c00
1216 /* TYPE_UNKNOWN is the type of an unknown value.
1217  * Used on unknown consts and other places where I don't know the type.
1218  */
1219
1220 #define ATTRIB_SHIFT                 16
1221 #define ATTRIB_MASK          0xffff0000
1222 #define ATTRIB_NOINLINE      0x00010000
1223 #define ATTRIB_ALWAYS_INLINE 0x00020000
1224
1225 #define ELEMENT_COUNT_UNSPECIFIED ULONG_T_MAX
1226
1227 struct type {
1228         unsigned int type;
1229         struct type *left, *right;
1230         ulong_t elements;
1231         struct hash_entry *field_ident;
1232         struct hash_entry *type_ident;
1233 };
1234
1235 #define TEMPLATE_BITS      7
1236 #define MAX_TEMPLATES      (1<<TEMPLATE_BITS)
1237 #define MAX_REG_EQUIVS     16
1238 #define MAX_REGC           14
1239 #define MAX_REGISTERS      75
1240 #define REGISTER_BITS      7
1241 #define MAX_VIRT_REGISTERS (1<<REGISTER_BITS)
1242 #define REG_ERROR          0
1243 #define REG_UNSET          1
1244 #define REG_UNNEEDED       2
1245 #define REG_VIRT0          (MAX_REGISTERS + 0)
1246 #define REG_VIRT1          (MAX_REGISTERS + 1)
1247 #define REG_VIRT2          (MAX_REGISTERS + 2)
1248 #define REG_VIRT3          (MAX_REGISTERS + 3)
1249 #define REG_VIRT4          (MAX_REGISTERS + 4)
1250 #define REG_VIRT5          (MAX_REGISTERS + 5)
1251 #define REG_VIRT6          (MAX_REGISTERS + 6)
1252 #define REG_VIRT7          (MAX_REGISTERS + 7)
1253 #define REG_VIRT8          (MAX_REGISTERS + 8)
1254 #define REG_VIRT9          (MAX_REGISTERS + 9)
1255
1256 #if (MAX_REGISTERS + 9) > MAX_VIRT_REGISTERS
1257 #error "MAX_VIRT_REGISTERS to small"
1258 #endif
1259 #if (MAX_REGC + REGISTER_BITS) >= 26
1260 #error "Too many id bits used"
1261 #endif
1262
1263 /* Provision for 8 register classes */
1264 #define REG_SHIFT  0
1265 #define REGC_SHIFT REGISTER_BITS
1266 #define REGC_MASK (((1 << MAX_REGC) - 1) << REGISTER_BITS)
1267 #define REG_MASK (MAX_VIRT_REGISTERS -1)
1268 #define ID_REG(ID)              ((ID) & REG_MASK)
1269 #define SET_REG(ID, REG)        ((ID) = (((ID) & ~REG_MASK) | ((REG) & REG_MASK)))
1270 #define ID_REGCM(ID)            (((ID) & REGC_MASK) >> REGC_SHIFT)
1271 #define SET_REGCM(ID, REGCM)    ((ID) = (((ID) & ~REGC_MASK) | (((REGCM) << REGC_SHIFT) & REGC_MASK)))
1272 #define SET_INFO(ID, INFO)      ((ID) = (((ID) & ~(REG_MASK | REGC_MASK)) | \
1273                 (((INFO).reg) & REG_MASK) | ((((INFO).regcm) << REGC_SHIFT) & REGC_MASK)))
1274
1275 #define ARCH_INPUT_REGS 4
1276 #define ARCH_OUTPUT_REGS 4
1277
1278 static const struct reg_info arch_input_regs[ARCH_INPUT_REGS];
1279 static const struct reg_info arch_output_regs[ARCH_OUTPUT_REGS];
1280 static unsigned arch_reg_regcm(struct compile_state *state, int reg);
1281 static unsigned arch_regcm_normalize(struct compile_state *state, unsigned regcm);
1282 static unsigned arch_regcm_reg_normalize(struct compile_state *state, unsigned regcm);
1283 static void arch_reg_equivs(
1284         struct compile_state *state, unsigned *equiv, int reg);
1285 static int arch_select_free_register(
1286         struct compile_state *state, char *used, int classes);
1287 static unsigned arch_regc_size(struct compile_state *state, int class);
1288 static int arch_regcm_intersect(unsigned regcm1, unsigned regcm2);
1289 static unsigned arch_type_to_regcm(struct compile_state *state, struct type *type);
1290 static const char *arch_reg_str(int reg);
1291 static struct reg_info arch_reg_constraint(
1292         struct compile_state *state, struct type *type, const char *constraint);
1293 static struct reg_info arch_reg_clobber(
1294         struct compile_state *state, const char *clobber);
1295 static struct reg_info arch_reg_lhs(struct compile_state *state, 
1296         struct triple *ins, int index);
1297 static struct reg_info arch_reg_rhs(struct compile_state *state, 
1298         struct triple *ins, int index);
1299 static int arch_reg_size(int reg);
1300 static struct triple *transform_to_arch_instruction(
1301         struct compile_state *state, struct triple *ins);
1302 static struct triple *flatten(
1303         struct compile_state *state, struct triple *first, struct triple *ptr);
1304 static void print_dominators(struct compile_state *state,
1305         FILE *fp, struct basic_blocks *bb);
1306 static void print_dominance_frontiers(struct compile_state *state,
1307         FILE *fp, struct basic_blocks *bb);
1308
1309
1310
1311 #define DEBUG_ABORT_ON_ERROR    0x00000001
1312 #define DEBUG_BASIC_BLOCKS      0x00000002
1313 #define DEBUG_FDOMINATORS       0x00000004
1314 #define DEBUG_RDOMINATORS       0x00000008
1315 #define DEBUG_TRIPLES           0x00000010
1316 #define DEBUG_INTERFERENCE      0x00000020
1317 #define DEBUG_SCC_TRANSFORM     0x00000040
1318 #define DEBUG_SCC_TRANSFORM2    0x00000080
1319 #define DEBUG_REBUILD_SSA_FORM  0x00000100
1320 #define DEBUG_INLINE            0x00000200
1321 #define DEBUG_RANGE_CONFLICTS   0x00000400
1322 #define DEBUG_RANGE_CONFLICTS2  0x00000800
1323 #define DEBUG_COLOR_GRAPH       0x00001000
1324 #define DEBUG_COLOR_GRAPH2      0x00002000
1325 #define DEBUG_COALESCING        0x00004000
1326 #define DEBUG_COALESCING2       0x00008000
1327 #define DEBUG_VERIFICATION      0x00010000
1328 #define DEBUG_CALLS             0x00020000
1329 #define DEBUG_CALLS2            0x00040000
1330 #define DEBUG_TOKENS            0x80000000
1331
1332 #define DEBUG_DEFAULT ( \
1333         DEBUG_ABORT_ON_ERROR | \
1334         DEBUG_BASIC_BLOCKS | \
1335         DEBUG_FDOMINATORS | \
1336         DEBUG_RDOMINATORS | \
1337         DEBUG_TRIPLES | \
1338         0 )
1339
1340 #define DEBUG_ALL ( \
1341         DEBUG_ABORT_ON_ERROR   | \
1342         DEBUG_BASIC_BLOCKS     | \
1343         DEBUG_FDOMINATORS      | \
1344         DEBUG_RDOMINATORS      | \
1345         DEBUG_TRIPLES          | \
1346         DEBUG_INTERFERENCE     | \
1347         DEBUG_SCC_TRANSFORM    | \
1348         DEBUG_SCC_TRANSFORM2   | \
1349         DEBUG_REBUILD_SSA_FORM | \
1350         DEBUG_INLINE           | \
1351         DEBUG_RANGE_CONFLICTS  | \
1352         DEBUG_RANGE_CONFLICTS2 | \
1353         DEBUG_COLOR_GRAPH      | \
1354         DEBUG_COLOR_GRAPH2     | \
1355         DEBUG_COALESCING       | \
1356         DEBUG_COALESCING2      | \
1357         DEBUG_VERIFICATION     | \
1358         DEBUG_CALLS            | \
1359         DEBUG_CALLS2           | \
1360         DEBUG_TOKENS           | \
1361         0 )
1362
1363 #define COMPILER_INLINE_MASK               0x00000007
1364 #define COMPILER_INLINE_ALWAYS             0x00000000
1365 #define COMPILER_INLINE_NEVER              0x00000001
1366 #define COMPILER_INLINE_DEFAULTON          0x00000002
1367 #define COMPILER_INLINE_DEFAULTOFF         0x00000003
1368 #define COMPILER_INLINE_NOPENALTY          0x00000004
1369 #define COMPILER_ELIMINATE_INEFECTUAL_CODE 0x00000008
1370 #define COMPILER_SIMPLIFY                  0x00000010
1371 #define COMPILER_SCC_TRANSFORM             0x00000020
1372 #define COMPILER_SIMPLIFY_OP               0x00000040
1373 #define COMPILER_SIMPLIFY_PHI              0x00000080
1374 #define COMPILER_SIMPLIFY_LABEL            0x00000100
1375 #define COMPILER_SIMPLIFY_BRANCH           0x00000200
1376 #define COMPILER_SIMPLIFY_COPY             0x00000400
1377 #define COMPILER_SIMPLIFY_ARITH            0x00000800
1378 #define COMPILER_SIMPLIFY_SHIFT            0x00001000
1379 #define COMPILER_SIMPLIFY_BITWISE          0x00002000
1380 #define COMPILER_SIMPLIFY_LOGICAL          0x00004000
1381 #define COMPILER_SIMPLIFY_BITFIELD         0x00008000
1382
1383 #define COMPILER_TRIGRAPHS                 0x40000000
1384 #define COMPILER_PP_ONLY                   0x80000000
1385
1386 #define COMPILER_DEFAULT_FLAGS ( \
1387         COMPILER_TRIGRAPHS | \
1388         COMPILER_ELIMINATE_INEFECTUAL_CODE | \
1389         COMPILER_INLINE_DEFAULTON | \
1390         COMPILER_SIMPLIFY_OP | \
1391         COMPILER_SIMPLIFY_PHI | \
1392         COMPILER_SIMPLIFY_LABEL | \
1393         COMPILER_SIMPLIFY_BRANCH | \
1394         COMPILER_SIMPLIFY_COPY | \
1395         COMPILER_SIMPLIFY_ARITH | \
1396         COMPILER_SIMPLIFY_SHIFT | \
1397         COMPILER_SIMPLIFY_BITWISE | \
1398         COMPILER_SIMPLIFY_LOGICAL | \
1399         COMPILER_SIMPLIFY_BITFIELD | \
1400         0 )
1401
1402 #define GLOBAL_SCOPE_DEPTH   1
1403 #define FUNCTION_SCOPE_DEPTH (GLOBAL_SCOPE_DEPTH + 1)
1404
1405 static void compile_file(struct compile_state *old_state, const char *filename, int local);
1406
1407
1408
1409 static void init_compiler_state(struct compiler_state *compiler)
1410 {
1411         memset(compiler, 0, sizeof(*compiler));
1412         compiler->label_prefix = "";
1413         compiler->ofilename = "auto.inc";
1414         compiler->flags = COMPILER_DEFAULT_FLAGS;
1415         compiler->debug = 0;
1416         compiler->max_allocation_passes = MAX_ALLOCATION_PASSES;
1417         compiler->include_path_count = 1;
1418         compiler->include_paths      = xcmalloc(sizeof(char *), "include_paths");
1419         compiler->define_count       = 1;
1420         compiler->defines            = xcmalloc(sizeof(char *), "defines");
1421         compiler->undef_count        = 1;
1422         compiler->undefs             = xcmalloc(sizeof(char *), "undefs");
1423 }
1424
1425 struct compiler_flag {
1426         const char *name;
1427         unsigned long flag;
1428 };
1429
1430 struct compiler_arg {
1431         const char *name;
1432         unsigned long mask;
1433         struct compiler_flag flags[16];
1434 };
1435
1436 static int set_flag(
1437         const struct compiler_flag *ptr, unsigned long *flags,
1438         int act, const char *flag)
1439 {
1440         int result = -1;
1441         for(; ptr->name; ptr++) {
1442                 if (strcmp(ptr->name, flag) == 0) {
1443                         break;
1444                 }
1445         }
1446         if (ptr->name) {
1447                 result = 0;
1448                 *flags &= ~(ptr->flag);
1449                 if (act) {
1450                         *flags |= ptr->flag;
1451                 }
1452         }
1453         return result;
1454 }
1455
1456 static int set_arg(
1457         const struct compiler_arg *ptr, unsigned long *flags, const char *arg)
1458 {
1459         const char *val;
1460         int result = -1;
1461         int len;
1462         val = strchr(arg, '=');
1463         if (val) {
1464                 len = val - arg;
1465                 val++;
1466                 for(; ptr->name; ptr++) {
1467                         if (strncmp(ptr->name, arg, len) == 0) {
1468                                 break;
1469                         }
1470                 }
1471                 if (ptr->name) {
1472                         *flags &= ~ptr->mask;
1473                         result = set_flag(&ptr->flags[0], flags, 1, val);
1474                 }
1475         }
1476         return result;
1477 }
1478         
1479
1480 static void flag_usage(FILE *fp, const struct compiler_flag *ptr, 
1481         const char *prefix, const char *invert_prefix)
1482 {
1483         for(;ptr->name; ptr++) {
1484                 fprintf(fp, "%s%s\n", prefix, ptr->name);
1485                 if (invert_prefix) {
1486                         fprintf(fp, "%s%s\n", invert_prefix, ptr->name);
1487                 }
1488         }
1489 }
1490
1491 static void arg_usage(FILE *fp, const struct compiler_arg *ptr,
1492         const char *prefix)
1493 {
1494         for(;ptr->name; ptr++) {
1495                 const struct compiler_flag *flag;
1496                 for(flag = &ptr->flags[0]; flag->name; flag++) {
1497                         fprintf(fp, "%s%s=%s\n", 
1498                                 prefix, ptr->name, flag->name);
1499                 }
1500         }
1501 }
1502
1503 static int append_string(size_t *max, const char ***vec, const char *str,
1504         const char *name)
1505 {
1506         size_t count;
1507         count = ++(*max);
1508         *vec = xrealloc(*vec, sizeof(char *)*count, "name");
1509         (*vec)[count -1] = 0;
1510         (*vec)[count -2] = str; 
1511         return 0;
1512 }
1513
1514 static void arg_error(char *fmt, ...);
1515 static const char *identifier(const char *str, const char *end);
1516
1517 static int append_include_path(struct compiler_state *compiler, const char *str)
1518 {
1519         int result;
1520         if (!exists(str, ".")) {
1521                 arg_error("Nonexistent include path: `%s'\n",
1522                         str);
1523         }
1524         result = append_string(&compiler->include_path_count,
1525                 &compiler->include_paths, str, "include_paths");
1526         return result;
1527 }
1528
1529 static int append_define(struct compiler_state *compiler, const char *str)
1530 {
1531         const char *end, *rest;
1532         int result;
1533
1534         end = strchr(str, '=');
1535         if (!end) {
1536                 end = str + strlen(str);
1537         }
1538         rest = identifier(str, end);
1539         if (rest != end) {
1540                 int len = end - str - 1;
1541                 arg_error("Invalid name cannot define macro: `%*.*s'\n", 
1542                         len, len, str);
1543         }
1544         result = append_string(&compiler->define_count,
1545                 &compiler->defines, str, "defines");
1546         return result;
1547 }
1548
1549 static int append_undef(struct compiler_state *compiler, const char *str)
1550 {
1551         const char *end, *rest;
1552         int result;
1553
1554         end = str + strlen(str);
1555         rest = identifier(str, end);
1556         if (rest != end) {
1557                 int len = end - str - 1;
1558                 arg_error("Invalid name cannot undefine macro: `%*.*s'\n", 
1559                         len, len, str);
1560         }
1561         result = append_string(&compiler->undef_count,
1562                 &compiler->undefs, str, "undefs");
1563         return result;
1564 }
1565
1566 static const struct compiler_flag romcc_flags[] = {
1567         { "trigraphs",                 COMPILER_TRIGRAPHS },
1568         { "pp-only",                   COMPILER_PP_ONLY },
1569         { "eliminate-inefectual-code", COMPILER_ELIMINATE_INEFECTUAL_CODE },
1570         { "simplify",                  COMPILER_SIMPLIFY },
1571         { "scc-transform",             COMPILER_SCC_TRANSFORM },
1572         { "simplify-op",               COMPILER_SIMPLIFY_OP },
1573         { "simplify-phi",              COMPILER_SIMPLIFY_PHI },
1574         { "simplify-label",            COMPILER_SIMPLIFY_LABEL },
1575         { "simplify-branch",           COMPILER_SIMPLIFY_BRANCH },
1576         { "simplify-copy",             COMPILER_SIMPLIFY_COPY },
1577         { "simplify-arith",            COMPILER_SIMPLIFY_ARITH },
1578         { "simplify-shift",            COMPILER_SIMPLIFY_SHIFT },
1579         { "simplify-bitwise",          COMPILER_SIMPLIFY_BITWISE },
1580         { "simplify-logical",          COMPILER_SIMPLIFY_LOGICAL },
1581         { "simplify-bitfield",         COMPILER_SIMPLIFY_BITFIELD },
1582         { 0, 0 },
1583 };
1584 static const struct compiler_arg romcc_args[] = {
1585         { "inline-policy",             COMPILER_INLINE_MASK,
1586                 {
1587                         { "always",      COMPILER_INLINE_ALWAYS, },
1588                         { "never",       COMPILER_INLINE_NEVER, },
1589                         { "defaulton",   COMPILER_INLINE_DEFAULTON, },
1590                         { "defaultoff",  COMPILER_INLINE_DEFAULTOFF, },
1591                         { "nopenalty",   COMPILER_INLINE_NOPENALTY, },
1592                         { 0, 0 },
1593                 },
1594         },
1595         { 0, 0 },
1596 };
1597 static const struct compiler_flag romcc_opt_flags[] = {
1598         { "-O",  COMPILER_SIMPLIFY },
1599         { "-O2", COMPILER_SIMPLIFY | COMPILER_SCC_TRANSFORM },
1600         { "-E",  COMPILER_PP_ONLY },
1601         { 0, 0, },
1602 };
1603 static const struct compiler_flag romcc_debug_flags[] = {
1604         { "all",                   DEBUG_ALL },
1605         { "abort-on-error",        DEBUG_ABORT_ON_ERROR },
1606         { "basic-blocks",          DEBUG_BASIC_BLOCKS },
1607         { "fdominators",           DEBUG_FDOMINATORS },
1608         { "rdominators",           DEBUG_RDOMINATORS },
1609         { "triples",               DEBUG_TRIPLES },
1610         { "interference",          DEBUG_INTERFERENCE },
1611         { "scc-transform",         DEBUG_SCC_TRANSFORM },
1612         { "scc-transform2",        DEBUG_SCC_TRANSFORM2 },
1613         { "rebuild-ssa-form",      DEBUG_REBUILD_SSA_FORM },
1614         { "inline",                DEBUG_INLINE },
1615         { "live-range-conflicts",  DEBUG_RANGE_CONFLICTS },
1616         { "live-range-conflicts2", DEBUG_RANGE_CONFLICTS2 },
1617         { "color-graph",           DEBUG_COLOR_GRAPH },
1618         { "color-graph2",          DEBUG_COLOR_GRAPH2 },
1619         { "coalescing",            DEBUG_COALESCING },
1620         { "coalescing2",           DEBUG_COALESCING2 },
1621         { "verification",          DEBUG_VERIFICATION },
1622         { "calls",                 DEBUG_CALLS },
1623         { "calls2",                DEBUG_CALLS2 },
1624         { "tokens",                DEBUG_TOKENS },
1625         { 0, 0 },
1626 };
1627
1628 static int compiler_encode_flag(
1629         struct compiler_state *compiler, const char *flag)
1630 {
1631         int act;
1632         int result;
1633
1634         act = 1;
1635         result = -1;
1636         if (strncmp(flag, "no-", 3) == 0) {
1637                 flag += 3;
1638                 act = 0;
1639         }
1640         if (strncmp(flag, "-O", 2) == 0) {
1641                 result = set_flag(romcc_opt_flags, &compiler->flags, act, flag);
1642         }
1643         else if (strncmp(flag, "-E", 2) == 0) {
1644                 result = set_flag(romcc_opt_flags, &compiler->flags, act, flag);
1645         }
1646         else if (strncmp(flag, "-I", 2) == 0) {
1647                 result = append_include_path(compiler, flag + 2);
1648         }
1649         else if (strncmp(flag, "-D", 2) == 0) {
1650                 result = append_define(compiler, flag + 2);
1651         }
1652         else if (strncmp(flag, "-U", 2) == 0) {
1653                 result = append_undef(compiler, flag + 2);
1654         }
1655         else if (act && strncmp(flag, "label-prefix=", 13) == 0) {
1656                 result = 0;
1657                 compiler->label_prefix = flag + 13;
1658         }
1659         else if (act && strncmp(flag, "max-allocation-passes=", 22) == 0) {
1660                 unsigned long max_passes;
1661                 char *end;
1662                 max_passes = strtoul(flag + 22, &end, 10);
1663                 if (end[0] == '\0') {
1664                         result = 0;
1665                         compiler->max_allocation_passes = max_passes;
1666                 }
1667         }
1668         else if (act && strcmp(flag, "debug") == 0) {
1669                 result = 0;
1670                 compiler->debug |= DEBUG_DEFAULT;
1671         }
1672         else if (strncmp(flag, "debug-", 6) == 0) {
1673                 flag += 6;
1674                 result = set_flag(romcc_debug_flags, &compiler->debug, act, flag);
1675         }
1676         else {
1677                 result = set_flag(romcc_flags, &compiler->flags, act, flag);
1678                 if (result < 0) {
1679                         result = set_arg(romcc_args, &compiler->flags, flag);
1680                 }
1681         }
1682         return result;
1683 }
1684
1685 static void compiler_usage(FILE *fp)
1686 {
1687         flag_usage(fp, romcc_opt_flags, "", 0);
1688         flag_usage(fp, romcc_flags, "-f", "-fno-");
1689         arg_usage(fp,  romcc_args, "-f");
1690         flag_usage(fp, romcc_debug_flags, "-fdebug-", "-fno-debug-");
1691         fprintf(fp, "-flabel-prefix=<prefix for assembly language labels>\n");
1692         fprintf(fp, "--label-prefix=<prefix for assembly language labels>\n");
1693         fprintf(fp, "-I<include path>\n");
1694         fprintf(fp, "-D<macro>[=defn]\n");
1695         fprintf(fp, "-U<macro>\n");
1696 }
1697
1698 static void do_cleanup(struct compile_state *state)
1699 {
1700         if (state->output) {
1701                 fclose(state->output);
1702                 unlink(state->compiler->ofilename);
1703                 state->output = 0;
1704         }
1705         if (state->dbgout) {
1706                 fflush(state->dbgout);
1707         }
1708         if (state->errout) {
1709                 fflush(state->errout);
1710         }
1711 }
1712
1713 static struct compile_state *exit_state;
1714 static void exit_cleanup(void)
1715 {
1716         if (exit_state) {
1717                 do_cleanup(exit_state);
1718         }
1719 }
1720
1721 static int get_col(struct file_state *file)
1722 {
1723         int col;
1724         const char *ptr, *end;
1725         ptr = file->line_start;
1726         end = file->pos;
1727         for(col = 0; ptr < end; ptr++) {
1728                 if (*ptr != '\t') {
1729                         col++;
1730                 } 
1731                 else {
1732                         col = (col & ~7) + 8;
1733                 }
1734         }
1735         return col;
1736 }
1737
1738 static void loc(FILE *fp, struct compile_state *state, struct triple *triple)
1739 {
1740         int col;
1741         if (triple && triple->occurance) {
1742                 struct occurance *spot;
1743                 for(spot = triple->occurance; spot; spot = spot->parent) {
1744                         fprintf(fp, "%s:%d.%d: ", 
1745                                 spot->filename, spot->line, spot->col);
1746                 }
1747                 return;
1748         }
1749         if (!state->file) {
1750                 return;
1751         }
1752         col = get_col(state->file);
1753         fprintf(fp, "%s:%d.%d: ", 
1754                 state->file->report_name, state->file->report_line, col);
1755 }
1756
1757 static void internal_error(struct compile_state *state, struct triple *ptr, 
1758         const char *fmt, ...)
1759 {
1760         FILE *fp = state->errout;
1761         va_list args;
1762         va_start(args, fmt);
1763         loc(fp, state, ptr);
1764         fputc('\n', fp);
1765         if (ptr) {
1766                 fprintf(fp, "%p %-10s ", ptr, tops(ptr->op));
1767         }
1768         fprintf(fp, "Internal compiler error: ");
1769         vfprintf(fp, fmt, args);
1770         fprintf(fp, "\n");
1771         va_end(args);
1772         do_cleanup(state);
1773         abort();
1774 }
1775
1776
1777 static void internal_warning(struct compile_state *state, struct triple *ptr, 
1778         const char *fmt, ...)
1779 {
1780         FILE *fp = state->errout;
1781         va_list args;
1782         va_start(args, fmt);
1783         loc(fp, state, ptr);
1784         if (ptr) {
1785                 fprintf(fp, "%p %-10s ", ptr, tops(ptr->op));
1786         }
1787         fprintf(fp, "Internal compiler warning: ");
1788         vfprintf(fp, fmt, args);
1789         fprintf(fp, "\n");
1790         va_end(args);
1791 }
1792
1793
1794
1795 static void error(struct compile_state *state, struct triple *ptr, 
1796         const char *fmt, ...)
1797 {
1798         FILE *fp = state->errout;
1799         va_list args;
1800         va_start(args, fmt);
1801         loc(fp, state, ptr);
1802         fputc('\n', fp);
1803         if (ptr && (state->compiler->debug & DEBUG_ABORT_ON_ERROR)) {
1804                 fprintf(fp, "%p %-10s ", ptr, tops(ptr->op));
1805         }
1806         vfprintf(fp, fmt, args);
1807         va_end(args);
1808         fprintf(fp, "\n");
1809         do_cleanup(state);
1810         if (state->compiler->debug & DEBUG_ABORT_ON_ERROR) {
1811                 abort();
1812         }
1813         exit(1);
1814 }
1815
1816 static void warning(struct compile_state *state, struct triple *ptr, 
1817         const char *fmt, ...)
1818 {
1819         FILE *fp = state->errout;
1820         va_list args;
1821         va_start(args, fmt);
1822         loc(fp, state, ptr);
1823         fprintf(fp, "warning: "); 
1824         if (ptr && (state->compiler->debug & DEBUG_ABORT_ON_ERROR)) {
1825                 fprintf(fp, "%p %-10s ", ptr, tops(ptr->op));
1826         }
1827         vfprintf(fp, fmt, args);
1828         fprintf(fp, "\n");
1829         va_end(args);
1830 }
1831
1832 #define FINISHME() warning(state, 0, "FINISHME @ %s.%s:%d", __FILE__, __func__, __LINE__)
1833
1834 static void valid_op(struct compile_state *state, int op)
1835 {
1836         char *fmt = "invalid op: %d";
1837         if (op >= OP_MAX) {
1838                 internal_error(state, 0, fmt, op);
1839         }
1840         if (op < 0) {
1841                 internal_error(state, 0, fmt, op);
1842         }
1843 }
1844
1845 static void valid_ins(struct compile_state *state, struct triple *ptr)
1846 {
1847         valid_op(state, ptr->op);
1848 }
1849
1850 static void valid_param_count(struct compile_state *state, struct triple *ins)
1851 {
1852         int lhs, rhs, misc, targ;
1853         valid_ins(state, ins);
1854         lhs  = table_ops[ins->op].lhs;
1855         rhs  = table_ops[ins->op].rhs;
1856         misc = table_ops[ins->op].misc;
1857         targ = table_ops[ins->op].targ;
1858
1859         if ((lhs >= 0) && (ins->lhs != lhs)) {
1860                 internal_error(state, ins, "Bad lhs count");
1861         }
1862         if ((rhs >= 0) && (ins->rhs != rhs)) {
1863                 internal_error(state, ins, "Bad rhs count");
1864         }
1865         if ((misc >= 0) && (ins->misc != misc)) {
1866                 internal_error(state, ins, "Bad misc count");
1867         }
1868         if ((targ >= 0) && (ins->targ != targ)) {
1869                 internal_error(state, ins, "Bad targ count");
1870         }
1871 }
1872
1873 static struct type void_type;
1874 static struct type unknown_type;
1875 static void use_triple(struct triple *used, struct triple *user)
1876 {
1877         struct triple_set **ptr, *new;
1878         if (!used)
1879                 return;
1880         if (!user)
1881                 return;
1882         ptr = &used->use;
1883         while(*ptr) {
1884                 if ((*ptr)->member == user) {
1885                         return;
1886                 }
1887                 ptr = &(*ptr)->next;
1888         }
1889         /* Append new to the head of the list, 
1890          * copy_func and rename_block_variables
1891          * depends on this.
1892          */
1893         new = xcmalloc(sizeof(*new), "triple_set");
1894         new->member = user;
1895         new->next   = used->use;
1896         used->use   = new;
1897 }
1898
1899 static void unuse_triple(struct triple *used, struct triple *unuser)
1900 {
1901         struct triple_set *use, **ptr;
1902         if (!used) {
1903                 return;
1904         }
1905         ptr = &used->use;
1906         while(*ptr) {
1907                 use = *ptr;
1908                 if (use->member == unuser) {
1909                         *ptr = use->next;
1910                         xfree(use);
1911                 }
1912                 else {
1913                         ptr = &use->next;
1914                 }
1915         }
1916 }
1917
1918 static void put_occurance(struct occurance *occurance)
1919 {
1920         if (occurance) {
1921                 occurance->count -= 1;
1922                 if (occurance->count <= 0) {
1923                         if (occurance->parent) {
1924                                 put_occurance(occurance->parent);
1925                         }
1926                         xfree(occurance);
1927                 }
1928         }
1929 }
1930
1931 static void get_occurance(struct occurance *occurance)
1932 {
1933         if (occurance) {
1934                 occurance->count += 1;
1935         }
1936 }
1937
1938
1939 static struct occurance *new_occurance(struct compile_state *state)
1940 {
1941         struct occurance *result, *last;
1942         const char *filename;
1943         const char *function;
1944         int line, col;
1945
1946         function = "";
1947         filename = 0;
1948         line = 0;
1949         col  = 0;
1950         if (state->file) {
1951                 filename = state->file->report_name;
1952                 line     = state->file->report_line;
1953                 col      = get_col(state->file);
1954         }
1955         if (state->function) {
1956                 function = state->function;
1957         }
1958         last = state->last_occurance;
1959         if (last &&
1960                 (last->col == col) &&
1961                 (last->line == line) &&
1962                 (last->function == function) &&
1963                 ((last->filename == filename) ||
1964                         (strcmp(last->filename, filename) == 0))) 
1965         {
1966                 get_occurance(last);
1967                 return last;
1968         }
1969         if (last) {
1970                 state->last_occurance = 0;
1971                 put_occurance(last);
1972         }
1973         result = xmalloc(sizeof(*result), "occurance");
1974         result->count    = 2;
1975         result->filename = filename;
1976         result->function = function;
1977         result->line     = line;
1978         result->col      = col;
1979         result->parent   = 0;
1980         state->last_occurance = result;
1981         return result;
1982 }
1983
1984 static struct occurance *inline_occurance(struct compile_state *state,
1985         struct occurance *base, struct occurance *top)
1986 {
1987         struct occurance *result, *last;
1988         if (top->parent) {
1989                 internal_error(state, 0, "inlining an already inlined function?");
1990         }
1991         /* If I have a null base treat it that way */
1992         if ((base->parent == 0) &&
1993                 (base->col == 0) &&
1994                 (base->line == 0) &&
1995                 (base->function[0] == '\0') &&
1996                 (base->filename[0] == '\0')) {
1997                 base = 0;
1998         }
1999         /* See if I can reuse the last occurance I had */
2000         last = state->last_occurance;
2001         if (last &&
2002                 (last->parent   == base) &&
2003                 (last->col      == top->col) &&
2004                 (last->line     == top->line) &&
2005                 (last->function == top->function) &&
2006                 (last->filename == top->filename)) {
2007                 get_occurance(last);
2008                 return last;
2009         }
2010         /* I can't reuse the last occurance so free it */
2011         if (last) {
2012                 state->last_occurance = 0;
2013                 put_occurance(last);
2014         }
2015         /* Generate a new occurance structure */
2016         get_occurance(base);
2017         result = xmalloc(sizeof(*result), "occurance");
2018         result->count    = 2;
2019         result->filename = top->filename;
2020         result->function = top->function;
2021         result->line     = top->line;
2022         result->col      = top->col;
2023         result->parent   = base;
2024         state->last_occurance = result;
2025         return result;
2026 }
2027
2028 static struct occurance dummy_occurance = {
2029         .count    = 2,
2030         .filename = __FILE__,
2031         .function = "",
2032         .line     = __LINE__,
2033         .col      = 0,
2034         .parent   = 0,
2035 };
2036
2037 /* The undef triple is used as a place holder when we are removing pointers
2038  * from a triple.  Having allows certain sanity checks to pass even
2039  * when the original triple that was pointed to is gone.
2040  */
2041 static struct triple unknown_triple = {
2042         .next      = &unknown_triple,
2043         .prev      = &unknown_triple,
2044         .use       = 0,
2045         .op        = OP_UNKNOWNVAL,
2046         .lhs       = 0,
2047         .rhs       = 0,
2048         .misc      = 0,
2049         .targ      = 0,
2050         .type      = &unknown_type,
2051         .id        = -1, /* An invalid id */
2052         .u = { .cval = 0, },
2053         .occurance = &dummy_occurance,
2054         .param = { [0] = 0, [1] = 0, },
2055 };
2056
2057
2058 static size_t registers_of(struct compile_state *state, struct type *type);
2059
2060 static struct triple *alloc_triple(struct compile_state *state, 
2061         int op, struct type *type, int lhs_wanted, int rhs_wanted,
2062         struct occurance *occurance)
2063 {
2064         size_t size, extra_count, min_count;
2065         int lhs, rhs, misc, targ;
2066         struct triple *ret, dummy;
2067         dummy.op = op;
2068         dummy.occurance = occurance;
2069         valid_op(state, op);
2070         lhs = table_ops[op].lhs;
2071         rhs = table_ops[op].rhs;
2072         misc = table_ops[op].misc;
2073         targ = table_ops[op].targ;
2074
2075         switch(op) {
2076         case OP_FCALL:
2077                 rhs = rhs_wanted;
2078                 break;
2079         case OP_PHI:
2080                 rhs = rhs_wanted;
2081                 break;
2082         case OP_ADECL:
2083                 lhs = registers_of(state, type);
2084                 break;
2085         case OP_TUPLE:
2086                 lhs = registers_of(state, type);
2087                 break;
2088         case OP_ASM:
2089                 rhs = rhs_wanted;
2090                 lhs = lhs_wanted;
2091                 break;
2092         }
2093         if ((rhs < 0) || (rhs > MAX_RHS)) {
2094                 internal_error(state, &dummy, "bad rhs count %d", rhs);
2095         }
2096         if ((lhs < 0) || (lhs > MAX_LHS)) {
2097                 internal_error(state, &dummy, "bad lhs count %d", lhs);
2098         }
2099         if ((misc < 0) || (misc > MAX_MISC)) {
2100                 internal_error(state, &dummy, "bad misc count %d", misc);
2101         }
2102         if ((targ < 0) || (targ > MAX_TARG)) {
2103                 internal_error(state, &dummy, "bad targs count %d", targ);
2104         }
2105
2106         min_count = sizeof(ret->param)/sizeof(ret->param[0]);
2107         extra_count = lhs + rhs + misc + targ;
2108         extra_count = (extra_count < min_count)? 0 : extra_count - min_count;
2109
2110         size = sizeof(*ret) + sizeof(ret->param[0]) * extra_count;
2111         ret = xcmalloc(size, "tripple");
2112         ret->op        = op;
2113         ret->lhs       = lhs;
2114         ret->rhs       = rhs;
2115         ret->misc      = misc;
2116         ret->targ      = targ;
2117         ret->type      = type;
2118         ret->next      = ret;
2119         ret->prev      = ret;
2120         ret->occurance = occurance;
2121         /* A simple sanity check */
2122         if ((ret->op != op) ||
2123                 (ret->lhs != lhs) ||
2124                 (ret->rhs != rhs) ||
2125                 (ret->misc != misc) ||
2126                 (ret->targ != targ) ||
2127                 (ret->type != type) ||
2128                 (ret->next != ret) ||
2129                 (ret->prev != ret) ||
2130                 (ret->occurance != occurance)) {
2131                 internal_error(state, ret, "huh?");
2132         }
2133         return ret;
2134 }
2135
2136 struct triple *dup_triple(struct compile_state *state, struct triple *src)
2137 {
2138         struct triple *dup;
2139         int src_lhs, src_rhs, src_size;
2140         src_lhs = src->lhs;
2141         src_rhs = src->rhs;
2142         src_size = TRIPLE_SIZE(src);
2143         get_occurance(src->occurance);
2144         dup = alloc_triple(state, src->op, src->type, src_lhs, src_rhs,
2145                 src->occurance);
2146         memcpy(dup, src, sizeof(*src));
2147         memcpy(dup->param, src->param, src_size * sizeof(src->param[0]));
2148         return dup;
2149 }
2150
2151 static struct triple *copy_triple(struct compile_state *state, struct triple *src)
2152 {
2153         struct triple *copy;
2154         copy = dup_triple(state, src);
2155         copy->use = 0;
2156         copy->next = copy->prev = copy;
2157         return copy;
2158 }
2159
2160 static struct triple *new_triple(struct compile_state *state, 
2161         int op, struct type *type, int lhs, int rhs)
2162 {
2163         struct triple *ret;
2164         struct occurance *occurance;
2165         occurance = new_occurance(state);
2166         ret = alloc_triple(state, op, type, lhs, rhs, occurance);
2167         return ret;
2168 }
2169
2170 static struct triple *build_triple(struct compile_state *state, 
2171         int op, struct type *type, struct triple *left, struct triple *right,
2172         struct occurance *occurance)
2173 {
2174         struct triple *ret;
2175         size_t count;
2176         ret = alloc_triple(state, op, type, -1, -1, occurance);
2177         count = TRIPLE_SIZE(ret);
2178         if (count > 0) {
2179                 ret->param[0] = left;
2180         }
2181         if (count > 1) {
2182                 ret->param[1] = right;
2183         }
2184         return ret;
2185 }
2186
2187 static struct triple *triple(struct compile_state *state, 
2188         int op, struct type *type, struct triple *left, struct triple *right)
2189 {
2190         struct triple *ret;
2191         size_t count;
2192         ret = new_triple(state, op, type, -1, -1);
2193         count = TRIPLE_SIZE(ret);
2194         if (count >= 1) {
2195                 ret->param[0] = left;
2196         }
2197         if (count >= 2) {
2198                 ret->param[1] = right;
2199         }
2200         return ret;
2201 }
2202
2203 static struct triple *branch(struct compile_state *state, 
2204         struct triple *targ, struct triple *test)
2205 {
2206         struct triple *ret;
2207         if (test) {
2208                 ret = new_triple(state, OP_CBRANCH, &void_type, -1, 1);
2209                 RHS(ret, 0) = test;
2210         } else {
2211                 ret = new_triple(state, OP_BRANCH, &void_type, -1, 0);
2212         }
2213         TARG(ret, 0) = targ;
2214         /* record the branch target was used */
2215         if (!targ || (targ->op != OP_LABEL)) {
2216                 internal_error(state, 0, "branch not to label");
2217         }
2218         return ret;
2219 }
2220
2221 static int triple_is_label(struct compile_state *state, struct triple *ins);
2222 static int triple_is_call(struct compile_state *state, struct triple *ins);
2223 static int triple_is_cbranch(struct compile_state *state, struct triple *ins);
2224 static void insert_triple(struct compile_state *state,
2225         struct triple *first, struct triple *ptr)
2226 {
2227         if (ptr) {
2228                 if ((ptr->id & TRIPLE_FLAG_FLATTENED) || (ptr->next != ptr)) {
2229                         internal_error(state, ptr, "expression already used");
2230                 }
2231                 ptr->next       = first;
2232                 ptr->prev       = first->prev;
2233                 ptr->prev->next = ptr;
2234                 ptr->next->prev = ptr;
2235
2236                 if (triple_is_cbranch(state, ptr->prev) ||
2237                         triple_is_call(state, ptr->prev)) {
2238                         unuse_triple(first, ptr->prev);
2239                         use_triple(ptr, ptr->prev);
2240                 }
2241         }
2242 }
2243
2244 static int triple_stores_block(struct compile_state *state, struct triple *ins)
2245 {
2246         /* This function is used to determine if u.block 
2247          * is utilized to store the current block number.
2248          */
2249         int stores_block;
2250         valid_ins(state, ins);
2251         stores_block = (table_ops[ins->op].flags & BLOCK) == BLOCK;
2252         return stores_block;
2253 }
2254
2255 static int triple_is_branch(struct compile_state *state, struct triple *ins);
2256 static struct block *block_of_triple(struct compile_state *state, 
2257         struct triple *ins)
2258 {
2259         struct triple *first;
2260         if (!ins || ins == &unknown_triple) {
2261                 return 0;
2262         }
2263         first = state->first;
2264         while(ins != first && !triple_is_branch(state, ins->prev) &&
2265                 !triple_stores_block(state, ins)) 
2266         { 
2267                 if (ins == ins->prev) {
2268                         internal_error(state, ins, "ins == ins->prev?");
2269                 }
2270                 ins = ins->prev;
2271         }
2272         return triple_stores_block(state, ins)? ins->u.block: 0;
2273 }
2274
2275 static void generate_lhs_pieces(struct compile_state *state, struct triple *ins);
2276 static struct triple *pre_triple(struct compile_state *state,
2277         struct triple *base,
2278         int op, struct type *type, struct triple *left, struct triple *right)
2279 {
2280         struct block *block;
2281         struct triple *ret;
2282         int i;
2283         /* If I am an OP_PIECE jump to the real instruction */
2284         if (base->op == OP_PIECE) {
2285                 base = MISC(base, 0);
2286         }
2287         block = block_of_triple(state, base);
2288         get_occurance(base->occurance);
2289         ret = build_triple(state, op, type, left, right, base->occurance);
2290         generate_lhs_pieces(state, ret);
2291         if (triple_stores_block(state, ret)) {
2292                 ret->u.block = block;
2293         }
2294         insert_triple(state, base, ret);
2295         for(i = 0; i < ret->lhs; i++) {
2296                 struct triple *piece;
2297                 piece = LHS(ret, i);
2298                 insert_triple(state, base, piece);
2299                 use_triple(ret, piece);
2300                 use_triple(piece, ret);
2301         }
2302         if (block && (block->first == base)) {
2303                 block->first = ret;
2304         }
2305         return ret;
2306 }
2307
2308 static struct triple *post_triple(struct compile_state *state,
2309         struct triple *base,
2310         int op, struct type *type, struct triple *left, struct triple *right)
2311 {
2312         struct block *block;
2313         struct triple *ret, *next;
2314         int zlhs, i;
2315         /* If I am an OP_PIECE jump to the real instruction */
2316         if (base->op == OP_PIECE) {
2317                 base = MISC(base, 0);
2318         }
2319         /* If I have a left hand side skip over it */
2320         zlhs = base->lhs;
2321         if (zlhs) {
2322                 base = LHS(base, zlhs - 1);
2323         }
2324
2325         block = block_of_triple(state, base);
2326         get_occurance(base->occurance);
2327         ret = build_triple(state, op, type, left, right, base->occurance);
2328         generate_lhs_pieces(state, ret);
2329         if (triple_stores_block(state, ret)) {
2330                 ret->u.block = block;
2331         }
2332         next = base->next;
2333         insert_triple(state, next, ret);
2334         zlhs = ret->lhs;
2335         for(i = 0; i < zlhs; i++) {
2336                 struct triple *piece;
2337                 piece = LHS(ret, i);
2338                 insert_triple(state, next, piece);
2339                 use_triple(ret, piece);
2340                 use_triple(piece, ret);
2341         }
2342         if (block && (block->last == base)) {
2343                 block->last = ret;
2344                 if (zlhs) {
2345                         block->last = LHS(ret, zlhs - 1);
2346                 }
2347         }
2348         return ret;
2349 }
2350
2351 static struct type *reg_type(
2352         struct compile_state *state, struct type *type, int reg);
2353
2354 static void generate_lhs_piece(
2355         struct compile_state *state, struct triple *ins, int index)
2356 {
2357         struct type *piece_type;
2358         struct triple *piece;
2359         get_occurance(ins->occurance);
2360         piece_type = reg_type(state, ins->type, index * REG_SIZEOF_REG);
2361
2362         if ((piece_type->type & TYPE_MASK) == TYPE_BITFIELD) {
2363                 piece_type = piece_type->left;
2364         }
2365 #if 0
2366 {
2367         static void name_of(FILE *fp, struct type *type);
2368         FILE * fp = state->errout;
2369         fprintf(fp, "piece_type(%d): ", index);
2370         name_of(fp, piece_type);
2371         fprintf(fp, "\n");
2372 }
2373 #endif
2374         piece = alloc_triple(state, OP_PIECE, piece_type, -1, -1, ins->occurance);
2375         piece->u.cval  = index;
2376         LHS(ins, piece->u.cval) = piece;
2377         MISC(piece, 0) = ins;
2378 }
2379
2380 static void generate_lhs_pieces(struct compile_state *state, struct triple *ins)
2381 {
2382         int i, zlhs;
2383         zlhs = ins->lhs;
2384         for(i = 0; i < zlhs; i++) {
2385                 generate_lhs_piece(state, ins, i);
2386         }
2387 }
2388
2389 static struct triple *label(struct compile_state *state)
2390 {
2391         /* Labels don't get a type */
2392         struct triple *result;
2393         result = triple(state, OP_LABEL, &void_type, 0, 0);
2394         return result;
2395 }
2396
2397 static struct triple *mkprog(struct compile_state *state, ...)
2398 {
2399         struct triple *prog, *head, *arg;
2400         va_list args;
2401         int i;
2402
2403         head = label(state);
2404         prog = new_triple(state, OP_PROG, &void_type, -1, -1);
2405         RHS(prog, 0) = head;
2406         va_start(args, state);
2407         i = 0;
2408         while((arg = va_arg(args, struct triple *)) != 0) {
2409                 if (++i >= 100) {
2410                         internal_error(state, 0, "too many arguments to mkprog");
2411                 }
2412                 flatten(state, head, arg);
2413         }
2414         va_end(args);
2415         prog->type = head->prev->type;
2416         return prog;
2417 }
2418 static void name_of(FILE *fp, struct type *type);
2419 static void display_triple(FILE *fp, struct triple *ins)
2420 {
2421         struct occurance *ptr;
2422         const char *reg;
2423         char pre, post, vol;
2424         pre = post = vol = ' ';
2425         if (ins) {
2426                 if (ins->id & TRIPLE_FLAG_PRE_SPLIT) {
2427                         pre = '^';
2428                 }
2429                 if (ins->id & TRIPLE_FLAG_POST_SPLIT) {
2430                         post = ',';
2431                 }
2432                 if (ins->id & TRIPLE_FLAG_VOLATILE) {
2433                         vol = 'v';
2434                 }
2435                 reg = arch_reg_str(ID_REG(ins->id));
2436         }
2437         if (ins == 0) {
2438                 fprintf(fp, "(%p) <nothing> ", ins);
2439         }
2440         else if (ins->op == OP_INTCONST) {
2441                 fprintf(fp, "(%p) %c%c%c %-7s %-2d %-10s <0x%08lx>         ",
2442                         ins, pre, post, vol, reg, ins->template_id, tops(ins->op), 
2443                         (unsigned long)(ins->u.cval));
2444         }
2445         else if (ins->op == OP_ADDRCONST) {
2446                 fprintf(fp, "(%p) %c%c%c %-7s %-2d %-10s %-10p <0x%08lx>",
2447                         ins, pre, post, vol, reg, ins->template_id, tops(ins->op), 
2448                         MISC(ins, 0), (unsigned long)(ins->u.cval));
2449         }
2450         else if (ins->op == OP_INDEX) {
2451                 fprintf(fp, "(%p) %c%c%c %-7s %-2d %-10s %-10p <0x%08lx>",
2452                         ins, pre, post, vol, reg, ins->template_id, tops(ins->op), 
2453                         RHS(ins, 0), (unsigned long)(ins->u.cval));
2454         }
2455         else if (ins->op == OP_PIECE) {
2456                 fprintf(fp, "(%p) %c%c%c %-7s %-2d %-10s %-10p <0x%08lx>",
2457                         ins, pre, post, vol, reg, ins->template_id, tops(ins->op), 
2458                         MISC(ins, 0), (unsigned long)(ins->u.cval));
2459         }
2460         else {
2461                 int i, count;
2462                 fprintf(fp, "(%p) %c%c%c %-7s %-2d %-10s", 
2463                         ins, pre, post, vol, reg, ins->template_id, tops(ins->op));
2464                 if (table_ops[ins->op].flags & BITFIELD) {
2465                         fprintf(fp, " <%2d-%2d:%2d>", 
2466                                 ins->u.bitfield.offset,
2467                                 ins->u.bitfield.offset + ins->u.bitfield.size,
2468                                 ins->u.bitfield.size);
2469                 }
2470                 count = TRIPLE_SIZE(ins);
2471                 for(i = 0; i < count; i++) {
2472                         fprintf(fp, " %-10p", ins->param[i]);
2473                 }
2474                 for(; i < 2; i++) {
2475                         fprintf(fp, "           ");
2476                 }
2477         }
2478         if (ins) {
2479                 struct triple_set *user;
2480 #if DEBUG_DISPLAY_TYPES
2481                 fprintf(fp, " <");
2482                 name_of(fp, ins->type);
2483                 fprintf(fp, "> ");
2484 #endif
2485 #if DEBUG_DISPLAY_USES
2486                 fprintf(fp, " [");
2487                 for(user = ins->use; user; user = user->next) {
2488                         fprintf(fp, " %-10p", user->member);
2489                 }
2490                 fprintf(fp, " ]");
2491 #endif
2492                 fprintf(fp, " @");
2493                 for(ptr = ins->occurance; ptr; ptr = ptr->parent) {
2494                         fprintf(fp, " %s,%s:%d.%d",
2495                                 ptr->function, 
2496                                 ptr->filename,
2497                                 ptr->line, 
2498                                 ptr->col);
2499                 }
2500                 if (ins->op == OP_ASM) {
2501                         fprintf(fp, "\n\t%s", ins->u.ainfo->str);
2502                 }
2503         }
2504         fprintf(fp, "\n");
2505         fflush(fp);
2506 }
2507
2508 static int equiv_types(struct type *left, struct type *right);
2509 static void display_triple_changes(
2510         FILE *fp, const struct triple *new, const struct triple *orig)
2511 {
2512
2513         int new_count, orig_count;
2514         new_count = TRIPLE_SIZE(new);
2515         orig_count = TRIPLE_SIZE(orig);
2516         if ((new->op != orig->op) ||
2517                 (new_count != orig_count) ||
2518                 (memcmp(orig->param, new->param,        
2519                         orig_count * sizeof(orig->param[0])) != 0) ||
2520                 (memcmp(&orig->u, &new->u, sizeof(orig->u)) != 0)) 
2521         {
2522                 struct occurance *ptr;
2523                 int i, min_count, indent;
2524                 fprintf(fp, "(%p %p)", new, orig);
2525                 if (orig->op == new->op) {
2526                         fprintf(fp, " %-11s", tops(orig->op));
2527                 } else {
2528                         fprintf(fp, " [%-10s %-10s]", 
2529                                 tops(new->op), tops(orig->op));
2530                 }
2531                 min_count = new_count;
2532                 if (min_count > orig_count) {
2533                         min_count = orig_count;
2534                 }
2535                 for(indent = i = 0; i < min_count; i++) {
2536                         if (orig->param[i] == new->param[i]) {
2537                                 fprintf(fp, " %-11p", 
2538                                         orig->param[i]);
2539                                 indent += 12;
2540                         } else {
2541                                 fprintf(fp, " [%-10p %-10p]",
2542                                         new->param[i], 
2543                                         orig->param[i]);
2544                                 indent += 24;
2545                         }
2546                 }
2547                 for(; i < orig_count; i++) {
2548                         fprintf(fp, " [%-9p]", orig->param[i]);
2549                         indent += 12;
2550                 }
2551                 for(; i < new_count; i++) {
2552                         fprintf(fp, " [%-9p]", new->param[i]);
2553                         indent += 12;
2554                 }
2555                 if ((new->op == OP_INTCONST)||
2556                         (new->op == OP_ADDRCONST)) {
2557                         fprintf(fp, " <0x%08lx>", 
2558                                 (unsigned long)(new->u.cval));
2559                         indent += 13;
2560                 }
2561                 for(;indent < 36; indent++) {
2562                         putc(' ', fp);
2563                 }
2564
2565 #if DEBUG_DISPLAY_TYPES
2566                 fprintf(fp, " <");
2567                 name_of(fp, new->type);
2568                 if (!equiv_types(new->type, orig->type)) {
2569                         fprintf(fp, " -- ");
2570                         name_of(fp, orig->type);
2571                 }
2572                 fprintf(fp, "> ");
2573 #endif
2574
2575                 fprintf(fp, " @");
2576                 for(ptr = orig->occurance; ptr; ptr = ptr->parent) {
2577                         fprintf(fp, " %s,%s:%d.%d",
2578                                 ptr->function, 
2579                                 ptr->filename,
2580                                 ptr->line, 
2581                                 ptr->col);
2582                         
2583                 }
2584                 fprintf(fp, "\n");
2585                 fflush(fp);
2586         }
2587 }
2588
2589 static int triple_is_pure(struct compile_state *state, struct triple *ins, unsigned id)
2590 {
2591         /* Does the triple have no side effects.
2592          * I.e. Rexecuting the triple with the same arguments 
2593          * gives the same value.
2594          */
2595         unsigned pure;
2596         valid_ins(state, ins);
2597         pure = PURE_BITS(table_ops[ins->op].flags);
2598         if ((pure != PURE) && (pure != IMPURE)) {
2599                 internal_error(state, 0, "Purity of %s not known",
2600                         tops(ins->op));
2601         }
2602         return (pure == PURE) && !(id & TRIPLE_FLAG_VOLATILE);
2603 }
2604
2605 static int triple_is_branch_type(struct compile_state *state, 
2606         struct triple *ins, unsigned type)
2607 {
2608         /* Is this one of the passed branch types? */
2609         valid_ins(state, ins);
2610         return (BRANCH_BITS(table_ops[ins->op].flags) == type);
2611 }
2612
2613 static int triple_is_branch(struct compile_state *state, struct triple *ins)
2614 {
2615         /* Is this triple a branch instruction? */
2616         valid_ins(state, ins);
2617         return (BRANCH_BITS(table_ops[ins->op].flags) != 0);
2618 }
2619
2620 static int triple_is_cbranch(struct compile_state *state, struct triple *ins)
2621 {
2622         /* Is this triple a conditional branch instruction? */
2623         return triple_is_branch_type(state, ins, CBRANCH);
2624 }
2625
2626 static int triple_is_ubranch(struct compile_state *state, struct triple *ins)
2627 {
2628         /* Is this triple a unconditional branch instruction? */
2629         unsigned type;
2630         valid_ins(state, ins);
2631         type = BRANCH_BITS(table_ops[ins->op].flags);
2632         return (type != 0) && (type != CBRANCH);
2633 }
2634
2635 static int triple_is_call(struct compile_state *state, struct triple *ins)
2636 {
2637         /* Is this triple a call instruction? */
2638         return triple_is_branch_type(state, ins, CALLBRANCH);
2639 }
2640
2641 static int triple_is_ret(struct compile_state *state, struct triple *ins)
2642 {
2643         /* Is this triple a return instruction? */
2644         return triple_is_branch_type(state, ins, RETBRANCH);
2645 }
2646
2647 static int triple_is_simple_ubranch(struct compile_state *state, struct triple *ins)
2648 {
2649         /* Is this triple an unconditional branch and not a call or a
2650          * return? */
2651         return triple_is_branch_type(state, ins, UBRANCH);
2652 }
2653
2654 static int triple_is_end(struct compile_state *state, struct triple *ins)
2655 {
2656         return triple_is_branch_type(state, ins, ENDBRANCH);
2657 }
2658
2659 static int triple_is_label(struct compile_state *state, struct triple *ins)
2660 {
2661         valid_ins(state, ins);
2662         return (ins->op == OP_LABEL);
2663 }
2664
2665 static struct triple *triple_to_block_start(
2666         struct compile_state *state, struct triple *start)
2667 {
2668         while(!triple_is_branch(state, start->prev) &&
2669                 (!triple_is_label(state, start) || !start->use)) {
2670                 start = start->prev;
2671         }
2672         return start;
2673 }
2674
2675 static int triple_is_def(struct compile_state *state, struct triple *ins)
2676 {
2677         /* This function is used to determine which triples need
2678          * a register.
2679          */
2680         int is_def;
2681         valid_ins(state, ins);
2682         is_def = (table_ops[ins->op].flags & DEF) == DEF;
2683         if (ins->lhs >= 1) {
2684                 is_def = 0;
2685         }
2686         return is_def;
2687 }
2688
2689 static int triple_is_structural(struct compile_state *state, struct triple *ins)
2690 {
2691         int is_structural;
2692         valid_ins(state, ins);
2693         is_structural = (table_ops[ins->op].flags & STRUCTURAL) == STRUCTURAL;
2694         return is_structural;
2695 }
2696
2697 static int triple_is_part(struct compile_state *state, struct triple *ins)
2698 {
2699         int is_part;
2700         valid_ins(state, ins);
2701         is_part = (table_ops[ins->op].flags & PART) == PART;
2702         return is_part;
2703 }
2704
2705 static int triple_is_auto_var(struct compile_state *state, struct triple *ins)
2706 {
2707         return (ins->op == OP_PIECE) && (MISC(ins, 0)->op == OP_ADECL);
2708 }
2709
2710 static struct triple **triple_iter(struct compile_state *state,
2711         size_t count, struct triple **vector,
2712         struct triple *ins, struct triple **last)
2713 {
2714         struct triple **ret;
2715         ret = 0;
2716         if (count) {
2717                 if (!last) {
2718                         ret = vector;
2719                 }
2720                 else if ((last >= vector) && (last < (vector + count - 1))) {
2721                         ret = last + 1;
2722                 }
2723         }
2724         return ret;
2725         
2726 }
2727
2728 static struct triple **triple_lhs(struct compile_state *state,
2729         struct triple *ins, struct triple **last)
2730 {
2731         return triple_iter(state, ins->lhs, &LHS(ins,0), 
2732                 ins, last);
2733 }
2734
2735 static struct triple **triple_rhs(struct compile_state *state,
2736         struct triple *ins, struct triple **last)
2737 {
2738         return triple_iter(state, ins->rhs, &RHS(ins,0), 
2739                 ins, last);
2740 }
2741
2742 static struct triple **triple_misc(struct compile_state *state,
2743         struct triple *ins, struct triple **last)
2744 {
2745         return triple_iter(state, ins->misc, &MISC(ins,0), 
2746                 ins, last);
2747 }
2748
2749 static struct triple **do_triple_targ(struct compile_state *state,
2750         struct triple *ins, struct triple **last, int call_edges, int next_edges)
2751 {
2752         size_t count;
2753         struct triple **ret, **vector;
2754         int next_is_targ;
2755         ret = 0;
2756         count = ins->targ;
2757         next_is_targ = 0;
2758         if (triple_is_cbranch(state, ins)) {
2759                 next_is_targ = 1;
2760         }
2761         if (!call_edges && triple_is_call(state, ins)) {
2762                 count = 0;
2763         }
2764         if (next_edges && triple_is_call(state, ins)) {
2765                 next_is_targ = 1;
2766         }
2767         vector = &TARG(ins, 0);
2768         if (!ret && next_is_targ) {
2769                 if (!last) {
2770                         ret = &ins->next;
2771                 } else if (last == &ins->next) {
2772                         last = 0;
2773                 }
2774         }
2775         if (!ret && count) {
2776                 if (!last) {
2777                         ret = vector;
2778                 }
2779                 else if ((last >= vector) && (last < (vector + count - 1))) {
2780                         ret = last + 1;
2781                 }
2782                 else if (last == vector + count - 1) {
2783                         last = 0;
2784                 }
2785         }
2786         if (!ret && triple_is_ret(state, ins) && call_edges) {
2787                 struct triple_set *use;
2788                 for(use = ins->use; use; use = use->next) {
2789                         if (!triple_is_call(state, use->member)) {
2790                                 continue;
2791                         }
2792                         if (!last) {
2793                                 ret = &use->member->next;
2794                                 break;
2795                         }
2796                         else if (last == &use->member->next) {
2797                                 last = 0;
2798                         }
2799                 }
2800         }
2801         return ret;
2802 }
2803
2804 static struct triple **triple_targ(struct compile_state *state,
2805         struct triple *ins, struct triple **last)
2806 {
2807         return do_triple_targ(state, ins, last, 1, 1);
2808 }
2809
2810 static struct triple **triple_edge_targ(struct compile_state *state,
2811         struct triple *ins, struct triple **last)
2812 {
2813         return do_triple_targ(state, ins, last, 
2814                 state->functions_joined, !state->functions_joined);
2815 }
2816
2817 static struct triple *after_lhs(struct compile_state *state, struct triple *ins)
2818 {
2819         struct triple *next;
2820         int lhs, i;
2821         lhs = ins->lhs;
2822         next = ins->next;
2823         for(i = 0; i < lhs; i++) {
2824                 struct triple *piece;
2825                 piece = LHS(ins, i);
2826                 if (next != piece) {
2827                         internal_error(state, ins, "malformed lhs on %s",
2828                                 tops(ins->op));
2829                 }
2830                 if (next->op != OP_PIECE) {
2831                         internal_error(state, ins, "bad lhs op %s at %d on %s",
2832                                 tops(next->op), i, tops(ins->op));
2833                 }
2834                 if (next->u.cval != i) {
2835                         internal_error(state, ins, "bad u.cval of %d %d expected",
2836                                 next->u.cval, i);
2837                 }
2838                 next = next->next;
2839         }
2840         return next;
2841 }
2842
2843 /* Function piece accessor functions */
2844 static struct triple *do_farg(struct compile_state *state, 
2845         struct triple *func, unsigned index)
2846 {
2847         struct type *ftype;
2848         struct triple *first, *arg;
2849         unsigned i;
2850
2851         ftype = func->type;
2852         if((index < 0) || (index >= (ftype->elements + 2))) {
2853                 internal_error(state, func, "bad argument index: %d", index);
2854         }
2855         first = RHS(func, 0);
2856         arg = first->next;
2857         for(i = 0; i < index; i++, arg = after_lhs(state, arg)) {
2858                 /* do nothing */
2859         }
2860         if (arg->op != OP_ADECL) {
2861                 internal_error(state, 0, "arg not adecl?");
2862         }
2863         return arg;
2864 }
2865 static struct triple *fresult(struct compile_state *state, struct triple *func)
2866 {
2867         return do_farg(state, func, 0);
2868 }
2869 static struct triple *fretaddr(struct compile_state *state, struct triple *func)
2870 {
2871         return do_farg(state, func, 1);
2872 }
2873 static struct triple *farg(struct compile_state *state, 
2874         struct triple *func, unsigned index)
2875 {
2876         return do_farg(state, func, index + 2);
2877 }
2878
2879
2880 static void display_func(struct compile_state *state, FILE *fp, struct triple *func)
2881 {
2882         struct triple *first, *ins;
2883         fprintf(fp, "display_func %s\n", func->type->type_ident->name);
2884         first = ins = RHS(func, 0);
2885         do {
2886                 if (triple_is_label(state, ins) && ins->use) {
2887                         fprintf(fp, "%p:\n", ins);
2888                 }
2889                 display_triple(fp, ins);
2890
2891                 if (triple_is_branch(state, ins)) {
2892                         fprintf(fp, "\n");
2893                 }
2894                 if (ins->next->prev != ins) {
2895                         internal_error(state, ins->next, "bad prev");
2896                 }
2897                 ins = ins->next;
2898         } while(ins != first);
2899 }
2900
2901 static void verify_use(struct compile_state *state,
2902         struct triple *user, struct triple *used)
2903 {
2904         int size, i;
2905         size = TRIPLE_SIZE(user);
2906         for(i = 0; i < size; i++) {
2907                 if (user->param[i] == used) {
2908                         break;
2909                 }
2910         }
2911         if (triple_is_branch(state, user)) {
2912                 if (user->next == used) {
2913                         i = -1;
2914                 }
2915         }
2916         if (i == size) {
2917                 internal_error(state, user, "%s(%p) does not use %s(%p)",
2918                         tops(user->op), user, tops(used->op), used);
2919         }
2920 }
2921
2922 static int find_rhs_use(struct compile_state *state, 
2923         struct triple *user, struct triple *used)
2924 {
2925         struct triple **param;
2926         int size, i;
2927         verify_use(state, user, used);
2928 #warning "AUDIT ME ->rhs"
2929         size = user->rhs;
2930         param = &RHS(user, 0);
2931         for(i = 0; i < size; i++) {
2932                 if (param[i] == used) {
2933                         return i;
2934                 }
2935         }
2936         return -1;
2937 }
2938
2939 static void free_triple(struct compile_state *state, struct triple *ptr)
2940 {
2941         size_t size;
2942         size = sizeof(*ptr) - sizeof(ptr->param) +
2943                 (sizeof(ptr->param[0])*TRIPLE_SIZE(ptr));
2944         ptr->prev->next = ptr->next;
2945         ptr->next->prev = ptr->prev;
2946         if (ptr->use) {
2947                 internal_error(state, ptr, "ptr->use != 0");
2948         }
2949         put_occurance(ptr->occurance);
2950         memset(ptr, -1, size);
2951         xfree(ptr);
2952 }
2953
2954 static void release_triple(struct compile_state *state, struct triple *ptr)
2955 {
2956         struct triple_set *set, *next;
2957         struct triple **expr;
2958         struct block *block;
2959         if (ptr == &unknown_triple) {
2960                 return;
2961         }
2962         valid_ins(state, ptr);
2963         /* Make certain the we are not the first or last element of a block */
2964         block = block_of_triple(state, ptr);
2965         if (block) {
2966                 if ((block->last == ptr) && (block->first == ptr)) {
2967                         block->last = block->first = 0;
2968                 }
2969                 else if (block->last == ptr) {
2970                         block->last = ptr->prev;
2971                 }
2972                 else if (block->first == ptr) {
2973                         block->first = ptr->next;
2974                 }
2975         }
2976         /* Remove ptr from use chains where it is the user */
2977         expr = triple_rhs(state, ptr, 0);
2978         for(; expr; expr = triple_rhs(state, ptr, expr)) {
2979                 if (*expr) {
2980                         unuse_triple(*expr, ptr);
2981                 }
2982         }
2983         expr = triple_lhs(state, ptr, 0);
2984         for(; expr; expr = triple_lhs(state, ptr, expr)) {
2985                 if (*expr) {
2986                         unuse_triple(*expr, ptr);
2987                 }
2988         }
2989         expr = triple_misc(state, ptr, 0);
2990         for(; expr; expr = triple_misc(state, ptr, expr)) {
2991                 if (*expr) {
2992                         unuse_triple(*expr, ptr);
2993                 }
2994         }
2995         expr = triple_targ(state, ptr, 0);
2996         for(; expr; expr = triple_targ(state, ptr, expr)) {
2997                 if (*expr){
2998                         unuse_triple(*expr, ptr);
2999                 }
3000         }
3001         /* Reomve ptr from use chains where it is used */
3002         for(set = ptr->use; set; set = next) {
3003                 next = set->next;
3004                 valid_ins(state, set->member);
3005                 expr = triple_rhs(state, set->member, 0);
3006                 for(; expr; expr = triple_rhs(state, set->member, expr)) {
3007                         if (*expr == ptr) {
3008                                 *expr = &unknown_triple;
3009                         }
3010                 }
3011                 expr = triple_lhs(state, set->member, 0);
3012                 for(; expr; expr = triple_lhs(state, set->member, expr)) {
3013                         if (*expr == ptr) {
3014                                 *expr = &unknown_triple;
3015                         }
3016                 }
3017                 expr = triple_misc(state, set->member, 0);
3018                 for(; expr; expr = triple_misc(state, set->member, expr)) {
3019                         if (*expr == ptr) {
3020                                 *expr = &unknown_triple;
3021                         }
3022                 }
3023                 expr = triple_targ(state, set->member, 0);
3024                 for(; expr; expr = triple_targ(state, set->member, expr)) {
3025                         if (*expr == ptr) {
3026                                 *expr = &unknown_triple;
3027                         }
3028                 }
3029                 unuse_triple(ptr, set->member);
3030         }
3031         free_triple(state, ptr);
3032 }
3033
3034 static void print_triples(struct compile_state *state);
3035 static void print_blocks(struct compile_state *state, const char *func, FILE *fp);
3036
3037 #define TOK_UNKNOWN       0
3038 #define TOK_SPACE         1
3039 #define TOK_SEMI          2
3040 #define TOK_LBRACE        3
3041 #define TOK_RBRACE        4
3042 #define TOK_COMMA         5
3043 #define TOK_EQ            6
3044 #define TOK_COLON         7
3045 #define TOK_LBRACKET      8
3046 #define TOK_RBRACKET      9
3047 #define TOK_LPAREN        10
3048 #define TOK_RPAREN        11
3049 #define TOK_STAR          12
3050 #define TOK_DOTS          13
3051 #define TOK_MORE          14
3052 #define TOK_LESS          15
3053 #define TOK_TIMESEQ       16
3054 #define TOK_DIVEQ         17
3055 #define TOK_MODEQ         18
3056 #define TOK_PLUSEQ        19
3057 #define TOK_MINUSEQ       20
3058 #define TOK_SLEQ          21
3059 #define TOK_SREQ          22
3060 #define TOK_ANDEQ         23
3061 #define TOK_XOREQ         24
3062 #define TOK_OREQ          25
3063 #define TOK_EQEQ          26
3064 #define TOK_NOTEQ         27
3065 #define TOK_QUEST         28
3066 #define TOK_LOGOR         29
3067 #define TOK_LOGAND        30
3068 #define TOK_OR            31
3069 #define TOK_AND           32
3070 #define TOK_XOR           33
3071 #define TOK_LESSEQ        34
3072 #define TOK_MOREEQ        35
3073 #define TOK_SL            36
3074 #define TOK_SR            37
3075 #define TOK_PLUS          38
3076 #define TOK_MINUS         39
3077 #define TOK_DIV           40
3078 #define TOK_MOD           41
3079 #define TOK_PLUSPLUS      42
3080 #define TOK_MINUSMINUS    43
3081 #define TOK_BANG          44
3082 #define TOK_ARROW         45
3083 #define TOK_DOT           46
3084 #define TOK_TILDE         47
3085 #define TOK_LIT_STRING    48
3086 #define TOK_LIT_CHAR      49
3087 #define TOK_LIT_INT       50
3088 #define TOK_LIT_FLOAT     51
3089 #define TOK_MACRO         52
3090 #define TOK_CONCATENATE   53
3091
3092 #define TOK_IDENT         54
3093 #define TOK_STRUCT_NAME   55
3094 #define TOK_ENUM_CONST    56
3095 #define TOK_TYPE_NAME     57
3096
3097 #define TOK_AUTO          58
3098 #define TOK_BREAK         59
3099 #define TOK_CASE          60
3100 #define TOK_CHAR          61
3101 #define TOK_CONST         62
3102 #define TOK_CONTINUE      63
3103 #define TOK_DEFAULT       64
3104 #define TOK_DO            65
3105 #define TOK_DOUBLE        66
3106 #define TOK_ELSE          67
3107 #define TOK_ENUM          68
3108 #define TOK_EXTERN        69
3109 #define TOK_FLOAT         70
3110 #define TOK_FOR           71
3111 #define TOK_GOTO          72
3112 #define TOK_IF            73
3113 #define TOK_INLINE        74
3114 #define TOK_INT           75
3115 #define TOK_LONG          76
3116 #define TOK_REGISTER      77
3117 #define TOK_RESTRICT      78
3118 #define TOK_RETURN        79
3119 #define TOK_SHORT         80
3120 #define TOK_SIGNED        81
3121 #define TOK_SIZEOF        82
3122 #define TOK_STATIC        83
3123 #define TOK_STRUCT        84
3124 #define TOK_SWITCH        85
3125 #define TOK_TYPEDEF       86
3126 #define TOK_UNION         87
3127 #define TOK_UNSIGNED      88
3128 #define TOK_VOID          89
3129 #define TOK_VOLATILE      90
3130 #define TOK_WHILE         91
3131 #define TOK_ASM           92
3132 #define TOK_ATTRIBUTE     93
3133 #define TOK_ALIGNOF       94
3134 #define TOK_FIRST_KEYWORD TOK_AUTO
3135 #define TOK_LAST_KEYWORD  TOK_ALIGNOF
3136
3137 #define TOK_MDEFINE       100
3138 #define TOK_MDEFINED      101
3139 #define TOK_MUNDEF        102
3140 #define TOK_MINCLUDE      103
3141 #define TOK_MLINE         104
3142 #define TOK_MERROR        105
3143 #define TOK_MWARNING      106
3144 #define TOK_MPRAGMA       107
3145 #define TOK_MIFDEF        108
3146 #define TOK_MIFNDEF       109
3147 #define TOK_MELIF         110
3148 #define TOK_MENDIF        111
3149
3150 #define TOK_FIRST_MACRO   TOK_MDEFINE
3151 #define TOK_LAST_MACRO    TOK_MENDIF
3152          
3153 #define TOK_MIF           112
3154 #define TOK_MELSE         113
3155 #define TOK_MIDENT        114
3156
3157 #define TOK_EOL           115
3158 #define TOK_EOF           116
3159
3160 static const char *tokens[] = {
3161 [TOK_UNKNOWN     ] = ":unknown:",
3162 [TOK_SPACE       ] = ":space:",
3163 [TOK_SEMI        ] = ";",
3164 [TOK_LBRACE      ] = "{",
3165 [TOK_RBRACE      ] = "}",
3166 [TOK_COMMA       ] = ",",
3167 [TOK_EQ          ] = "=",
3168 [TOK_COLON       ] = ":",
3169 [TOK_LBRACKET    ] = "[",
3170 [TOK_RBRACKET    ] = "]",
3171 [TOK_LPAREN      ] = "(",
3172 [TOK_RPAREN      ] = ")",
3173 [TOK_STAR        ] = "*",
3174 [TOK_DOTS        ] = "...",
3175 [TOK_MORE        ] = ">",
3176 [TOK_LESS        ] = "<",
3177 [TOK_TIMESEQ     ] = "*=",
3178 [TOK_DIVEQ       ] = "/=",
3179 [TOK_MODEQ       ] = "%=",
3180 [TOK_PLUSEQ      ] = "+=",
3181 [TOK_MINUSEQ     ] = "-=",
3182 [TOK_SLEQ        ] = "<<=",
3183 [TOK_SREQ        ] = ">>=",
3184 [TOK_ANDEQ       ] = "&=",
3185 [TOK_XOREQ       ] = "^=",
3186 [TOK_OREQ        ] = "|=",
3187 [TOK_EQEQ        ] = "==",
3188 [TOK_NOTEQ       ] = "!=",
3189 [TOK_QUEST       ] = "?",
3190 [TOK_LOGOR       ] = "||",
3191 [TOK_LOGAND      ] = "&&",
3192 [TOK_OR          ] = "|",
3193 [TOK_AND         ] = "&",
3194 [TOK_XOR         ] = "^",
3195 [TOK_LESSEQ      ] = "<=",
3196 [TOK_MOREEQ      ] = ">=",
3197 [TOK_SL          ] = "<<",
3198 [TOK_SR          ] = ">>",
3199 [TOK_PLUS        ] = "+",
3200 [TOK_MINUS       ] = "-",
3201 [TOK_DIV         ] = "/",
3202 [TOK_MOD         ] = "%",
3203 [TOK_PLUSPLUS    ] = "++",
3204 [TOK_MINUSMINUS  ] = "--",
3205 [TOK_BANG        ] = "!",
3206 [TOK_ARROW       ] = "->",
3207 [TOK_DOT         ] = ".",
3208 [TOK_TILDE       ] = "~",
3209 [TOK_LIT_STRING  ] = ":string:",
3210 [TOK_IDENT       ] = ":ident:",
3211 [TOK_TYPE_NAME   ] = ":typename:",
3212 [TOK_LIT_CHAR    ] = ":char:",
3213 [TOK_LIT_INT     ] = ":integer:",
3214 [TOK_LIT_FLOAT   ] = ":float:",
3215 [TOK_MACRO       ] = "#",
3216 [TOK_CONCATENATE ] = "##",
3217
3218 [TOK_AUTO        ] = "auto",
3219 [TOK_BREAK       ] = "break",
3220 [TOK_CASE        ] = "case",
3221 [TOK_CHAR        ] = "char",
3222 [TOK_CONST       ] = "const",
3223 [TOK_CONTINUE    ] = "continue",
3224 [TOK_DEFAULT     ] = "default",
3225 [TOK_DO          ] = "do",
3226 [TOK_DOUBLE      ] = "double",
3227 [TOK_ELSE        ] = "else",
3228 [TOK_ENUM        ] = "enum",
3229 [TOK_EXTERN      ] = "extern",
3230 [TOK_FLOAT       ] = "float",
3231 [TOK_FOR         ] = "for",
3232 [TOK_GOTO        ] = "goto",
3233 [TOK_IF          ] = "if",
3234 [TOK_INLINE      ] = "inline",
3235 [TOK_INT         ] = "int",
3236 [TOK_LONG        ] = "long",
3237 [TOK_REGISTER    ] = "register",
3238 [TOK_RESTRICT    ] = "restrict",
3239 [TOK_RETURN      ] = "return",
3240 [TOK_SHORT       ] = "short",
3241 [TOK_SIGNED      ] = "signed",
3242 [TOK_SIZEOF      ] = "sizeof",
3243 [TOK_STATIC      ] = "static",
3244 [TOK_STRUCT      ] = "struct",
3245 [TOK_SWITCH      ] = "switch",
3246 [TOK_TYPEDEF     ] = "typedef",
3247 [TOK_UNION       ] = "union",
3248 [TOK_UNSIGNED    ] = "unsigned",
3249 [TOK_VOID        ] = "void",
3250 [TOK_VOLATILE    ] = "volatile",
3251 [TOK_WHILE       ] = "while",
3252 [TOK_ASM         ] = "asm",
3253 [TOK_ATTRIBUTE   ] = "__attribute__",
3254 [TOK_ALIGNOF     ] = "__alignof__",
3255
3256 [TOK_MDEFINE     ] = "#define",
3257 [TOK_MDEFINED    ] = "#defined",
3258 [TOK_MUNDEF      ] = "#undef",
3259 [TOK_MINCLUDE    ] = "#include",
3260 [TOK_MLINE       ] = "#line",
3261 [TOK_MERROR      ] = "#error",
3262 [TOK_MWARNING    ] = "#warning",
3263 [TOK_MPRAGMA     ] = "#pragma",
3264 [TOK_MIFDEF      ] = "#ifdef",
3265 [TOK_MIFNDEF     ] = "#ifndef",
3266 [TOK_MELIF       ] = "#elif",
3267 [TOK_MENDIF      ] = "#endif",
3268
3269 [TOK_MIF         ] = "#if",
3270 [TOK_MELSE       ] = "#else",
3271 [TOK_MIDENT      ] = "#:ident:",
3272 [TOK_EOL         ] = "EOL", 
3273 [TOK_EOF         ] = "EOF",
3274 };
3275
3276 static unsigned int hash(const char *str, int str_len)
3277 {
3278         unsigned int hash;
3279         const char *end;
3280         end = str + str_len;
3281         hash = 0;
3282         for(; str < end; str++) {
3283                 hash = (hash *263) + *str;
3284         }
3285         hash = hash & (HASH_TABLE_SIZE -1);
3286         return hash;
3287 }
3288
3289 static struct hash_entry *lookup(
3290         struct compile_state *state, const char *name, int name_len)
3291 {
3292         struct hash_entry *entry;
3293         unsigned int index;
3294         index = hash(name, name_len);
3295         entry = state->hash_table[index];
3296         while(entry && 
3297                 ((entry->name_len != name_len) ||
3298                         (memcmp(entry->name, name, name_len) != 0))) {
3299                 entry = entry->next;
3300         }
3301         if (!entry) {
3302                 char *new_name;
3303                 /* Get a private copy of the name */
3304                 new_name = xmalloc(name_len + 1, "hash_name");
3305                 memcpy(new_name, name, name_len);
3306                 new_name[name_len] = '\0';
3307
3308                 /* Create a new hash entry */
3309                 entry = xcmalloc(sizeof(*entry), "hash_entry");
3310                 entry->next = state->hash_table[index];
3311                 entry->name = new_name;
3312                 entry->name_len = name_len;
3313
3314                 /* Place the new entry in the hash table */
3315                 state->hash_table[index] = entry;
3316         }
3317         return entry;
3318 }
3319
3320 static void ident_to_keyword(struct compile_state *state, struct token *tk)
3321 {
3322         struct hash_entry *entry;
3323         entry = tk->ident;
3324         if (entry && ((entry->tok == TOK_TYPE_NAME) ||
3325                 (entry->tok == TOK_ENUM_CONST) ||
3326                 ((entry->tok >= TOK_FIRST_KEYWORD) && 
3327                         (entry->tok <= TOK_LAST_KEYWORD)))) {
3328                 tk->tok = entry->tok;
3329         }
3330 }
3331
3332 static void ident_to_macro(struct compile_state *state, struct token *tk)
3333 {
3334         struct hash_entry *entry;
3335         entry = tk->ident;
3336         if (!entry)
3337                 return;
3338         if ((entry->tok >= TOK_FIRST_MACRO) && (entry->tok <= TOK_LAST_MACRO)) {
3339                 tk->tok = entry->tok;
3340         }
3341         else if (entry->tok == TOK_IF) {
3342                 tk->tok = TOK_MIF;
3343         }
3344         else if (entry->tok == TOK_ELSE) {
3345                 tk->tok = TOK_MELSE;
3346         }
3347         else {
3348                 tk->tok = TOK_MIDENT;
3349         }
3350 }
3351
3352 static void hash_keyword(
3353         struct compile_state *state, const char *keyword, int tok)
3354 {
3355         struct hash_entry *entry;
3356         entry = lookup(state, keyword, strlen(keyword));
3357         if (entry && entry->tok != TOK_UNKNOWN) {
3358                 die("keyword %s already hashed", keyword);
3359         }
3360         entry->tok  = tok;
3361 }
3362
3363 static void romcc_symbol(
3364         struct compile_state *state, struct hash_entry *ident,
3365         struct symbol **chain, struct triple *def, struct type *type, int depth)
3366 {
3367         struct symbol *sym;
3368         if (*chain && ((*chain)->scope_depth >= depth)) {
3369                 error(state, 0, "%s already defined", ident->name);
3370         }
3371         sym = xcmalloc(sizeof(*sym), "symbol");
3372         sym->ident = ident;
3373         sym->def   = def;
3374         sym->type  = type;
3375         sym->scope_depth = depth;
3376         sym->next = *chain;
3377         *chain    = sym;
3378 }
3379
3380 static void symbol(
3381         struct compile_state *state, struct hash_entry *ident,
3382         struct symbol **chain, struct triple *def, struct type *type)
3383 {
3384         romcc_symbol(state, ident, chain, def, type, state->scope_depth);
3385 }
3386
3387 static void var_symbol(struct compile_state *state, 
3388         struct hash_entry *ident, struct triple *def)
3389 {
3390         if ((def->type->type & TYPE_MASK) == TYPE_PRODUCT) {
3391                 internal_error(state, 0, "bad var type");
3392         }
3393         symbol(state, ident, &ident->sym_ident, def, def->type);
3394 }
3395
3396 static void label_symbol(struct compile_state *state, 
3397         struct hash_entry *ident, struct triple *label, int depth)
3398 {
3399         romcc_symbol(state, ident, &ident->sym_label, label, &void_type, depth);
3400 }
3401
3402 static void start_scope(struct compile_state *state)
3403 {
3404         state->scope_depth++;
3405 }
3406
3407 static void end_scope_syms(struct compile_state *state,
3408         struct symbol **chain, int depth)
3409 {
3410         struct symbol *sym, *next;
3411         sym = *chain;
3412         while(sym && (sym->scope_depth == depth)) {
3413                 next = sym->next;
3414                 xfree(sym);
3415                 sym = next;
3416         }
3417         *chain = sym;
3418 }
3419
3420 static void end_scope(struct compile_state *state)
3421 {
3422         int i;
3423         int depth;
3424         /* Walk through the hash table and remove all symbols
3425          * in the current scope. 
3426          */
3427         depth = state->scope_depth;
3428         for(i = 0; i < HASH_TABLE_SIZE; i++) {
3429                 struct hash_entry *entry;
3430                 entry = state->hash_table[i];
3431                 while(entry) {
3432                         end_scope_syms(state, &entry->sym_label, depth);
3433                         end_scope_syms(state, &entry->sym_tag,   depth);
3434                         end_scope_syms(state, &entry->sym_ident, depth);
3435                         entry = entry->next;
3436                 }
3437         }
3438         state->scope_depth = depth - 1;
3439 }
3440
3441 static void register_keywords(struct compile_state *state)
3442 {
3443         hash_keyword(state, "auto",          TOK_AUTO);
3444         hash_keyword(state, "break",         TOK_BREAK);
3445         hash_keyword(state, "case",          TOK_CASE);
3446         hash_keyword(state, "char",          TOK_CHAR);
3447         hash_keyword(state, "const",         TOK_CONST);
3448         hash_keyword(state, "continue",      TOK_CONTINUE);
3449         hash_keyword(state, "default",       TOK_DEFAULT);
3450         hash_keyword(state, "do",            TOK_DO);
3451         hash_keyword(state, "double",        TOK_DOUBLE);
3452         hash_keyword(state, "else",          TOK_ELSE);
3453         hash_keyword(state, "enum",          TOK_ENUM);
3454         hash_keyword(state, "extern",        TOK_EXTERN);
3455         hash_keyword(state, "float",         TOK_FLOAT);
3456         hash_keyword(state, "for",           TOK_FOR);
3457         hash_keyword(state, "goto",          TOK_GOTO);
3458         hash_keyword(state, "if",            TOK_IF);
3459         hash_keyword(state, "inline",        TOK_INLINE);
3460         hash_keyword(state, "int",           TOK_INT);
3461         hash_keyword(state, "long",          TOK_LONG);
3462         hash_keyword(state, "register",      TOK_REGISTER);
3463         hash_keyword(state, "restrict",      TOK_RESTRICT);
3464         hash_keyword(state, "return",        TOK_RETURN);
3465         hash_keyword(state, "short",         TOK_SHORT);
3466         hash_keyword(state, "signed",        TOK_SIGNED);
3467         hash_keyword(state, "sizeof",        TOK_SIZEOF);
3468         hash_keyword(state, "static",        TOK_STATIC);
3469         hash_keyword(state, "struct",        TOK_STRUCT);
3470         hash_keyword(state, "switch",        TOK_SWITCH);
3471         hash_keyword(state, "typedef",       TOK_TYPEDEF);
3472         hash_keyword(state, "union",         TOK_UNION);
3473         hash_keyword(state, "unsigned",      TOK_UNSIGNED);
3474         hash_keyword(state, "void",          TOK_VOID);
3475         hash_keyword(state, "volatile",      TOK_VOLATILE);
3476         hash_keyword(state, "__volatile__",  TOK_VOLATILE);
3477         hash_keyword(state, "while",         TOK_WHILE);
3478         hash_keyword(state, "asm",           TOK_ASM);
3479         hash_keyword(state, "__asm__",       TOK_ASM);
3480         hash_keyword(state, "__attribute__", TOK_ATTRIBUTE);
3481         hash_keyword(state, "__alignof__",   TOK_ALIGNOF);
3482 }
3483
3484 static void register_macro_keywords(struct compile_state *state)
3485 {
3486         hash_keyword(state, "define",        TOK_MDEFINE);
3487         hash_keyword(state, "defined",       TOK_MDEFINED);
3488         hash_keyword(state, "undef",         TOK_MUNDEF);
3489         hash_keyword(state, "include",       TOK_MINCLUDE);
3490         hash_keyword(state, "line",          TOK_MLINE);
3491         hash_keyword(state, "error",         TOK_MERROR);
3492         hash_keyword(state, "warning",       TOK_MWARNING);
3493         hash_keyword(state, "pragma",        TOK_MPRAGMA);
3494         hash_keyword(state, "ifdef",         TOK_MIFDEF);
3495         hash_keyword(state, "ifndef",        TOK_MIFNDEF);
3496         hash_keyword(state, "elif",          TOK_MELIF);
3497         hash_keyword(state, "endif",         TOK_MENDIF);
3498 }
3499
3500
3501 static void undef_macro(struct compile_state *state, struct hash_entry *ident)
3502 {
3503         if (ident->sym_define != 0) {
3504                 struct macro *macro;
3505                 struct macro_arg *arg, *anext;
3506                 macro = ident->sym_define;
3507                 ident->sym_define = 0;
3508                 
3509                 /* Free the macro arguments... */
3510                 anext = macro->args;
3511                 while(anext) {
3512                         arg = anext;
3513                         anext = arg->next;
3514                         xfree(arg);
3515                 }
3516
3517                 /* Free the macro buffer */
3518                 xfree(macro->buf);
3519
3520                 /* Now free the macro itself */
3521                 xfree(macro);
3522         }
3523 }
3524
3525 static void do_define_macro(struct compile_state *state, 
3526         struct hash_entry *ident, const char *body, 
3527         int argc, struct macro_arg *args)
3528 {
3529         struct macro *macro;
3530         struct macro_arg *arg;
3531         size_t body_len;
3532
3533         /* Find the length of the body */
3534         body_len = strlen(body);
3535         macro = ident->sym_define;
3536         if (macro != 0) {
3537                 int identical_bodies, identical_args;
3538                 struct macro_arg *oarg;
3539                 /* Explicitly allow identical redfinitions of the same macro */
3540                 identical_bodies = 
3541                         (macro->buf_len == body_len) &&
3542                         (memcmp(macro->buf, body, body_len) == 0);
3543                 identical_args = macro->argc == argc;
3544                 oarg = macro->args;
3545                 arg = args;
3546                 while(identical_args && arg) {
3547                         identical_args = oarg->ident == arg->ident;
3548                         arg = arg->next;
3549                         oarg = oarg->next;
3550                 }
3551                 if (identical_bodies && identical_args) {
3552                         xfree(body);
3553                         return;
3554                 }
3555                 error(state, 0, "macro %s already defined\n", ident->name);
3556         }
3557 #if 0
3558         fprintf(state->errout, "#define %s: `%*.*s'\n",
3559                 ident->name, body_len, body_len, body);
3560 #endif
3561         macro = xmalloc(sizeof(*macro), "macro");
3562         macro->ident   = ident;
3563         macro->buf     = body;
3564         macro->buf_len = body_len;
3565         macro->args    = args;
3566         macro->argc    = argc;
3567
3568         ident->sym_define = macro;
3569 }
3570         
3571 static void define_macro(
3572         struct compile_state *state,
3573         struct hash_entry *ident,
3574         const char *body, int body_len,
3575         int argc, struct macro_arg *args)
3576 {
3577         char *buf;
3578         buf = xmalloc(body_len + 1, "macro buf");
3579         memcpy(buf, body, body_len);
3580         buf[body_len] = '\0';
3581         do_define_macro(state, ident, buf, argc, args);
3582 }
3583
3584 static void register_builtin_macro(struct compile_state *state,
3585         const char *name, const char *value)
3586 {
3587         struct hash_entry *ident;
3588
3589         if (value[0] == '(') {
3590                 internal_error(state, 0, "Builtin macros with arguments not supported");
3591         }
3592         ident = lookup(state, name, strlen(name));
3593         define_macro(state, ident, value, strlen(value), -1, 0);
3594 }
3595
3596 static void register_builtin_macros(struct compile_state *state)
3597 {
3598         char buf[30];
3599         char scratch[30];
3600         time_t now;
3601         struct tm *tm;
3602         now = time(NULL);
3603         tm = localtime(&now);
3604
3605         register_builtin_macro(state, "__ROMCC__", VERSION_MAJOR);
3606         register_builtin_macro(state, "__ROMCC_MINOR__", VERSION_MINOR);
3607         register_builtin_macro(state, "__FILE__", "\"This should be the filename\"");
3608         register_builtin_macro(state, "__LINE__", "54321");
3609
3610         strftime(scratch, sizeof(scratch), "%b %e %Y", tm);
3611         sprintf(buf, "\"%s\"", scratch);
3612         register_builtin_macro(state, "__DATE__", buf);
3613
3614         strftime(scratch, sizeof(scratch), "%H:%M:%S", tm);
3615         sprintf(buf, "\"%s\"", scratch);
3616         register_builtin_macro(state, "__TIME__", buf);
3617
3618         /* I can't be a conforming implementation of C :( */
3619         register_builtin_macro(state, "__STDC__", "0");
3620         /* In particular I don't conform to C99 */
3621         register_builtin_macro(state, "__STDC_VERSION__", "199901L");
3622         
3623 }
3624
3625 static void process_cmdline_macros(struct compile_state *state)
3626 {
3627         const char **macro, *name;
3628         struct hash_entry *ident;
3629         for(macro = state->compiler->defines; (name = *macro); macro++) {
3630                 const char *body;
3631                 size_t name_len;
3632
3633                 name_len = strlen(name);
3634                 body = strchr(name, '=');
3635                 if (!body) {
3636                         body = "\0";
3637                 } else {
3638                         name_len = body - name;
3639                         body++;
3640                 }
3641                 ident = lookup(state, name, name_len);
3642                 define_macro(state, ident, body, strlen(body), -1, 0);
3643         }
3644         for(macro = state->compiler->undefs; (name = *macro); macro++) {
3645                 ident = lookup(state, name, strlen(name));
3646                 undef_macro(state, ident);
3647         }
3648 }
3649
3650 static int spacep(int c)
3651 {
3652         int ret = 0;
3653         switch(c) {
3654         case ' ':
3655         case '\t':
3656         case '\f':
3657         case '\v':
3658         case '\r':
3659                 ret = 1;
3660                 break;
3661         }
3662         return ret;
3663 }
3664
3665 static int digitp(int c)
3666 {
3667         int ret = 0;
3668         switch(c) {
3669         case '0': case '1': case '2': case '3': case '4': 
3670         case '5': case '6': case '7': case '8': case '9':
3671                 ret = 1;
3672                 break;
3673         }
3674         return ret;
3675 }
3676 static int digval(int c)
3677 {
3678         int val = -1;
3679         if ((c >= '0') && (c <= '9')) {
3680                 val = c - '0';
3681         }
3682         return val;
3683 }
3684
3685 static int hexdigitp(int c)
3686 {
3687         int ret = 0;
3688         switch(c) {
3689         case '0': case '1': case '2': case '3': case '4': 
3690         case '5': case '6': case '7': case '8': case '9':
3691         case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
3692         case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
3693                 ret = 1;
3694                 break;
3695         }
3696         return ret;
3697 }
3698 static int hexdigval(int c) 
3699 {
3700         int val = -1;
3701         if ((c >= '0') && (c <= '9')) {
3702                 val = c - '0';
3703         }
3704         else if ((c >= 'A') && (c <= 'F')) {
3705                 val = 10 + (c - 'A');
3706         }
3707         else if ((c >= 'a') && (c <= 'f')) {
3708                 val = 10 + (c - 'a');
3709         }
3710         return val;
3711 }
3712
3713 static int octdigitp(int c)
3714 {
3715         int ret = 0;
3716         switch(c) {
3717         case '0': case '1': case '2': case '3': 
3718         case '4': case '5': case '6': case '7':
3719                 ret = 1;
3720                 break;
3721         }
3722         return ret;
3723 }
3724 static int octdigval(int c)
3725 {
3726         int val = -1;
3727         if ((c >= '0') && (c <= '7')) {
3728                 val = c - '0';
3729         }
3730         return val;
3731 }
3732
3733 static int letterp(int c)
3734 {
3735         int ret = 0;
3736         switch(c) {
3737         case 'a': case 'b': case 'c': case 'd': case 'e':
3738         case 'f': case 'g': case 'h': case 'i': case 'j':
3739         case 'k': case 'l': case 'm': case 'n': case 'o':
3740         case 'p': case 'q': case 'r': case 's': case 't':
3741         case 'u': case 'v': case 'w': case 'x': case 'y':
3742         case 'z':
3743         case 'A': case 'B': case 'C': case 'D': case 'E':
3744         case 'F': case 'G': case 'H': case 'I': case 'J':
3745         case 'K': case 'L': case 'M': case 'N': case 'O':
3746         case 'P': case 'Q': case 'R': case 'S': case 'T':
3747         case 'U': case 'V': case 'W': case 'X': case 'Y':
3748         case 'Z':
3749         case '_':
3750                 ret = 1;
3751                 break;
3752         }
3753         return ret;
3754 }
3755
3756 static const char *identifier(const char *str, const char *end)
3757 {
3758         if (letterp(*str)) {
3759                 for(; str < end; str++) {
3760                         int c;
3761                         c = *str;
3762                         if (!letterp(c) && !digitp(c)) {
3763                                 break;
3764                         }
3765                 }
3766         }
3767         return str;
3768 }
3769
3770 static int char_value(struct compile_state *state,
3771         const signed char **strp, const signed char *end)
3772 {
3773         const signed char *str;
3774         int c;
3775         str = *strp;
3776         c = *str++;
3777         if ((c == '\\') && (str < end)) {
3778                 switch(*str) {
3779                 case 'n':  c = '\n'; str++; break;
3780                 case 't':  c = '\t'; str++; break;
3781                 case 'v':  c = '\v'; str++; break;
3782                 case 'b':  c = '\b'; str++; break;
3783                 case 'r':  c = '\r'; str++; break;
3784                 case 'f':  c = '\f'; str++; break;
3785                 case 'a':  c = '\a'; str++; break;
3786                 case '\\': c = '\\'; str++; break;
3787                 case '?':  c = '?';  str++; break;
3788                 case '\'': c = '\''; str++; break;
3789                 case '"':  c = '"';  str++; break;
3790                 case 'x': 
3791                         c = 0;
3792                         str++;
3793                         while((str < end) && hexdigitp(*str)) {
3794                                 c <<= 4;
3795                                 c += hexdigval(*str);
3796                                 str++;
3797                         }
3798                         break;
3799                 case '0': case '1': case '2': case '3': 
3800                 case '4': case '5': case '6': case '7':
3801                         c = 0;
3802                         while((str < end) && octdigitp(*str)) {
3803                                 c <<= 3;
3804                                 c += octdigval(*str);
3805                                 str++;
3806                         }
3807                         break;
3808                 default:
3809                         error(state, 0, "Invalid character constant");
3810                         break;
3811                 }
3812         }
3813         *strp = str;
3814         return c;
3815 }
3816
3817 static const char *next_char(struct file_state *file, const char *pos, int index)
3818 {
3819         const char *end = file->buf + file->size;
3820         while(pos < end) {
3821                 /* Lookup the character */
3822                 int size = 1;
3823                 int c = *pos;
3824                 /* Is this a trigraph? */
3825                 if (file->trigraphs &&
3826                         (c == '?') && ((end - pos) >= 3) && (pos[1] == '?')) 
3827                 {
3828                         switch(pos[2]) {
3829                         case '=': c = '#'; break;
3830                         case '/': c = '\\'; break;
3831                         case '\'': c = '^'; break;
3832                         case '(': c = '['; break;
3833                         case ')': c = ']'; break;
3834                         case '!': c = '!'; break;
3835                         case '<': c = '{'; break;
3836                         case '>': c = '}'; break;
3837                         case '-': c = '~'; break;
3838                         }
3839                         if (c != '?') {
3840                                 size = 3;
3841                         }
3842                 }
3843                 /* Is this an escaped newline? */
3844                 if (file->join_lines &&
3845                         (c == '\\') && (pos + size < end) && (pos[1] == '\n')) 
3846                 {
3847                         /* At the start of a line just eat it */
3848                         if (pos == file->pos) {
3849                                 file->line++;
3850                                 file->report_line++;
3851                                 file->line_start = pos + size + 1;
3852                         }
3853                         pos += size + 1;
3854                 }
3855                 /* Do I need to ga any farther? */
3856                 else if (index == 0) {
3857                         break;
3858                 }
3859                 /* Process a normal character */
3860                 else {
3861                         pos += size;
3862                         index -= 1;
3863                 }
3864         }
3865         return pos;
3866 }
3867
3868 static int get_char(struct file_state *file, const char *pos)
3869 {
3870         const char *end = file->buf + file->size;
3871         int c;
3872         c = -1;
3873         pos = next_char(file, pos, 0);
3874         if (pos < end) {
3875                 /* Lookup the character */
3876                 c = *pos;
3877                 /* If it is a trigraph get the trigraph value */
3878                 if (file->trigraphs &&
3879                         (c == '?') && ((end - pos) >= 3) && (pos[1] == '?')) 
3880                 {
3881                         switch(pos[2]) {
3882                         case '=': c = '#'; break;
3883                         case '/': c = '\\'; break;
3884                         case '\'': c = '^'; break;
3885                         case '(': c = '['; break;
3886                         case ')': c = ']'; break;
3887                         case '!': c = '!'; break;
3888                         case '<': c = '{'; break;
3889                         case '>': c = '}'; break;
3890                         case '-': c = '~'; break;
3891                         }
3892                 }
3893         }
3894         return c;
3895 }
3896
3897 static void eat_chars(struct file_state *file, const char *targ)
3898 {
3899         const char *pos = file->pos;
3900         while(pos < targ) {
3901                 /* Do we have a newline? */
3902                 if (pos[0] == '\n') {
3903                         file->line++;
3904                         file->report_line++;
3905                         file->line_start = pos + 1;
3906                 }
3907                 pos++;
3908         }
3909         file->pos = pos;
3910 }
3911
3912
3913 static size_t char_strlen(struct file_state *file, const char *src, const char *end)
3914 {
3915         size_t len;
3916         len = 0;
3917         while(src < end) {
3918                 src = next_char(file, src, 1);
3919                 len++;
3920         }
3921         return len;
3922 }
3923
3924 static void char_strcpy(char *dest, 
3925         struct file_state *file, const char *src, const char *end)
3926 {
3927         while(src < end) {
3928                 int c;
3929                 c = get_char(file, src);
3930                 src = next_char(file, src, 1);
3931                 *dest++ = c;
3932         }
3933 }
3934
3935 static char *char_strdup(struct file_state *file, 
3936         const char *start, const char *end, const char *id)
3937 {
3938         char *str;
3939         size_t str_len;
3940         str_len = char_strlen(file, start, end);
3941         str = xcmalloc(str_len + 1, id);
3942         char_strcpy(str, file, start, end);
3943         str[str_len] = '\0';
3944         return str;
3945 }
3946
3947 static const char *after_digits(struct file_state *file, const char *ptr)
3948 {
3949         while(digitp(get_char(file, ptr))) {
3950                 ptr = next_char(file, ptr, 1);
3951         }
3952         return ptr;
3953 }
3954
3955 static const char *after_octdigits(struct file_state *file, const char *ptr)
3956 {
3957         while(octdigitp(get_char(file, ptr))) {
3958                 ptr = next_char(file, ptr, 1);
3959         }
3960         return ptr;
3961 }
3962
3963 static const char *after_hexdigits(struct file_state *file, const char *ptr)
3964 {
3965         while(hexdigitp(get_char(file, ptr))) {
3966                 ptr = next_char(file, ptr, 1);
3967         }
3968         return ptr;
3969 }
3970
3971 static const char *after_alnums(struct file_state *file, const char *ptr)
3972 {
3973         int c;
3974         c = get_char(file, ptr);
3975         while(letterp(c) || digitp(c)) {
3976                 ptr = next_char(file, ptr, 1);
3977                 c = get_char(file, ptr);
3978         }
3979         return ptr;
3980 }
3981
3982 static void save_string(struct file_state *file,
3983         struct token *tk, const char *start, const char *end, const char *id)
3984 {
3985         char *str;
3986
3987         /* Create a private copy of the string */
3988         str = char_strdup(file, start, end, id);
3989
3990         /* Store the copy in the token */
3991         tk->val.str = str;
3992         tk->str_len = strlen(str);
3993 }
3994
3995 static void raw_next_token(struct compile_state *state, 
3996         struct file_state *file, struct token *tk)
3997 {
3998         const char *token;
3999         int c, c1, c2, c3;
4000         const char *tokp;
4001         int eat;
4002         int tok;
4003
4004         tk->str_len = 0;
4005         tk->ident = 0;
4006         token = tokp = next_char(file, file->pos, 0);
4007         tok = TOK_UNKNOWN;
4008         c  = get_char(file, tokp);
4009         tokp = next_char(file, tokp, 1);
4010         eat = 0;
4011         c1 = get_char(file, tokp);
4012         c2 = get_char(file, next_char(file, tokp, 1));
4013         c3 = get_char(file, next_char(file, tokp, 2));
4014
4015         /* The end of the file */
4016         if (c == -1) {
4017                 tok = TOK_EOF;
4018         }
4019         /* Whitespace */
4020         else if (spacep(c)) {
4021                 tok = TOK_SPACE;
4022                 while (spacep(get_char(file, tokp))) {
4023                         tokp = next_char(file, tokp, 1);
4024                 }
4025         }
4026         /* EOL Comments */
4027         else if ((c == '/') && (c1 == '/')) {
4028                 tok = TOK_SPACE;
4029                 tokp = next_char(file, tokp, 1);
4030                 while((c = get_char(file, tokp)) != -1) {
4031                         /* Advance to the next character only after we verify
4032                          * the current character is not a newline.  
4033                          * EOL is special to the preprocessor so we don't
4034                          * want to loose any.
4035                          */
4036                         if (c == '\n') {
4037                                 break;
4038                         }
4039                         tokp = next_char(file, tokp, 1);
4040                 }
4041         }
4042         /* Comments */
4043         else if ((c == '/') && (c1 == '*')) {
4044                 tokp = next_char(file, tokp, 2);
4045                 c = c2;
4046                 while((c1 = get_char(file, tokp)) != -1) {
4047                         tokp = next_char(file, tokp, 1);
4048                         if ((c == '*') && (c1 == '/')) {
4049                                 tok = TOK_SPACE;
4050                                 break;
4051                         }
4052                         c = c1;
4053                 }
4054                 if (tok == TOK_UNKNOWN) {
4055                         error(state, 0, "unterminated comment");
4056                 }
4057         }
4058         /* string constants */
4059         else if ((c == '"') || ((c == 'L') && (c1 == '"'))) {
4060                 int wchar, multiline;
4061
4062                 wchar = 0;
4063                 multiline = 0;
4064                 if (c == 'L') {
4065                         wchar = 1;
4066                         tokp = next_char(file, tokp, 1);
4067                 }
4068                 while((c = get_char(file, tokp)) != -1) {
4069                         tokp = next_char(file, tokp, 1);
4070                         if (c == '\n') {
4071                                 multiline = 1;
4072                         }
4073                         else if (c == '\\') {
4074                                 tokp = next_char(file, tokp, 1);
4075                         }
4076                         else if (c == '"') {
4077                                 tok = TOK_LIT_STRING;
4078                                 break;
4079                         }
4080                 }
4081                 if (tok == TOK_UNKNOWN) {
4082                         error(state, 0, "unterminated string constant");
4083                 }
4084                 if (multiline) {
4085                         warning(state, 0, "multiline string constant");
4086                 }
4087
4088                 /* Save the string value */
4089                 save_string(file, tk, token, tokp, "literal string");
4090         }
4091         /* character constants */
4092         else if ((c == '\'') || ((c == 'L') && (c1 == '\''))) {
4093                 int wchar, multiline;
4094
4095                 wchar = 0;
4096                 multiline = 0;
4097                 if (c == 'L') {
4098                         wchar = 1;
4099                         tokp = next_char(file, tokp, 1);
4100                 }
4101                 while((c = get_char(file, tokp)) != -1) {
4102                         tokp = next_char(file, tokp, 1);
4103                         if (c == '\n') {
4104                                 multiline = 1;
4105                         }
4106                         else if (c == '\\') {
4107                                 tokp = next_char(file, tokp, 1);
4108                         }
4109                         else if (c == '\'') {
4110                                 tok = TOK_LIT_CHAR;
4111                                 break;
4112                         }
4113                 }
4114                 if (tok == TOK_UNKNOWN) {
4115                         error(state, 0, "unterminated character constant");
4116                 }
4117                 if (multiline) {
4118                         warning(state, 0, "multiline character constant");
4119                 }
4120
4121                 /* Save the character value */
4122                 save_string(file, tk, token, tokp, "literal character");
4123         }
4124         /* integer and floating constants 
4125          * Integer Constants
4126          * {digits}
4127          * 0[Xx]{hexdigits}
4128          * 0{octdigit}+
4129          * 
4130          * Floating constants
4131          * {digits}.{digits}[Ee][+-]?{digits}
4132          * {digits}.{digits}
4133          * {digits}[Ee][+-]?{digits}
4134          * .{digits}[Ee][+-]?{digits}
4135          * .{digits}
4136          */
4137         else if (digitp(c) || ((c == '.') && (digitp(c1)))) {
4138                 const char *next;
4139                 int is_float;
4140                 int cn;
4141                 is_float = 0;
4142                 if (c != '.') {
4143                         next = after_digits(file, tokp);
4144                 }
4145                 else {
4146                         next = token;
4147                 }
4148                 cn = get_char(file, next);
4149                 if (cn == '.') {
4150                         next = next_char(file, next, 1);
4151                         next = after_digits(file, next);
4152                         is_float = 1;
4153                 }
4154                 cn = get_char(file, next);
4155                 if ((cn == 'e') || (cn == 'E')) {
4156                         const char *new;
4157                         next = next_char(file, next, 1);
4158                         cn = get_char(file, next);
4159                         if ((cn == '+') || (cn == '-')) {
4160                                 next = next_char(file, next, 1);
4161                         }
4162                         new = after_digits(file, next);
4163                         is_float |= (new != next);
4164                         next = new;
4165                 }
4166                 if (is_float) {
4167                         tok = TOK_LIT_FLOAT;
4168                         cn = get_char(file, next);
4169                         if ((cn  == 'f') || (cn == 'F') || (cn == 'l') || (cn == 'L')) {
4170                                 next = next_char(file, next, 1);
4171                         }
4172                 }
4173                 if (!is_float && digitp(c)) {
4174                         tok = TOK_LIT_INT;
4175                         if ((c == '0') && ((c1 == 'x') || (c1 == 'X'))) {
4176                                 next = next_char(file, tokp, 1);
4177                                 next = after_hexdigits(file, next);
4178                         }
4179                         else if (c == '0') {
4180                                 next = after_octdigits(file, tokp);
4181                         }
4182                         else {
4183                                 next = after_digits(file, tokp);
4184                         }
4185                         /* crazy integer suffixes */
4186                         cn = get_char(file, next);
4187                         if ((cn == 'u') || (cn == 'U')) {
4188                                 next = next_char(file, next, 1);
4189                                 cn = get_char(file, next);
4190                                 if ((cn == 'l') || (cn == 'L')) {
4191                                         next = next_char(file, next, 1);
4192                                         cn = get_char(file, next);
4193                                 }
4194                                 if ((cn == 'l') || (cn == 'L')) {
4195                                         next = next_char(file, next, 1);
4196                                 }
4197                         }
4198                         else if ((cn == 'l') || (cn == 'L')) {
4199                                 next = next_char(file, next, 1);
4200                                 cn = get_char(file, next);
4201                                 if ((cn == 'l') || (cn == 'L')) {
4202                                         next = next_char(file, next, 1);
4203                                         cn = get_char(file, next);
4204                                 }
4205                                 if ((cn == 'u') || (cn == 'U')) {
4206                                         next = next_char(file, next, 1);
4207                                 }
4208                         }
4209                 }
4210                 tokp = next;
4211
4212                 /* Save the integer/floating point value */
4213                 save_string(file, tk, token, tokp, "literal number");
4214         }
4215         /* identifiers */
4216         else if (letterp(c)) {
4217                 tok = TOK_IDENT;
4218
4219                 /* Find and save the identifier string */
4220                 tokp = after_alnums(file, tokp);
4221                 save_string(file, tk, token, tokp, "identifier");
4222
4223                 /* Look up to see which identifier it is */
4224                 tk->ident = lookup(state, tk->val.str, tk->str_len);
4225
4226                 /* Free the identifier string */
4227                 tk->str_len = 0;
4228                 xfree(tk->val.str);
4229
4230                 /* See if this identifier can be macro expanded */
4231                 tk->val.notmacro = 0;
4232                 c = get_char(file, tokp);
4233                 if (c == '$') {
4234                         tokp = next_char(file, tokp, 1);
4235                         tk->val.notmacro = 1;
4236                 }
4237         }
4238         /* C99 alternate macro characters */
4239         else if ((c == '%') && (c1 == ':') && (c2 == '%') && (c3 == ':')) { 
4240                 eat += 3;
4241                 tok = TOK_CONCATENATE; 
4242         }
4243         else if ((c == '.') && (c1 == '.') && (c2 == '.')) { eat += 2; tok = TOK_DOTS; }
4244         else if ((c == '<') && (c1 == '<') && (c2 == '=')) { eat += 2; tok = TOK_SLEQ; }
4245         else if ((c == '>') && (c1 == '>') && (c2 == '=')) { eat += 2; tok = TOK_SREQ; }
4246         else if ((c == '*') && (c1 == '=')) { eat += 1; tok = TOK_TIMESEQ; }
4247         else if ((c == '/') && (c1 == '=')) { eat += 1; tok = TOK_DIVEQ; }
4248         else if ((c == '%') && (c1 == '=')) { eat += 1; tok = TOK_MODEQ; }
4249         else if ((c == '+') && (c1 == '=')) { eat += 1; tok = TOK_PLUSEQ; }
4250         else if ((c == '-') && (c1 == '=')) { eat += 1; tok = TOK_MINUSEQ; }
4251         else if ((c == '&') && (c1 == '=')) { eat += 1; tok = TOK_ANDEQ; }
4252         else if ((c == '^') && (c1 == '=')) { eat += 1; tok = TOK_XOREQ; }
4253         else if ((c == '|') && (c1 == '=')) { eat += 1; tok = TOK_OREQ; }
4254         else if ((c == '=') && (c1 == '=')) { eat += 1; tok = TOK_EQEQ; }
4255         else if ((c == '!') && (c1 == '=')) { eat += 1; tok = TOK_NOTEQ; }
4256         else if ((c == '|') && (c1 == '|')) { eat += 1; tok = TOK_LOGOR; }
4257         else if ((c == '&') && (c1 == '&')) { eat += 1; tok = TOK_LOGAND; }
4258         else if ((c == '<') && (c1 == '=')) { eat += 1; tok = TOK_LESSEQ; }
4259         else if ((c == '>') && (c1 == '=')) { eat += 1; tok = TOK_MOREEQ; }
4260         else if ((c == '<') && (c1 == '<')) { eat += 1; tok = TOK_SL; }
4261         else if ((c == '>') && (c1 == '>')) { eat += 1; tok = TOK_SR; }
4262         else if ((c == '+') && (c1 == '+')) { eat += 1; tok = TOK_PLUSPLUS; }
4263         else if ((c == '-') && (c1 == '-')) { eat += 1; tok = TOK_MINUSMINUS; }
4264         else if ((c == '-') && (c1 == '>')) { eat += 1; tok = TOK_ARROW; }
4265         else if ((c == '<') && (c1 == ':')) { eat += 1; tok = TOK_LBRACKET; }
4266         else if ((c == ':') && (c1 == '>')) { eat += 1; tok = TOK_RBRACKET; }
4267         else if ((c == '<') && (c1 == '%')) { eat += 1; tok = TOK_LBRACE; }
4268         else if ((c == '%') && (c1 == '>')) { eat += 1; tok = TOK_RBRACE; }
4269         else if ((c == '%') && (c1 == ':')) { eat += 1; tok = TOK_MACRO; }
4270         else if ((c == '#') && (c1 == '#')) { eat += 1; tok = TOK_CONCATENATE; }
4271         else if (c == ';') { tok = TOK_SEMI; }
4272         else if (c == '{') { tok = TOK_LBRACE; }
4273         else if (c == '}') { tok = TOK_RBRACE; }
4274         else if (c == ',') { tok = TOK_COMMA; }
4275         else if (c == '=') { tok = TOK_EQ; }
4276         else if (c == ':') { tok = TOK_COLON; }
4277         else if (c == '[') { tok = TOK_LBRACKET; }
4278         else if (c == ']') { tok = TOK_RBRACKET; }
4279         else if (c == '(') { tok = TOK_LPAREN; }
4280         else if (c == ')') { tok = TOK_RPAREN; }
4281         else if (c == '*') { tok = TOK_STAR; }
4282         else if (c == '>') { tok = TOK_MORE; }
4283         else if (c == '<') { tok = TOK_LESS; }
4284         else if (c == '?') { tok = TOK_QUEST; }
4285         else if (c == '|') { tok = TOK_OR; }
4286         else if (c == '&') { tok = TOK_AND; }
4287         else if (c == '^') { tok = TOK_XOR; }
4288         else if (c == '+') { tok = TOK_PLUS; }
4289         else if (c == '-') { tok = TOK_MINUS; }
4290         else if (c == '/') { tok = TOK_DIV; }
4291         else if (c == '%') { tok = TOK_MOD; }
4292         else if (c == '!') { tok = TOK_BANG; }
4293         else if (c == '.') { tok = TOK_DOT; }
4294         else if (c == '~') { tok = TOK_TILDE; }
4295         else if (c == '#') { tok = TOK_MACRO; }
4296         else if (c == '\n') { tok = TOK_EOL; }
4297
4298         tokp = next_char(file, tokp, eat);
4299         eat_chars(file, tokp);
4300         tk->tok = tok;
4301         tk->pos = token;
4302 }
4303
4304 static void check_tok(struct compile_state *state, struct token *tk, int tok)
4305 {
4306         if (tk->tok != tok) {
4307                 const char *name1, *name2;
4308                 name1 = tokens[tk->tok];
4309                 name2 = "";
4310                 if ((tk->tok == TOK_IDENT) || (tk->tok == TOK_MIDENT)) {
4311                         name2 = tk->ident->name;
4312                 }
4313                 error(state, 0, "\tfound %s %s expected %s",
4314                         name1, name2, tokens[tok]);
4315         }
4316 }
4317
4318 struct macro_arg_value {
4319         struct hash_entry *ident;
4320         unsigned char *value;
4321         size_t len;
4322 };
4323 static struct macro_arg_value *read_macro_args(
4324         struct compile_state *state, struct macro *macro, 
4325         struct file_state *file, struct token *tk)
4326 {
4327         struct macro_arg_value *argv;
4328         struct macro_arg *arg;
4329         int paren_depth;
4330         int i;
4331
4332         if (macro->argc == 0) {
4333                 do {
4334                         raw_next_token(state, file, tk);
4335                 } while(tk->tok == TOK_SPACE);
4336                 return NULL;
4337         }
4338         argv = xcmalloc(sizeof(*argv) * macro->argc, "macro args");
4339         for(i = 0, arg = macro->args; arg; arg = arg->next, i++) {
4340                 argv[i].value = 0;
4341                 argv[i].len   = 0;
4342                 argv[i].ident = arg->ident;
4343         }
4344         paren_depth = 0;
4345         i = 0;
4346         
4347         for(;;) {
4348                 const char *start;
4349                 size_t len;
4350                 start = file->pos;
4351                 raw_next_token(state, file, tk);
4352                 
4353                 if (!paren_depth && (tk->tok == TOK_COMMA) &&
4354                         (argv[i].ident != state->i___VA_ARGS__)) 
4355                 {
4356                         i++;
4357                         if (i >= macro->argc) {
4358                                 error(state, 0, "too many args to %s\n",
4359                                         macro->ident->name);
4360                         }
4361                         continue;
4362                 }
4363                 
4364                 if (tk->tok == TOK_LPAREN) {
4365                         paren_depth++;
4366                 }
4367                 
4368                 if (tk->tok == TOK_RPAREN) {
4369                         if (paren_depth == 0) {
4370                                 break;
4371                         }
4372                         paren_depth--;
4373                 }
4374                 if (tk->tok == TOK_EOF) {
4375                         error(state, 0, "End of file encountered while parsing macro arguments");
4376                 }
4377
4378                 len = char_strlen(file, start, file->pos);
4379                 argv[i].value = xrealloc(
4380                         argv[i].value, argv[i].len + len, "macro args");
4381                 char_strcpy(argv[i].value + argv[i].len, file, start, file->pos);
4382                 argv[i].len += len;
4383         }
4384         if (i != macro->argc -1) {
4385                 error(state, 0, "missing %s arg %d\n", 
4386                         macro->ident->name, i +2);
4387         }
4388         return argv;
4389 }
4390
4391
4392 static void free_macro_args(struct macro *macro, struct macro_arg_value *argv)
4393 {
4394         int i;
4395         for(i = 0; i < macro->argc; i++) {
4396                 xfree(argv[i].value);
4397         }
4398         xfree(argv);
4399 }
4400
4401 struct macro_buf {
4402         char *str;
4403         size_t len, pos;
4404 };
4405
4406 static void grow_macro_buf(struct compile_state *state,
4407         const char *id, struct macro_buf *buf,
4408         size_t grow)
4409 {
4410         if ((buf->pos + grow) >= buf->len) {
4411                 buf->str = xrealloc(buf->str, buf->len + grow, id);
4412                 buf->len += grow;
4413         }
4414 }
4415
4416 static void append_macro_text(struct compile_state *state,
4417         const char *id, struct macro_buf *buf,
4418         const char *fstart, size_t flen)
4419 {
4420         grow_macro_buf(state, id, buf, flen);
4421         memcpy(buf->str + buf->pos, fstart, flen);
4422 #if 0
4423         fprintf(state->errout, "append: `%*.*s' `%*.*s'\n",
4424                 buf->pos, buf->pos, buf->str,
4425                 flen, flen, buf->str + buf->pos);
4426 #endif
4427         buf->pos += flen;
4428 }
4429
4430
4431 static void append_macro_chars(struct compile_state *state,
4432         const char *id, struct macro_buf *buf,
4433         struct file_state *file, const char *start, const char *end)
4434 {
4435         size_t flen;
4436         flen = char_strlen(file, start, end);
4437         grow_macro_buf(state, id, buf, flen);
4438         char_strcpy(buf->str + buf->pos, file, start, end);
4439 #if 0
4440         fprintf(state->errout, "append: `%*.*s' `%*.*s'\n",
4441                 buf->pos, buf->pos, buf->str,
4442                 flen, flen, buf->str + buf->pos);
4443 #endif
4444         buf->pos += flen;
4445 }
4446
4447 static int compile_macro(struct compile_state *state, 
4448         struct file_state **filep, struct token *tk);
4449
4450 static void macro_expand_args(struct compile_state *state, 
4451         struct macro *macro, struct macro_arg_value *argv, struct token *tk)
4452 {
4453         int i;
4454         
4455         for(i = 0; i < macro->argc; i++) {
4456                 struct file_state fmacro, *file;
4457                 struct macro_buf buf;
4458
4459                 fmacro.prev        = 0;
4460                 fmacro.basename    = argv[i].ident->name;
4461                 fmacro.dirname     = "";
4462                 fmacro.buf         = argv[i].value;
4463                 fmacro.size        = argv[i].len;
4464                 fmacro.pos         = fmacro.buf;
4465                 fmacro.line        = 1;
4466                 fmacro.line_start  = fmacro.buf;
4467                 fmacro.report_line = 1;
4468                 fmacro.report_name = fmacro.basename;
4469                 fmacro.report_dir  = fmacro.dirname;
4470                 fmacro.macro       = 1;
4471                 fmacro.trigraphs   = 0;
4472                 fmacro.join_lines  = 0;
4473
4474                 buf.len = argv[i].len;
4475                 buf.str = xmalloc(buf.len, argv[i].ident->name);
4476                 buf.pos = 0;
4477
4478                 file = &fmacro;
4479                 for(;;) {
4480                         raw_next_token(state, file, tk);
4481                         
4482                         /* If we have recursed into another macro body
4483                          * get out of it.
4484                          */
4485                         if (tk->tok == TOK_EOF) {
4486                                 struct file_state *old;
4487                                 old = file;
4488                                 file = file->prev;
4489                                 if (!file) {
4490                                         break;
4491                                 }
4492                                 /* old->basename is used keep it */
4493                                 xfree(old->dirname);
4494                                 xfree(old->buf);
4495                                 xfree(old);
4496                                 continue;
4497                         }
4498                         else if (tk->ident && tk->ident->sym_define) {
4499                                 if (compile_macro(state, &file, tk)) {
4500                                         continue;
4501                                 }
4502                         }
4503
4504                         append_macro_chars(state, macro->ident->name, &buf,
4505                                 file, tk->pos, file->pos);
4506                 }
4507                         
4508                 xfree(argv[i].value);
4509                 argv[i].value = buf.str;
4510                 argv[i].len   = buf.pos;
4511         }
4512         return;
4513 }
4514
4515 static void expand_macro(struct compile_state *state,
4516         struct macro *macro, struct macro_buf *buf,
4517         struct macro_arg_value *argv, struct token *tk)
4518 {
4519         struct file_state fmacro;
4520         const char space[] = " ";
4521         const char *fstart;
4522         size_t flen;
4523         int i, j;
4524
4525         /* Place the macro body in a dummy file */
4526         fmacro.prev        = 0;
4527         fmacro.basename    = macro->ident->name;
4528         fmacro.dirname     = "";
4529         fmacro.buf         = macro->buf;
4530         fmacro.size        = macro->buf_len;
4531         fmacro.pos         = fmacro.buf;
4532         fmacro.line        = 1;
4533         fmacro.line_start  = fmacro.buf;
4534         fmacro.report_line = 1;
4535         fmacro.report_name = fmacro.basename;
4536         fmacro.report_dir  = fmacro.dirname;
4537         fmacro.macro       = 1;
4538         fmacro.trigraphs   = 0;
4539         fmacro.join_lines  = 0;
4540         
4541         /* Allocate a buffer to hold the macro expansion */
4542         buf->len = macro->buf_len + 3;
4543         buf->str = xmalloc(buf->len, macro->ident->name);
4544         buf->pos = 0;
4545         
4546         fstart = fmacro.pos;
4547         raw_next_token(state, &fmacro, tk);
4548         while(tk->tok != TOK_EOF) {
4549                 flen = fmacro.pos - fstart;
4550                 switch(tk->tok) {
4551                 case TOK_IDENT:
4552                         for(i = 0; i < macro->argc; i++) {
4553                                 if (argv[i].ident == tk->ident) {
4554                                         break;
4555                                 }
4556                         }
4557                         if (i >= macro->argc) {
4558                                 break;
4559                         }
4560                         /* Substitute macro parameter */
4561                         fstart = argv[i].value;
4562                         flen   = argv[i].len;
4563                         break;
4564                 case TOK_MACRO:
4565                         if (macro->argc < 0) {
4566                                 break;
4567                         }
4568                         do {
4569                                 raw_next_token(state, &fmacro, tk);
4570                         } while(tk->tok == TOK_SPACE);
4571                         check_tok(state, tk, TOK_IDENT);
4572                         for(i = 0; i < macro->argc; i++) {
4573                                 if (argv[i].ident == tk->ident) {
4574                                         break;
4575                                 }
4576                         }
4577                         if (i >= macro->argc) {
4578                                 error(state, 0, "parameter `%s' not found",
4579                                         tk->ident->name);
4580                         }
4581                         /* Stringize token */
4582                         append_macro_text(state, macro->ident->name, buf, "\"", 1);
4583                         for(j = 0; j < argv[i].len; j++) {
4584                                 char *str = argv[i].value + j;
4585                                 size_t len = 1;
4586                                 if (*str == '\\') {
4587                                         str = "\\";
4588                                         len = 2;
4589                                 } 
4590                                 else if (*str == '"') {
4591                                         str = "\\\"";
4592                                         len = 2;
4593                                 }
4594                                 append_macro_text(state, macro->ident->name, buf, str, len);
4595                         }
4596                         append_macro_text(state, macro->ident->name, buf, "\"", 1);
4597                         fstart = 0;
4598                         flen   = 0;
4599                         break;
4600                 case TOK_CONCATENATE:
4601                         /* Concatenate tokens */
4602                         /* Delete the previous whitespace token */
4603                         if (buf->str[buf->pos - 1] == ' ') {
4604                                 buf->pos -= 1;
4605                         }
4606                         /* Skip the next sequence of whitspace tokens */
4607                         do {
4608                                 fstart = fmacro.pos;
4609                                 raw_next_token(state, &fmacro, tk);
4610                         } while(tk->tok == TOK_SPACE);
4611                         /* Restart at the top of the loop.
4612                          * I need to process the non white space token.
4613                          */
4614                         continue;
4615                         break;
4616                 case TOK_SPACE:
4617                         /* Collapse multiple spaces into one */
4618                         if (buf->str[buf->pos - 1] != ' ') {
4619                                 fstart = space;
4620                                 flen   = 1;
4621                         } else {
4622                                 fstart = 0;
4623                                 flen   = 0;
4624                         }
4625                         break;
4626                 default:
4627                         break;
4628                 }
4629
4630                 append_macro_text(state, macro->ident->name, buf, fstart, flen);
4631                 
4632                 fstart = fmacro.pos;
4633                 raw_next_token(state, &fmacro, tk);
4634         }
4635 }
4636
4637 static void tag_macro_name(struct compile_state *state,
4638         struct macro *macro, struct macro_buf *buf,
4639         struct token *tk)
4640 {
4641         /* Guard all instances of the macro name in the replacement
4642          * text from further macro expansion.
4643          */
4644         struct file_state fmacro;
4645         const char *fstart;
4646         size_t flen;
4647
4648         /* Put the old macro expansion buffer in a file */
4649         fmacro.prev        = 0;
4650         fmacro.basename    = macro->ident->name;
4651         fmacro.dirname     = "";
4652         fmacro.buf         = buf->str;
4653         fmacro.size        = buf->pos;
4654         fmacro.pos         = fmacro.buf;
4655         fmacro.line        = 1;
4656         fmacro.line_start  = fmacro.buf;
4657         fmacro.report_line = 1;
4658         fmacro.report_name = fmacro.basename;
4659         fmacro.report_dir  = fmacro.dirname;
4660         fmacro.macro       = 1;
4661         fmacro.trigraphs   = 0;
4662         fmacro.join_lines  = 0;
4663         
4664         /* Allocate a new macro expansion buffer */
4665         buf->len = macro->buf_len + 3;
4666         buf->str = xmalloc(buf->len, macro->ident->name);
4667         buf->pos = 0;
4668         
4669         fstart = fmacro.pos;
4670         raw_next_token(state, &fmacro, tk);
4671         while(tk->tok != TOK_EOF) {
4672                 flen = fmacro.pos - fstart;
4673                 if ((tk->tok == TOK_IDENT) &&
4674                         (tk->ident == macro->ident) &&
4675                         (tk->val.notmacro == 0)) 
4676                 {
4677                         append_macro_text(state, macro->ident->name, buf, fstart, flen);
4678                         fstart = "$";
4679                         flen   = 1;
4680                 }
4681
4682                 append_macro_text(state, macro->ident->name, buf, fstart, flen);
4683                 
4684                 fstart = fmacro.pos;
4685                 raw_next_token(state, &fmacro, tk);
4686         }
4687         xfree(fmacro.buf);
4688 }
4689
4690 static int compile_macro(struct compile_state *state, 
4691         struct file_state **filep, struct token *tk)
4692 {
4693         struct file_state *file;
4694         struct hash_entry *ident;
4695         struct macro *macro;
4696         struct macro_arg_value *argv;
4697         struct macro_buf buf;
4698
4699 #if 0
4700         fprintf(state->errout, "macro: %s\n", tk->ident->name);
4701 #endif
4702         ident = tk->ident;
4703         macro = ident->sym_define;
4704
4705         /* If this token comes from a macro expansion ignore it */
4706         if (tk->val.notmacro) {
4707                 return 0;
4708         }
4709         /* If I am a function like macro and the identifier is not followed
4710          * by a left parenthesis, do nothing.
4711          */
4712         if ((macro->argc >= 0) && (get_char(*filep, (*filep)->pos) != '(')) {
4713                 return 0;
4714         }
4715
4716         /* Read in the macro arguments */
4717         argv = 0;
4718         if (macro->argc >= 0) {
4719                 raw_next_token(state, *filep, tk);
4720                 check_tok(state, tk, TOK_LPAREN);
4721
4722                 argv = read_macro_args(state, macro, *filep, tk);
4723
4724                 check_tok(state, tk, TOK_RPAREN);
4725         }
4726         /* Macro expand the macro arguments */
4727         macro_expand_args(state, macro, argv, tk);
4728
4729         buf.str = 0;
4730         buf.len = 0;
4731         buf.pos = 0;
4732         if (ident == state->i___FILE__) {
4733                 buf.len = strlen(state->file->basename) + 1 + 2 + 3;
4734                 buf.str = xmalloc(buf.len, ident->name);
4735                 sprintf(buf.str, "\"%s\"", state->file->basename);
4736                 buf.pos = strlen(buf.str);
4737         }
4738         else if (ident == state->i___LINE__) {
4739                 buf.len = 30;
4740                 buf.str = xmalloc(buf.len, ident->name);
4741                 sprintf(buf.str, "%d", state->file->line);
4742                 buf.pos = strlen(buf.str);
4743         }
4744         else {
4745                 expand_macro(state, macro, &buf, argv, tk);
4746         }
4747         /* Tag the macro name with a $ so it will no longer
4748          * be regonized as a canidate for macro expansion.
4749          */
4750         tag_macro_name(state, macro, &buf, tk);
4751
4752 #if 0
4753         fprintf(state->errout, "%s: %d -> `%*.*s'\n",
4754                 ident->name, buf.pos, buf.pos, (int)(buf.pos), buf.str);
4755 #endif
4756
4757         free_macro_args(macro, argv);
4758
4759         file = xmalloc(sizeof(*file), "file_state");
4760         file->prev        = *filep;
4761         file->basename    = xstrdup(ident->name);
4762         file->dirname     = xstrdup("");
4763         file->buf         = buf.str;
4764         file->size        = buf.pos;
4765         file->pos         = file->buf;
4766         file->line        = 1;
4767         file->line_start  = file->pos;
4768         file->report_line = 1;
4769         file->report_name = file->basename;
4770         file->report_dir  = file->dirname;
4771         file->macro       = 1;
4772         file->trigraphs   = 0;
4773         file->join_lines  = 0;
4774         *filep = file;
4775         return 1;
4776 }
4777
4778 static void eat_tokens(struct compile_state *state, int targ_tok)
4779 {
4780         if (state->eat_depth > 0) {
4781                 internal_error(state, 0, "Already eating...");
4782         }
4783         state->eat_depth = state->if_depth;
4784         state->eat_targ = targ_tok;
4785 }
4786 static int if_eat(struct compile_state *state)
4787 {
4788         return state->eat_depth > 0;
4789 }
4790 static int if_value(struct compile_state *state)
4791 {
4792         int index, offset;
4793         index = state->if_depth / CHAR_BIT;
4794         offset = state->if_depth % CHAR_BIT;
4795         return !!(state->if_bytes[index] & (1 << (offset)));
4796 }
4797 static void set_if_value(struct compile_state *state, int value) 
4798 {
4799         int index, offset;
4800         index = state->if_depth / CHAR_BIT;
4801         offset = state->if_depth % CHAR_BIT;
4802
4803         state->if_bytes[index] &= ~(1 << offset);
4804         if (value) {
4805                 state->if_bytes[index] |= (1 << offset);
4806         }
4807 }
4808 static void in_if(struct compile_state *state, const char *name)
4809 {
4810         if (state->if_depth <= 0) {
4811                 error(state, 0, "%s without #if", name);
4812         }
4813 }
4814 static void enter_if(struct compile_state *state)
4815 {
4816         state->if_depth += 1;
4817         if (state->if_depth > MAX_PP_IF_DEPTH) {
4818                 error(state, 0, "#if depth too great");
4819         }
4820 }
4821 static void reenter_if(struct compile_state *state, const char *name)
4822 {
4823         in_if(state, name);
4824         if ((state->eat_depth == state->if_depth) &&
4825                 (state->eat_targ == TOK_MELSE)) {
4826                 state->eat_depth = 0;
4827                 state->eat_targ = 0;
4828         }
4829 }
4830 static void enter_else(struct compile_state *state, const char *name)
4831 {
4832         in_if(state, name);
4833         if ((state->eat_depth == state->if_depth) &&
4834                 (state->eat_targ == TOK_MELSE)) {
4835                 state->eat_depth = 0;
4836                 state->eat_targ = 0;
4837         }
4838 }
4839 static void exit_if(struct compile_state *state, const char *name)
4840 {
4841         in_if(state, name);
4842         if (state->eat_depth == state->if_depth) {
4843                 state->eat_depth = 0;
4844                 state->eat_targ = 0;
4845         }
4846         state->if_depth -= 1;
4847 }
4848
4849 static void raw_token(struct compile_state *state, struct token *tk)
4850 {
4851         struct file_state *file;
4852         int rescan;
4853
4854         file = state->file;
4855         raw_next_token(state, file, tk);
4856         do {
4857                 rescan = 0;
4858                 file = state->file;
4859                 /* Exit out of an include directive or macro call */
4860                 if ((tk->tok == TOK_EOF) && 
4861                         (file != state->macro_file) && file->prev) 
4862                 {
4863                         state->file = file->prev;
4864                         /* file->basename is used keep it */
4865                         xfree(file->dirname);
4866                         xfree(file->buf);
4867                         xfree(file);
4868                         file = 0;
4869                         raw_next_token(state, state->file, tk);
4870                         rescan = 1;
4871                 }
4872         } while(rescan);
4873 }
4874
4875 static void pp_token(struct compile_state *state, struct token *tk)
4876 {
4877         struct file_state *file;
4878         int rescan;
4879
4880         raw_token(state, tk);
4881         do {
4882                 rescan = 0;
4883                 file = state->file;
4884                 if (tk->tok == TOK_SPACE) {
4885                         raw_token(state, tk);
4886                         rescan = 1;
4887                 }
4888                 else if (tk->tok == TOK_IDENT) {
4889                         if (state->token_base == 0) {
4890                                 ident_to_keyword(state, tk);
4891                         } else {
4892                                 ident_to_macro(state, tk);
4893                         }
4894                 }
4895         } while(rescan);
4896 }
4897
4898 static void preprocess(struct compile_state *state, struct token *tk);
4899
4900 static void token(struct compile_state *state, struct token *tk)
4901 {
4902         int rescan;
4903         pp_token(state, tk);
4904         do {
4905                 rescan = 0;
4906                 /* Process a macro directive */
4907                 if (tk->tok == TOK_MACRO) {
4908                         /* Only match preprocessor directives at the start of a line */
4909                         const char *ptr;
4910                         ptr = state->file->line_start;
4911                         while((ptr < tk->pos)
4912                                 && spacep(get_char(state->file, ptr)))
4913                         {
4914                                 ptr = next_char(state->file, ptr, 1);
4915                         }
4916                         if (ptr == tk->pos) {
4917                                 preprocess(state, tk);
4918                                 rescan = 1;
4919                         }
4920                 }
4921                 /* Expand a macro call */
4922                 else if (tk->ident && tk->ident->sym_define) {
4923                         rescan = compile_macro(state, &state->file, tk);
4924                         if (rescan) {
4925                                 pp_token(state, tk);
4926                         }
4927                 }
4928                 /* Eat tokens disabled by the preprocessor 
4929                  * (Unless we are parsing a preprocessor directive 
4930                  */
4931                 else if (if_eat(state) && (state->token_base == 0)) {
4932                         pp_token(state, tk);
4933                         rescan = 1;
4934                 }
4935                 /* Make certain EOL only shows up in preprocessor directives */
4936                 else if ((tk->tok == TOK_EOL) && (state->token_base == 0)) {
4937                         pp_token(state, tk);
4938                         rescan = 1;
4939                 }
4940                 /* Error on unknown tokens */
4941                 else if (tk->tok == TOK_UNKNOWN) {
4942                         error(state, 0, "unknown token");
4943                 }
4944         } while(rescan);
4945 }
4946
4947
4948 static inline struct token *get_token(struct compile_state *state, int offset)
4949 {
4950         int index;
4951         index = state->token_base + offset;
4952         if (index >= sizeof(state->token)/sizeof(state->token[0])) {
4953                 internal_error(state, 0, "token array to small");
4954         }
4955         return &state->token[index];
4956 }
4957
4958 static struct token *do_eat_token(struct compile_state *state, int tok)
4959 {
4960         struct token *tk;
4961         int i;
4962         check_tok(state, get_token(state, 1), tok);
4963         
4964         /* Free the old token value */
4965         tk = get_token(state, 0);
4966         if (tk->str_len) {
4967                 memset((void *)tk->val.str, -1, tk->str_len);
4968                 xfree(tk->val.str);
4969         }
4970         /* Overwrite the old token with newer tokens */
4971         for(i = state->token_base; i < sizeof(state->token)/sizeof(state->token[0]) - 1; i++) {
4972                 state->token[i] = state->token[i + 1];
4973         }
4974         /* Clear the last token */
4975         memset(&state->token[i], 0, sizeof(state->token[i]));
4976         state->token[i].tok = -1;
4977
4978         /* Return the token */
4979         return tk;
4980 }
4981
4982 static int raw_peek(struct compile_state *state)
4983 {
4984         struct token *tk1;
4985         tk1 = get_token(state, 1);
4986         if (tk1->tok == -1) {
4987                 raw_token(state, tk1);
4988         }
4989         return tk1->tok;
4990 }
4991
4992 static struct token *raw_eat(struct compile_state *state, int tok)
4993 {
4994         raw_peek(state);
4995         return do_eat_token(state, tok);
4996 }
4997
4998 static int pp_peek(struct compile_state *state)
4999 {
5000         struct token *tk1;
5001         tk1 = get_token(state, 1);
5002         if (tk1->tok == -1) {
5003                 pp_token(state, tk1);
5004         }
5005         return tk1->tok;
5006 }
5007
5008 static struct token *pp_eat(struct compile_state *state, int tok)
5009 {
5010         pp_peek(state);
5011         return do_eat_token(state, tok);
5012 }
5013
5014 static int peek(struct compile_state *state)
5015 {
5016         struct token *tk1;
5017         tk1 = get_token(state, 1);
5018         if (tk1->tok == -1) {
5019                 token(state, tk1);
5020         }
5021         return tk1->tok;
5022 }
5023
5024 static int peek2(struct compile_state *state)
5025 {
5026         struct token *tk1, *tk2;
5027         tk1 = get_token(state, 1);
5028         tk2 = get_token(state, 2);
5029         if (tk1->tok == -1) {
5030                 token(state, tk1);
5031         }
5032         if (tk2->tok == -1) {
5033                 token(state, tk2);
5034         }
5035         return tk2->tok;
5036 }
5037
5038 static struct token *eat(struct compile_state *state, int tok)
5039 {
5040         peek(state);
5041         return do_eat_token(state, tok);
5042 }
5043
5044 static void compile_file(struct compile_state *state, const char *filename, int local)
5045 {
5046         char cwd[MAX_CWD_SIZE];
5047         const char *subdir, *base;
5048         int subdir_len;
5049         struct file_state *file;
5050         char *basename;
5051         file = xmalloc(sizeof(*file), "file_state");
5052
5053         base = strrchr(filename, '/');
5054         subdir = filename;
5055         if (base != 0) {
5056                 subdir_len = base - filename;
5057                 base++;
5058         }
5059         else {
5060                 base = filename;
5061                 subdir_len = 0;
5062         }
5063         basename = xmalloc(strlen(base) +1, "basename");
5064         strcpy(basename, base);
5065         file->basename = basename;
5066
5067         if (getcwd(cwd, sizeof(cwd)) == 0) {
5068                 die("cwd buffer to small");
5069         }
5070         if (subdir[0] == '/') {
5071                 file->dirname = xmalloc(subdir_len + 1, "dirname");
5072                 memcpy(file->dirname, subdir, subdir_len);
5073                 file->dirname[subdir_len] = '\0';
5074         }
5075         else {
5076                 const char *dir;
5077                 int dirlen;
5078                 const char **path;
5079                 /* Find the appropriate directory... */
5080                 dir = 0;
5081                 if (!state->file && exists(cwd, filename)) {
5082                         dir = cwd;
5083                 }
5084                 if (local && state->file && exists(state->file->dirname, filename)) {
5085                         dir = state->file->dirname;
5086                 }
5087                 for(path = state->compiler->include_paths; !dir && *path; path++) {
5088                         if (exists(*path, filename)) {
5089                                 dir = *path;
5090                         }
5091                 }
5092                 if (!dir) {
5093                         error(state, 0, "Cannot open `%s'\n", filename);
5094                 }
5095                 dirlen = strlen(dir);
5096                 file->dirname = xmalloc(dirlen + 1 + subdir_len + 1, "dirname");
5097                 memcpy(file->dirname, dir, dirlen);
5098                 file->dirname[dirlen] = '/';
5099                 memcpy(file->dirname + dirlen + 1, subdir, subdir_len);
5100                 file->dirname[dirlen + 1 + subdir_len] = '\0';
5101         }
5102         file->buf = slurp_file(file->dirname, file->basename, &file->size);
5103
5104         file->pos = file->buf;
5105         file->line_start = file->pos;
5106         file->line = 1;
5107
5108         file->report_line = 1;
5109         file->report_name = file->basename;
5110         file->report_dir  = file->dirname;
5111         file->macro       = 0;
5112         file->trigraphs   = (state->compiler->flags & COMPILER_TRIGRAPHS)? 1: 0;
5113         file->join_lines  = 1;
5114
5115         file->prev = state->file;
5116         state->file = file;
5117 }
5118
5119 static struct triple *constant_expr(struct compile_state *state);
5120 static void integral(struct compile_state *state, struct triple *def);
5121
5122 static int mcexpr(struct compile_state *state)
5123 {
5124         struct triple *cvalue;
5125         cvalue = constant_expr(state);
5126         integral(state, cvalue);
5127         if (cvalue->op != OP_INTCONST) {
5128                 error(state, 0, "integer constant expected");
5129         }
5130         return cvalue->u.cval != 0;
5131 }
5132
5133 static void preprocess(struct compile_state *state, struct token *current_token)
5134 {
5135         /* Doing much more with the preprocessor would require
5136          * a parser and a major restructuring.
5137          * Postpone that for later.
5138          */
5139         int old_token_base;
5140         int tok;
5141         
5142         state->macro_file = state->file;
5143
5144         old_token_base = state->token_base;
5145         state->token_base = current_token - state->token;
5146
5147         tok = pp_peek(state);
5148         switch(tok) {
5149         case TOK_LIT_INT:
5150         {
5151                 struct token *tk;
5152                 int override_line;
5153                 tk = pp_eat(state, TOK_LIT_INT);
5154                 override_line = strtoul(tk->val.str, 0, 10);
5155                 /* I have a preprocessor  line marker parse it */
5156                 if (pp_peek(state) == TOK_LIT_STRING) {
5157                         const char *token, *base;
5158                         char *name, *dir;
5159                         int name_len, dir_len;
5160                         tk = pp_eat(state, TOK_LIT_STRING);
5161                         name = xmalloc(tk->str_len, "report_name");
5162                         token = tk->val.str + 1;
5163                         base = strrchr(token, '/');
5164                         name_len = tk->str_len -2;
5165                         if (base != 0) {
5166                                 dir_len = base - token;
5167                                 base++;
5168                                 name_len -= base - token;
5169                         } else {
5170                                 dir_len = 0;
5171                                 base = token;
5172                         }
5173                         memcpy(name, base, name_len);
5174                         name[name_len] = '\0';
5175                         dir = xmalloc(dir_len + 1, "report_dir");
5176                         memcpy(dir, token, dir_len);
5177                         dir[dir_len] = '\0';
5178                         state->file->report_line = override_line - 1;
5179                         state->file->report_name = name;
5180                         state->file->report_dir = dir;
5181                         state->file->macro      = 0;
5182                 }
5183                 break;
5184         }
5185         case TOK_MLINE:
5186         {
5187                 struct token *tk;
5188                 pp_eat(state, TOK_MLINE);
5189                 tk = eat(state, TOK_LIT_INT);
5190                 state->file->report_line = strtoul(tk->val.str, 0, 10) -1;
5191                 if (pp_peek(state) == TOK_LIT_STRING) {
5192                         const char *token, *base;
5193                         char *name, *dir;
5194                         int name_len, dir_len;
5195                         tk = pp_eat(state, TOK_LIT_STRING);
5196                         name = xmalloc(tk->str_len, "report_name");
5197                         token = tk->val.str + 1;
5198                         base = strrchr(token, '/');
5199                         name_len = tk->str_len - 2;
5200                         if (base != 0) {
5201                                 dir_len = base - token;
5202                                 base++;
5203                                 name_len -= base - token;
5204                         } else {
5205                                 dir_len = 0;
5206                                 base = token;
5207                         }
5208                         memcpy(name, base, name_len);
5209                         name[name_len] = '\0';
5210                         dir = xmalloc(dir_len + 1, "report_dir");
5211                         memcpy(dir, token, dir_len);
5212                         dir[dir_len] = '\0';
5213                         state->file->report_name = name;
5214                         state->file->report_dir = dir;
5215                         state->file->macro      = 0;
5216                 }
5217                 break;
5218         }
5219         case TOK_MUNDEF:
5220         {
5221                 struct hash_entry *ident;
5222                 pp_eat(state, TOK_MUNDEF);
5223                 if (if_eat(state))  /* quit early when #if'd out */
5224                         break;
5225                 
5226                 ident = pp_eat(state, TOK_MIDENT)->ident;
5227
5228                 undef_macro(state, ident);
5229                 break;
5230         }
5231         case TOK_MPRAGMA:
5232                 pp_eat(state, TOK_MPRAGMA);
5233                 if (if_eat(state))  /* quit early when #if'd out */
5234                         break;
5235                 warning(state, 0, "Ignoring pragma"); 
5236                 break;
5237         case TOK_MELIF:
5238                 pp_eat(state, TOK_MELIF);
5239                 reenter_if(state, "#elif");
5240                 if (if_eat(state))   /* quit early when #if'd out */
5241                         break;
5242                 /* If the #if was taken the #elif just disables the following code */
5243                 if (if_value(state)) {
5244                         eat_tokens(state, TOK_MENDIF);
5245                 }
5246                 /* If the previous #if was not taken see if the #elif enables the 
5247                  * trailing code.
5248                  */
5249                 else {
5250                         set_if_value(state, mcexpr(state));
5251                         if (!if_value(state)) {
5252                                 eat_tokens(state, TOK_MELSE);
5253                         }
5254                 }
5255                 break;
5256         case TOK_MIF:
5257                 pp_eat(state, TOK_MIF);
5258                 enter_if(state);
5259                 if (if_eat(state))  /* quit early when #if'd out */
5260                         break;
5261                 set_if_value(state, mcexpr(state));
5262                 if (!if_value(state)) {
5263                         eat_tokens(state, TOK_MELSE);
5264                 }
5265                 break;
5266         case TOK_MIFNDEF:
5267         {
5268                 struct hash_entry *ident;
5269
5270                 pp_eat(state, TOK_MIFNDEF);
5271                 enter_if(state);
5272                 if (if_eat(state))  /* quit early when #if'd out */
5273                         break;
5274                 ident = pp_eat(state, TOK_MIDENT)->ident;
5275                 set_if_value(state, ident->sym_define == 0);
5276                 if (!if_value(state)) {
5277                         eat_tokens(state, TOK_MELSE);
5278                 }
5279                 break;
5280         }
5281         case TOK_MIFDEF:
5282         {
5283                 struct hash_entry *ident;
5284                 pp_eat(state, TOK_MIFDEF);
5285                 enter_if(state);
5286                 if (if_eat(state))  /* quit early when #if'd out */
5287                         break;
5288                 ident = pp_eat(state, TOK_MIDENT)->ident;
5289                 set_if_value(state, ident->sym_define != 0);
5290                 if (!if_value(state)) {
5291                         eat_tokens(state, TOK_MELSE);
5292                 }
5293                 break;
5294         }
5295         case TOK_MELSE:
5296                 pp_eat(state, TOK_MELSE);
5297                 enter_else(state, "#else");
5298                 if (!if_eat(state) && if_value(state)) {
5299                         eat_tokens(state, TOK_MENDIF);
5300                 }
5301                 break;
5302         case TOK_MENDIF:
5303                 pp_eat(state, TOK_MENDIF);
5304                 exit_if(state, "#endif");
5305                 break;
5306         case TOK_MDEFINE:
5307         {
5308                 struct hash_entry *ident;
5309                 struct macro_arg *args, **larg;
5310                 const char *mstart, *mend;
5311                 int argc;
5312
5313                 pp_eat(state, TOK_MDEFINE);
5314                 if (if_eat(state))  /* quit early when #if'd out */
5315                         break;
5316                 ident = pp_eat(state, TOK_MIDENT)->ident;
5317                 argc = -1;
5318                 args = 0;
5319                 larg = &args;
5320
5321                 /* Parse macro parameters */
5322                 if (raw_peek(state) == TOK_LPAREN) {
5323                         raw_eat(state, TOK_LPAREN);
5324                         argc += 1;
5325
5326                         for(;;) {
5327                                 struct macro_arg *narg, *arg;
5328                                 struct hash_entry *aident;
5329                                 int tok;
5330
5331                                 tok = pp_peek(state);
5332                                 if (!args && (tok == TOK_RPAREN)) {
5333                                         break;
5334                                 }
5335                                 else if (tok == TOK_DOTS) {
5336                                         pp_eat(state, TOK_DOTS);
5337                                         aident = state->i___VA_ARGS__;
5338                                 } 
5339                                 else {
5340                                         aident = pp_eat(state, TOK_MIDENT)->ident;
5341                                 }
5342                                 
5343                                 narg = xcmalloc(sizeof(*arg), "macro arg");
5344                                 narg->ident = aident;
5345
5346                                 /* Verify I don't have a duplicate identifier */
5347                                 for(arg = args; arg; arg = arg->next) {
5348                                         if (arg->ident == narg->ident) {
5349                                                 error(state, 0, "Duplicate macro arg `%s'",
5350                                                         narg->ident->name);
5351                                         }
5352                                 }
5353                                 /* Add the new argument to the end of the list */
5354                                 *larg = narg;
5355                                 larg = &narg->next;
5356                                 argc += 1;
5357
5358                                 if ((aident == state->i___VA_ARGS__) ||
5359                                         (pp_peek(state) != TOK_COMMA)) {
5360                                         break;
5361                                 }
5362                                 pp_eat(state, TOK_COMMA);
5363                         }
5364                         pp_eat(state, TOK_RPAREN);
5365                 }
5366                 /* Remove leading whitespace */
5367                 while(raw_peek(state) == TOK_SPACE) {
5368                         raw_eat(state, TOK_SPACE);
5369                 }
5370
5371                 /* Remember the start of the macro body */
5372                 tok = raw_peek(state);
5373                 mend = mstart = get_token(state, 1)->pos;
5374
5375                 /* Find the end of the macro */
5376                 for(tok = raw_peek(state); tok != TOK_EOL; tok = raw_peek(state)) {
5377                         raw_eat(state, tok);
5378                         /* Remember the end of the last non space token */
5379                         raw_peek(state);
5380                         if (tok != TOK_SPACE) {
5381                                 mend = get_token(state, 1)->pos;
5382                         }
5383                 }
5384                 
5385                 /* Now that I have found the body defined the token */
5386                 do_define_macro(state, ident,
5387                         char_strdup(state->file, mstart, mend, "macro buf"),
5388                         argc, args);
5389                 break;
5390         }
5391         case TOK_MERROR:
5392         {
5393                 const char *start, *end;
5394                 int len;
5395                 
5396                 pp_eat(state, TOK_MERROR);
5397                 /* Find the start of the line */
5398                 raw_peek(state);
5399                 start = get_token(state, 1)->pos;
5400
5401                 /* Find the end of the line */
5402                 while((tok = raw_peek(state)) != TOK_EOL) {
5403                         raw_eat(state, tok);
5404                 }
5405                 end = get_token(state, 1)->pos;
5406                 len = end - start;
5407                 if (!if_eat(state)) {
5408                         error(state, 0, "%*.*s", len, len, start);
5409                 }
5410                 break;
5411         }
5412         case TOK_MWARNING:
5413         {
5414                 const char *start, *end;
5415                 int len;
5416                 
5417                 pp_eat(state, TOK_MWARNING);
5418
5419                 /* Find the start of the line */
5420                 raw_peek(state);
5421                 start = get_token(state, 1)->pos;
5422                  
5423                 /* Find the end of the line */
5424                 while((tok = raw_peek(state)) != TOK_EOL) {
5425                         raw_eat(state, tok);
5426                 }
5427                 end = get_token(state, 1)->pos;
5428                 len = end - start;
5429                 if (!if_eat(state)) {
5430                         warning(state, 0, "%*.*s", len, len, start);
5431                 }
5432                 break;
5433         }
5434         case TOK_MINCLUDE:
5435         {
5436                 char *name;
5437                 int local;
5438                 local = 0;
5439                 name = 0;
5440
5441                 pp_eat(state, TOK_MINCLUDE);
5442                 tok = peek(state);
5443                 if (tok == TOK_LIT_STRING) {
5444                         struct token *tk;
5445                         const char *token;
5446                         int name_len;
5447                         tk = eat(state, TOK_LIT_STRING);
5448                         name = xmalloc(tk->str_len, "include");
5449                         token = tk->val.str +1;
5450                         name_len = tk->str_len -2;
5451                         if (*token == '"') {
5452                                 token++;
5453                                 name_len--;
5454                         }
5455                         memcpy(name, token, name_len);
5456                         name[name_len] = '\0';
5457                         local = 1;
5458                 }
5459                 else if (tok == TOK_LESS) {
5460                         struct macro_buf buf;
5461                         eat(state, TOK_LESS);
5462
5463                         buf.len = 40;
5464                         buf.str = xmalloc(buf.len, "include");
5465                         buf.pos = 0;
5466
5467                         tok = peek(state);
5468                         while((tok != TOK_MORE) &&
5469                                 (tok != TOK_EOL) && (tok != TOK_EOF))
5470                         {
5471                                 struct token *tk;
5472                                 tk = eat(state, tok);
5473                                 append_macro_chars(state, "include", &buf,
5474                                         state->file, tk->pos, state->file->pos);
5475                                 tok = peek(state);
5476                         }
5477                         append_macro_text(state, "include", &buf, "\0", 1);
5478                         if (peek(state) != TOK_MORE) {
5479                                 error(state, 0, "Unterminated include directive");
5480                         }
5481                         eat(state, TOK_MORE);
5482                         local = 0;
5483                         name = buf.str;
5484                 }
5485                 else {
5486                         error(state, 0, "Invalid include directive");
5487                 }
5488                 /* Error if there are any tokens after the include */
5489                 if (pp_peek(state) != TOK_EOL) {
5490                         error(state, 0, "garbage after include directive");
5491                 }
5492                 if (!if_eat(state)) {
5493                         compile_file(state, name, local);
5494                 }
5495                 xfree(name);
5496                 break;
5497         }
5498         case TOK_EOL:
5499                 /* Ignore # without a follwing ident */
5500                 break;
5501         default:
5502         {
5503                 const char *name1, *name2;
5504                 name1 = tokens[tok];
5505                 name2 = "";
5506                 if (tok == TOK_MIDENT) {
5507                         name2 = get_token(state, 1)->ident->name;
5508                 }
5509                 error(state, 0, "Invalid preprocessor directive: %s %s", 
5510                         name1, name2);
5511                 break;
5512         }
5513         }
5514         /* Consume the rest of the macro line */
5515         do {
5516                 tok = pp_peek(state);
5517                 pp_eat(state, tok);
5518         } while((tok != TOK_EOF) && (tok != TOK_EOL));
5519         state->token_base = old_token_base;
5520         state->macro_file = NULL;
5521         return;
5522 }
5523
5524 /* Type helper functions */
5525
5526 static struct type *new_type(
5527         unsigned int type, struct type *left, struct type *right)
5528 {
5529         struct type *result;
5530         result = xmalloc(sizeof(*result), "type");
5531         result->type = type;
5532         result->left = left;
5533         result->right = right;
5534         result->field_ident = 0;
5535         result->type_ident = 0;
5536         result->elements = 0;
5537         return result;
5538 }
5539
5540 static struct type *clone_type(unsigned int specifiers, struct type *old)
5541 {
5542         struct type *result;
5543         result = xmalloc(sizeof(*result), "type");
5544         memcpy(result, old, sizeof(*result));
5545         result->type &= TYPE_MASK;
5546         result->type |= specifiers;
5547         return result;
5548 }
5549
5550 static struct type *dup_type(struct compile_state *state, struct type *orig)
5551 {
5552         struct type *new;
5553         new = xcmalloc(sizeof(*new), "type");
5554         new->type = orig->type;
5555         new->field_ident = orig->field_ident;
5556         new->type_ident  = orig->type_ident;
5557         new->elements    = orig->elements;
5558         if (orig->left) {
5559                 new->left = dup_type(state, orig->left);
5560         }
5561         if (orig->right) {
5562                 new->right = dup_type(state, orig->right);
5563         }
5564         return new;
5565 }
5566
5567
5568 static struct type *invalid_type(struct compile_state *state, struct type *type)
5569 {
5570         struct type *invalid, *member;
5571         invalid = 0;
5572         if (!type) {
5573                 internal_error(state, 0, "type missing?");
5574         }
5575         switch(type->type & TYPE_MASK) {
5576         case TYPE_VOID:
5577         case TYPE_CHAR:         case TYPE_UCHAR:
5578         case TYPE_SHORT:        case TYPE_USHORT:
5579         case TYPE_INT:          case TYPE_UINT:
5580         case TYPE_LONG:         case TYPE_ULONG:
5581         case TYPE_LLONG:        case TYPE_ULLONG:
5582         case TYPE_POINTER:
5583         case TYPE_ENUM:
5584                 break;
5585         case TYPE_BITFIELD:
5586                 invalid = invalid_type(state, type->left);
5587                 break;
5588         case TYPE_ARRAY:
5589                 invalid = invalid_type(state, type->left);
5590                 break;
5591         case TYPE_STRUCT:
5592         case TYPE_TUPLE:
5593                 member = type->left;
5594                 while(member && (invalid == 0) && 
5595                         ((member->type & TYPE_MASK) == TYPE_PRODUCT)) {
5596                         invalid = invalid_type(state, member->left);
5597                         member = member->right;
5598                 }
5599                 if (!invalid) {
5600                         invalid = invalid_type(state, member);
5601                 }
5602                 break;
5603         case TYPE_UNION:
5604         case TYPE_JOIN:
5605                 member = type->left;
5606                 while(member && (invalid == 0) &&
5607                         ((member->type & TYPE_MASK) == TYPE_OVERLAP)) {
5608                         invalid = invalid_type(state, member->left);
5609                         member = member->right;
5610                 }
5611                 if (!invalid) {
5612                         invalid = invalid_type(state, member);
5613                 }
5614                 break;
5615         default:
5616                 invalid = type;
5617                 break;
5618         }
5619         return invalid;
5620         
5621 }
5622
5623 #define MASK_UCHAR(X)    ((X) & ((ulong_t)0xff))
5624 #define MASK_USHORT(X)   ((X) & (((ulong_t)1 << (SIZEOF_SHORT)) - 1))
5625 static inline ulong_t mask_uint(ulong_t x)
5626 {
5627         if (SIZEOF_INT < SIZEOF_LONG) {
5628                 ulong_t mask = (((ulong_t)1) << ((ulong_t)(SIZEOF_INT))) -1;
5629                 x &= mask;
5630         }
5631         return x;
5632 }
5633 #define MASK_UINT(X)      (mask_uint(X))
5634 #define MASK_ULONG(X)    (X)
5635
5636 static struct type void_type    = { .type  = TYPE_VOID };
5637 static struct type char_type    = { .type  = TYPE_CHAR };
5638 static struct type uchar_type   = { .type  = TYPE_UCHAR };
5639 static struct type short_type   = { .type  = TYPE_SHORT };
5640 static struct type ushort_type  = { .type  = TYPE_USHORT };
5641 static struct type int_type     = { .type  = TYPE_INT };
5642 static struct type uint_type    = { .type  = TYPE_UINT };
5643 static struct type long_type    = { .type  = TYPE_LONG };
5644 static struct type ulong_type   = { .type  = TYPE_ULONG };
5645 static struct type unknown_type = { .type  = TYPE_UNKNOWN };
5646
5647 static struct type void_ptr_type  = {
5648         .type = TYPE_POINTER,
5649         .left = &void_type,
5650 };
5651
5652 static struct type void_func_type = { 
5653         .type  = TYPE_FUNCTION,
5654         .left  = &void_type,
5655         .right = &void_type,
5656 };
5657
5658 static size_t bits_to_bytes(size_t size)
5659 {
5660         return (size + SIZEOF_CHAR - 1)/SIZEOF_CHAR;
5661 }
5662
5663 static struct triple *variable(struct compile_state *state, struct type *type)
5664 {
5665         struct triple *result;
5666         if ((type->type & STOR_MASK) != STOR_PERM) {
5667                 result = triple(state, OP_ADECL, type, 0, 0);
5668                 generate_lhs_pieces(state, result);
5669         }
5670         else {
5671                 result = triple(state, OP_SDECL, type, 0, 0);
5672         }
5673         return result;
5674 }
5675
5676 static void stor_of(FILE *fp, struct type *type)
5677 {
5678         switch(type->type & STOR_MASK) {
5679         case STOR_AUTO:
5680                 fprintf(fp, "auto ");
5681                 break;
5682         case STOR_STATIC:
5683                 fprintf(fp, "static ");
5684                 break;
5685         case STOR_LOCAL:
5686                 fprintf(fp, "local ");
5687                 break;
5688         case STOR_EXTERN:
5689                 fprintf(fp, "extern ");
5690                 break;
5691         case STOR_REGISTER:
5692                 fprintf(fp, "register ");
5693                 break;
5694         case STOR_TYPEDEF:
5695                 fprintf(fp, "typedef ");
5696                 break;
5697         case STOR_INLINE | STOR_LOCAL:
5698                 fprintf(fp, "inline ");
5699                 break;
5700         case STOR_INLINE | STOR_STATIC:
5701                 fprintf(fp, "static inline");
5702                 break;
5703         case STOR_INLINE | STOR_EXTERN:
5704                 fprintf(fp, "extern inline");
5705                 break;
5706         default:
5707                 fprintf(fp, "stor:%x", type->type & STOR_MASK);
5708                 break;
5709         }
5710 }
5711 static void qual_of(FILE *fp, struct type *type)
5712 {
5713         if (type->type & QUAL_CONST) {
5714                 fprintf(fp, " const");
5715         }
5716         if (type->type & QUAL_VOLATILE) {
5717                 fprintf(fp, " volatile");
5718         }
5719         if (type->type & QUAL_RESTRICT) {
5720                 fprintf(fp, " restrict");
5721         }
5722 }
5723
5724 static void name_of(FILE *fp, struct type *type)
5725 {
5726         unsigned int base_type;
5727         base_type = type->type & TYPE_MASK;
5728         if ((base_type != TYPE_PRODUCT) && (base_type != TYPE_OVERLAP)) {
5729                 stor_of(fp, type);
5730         }
5731         switch(base_type) {
5732         case TYPE_VOID:
5733                 fprintf(fp, "void");
5734                 qual_of(fp, type);
5735                 break;
5736         case TYPE_CHAR:
5737                 fprintf(fp, "signed char");
5738                 qual_of(fp, type);
5739                 break;
5740         case TYPE_UCHAR:
5741                 fprintf(fp, "unsigned char");
5742                 qual_of(fp, type);
5743                 break;
5744         case TYPE_SHORT:
5745                 fprintf(fp, "signed short");
5746                 qual_of(fp, type);
5747                 break;
5748         case TYPE_USHORT:
5749                 fprintf(fp, "unsigned short");
5750                 qual_of(fp, type);
5751                 break;
5752         case TYPE_INT:
5753                 fprintf(fp, "signed int");
5754                 qual_of(fp, type);
5755                 break;
5756         case TYPE_UINT:
5757                 fprintf(fp, "unsigned int");
5758                 qual_of(fp, type);
5759                 break;
5760         case TYPE_LONG:
5761                 fprintf(fp, "signed long");
5762                 qual_of(fp, type);
5763                 break;
5764         case TYPE_ULONG:
5765                 fprintf(fp, "unsigned long");
5766                 qual_of(fp, type);
5767                 break;
5768         case TYPE_POINTER:
5769                 name_of(fp, type->left);
5770                 fprintf(fp, " * ");
5771                 qual_of(fp, type);
5772                 break;
5773         case TYPE_PRODUCT:
5774                 name_of(fp, type->left);
5775                 fprintf(fp, ", ");
5776                 name_of(fp, type->right);
5777                 break;
5778         case TYPE_OVERLAP:
5779                 name_of(fp, type->left);
5780                 fprintf(fp, ",| ");
5781                 name_of(fp, type->right);
5782                 break;
5783         case TYPE_ENUM:
5784                 fprintf(fp, "enum %s", 
5785                         (type->type_ident)? type->type_ident->name : "");
5786                 qual_of(fp, type);
5787                 break;
5788         case TYPE_STRUCT:
5789                 fprintf(fp, "struct %s { ", 
5790                         (type->type_ident)? type->type_ident->name : "");
5791                 name_of(fp, type->left);
5792                 fprintf(fp, " } ");
5793                 qual_of(fp, type);
5794                 break;
5795         case TYPE_UNION:
5796                 fprintf(fp, "union %s { ", 
5797                         (type->type_ident)? type->type_ident->name : "");
5798                 name_of(fp, type->left);
5799                 fprintf(fp, " } ");
5800                 qual_of(fp, type);
5801                 break;
5802         case TYPE_FUNCTION:
5803                 name_of(fp, type->left);
5804                 fprintf(fp, " (*)(");
5805                 name_of(fp, type->right);
5806                 fprintf(fp, ")");
5807                 break;
5808         case TYPE_ARRAY:
5809                 name_of(fp, type->left);
5810                 fprintf(fp, " [%ld]", (long)(type->elements));
5811                 break;
5812         case TYPE_TUPLE:
5813                 fprintf(fp, "tuple { "); 
5814                 name_of(fp, type->left);
5815                 fprintf(fp, " } ");
5816                 qual_of(fp, type);
5817                 break;
5818         case TYPE_JOIN:
5819                 fprintf(fp, "join { ");
5820                 name_of(fp, type->left);
5821                 fprintf(fp, " } ");
5822                 qual_of(fp, type);
5823                 break;
5824         case TYPE_BITFIELD:
5825                 name_of(fp, type->left);
5826                 fprintf(fp, " : %d ", type->elements);
5827                 qual_of(fp, type);
5828                 break;
5829         case TYPE_UNKNOWN:
5830                 fprintf(fp, "unknown_t");
5831                 break;
5832         default:
5833                 fprintf(fp, "????: %x", base_type);
5834                 break;
5835         }
5836         if (type->field_ident && type->field_ident->name) {
5837                 fprintf(fp, " .%s", type->field_ident->name);
5838         }
5839 }
5840
5841 static size_t align_of(struct compile_state *state, struct type *type)
5842 {
5843         size_t align;
5844         align = 0;
5845         switch(type->type & TYPE_MASK) {
5846         case TYPE_VOID:
5847                 align = 1;
5848                 break;
5849         case TYPE_BITFIELD:
5850                 align = 1;
5851                 break;
5852         case TYPE_CHAR:
5853         case TYPE_UCHAR:
5854                 align = ALIGNOF_CHAR;
5855                 break;
5856         case TYPE_SHORT:
5857         case TYPE_USHORT:
5858                 align = ALIGNOF_SHORT;
5859                 break;
5860         case TYPE_INT:
5861         case TYPE_UINT:
5862         case TYPE_ENUM:
5863                 align = ALIGNOF_INT;
5864                 break;
5865         case TYPE_LONG:
5866         case TYPE_ULONG:
5867                 align = ALIGNOF_LONG;
5868                 break;
5869         case TYPE_POINTER:
5870                 align = ALIGNOF_POINTER;
5871                 break;
5872         case TYPE_PRODUCT:
5873         case TYPE_OVERLAP:
5874         {
5875                 size_t left_align, right_align;
5876                 left_align  = align_of(state, type->left);
5877                 right_align = align_of(state, type->right);
5878                 align = (left_align >= right_align) ? left_align : right_align;
5879                 break;
5880         }
5881         case TYPE_ARRAY:
5882                 align = align_of(state, type->left);
5883                 break;
5884         case TYPE_STRUCT:
5885         case TYPE_TUPLE:
5886         case TYPE_UNION:
5887         case TYPE_JOIN:
5888                 align = align_of(state, type->left);
5889                 break;
5890         default:
5891                 error(state, 0, "alignof not yet defined for type\n");
5892                 break;
5893         }
5894         return align;
5895 }
5896
5897 static size_t reg_align_of(struct compile_state *state, struct type *type)
5898 {
5899         size_t align;
5900         align = 0;
5901         switch(type->type & TYPE_MASK) {
5902         case TYPE_VOID:
5903                 align = 1;
5904                 break;
5905         case TYPE_BITFIELD:
5906                 align = 1;
5907                 break;
5908         case TYPE_CHAR:
5909         case TYPE_UCHAR:
5910                 align = REG_ALIGNOF_CHAR;
5911                 break;
5912         case TYPE_SHORT:
5913         case TYPE_USHORT:
5914                 align = REG_ALIGNOF_SHORT;
5915                 break;
5916         case TYPE_INT:
5917         case TYPE_UINT:
5918         case TYPE_ENUM:
5919                 align = REG_ALIGNOF_INT;
5920                 break;
5921         case TYPE_LONG:
5922         case TYPE_ULONG:
5923                 align = REG_ALIGNOF_LONG;
5924                 break;
5925         case TYPE_POINTER:
5926                 align = REG_ALIGNOF_POINTER;
5927                 break;
5928         case TYPE_PRODUCT:
5929         case TYPE_OVERLAP:
5930         {
5931                 size_t left_align, right_align;
5932                 left_align  = reg_align_of(state, type->left);
5933                 right_align = reg_align_of(state, type->right);
5934                 align = (left_align >= right_align) ? left_align : right_align;
5935                 break;
5936         }
5937         case TYPE_ARRAY:
5938                 align = reg_align_of(state, type->left);
5939                 break;
5940         case TYPE_STRUCT:
5941         case TYPE_UNION:
5942         case TYPE_TUPLE:
5943         case TYPE_JOIN:
5944                 align = reg_align_of(state, type->left);
5945                 break;
5946         default:
5947                 error(state, 0, "alignof not yet defined for type\n");
5948                 break;
5949         }
5950         return align;
5951 }
5952
5953 static size_t align_of_in_bytes(struct compile_state *state, struct type *type)
5954 {
5955         return bits_to_bytes(align_of(state, type));
5956 }
5957 static size_t size_of(struct compile_state *state, struct type *type);
5958 static size_t reg_size_of(struct compile_state *state, struct type *type);
5959
5960 static size_t needed_padding(struct compile_state *state, 
5961         struct type *type, size_t offset)
5962 {
5963         size_t padding, align;
5964         align = align_of(state, type);
5965         /* Align to the next machine word if the bitfield does completely
5966          * fit into the current word.
5967          */
5968         if ((type->type & TYPE_MASK) == TYPE_BITFIELD) {
5969                 size_t size;
5970                 size = size_of(state, type);
5971                 if ((offset + type->elements)/size != offset/size) {
5972                         align = size;
5973                 }
5974         }
5975         padding = 0;
5976         if (offset % align) {
5977                 padding = align - (offset % align);
5978         }
5979         return padding;
5980 }
5981
5982 static size_t reg_needed_padding(struct compile_state *state, 
5983         struct type *type, size_t offset)
5984 {
5985         size_t padding, align;
5986         align = reg_align_of(state, type);
5987         /* Align to the next register word if the bitfield does completely
5988          * fit into the current register.
5989          */
5990         if (((type->type & TYPE_MASK) == TYPE_BITFIELD) &&
5991                 (((offset + type->elements)/REG_SIZEOF_REG) != (offset/REG_SIZEOF_REG))) 
5992         {
5993                 align = REG_SIZEOF_REG;
5994         }
5995         padding = 0;
5996         if (offset % align) {
5997                 padding = align - (offset % align);
5998         }
5999         return padding;
6000 }
6001
6002 static size_t size_of(struct compile_state *state, struct type *type)
6003 {
6004         size_t size;
6005         size = 0;
6006         switch(type->type & TYPE_MASK) {
6007         case TYPE_VOID:
6008                 size = 0;
6009                 break;
6010         case TYPE_BITFIELD:
6011                 size = type->elements;
6012                 break;
6013         case TYPE_CHAR:
6014         case TYPE_UCHAR:
6015                 size = SIZEOF_CHAR;
6016                 break;
6017         case TYPE_SHORT:
6018         case TYPE_USHORT:
6019                 size = SIZEOF_SHORT;
6020                 break;
6021         case TYPE_INT:
6022         case TYPE_UINT:
6023         case TYPE_ENUM:
6024                 size = SIZEOF_INT;
6025                 break;
6026         case TYPE_LONG:
6027         case TYPE_ULONG:
6028                 size = SIZEOF_LONG;
6029                 break;
6030         case TYPE_POINTER:
6031                 size = SIZEOF_POINTER;
6032                 break;
6033         case TYPE_PRODUCT:
6034         {
6035                 size_t pad;
6036                 size = 0;
6037                 while((type->type & TYPE_MASK) == TYPE_PRODUCT) {
6038                         pad = needed_padding(state, type->left, size);
6039                         size = size + pad + size_of(state, type->left);
6040                         type = type->right;
6041                 }
6042                 pad = needed_padding(state, type, size);
6043                 size = size + pad + size_of(state, type);
6044                 break;
6045         }
6046         case TYPE_OVERLAP:
6047         {
6048                 size_t size_left, size_right;
6049                 size_left = size_of(state, type->left);
6050                 size_right = size_of(state, type->right);
6051                 size = (size_left >= size_right)? size_left : size_right;
6052                 break;
6053         }
6054         case TYPE_ARRAY:
6055                 if (type->elements == ELEMENT_COUNT_UNSPECIFIED) {
6056                         internal_error(state, 0, "Invalid array type");
6057                 } else {
6058                         size = size_of(state, type->left) * type->elements;
6059                 }
6060                 break;
6061         case TYPE_STRUCT:
6062         case TYPE_TUPLE:
6063         {
6064                 size_t pad;
6065                 size = size_of(state, type->left);
6066                 /* Pad structures so their size is a multiples of their alignment */
6067                 pad = needed_padding(state, type, size);
6068                 size = size + pad;
6069                 break;
6070         }
6071         case TYPE_UNION:
6072         case TYPE_JOIN:
6073         {
6074                 size_t pad;
6075                 size = size_of(state, type->left);
6076                 /* Pad unions so their size is a multiple of their alignment */
6077                 pad = needed_padding(state, type, size);
6078                 size = size + pad;
6079                 break;
6080         }
6081         default:
6082                 internal_error(state, 0, "sizeof not yet defined for type");
6083                 break;
6084         }
6085         return size;
6086 }
6087
6088 static size_t reg_size_of(struct compile_state *state, struct type *type)
6089 {
6090         size_t size;
6091         size = 0;
6092         switch(type->type & TYPE_MASK) {
6093         case TYPE_VOID:
6094                 size = 0;
6095                 break;
6096         case TYPE_BITFIELD:
6097                 size = type->elements;
6098                 break;
6099         case TYPE_CHAR:
6100         case TYPE_UCHAR:
6101                 size = REG_SIZEOF_CHAR;
6102                 break;
6103         case TYPE_SHORT:
6104         case TYPE_USHORT:
6105                 size = REG_SIZEOF_SHORT;
6106                 break;
6107         case TYPE_INT:
6108         case TYPE_UINT:
6109         case TYPE_ENUM:
6110                 size = REG_SIZEOF_INT;
6111                 break;
6112         case TYPE_LONG:
6113         case TYPE_ULONG:
6114                 size = REG_SIZEOF_LONG;
6115                 break;
6116         case TYPE_POINTER:
6117                 size = REG_SIZEOF_POINTER;
6118                 break;
6119         case TYPE_PRODUCT:
6120         {
6121                 size_t pad;
6122                 size = 0;
6123                 while((type->type & TYPE_MASK) == TYPE_PRODUCT) {
6124                         pad = reg_needed_padding(state, type->left, size);
6125                         size = size + pad + reg_size_of(state, type->left);
6126                         type = type->right;
6127                 }
6128                 pad = reg_needed_padding(state, type, size);
6129                 size = size + pad + reg_size_of(state, type);
6130                 break;
6131         }
6132         case TYPE_OVERLAP:
6133         {
6134                 size_t size_left, size_right;
6135                 size_left  = reg_size_of(state, type->left);
6136                 size_right = reg_size_of(state, type->right);
6137                 size = (size_left >= size_right)? size_left : size_right;
6138                 break;
6139         }
6140         case TYPE_ARRAY:
6141                 if (type->elements == ELEMENT_COUNT_UNSPECIFIED) {
6142                         internal_error(state, 0, "Invalid array type");
6143                 } else {
6144                         size = reg_size_of(state, type->left) * type->elements;
6145                 }
6146                 break;
6147         case TYPE_STRUCT:
6148         case TYPE_TUPLE:
6149         {
6150                 size_t pad;
6151                 size = reg_size_of(state, type->left);
6152                 /* Pad structures so their size is a multiples of their alignment */
6153                 pad = reg_needed_padding(state, type, size);
6154                 size = size + pad;
6155                 break;
6156         }
6157         case TYPE_UNION:
6158         case TYPE_JOIN:
6159         {
6160                 size_t pad;
6161                 size = reg_size_of(state, type->left);
6162                 /* Pad unions so their size is a multiple of their alignment */
6163                 pad = reg_needed_padding(state, type, size);
6164                 size = size + pad;
6165                 break;
6166         }
6167         default:
6168                 internal_error(state, 0, "sizeof not yet defined for type");
6169                 break;
6170         }
6171         return size;
6172 }
6173
6174 static size_t registers_of(struct compile_state *state, struct type *type)
6175 {
6176         size_t registers;
6177         registers = reg_size_of(state, type);
6178         registers += REG_SIZEOF_REG - 1;
6179         registers /= REG_SIZEOF_REG;
6180         return registers;
6181 }
6182
6183 static size_t size_of_in_bytes(struct compile_state *state, struct type *type)
6184 {
6185         return bits_to_bytes(size_of(state, type));
6186 }
6187
6188 static size_t field_offset(struct compile_state *state, 
6189         struct type *type, struct hash_entry *field)
6190 {
6191         struct type *member;
6192         size_t size;
6193
6194         size = 0;
6195         member = 0;
6196         if ((type->type & TYPE_MASK) == TYPE_STRUCT) {
6197                 member = type->left;
6198                 while(member && ((member->type & TYPE_MASK) == TYPE_PRODUCT)) {
6199                         size += needed_padding(state, member->left, size);
6200                         if (member->left->field_ident == field) {
6201                                 member = member->left;
6202                                 break;
6203                         }
6204                         size += size_of(state, member->left);
6205                         member = member->right;
6206                 }
6207                 size += needed_padding(state, member, size);
6208         }
6209         else if ((type->type & TYPE_MASK) == TYPE_UNION) {
6210                 member = type->left;
6211                 while(member && ((member->type & TYPE_MASK) == TYPE_OVERLAP)) {
6212                         if (member->left->field_ident == field) {
6213                                 member = member->left;
6214                                 break;
6215                         }
6216                         member = member->right;
6217                 }
6218         }
6219         else {
6220                 internal_error(state, 0, "field_offset only works on structures and unions");
6221         }
6222
6223         if (!member || (member->field_ident != field)) {
6224                 error(state, 0, "member %s not present", field->name);
6225         }
6226         return size;
6227 }
6228
6229 static size_t field_reg_offset(struct compile_state *state, 
6230         struct type *type, struct hash_entry *field)
6231 {
6232         struct type *member;
6233         size_t size;
6234
6235         size = 0;
6236         member = 0;
6237         if ((type->type & TYPE_MASK) == TYPE_STRUCT) {
6238                 member = type->left;
6239                 while(member && ((member->type & TYPE_MASK) == TYPE_PRODUCT)) {
6240                         size += reg_needed_padding(state, member->left, size);
6241                         if (member->left->field_ident == field) {
6242                                 member = member->left;
6243                                 break;
6244                         }
6245                         size += reg_size_of(state, member->left);
6246                         member = member->right;
6247                 }
6248         }
6249         else if ((type->type & TYPE_MASK) == TYPE_UNION) {
6250                 member = type->left;
6251                 while(member && ((member->type & TYPE_MASK) == TYPE_OVERLAP)) {
6252                         if (member->left->field_ident == field) {
6253                                 member = member->left;
6254                                 break;
6255                         }
6256                         member = member->right;
6257                 }
6258         }
6259         else {
6260                 internal_error(state, 0, "field_reg_offset only works on structures and unions");
6261         }
6262
6263         size += reg_needed_padding(state, member, size);
6264         if (!member || (member->field_ident != field)) {
6265                 error(state, 0, "member %s not present", field->name);
6266         }
6267         return size;
6268 }
6269
6270 static struct type *field_type(struct compile_state *state, 
6271         struct type *type, struct hash_entry *field)
6272 {
6273         struct type *member;
6274
6275         member = 0;
6276         if ((type->type & TYPE_MASK) == TYPE_STRUCT) {
6277                 member = type->left;
6278                 while(member && ((member->type & TYPE_MASK) == TYPE_PRODUCT)) {
6279                         if (member->left->field_ident == field) {
6280                                 member = member->left;
6281                                 break;
6282                         }
6283                         member = member->right;
6284                 }
6285         }
6286         else if ((type->type & TYPE_MASK) == TYPE_UNION) {
6287                 member = type->left;
6288                 while(member && ((member->type & TYPE_MASK) == TYPE_OVERLAP)) {
6289                         if (member->left->field_ident == field) {
6290                                 member = member->left;
6291                                 break;
6292                         }
6293                         member = member->right;
6294                 }
6295         }
6296         else {
6297                 internal_error(state, 0, "field_type only works on structures and unions");
6298         }
6299         
6300         if (!member || (member->field_ident != field)) {
6301                 error(state, 0, "member %s not present", field->name);
6302         }
6303         return member;
6304 }
6305
6306 static size_t index_offset(struct compile_state *state, 
6307         struct type *type, ulong_t index)
6308 {
6309         struct type *member;
6310         size_t size;
6311         size = 0;
6312         if ((type->type & TYPE_MASK) == TYPE_ARRAY) {
6313                 size = size_of(state, type->left) * index;
6314         }
6315         else if ((type->type & TYPE_MASK) == TYPE_TUPLE) {
6316                 ulong_t i;
6317                 member = type->left;
6318                 i = 0;
6319                 while(member && ((member->type & TYPE_MASK) == TYPE_PRODUCT)) {
6320                         size += needed_padding(state, member->left, size);
6321                         if (i == index) {
6322                                 member = member->left;
6323                                 break;
6324                         }
6325                         size += size_of(state, member->left);
6326                         i++;
6327                         member = member->right;
6328                 }
6329                 size += needed_padding(state, member, size);
6330                 if (i != index) {
6331                         internal_error(state, 0, "Missing member index: %u", index);
6332                 }
6333         }
6334         else if ((type->type & TYPE_MASK) == TYPE_JOIN) {
6335                 ulong_t i;
6336                 size = 0;
6337                 member = type->left;
6338                 i = 0;
6339                 while(member && ((member->type & TYPE_MASK) == TYPE_OVERLAP)) {
6340                         if (i == index) {
6341                                 member = member->left;
6342                                 break;
6343                         }
6344                         i++;
6345                         member = member->right;
6346                 }
6347                 if (i != index) {
6348                         internal_error(state, 0, "Missing member index: %u", index);
6349                 }
6350         }
6351         else {
6352                 internal_error(state, 0, 
6353                         "request for index %u in something not an array, tuple or join",
6354                         index);
6355         }
6356         return size;
6357 }
6358
6359 static size_t index_reg_offset(struct compile_state *state, 
6360         struct type *type, ulong_t index)
6361 {
6362         struct type *member;
6363         size_t size;
6364         size = 0;
6365         if ((type->type & TYPE_MASK) == TYPE_ARRAY) {
6366                 size = reg_size_of(state, type->left) * index;
6367         }
6368         else if ((type->type & TYPE_MASK) == TYPE_TUPLE) {
6369                 ulong_t i;
6370                 member = type->left;
6371                 i = 0;
6372                 while(member && ((member->type & TYPE_MASK) == TYPE_PRODUCT)) {
6373                         size += reg_needed_padding(state, member->left, size);
6374                         if (i == index) {
6375                                 member = member->left;
6376                                 break;
6377                         }
6378                         size += reg_size_of(state, member->left);
6379                         i++;
6380                         member = member->right;
6381                 }
6382                 size += reg_needed_padding(state, member, size);
6383                 if (i != index) {
6384                         internal_error(state, 0, "Missing member index: %u", index);
6385                 }
6386                 
6387         }
6388         else if ((type->type & TYPE_MASK) == TYPE_JOIN) {
6389                 ulong_t i;
6390                 size = 0;
6391                 member = type->left;
6392                 i = 0;
6393                 while(member && ((member->type & TYPE_MASK) == TYPE_OVERLAP)) {
6394                         if (i == index) {
6395                                 member = member->left;
6396                                 break;
6397                         }
6398                         i++;
6399                         member = member->right;
6400                 }
6401                 if (i != index) {
6402                         internal_error(state, 0, "Missing member index: %u", index);
6403                 }
6404         }
6405         else {
6406                 internal_error(state, 0, 
6407                         "request for index %u in something not an array, tuple or join",
6408                         index);
6409         }
6410         return size;
6411 }
6412
6413 static struct type *index_type(struct compile_state *state,
6414         struct type *type, ulong_t index)
6415 {
6416         struct type *member;
6417         if (index >= type->elements) {
6418                 internal_error(state, 0, "Invalid element %u requested", index);
6419         }
6420         if ((type->type & TYPE_MASK) == TYPE_ARRAY) {
6421                 member = type->left;
6422         }
6423         else if ((type->type & TYPE_MASK) == TYPE_TUPLE) {
6424                 ulong_t i;
6425                 member = type->left;
6426                 i = 0;
6427                 while(member && ((member->type & TYPE_MASK) == TYPE_PRODUCT)) {
6428                         if (i == index) {
6429                                 member = member->left;
6430                                 break;
6431                         }
6432                         i++;
6433                         member = member->right;
6434                 }
6435                 if (i != index) {
6436                         internal_error(state, 0, "Missing member index: %u", index);
6437                 }
6438         }
6439         else if ((type->type & TYPE_MASK) == TYPE_JOIN) {
6440                 ulong_t i;
6441                 member = type->left;
6442                 i = 0;
6443                 while(member && ((member->type & TYPE_MASK) == TYPE_OVERLAP)) {
6444                         if (i == index) {
6445                                 member = member->left;
6446                                 break;
6447                         }
6448                         i++;
6449                         member = member->right;
6450                 }
6451                 if (i != index) {
6452                         internal_error(state, 0, "Missing member index: %u", index);
6453                 }
6454         }
6455         else {
6456                 member = 0;
6457                 internal_error(state, 0, 
6458                         "request for index %u in something not an array, tuple or join",
6459                         index);
6460         }
6461         return member;
6462 }
6463
6464 static struct type *unpack_type(struct compile_state *state, struct type *type)
6465 {
6466         /* If I have a single register compound type not a bit-field
6467          * find the real type.
6468          */
6469         struct type *start_type;
6470         size_t size;
6471         /* Get out early if I need multiple registers for this type */
6472         size = reg_size_of(state, type);
6473         if (size > REG_SIZEOF_REG) {
6474                 return type;
6475         }
6476         /* Get out early if I don't need any registers for this type */
6477         if (size == 0) {
6478                 return &void_type;
6479         }
6480         /* Loop until I have no more layers I can remove */
6481         do {
6482                 start_type = type;
6483                 switch(type->type & TYPE_MASK) {
6484                 case TYPE_ARRAY:
6485                         /* If I have a single element the unpacked type
6486                          * is that element.
6487                          */
6488                         if (type->elements == 1) {
6489                                 type = type->left;
6490                         }
6491                         break;
6492                 case TYPE_STRUCT:
6493                 case TYPE_TUPLE:
6494                         /* If I have a single element the unpacked type
6495                          * is that element.
6496                          */
6497                         if (type->elements == 1) {
6498                                 type = type->left;
6499                         }
6500                         /* If I have multiple elements the unpacked
6501                          * type is the non-void element.
6502                          */
6503                         else {
6504                                 struct type *next, *member;
6505                                 struct type *sub_type;
6506                                 sub_type = 0;
6507                                 next = type->left;
6508                                 while(next) {
6509                                         member = next;
6510                                         next = 0;
6511                                         if ((member->type & TYPE_MASK) == TYPE_PRODUCT) {
6512                                                 next = member->right;
6513                                                 member = member->left;
6514                                         }
6515                                         if (reg_size_of(state, member) > 0) {
6516                                                 if (sub_type) {
6517                                                         internal_error(state, 0, "true compound type in a register");
6518                                                 }
6519                                                 sub_type = member;
6520                                         }
6521                                 }
6522                                 if (sub_type) {
6523                                         type = sub_type;
6524                                 }
6525                         }
6526                         break;
6527
6528                 case TYPE_UNION:
6529                 case TYPE_JOIN:
6530                         /* If I have a single element the unpacked type
6531                          * is that element.
6532                          */
6533                         if (type->elements == 1) {
6534                                 type = type->left;
6535                         }
6536                         /* I can't in general unpack union types */
6537                         break;
6538                 default:
6539                         /* If I'm not a compound type I can't unpack it */
6540                         break;
6541                 }
6542         } while(start_type != type);
6543         switch(type->type & TYPE_MASK) {
6544         case TYPE_STRUCT:
6545         case TYPE_ARRAY:
6546         case TYPE_TUPLE:
6547                 internal_error(state, 0, "irredicible type?");
6548                 break;
6549         }
6550         return type;
6551 }
6552
6553 static int equiv_types(struct type *left, struct type *right);
6554 static int is_compound_type(struct type *type);
6555
6556 static struct type *reg_type(
6557         struct compile_state *state, struct type *type, int reg_offset)
6558 {
6559         struct type *member;
6560         size_t size;
6561 #if 1
6562         struct type *invalid;
6563         invalid = invalid_type(state, type);
6564         if (invalid) {
6565                 fprintf(state->errout, "type: ");
6566                 name_of(state->errout, type);
6567                 fprintf(state->errout, "\n");
6568                 fprintf(state->errout, "invalid: ");
6569                 name_of(state->errout, invalid);
6570                 fprintf(state->errout, "\n");
6571                 internal_error(state, 0, "bad input type?");
6572         }
6573 #endif
6574
6575         size = reg_size_of(state, type);
6576         if (reg_offset > size) {
6577                 member = 0;
6578                 fprintf(state->errout, "type: ");
6579                 name_of(state->errout, type);
6580                 fprintf(state->errout, "\n");
6581                 internal_error(state, 0, "offset outside of type");
6582         }
6583         else {
6584                 switch(type->type & TYPE_MASK) {
6585                         /* Don't do anything with the basic types */
6586                 case TYPE_VOID:
6587                 case TYPE_CHAR:         case TYPE_UCHAR:
6588                 case TYPE_SHORT:        case TYPE_USHORT:
6589                 case TYPE_INT:          case TYPE_UINT:
6590                 case TYPE_LONG:         case TYPE_ULONG:
6591                 case TYPE_LLONG:        case TYPE_ULLONG:
6592                 case TYPE_FLOAT:        case TYPE_DOUBLE:
6593                 case TYPE_LDOUBLE:
6594                 case TYPE_POINTER:
6595                 case TYPE_ENUM:
6596                 case TYPE_BITFIELD:
6597                         member = type;
6598                         break;
6599                 case TYPE_ARRAY:
6600                         member = type->left;
6601                         size = reg_size_of(state, member);
6602                         if (size > REG_SIZEOF_REG) {
6603                                 member = reg_type(state, member, reg_offset % size);
6604                         }
6605                         break;
6606                 case TYPE_STRUCT:
6607                 case TYPE_TUPLE:
6608                 {
6609                         size_t offset;
6610                         offset = 0;
6611                         member = type->left;
6612                         while(member && ((member->type & TYPE_MASK) == TYPE_PRODUCT)) {
6613                                 size = reg_size_of(state, member->left);
6614                                 offset += reg_needed_padding(state, member->left, offset);
6615                                 if ((offset + size) > reg_offset) {
6616                                         member = member->left;
6617                                         break;
6618                                 }
6619                                 offset += size;
6620                                 member = member->right;
6621                         }
6622                         offset += reg_needed_padding(state, member, offset);
6623                         member = reg_type(state, member, reg_offset - offset);
6624                         break;
6625                 }
6626                 case TYPE_UNION:
6627                 case TYPE_JOIN:
6628                 {
6629                         struct type *join, **jnext, *mnext;
6630                         join = new_type(TYPE_JOIN, 0, 0);
6631                         jnext = &join->left;
6632                         mnext = type->left;
6633                         while(mnext) {
6634                                 size_t size;
6635                                 member = mnext;
6636                                 mnext = 0;
6637                                 if ((member->type & TYPE_MASK) == TYPE_OVERLAP) {
6638                                         mnext = member->right;
6639                                         member = member->left;
6640                                 }
6641                                 size = reg_size_of(state, member);
6642                                 if (size > reg_offset) {
6643                                         struct type *part, *hunt;
6644                                         part = reg_type(state, member, reg_offset);
6645                                         /* See if this type is already in the union */
6646                                         hunt = join->left;
6647                                         while(hunt) {
6648                                                 struct type *test = hunt;
6649                                                 hunt = 0;
6650                                                 if ((test->type & TYPE_MASK) == TYPE_OVERLAP) {
6651                                                         hunt = test->right;
6652                                                         test = test->left;
6653                                                 }
6654                                                 if (equiv_types(part, test)) {
6655                                                         goto next;
6656                                                 }
6657                                         }
6658                                         /* Nope add it */
6659                                         if (!*jnext) {
6660                                                 *jnext = part;
6661                                         } else {
6662                                                 *jnext = new_type(TYPE_OVERLAP, *jnext, part);
6663                                                 jnext = &(*jnext)->right;
6664                                         }
6665                                         join->elements++;
6666                                 }
6667                         next:
6668                                 ;
6669                         }
6670                         if (join->elements == 0) {
6671                                 internal_error(state, 0, "No elements?");
6672                         }
6673                         member = join;
6674                         break;
6675                 }
6676                 default:
6677                         member = 0;
6678                         fprintf(state->errout, "type: ");
6679                         name_of(state->errout, type);
6680                         fprintf(state->errout, "\n");
6681                         internal_error(state, 0, "reg_type not yet defined for type");
6682                         
6683                 }
6684         }
6685         /* If I have a single register compound type not a bit-field
6686          * find the real type.
6687          */
6688         member = unpack_type(state, member);
6689                 ;
6690         size  = reg_size_of(state, member);
6691         if (size > REG_SIZEOF_REG) {
6692                 internal_error(state, 0, "Cannot find type of single register");
6693         }
6694 #if 1
6695         invalid = invalid_type(state, member);
6696         if (invalid) {
6697                 fprintf(state->errout, "type: ");
6698                 name_of(state->errout, member);
6699                 fprintf(state->errout, "\n");
6700                 fprintf(state->errout, "invalid: ");
6701                 name_of(state->errout, invalid);
6702                 fprintf(state->errout, "\n");
6703                 internal_error(state, 0, "returning bad type?");
6704         }
6705 #endif
6706         return member;
6707 }
6708
6709 static struct type *next_field(struct compile_state *state,
6710         struct type *type, struct type *prev_member) 
6711 {
6712         struct type *member;
6713         if ((type->type & TYPE_MASK) != TYPE_STRUCT) {
6714                 internal_error(state, 0, "next_field only works on structures");
6715         }
6716         member = type->left;
6717         while((member->type & TYPE_MASK) == TYPE_PRODUCT) {
6718                 if (!prev_member) {
6719                         member = member->left;
6720                         break;
6721                 }
6722                 if (member->left == prev_member) {
6723                         prev_member = 0;
6724                 }
6725                 member = member->right;
6726         }
6727         if (member == prev_member) {
6728                 prev_member = 0;
6729         }
6730         if (prev_member) {
6731                 internal_error(state, 0, "prev_member %s not present", 
6732                         prev_member->field_ident->name);
6733         }
6734         return member;
6735 }
6736
6737 typedef void (*walk_type_fields_cb_t)(struct compile_state *state, struct type *type, 
6738         size_t ret_offset, size_t mem_offset, void *arg);
6739
6740 static void walk_type_fields(struct compile_state *state,
6741         struct type *type, size_t reg_offset, size_t mem_offset,
6742         walk_type_fields_cb_t cb, void *arg);
6743
6744 static void walk_struct_fields(struct compile_state *state,
6745         struct type *type, size_t reg_offset, size_t mem_offset,
6746         walk_type_fields_cb_t cb, void *arg)
6747 {
6748         struct type *tptr;
6749         ulong_t i;
6750         if ((type->type & TYPE_MASK) != TYPE_STRUCT) {
6751                 internal_error(state, 0, "walk_struct_fields only works on structures");
6752         }
6753         tptr = type->left;
6754         for(i = 0; i < type->elements; i++) {
6755                 struct type *mtype;
6756                 mtype = tptr;
6757                 if ((mtype->type & TYPE_MASK) == TYPE_PRODUCT) {
6758                         mtype = mtype->left;
6759                 }
6760                 walk_type_fields(state, mtype, 
6761                         reg_offset + 
6762                         field_reg_offset(state, type, mtype->field_ident),
6763                         mem_offset + 
6764                         field_offset(state, type, mtype->field_ident),
6765                         cb, arg);
6766                 tptr = tptr->right;
6767         }
6768         
6769 }
6770
6771 static void walk_type_fields(struct compile_state *state,
6772         struct type *type, size_t reg_offset, size_t mem_offset,
6773         walk_type_fields_cb_t cb, void *arg)
6774 {
6775         switch(type->type & TYPE_MASK) {
6776         case TYPE_STRUCT:
6777                 walk_struct_fields(state, type, reg_offset, mem_offset, cb, arg);
6778                 break;
6779         case TYPE_CHAR:
6780         case TYPE_UCHAR:
6781         case TYPE_SHORT:
6782         case TYPE_USHORT:
6783         case TYPE_INT:
6784         case TYPE_UINT:
6785         case TYPE_LONG:
6786         case TYPE_ULONG:
6787                 cb(state, type, reg_offset, mem_offset, arg);
6788                 break;
6789         case TYPE_VOID:
6790                 break;
6791         default:
6792                 internal_error(state, 0, "walk_type_fields not yet implemented for type");
6793         }
6794 }
6795
6796 static void arrays_complete(struct compile_state *state, struct type *type)
6797 {
6798         if ((type->type & TYPE_MASK) == TYPE_ARRAY) {
6799                 if (type->elements == ELEMENT_COUNT_UNSPECIFIED) {
6800                         error(state, 0, "array size not specified");
6801                 }
6802                 arrays_complete(state, type->left);
6803         }
6804 }
6805
6806 static unsigned int get_basic_type(struct type *type)
6807 {
6808         unsigned int basic;
6809         basic = type->type & TYPE_MASK;
6810         /* Convert enums to ints */
6811         if (basic == TYPE_ENUM) {
6812                 basic = TYPE_INT;
6813         }
6814         /* Convert bitfields to standard types */
6815         else if (basic == TYPE_BITFIELD) {
6816                 if (type->elements <= SIZEOF_CHAR) {
6817                         basic = TYPE_CHAR;
6818                 }
6819                 else if (type->elements <= SIZEOF_SHORT) {
6820                         basic = TYPE_SHORT;
6821                 }
6822                 else if (type->elements <= SIZEOF_INT) {
6823                         basic = TYPE_INT;
6824                 }
6825                 else if (type->elements <= SIZEOF_LONG) {
6826                         basic = TYPE_LONG;
6827                 }
6828                 if (!TYPE_SIGNED(type->left->type)) {
6829                         basic += 1;
6830                 }
6831         }
6832         return basic;
6833 }
6834
6835 static unsigned int do_integral_promotion(unsigned int type)
6836 {
6837         if (TYPE_INTEGER(type) && (TYPE_RANK(type) < TYPE_RANK(TYPE_INT))) {
6838                 type = TYPE_INT;
6839         }
6840         return type;
6841 }
6842
6843 static unsigned int do_arithmetic_conversion(
6844         unsigned int left, unsigned int right)
6845 {
6846         if ((left == TYPE_LDOUBLE) || (right == TYPE_LDOUBLE)) {
6847                 return TYPE_LDOUBLE;
6848         }
6849         else if ((left == TYPE_DOUBLE) || (right == TYPE_DOUBLE)) {
6850                 return TYPE_DOUBLE;
6851         }
6852         else if ((left == TYPE_FLOAT) || (right == TYPE_FLOAT)) {
6853                 return TYPE_FLOAT;
6854         }
6855         left = do_integral_promotion(left);
6856         right = do_integral_promotion(right);
6857         /* If both operands have the same size done */
6858         if (left == right) {
6859                 return left;
6860         }
6861         /* If both operands have the same signedness pick the larger */
6862         else if (!!TYPE_UNSIGNED(left) == !!TYPE_UNSIGNED(right)) {
6863                 return (TYPE_RANK(left) >= TYPE_RANK(right)) ? left : right;
6864         }
6865         /* If the signed type can hold everything use it */
6866         else if (TYPE_SIGNED(left) && (TYPE_RANK(left) > TYPE_RANK(right))) {
6867                 return left;
6868         }
6869         else if (TYPE_SIGNED(right) && (TYPE_RANK(right) > TYPE_RANK(left))) {
6870                 return right;
6871         }
6872         /* Convert to the unsigned type with the same rank as the signed type */
6873         else if (TYPE_SIGNED(left)) {
6874                 return TYPE_MKUNSIGNED(left);
6875         }
6876         else {
6877                 return TYPE_MKUNSIGNED(right);
6878         }
6879 }
6880
6881 /* see if two types are the same except for qualifiers */
6882 static int equiv_types(struct type *left, struct type *right)
6883 {
6884         unsigned int type;
6885         /* Error if the basic types do not match */
6886         if ((left->type & TYPE_MASK) != (right->type & TYPE_MASK)) {
6887                 return 0;
6888         }
6889         type = left->type & TYPE_MASK;
6890         /* If the basic types match and it is a void type we are done */
6891         if (type == TYPE_VOID) {
6892                 return 1;
6893         }
6894         /* For bitfields we need to compare the sizes */
6895         else if (type == TYPE_BITFIELD) {
6896                 return (left->elements == right->elements) &&
6897                         (TYPE_SIGNED(left->left->type) == TYPE_SIGNED(right->left->type));
6898         }
6899         /* if the basic types match and it is an arithmetic type we are done */
6900         else if (TYPE_ARITHMETIC(type)) {
6901                 return 1;
6902         }
6903         /* If it is a pointer type recurse and keep testing */
6904         else if (type == TYPE_POINTER) {
6905                 return equiv_types(left->left, right->left);
6906         }
6907         else if (type == TYPE_ARRAY) {
6908                 return (left->elements == right->elements) &&
6909                         equiv_types(left->left, right->left);
6910         }
6911         /* test for struct equality */
6912         else if (type == TYPE_STRUCT) {
6913                 return left->type_ident == right->type_ident;
6914         }
6915         /* test for union equality */
6916         else if (type == TYPE_UNION) {
6917                 return left->type_ident == right->type_ident;
6918         }
6919         /* Test for equivalent functions */
6920         else if (type == TYPE_FUNCTION) {
6921                 return equiv_types(left->left, right->left) &&
6922                         equiv_types(left->right, right->right);
6923         }
6924         /* We only see TYPE_PRODUCT as part of function equivalence matching */
6925         /* We also see TYPE_PRODUCT as part of of tuple equivalence matchin */
6926         else if (type == TYPE_PRODUCT) {
6927                 return equiv_types(left->left, right->left) &&
6928                         equiv_types(left->right, right->right);
6929         }
6930         /* We should see TYPE_OVERLAP when comparing joins */
6931         else if (type == TYPE_OVERLAP) {
6932                 return equiv_types(left->left, right->left) &&
6933                         equiv_types(left->right, right->right);
6934         }
6935         /* Test for equivalence of tuples */
6936         else if (type == TYPE_TUPLE) {
6937                 return (left->elements == right->elements) &&
6938                         equiv_types(left->left, right->left);
6939         }
6940         /* Test for equivalence of joins */
6941         else if (type == TYPE_JOIN) {
6942                 return (left->elements == right->elements) &&
6943                         equiv_types(left->left, right->left);
6944         }
6945         else {
6946                 return 0;
6947         }
6948 }
6949
6950 static int equiv_ptrs(struct type *left, struct type *right)
6951 {
6952         if (((left->type & TYPE_MASK) != TYPE_POINTER) ||
6953                 ((right->type & TYPE_MASK) != TYPE_POINTER)) {
6954                 return 0;
6955         }
6956         return equiv_types(left->left, right->left);
6957 }
6958
6959 static struct type *compatible_types(struct type *left, struct type *right)
6960 {
6961         struct type *result;
6962         unsigned int type, qual_type;
6963         /* Error if the basic types do not match */
6964         if ((left->type & TYPE_MASK) != (right->type & TYPE_MASK)) {
6965                 return 0;
6966         }
6967         type = left->type & TYPE_MASK;
6968         qual_type = (left->type & ~STOR_MASK) | (right->type & ~STOR_MASK);
6969         result = 0;
6970         /* if the basic types match and it is an arithmetic type we are done */
6971         if (TYPE_ARITHMETIC(type)) {
6972                 result = new_type(qual_type, 0, 0);
6973         }
6974         /* If it is a pointer type recurse and keep testing */
6975         else if (type == TYPE_POINTER) {
6976                 result = compatible_types(left->left, right->left);
6977                 if (result) {
6978                         result = new_type(qual_type, result, 0);
6979                 }
6980         }
6981         /* test for struct equality */
6982         else if (type == TYPE_STRUCT) {
6983                 if (left->type_ident == right->type_ident) {
6984                         result = left;
6985                 }
6986         }
6987         /* test for union equality */
6988         else if (type == TYPE_UNION) {
6989                 if (left->type_ident == right->type_ident) {
6990                         result = left;
6991                 }
6992         }
6993         /* Test for equivalent functions */
6994         else if (type == TYPE_FUNCTION) {
6995                 struct type *lf, *rf;
6996                 lf = compatible_types(left->left, right->left);
6997                 rf = compatible_types(left->right, right->right);
6998                 if (lf && rf) {
6999                         result = new_type(qual_type, lf, rf);
7000                 }
7001         }
7002         /* We only see TYPE_PRODUCT as part of function equivalence matching */
7003         else if (type == TYPE_PRODUCT) {
7004                 struct type *lf, *rf;
7005                 lf = compatible_types(left->left, right->left);
7006                 rf = compatible_types(left->right, right->right);
7007                 if (lf && rf) {
7008                         result = new_type(qual_type, lf, rf);
7009                 }
7010         }
7011         else {
7012                 /* Nothing else is compatible */
7013         }
7014         return result;
7015 }
7016
7017 /* See if left is a equivalent to right or right is a union member of left */
7018 static int is_subset_type(struct type *left, struct type *right)
7019 {
7020         if (equiv_types(left, right)) {
7021                 return 1;
7022         }
7023         if ((left->type & TYPE_MASK) == TYPE_JOIN) {
7024                 struct type *member, *mnext;
7025                 mnext = left->left;
7026                 while(mnext) {
7027                         member = mnext;
7028                         mnext = 0;
7029                         if ((member->type & TYPE_MASK) == TYPE_OVERLAP) {
7030                                 mnext = member->right;
7031                                 member = member->left;
7032                         }
7033                         if (is_subset_type( member, right)) {
7034                                 return 1;
7035                         }
7036                 }
7037         }
7038         return 0;
7039 }
7040
7041 static struct type *compatible_ptrs(struct type *left, struct type *right)
7042 {
7043         struct type *result;
7044         if (((left->type & TYPE_MASK) != TYPE_POINTER) ||
7045                 ((right->type & TYPE_MASK) != TYPE_POINTER)) {
7046                 return 0;
7047         }
7048         result = compatible_types(left->left, right->left);
7049         if (result) {
7050                 unsigned int qual_type;
7051                 qual_type = (left->type & ~STOR_MASK) | (right->type & ~STOR_MASK);
7052                 result = new_type(qual_type, result, 0);
7053         }
7054         return result;
7055         
7056 }
7057 static struct triple *integral_promotion(
7058         struct compile_state *state, struct triple *def)
7059 {
7060         struct type *type;
7061         type = def->type;
7062         /* As all operations are carried out in registers
7063          * the values are converted on load I just convert
7064          * logical type of the operand.
7065          */
7066         if (TYPE_INTEGER(type->type)) {
7067                 unsigned int int_type;
7068                 int_type = type->type & ~TYPE_MASK;
7069                 int_type |= do_integral_promotion(get_basic_type(type));
7070                 if (int_type != type->type) {
7071                         if (def->op != OP_LOAD) {
7072                                 def->type = new_type(int_type, 0, 0);
7073                         }
7074                         else {
7075                                 def = triple(state, OP_CONVERT, 
7076                                         new_type(int_type, 0, 0), def, 0);
7077                         }
7078                 }
7079         }
7080         return def;
7081 }
7082
7083
7084 static void arithmetic(struct compile_state *state, struct triple *def)
7085 {
7086         if (!TYPE_ARITHMETIC(def->type->type)) {
7087                 error(state, 0, "arithmetic type expexted");
7088         }
7089 }
7090
7091 static void ptr_arithmetic(struct compile_state *state, struct triple *def)
7092 {
7093         if (!TYPE_PTR(def->type->type) && !TYPE_ARITHMETIC(def->type->type)) {
7094                 error(state, def, "pointer or arithmetic type expected");
7095         }
7096 }
7097
7098 static int is_integral(struct triple *ins)
7099 {
7100         return TYPE_INTEGER(ins->type->type);
7101 }
7102
7103 static void integral(struct compile_state *state, struct triple *def)
7104 {
7105         if (!is_integral(def)) {
7106                 error(state, 0, "integral type expected");
7107         }
7108 }
7109
7110
7111 static void bool(struct compile_state *state, struct triple *def)
7112 {
7113         if (!TYPE_ARITHMETIC(def->type->type) &&
7114                 ((def->type->type & TYPE_MASK) != TYPE_POINTER)) {
7115                 error(state, 0, "arithmetic or pointer type expected");
7116         }
7117 }
7118
7119 static int is_signed(struct type *type)
7120 {
7121         if ((type->type & TYPE_MASK) == TYPE_BITFIELD) {
7122                 type = type->left;
7123         }
7124         return !!TYPE_SIGNED(type->type);
7125 }
7126 static int is_compound_type(struct type *type)
7127 {
7128         int is_compound;
7129         switch((type->type & TYPE_MASK)) {
7130         case TYPE_ARRAY:
7131         case TYPE_STRUCT:
7132         case TYPE_TUPLE:
7133         case TYPE_UNION:
7134         case TYPE_JOIN: 
7135                 is_compound = 1;
7136                 break;
7137         default:
7138                 is_compound = 0;
7139                 break;
7140         }
7141         return is_compound;
7142 }
7143
7144 /* Is this value located in a register otherwise it must be in memory */
7145 static int is_in_reg(struct compile_state *state, struct triple *def)
7146 {
7147         int in_reg;
7148         if (def->op == OP_ADECL) {
7149                 in_reg = 1;
7150         }
7151         else if ((def->op == OP_SDECL) || (def->op == OP_DEREF)) {
7152                 in_reg = 0;
7153         }
7154         else if (triple_is_part(state, def)) {
7155                 in_reg = is_in_reg(state, MISC(def, 0));
7156         }
7157         else {
7158                 internal_error(state, def, "unknown expr storage location");
7159                 in_reg = -1;
7160         }
7161         return in_reg;
7162 }
7163
7164 /* Is this an auto or static variable location? Something that can
7165  * be assigned to.  Otherwise it must must be a pure value, a temporary.
7166  */
7167 static int is_lvalue(struct compile_state *state, struct triple *def)
7168 {
7169         int ret;
7170         ret = 0;
7171         if (!def) {
7172                 return 0;
7173         }
7174         if ((def->op == OP_ADECL) || 
7175                 (def->op == OP_SDECL) || 
7176                 (def->op == OP_DEREF) ||
7177                 (def->op == OP_BLOBCONST) ||
7178                 (def->op == OP_LIST)) {
7179                 ret = 1;
7180         }
7181         else if (triple_is_part(state, def)) {
7182                 ret = is_lvalue(state, MISC(def, 0));
7183         }
7184         return ret;
7185 }
7186
7187 static void clvalue(struct compile_state *state, struct triple *def)
7188 {
7189         if (!def) {
7190                 internal_error(state, def, "nothing where lvalue expected?");
7191         }
7192         if (!is_lvalue(state, def)) { 
7193                 error(state, def, "lvalue expected");
7194         }
7195 }
7196 static void lvalue(struct compile_state *state, struct triple *def)
7197 {
7198         clvalue(state, def);
7199         if (def->type->type & QUAL_CONST) {
7200                 error(state, def, "modifable lvalue expected");
7201         }
7202 }
7203
7204 static int is_pointer(struct triple *def)
7205 {
7206         return (def->type->type & TYPE_MASK) == TYPE_POINTER;
7207 }
7208
7209 static void pointer(struct compile_state *state, struct triple *def)
7210 {
7211         if (!is_pointer(def)) {
7212                 error(state, def, "pointer expected");
7213         }
7214 }
7215
7216 static struct triple *int_const(
7217         struct compile_state *state, struct type *type, ulong_t value)
7218 {
7219         struct triple *result;
7220         switch(type->type & TYPE_MASK) {
7221         case TYPE_CHAR:
7222         case TYPE_INT:   case TYPE_UINT:
7223         case TYPE_LONG:  case TYPE_ULONG:
7224                 break;
7225         default:
7226                 internal_error(state, 0, "constant for unknown type");
7227         }
7228         result = triple(state, OP_INTCONST, type, 0, 0);
7229         result->u.cval = value;
7230         return result;
7231 }
7232
7233
7234 static struct triple *read_expr(struct compile_state *state, struct triple *def);
7235
7236 static struct triple *do_mk_addr_expr(struct compile_state *state, 
7237         struct triple *expr, struct type *type, ulong_t offset)
7238 {
7239         struct triple *result;
7240         struct type *ptr_type;
7241         clvalue(state, expr);
7242
7243         ptr_type = new_type(TYPE_POINTER | (type->type & QUAL_MASK), type, 0);
7244
7245         
7246         result = 0;
7247         if (expr->op == OP_ADECL) {
7248                 error(state, expr, "address of auto variables not supported");
7249         }
7250         else if (expr->op == OP_SDECL) {
7251                 result = triple(state, OP_ADDRCONST, ptr_type, 0, 0);
7252                 MISC(result, 0) = expr;
7253                 result->u.cval = offset;
7254         }
7255         else if (expr->op == OP_DEREF) {
7256                 result = triple(state, OP_ADD, ptr_type,
7257                         RHS(expr, 0),
7258                         int_const(state, &ulong_type, offset));
7259         }
7260         else if (expr->op == OP_BLOBCONST) {
7261                 FINISHME();
7262                 internal_error(state, expr, "not yet implemented");
7263         }
7264         else if (expr->op == OP_LIST) {
7265                 error(state, 0, "Function addresses not supported");
7266         }
7267         else if (triple_is_part(state, expr)) {
7268                 struct triple *part;
7269                 part = expr;
7270                 expr = MISC(expr, 0);
7271                 if (part->op == OP_DOT) {
7272                         offset += bits_to_bytes(
7273                                 field_offset(state, expr->type, part->u.field));
7274                 }
7275                 else if (part->op == OP_INDEX) {
7276                         offset += bits_to_bytes(
7277                                 index_offset(state, expr->type, part->u.cval));
7278                 }
7279                 else {
7280                         internal_error(state, part, "unhandled part type");
7281                 }
7282                 result = do_mk_addr_expr(state, expr, type, offset);
7283         }
7284         if (!result) {
7285                 internal_error(state, expr, "cannot take address of expression");
7286         }
7287         return result;
7288 }
7289
7290 static struct triple *mk_addr_expr(
7291         struct compile_state *state, struct triple *expr, ulong_t offset)
7292 {
7293         return do_mk_addr_expr(state, expr, expr->type, offset);
7294 }
7295
7296 static struct triple *mk_deref_expr(
7297         struct compile_state *state, struct triple *expr)
7298 {
7299         struct type *base_type;
7300         pointer(state, expr);
7301         base_type = expr->type->left;
7302         return triple(state, OP_DEREF, base_type, expr, 0);
7303 }
7304
7305 /* lvalue conversions always apply except when certain operators
7306  * are applied.  So I apply apply it when I know no more
7307  * operators will be applied.
7308  */
7309 static struct triple *lvalue_conversion(struct compile_state *state, struct triple *def)
7310 {
7311         /* Tranform an array to a pointer to the first element */
7312         if ((def->type->type & TYPE_MASK) == TYPE_ARRAY) {
7313                 struct type *type;
7314                 type = new_type(
7315                         TYPE_POINTER | (def->type->type & QUAL_MASK),
7316                         def->type->left, 0);
7317                 if ((def->op == OP_SDECL) || IS_CONST_OP(def->op)) {
7318                         struct triple *addrconst;
7319                         if ((def->op != OP_SDECL) && (def->op != OP_BLOBCONST)) {
7320                                 internal_error(state, def, "bad array constant");
7321                         }
7322                         addrconst = triple(state, OP_ADDRCONST, type, 0, 0);
7323                         MISC(addrconst, 0) = def;
7324                         def = addrconst;
7325                 }
7326                 else {
7327                         def = triple(state, OP_CONVERT, type, def, 0);
7328                 }
7329         }
7330         /* Transform a function to a pointer to it */
7331         else if ((def->type->type & TYPE_MASK) == TYPE_FUNCTION) {
7332                 def = mk_addr_expr(state, def, 0);
7333         }
7334         return def;
7335 }
7336
7337 static struct triple *deref_field(
7338         struct compile_state *state, struct triple *expr, struct hash_entry *field)
7339 {
7340         struct triple *result;
7341         struct type *type, *member;
7342         ulong_t offset;
7343         if (!field) {
7344                 internal_error(state, 0, "No field passed to deref_field");
7345         }
7346         result = 0;
7347         type = expr->type;
7348         if (((type->type & TYPE_MASK) != TYPE_STRUCT) &&
7349                 ((type->type & TYPE_MASK) != TYPE_UNION)) {
7350                 error(state, 0, "request for member %s in something not a struct or union",
7351                         field->name);
7352         }
7353         member = field_type(state, type, field);
7354         if ((type->type & STOR_MASK) == STOR_PERM) {
7355                 /* Do the pointer arithmetic to get a deref the field */
7356                 offset = bits_to_bytes(field_offset(state, type, field));
7357                 result = do_mk_addr_expr(state, expr, member, offset);
7358                 result = mk_deref_expr(state, result);
7359         }
7360         else {
7361                 /* Find the variable for the field I want. */
7362                 result = triple(state, OP_DOT, member, expr, 0);
7363                 result->u.field = field;
7364         }
7365         return result;
7366 }
7367
7368 static struct triple *deref_index(
7369         struct compile_state *state, struct triple *expr, size_t index)
7370 {
7371         struct triple *result;
7372         struct type *type, *member;
7373         ulong_t offset;
7374
7375         result = 0;
7376         type = expr->type;
7377         member = index_type(state, type, index);
7378
7379         if ((type->type & STOR_MASK) == STOR_PERM) {
7380                 offset = bits_to_bytes(index_offset(state, type, index));
7381                 result = do_mk_addr_expr(state, expr, member, offset);
7382                 result = mk_deref_expr(state, result);
7383         }
7384         else {
7385                 result = triple(state, OP_INDEX, member, expr, 0);
7386                 result->u.cval = index;
7387         }
7388         return result;
7389 }
7390
7391 static struct triple *read_expr(struct compile_state *state, struct triple *def)
7392 {
7393         int op;
7394         if  (!def) {
7395                 return 0;
7396         }
7397 #warning "CHECK_ME is this the only place I need to do lvalue conversions?"
7398         /* Transform lvalues into something we can read */
7399         def = lvalue_conversion(state, def);
7400         if (!is_lvalue(state, def)) {
7401                 return def;
7402         }
7403         if (is_in_reg(state, def)) {
7404                 op = OP_READ;
7405         } else {
7406                 if (def->op == OP_SDECL) {
7407                         def = mk_addr_expr(state, def, 0);
7408                         def = mk_deref_expr(state, def);
7409                 }
7410                 op = OP_LOAD;
7411         }
7412         def = triple(state, op, def->type, def, 0);
7413         if (def->type->type & QUAL_VOLATILE) {
7414                 def->id |= TRIPLE_FLAG_VOLATILE;
7415         }
7416         return def;
7417 }
7418
7419 int is_write_compatible(struct compile_state *state, 
7420         struct type *dest, struct type *rval)
7421 {
7422         int compatible = 0;
7423         /* Both operands have arithmetic type */
7424         if (TYPE_ARITHMETIC(dest->type) && TYPE_ARITHMETIC(rval->type)) {
7425                 compatible = 1;
7426         }
7427         /* One operand is a pointer and the other is a pointer to void */
7428         else if (((dest->type & TYPE_MASK) == TYPE_POINTER) &&
7429                 ((rval->type & TYPE_MASK) == TYPE_POINTER) &&
7430                 (((dest->left->type & TYPE_MASK) == TYPE_VOID) ||
7431                         ((rval->left->type & TYPE_MASK) == TYPE_VOID))) {
7432                 compatible = 1;
7433         }
7434         /* If both types are the same without qualifiers we are good */
7435         else if (equiv_ptrs(dest, rval)) {
7436                 compatible = 1;
7437         }
7438         /* test for struct/union equality  */
7439         else if (equiv_types(dest, rval)) {
7440                 compatible = 1;
7441         }
7442         return compatible;
7443 }
7444
7445 static void write_compatible(struct compile_state *state,
7446         struct type *dest, struct type *rval)
7447 {
7448         if (!is_write_compatible(state, dest, rval)) {
7449                 FILE *fp = state->errout;
7450                 fprintf(fp, "dest: ");
7451                 name_of(fp, dest);
7452                 fprintf(fp,"\nrval: ");
7453                 name_of(fp, rval);
7454                 fprintf(fp, "\n");
7455                 error(state, 0, "Incompatible types in assignment");
7456         }
7457 }
7458
7459 static int is_init_compatible(struct compile_state *state,
7460         struct type *dest, struct type *rval)
7461 {
7462         int compatible = 0;
7463         if (is_write_compatible(state, dest, rval)) {
7464                 compatible = 1;
7465         }
7466         else if (equiv_types(dest, rval)) {
7467                 compatible = 1;
7468         }
7469         return compatible;
7470 }
7471
7472 static struct triple *write_expr(
7473         struct compile_state *state, struct triple *dest, struct triple *rval)
7474 {
7475         struct triple *def;
7476         int op;
7477
7478         def = 0;
7479         if (!rval) {
7480                 internal_error(state, 0, "missing rval");
7481         }
7482
7483         if (rval->op == OP_LIST) {
7484                 internal_error(state, 0, "expression of type OP_LIST?");
7485         }
7486         if (!is_lvalue(state, dest)) {
7487                 internal_error(state, 0, "writing to a non lvalue?");
7488         }
7489         if (dest->type->type & QUAL_CONST) {
7490                 internal_error(state, 0, "modifable lvalue expexted");
7491         }
7492
7493         write_compatible(state, dest->type, rval->type);
7494         if (!equiv_types(dest->type, rval->type)) {
7495                 rval = triple(state, OP_CONVERT, dest->type, rval, 0);
7496         }
7497
7498         /* Now figure out which assignment operator to use */
7499         op = -1;
7500         if (is_in_reg(state, dest)) {
7501                 def = triple(state, OP_WRITE, dest->type, rval, dest);
7502                 if (MISC(def, 0) != dest) {
7503                         internal_error(state, def, "huh?");
7504                 }
7505                 if (RHS(def, 0) != rval) {
7506                         internal_error(state, def, "huh?");
7507                 }
7508         } else {
7509                 def = triple(state, OP_STORE, dest->type, dest, rval);
7510         }
7511         if (def->type->type & QUAL_VOLATILE) {
7512                 def->id |= TRIPLE_FLAG_VOLATILE;
7513         }
7514         return def;
7515 }
7516
7517 static struct triple *init_expr(
7518         struct compile_state *state, struct triple *dest, struct triple *rval)
7519 {
7520         struct triple *def;
7521
7522         def = 0;
7523         if (!rval) {
7524                 internal_error(state, 0, "missing rval");
7525         }
7526         if ((dest->type->type & STOR_MASK) != STOR_PERM) {
7527                 rval = read_expr(state, rval);
7528                 def = write_expr(state, dest, rval);
7529         }
7530         else {
7531                 /* Fill in the array size if necessary */
7532                 if (((dest->type->type & TYPE_MASK) == TYPE_ARRAY) &&
7533                         ((rval->type->type & TYPE_MASK) == TYPE_ARRAY)) {
7534                         if (dest->type->elements == ELEMENT_COUNT_UNSPECIFIED) {
7535                                 dest->type->elements = rval->type->elements;
7536                         }
7537                 }
7538                 if (!equiv_types(dest->type, rval->type)) {
7539                         error(state, 0, "Incompatible types in inializer");
7540                 }
7541                 MISC(dest, 0) = rval;
7542                 insert_triple(state, dest, rval);
7543                 rval->id |= TRIPLE_FLAG_FLATTENED;
7544                 use_triple(MISC(dest, 0), dest);
7545         }
7546         return def;
7547 }
7548
7549 struct type *arithmetic_result(
7550         struct compile_state *state, struct triple *left, struct triple *right)
7551 {
7552         struct type *type;
7553         /* Sanity checks to ensure I am working with arithmetic types */
7554         arithmetic(state, left);
7555         arithmetic(state, right);
7556         type = new_type(
7557                 do_arithmetic_conversion(
7558                         get_basic_type(left->type),
7559                         get_basic_type(right->type)),
7560                 0, 0);
7561         return type;
7562 }
7563
7564 struct type *ptr_arithmetic_result(
7565         struct compile_state *state, struct triple *left, struct triple *right)
7566 {
7567         struct type *type;
7568         /* Sanity checks to ensure I am working with the proper types */
7569         ptr_arithmetic(state, left);
7570         arithmetic(state, right);
7571         if (TYPE_ARITHMETIC(left->type->type) && 
7572                 TYPE_ARITHMETIC(right->type->type)) {
7573                 type = arithmetic_result(state, left, right);
7574         }
7575         else if (TYPE_PTR(left->type->type)) {
7576                 type = left->type;
7577         }
7578         else {
7579                 internal_error(state, 0, "huh?");
7580                 type = 0;
7581         }
7582         return type;
7583 }
7584
7585 /* boolean helper function */
7586
7587 static struct triple *ltrue_expr(struct compile_state *state, 
7588         struct triple *expr)
7589 {
7590         switch(expr->op) {
7591         case OP_LTRUE:   case OP_LFALSE:  case OP_EQ:      case OP_NOTEQ:
7592         case OP_SLESS:   case OP_ULESS:   case OP_SMORE:   case OP_UMORE:
7593         case OP_SLESSEQ: case OP_ULESSEQ: case OP_SMOREEQ: case OP_UMOREEQ:
7594                 /* If the expression is already boolean do nothing */
7595                 break;
7596         default:
7597                 expr = triple(state, OP_LTRUE, &int_type, expr, 0);
7598                 break;
7599         }
7600         return expr;
7601 }
7602
7603 static struct triple *lfalse_expr(struct compile_state *state, 
7604         struct triple *expr)
7605 {
7606         return triple(state, OP_LFALSE, &int_type, expr, 0);
7607 }
7608
7609 static struct triple *mkland_expr(
7610         struct compile_state *state,
7611         struct triple *left, struct triple *right)
7612 {
7613         struct triple *def, *val, *var, *jmp, *mid, *end;
7614         struct triple *lstore, *rstore;
7615
7616         /* Generate some intermediate triples */
7617         end = label(state);
7618         var = variable(state, &int_type);
7619         
7620         /* Store the left hand side value */
7621         lstore = write_expr(state, var, left);
7622
7623         /* Jump if the value is false */
7624         jmp =  branch(state, end, 
7625                 lfalse_expr(state, read_expr(state, var)));
7626         mid = label(state);
7627         
7628         /* Store the right hand side value */
7629         rstore = write_expr(state, var, right);
7630
7631         /* An expression for the computed value */
7632         val = read_expr(state, var);
7633
7634         /* Generate the prog for a logical and */
7635         def = mkprog(state, var, lstore, jmp, mid, rstore, end, val, 0UL);
7636         
7637         return def;
7638 }
7639
7640 static struct triple *mklor_expr(
7641         struct compile_state *state,
7642         struct triple *left, struct triple *right)
7643 {
7644         struct triple *def, *val, *var, *jmp, *mid, *end;
7645
7646         /* Generate some intermediate triples */
7647         end = label(state);
7648         var = variable(state, &int_type);
7649         
7650         /* Store the left hand side value */
7651         left = write_expr(state, var, left);
7652         
7653         /* Jump if the value is true */
7654         jmp = branch(state, end, read_expr(state, var));
7655         mid = label(state);
7656         
7657         /* Store the right hand side value */
7658         right = write_expr(state, var, right);
7659                 
7660         /* An expression for the computed value*/
7661         val = read_expr(state, var);
7662
7663         /* Generate the prog for a logical or */
7664         def = mkprog(state, var, left, jmp, mid, right, end, val, 0UL);
7665
7666         return def;
7667 }
7668
7669 static struct triple *mkcond_expr(
7670         struct compile_state *state, 
7671         struct triple *test, struct triple *left, struct triple *right)
7672 {
7673         struct triple *def, *val, *var, *jmp1, *jmp2, *top, *mid, *end;
7674         struct type *result_type;
7675         unsigned int left_type, right_type;
7676         bool(state, test);
7677         left_type = left->type->type;
7678         right_type = right->type->type;
7679         result_type = 0;
7680         /* Both operands have arithmetic type */
7681         if (TYPE_ARITHMETIC(left_type) && TYPE_ARITHMETIC(right_type)) {
7682                 result_type = arithmetic_result(state, left, right);
7683         }
7684         /* Both operands have void type */
7685         else if (((left_type & TYPE_MASK) == TYPE_VOID) &&
7686                 ((right_type & TYPE_MASK) == TYPE_VOID)) {
7687                 result_type = &void_type;
7688         }
7689         /* pointers to the same type... */
7690         else if ((result_type = compatible_ptrs(left->type, right->type))) {
7691                 ;
7692         }
7693         /* Both operands are pointers and left is a pointer to void */
7694         else if (((left_type & TYPE_MASK) == TYPE_POINTER) &&
7695                 ((right_type & TYPE_MASK) == TYPE_POINTER) &&
7696                 ((left->type->left->type & TYPE_MASK) == TYPE_VOID)) {
7697                 result_type = right->type;
7698         }
7699         /* Both operands are pointers and right is a pointer to void */
7700         else if (((left_type & TYPE_MASK) == TYPE_POINTER) &&
7701                 ((right_type & TYPE_MASK) == TYPE_POINTER) &&
7702                 ((right->type->left->type & TYPE_MASK) == TYPE_VOID)) {
7703                 result_type = left->type;
7704         }
7705         if (!result_type) {
7706                 error(state, 0, "Incompatible types in conditional expression");
7707         }
7708         /* Generate some intermediate triples */
7709         mid = label(state);
7710         end = label(state);
7711         var = variable(state, result_type);
7712
7713         /* Branch if the test is false */
7714         jmp1 = branch(state, mid, lfalse_expr(state, read_expr(state, test)));
7715         top = label(state);
7716
7717         /* Store the left hand side value */
7718         left = write_expr(state, var, left);
7719
7720         /* Branch to the end */
7721         jmp2 = branch(state, end, 0);
7722
7723         /* Store the right hand side value */
7724         right = write_expr(state, var, right);
7725         
7726         /* An expression for the computed value */
7727         val = read_expr(state, var);
7728
7729         /* Generate the prog for a conditional expression */
7730         def = mkprog(state, var, jmp1, top, left, jmp2, mid, right, end, val, 0UL);
7731
7732         return def;
7733 }
7734
7735
7736 static int expr_depth(struct compile_state *state, struct triple *ins)
7737 {
7738 #warning "FIXME move optimal ordering of subexpressions into the optimizer"
7739         int count;
7740         count = 0;
7741         if (!ins || (ins->id & TRIPLE_FLAG_FLATTENED)) {
7742                 count = 0;
7743         }
7744         else if (ins->op == OP_DEREF) {
7745                 count = expr_depth(state, RHS(ins, 0)) - 1;
7746         }
7747         else if (ins->op == OP_VAL) {
7748                 count = expr_depth(state, RHS(ins, 0)) - 1;
7749         }
7750         else if (ins->op == OP_FCALL) {
7751                 /* Don't figure the depth of a call just guess it is huge */
7752                 count = 1000;
7753         }
7754         else {
7755                 struct triple **expr;
7756                 expr = triple_rhs(state, ins, 0);
7757                 for(;expr; expr = triple_rhs(state, ins, expr)) {
7758                         if (*expr) {
7759                                 int depth;
7760                                 depth = expr_depth(state, *expr);
7761                                 if (depth > count) {
7762                                         count = depth;
7763                                 }
7764                         }
7765                 }
7766         }
7767         return count + 1;
7768 }
7769
7770 static struct triple *flatten_generic(
7771         struct compile_state *state, struct triple *first, struct triple *ptr,
7772         int ignored)
7773 {
7774         struct rhs_vector {
7775                 int depth;
7776                 struct triple **ins;
7777         } vector[MAX_RHS];
7778         int i, rhs, lhs;
7779         /* Only operations with just a rhs and a lhs should come here */
7780         rhs = ptr->rhs;
7781         lhs = ptr->lhs;
7782         if (TRIPLE_SIZE(ptr) != lhs + rhs + ignored) {
7783                 internal_error(state, ptr, "unexpected args for: %d %s",
7784                         ptr->op, tops(ptr->op));
7785         }
7786         /* Find the depth of the rhs elements */
7787         for(i = 0; i < rhs; i++) {
7788                 vector[i].ins = &RHS(ptr, i);
7789                 vector[i].depth = expr_depth(state, *vector[i].ins);
7790         }
7791         /* Selection sort the rhs */
7792         for(i = 0; i < rhs; i++) {
7793                 int j, max = i;
7794                 for(j = i + 1; j < rhs; j++ ) {
7795                         if (vector[j].depth > vector[max].depth) {
7796                                 max = j;
7797                         }
7798                 }
7799                 if (max != i) {
7800                         struct rhs_vector tmp;
7801                         tmp = vector[i];
7802                         vector[i] = vector[max];
7803                         vector[max] = tmp;
7804                 }
7805         }
7806         /* Now flatten the rhs elements */
7807         for(i = 0; i < rhs; i++) {
7808                 *vector[i].ins = flatten(state, first, *vector[i].ins);
7809                 use_triple(*vector[i].ins, ptr);
7810         }
7811         if (lhs) {
7812                 insert_triple(state, first, ptr);
7813                 ptr->id |= TRIPLE_FLAG_FLATTENED;
7814                 ptr->id &= ~TRIPLE_FLAG_LOCAL;
7815                 
7816                 /* Now flatten the lhs elements */
7817                 for(i = 0; i < lhs; i++) {
7818                         struct triple **ins = &LHS(ptr, i);
7819                         *ins = flatten(state, first, *ins);
7820                         use_triple(*ins, ptr);
7821                 }
7822         }
7823         return ptr;
7824 }
7825
7826 static struct triple *flatten_prog(
7827         struct compile_state *state, struct triple *first, struct triple *ptr)
7828 {
7829         struct triple *head, *body, *val;
7830         head = RHS(ptr, 0);
7831         RHS(ptr, 0) = 0;
7832         val  = head->prev;
7833         body = head->next;
7834         release_triple(state, head);
7835         release_triple(state, ptr);
7836         val->next        = first;
7837         body->prev       = first->prev;
7838         body->prev->next = body;
7839         val->next->prev  = val;
7840
7841         if (triple_is_cbranch(state, body->prev) ||
7842                 triple_is_call(state, body->prev)) {
7843                 unuse_triple(first, body->prev);
7844                 use_triple(body, body->prev);
7845         }
7846         
7847         if (!(val->id & TRIPLE_FLAG_FLATTENED)) {
7848                 internal_error(state, val, "val not flattened?");
7849         }
7850
7851         return val;
7852 }
7853
7854
7855 static struct triple *flatten_part(
7856         struct compile_state *state, struct triple *first, struct triple *ptr)
7857 {
7858         if (!triple_is_part(state, ptr)) {
7859                 internal_error(state, ptr,  "not a part");
7860         }
7861         if (ptr->rhs || ptr->lhs || ptr->targ || (ptr->misc != 1)) {
7862                 internal_error(state, ptr, "unexpected args for: %d %s",
7863                         ptr->op, tops(ptr->op));
7864         }
7865         MISC(ptr, 0) = flatten(state, first, MISC(ptr, 0));
7866         use_triple(MISC(ptr, 0), ptr);
7867         return flatten_generic(state, first, ptr, 1);
7868 }
7869
7870 static struct triple *flatten(
7871         struct compile_state *state, struct triple *first, struct triple *ptr)
7872 {
7873         struct triple *orig_ptr;
7874         if (!ptr)
7875                 return 0;
7876         do {
7877                 orig_ptr = ptr;
7878                 /* Only flatten triples once */
7879                 if (ptr->id & TRIPLE_FLAG_FLATTENED) {
7880                         return ptr;
7881                 }
7882                 switch(ptr->op) {
7883                 case OP_VAL:
7884                         RHS(ptr, 0) = flatten(state, first, RHS(ptr, 0));
7885                         return MISC(ptr, 0);
7886                         break;
7887                 case OP_PROG:
7888                         ptr = flatten_prog(state, first, ptr);
7889                         break;
7890                 case OP_FCALL:
7891                         ptr = flatten_generic(state, first, ptr, 1);
7892                         insert_triple(state, first, ptr);
7893                         ptr->id |= TRIPLE_FLAG_FLATTENED;
7894                         ptr->id &= ~TRIPLE_FLAG_LOCAL;
7895                         if (ptr->next != ptr) {
7896                                 use_triple(ptr->next, ptr);
7897                         }
7898                         break;
7899                 case OP_READ:
7900                 case OP_LOAD:
7901                         RHS(ptr, 0) = flatten(state, first, RHS(ptr, 0));
7902                         use_triple(RHS(ptr, 0), ptr);
7903                         break;
7904                 case OP_WRITE:
7905                         ptr = flatten_generic(state, first, ptr, 1);
7906                         MISC(ptr, 0) = flatten(state, first, MISC(ptr, 0));
7907                         use_triple(MISC(ptr, 0), ptr);
7908                         break;
7909                 case OP_BRANCH:
7910                         use_triple(TARG(ptr, 0), ptr);
7911                         break;
7912                 case OP_CBRANCH:
7913                         RHS(ptr, 0) = flatten(state, first, RHS(ptr, 0));
7914                         use_triple(RHS(ptr, 0), ptr);
7915                         use_triple(TARG(ptr, 0), ptr);
7916                         insert_triple(state, first, ptr);
7917                         ptr->id |= TRIPLE_FLAG_FLATTENED;
7918                         ptr->id &= ~TRIPLE_FLAG_LOCAL;
7919                         if (ptr->next != ptr) {
7920                                 use_triple(ptr->next, ptr);
7921                         }
7922                         break;
7923                 case OP_CALL:
7924                         MISC(ptr, 0) = flatten(state, first, MISC(ptr, 0));
7925                         use_triple(MISC(ptr, 0), ptr);
7926                         use_triple(TARG(ptr, 0), ptr);
7927                         insert_triple(state, first, ptr);
7928                         ptr->id |= TRIPLE_FLAG_FLATTENED;
7929                         ptr->id &= ~TRIPLE_FLAG_LOCAL;
7930                         if (ptr->next != ptr) {
7931                                 use_triple(ptr->next, ptr);
7932                         }
7933                         break;
7934                 case OP_RET:
7935                         RHS(ptr, 0) = flatten(state, first, RHS(ptr, 0));
7936                         use_triple(RHS(ptr, 0), ptr);
7937                         break;
7938                 case OP_BLOBCONST:
7939                         insert_triple(state, state->global_pool, ptr);
7940                         ptr->id |= TRIPLE_FLAG_FLATTENED;
7941                         ptr->id &= ~TRIPLE_FLAG_LOCAL;
7942                         ptr = triple(state, OP_SDECL, ptr->type, ptr, 0);
7943                         use_triple(MISC(ptr, 0), ptr);
7944                         break;
7945                 case OP_DEREF:
7946                         /* Since OP_DEREF is just a marker delete it when I flatten it */
7947                         ptr = RHS(ptr, 0);
7948                         RHS(orig_ptr, 0) = 0;
7949                         free_triple(state, orig_ptr);
7950                         break;
7951                 case OP_DOT:
7952                         if (RHS(ptr, 0)->op == OP_DEREF) {
7953                                 struct triple *base, *left;
7954                                 ulong_t offset;
7955                                 base = MISC(ptr, 0);
7956                                 offset = bits_to_bytes(field_offset(state, base->type, ptr->u.field));
7957                                 left = RHS(base, 0);
7958                                 ptr = triple(state, OP_ADD, left->type, 
7959                                         read_expr(state, left),
7960                                         int_const(state, &ulong_type, offset));
7961                                 free_triple(state, base);
7962                         }
7963                         else {
7964                                 ptr = flatten_part(state, first, ptr);
7965                         }
7966                         break;
7967                 case OP_INDEX:
7968                         if (RHS(ptr, 0)->op == OP_DEREF) {
7969                                 struct triple *base, *left;
7970                                 ulong_t offset;
7971                                 base = MISC(ptr, 0);
7972                                 offset = bits_to_bytes(index_offset(state, base->type, ptr->u.cval));
7973                                 left = RHS(base, 0);
7974                                 ptr = triple(state, OP_ADD, left->type,
7975                                         read_expr(state, left),
7976                                         int_const(state, &long_type, offset));
7977                                 free_triple(state, base);
7978                         }
7979                         else {
7980                                 ptr = flatten_part(state, first, ptr);
7981                         }
7982                         break;
7983                 case OP_PIECE:
7984                         ptr = flatten_part(state, first, ptr);
7985                         use_triple(ptr, MISC(ptr, 0));
7986                         break;
7987                 case OP_ADDRCONST:
7988                         MISC(ptr, 0) = flatten(state, first, MISC(ptr, 0));
7989                         use_triple(MISC(ptr, 0), ptr);
7990                         break;
7991                 case OP_SDECL:
7992                         first = state->global_pool;
7993                         MISC(ptr, 0) = flatten(state, first, MISC(ptr, 0));
7994                         use_triple(MISC(ptr, 0), ptr);
7995                         insert_triple(state, first, ptr);
7996                         ptr->id |= TRIPLE_FLAG_FLATTENED;
7997                         ptr->id &= ~TRIPLE_FLAG_LOCAL;
7998                         return ptr;
7999                 case OP_ADECL:
8000                         ptr = flatten_generic(state, first, ptr, 0);
8001                         break;
8002                 default:
8003                         /* Flatten the easy cases we don't override */
8004                         ptr = flatten_generic(state, first, ptr, 0);
8005                         break;
8006                 }
8007         } while(ptr && (ptr != orig_ptr));
8008         if (ptr && !(ptr->id & TRIPLE_FLAG_FLATTENED)) {
8009                 insert_triple(state, first, ptr);
8010                 ptr->id |= TRIPLE_FLAG_FLATTENED;
8011                 ptr->id &= ~TRIPLE_FLAG_LOCAL;
8012         }
8013         return ptr;
8014 }
8015
8016 static void release_expr(struct compile_state *state, struct triple *expr)
8017 {
8018         struct triple *head;
8019         head = label(state);
8020         flatten(state, head, expr);
8021         while(head->next != head) {
8022                 release_triple(state, head->next);
8023         }
8024         free_triple(state, head);
8025 }
8026
8027 static int replace_rhs_use(struct compile_state *state,
8028         struct triple *orig, struct triple *new, struct triple *use)
8029 {
8030         struct triple **expr;
8031         int found;
8032         found = 0;
8033         expr = triple_rhs(state, use, 0);
8034         for(;expr; expr = triple_rhs(state, use, expr)) {
8035                 if (*expr == orig) {
8036                         *expr = new;
8037                         found = 1;
8038                 }
8039         }
8040         if (found) {
8041                 unuse_triple(orig, use);
8042                 use_triple(new, use);
8043         }
8044         return found;
8045 }
8046
8047 static int replace_lhs_use(struct compile_state *state,
8048         struct triple *orig, struct triple *new, struct triple *use)
8049 {
8050         struct triple **expr;
8051         int found;
8052         found = 0;
8053         expr = triple_lhs(state, use, 0);
8054         for(;expr; expr = triple_lhs(state, use, expr)) {
8055                 if (*expr == orig) {
8056                         *expr = new;
8057                         found = 1;
8058                 }
8059         }
8060         if (found) {
8061                 unuse_triple(orig, use);
8062                 use_triple(new, use);
8063         }
8064         return found;
8065 }
8066
8067 static int replace_misc_use(struct compile_state *state,
8068         struct triple *orig, struct triple *new, struct triple *use)
8069 {
8070         struct triple **expr;
8071         int found;
8072         found = 0;
8073         expr = triple_misc(state, use, 0);
8074         for(;expr; expr = triple_misc(state, use, expr)) {
8075                 if (*expr == orig) {
8076                         *expr = new;
8077                         found = 1;
8078                 }
8079         }
8080         if (found) {
8081                 unuse_triple(orig, use);
8082                 use_triple(new, use);
8083         }
8084         return found;
8085 }
8086
8087 static int replace_targ_use(struct compile_state *state,
8088         struct triple *orig, struct triple *new, struct triple *use)
8089 {
8090         struct triple **expr;
8091         int found;
8092         found = 0;
8093         expr = triple_targ(state, use, 0);
8094         for(;expr; expr = triple_targ(state, use, expr)) {
8095                 if (*expr == orig) {
8096                         *expr = new;
8097                         found = 1;
8098                 }
8099         }
8100         if (found) {
8101                 unuse_triple(orig, use);
8102                 use_triple(new, use);
8103         }
8104         return found;
8105 }
8106
8107 static void replace_use(struct compile_state *state,
8108         struct triple *orig, struct triple *new, struct triple *use)
8109 {
8110         int found;
8111         found = 0;
8112         found |= replace_rhs_use(state, orig, new, use);
8113         found |= replace_lhs_use(state, orig, new, use);
8114         found |= replace_misc_use(state, orig, new, use);
8115         found |= replace_targ_use(state, orig, new, use);
8116         if (!found) {
8117                 internal_error(state, use, "use without use");
8118         }
8119 }
8120
8121 static void propogate_use(struct compile_state *state,
8122         struct triple *orig, struct triple *new)
8123 {
8124         struct triple_set *user, *next;
8125         for(user = orig->use; user; user = next) {
8126                 /* Careful replace_use modifies the use chain and
8127                  * removes use.  So we must get a copy of the next
8128                  * entry early.
8129                  */
8130                 next = user->next;
8131                 replace_use(state, orig, new, user->member);
8132         }
8133         if (orig->use) {
8134                 internal_error(state, orig, "used after propogate_use");
8135         }
8136 }
8137
8138 /*
8139  * Code generators
8140  * ===========================
8141  */
8142
8143 static struct triple *mk_cast_expr(
8144         struct compile_state *state, struct type *type, struct triple *expr)
8145 {
8146         struct triple *def;
8147         def = read_expr(state, expr);
8148         def = triple(state, OP_CONVERT, type, def, 0);
8149         return def;
8150 }
8151
8152 static struct triple *mk_add_expr(
8153         struct compile_state *state, struct triple *left, struct triple *right)
8154 {
8155         struct type *result_type;
8156         /* Put pointer operands on the left */
8157         if (is_pointer(right)) {
8158                 struct triple *tmp;
8159                 tmp = left;
8160                 left = right;
8161                 right = tmp;
8162         }
8163         left  = read_expr(state, left);
8164         right = read_expr(state, right);
8165         result_type = ptr_arithmetic_result(state, left, right);
8166         if (is_pointer(left)) {
8167                 struct type *ptr_math;
8168                 int op;
8169                 if (is_signed(right->type)) {
8170                         ptr_math = &long_type;
8171                         op = OP_SMUL;
8172                 } else {
8173                         ptr_math = &ulong_type;
8174                         op = OP_UMUL;
8175                 }
8176                 if (!equiv_types(right->type, ptr_math)) {
8177                         right = mk_cast_expr(state, ptr_math, right);
8178                 }
8179                 right = triple(state, op, ptr_math, right, 
8180                         int_const(state, ptr_math, 
8181                                 size_of_in_bytes(state, left->type->left)));
8182         }
8183         return triple(state, OP_ADD, result_type, left, right);
8184 }
8185
8186 static struct triple *mk_sub_expr(
8187         struct compile_state *state, struct triple *left, struct triple *right)
8188 {
8189         struct type *result_type;
8190         result_type = ptr_arithmetic_result(state, left, right);
8191         left  = read_expr(state, left);
8192         right = read_expr(state, right);
8193         if (is_pointer(left)) {
8194                 struct type *ptr_math;
8195                 int op;
8196                 if (is_signed(right->type)) {
8197                         ptr_math = &long_type;
8198                         op = OP_SMUL;
8199                 } else {
8200                         ptr_math = &ulong_type;
8201                         op = OP_UMUL;
8202                 }
8203                 if (!equiv_types(right->type, ptr_math)) {
8204                         right = mk_cast_expr(state, ptr_math, right);
8205                 }
8206                 right = triple(state, op, ptr_math, right, 
8207                         int_const(state, ptr_math, 
8208                                 size_of_in_bytes(state, left->type->left)));
8209         }
8210         return triple(state, OP_SUB, result_type, left, right);
8211 }
8212
8213 static struct triple *mk_pre_inc_expr(
8214         struct compile_state *state, struct triple *def)
8215 {
8216         struct triple *val;
8217         lvalue(state, def);
8218         val = mk_add_expr(state, def, int_const(state, &int_type, 1));
8219         return triple(state, OP_VAL, def->type,
8220                 write_expr(state, def, val),
8221                 val);
8222 }
8223
8224 static struct triple *mk_pre_dec_expr(
8225         struct compile_state *state, struct triple *def)
8226 {
8227         struct triple *val;
8228         lvalue(state, def);
8229         val = mk_sub_expr(state, def, int_const(state, &int_type, 1));
8230         return triple(state, OP_VAL, def->type,
8231                 write_expr(state, def, val),
8232                 val);
8233 }
8234
8235 static struct triple *mk_post_inc_expr(
8236         struct compile_state *state, struct triple *def)
8237 {
8238         struct triple *val;
8239         lvalue(state, def);
8240         val = read_expr(state, def);
8241         return triple(state, OP_VAL, def->type,
8242                 write_expr(state, def,
8243                         mk_add_expr(state, val, int_const(state, &int_type, 1)))
8244                 , val);
8245 }
8246
8247 static struct triple *mk_post_dec_expr(
8248         struct compile_state *state, struct triple *def)
8249 {
8250         struct triple *val;
8251         lvalue(state, def);
8252         val = read_expr(state, def);
8253         return triple(state, OP_VAL, def->type, 
8254                 write_expr(state, def,
8255                         mk_sub_expr(state, val, int_const(state, &int_type, 1)))
8256                 , val);
8257 }
8258
8259 static struct triple *mk_subscript_expr(
8260         struct compile_state *state, struct triple *left, struct triple *right)
8261 {
8262         left  = read_expr(state, left);
8263         right = read_expr(state, right);
8264         if (!is_pointer(left) && !is_pointer(right)) {
8265                 error(state, left, "subscripted value is not a pointer");
8266         }
8267         return mk_deref_expr(state, mk_add_expr(state, left, right));
8268 }
8269
8270
8271 /*
8272  * Compile time evaluation
8273  * ===========================
8274  */
8275 static int is_const(struct triple *ins)
8276 {
8277         return IS_CONST_OP(ins->op);
8278 }
8279
8280 static int is_simple_const(struct triple *ins)
8281 {
8282         /* Is this a constant that u.cval has the value.
8283          * Or equivalently is this a constant that read_const
8284          * works on.
8285          * So far only OP_INTCONST qualifies.  
8286          */
8287         return (ins->op == OP_INTCONST);
8288 }
8289
8290 static int constants_equal(struct compile_state *state, 
8291         struct triple *left, struct triple *right)
8292 {
8293         int equal;
8294         if ((left->op == OP_UNKNOWNVAL) || (right->op == OP_UNKNOWNVAL)) {
8295                 equal = 0;
8296         }
8297         else if (!is_const(left) || !is_const(right)) {
8298                 equal = 0;
8299         }
8300         else if (left->op != right->op) {
8301                 equal = 0;
8302         }
8303         else if (!equiv_types(left->type, right->type)) {
8304                 equal = 0;
8305         }
8306         else {
8307                 equal = 0;
8308                 switch(left->op) {
8309                 case OP_INTCONST:
8310                         if (left->u.cval == right->u.cval) {
8311                                 equal = 1;
8312                         }
8313                         break;
8314                 case OP_BLOBCONST:
8315                 {
8316                         size_t lsize, rsize, bytes;
8317                         lsize = size_of(state, left->type);
8318                         rsize = size_of(state, right->type);
8319                         if (lsize != rsize) {
8320                                 break;
8321                         }
8322                         bytes = bits_to_bytes(lsize);
8323                         if (memcmp(left->u.blob, right->u.blob, bytes) == 0) {
8324                                 equal = 1;
8325                         }
8326                         break;
8327                 }
8328                 case OP_ADDRCONST:
8329                         if ((MISC(left, 0) == MISC(right, 0)) &&
8330                                 (left->u.cval == right->u.cval)) {
8331                                 equal = 1;
8332                         }
8333                         break;
8334                 default:
8335                         internal_error(state, left, "uknown constant type");
8336                         break;
8337                 }
8338         }
8339         return equal;
8340 }
8341
8342 static int is_zero(struct triple *ins)
8343 {
8344         return is_simple_const(ins) && (ins->u.cval == 0);
8345 }
8346
8347 static int is_one(struct triple *ins)
8348 {
8349         return is_simple_const(ins) && (ins->u.cval == 1);
8350 }
8351
8352 static long_t bit_count(ulong_t value)
8353 {
8354         int count;
8355         int i;
8356         count = 0;
8357         for(i = (sizeof(ulong_t)*8) -1; i >= 0; i--) {
8358                 ulong_t mask;
8359                 mask = 1;
8360                 mask <<= i;
8361                 if (value & mask) {
8362                         count++;
8363                 }
8364         }
8365         return count;
8366         
8367 }
8368 static long_t bsr(ulong_t value)
8369 {
8370         int i;
8371         for(i = (sizeof(ulong_t)*8) -1; i >= 0; i--) {
8372                 ulong_t mask;
8373                 mask = 1;
8374                 mask <<= i;
8375                 if (value & mask) {
8376                         return i;
8377                 }
8378         }
8379         return -1;
8380 }
8381
8382 static long_t bsf(ulong_t value)
8383 {
8384         int i;
8385         for(i = 0; i < (sizeof(ulong_t)*8); i++) {
8386                 ulong_t mask;
8387                 mask = 1;
8388                 mask <<= 1;
8389                 if (value & mask) {
8390                         return i;
8391                 }
8392         }
8393         return -1;
8394 }
8395
8396 static long_t ilog2(ulong_t value)
8397 {
8398         return bsr(value);
8399 }
8400
8401 static long_t tlog2(struct triple *ins)
8402 {
8403         return ilog2(ins->u.cval);
8404 }
8405
8406 static int is_pow2(struct triple *ins)
8407 {
8408         ulong_t value, mask;
8409         long_t log;
8410         if (!is_const(ins)) {
8411                 return 0;
8412         }
8413         value = ins->u.cval;
8414         log = ilog2(value);
8415         if (log == -1) {
8416                 return 0;
8417         }
8418         mask = 1;
8419         mask <<= log;
8420         return  ((value & mask) == value);
8421 }
8422
8423 static ulong_t read_const(struct compile_state *state,
8424         struct triple *ins, struct triple *rhs)
8425 {
8426         switch(rhs->type->type &TYPE_MASK) {
8427         case TYPE_CHAR:   
8428         case TYPE_SHORT:
8429         case TYPE_INT:
8430         case TYPE_LONG:
8431         case TYPE_UCHAR:   
8432         case TYPE_USHORT:  
8433         case TYPE_UINT:
8434         case TYPE_ULONG:
8435         case TYPE_POINTER:
8436         case TYPE_BITFIELD:
8437                 break;
8438         default:
8439                 fprintf(state->errout, "type: ");
8440                 name_of(state->errout, rhs->type);
8441                 fprintf(state->errout, "\n");
8442                 internal_warning(state, rhs, "bad type to read_const");
8443                 break;
8444         }
8445         if (!is_simple_const(rhs)) {
8446                 internal_error(state, rhs, "bad op to read_const");
8447         }
8448         return rhs->u.cval;
8449 }
8450
8451 static long_t read_sconst(struct compile_state *state,
8452         struct triple *ins, struct triple *rhs)
8453 {
8454         return (long_t)(rhs->u.cval);
8455 }
8456
8457 int const_ltrue(struct compile_state *state, struct triple *ins, struct triple *rhs)
8458 {
8459         if (!is_const(rhs)) {
8460                 internal_error(state, 0, "non const passed to const_true");
8461         }
8462         return !is_zero(rhs);
8463 }
8464
8465 int const_eq(struct compile_state *state, struct triple *ins,
8466         struct triple *left, struct triple *right)
8467 {
8468         int result;
8469         if (!is_const(left) || !is_const(right)) {
8470                 internal_warning(state, ins, "non const passed to const_eq");
8471                 result = -1;
8472         }
8473         else if (left == right) {
8474                 result = 1;
8475         }
8476         else if (is_simple_const(left) && is_simple_const(right)) {
8477                 ulong_t lval, rval;
8478                 lval = read_const(state, ins, left);
8479                 rval = read_const(state, ins, right);
8480                 result = (lval == rval);
8481         }
8482         else if ((left->op == OP_ADDRCONST) && 
8483                 (right->op == OP_ADDRCONST)) {
8484                 result = (MISC(left, 0) == MISC(right, 0)) &&
8485                         (left->u.cval == right->u.cval);
8486         }
8487         else {
8488                 internal_warning(state, ins, "incomparable constants passed to const_eq");
8489                 result = -1;
8490         }
8491         return result;
8492         
8493 }
8494
8495 int const_ucmp(struct compile_state *state, struct triple *ins,
8496         struct triple *left, struct triple *right)
8497 {
8498         int result;
8499         if (!is_const(left) || !is_const(right)) {
8500                 internal_warning(state, ins, "non const past to const_ucmp");
8501                 result = -2;
8502         }
8503         else if (left == right) {
8504                 result = 0;
8505         }
8506         else if (is_simple_const(left) && is_simple_const(right)) {
8507                 ulong_t lval, rval;
8508                 lval = read_const(state, ins, left);
8509                 rval = read_const(state, ins, right);
8510                 result = 0;
8511                 if (lval > rval) {
8512                         result = 1;
8513                 } else if (rval > lval) {
8514                         result = -1;
8515                 }
8516         }
8517         else if ((left->op == OP_ADDRCONST) && 
8518                 (right->op == OP_ADDRCONST) &&
8519                 (MISC(left, 0) == MISC(right, 0))) {
8520                 result = 0;
8521                 if (left->u.cval > right->u.cval) {
8522                         result = 1;
8523                 } else if (left->u.cval < right->u.cval) {
8524                         result = -1;
8525                 }
8526         }
8527         else {
8528                 internal_warning(state, ins, "incomparable constants passed to const_ucmp");
8529                 result = -2;
8530         }
8531         return result;
8532 }
8533
8534 int const_scmp(struct compile_state *state, struct triple *ins,
8535         struct triple *left, struct triple *right)
8536 {
8537         int result;
8538         if (!is_const(left) || !is_const(right)) {
8539                 internal_warning(state, ins, "non const past to ucmp_const");
8540                 result = -2;
8541         }
8542         else if (left == right) {
8543                 result = 0;
8544         }
8545         else if (is_simple_const(left) && is_simple_const(right)) {
8546                 long_t lval, rval;
8547                 lval = read_sconst(state, ins, left);
8548                 rval = read_sconst(state, ins, right);
8549                 result = 0;
8550                 if (lval > rval) {
8551                         result = 1;
8552                 } else if (rval > lval) {
8553                         result = -1;
8554                 }
8555         }
8556         else {
8557                 internal_warning(state, ins, "incomparable constants passed to const_scmp");
8558                 result = -2;
8559         }
8560         return result;
8561 }
8562
8563 static void unuse_rhs(struct compile_state *state, struct triple *ins)
8564 {
8565         struct triple **expr;
8566         expr = triple_rhs(state, ins, 0);
8567         for(;expr;expr = triple_rhs(state, ins, expr)) {
8568                 if (*expr) {
8569                         unuse_triple(*expr, ins);
8570                         *expr = 0;
8571                 }
8572         }
8573 }
8574
8575 static void unuse_lhs(struct compile_state *state, struct triple *ins)
8576 {
8577         struct triple **expr;
8578         expr = triple_lhs(state, ins, 0);
8579         for(;expr;expr = triple_lhs(state, ins, expr)) {
8580                 unuse_triple(*expr, ins);
8581                 *expr = 0;
8582         }
8583 }
8584
8585 static void unuse_misc(struct compile_state *state, struct triple *ins)
8586 {
8587         struct triple **expr;
8588         expr = triple_misc(state, ins, 0);
8589         for(;expr;expr = triple_misc(state, ins, expr)) {
8590                 unuse_triple(*expr, ins);
8591                 *expr = 0;
8592         }
8593 }
8594
8595 static void unuse_targ(struct compile_state *state, struct triple *ins)
8596 {
8597         int i;
8598         struct triple **slot;
8599         slot = &TARG(ins, 0);
8600         for(i = 0; i < ins->targ; i++) {
8601                 unuse_triple(slot[i], ins);
8602                 slot[i] = 0;
8603         }
8604 }
8605
8606 static void check_lhs(struct compile_state *state, struct triple *ins)
8607 {
8608         struct triple **expr;
8609         expr = triple_lhs(state, ins, 0);
8610         for(;expr;expr = triple_lhs(state, ins, expr)) {
8611                 internal_error(state, ins, "unexpected lhs");
8612         }
8613         
8614 }
8615
8616 static void check_misc(struct compile_state *state, struct triple *ins)
8617 {
8618         struct triple **expr;
8619         expr = triple_misc(state, ins, 0);
8620         for(;expr;expr = triple_misc(state, ins, expr)) {
8621                 if (*expr) {
8622                         internal_error(state, ins, "unexpected misc");
8623                 }
8624         }
8625 }
8626
8627 static void check_targ(struct compile_state *state, struct triple *ins)
8628 {
8629         struct triple **expr;
8630         expr = triple_targ(state, ins, 0);
8631         for(;expr;expr = triple_targ(state, ins, expr)) {
8632                 internal_error(state, ins, "unexpected targ");
8633         }
8634 }
8635
8636 static void wipe_ins(struct compile_state *state, struct triple *ins)
8637 {
8638         /* Becareful which instructions you replace the wiped
8639          * instruction with, as there are not enough slots
8640          * in all instructions to hold all others.
8641          */
8642         check_targ(state, ins);
8643         check_misc(state, ins);
8644         unuse_rhs(state, ins);
8645         unuse_lhs(state, ins);
8646         ins->lhs  = 0;
8647         ins->rhs  = 0;
8648         ins->misc = 0;
8649         ins->targ = 0;
8650 }
8651
8652 static void wipe_branch(struct compile_state *state, struct triple *ins)
8653 {
8654         /* Becareful which instructions you replace the wiped
8655          * instruction with, as there are not enough slots
8656          * in all instructions to hold all others.
8657          */
8658         unuse_rhs(state, ins);
8659         unuse_lhs(state, ins);
8660         unuse_misc(state, ins);
8661         unuse_targ(state, ins);
8662         ins->lhs  = 0;
8663         ins->rhs  = 0;
8664         ins->misc = 0;
8665         ins->targ = 0;
8666 }
8667
8668 static void mkcopy(struct compile_state *state, 
8669         struct triple *ins, struct triple *rhs)
8670 {
8671         struct block *block;
8672         if (!equiv_types(ins->type, rhs->type)) {
8673                 FILE *fp = state->errout;
8674                 fprintf(fp, "src type: ");
8675                 name_of(fp, rhs->type);
8676                 fprintf(fp, "\ndst type: ");
8677                 name_of(fp, ins->type);
8678                 fprintf(fp, "\n");
8679                 internal_error(state, ins, "mkcopy type mismatch");
8680         }
8681         block = block_of_triple(state, ins);
8682         wipe_ins(state, ins);
8683         ins->op = OP_COPY;
8684         ins->rhs  = 1;
8685         ins->u.block = block;
8686         RHS(ins, 0) = rhs;
8687         use_triple(RHS(ins, 0), ins);
8688 }
8689
8690 static void mkconst(struct compile_state *state, 
8691         struct triple *ins, ulong_t value)
8692 {
8693         if (!is_integral(ins) && !is_pointer(ins)) {
8694                 fprintf(state->errout, "type: ");
8695                 name_of(state->errout, ins->type);
8696                 fprintf(state->errout, "\n");
8697                 internal_error(state, ins, "unknown type to make constant value: %ld",
8698                         value);
8699         }
8700         wipe_ins(state, ins);
8701         ins->op = OP_INTCONST;
8702         ins->u.cval = value;
8703 }
8704
8705 static void mkaddr_const(struct compile_state *state,
8706         struct triple *ins, struct triple *sdecl, ulong_t value)
8707 {
8708         if ((sdecl->op != OP_SDECL) && (sdecl->op != OP_LABEL)) {
8709                 internal_error(state, ins, "bad base for addrconst");
8710         }
8711         wipe_ins(state, ins);
8712         ins->op = OP_ADDRCONST;
8713         ins->misc = 1;
8714         MISC(ins, 0) = sdecl;
8715         ins->u.cval = value;
8716         use_triple(sdecl, ins);
8717 }
8718
8719 #if DEBUG_DECOMPOSE_PRINT_TUPLES
8720 static void print_tuple(struct compile_state *state, 
8721         struct triple *ins, struct triple *tuple)
8722 {
8723         FILE *fp = state->dbgout;
8724         fprintf(fp, "%5s %p tuple: %p ", tops(ins->op), ins, tuple);
8725         name_of(fp, tuple->type);
8726         if (tuple->lhs > 0) {
8727                 fprintf(fp, " lhs: ");
8728                 name_of(fp, LHS(tuple, 0)->type);
8729         }
8730         fprintf(fp, "\n");
8731         
8732 }
8733 #endif
8734
8735 static struct triple *decompose_with_tuple(struct compile_state *state, 
8736         struct triple *ins, struct triple *tuple)
8737 {
8738         struct triple *next;
8739         next = ins->next;
8740         flatten(state, next, tuple);
8741 #if DEBUG_DECOMPOSE_PRINT_TUPLES
8742         print_tuple(state, ins, tuple);
8743 #endif
8744
8745         if (!is_compound_type(tuple->type) && (tuple->lhs > 0)) {
8746                 struct triple *tmp;
8747                 if (tuple->lhs != 1) {
8748                         internal_error(state, tuple, "plain type in multiple registers?");
8749                 }
8750                 tmp = LHS(tuple, 0);
8751                 release_triple(state, tuple);
8752                 tuple = tmp;
8753         }
8754
8755         propogate_use(state, ins, tuple);
8756         release_triple(state, ins);
8757         
8758         return next;
8759 }
8760
8761 static struct triple *decompose_unknownval(struct compile_state *state,
8762         struct triple *ins)
8763 {
8764         struct triple *tuple;
8765         ulong_t i;
8766
8767 #if DEBUG_DECOMPOSE_HIRES
8768         FILE *fp = state->dbgout;
8769         fprintf(fp, "unknown type: ");
8770         name_of(fp, ins->type);
8771         fprintf(fp, "\n");
8772 #endif
8773
8774         get_occurance(ins->occurance);
8775         tuple = alloc_triple(state, OP_TUPLE, ins->type, -1, -1, 
8776                 ins->occurance);
8777
8778         for(i = 0; i < tuple->lhs; i++) {
8779                 struct type *piece_type;
8780                 struct triple *unknown;
8781
8782                 piece_type = reg_type(state, ins->type, i * REG_SIZEOF_REG);
8783                 get_occurance(tuple->occurance);
8784                 unknown = alloc_triple(state, OP_UNKNOWNVAL, piece_type, 0, 0,
8785                         tuple->occurance);
8786                 LHS(tuple, i) = unknown;
8787         }
8788         return decompose_with_tuple(state, ins, tuple);
8789 }
8790
8791
8792 static struct triple *decompose_read(struct compile_state *state, 
8793         struct triple *ins)
8794 {
8795         struct triple *tuple, *lval;
8796         ulong_t i;
8797
8798         lval = RHS(ins, 0);
8799
8800         if (lval->op == OP_PIECE) {
8801                 return ins->next;
8802         }
8803         get_occurance(ins->occurance);
8804         tuple = alloc_triple(state, OP_TUPLE, lval->type, -1, -1,
8805                 ins->occurance);
8806
8807         if ((tuple->lhs != lval->lhs) &&
8808                 (!triple_is_def(state, lval) || (tuple->lhs != 1))) 
8809         {
8810                 internal_error(state, ins, "lhs size inconsistency?");
8811         }
8812         for(i = 0; i < tuple->lhs; i++) {
8813                 struct triple *piece, *read, *bitref;
8814                 if ((i != 0) || !triple_is_def(state, lval)) {
8815                         piece = LHS(lval, i);
8816                 } else {
8817                         piece = lval;
8818                 }
8819
8820                 /* See if the piece is really a bitref */
8821                 bitref = 0;
8822                 if (piece->op == OP_BITREF) {
8823                         bitref = piece;
8824                         piece = RHS(bitref, 0);
8825                 }
8826
8827                 get_occurance(tuple->occurance);
8828                 read = alloc_triple(state, OP_READ, piece->type, -1, -1, 
8829                         tuple->occurance);
8830                 RHS(read, 0) = piece;
8831
8832                 if (bitref) {
8833                         struct triple *extract;
8834                         int op;
8835                         if (is_signed(bitref->type->left)) {
8836                                 op = OP_SEXTRACT;
8837                         } else {
8838                                 op = OP_UEXTRACT;
8839                         }
8840                         get_occurance(tuple->occurance);
8841                         extract = alloc_triple(state, op, bitref->type, -1, -1,
8842                                 tuple->occurance);
8843                         RHS(extract, 0) = read;
8844                         extract->u.bitfield.size   = bitref->u.bitfield.size;
8845                         extract->u.bitfield.offset = bitref->u.bitfield.offset;
8846
8847                         read = extract;
8848                 }
8849
8850                 LHS(tuple, i) = read;
8851         }
8852         return decompose_with_tuple(state, ins, tuple);
8853 }
8854
8855 static struct triple *decompose_write(struct compile_state *state, 
8856         struct triple *ins)
8857 {
8858         struct triple *tuple, *lval, *val;
8859         ulong_t i;
8860         
8861         lval = MISC(ins, 0);
8862         val = RHS(ins, 0);
8863         get_occurance(ins->occurance);
8864         tuple = alloc_triple(state, OP_TUPLE, ins->type, -1, -1,
8865                 ins->occurance);
8866
8867         if ((tuple->lhs != lval->lhs) &&
8868                 (!triple_is_def(state, lval) || tuple->lhs != 1)) 
8869         {
8870                 internal_error(state, ins, "lhs size inconsistency?");
8871         }
8872         for(i = 0; i < tuple->lhs; i++) {
8873                 struct triple *piece, *write, *pval, *bitref;
8874                 if ((i != 0) || !triple_is_def(state, lval)) {
8875                         piece = LHS(lval, i);
8876                 } else {
8877                         piece = lval;
8878                 }
8879                 if ((i == 0) && (tuple->lhs == 1) && (val->lhs == 0)) {
8880                         pval = val;
8881                 }
8882                 else {
8883                         if (i > val->lhs) {
8884                                 internal_error(state, ins, "lhs size inconsistency?");
8885                         }
8886                         pval = LHS(val, i);
8887                 }
8888                 
8889                 /* See if the piece is really a bitref */
8890                 bitref = 0;
8891                 if (piece->op == OP_BITREF) {
8892                         struct triple *read, *deposit;
8893                         bitref = piece;
8894                         piece = RHS(bitref, 0);
8895
8896                         /* Read the destination register */
8897                         get_occurance(tuple->occurance);
8898                         read = alloc_triple(state, OP_READ, piece->type, -1, -1,
8899                                 tuple->occurance);
8900                         RHS(read, 0) = piece;
8901
8902                         /* Deposit the new bitfield value */
8903                         get_occurance(tuple->occurance);
8904                         deposit = alloc_triple(state, OP_DEPOSIT, piece->type, -1, -1,
8905                                 tuple->occurance);
8906                         RHS(deposit, 0) = read;
8907                         RHS(deposit, 1) = pval;
8908                         deposit->u.bitfield.size   = bitref->u.bitfield.size;
8909                         deposit->u.bitfield.offset = bitref->u.bitfield.offset;
8910
8911                         /* Now write the newly generated value */
8912                         pval = deposit;
8913                 }
8914
8915                 get_occurance(tuple->occurance);
8916                 write = alloc_triple(state, OP_WRITE, piece->type, -1, -1, 
8917                         tuple->occurance);
8918                 MISC(write, 0) = piece;
8919                 RHS(write, 0) = pval;
8920                 LHS(tuple, i) = write;
8921         }
8922         return decompose_with_tuple(state, ins, tuple);
8923 }
8924
8925 struct decompose_load_info {
8926         struct occurance *occurance;
8927         struct triple *lval;
8928         struct triple *tuple;
8929 };
8930 static void decompose_load_cb(struct compile_state *state,
8931         struct type *type, size_t reg_offset, size_t mem_offset, void *arg)
8932 {
8933         struct decompose_load_info *info = arg;
8934         struct triple *load;
8935         
8936         if (reg_offset > info->tuple->lhs) {
8937                 internal_error(state, info->tuple, "lhs to small?");
8938         }
8939         get_occurance(info->occurance);
8940         load = alloc_triple(state, OP_LOAD, type, -1, -1, info->occurance);
8941         RHS(load, 0) = mk_addr_expr(state, info->lval, mem_offset);
8942         LHS(info->tuple, reg_offset/REG_SIZEOF_REG) = load;
8943 }
8944
8945 static struct triple *decompose_load(struct compile_state *state, 
8946         struct triple *ins)
8947 {
8948         struct triple *tuple;
8949         struct decompose_load_info info;
8950
8951         if (!is_compound_type(ins->type)) {
8952                 return ins->next;
8953         }
8954         get_occurance(ins->occurance);
8955         tuple = alloc_triple(state, OP_TUPLE, ins->type, -1, -1,
8956                 ins->occurance);
8957
8958         info.occurance = ins->occurance;
8959         info.lval      = RHS(ins, 0);
8960         info.tuple     = tuple;
8961         walk_type_fields(state, ins->type, 0, 0, decompose_load_cb, &info);
8962
8963         return decompose_with_tuple(state, ins, tuple);
8964 }
8965
8966
8967 struct decompose_store_info {
8968         struct occurance *occurance;
8969         struct triple *lval;
8970         struct triple *val;
8971         struct triple *tuple;
8972 };
8973 static void decompose_store_cb(struct compile_state *state,
8974         struct type *type, size_t reg_offset, size_t mem_offset, void *arg)
8975 {
8976         struct decompose_store_info *info = arg;
8977         struct triple *store;
8978         
8979         if (reg_offset > info->tuple->lhs) {
8980                 internal_error(state, info->tuple, "lhs to small?");
8981         }
8982         get_occurance(info->occurance);
8983         store = alloc_triple(state, OP_STORE, type, -1, -1, info->occurance);
8984         RHS(store, 0) = mk_addr_expr(state, info->lval, mem_offset);
8985         RHS(store, 1) = LHS(info->val, reg_offset);
8986         LHS(info->tuple, reg_offset/REG_SIZEOF_REG) = store;
8987 }
8988
8989 static struct triple *decompose_store(struct compile_state *state, 
8990         struct triple *ins)
8991 {
8992         struct triple *tuple;
8993         struct decompose_store_info info;
8994
8995         if (!is_compound_type(ins->type)) {
8996                 return ins->next;
8997         }
8998         get_occurance(ins->occurance);
8999         tuple = alloc_triple(state, OP_TUPLE, ins->type, -1, -1,
9000                 ins->occurance);
9001
9002         info.occurance = ins->occurance;
9003         info.lval      = RHS(ins, 0);
9004         info.val       = RHS(ins, 1);
9005         info.tuple     = tuple;
9006         walk_type_fields(state, ins->type, 0, 0, decompose_store_cb, &info);
9007
9008         return decompose_with_tuple(state, ins, tuple);
9009 }
9010
9011 static struct triple *decompose_dot(struct compile_state *state, 
9012         struct triple *ins)
9013 {
9014         struct triple *tuple, *lval;
9015         struct type *type;
9016         size_t reg_offset;
9017         int i, idx;
9018
9019         lval = MISC(ins, 0);
9020         reg_offset = field_reg_offset(state, lval->type, ins->u.field);
9021         idx  = reg_offset/REG_SIZEOF_REG;
9022         type = field_type(state, lval->type, ins->u.field);
9023 #if DEBUG_DECOMPOSE_HIRES
9024         {
9025                 FILE *fp = state->dbgout;
9026                 fprintf(fp, "field type: ");
9027                 name_of(fp, type);
9028                 fprintf(fp, "\n");
9029         }
9030 #endif
9031
9032         get_occurance(ins->occurance);
9033         tuple = alloc_triple(state, OP_TUPLE, type, -1, -1, 
9034                 ins->occurance);
9035
9036         if (((ins->type->type & TYPE_MASK) == TYPE_BITFIELD) &&
9037                 (tuple->lhs != 1))
9038         {
9039                 internal_error(state, ins, "multi register bitfield?");
9040         }
9041
9042         for(i = 0; i < tuple->lhs; i++, idx++) {
9043                 struct triple *piece;
9044                 if (!triple_is_def(state, lval)) {
9045                         if (idx > lval->lhs) {
9046                                 internal_error(state, ins, "inconsistent lhs count");
9047                         }
9048                         piece = LHS(lval, idx);
9049                 } else {
9050                         if (idx != 0) {
9051                                 internal_error(state, ins, "bad reg_offset into def");
9052                         }
9053                         if (i != 0) {
9054                                 internal_error(state, ins, "bad reg count from def");
9055                         }
9056                         piece = lval;
9057                 }
9058
9059                 /* Remember the offset of the bitfield */
9060                 if ((type->type & TYPE_MASK) == TYPE_BITFIELD) {
9061                         get_occurance(ins->occurance);
9062                         piece = build_triple(state, OP_BITREF, type, piece, 0,
9063                                 ins->occurance);
9064                         piece->u.bitfield.size   = size_of(state, type);
9065                         piece->u.bitfield.offset = reg_offset % REG_SIZEOF_REG;
9066                 }
9067                 else if ((reg_offset % REG_SIZEOF_REG) != 0) {
9068                         internal_error(state, ins, 
9069                                 "request for a nonbitfield sub register?");
9070                 }
9071
9072                 LHS(tuple, i) = piece;
9073         }
9074
9075         return decompose_with_tuple(state, ins, tuple);
9076 }
9077
9078 static struct triple *decompose_index(struct compile_state *state, 
9079         struct triple *ins)
9080 {
9081         struct triple *tuple, *lval;
9082         struct type *type;
9083         int i, idx;
9084
9085         lval = MISC(ins, 0);
9086         idx = index_reg_offset(state, lval->type, ins->u.cval)/REG_SIZEOF_REG;
9087         type = index_type(state, lval->type, ins->u.cval);
9088 #if DEBUG_DECOMPOSE_HIRES
9089 {
9090         FILE *fp = state->dbgout;
9091         fprintf(fp, "index type: ");
9092         name_of(fp, type);
9093         fprintf(fp, "\n");
9094 }
9095 #endif
9096
9097         get_occurance(ins->occurance);
9098         tuple = alloc_triple(state, OP_TUPLE, type, -1, -1, 
9099                 ins->occurance);
9100
9101         for(i = 0; i < tuple->lhs; i++, idx++) {
9102                 struct triple *piece;
9103                 if (!triple_is_def(state, lval)) {
9104                         if (idx > lval->lhs) {
9105                                 internal_error(state, ins, "inconsistent lhs count");
9106                         }
9107                         piece = LHS(lval, idx);
9108                 } else {
9109                         if (idx != 0) {
9110                                 internal_error(state, ins, "bad reg_offset into def");
9111                         }
9112                         if (i != 0) {
9113                                 internal_error(state, ins, "bad reg count from def");
9114                         }
9115                         piece = lval;
9116                 }
9117                 LHS(tuple, i) = piece;
9118         }
9119
9120         return decompose_with_tuple(state, ins, tuple);
9121 }
9122
9123 static void decompose_compound_types(struct compile_state *state)
9124 {
9125         struct triple *ins, *next, *first;
9126         FILE *fp;
9127         fp = state->dbgout;
9128         first = state->first;
9129         ins = first;
9130
9131         /* Pass one expand compound values into pseudo registers.
9132          */
9133         next = first;
9134         do {
9135                 ins = next;
9136                 next = ins->next;
9137                 switch(ins->op) {
9138                 case OP_UNKNOWNVAL:
9139                         next = decompose_unknownval(state, ins);
9140                         break;
9141
9142                 case OP_READ:
9143                         next = decompose_read(state, ins);
9144                         break;
9145
9146                 case OP_WRITE:
9147                         next = decompose_write(state, ins);
9148                         break;
9149
9150
9151                 /* Be very careful with the load/store logic. These
9152                  * operations must convert from the in register layout
9153                  * to the in memory layout, which is nontrivial.
9154                  */
9155                 case OP_LOAD:
9156                         next = decompose_load(state, ins);
9157                         break;
9158                 case OP_STORE:
9159                         next = decompose_store(state, ins);
9160                         break;
9161
9162                 case OP_DOT:
9163                         next = decompose_dot(state, ins);
9164                         break;
9165                 case OP_INDEX:
9166                         next = decompose_index(state, ins);
9167                         break;
9168                         
9169                 }
9170 #if DEBUG_DECOMPOSE_HIRES
9171                 fprintf(fp, "decompose next: %p \n", next);
9172                 fflush(fp);
9173                 fprintf(fp, "next->op: %d %s\n",
9174                         next->op, tops(next->op));
9175                 /* High resolution debugging mode */
9176                 print_triples(state);
9177 #endif
9178         } while (next != first);
9179
9180         /* Pass two remove the tuples.
9181          */
9182         ins = first;
9183         do {
9184                 next = ins->next;
9185                 if (ins->op == OP_TUPLE) {
9186                         if (ins->use) {
9187                                 internal_error(state, ins, "tuple used");
9188                         }
9189                         else {
9190                                 release_triple(state, ins);
9191                         }
9192                 } 
9193                 ins = next;
9194         } while(ins != first);
9195         ins = first;
9196         do {
9197                 next = ins->next;
9198                 if (ins->op == OP_BITREF) {
9199                         if (ins->use) {
9200                                 internal_error(state, ins, "bitref used");
9201                         } 
9202                         else {
9203                                 release_triple(state, ins);
9204                         }
9205                 }
9206                 ins = next;
9207         } while(ins != first);
9208
9209         /* Pass three verify the state and set ->id to 0.
9210          */
9211         next = first;
9212         do {
9213                 ins = next;
9214                 next = ins->next;
9215                 ins->id &= ~TRIPLE_FLAG_FLATTENED;
9216                 if (triple_stores_block(state, ins)) {
9217                         ins->u.block = 0;
9218                 }
9219                 if (triple_is_def(state, ins)) {
9220                         if (reg_size_of(state, ins->type) > REG_SIZEOF_REG) {
9221                                 internal_error(state, ins, "multi register value remains?");
9222                         }
9223                 }
9224                 if (ins->op == OP_DOT) {
9225                         internal_error(state, ins, "OP_DOT remains?");
9226                 }
9227                 if (ins->op == OP_INDEX) {
9228                         internal_error(state, ins, "OP_INDEX remains?");
9229                 }
9230                 if (ins->op == OP_BITREF) {
9231                         internal_error(state, ins, "OP_BITREF remains?");
9232                 }
9233                 if (ins->op == OP_TUPLE) {
9234                         internal_error(state, ins, "OP_TUPLE remains?");
9235                 }
9236         } while(next != first);
9237 }
9238
9239 /* For those operations that cannot be simplified */
9240 static void simplify_noop(struct compile_state *state, struct triple *ins)
9241 {
9242         return;
9243 }
9244
9245 static void simplify_smul(struct compile_state *state, struct triple *ins)
9246 {
9247         if (is_const(RHS(ins, 0)) && !is_const(RHS(ins, 1))) {
9248                 struct triple *tmp;
9249                 tmp = RHS(ins, 0);
9250                 RHS(ins, 0) = RHS(ins, 1);
9251                 RHS(ins, 1) = tmp;
9252         }
9253         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
9254                 long_t left, right;
9255                 left  = read_sconst(state, ins, RHS(ins, 0));
9256                 right = read_sconst(state, ins, RHS(ins, 1));
9257                 mkconst(state, ins, left * right);
9258         }
9259         else if (is_zero(RHS(ins, 1))) {
9260                 mkconst(state, ins, 0);
9261         }
9262         else if (is_one(RHS(ins, 1))) {
9263                 mkcopy(state, ins, RHS(ins, 0));
9264         }
9265         else if (is_pow2(RHS(ins, 1))) {
9266                 struct triple *val;
9267                 val = int_const(state, ins->type, tlog2(RHS(ins, 1)));
9268                 ins->op = OP_SL;
9269                 insert_triple(state, state->global_pool, val);
9270                 unuse_triple(RHS(ins, 1), ins);
9271                 use_triple(val, ins);
9272                 RHS(ins, 1) = val;
9273         }
9274 }
9275
9276 static void simplify_umul(struct compile_state *state, struct triple *ins)
9277 {
9278         if (is_const(RHS(ins, 0)) && !is_const(RHS(ins, 1))) {
9279                 struct triple *tmp;
9280                 tmp = RHS(ins, 0);
9281                 RHS(ins, 0) = RHS(ins, 1);
9282                 RHS(ins, 1) = tmp;
9283         }
9284         if (is_simple_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9285                 ulong_t left, right;
9286                 left  = read_const(state, ins, RHS(ins, 0));
9287                 right = read_const(state, ins, RHS(ins, 1));
9288                 mkconst(state, ins, left * right);
9289         }
9290         else if (is_zero(RHS(ins, 1))) {
9291                 mkconst(state, ins, 0);
9292         }
9293         else if (is_one(RHS(ins, 1))) {
9294                 mkcopy(state, ins, RHS(ins, 0));
9295         }
9296         else if (is_pow2(RHS(ins, 1))) {
9297                 struct triple *val;
9298                 val = int_const(state, ins->type, tlog2(RHS(ins, 1)));
9299                 ins->op = OP_SL;
9300                 insert_triple(state, state->global_pool, val);
9301                 unuse_triple(RHS(ins, 1), ins);
9302                 use_triple(val, ins);
9303                 RHS(ins, 1) = val;
9304         }
9305 }
9306
9307 static void simplify_sdiv(struct compile_state *state, struct triple *ins)
9308 {
9309         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
9310                 long_t left, right;
9311                 left  = read_sconst(state, ins, RHS(ins, 0));
9312                 right = read_sconst(state, ins, RHS(ins, 1));
9313                 mkconst(state, ins, left / right);
9314         }
9315         else if (is_zero(RHS(ins, 0))) {
9316                 mkconst(state, ins, 0);
9317         }
9318         else if (is_zero(RHS(ins, 1))) {
9319                 error(state, ins, "division by zero");
9320         }
9321         else if (is_one(RHS(ins, 1))) {
9322                 mkcopy(state, ins, RHS(ins, 0));
9323         }
9324         else if (is_pow2(RHS(ins, 1))) {
9325                 struct triple *val;
9326                 val = int_const(state, ins->type, tlog2(RHS(ins, 1)));
9327                 ins->op = OP_SSR;
9328                 insert_triple(state, state->global_pool, val);
9329                 unuse_triple(RHS(ins, 1), ins);
9330                 use_triple(val, ins);
9331                 RHS(ins, 1) = val;
9332         }
9333 }
9334
9335 static void simplify_udiv(struct compile_state *state, struct triple *ins)
9336 {
9337         if (is_simple_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9338                 ulong_t left, right;
9339                 left  = read_const(state, ins, RHS(ins, 0));
9340                 right = read_const(state, ins, RHS(ins, 1));
9341                 mkconst(state, ins, left / right);
9342         }
9343         else if (is_zero(RHS(ins, 0))) {
9344                 mkconst(state, ins, 0);
9345         }
9346         else if (is_zero(RHS(ins, 1))) {
9347                 error(state, ins, "division by zero");
9348         }
9349         else if (is_one(RHS(ins, 1))) {
9350                 mkcopy(state, ins, RHS(ins, 0));
9351         }
9352         else if (is_pow2(RHS(ins, 1))) {
9353                 struct triple *val;
9354                 val = int_const(state, ins->type, tlog2(RHS(ins, 1)));
9355                 ins->op = OP_USR;
9356                 insert_triple(state, state->global_pool, val);
9357                 unuse_triple(RHS(ins, 1), ins);
9358                 use_triple(val, ins);
9359                 RHS(ins, 1) = val;
9360         }
9361 }
9362
9363 static void simplify_smod(struct compile_state *state, struct triple *ins)
9364 {
9365         if (is_simple_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9366                 long_t left, right;
9367                 left  = read_const(state, ins, RHS(ins, 0));
9368                 right = read_const(state, ins, RHS(ins, 1));
9369                 mkconst(state, ins, left % right);
9370         }
9371         else if (is_zero(RHS(ins, 0))) {
9372                 mkconst(state, ins, 0);
9373         }
9374         else if (is_zero(RHS(ins, 1))) {
9375                 error(state, ins, "division by zero");
9376         }
9377         else if (is_one(RHS(ins, 1))) {
9378                 mkconst(state, ins, 0);
9379         }
9380         else if (is_pow2(RHS(ins, 1))) {
9381                 struct triple *val;
9382                 val = int_const(state, ins->type, RHS(ins, 1)->u.cval - 1);
9383                 ins->op = OP_AND;
9384                 insert_triple(state, state->global_pool, val);
9385                 unuse_triple(RHS(ins, 1), ins);
9386                 use_triple(val, ins);
9387                 RHS(ins, 1) = val;
9388         }
9389 }
9390
9391 static void simplify_umod(struct compile_state *state, struct triple *ins)
9392 {
9393         if (is_simple_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9394                 ulong_t left, right;
9395                 left  = read_const(state, ins, RHS(ins, 0));
9396                 right = read_const(state, ins, RHS(ins, 1));
9397                 mkconst(state, ins, left % right);
9398         }
9399         else if (is_zero(RHS(ins, 0))) {
9400                 mkconst(state, ins, 0);
9401         }
9402         else if (is_zero(RHS(ins, 1))) {
9403                 error(state, ins, "division by zero");
9404         }
9405         else if (is_one(RHS(ins, 1))) {
9406                 mkconst(state, ins, 0);
9407         }
9408         else if (is_pow2(RHS(ins, 1))) {
9409                 struct triple *val;
9410                 val = int_const(state, ins->type, RHS(ins, 1)->u.cval - 1);
9411                 ins->op = OP_AND;
9412                 insert_triple(state, state->global_pool, val);
9413                 unuse_triple(RHS(ins, 1), ins);
9414                 use_triple(val, ins);
9415                 RHS(ins, 1) = val;
9416         }
9417 }
9418
9419 static void simplify_add(struct compile_state *state, struct triple *ins)
9420 {
9421         /* start with the pointer on the left */
9422         if (is_pointer(RHS(ins, 1))) {
9423                 struct triple *tmp;
9424                 tmp = RHS(ins, 0);
9425                 RHS(ins, 0) = RHS(ins, 1);
9426                 RHS(ins, 1) = tmp;
9427         }
9428         if (is_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9429                 if (RHS(ins, 0)->op == OP_INTCONST) {
9430                         ulong_t left, right;
9431                         left  = read_const(state, ins, RHS(ins, 0));
9432                         right = read_const(state, ins, RHS(ins, 1));
9433                         mkconst(state, ins, left + right);
9434                 }
9435                 else if (RHS(ins, 0)->op == OP_ADDRCONST) {
9436                         struct triple *sdecl;
9437                         ulong_t left, right;
9438                         sdecl = MISC(RHS(ins, 0), 0);
9439                         left  = RHS(ins, 0)->u.cval;
9440                         right = RHS(ins, 1)->u.cval;
9441                         mkaddr_const(state, ins, sdecl, left + right);
9442                 }
9443                 else {
9444                         internal_warning(state, ins, "Optimize me!");
9445                 }
9446         }
9447         else if (is_const(RHS(ins, 0)) && !is_const(RHS(ins, 1))) {
9448                 struct triple *tmp;
9449                 tmp = RHS(ins, 1);
9450                 RHS(ins, 1) = RHS(ins, 0);
9451                 RHS(ins, 0) = tmp;
9452         }
9453 }
9454
9455 static void simplify_sub(struct compile_state *state, struct triple *ins)
9456 {
9457         if (is_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9458                 if (RHS(ins, 0)->op == OP_INTCONST) {
9459                         ulong_t left, right;
9460                         left  = read_const(state, ins, RHS(ins, 0));
9461                         right = read_const(state, ins, RHS(ins, 1));
9462                         mkconst(state, ins, left - right);
9463                 }
9464                 else if (RHS(ins, 0)->op == OP_ADDRCONST) {
9465                         struct triple *sdecl;
9466                         ulong_t left, right;
9467                         sdecl = MISC(RHS(ins, 0), 0);
9468                         left  = RHS(ins, 0)->u.cval;
9469                         right = RHS(ins, 1)->u.cval;
9470                         mkaddr_const(state, ins, sdecl, left - right);
9471                 }
9472                 else {
9473                         internal_warning(state, ins, "Optimize me!");
9474                 }
9475         }
9476 }
9477
9478 static void simplify_sl(struct compile_state *state, struct triple *ins)
9479 {
9480         if (is_simple_const(RHS(ins, 1))) {
9481                 ulong_t right;
9482                 right = read_const(state, ins, RHS(ins, 1));
9483                 if (right >= (size_of(state, ins->type))) {
9484                         warning(state, ins, "left shift count >= width of type");
9485                 }
9486         }
9487         if (is_simple_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9488                 ulong_t left, right;
9489                 left  = read_const(state, ins, RHS(ins, 0));
9490                 right = read_const(state, ins, RHS(ins, 1));
9491                 mkconst(state, ins,  left << right);
9492         }
9493 }
9494
9495 static void simplify_usr(struct compile_state *state, struct triple *ins)
9496 {
9497         if (is_simple_const(RHS(ins, 1))) {
9498                 ulong_t right;
9499                 right = read_const(state, ins, RHS(ins, 1));
9500                 if (right >= (size_of(state, ins->type))) {
9501                         warning(state, ins, "right shift count >= width of type");
9502                 }
9503         }
9504         if (is_simple_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9505                 ulong_t left, right;
9506                 left  = read_const(state, ins, RHS(ins, 0));
9507                 right = read_const(state, ins, RHS(ins, 1));
9508                 mkconst(state, ins, left >> right);
9509         }
9510 }
9511
9512 static void simplify_ssr(struct compile_state *state, struct triple *ins)
9513 {
9514         if (is_simple_const(RHS(ins, 1))) {
9515                 ulong_t right;
9516                 right = read_const(state, ins, RHS(ins, 1));
9517                 if (right >= (size_of(state, ins->type))) {
9518                         warning(state, ins, "right shift count >= width of type");
9519                 }
9520         }
9521         if (is_simple_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9522                 long_t left, right;
9523                 left  = read_sconst(state, ins, RHS(ins, 0));
9524                 right = read_sconst(state, ins, RHS(ins, 1));
9525                 mkconst(state, ins, left >> right);
9526         }
9527 }
9528
9529 static void simplify_and(struct compile_state *state, struct triple *ins)
9530 {
9531         struct triple *left, *right;
9532         left = RHS(ins, 0);
9533         right = RHS(ins, 1);
9534
9535         if (is_simple_const(left) && is_simple_const(right)) {
9536                 ulong_t lval, rval;
9537                 lval = read_const(state, ins, left);
9538                 rval = read_const(state, ins, right);
9539                 mkconst(state, ins, lval & rval);
9540         }
9541         else if (is_zero(right) || is_zero(left)) {
9542                 mkconst(state, ins, 0);
9543         }
9544 }
9545
9546 static void simplify_or(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_simple_const(left) && is_simple_const(right)) {
9553                 ulong_t lval, rval;
9554                 lval = read_const(state, ins, left);
9555                 rval = read_const(state, ins, right);
9556                 mkconst(state, ins, lval | rval);
9557         }
9558 #if 0 /* I need to handle type mismatches here... */
9559         else if (is_zero(right)) {
9560                 mkcopy(state, ins, left);
9561         }
9562         else if (is_zero(left)) {
9563                 mkcopy(state, ins, right);
9564         }
9565 #endif
9566 }
9567
9568 static void simplify_xor(struct compile_state *state, struct triple *ins)
9569 {
9570         if (is_simple_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9571                 ulong_t left, right;
9572                 left  = read_const(state, ins, RHS(ins, 0));
9573                 right = read_const(state, ins, RHS(ins, 1));
9574                 mkconst(state, ins, left ^ right);
9575         }
9576 }
9577
9578 static void simplify_pos(struct compile_state *state, struct triple *ins)
9579 {
9580         if (is_const(RHS(ins, 0))) {
9581                 mkconst(state, ins, RHS(ins, 0)->u.cval);
9582         }
9583         else {
9584                 mkcopy(state, ins, RHS(ins, 0));
9585         }
9586 }
9587
9588 static void simplify_neg(struct compile_state *state, struct triple *ins)
9589 {
9590         if (is_simple_const(RHS(ins, 0))) {
9591                 ulong_t left;
9592                 left = read_const(state, ins, RHS(ins, 0));
9593                 mkconst(state, ins, -left);
9594         }
9595         else if (RHS(ins, 0)->op == OP_NEG) {
9596                 mkcopy(state, ins, RHS(RHS(ins, 0), 0));
9597         }
9598 }
9599
9600 static void simplify_invert(struct compile_state *state, struct triple *ins)
9601 {
9602         if (is_simple_const(RHS(ins, 0))) {
9603                 ulong_t left;
9604                 left = read_const(state, ins, RHS(ins, 0));
9605                 mkconst(state, ins, ~left);
9606         }
9607 }
9608
9609 static void simplify_eq(struct compile_state *state, struct triple *ins)
9610 {
9611         struct triple *left, *right;
9612         left = RHS(ins, 0);
9613         right = RHS(ins, 1);
9614
9615         if (is_const(left) && is_const(right)) {
9616                 int val;
9617                 val = const_eq(state, ins, left, right);
9618                 if (val >= 0) {
9619                         mkconst(state, ins, val == 1);
9620                 }
9621         }
9622         else if (left == right) {
9623                 mkconst(state, ins, 1);
9624         }
9625 }
9626
9627 static void simplify_noteq(struct compile_state *state, struct triple *ins)
9628 {
9629         struct triple *left, *right;
9630         left = RHS(ins, 0);
9631         right = RHS(ins, 1);
9632
9633         if (is_const(left) && is_const(right)) {
9634                 int val;
9635                 val = const_eq(state, ins, left, right);
9636                 if (val >= 0) {
9637                         mkconst(state, ins, val != 1);
9638                 }
9639         }
9640         if (left == right) {
9641                 mkconst(state, ins, 0);
9642         }
9643 }
9644
9645 static void simplify_sless(struct compile_state *state, struct triple *ins)
9646 {
9647         struct triple *left, *right;
9648         left = RHS(ins, 0);
9649         right = RHS(ins, 1);
9650
9651         if (is_const(left) && is_const(right)) {
9652                 int val;
9653                 val = const_scmp(state, ins, left, right);
9654                 if ((val >= -1) && (val <= 1)) {
9655                         mkconst(state, ins, val < 0);
9656                 }
9657         }
9658         else if (left == right) {
9659                 mkconst(state, ins, 0);
9660         }
9661 }
9662
9663 static void simplify_uless(struct compile_state *state, struct triple *ins)
9664 {
9665         struct triple *left, *right;
9666         left = RHS(ins, 0);
9667         right = RHS(ins, 1);
9668
9669         if (is_const(left) && is_const(right)) {
9670                 int val;
9671                 val = const_ucmp(state, ins, left, right);
9672                 if ((val >= -1) && (val <= 1)) {
9673                         mkconst(state, ins, val < 0);
9674                 }
9675         }
9676         else if (is_zero(right)) {
9677                 mkconst(state, ins, 0);
9678         }
9679         else if (left == right) {
9680                 mkconst(state, ins, 0);
9681         }
9682 }
9683
9684 static void simplify_smore(struct compile_state *state, struct triple *ins)
9685 {
9686         struct triple *left, *right;
9687         left = RHS(ins, 0);
9688         right = RHS(ins, 1);
9689
9690         if (is_const(left) && is_const(right)) {
9691                 int val;
9692                 val = const_scmp(state, ins, left, right);
9693                 if ((val >= -1) && (val <= 1)) {
9694                         mkconst(state, ins, val > 0);
9695                 }
9696         }
9697         else if (left == right) {
9698                 mkconst(state, ins, 0);
9699         }
9700 }
9701
9702 static void simplify_umore(struct compile_state *state, struct triple *ins)
9703 {
9704         struct triple *left, *right;
9705         left = RHS(ins, 0);
9706         right = RHS(ins, 1);
9707
9708         if (is_const(left) && is_const(right)) {
9709                 int val;
9710                 val = const_ucmp(state, ins, left, right);
9711                 if ((val >= -1) && (val <= 1)) {
9712                         mkconst(state, ins, val > 0);
9713                 }
9714         }
9715         else if (is_zero(left)) {
9716                 mkconst(state, ins, 0);
9717         }
9718         else if (left == right) {
9719                 mkconst(state, ins, 0);
9720         }
9721 }
9722
9723
9724 static void simplify_slesseq(struct compile_state *state, struct triple *ins)
9725 {
9726         struct triple *left, *right;
9727         left = RHS(ins, 0);
9728         right = RHS(ins, 1);
9729
9730         if (is_const(left) && is_const(right)) {
9731                 int val;
9732                 val = const_scmp(state, ins, left, right);
9733                 if ((val >= -1) && (val <= 1)) {
9734                         mkconst(state, ins, val <= 0);
9735                 }
9736         }
9737         else if (left == right) {
9738                 mkconst(state, ins, 1);
9739         }
9740 }
9741
9742 static void simplify_ulesseq(struct compile_state *state, struct triple *ins)
9743 {
9744         struct triple *left, *right;
9745         left = RHS(ins, 0);
9746         right = RHS(ins, 1);
9747
9748         if (is_const(left) && is_const(right)) {
9749                 int val;
9750                 val = const_ucmp(state, ins, left, right);
9751                 if ((val >= -1) && (val <= 1)) {
9752                         mkconst(state, ins, val <= 0);
9753                 }
9754         }
9755         else if (is_zero(left)) {
9756                 mkconst(state, ins, 1);
9757         }
9758         else if (left == right) {
9759                 mkconst(state, ins, 1);
9760         }
9761 }
9762
9763 static void simplify_smoreeq(struct compile_state *state, struct triple *ins)
9764 {
9765         struct triple *left, *right;
9766         left = RHS(ins, 0);
9767         right = RHS(ins, 1);
9768
9769         if (is_const(left) && is_const(right)) {
9770                 int val;
9771                 val = const_scmp(state, ins, left, right);
9772                 if ((val >= -1) && (val <= 1)) {
9773                         mkconst(state, ins, val >= 0);
9774                 }
9775         }
9776         else if (left == right) {
9777                 mkconst(state, ins, 1);
9778         }
9779 }
9780
9781 static void simplify_umoreeq(struct compile_state *state, struct triple *ins)
9782 {
9783         struct triple *left, *right;
9784         left = RHS(ins, 0);
9785         right = RHS(ins, 1);
9786
9787         if (is_const(left) && is_const(right)) {
9788                 int val;
9789                 val = const_ucmp(state, ins, left, right);
9790                 if ((val >= -1) && (val <= 1)) {
9791                         mkconst(state, ins, val >= 0);
9792                 }
9793         }
9794         else if (is_zero(right)) {
9795                 mkconst(state, ins, 1);
9796         }
9797         else if (left == right) {
9798                 mkconst(state, ins, 1);
9799         }
9800 }
9801
9802 static void simplify_lfalse(struct compile_state *state, struct triple *ins)
9803 {
9804         struct triple *rhs;
9805         rhs = RHS(ins, 0);
9806
9807         if (is_const(rhs)) {
9808                 mkconst(state, ins, !const_ltrue(state, ins, rhs));
9809         }
9810         /* Otherwise if I am the only user... */
9811         else if ((rhs->use) &&
9812                 (rhs->use->member == ins) && (rhs->use->next == 0)) {
9813                 int need_copy = 1;
9814                 /* Invert a boolean operation */
9815                 switch(rhs->op) {
9816                 case OP_LTRUE:   rhs->op = OP_LFALSE;  break;
9817                 case OP_LFALSE:  rhs->op = OP_LTRUE;   break;
9818                 case OP_EQ:      rhs->op = OP_NOTEQ;   break;
9819                 case OP_NOTEQ:   rhs->op = OP_EQ;      break;
9820                 case OP_SLESS:   rhs->op = OP_SMOREEQ; break;
9821                 case OP_ULESS:   rhs->op = OP_UMOREEQ; break;
9822                 case OP_SMORE:   rhs->op = OP_SLESSEQ; break;
9823                 case OP_UMORE:   rhs->op = OP_ULESSEQ; break;
9824                 case OP_SLESSEQ: rhs->op = OP_SMORE;   break;
9825                 case OP_ULESSEQ: rhs->op = OP_UMORE;   break;
9826                 case OP_SMOREEQ: rhs->op = OP_SLESS;   break;
9827                 case OP_UMOREEQ: rhs->op = OP_ULESS;   break;
9828                 default:
9829                         need_copy = 0;
9830                         break;
9831                 }
9832                 if (need_copy) {
9833                         mkcopy(state, ins, rhs);
9834                 }
9835         }
9836 }
9837
9838 static void simplify_ltrue (struct compile_state *state, struct triple *ins)
9839 {
9840         struct triple *rhs;
9841         rhs = RHS(ins, 0);
9842
9843         if (is_const(rhs)) {
9844                 mkconst(state, ins, const_ltrue(state, ins, rhs));
9845         }
9846         else switch(rhs->op) {
9847         case OP_LTRUE:   case OP_LFALSE:  case OP_EQ:      case OP_NOTEQ:
9848         case OP_SLESS:   case OP_ULESS:   case OP_SMORE:   case OP_UMORE:
9849         case OP_SLESSEQ: case OP_ULESSEQ: case OP_SMOREEQ: case OP_UMOREEQ:
9850                 mkcopy(state, ins, rhs);
9851         }
9852
9853 }
9854
9855 static void simplify_load(struct compile_state *state, struct triple *ins)
9856 {
9857         struct triple *addr, *sdecl, *blob;
9858
9859         /* If I am doing a load with a constant pointer from a constant
9860          * table get the value.
9861          */
9862         addr = RHS(ins, 0);
9863         if ((addr->op == OP_ADDRCONST) && (sdecl = MISC(addr, 0)) &&
9864                 (sdecl->op == OP_SDECL) && (blob = MISC(sdecl, 0)) &&
9865                 (blob->op == OP_BLOBCONST)) {
9866                 unsigned char buffer[SIZEOF_WORD];
9867                 size_t reg_size, mem_size;
9868                 const char *src, *end;
9869                 ulong_t val;
9870                 reg_size = reg_size_of(state, ins->type);
9871                 if (reg_size > REG_SIZEOF_REG) {
9872                         internal_error(state, ins, "load size greater than register");
9873                 }
9874                 mem_size = size_of(state, ins->type);
9875                 end = blob->u.blob;
9876                 end += bits_to_bytes(size_of(state, sdecl->type));
9877                 src = blob->u.blob;
9878                 src += addr->u.cval;
9879
9880                 if (src > end) {
9881                         error(state, ins, "Load address out of bounds");
9882                 }
9883
9884                 memset(buffer, 0, sizeof(buffer));
9885                 memcpy(buffer, src, bits_to_bytes(mem_size));
9886
9887                 switch(mem_size) {
9888                 case SIZEOF_I8:  val = *((uint8_t *) buffer); break;
9889                 case SIZEOF_I16: val = *((uint16_t *)buffer); break;
9890                 case SIZEOF_I32: val = *((uint32_t *)buffer); break;
9891                 case SIZEOF_I64: val = *((uint64_t *)buffer); break;
9892                 default:
9893                         internal_error(state, ins, "mem_size: %d not handled",
9894                                 mem_size);
9895                         val = 0;
9896                         break;
9897                 }
9898                 mkconst(state, ins, val);
9899         }
9900 }
9901
9902 static void simplify_uextract(struct compile_state *state, struct triple *ins)
9903 {
9904         if (is_simple_const(RHS(ins, 0))) {
9905                 ulong_t val;
9906                 ulong_t mask;
9907                 val = read_const(state, ins, RHS(ins, 0));
9908                 mask = 1;
9909                 mask <<= ins->u.bitfield.size;
9910                 mask -= 1;
9911                 val >>= ins->u.bitfield.offset;
9912                 val &= mask;
9913                 mkconst(state, ins, val);
9914         }
9915 }
9916
9917 static void simplify_sextract(struct compile_state *state, struct triple *ins)
9918 {
9919         if (is_simple_const(RHS(ins, 0))) {
9920                 ulong_t val;
9921                 ulong_t mask;
9922                 long_t sval;
9923                 val = read_const(state, ins, RHS(ins, 0));
9924                 mask = 1;
9925                 mask <<= ins->u.bitfield.size;
9926                 mask -= 1;
9927                 val >>= ins->u.bitfield.offset;
9928                 val &= mask;
9929                 val <<= (SIZEOF_LONG - ins->u.bitfield.size);
9930                 sval = val;
9931                 sval >>= (SIZEOF_LONG - ins->u.bitfield.size); 
9932                 mkconst(state, ins, sval);
9933         }
9934 }
9935
9936 static void simplify_deposit(struct compile_state *state, struct triple *ins)
9937 {
9938         if (is_simple_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9939                 ulong_t targ, val;
9940                 ulong_t mask;
9941                 targ = read_const(state, ins, RHS(ins, 0));
9942                 val  = read_const(state, ins, RHS(ins, 1));
9943                 mask = 1;
9944                 mask <<= ins->u.bitfield.size;
9945                 mask -= 1;
9946                 mask <<= ins->u.bitfield.offset;
9947                 targ &= ~mask;
9948                 val <<= ins->u.bitfield.offset;
9949                 val &= mask;
9950                 targ |= val;
9951                 mkconst(state, ins, targ);
9952         }
9953 }
9954
9955 static void simplify_copy(struct compile_state *state, struct triple *ins)
9956 {
9957         struct triple *right;
9958         right = RHS(ins, 0);
9959         if (is_subset_type(ins->type, right->type)) {
9960                 ins->type = right->type;
9961         }
9962         if (equiv_types(ins->type, right->type)) {
9963                 ins->op = OP_COPY;/* I don't need to convert if the types match */
9964         } else {
9965                 if (ins->op == OP_COPY) {
9966                         internal_error(state, ins, "type mismatch on copy");
9967                 }
9968         }
9969         if (is_const(right) && (right->op == OP_ADDRCONST) && is_pointer(ins)) {
9970                 struct triple *sdecl;
9971                 ulong_t offset;
9972                 sdecl  = MISC(right, 0);
9973                 offset = right->u.cval;
9974                 mkaddr_const(state, ins, sdecl, offset);
9975         }
9976         else if (is_const(right) && is_write_compatible(state, ins->type, right->type)) {
9977                 switch(right->op) {
9978                 case OP_INTCONST:
9979                 {
9980                         ulong_t left;
9981                         left = read_const(state, ins, right);
9982                         /* Ensure I have not overflowed the destination. */
9983                         if (size_of(state, right->type) > size_of(state, ins->type)) {
9984                                 ulong_t mask;
9985                                 mask = 1;
9986                                 mask <<= size_of(state, ins->type);
9987                                 mask -= 1;
9988                                 left &= mask;
9989                         }
9990                         /* Ensure I am properly sign extended */
9991                         if (size_of(state, right->type) < size_of(state, ins->type) &&
9992                                 is_signed(right->type)) {
9993                                 long_t val;
9994                                 int shift;
9995                                 shift = SIZEOF_LONG - size_of(state, right->type);
9996                                 val = left;
9997                                 val <<= shift;
9998                                 val >>= shift;
9999                                 left = val;
10000                         }
10001                         mkconst(state, ins, left);
10002                         break;
10003                 }
10004                 default:
10005                         internal_error(state, ins, "uknown constant");
10006                         break;
10007                 }
10008         }
10009 }
10010
10011 static int phi_present(struct block *block)
10012 {
10013         struct triple *ptr;
10014         if (!block) {
10015                 return 0;
10016         }
10017         ptr = block->first;
10018         do {
10019                 if (ptr->op == OP_PHI) {
10020                         return 1;
10021                 }
10022                 ptr = ptr->next;
10023         } while(ptr != block->last);
10024         return 0;
10025 }
10026
10027 static int phi_dependency(struct block *block)
10028 {
10029         /* A block has a phi dependency if a phi function
10030          * depends on that block to exist, and makes a block
10031          * that is otherwise useless unsafe to remove.
10032          */
10033         if (block) {
10034                 struct block_set *edge;
10035                 for(edge = block->edges; edge; edge = edge->next) {
10036                         if (phi_present(edge->member)) {
10037                                 return 1;
10038                         }
10039                 }
10040         }
10041         return 0;
10042 }
10043
10044 static struct triple *branch_target(struct compile_state *state, struct triple *ins)
10045 {
10046         struct triple *targ;
10047         targ = TARG(ins, 0);
10048         /* During scc_transform temporary triples are allocated that
10049          * loop back onto themselves. If I see one don't advance the
10050          * target.
10051          */
10052         while(triple_is_structural(state, targ) && 
10053                 (targ->next != targ) && (targ->next != state->first)) {
10054                 targ = targ->next;
10055         }
10056         return targ;
10057 }
10058
10059
10060 static void simplify_branch(struct compile_state *state, struct triple *ins)
10061 {
10062         int simplified, loops;
10063         if ((ins->op != OP_BRANCH) && (ins->op != OP_CBRANCH)) {
10064                 internal_error(state, ins, "not branch");
10065         }
10066         if (ins->use != 0) {
10067                 internal_error(state, ins, "branch use");
10068         }
10069         /* The challenge here with simplify branch is that I need to 
10070          * make modifications to the control flow graph as well
10071          * as to the branch instruction itself.  That is handled
10072          * by rebuilding the basic blocks after simplify all is called.
10073          */
10074
10075         /* If we have a branch to an unconditional branch update
10076          * our target.  But watch out for dependencies from phi
10077          * functions.
10078          * Also only do this a limited number of times so
10079          * we don't get into an infinite loop.
10080          */
10081         loops = 0;
10082         do {
10083                 struct triple *targ;
10084                 simplified = 0;
10085                 targ = branch_target(state, ins);
10086                 if ((targ != ins) && (targ->op == OP_BRANCH) && 
10087                         !phi_dependency(targ->u.block))
10088                 {
10089                         unuse_triple(TARG(ins, 0), ins);
10090                         TARG(ins, 0) = TARG(targ, 0);
10091                         use_triple(TARG(ins, 0), ins);
10092                         simplified = 1;
10093                 }
10094         } while(simplified && (++loops < 20));
10095
10096         /* If we have a conditional branch with a constant condition
10097          * make it an unconditional branch.
10098          */
10099         if ((ins->op == OP_CBRANCH) && is_simple_const(RHS(ins, 0))) {
10100                 struct triple *targ;
10101                 ulong_t value;
10102                 value = read_const(state, ins, RHS(ins, 0));
10103                 unuse_triple(RHS(ins, 0), ins);
10104                 targ = TARG(ins, 0);
10105                 ins->rhs  = 0;
10106                 ins->targ = 1;
10107                 ins->op = OP_BRANCH;
10108                 if (value) {
10109                         unuse_triple(ins->next, ins);
10110                         TARG(ins, 0) = targ;
10111                 }
10112                 else {
10113                         unuse_triple(targ, ins);
10114                         TARG(ins, 0) = ins->next;
10115                 }
10116         }
10117
10118         /* If we have a branch to the next instruction,
10119          * make it a noop.
10120          */
10121         if (TARG(ins, 0) == ins->next) {
10122                 unuse_triple(TARG(ins, 0), ins);
10123                 if (ins->op == OP_CBRANCH) {
10124                         unuse_triple(RHS(ins, 0), ins);
10125                         unuse_triple(ins->next, ins);
10126                 }
10127                 ins->lhs = 0;
10128                 ins->rhs = 0;
10129                 ins->misc = 0;
10130                 ins->targ = 0;
10131                 ins->op = OP_NOOP;
10132                 if (ins->use) {
10133                         internal_error(state, ins, "noop use != 0");
10134                 }
10135         }
10136 }
10137
10138 static void simplify_label(struct compile_state *state, struct triple *ins)
10139 {
10140         /* Ignore volatile labels */
10141         if (!triple_is_pure(state, ins, ins->id)) {
10142                 return;
10143         }
10144         if (ins->use == 0) {
10145                 ins->op = OP_NOOP;
10146         }
10147         else if (ins->prev->op == OP_LABEL) {
10148                 /* In general it is not safe to merge one label that
10149                  * imediately follows another.  The problem is that the empty
10150                  * looking block may have phi functions that depend on it.
10151                  */
10152                 if (!phi_dependency(ins->prev->u.block)) {
10153                         struct triple_set *user, *next;
10154                         ins->op = OP_NOOP;
10155                         for(user = ins->use; user; user = next) {
10156                                 struct triple *use, **expr;
10157                                 next = user->next;
10158                                 use = user->member;
10159                                 expr = triple_targ(state, use, 0);
10160                                 for(;expr; expr = triple_targ(state, use, expr)) {
10161                                         if (*expr == ins) {
10162                                                 *expr = ins->prev;
10163                                                 unuse_triple(ins, use);
10164                                                 use_triple(ins->prev, use);
10165                                         }
10166                                         
10167                                 }
10168                         }
10169                         if (ins->use) {
10170                                 internal_error(state, ins, "noop use != 0");
10171                         }
10172                 }
10173         }
10174 }
10175
10176 static void simplify_phi(struct compile_state *state, struct triple *ins)
10177 {
10178         struct triple **slot;
10179         struct triple *value;
10180         int zrhs, i;
10181         ulong_t cvalue;
10182         slot = &RHS(ins, 0);
10183         zrhs = ins->rhs;
10184         if (zrhs == 0) {
10185                 return;
10186         }
10187         /* See if all of the rhs members of a phi have the same value */
10188         if (slot[0] && is_simple_const(slot[0])) {
10189                 cvalue = read_const(state, ins, slot[0]);
10190                 for(i = 1; i < zrhs; i++) {
10191                         if (    !slot[i] ||
10192                                 !is_simple_const(slot[i]) ||
10193                                 !equiv_types(slot[0]->type, slot[i]->type) ||
10194                                 (cvalue != read_const(state, ins, slot[i]))) {
10195                                 break;
10196                         }
10197                 }
10198                 if (i == zrhs) {
10199                         mkconst(state, ins, cvalue);
10200                         return;
10201                 }
10202         }
10203         
10204         /* See if all of rhs members of a phi are the same */
10205         value = slot[0];
10206         for(i = 1; i < zrhs; i++) {
10207                 if (slot[i] != value) {
10208                         break;
10209                 }
10210         }
10211         if (i == zrhs) {
10212                 /* If the phi has a single value just copy it */
10213                 if (!is_subset_type(ins->type, value->type)) {
10214                         internal_error(state, ins, "bad input type to phi");
10215                 }
10216                 /* Make the types match */
10217                 if (!equiv_types(ins->type, value->type)) {
10218                         ins->type = value->type;
10219                 }
10220                 /* Now make the actual copy */
10221                 mkcopy(state, ins, value);
10222                 return;
10223         }
10224 }
10225
10226
10227 static void simplify_bsf(struct compile_state *state, struct triple *ins)
10228 {
10229         if (is_simple_const(RHS(ins, 0))) {
10230                 ulong_t left;
10231                 left = read_const(state, ins, RHS(ins, 0));
10232                 mkconst(state, ins, bsf(left));
10233         }
10234 }
10235
10236 static void simplify_bsr(struct compile_state *state, struct triple *ins)
10237 {
10238         if (is_simple_const(RHS(ins, 0))) {
10239                 ulong_t left;
10240                 left = read_const(state, ins, RHS(ins, 0));
10241                 mkconst(state, ins, bsr(left));
10242         }
10243 }
10244
10245
10246 typedef void (*simplify_t)(struct compile_state *state, struct triple *ins);
10247 static const struct simplify_table {
10248         simplify_t func;
10249         unsigned long flag;
10250 } table_simplify[] = {
10251 #define simplify_sdivt    simplify_noop
10252 #define simplify_udivt    simplify_noop
10253 #define simplify_piece    simplify_noop
10254
10255 [OP_SDIVT      ] = { simplify_sdivt,    COMPILER_SIMPLIFY_ARITH },
10256 [OP_UDIVT      ] = { simplify_udivt,    COMPILER_SIMPLIFY_ARITH },
10257 [OP_SMUL       ] = { simplify_smul,     COMPILER_SIMPLIFY_ARITH },
10258 [OP_UMUL       ] = { simplify_umul,     COMPILER_SIMPLIFY_ARITH },
10259 [OP_SDIV       ] = { simplify_sdiv,     COMPILER_SIMPLIFY_ARITH },
10260 [OP_UDIV       ] = { simplify_udiv,     COMPILER_SIMPLIFY_ARITH },
10261 [OP_SMOD       ] = { simplify_smod,     COMPILER_SIMPLIFY_ARITH },
10262 [OP_UMOD       ] = { simplify_umod,     COMPILER_SIMPLIFY_ARITH },
10263 [OP_ADD        ] = { simplify_add,      COMPILER_SIMPLIFY_ARITH },
10264 [OP_SUB        ] = { simplify_sub,      COMPILER_SIMPLIFY_ARITH },
10265 [OP_SL         ] = { simplify_sl,       COMPILER_SIMPLIFY_SHIFT },
10266 [OP_USR        ] = { simplify_usr,      COMPILER_SIMPLIFY_SHIFT },
10267 [OP_SSR        ] = { simplify_ssr,      COMPILER_SIMPLIFY_SHIFT },
10268 [OP_AND        ] = { simplify_and,      COMPILER_SIMPLIFY_BITWISE },
10269 [OP_XOR        ] = { simplify_xor,      COMPILER_SIMPLIFY_BITWISE },
10270 [OP_OR         ] = { simplify_or,       COMPILER_SIMPLIFY_BITWISE },
10271 [OP_POS        ] = { simplify_pos,      COMPILER_SIMPLIFY_ARITH },
10272 [OP_NEG        ] = { simplify_neg,      COMPILER_SIMPLIFY_ARITH },
10273 [OP_INVERT     ] = { simplify_invert,   COMPILER_SIMPLIFY_BITWISE },
10274
10275 [OP_EQ         ] = { simplify_eq,       COMPILER_SIMPLIFY_LOGICAL },
10276 [OP_NOTEQ      ] = { simplify_noteq,    COMPILER_SIMPLIFY_LOGICAL },
10277 [OP_SLESS      ] = { simplify_sless,    COMPILER_SIMPLIFY_LOGICAL },
10278 [OP_ULESS      ] = { simplify_uless,    COMPILER_SIMPLIFY_LOGICAL },
10279 [OP_SMORE      ] = { simplify_smore,    COMPILER_SIMPLIFY_LOGICAL },
10280 [OP_UMORE      ] = { simplify_umore,    COMPILER_SIMPLIFY_LOGICAL },
10281 [OP_SLESSEQ    ] = { simplify_slesseq,  COMPILER_SIMPLIFY_LOGICAL },
10282 [OP_ULESSEQ    ] = { simplify_ulesseq,  COMPILER_SIMPLIFY_LOGICAL },
10283 [OP_SMOREEQ    ] = { simplify_smoreeq,  COMPILER_SIMPLIFY_LOGICAL },
10284 [OP_UMOREEQ    ] = { simplify_umoreeq,  COMPILER_SIMPLIFY_LOGICAL },
10285 [OP_LFALSE     ] = { simplify_lfalse,   COMPILER_SIMPLIFY_LOGICAL },
10286 [OP_LTRUE      ] = { simplify_ltrue,    COMPILER_SIMPLIFY_LOGICAL },
10287
10288 [OP_LOAD       ] = { simplify_load,     COMPILER_SIMPLIFY_OP },
10289 [OP_STORE      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10290
10291 [OP_UEXTRACT   ] = { simplify_uextract, COMPILER_SIMPLIFY_BITFIELD },
10292 [OP_SEXTRACT   ] = { simplify_sextract, COMPILER_SIMPLIFY_BITFIELD },
10293 [OP_DEPOSIT    ] = { simplify_deposit,  COMPILER_SIMPLIFY_BITFIELD },
10294
10295 [OP_NOOP       ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10296
10297 [OP_INTCONST   ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10298 [OP_BLOBCONST  ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10299 [OP_ADDRCONST  ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10300 [OP_UNKNOWNVAL ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10301
10302 [OP_WRITE      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10303 [OP_READ       ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10304 [OP_COPY       ] = { simplify_copy,     COMPILER_SIMPLIFY_COPY },
10305 [OP_CONVERT    ] = { simplify_copy,     COMPILER_SIMPLIFY_COPY },
10306 [OP_PIECE      ] = { simplify_piece,    COMPILER_SIMPLIFY_OP },
10307 [OP_ASM        ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10308
10309 [OP_DOT        ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10310 [OP_INDEX      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10311
10312 [OP_LIST       ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10313 [OP_BRANCH     ] = { simplify_branch,   COMPILER_SIMPLIFY_BRANCH },
10314 [OP_CBRANCH    ] = { simplify_branch,   COMPILER_SIMPLIFY_BRANCH },
10315 [OP_CALL       ] = { simplify_noop,     COMPILER_SIMPLIFY_BRANCH },
10316 [OP_RET        ] = { simplify_noop,     COMPILER_SIMPLIFY_BRANCH },
10317 [OP_LABEL      ] = { simplify_label,    COMPILER_SIMPLIFY_LABEL },
10318 [OP_ADECL      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10319 [OP_SDECL      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10320 [OP_PHI        ] = { simplify_phi,      COMPILER_SIMPLIFY_PHI },
10321
10322 [OP_INB        ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10323 [OP_INW        ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10324 [OP_INL        ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10325 [OP_OUTB       ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10326 [OP_OUTW       ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10327 [OP_OUTL       ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10328 [OP_BSF        ] = { simplify_bsf,      COMPILER_SIMPLIFY_OP },
10329 [OP_BSR        ] = { simplify_bsr,      COMPILER_SIMPLIFY_OP },
10330 [OP_RDMSR      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10331 [OP_WRMSR      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },               
10332 [OP_HLT        ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10333 };
10334
10335 static inline void debug_simplify(struct compile_state *state, 
10336         simplify_t do_simplify, struct triple *ins)
10337 {
10338 #if DEBUG_SIMPLIFY_HIRES
10339                 if (state->functions_joined && (do_simplify != simplify_noop)) {
10340                         /* High resolution debugging mode */
10341                         fprintf(state->dbgout, "simplifing: ");
10342                         display_triple(state->dbgout, ins);
10343                 }
10344 #endif
10345                 do_simplify(state, ins);
10346 #if DEBUG_SIMPLIFY_HIRES
10347                 if (state->functions_joined && (do_simplify != simplify_noop)) {
10348                         /* High resolution debugging mode */
10349                         fprintf(state->dbgout, "simplified: ");
10350                         display_triple(state->dbgout, ins);
10351                 }
10352 #endif
10353 }
10354 static void simplify(struct compile_state *state, struct triple *ins)
10355 {
10356         int op;
10357         simplify_t do_simplify;
10358         if (ins == &unknown_triple) {
10359                 internal_error(state, ins, "simplifying the unknown triple?");
10360         }
10361         do {
10362                 op = ins->op;
10363                 do_simplify = 0;
10364                 if ((op < 0) || (op > sizeof(table_simplify)/sizeof(table_simplify[0]))) {
10365                         do_simplify = 0;
10366                 }
10367                 else {
10368                         do_simplify = table_simplify[op].func;
10369                 }
10370                 if (do_simplify && 
10371                         !(state->compiler->flags & table_simplify[op].flag)) {
10372                         do_simplify = simplify_noop;
10373                 }
10374                 if (do_simplify && (ins->id & TRIPLE_FLAG_VOLATILE)) {
10375                         do_simplify = simplify_noop;
10376                 }
10377         
10378                 if (!do_simplify) {
10379                         internal_error(state, ins, "cannot simplify op: %d %s",
10380                                 op, tops(op));
10381                         return;
10382                 }
10383                 debug_simplify(state, do_simplify, ins);
10384         } while(ins->op != op);
10385 }
10386
10387 static void rebuild_ssa_form(struct compile_state *state);
10388
10389 static void simplify_all(struct compile_state *state)
10390 {
10391         struct triple *ins, *first;
10392         if (!(state->compiler->flags & COMPILER_SIMPLIFY)) {
10393                 return;
10394         }
10395         first = state->first;
10396         ins = first->prev;
10397         do {
10398                 simplify(state, ins);
10399                 ins = ins->prev;
10400         } while(ins != first->prev);
10401         ins = first;
10402         do {
10403                 simplify(state, ins);
10404                 ins = ins->next;
10405         }while(ins != first);
10406         rebuild_ssa_form(state);
10407
10408         print_blocks(state, __func__, state->dbgout);
10409 }
10410
10411 /*
10412  * Builtins....
10413  * ============================
10414  */
10415
10416 static void register_builtin_function(struct compile_state *state,
10417         const char *name, int op, struct type *rtype, ...)
10418 {
10419         struct type *ftype, *atype, *ctype, *crtype, *param, **next;
10420         struct triple *def, *arg, *result, *work, *last, *first, *retvar, *ret;
10421         struct hash_entry *ident;
10422         struct file_state file;
10423         int parameters;
10424         int name_len;
10425         va_list args;
10426         int i;
10427
10428         /* Dummy file state to get debug handling right */
10429         memset(&file, 0, sizeof(file));
10430         file.basename = "<built-in>";
10431         file.line = 1;
10432         file.report_line = 1;
10433         file.report_name = file.basename;
10434         file.prev = state->file;
10435         state->file = &file;
10436         state->function = name;
10437
10438         /* Find the Parameter count */
10439         valid_op(state, op);
10440         parameters = table_ops[op].rhs;
10441         if (parameters < 0 ) {
10442                 internal_error(state, 0, "Invalid builtin parameter count");
10443         }
10444
10445         /* Find the function type */
10446         ftype = new_type(TYPE_FUNCTION | STOR_INLINE | STOR_STATIC, rtype, 0);
10447         ftype->elements = parameters;
10448         next = &ftype->right;
10449         va_start(args, rtype);
10450         for(i = 0; i < parameters; i++) {
10451                 atype = va_arg(args, struct type *);
10452                 if (!*next) {
10453                         *next = atype;
10454                 } else {
10455                         *next = new_type(TYPE_PRODUCT, *next, atype);
10456                         next = &((*next)->right);
10457                 }
10458         }
10459         if (!*next) {
10460                 *next = &void_type;
10461         }
10462         va_end(args);
10463
10464         /* Get the initial closure type */
10465         ctype = new_type(TYPE_JOIN, &void_type, 0);
10466         ctype->elements = 1;
10467
10468         /* Get the return type */
10469         crtype = new_type(TYPE_TUPLE, new_type(TYPE_PRODUCT, ctype, rtype), 0);
10470         crtype->elements = 2;
10471
10472         /* Generate the needed triples */
10473         def = triple(state, OP_LIST, ftype, 0, 0);
10474         first = label(state);
10475         RHS(def, 0) = first;
10476         result = flatten(state, first, variable(state, crtype));
10477         retvar = flatten(state, first, variable(state, &void_ptr_type));
10478         ret = triple(state, OP_RET, &void_type, read_expr(state, retvar), 0);
10479
10480         /* Now string them together */
10481         param = ftype->right;
10482         for(i = 0; i < parameters; i++) {
10483                 if ((param->type & TYPE_MASK) == TYPE_PRODUCT) {
10484                         atype = param->left;
10485                 } else {
10486                         atype = param;
10487                 }
10488                 arg = flatten(state, first, variable(state, atype));
10489                 param = param->right;
10490         }
10491         work = new_triple(state, op, rtype, -1, parameters);
10492         generate_lhs_pieces(state, work);
10493         for(i = 0; i < parameters; i++) {
10494                 RHS(work, i) = read_expr(state, farg(state, def, i));
10495         }
10496         if ((rtype->type & TYPE_MASK) != TYPE_VOID) {
10497                 work = write_expr(state, deref_index(state, result, 1), work);
10498         }
10499         work = flatten(state, first, work);
10500         last = flatten(state, first, label(state));
10501         ret  = flatten(state, first, ret);
10502         name_len = strlen(name);
10503         ident = lookup(state, name, name_len);
10504         ftype->type_ident = ident;
10505         symbol(state, ident, &ident->sym_ident, def, ftype);
10506         
10507         state->file = file.prev;
10508         state->function = 0;
10509         state->main_function = 0;
10510
10511         if (!state->functions) {
10512                 state->functions = def;
10513         } else {
10514                 insert_triple(state, state->functions, def);
10515         }
10516         if (state->compiler->debug & DEBUG_INLINE) {
10517                 FILE *fp = state->dbgout;
10518                 fprintf(fp, "\n");
10519                 loc(fp, state, 0);
10520                 fprintf(fp, "\n__________ %s _________\n", __FUNCTION__);
10521                 display_func(state, fp, def);
10522                 fprintf(fp, "__________ %s _________ done\n\n", __FUNCTION__);
10523         }
10524 }
10525
10526 static struct type *partial_struct(struct compile_state *state,
10527         const char *field_name, struct type *type, struct type *rest)
10528 {
10529         struct hash_entry *field_ident;
10530         struct type *result;
10531         int field_name_len;
10532
10533         field_name_len = strlen(field_name);
10534         field_ident = lookup(state, field_name, field_name_len);
10535
10536         result = clone_type(0, type);
10537         result->field_ident = field_ident;
10538
10539         if (rest) {
10540                 result = new_type(TYPE_PRODUCT, result, rest);
10541         }
10542         return result;
10543 }
10544
10545 static struct type *register_builtin_type(struct compile_state *state,
10546         const char *name, struct type *type)
10547 {
10548         struct hash_entry *ident;
10549         int name_len;
10550
10551         name_len = strlen(name);
10552         ident = lookup(state, name, name_len);
10553         
10554         if ((type->type & TYPE_MASK) == TYPE_PRODUCT) {
10555                 ulong_t elements = 0;
10556                 struct type *field;
10557                 type = new_type(TYPE_STRUCT, type, 0);
10558                 field = type->left;
10559                 while((field->type & TYPE_MASK) == TYPE_PRODUCT) {
10560                         elements++;
10561                         field = field->right;
10562                 }
10563                 elements++;
10564                 symbol(state, ident, &ident->sym_tag, 0, type);
10565                 type->type_ident = ident;
10566                 type->elements = elements;
10567         }
10568         symbol(state, ident, &ident->sym_ident, 0, type);
10569         ident->tok = TOK_TYPE_NAME;
10570         return type;
10571 }
10572
10573
10574 static void register_builtins(struct compile_state *state)
10575 {
10576         struct type *div_type, *ldiv_type;
10577         struct type *udiv_type, *uldiv_type;
10578         struct type *msr_type;
10579
10580         div_type = register_builtin_type(state, "__builtin_div_t",
10581                 partial_struct(state, "quot", &int_type,
10582                 partial_struct(state, "rem",  &int_type, 0)));
10583         ldiv_type = register_builtin_type(state, "__builtin_ldiv_t",
10584                 partial_struct(state, "quot", &long_type,
10585                 partial_struct(state, "rem",  &long_type, 0)));
10586         udiv_type = register_builtin_type(state, "__builtin_udiv_t",
10587                 partial_struct(state, "quot", &uint_type,
10588                 partial_struct(state, "rem",  &uint_type, 0)));
10589         uldiv_type = register_builtin_type(state, "__builtin_uldiv_t",
10590                 partial_struct(state, "quot", &ulong_type,
10591                 partial_struct(state, "rem",  &ulong_type, 0)));
10592
10593         register_builtin_function(state, "__builtin_div",   OP_SDIVT, div_type,
10594                 &int_type, &int_type);
10595         register_builtin_function(state, "__builtin_ldiv",  OP_SDIVT, ldiv_type,
10596                 &long_type, &long_type);
10597         register_builtin_function(state, "__builtin_udiv",  OP_UDIVT, udiv_type,
10598                 &uint_type, &uint_type);
10599         register_builtin_function(state, "__builtin_uldiv", OP_UDIVT, uldiv_type,
10600                 &ulong_type, &ulong_type);
10601
10602         register_builtin_function(state, "__builtin_inb", OP_INB, &uchar_type, 
10603                 &ushort_type);
10604         register_builtin_function(state, "__builtin_inw", OP_INW, &ushort_type,
10605                 &ushort_type);
10606         register_builtin_function(state, "__builtin_inl", OP_INL, &uint_type,   
10607                 &ushort_type);
10608
10609         register_builtin_function(state, "__builtin_outb", OP_OUTB, &void_type, 
10610                 &uchar_type, &ushort_type);
10611         register_builtin_function(state, "__builtin_outw", OP_OUTW, &void_type, 
10612                 &ushort_type, &ushort_type);
10613         register_builtin_function(state, "__builtin_outl", OP_OUTL, &void_type, 
10614                 &uint_type, &ushort_type);
10615         
10616         register_builtin_function(state, "__builtin_bsf", OP_BSF, &int_type, 
10617                 &int_type);
10618         register_builtin_function(state, "__builtin_bsr", OP_BSR, &int_type, 
10619                 &int_type);
10620
10621         msr_type = register_builtin_type(state, "__builtin_msr_t",
10622                 partial_struct(state, "lo", &ulong_type,
10623                 partial_struct(state, "hi", &ulong_type, 0)));
10624
10625         register_builtin_function(state, "__builtin_rdmsr", OP_RDMSR, msr_type,
10626                 &ulong_type);
10627         register_builtin_function(state, "__builtin_wrmsr", OP_WRMSR, &void_type,
10628                 &ulong_type, &ulong_type, &ulong_type);
10629         
10630         register_builtin_function(state, "__builtin_hlt", OP_HLT, &void_type, 
10631                 &void_type);
10632 }
10633
10634 static struct type *declarator(
10635         struct compile_state *state, struct type *type, 
10636         struct hash_entry **ident, int need_ident);
10637 static void decl(struct compile_state *state, struct triple *first);
10638 static struct type *specifier_qualifier_list(struct compile_state *state);
10639 static int isdecl_specifier(int tok);
10640 static struct type *decl_specifiers(struct compile_state *state);
10641 static int istype(int tok);
10642 static struct triple *expr(struct compile_state *state);
10643 static struct triple *assignment_expr(struct compile_state *state);
10644 static struct type *type_name(struct compile_state *state);
10645 static void statement(struct compile_state *state, struct triple *first);
10646
10647 static struct triple *call_expr(
10648         struct compile_state *state, struct triple *func)
10649 {
10650         struct triple *def;
10651         struct type *param, *type;
10652         ulong_t pvals, index;
10653
10654         if ((func->type->type & TYPE_MASK) != TYPE_FUNCTION) {
10655                 error(state, 0, "Called object is not a function");
10656         }
10657         if (func->op != OP_LIST) {
10658                 internal_error(state, 0, "improper function");
10659         }
10660         eat(state, TOK_LPAREN);
10661         /* Find the return type without any specifiers */
10662         type = clone_type(0, func->type->left);
10663         /* Count the number of rhs entries for OP_FCALL */
10664         param = func->type->right;
10665         pvals = 0;
10666         while((param->type & TYPE_MASK) == TYPE_PRODUCT) {
10667                 pvals++;
10668                 param = param->right;
10669         }
10670         if ((param->type & TYPE_MASK) != TYPE_VOID) {
10671                 pvals++;
10672         }
10673         def = new_triple(state, OP_FCALL, type, -1, pvals);
10674         MISC(def, 0) = func;
10675
10676         param = func->type->right;
10677         for(index = 0; index < pvals; index++) {
10678                 struct triple *val;
10679                 struct type *arg_type;
10680                 val = read_expr(state, assignment_expr(state));
10681                 arg_type = param;
10682                 if ((param->type & TYPE_MASK) == TYPE_PRODUCT) {
10683                         arg_type = param->left;
10684                 }
10685                 write_compatible(state, arg_type, val->type);
10686                 RHS(def, index) = val;
10687                 if (index != (pvals - 1)) {
10688                         eat(state, TOK_COMMA);
10689                         param = param->right;
10690                 }
10691         }
10692         eat(state, TOK_RPAREN);
10693         return def;
10694 }
10695
10696
10697 static struct triple *character_constant(struct compile_state *state)
10698 {
10699         struct triple *def;
10700         struct token *tk;
10701         const signed char *str, *end;
10702         int c;
10703         int str_len;
10704         tk = eat(state, TOK_LIT_CHAR);
10705         str = tk->val.str + 1;
10706         str_len = tk->str_len - 2;
10707         if (str_len <= 0) {
10708                 error(state, 0, "empty character constant");
10709         }
10710         end = str + str_len;
10711         c = char_value(state, &str, end);
10712         if (str != end) {
10713                 error(state, 0, "multibyte character constant not supported");
10714         }
10715         def = int_const(state, &char_type, (ulong_t)((long_t)c));
10716         return def;
10717 }
10718
10719 static struct triple *string_constant(struct compile_state *state)
10720 {
10721         struct triple *def;
10722         struct token *tk;
10723         struct type *type;
10724         const signed char *str, *end;
10725         signed char *buf, *ptr;
10726         int str_len;
10727
10728         buf = 0;
10729         type = new_type(TYPE_ARRAY, &char_type, 0);
10730         type->elements = 0;
10731         /* The while loop handles string concatenation */
10732         do {
10733                 tk = eat(state, TOK_LIT_STRING);
10734                 str = tk->val.str + 1;
10735                 str_len = tk->str_len - 2;
10736                 if (str_len < 0) {
10737                         error(state, 0, "negative string constant length");
10738                 }
10739                 end = str + str_len;
10740                 ptr = buf;
10741                 buf = xmalloc(type->elements + str_len + 1, "string_constant");
10742                 memcpy(buf, ptr, type->elements);
10743                 ptr = buf + type->elements;
10744                 do {
10745                         *ptr++ = char_value(state, &str, end);
10746                 } while(str < end);
10747                 type->elements = ptr - buf;
10748         } while(peek(state) == TOK_LIT_STRING);
10749         *ptr = '\0';
10750         type->elements += 1;
10751         def = triple(state, OP_BLOBCONST, type, 0, 0);
10752         def->u.blob = buf;
10753
10754         return def;
10755 }
10756
10757
10758 static struct triple *integer_constant(struct compile_state *state)
10759 {
10760         struct triple *def;
10761         unsigned long val;
10762         struct token *tk;
10763         char *end;
10764         int u, l, decimal;
10765         struct type *type;
10766
10767         tk = eat(state, TOK_LIT_INT);
10768         errno = 0;
10769         decimal = (tk->val.str[0] != '0');
10770         val = strtoul(tk->val.str, &end, 0);
10771         if ((val > ULONG_T_MAX) || ((val == ULONG_MAX) && (errno == ERANGE))) {
10772                 error(state, 0, "Integer constant to large");
10773         }
10774         u = l = 0;
10775         if ((*end == 'u') || (*end == 'U')) {
10776                 u = 1;
10777                         end++;
10778         }
10779         if ((*end == 'l') || (*end == 'L')) {
10780                 l = 1;
10781                 end++;
10782         }
10783         if ((*end == 'u') || (*end == 'U')) {
10784                 u = 1;
10785                 end++;
10786         }
10787         if (*end) {
10788                 error(state, 0, "Junk at end of integer constant");
10789         }
10790         if (u && l)  {
10791                 type = &ulong_type;
10792         }
10793         else if (l) {
10794                 type = &long_type;
10795                 if (!decimal && (val > LONG_T_MAX)) {
10796                         type = &ulong_type;
10797                 }
10798         }
10799         else if (u) {
10800                 type = &uint_type;
10801                 if (val > UINT_T_MAX) {
10802                         type = &ulong_type;
10803                 }
10804         }
10805         else {
10806                 type = &int_type;
10807                 if (!decimal && (val > INT_T_MAX) && (val <= UINT_T_MAX)) {
10808                         type = &uint_type;
10809                 }
10810                 else if (!decimal && (val > LONG_T_MAX)) {
10811                         type = &ulong_type;
10812                 }
10813                 else if (val > INT_T_MAX) {
10814                         type = &long_type;
10815                 }
10816         }
10817         def = int_const(state, type, val);
10818         return def;
10819 }
10820
10821 static struct triple *primary_expr(struct compile_state *state)
10822 {
10823         struct triple *def;
10824         int tok;
10825         tok = peek(state);
10826         switch(tok) {
10827         case TOK_IDENT:
10828         {
10829                 struct hash_entry *ident;
10830                 /* Here ident is either:
10831                  * a varable name
10832                  * a function name
10833                  */
10834                 ident = eat(state, TOK_IDENT)->ident;
10835                 if (!ident->sym_ident) {
10836                         error(state, 0, "%s undeclared", ident->name);
10837                 }
10838                 def = ident->sym_ident->def;
10839                 break;
10840         }
10841         case TOK_ENUM_CONST:
10842         {
10843                 struct hash_entry *ident;
10844                 /* Here ident is an enumeration constant */
10845                 ident = eat(state, TOK_ENUM_CONST)->ident;
10846                 if (!ident->sym_ident) {
10847                         error(state, 0, "%s undeclared", ident->name);
10848                 }
10849                 def = ident->sym_ident->def;
10850                 break;
10851         }
10852         case TOK_MIDENT:
10853         {
10854                 struct hash_entry *ident;
10855                 ident = eat(state, TOK_MIDENT)->ident;
10856                 warning(state, 0, "Replacing undefined macro: %s with 0",
10857                         ident->name);
10858                 def = int_const(state, &int_type, 0);
10859                 break;
10860         }
10861         case TOK_LPAREN:
10862                 eat(state, TOK_LPAREN);
10863                 def = expr(state);
10864                 eat(state, TOK_RPAREN);
10865                 break;
10866         case TOK_LIT_INT:
10867                 def = integer_constant(state);
10868                 break;
10869         case TOK_LIT_FLOAT:
10870                 eat(state, TOK_LIT_FLOAT);
10871                 error(state, 0, "Floating point constants not supported");
10872                 def = 0;
10873                 FINISHME();
10874                 break;
10875         case TOK_LIT_CHAR:
10876                 def = character_constant(state);
10877                 break;
10878         case TOK_LIT_STRING:
10879                 def = string_constant(state);
10880                 break;
10881         default:
10882                 def = 0;
10883                 error(state, 0, "Unexpected token: %s\n", tokens[tok]);
10884         }
10885         return def;
10886 }
10887
10888 static struct triple *postfix_expr(struct compile_state *state)
10889 {
10890         struct triple *def;
10891         int postfix;
10892         def = primary_expr(state);
10893         do {
10894                 struct triple *left;
10895                 int tok;
10896                 postfix = 1;
10897                 left = def;
10898                 switch((tok = peek(state))) {
10899                 case TOK_LBRACKET:
10900                         eat(state, TOK_LBRACKET);
10901                         def = mk_subscript_expr(state, left, expr(state));
10902                         eat(state, TOK_RBRACKET);
10903                         break;
10904                 case TOK_LPAREN:
10905                         def = call_expr(state, def);
10906                         break;
10907                 case TOK_DOT:
10908                 {
10909                         struct hash_entry *field;
10910                         eat(state, TOK_DOT);
10911                         field = eat(state, TOK_IDENT)->ident;
10912                         def = deref_field(state, def, field);
10913                         break;
10914                 }
10915                 case TOK_ARROW:
10916                 {
10917                         struct hash_entry *field;
10918                         eat(state, TOK_ARROW);
10919                         field = eat(state, TOK_IDENT)->ident;
10920                         def = mk_deref_expr(state, read_expr(state, def));
10921                         def = deref_field(state, def, field);
10922                         break;
10923                 }
10924                 case TOK_PLUSPLUS:
10925                         eat(state, TOK_PLUSPLUS);
10926                         def = mk_post_inc_expr(state, left);
10927                         break;
10928                 case TOK_MINUSMINUS:
10929                         eat(state, TOK_MINUSMINUS);
10930                         def = mk_post_dec_expr(state, left);
10931                         break;
10932                 default:
10933                         postfix = 0;
10934                         break;
10935                 }
10936         } while(postfix);
10937         return def;
10938 }
10939
10940 static struct triple *cast_expr(struct compile_state *state);
10941
10942 static struct triple *unary_expr(struct compile_state *state)
10943 {
10944         struct triple *def, *right;
10945         int tok;
10946         switch((tok = peek(state))) {
10947         case TOK_PLUSPLUS:
10948                 eat(state, TOK_PLUSPLUS);
10949                 def = mk_pre_inc_expr(state, unary_expr(state));
10950                 break;
10951         case TOK_MINUSMINUS:
10952                 eat(state, TOK_MINUSMINUS);
10953                 def = mk_pre_dec_expr(state, unary_expr(state));
10954                 break;
10955         case TOK_AND:
10956                 eat(state, TOK_AND);
10957                 def = mk_addr_expr(state, cast_expr(state), 0);
10958                 break;
10959         case TOK_STAR:
10960                 eat(state, TOK_STAR);
10961                 def = mk_deref_expr(state, read_expr(state, cast_expr(state)));
10962                 break;
10963         case TOK_PLUS:
10964                 eat(state, TOK_PLUS);
10965                 right = read_expr(state, cast_expr(state));
10966                 arithmetic(state, right);
10967                 def = integral_promotion(state, right);
10968                 break;
10969         case TOK_MINUS:
10970                 eat(state, TOK_MINUS);
10971                 right = read_expr(state, cast_expr(state));
10972                 arithmetic(state, right);
10973                 def = integral_promotion(state, right);
10974                 def = triple(state, OP_NEG, def->type, def, 0);
10975                 break;
10976         case TOK_TILDE:
10977                 eat(state, TOK_TILDE);
10978                 right = read_expr(state, cast_expr(state));
10979                 integral(state, right);
10980                 def = integral_promotion(state, right);
10981                 def = triple(state, OP_INVERT, def->type, def, 0);
10982                 break;
10983         case TOK_BANG:
10984                 eat(state, TOK_BANG);
10985                 right = read_expr(state, cast_expr(state));
10986                 bool(state, right);
10987                 def = lfalse_expr(state, right);
10988                 break;
10989         case TOK_SIZEOF:
10990         {
10991                 struct type *type;
10992                 int tok1, tok2;
10993                 eat(state, TOK_SIZEOF);
10994                 tok1 = peek(state);
10995                 tok2 = peek2(state);
10996                 if ((tok1 == TOK_LPAREN) && istype(tok2)) {
10997                         eat(state, TOK_LPAREN);
10998                         type = type_name(state);
10999                         eat(state, TOK_RPAREN);
11000                 }
11001                 else {
11002                         struct triple *expr;
11003                         expr = unary_expr(state);
11004                         type = expr->type;
11005                         release_expr(state, expr);
11006                 }
11007                 def = int_const(state, &ulong_type, size_of_in_bytes(state, type));
11008                 break;
11009         }
11010         case TOK_ALIGNOF:
11011         {
11012                 struct type *type;
11013                 int tok1, tok2;
11014                 eat(state, TOK_ALIGNOF);
11015                 tok1 = peek(state);
11016                 tok2 = peek2(state);
11017                 if ((tok1 == TOK_LPAREN) && istype(tok2)) {
11018                         eat(state, TOK_LPAREN);
11019                         type = type_name(state);
11020                         eat(state, TOK_RPAREN);
11021                 }
11022                 else {
11023                         struct triple *expr;
11024                         expr = unary_expr(state);
11025                         type = expr->type;
11026                         release_expr(state, expr);
11027                 }
11028                 def = int_const(state, &ulong_type, align_of_in_bytes(state, type));
11029                 break;
11030         }
11031         case TOK_MDEFINED:
11032         {
11033                 /* We only come here if we are called from the preprocessor */
11034                 struct hash_entry *ident;
11035                 int parens;
11036                 eat(state, TOK_MDEFINED);
11037                 parens = 0;
11038                 if (pp_peek(state) == TOK_LPAREN) {
11039                         pp_eat(state, TOK_LPAREN);
11040                         parens = 1;
11041                 }
11042                 ident = pp_eat(state, TOK_MIDENT)->ident;
11043                 if (parens) {
11044                         eat(state, TOK_RPAREN);
11045                 }
11046                 def = int_const(state, &int_type, ident->sym_define != 0);
11047                 break;
11048         }
11049         default:
11050                 def = postfix_expr(state);
11051                 break;
11052         }
11053         return def;
11054 }
11055
11056 static struct triple *cast_expr(struct compile_state *state)
11057 {
11058         struct triple *def;
11059         int tok1, tok2;
11060         tok1 = peek(state);
11061         tok2 = peek2(state);
11062         if ((tok1 == TOK_LPAREN) && istype(tok2)) {
11063                 struct type *type;
11064                 eat(state, TOK_LPAREN);
11065                 type = type_name(state);
11066                 eat(state, TOK_RPAREN);
11067                 def = mk_cast_expr(state, type, cast_expr(state));
11068         }
11069         else {
11070                 def = unary_expr(state);
11071         }
11072         return def;
11073 }
11074
11075 static struct triple *mult_expr(struct compile_state *state)
11076 {
11077         struct triple *def;
11078         int done;
11079         def = cast_expr(state);
11080         do {
11081                 struct triple *left, *right;
11082                 struct type *result_type;
11083                 int tok, op, sign;
11084                 done = 0;
11085                 tok = peek(state);
11086                 switch(tok) {
11087                 case TOK_STAR:
11088                 case TOK_DIV:
11089                 case TOK_MOD:
11090                         left = read_expr(state, def);
11091                         arithmetic(state, left);
11092
11093                         eat(state, tok);
11094
11095                         right = read_expr(state, cast_expr(state));
11096                         arithmetic(state, right);
11097
11098                         result_type = arithmetic_result(state, left, right);
11099                         sign = is_signed(result_type);
11100                         op = -1;
11101                         switch(tok) {
11102                         case TOK_STAR: op = sign? OP_SMUL : OP_UMUL; break;
11103                         case TOK_DIV:  op = sign? OP_SDIV : OP_UDIV; break;
11104                         case TOK_MOD:  op = sign? OP_SMOD : OP_UMOD; break;
11105                         }
11106                         def = triple(state, op, result_type, left, right);
11107                         break;
11108                 default:
11109                         done = 1;
11110                         break;
11111                 }
11112         } while(!done);
11113         return def;
11114 }
11115
11116 static struct triple *add_expr(struct compile_state *state)
11117 {
11118         struct triple *def;
11119         int done;
11120         def = mult_expr(state);
11121         do {
11122                 done = 0;
11123                 switch( peek(state)) {
11124                 case TOK_PLUS:
11125                         eat(state, TOK_PLUS);
11126                         def = mk_add_expr(state, def, mult_expr(state));
11127                         break;
11128                 case TOK_MINUS:
11129                         eat(state, TOK_MINUS);
11130                         def = mk_sub_expr(state, def, mult_expr(state));
11131                         break;
11132                 default:
11133                         done = 1;
11134                         break;
11135                 }
11136         } while(!done);
11137         return def;
11138 }
11139
11140 static struct triple *shift_expr(struct compile_state *state)
11141 {
11142         struct triple *def;
11143         int done;
11144         def = add_expr(state);
11145         do {
11146                 struct triple *left, *right;
11147                 int tok, op;
11148                 done = 0;
11149                 switch((tok = peek(state))) {
11150                 case TOK_SL:
11151                 case TOK_SR:
11152                         left = read_expr(state, def);
11153                         integral(state, left);
11154                         left = integral_promotion(state, left);
11155
11156                         eat(state, tok);
11157
11158                         right = read_expr(state, add_expr(state));
11159                         integral(state, right);
11160                         right = integral_promotion(state, right);
11161                         
11162                         op = (tok == TOK_SL)? OP_SL : 
11163                                 is_signed(left->type)? OP_SSR: OP_USR;
11164
11165                         def = triple(state, op, left->type, left, right);
11166                         break;
11167                 default:
11168                         done = 1;
11169                         break;
11170                 }
11171         } while(!done);
11172         return def;
11173 }
11174
11175 static struct triple *relational_expr(struct compile_state *state)
11176 {
11177 #warning "Extend relational exprs to work on more than arithmetic types"
11178         struct triple *def;
11179         int done;
11180         def = shift_expr(state);
11181         do {
11182                 struct triple *left, *right;
11183                 struct type *arg_type;
11184                 int tok, op, sign;
11185                 done = 0;
11186                 switch((tok = peek(state))) {
11187                 case TOK_LESS:
11188                 case TOK_MORE:
11189                 case TOK_LESSEQ:
11190                 case TOK_MOREEQ:
11191                         left = read_expr(state, def);
11192                         arithmetic(state, left);
11193
11194                         eat(state, tok);
11195
11196                         right = read_expr(state, shift_expr(state));
11197                         arithmetic(state, right);
11198
11199                         arg_type = arithmetic_result(state, left, right);
11200                         sign = is_signed(arg_type);
11201                         op = -1;
11202                         switch(tok) {
11203                         case TOK_LESS:   op = sign? OP_SLESS : OP_ULESS; break;
11204                         case TOK_MORE:   op = sign? OP_SMORE : OP_UMORE; break;
11205                         case TOK_LESSEQ: op = sign? OP_SLESSEQ : OP_ULESSEQ; break;
11206                         case TOK_MOREEQ: op = sign? OP_SMOREEQ : OP_UMOREEQ; break;
11207                         }
11208                         def = triple(state, op, &int_type, left, right);
11209                         break;
11210                 default:
11211                         done = 1;
11212                         break;
11213                 }
11214         } while(!done);
11215         return def;
11216 }
11217
11218 static struct triple *equality_expr(struct compile_state *state)
11219 {
11220 #warning "Extend equality exprs to work on more than arithmetic types"
11221         struct triple *def;
11222         int done;
11223         def = relational_expr(state);
11224         do {
11225                 struct triple *left, *right;
11226                 int tok, op;
11227                 done = 0;
11228                 switch((tok = peek(state))) {
11229                 case TOK_EQEQ:
11230                 case TOK_NOTEQ:
11231                         left = read_expr(state, def);
11232                         arithmetic(state, left);
11233                         eat(state, tok);
11234                         right = read_expr(state, relational_expr(state));
11235                         arithmetic(state, right);
11236                         op = (tok == TOK_EQEQ) ? OP_EQ: OP_NOTEQ;
11237                         def = triple(state, op, &int_type, left, right);
11238                         break;
11239                 default:
11240                         done = 1;
11241                         break;
11242                 }
11243         } while(!done);
11244         return def;
11245 }
11246
11247 static struct triple *and_expr(struct compile_state *state)
11248 {
11249         struct triple *def;
11250         def = equality_expr(state);
11251         while(peek(state) == TOK_AND) {
11252                 struct triple *left, *right;
11253                 struct type *result_type;
11254                 left = read_expr(state, def);
11255                 integral(state, left);
11256                 eat(state, TOK_AND);
11257                 right = read_expr(state, equality_expr(state));
11258                 integral(state, right);
11259                 result_type = arithmetic_result(state, left, right);
11260                 def = triple(state, OP_AND, result_type, left, right);
11261         }
11262         return def;
11263 }
11264
11265 static struct triple *xor_expr(struct compile_state *state)
11266 {
11267         struct triple *def;
11268         def = and_expr(state);
11269         while(peek(state) == TOK_XOR) {
11270                 struct triple *left, *right;
11271                 struct type *result_type;
11272                 left = read_expr(state, def);
11273                 integral(state, left);
11274                 eat(state, TOK_XOR);
11275                 right = read_expr(state, and_expr(state));
11276                 integral(state, right);
11277                 result_type = arithmetic_result(state, left, right);
11278                 def = triple(state, OP_XOR, result_type, left, right);
11279         }
11280         return def;
11281 }
11282
11283 static struct triple *or_expr(struct compile_state *state)
11284 {
11285         struct triple *def;
11286         def = xor_expr(state);
11287         while(peek(state) == TOK_OR) {
11288                 struct triple *left, *right;
11289                 struct type *result_type;
11290                 left = read_expr(state, def);
11291                 integral(state, left);
11292                 eat(state, TOK_OR);
11293                 right = read_expr(state, xor_expr(state));
11294                 integral(state, right);
11295                 result_type = arithmetic_result(state, left, right);
11296                 def = triple(state, OP_OR, result_type, left, right);
11297         }
11298         return def;
11299 }
11300
11301 static struct triple *land_expr(struct compile_state *state)
11302 {
11303         struct triple *def;
11304         def = or_expr(state);
11305         while(peek(state) == TOK_LOGAND) {
11306                 struct triple *left, *right;
11307                 left = read_expr(state, def);
11308                 bool(state, left);
11309                 eat(state, TOK_LOGAND);
11310                 right = read_expr(state, or_expr(state));
11311                 bool(state, right);
11312
11313                 def = mkland_expr(state,
11314                         ltrue_expr(state, left),
11315                         ltrue_expr(state, right));
11316         }
11317         return def;
11318 }
11319
11320 static struct triple *lor_expr(struct compile_state *state)
11321 {
11322         struct triple *def;
11323         def = land_expr(state);
11324         while(peek(state) == TOK_LOGOR) {
11325                 struct triple *left, *right;
11326                 left = read_expr(state, def);
11327                 bool(state, left);
11328                 eat(state, TOK_LOGOR);
11329                 right = read_expr(state, land_expr(state));
11330                 bool(state, right);
11331
11332                 def = mklor_expr(state, 
11333                         ltrue_expr(state, left),
11334                         ltrue_expr(state, right));
11335         }
11336         return def;
11337 }
11338
11339 static struct triple *conditional_expr(struct compile_state *state)
11340 {
11341         struct triple *def;
11342         def = lor_expr(state);
11343         if (peek(state) == TOK_QUEST) {
11344                 struct triple *test, *left, *right;
11345                 bool(state, def);
11346                 test = ltrue_expr(state, read_expr(state, def));
11347                 eat(state, TOK_QUEST);
11348                 left = read_expr(state, expr(state));
11349                 eat(state, TOK_COLON);
11350                 right = read_expr(state, conditional_expr(state));
11351
11352                 def = mkcond_expr(state, test, left, right);
11353         }
11354         return def;
11355 }
11356
11357 struct cv_triple {
11358         struct triple *val;
11359         int id;
11360 };
11361
11362 static void set_cv(struct compile_state *state, struct cv_triple *cv,
11363         struct triple *dest, struct triple *val)
11364 {
11365         if (cv[dest->id].val) {
11366                 free_triple(state, cv[dest->id].val);
11367         }
11368         cv[dest->id].val = val;
11369 }
11370 static struct triple *get_cv(struct compile_state *state, struct cv_triple *cv,
11371         struct triple *src)
11372 {
11373         return cv[src->id].val;
11374 }
11375
11376 static struct triple *eval_const_expr(
11377         struct compile_state *state, struct triple *expr)
11378 {
11379         struct triple *def;
11380         if (is_const(expr)) {
11381                 def = expr;
11382         }
11383         else {
11384                 /* If we don't start out as a constant simplify into one */
11385                 struct triple *head, *ptr;
11386                 struct cv_triple *cv;
11387                 int i, count;
11388                 head = label(state); /* dummy initial triple */
11389                 flatten(state, head, expr);
11390                 count = 1;
11391                 for(ptr = head->next; ptr != head; ptr = ptr->next) {
11392                         count++;
11393                 }
11394                 cv = xcmalloc(sizeof(struct cv_triple)*count, "const value vector");
11395                 i = 1;
11396                 for(ptr = head->next; ptr != head; ptr = ptr->next) {
11397                         cv[i].val = 0;
11398                         cv[i].id  = ptr->id;
11399                         ptr->id   = i;
11400                         i++;
11401                 }
11402                 ptr = head->next;
11403                 do {
11404                         valid_ins(state, ptr);
11405                         if ((ptr->op == OP_PHI) || (ptr->op == OP_LIST)) {
11406                                 internal_error(state, ptr, 
11407                                         "unexpected %s in constant expression",
11408                                         tops(ptr->op));
11409                         }
11410                         else if (ptr->op == OP_LIST) {
11411                         }
11412                         else if (triple_is_structural(state, ptr)) {
11413                                 ptr = ptr->next;
11414                         }
11415                         else if (triple_is_ubranch(state, ptr)) {
11416                                 ptr = TARG(ptr, 0);
11417                         }
11418                         else if (triple_is_cbranch(state, ptr)) {
11419                                 struct triple *cond_val;
11420                                 cond_val = get_cv(state, cv, RHS(ptr, 0));
11421                                 if (!cond_val || !is_const(cond_val) || 
11422                                         (cond_val->op != OP_INTCONST)) 
11423                                 {
11424                                         internal_error(state, ptr, "bad branch condition");
11425                                 }
11426                                 if (cond_val->u.cval == 0) {
11427                                         ptr = ptr->next;
11428                                 } else {
11429                                         ptr = TARG(ptr, 0);
11430                                 }
11431                         }
11432                         else if (triple_is_branch(state, ptr)) {
11433                                 error(state, ptr, "bad branch type in constant expression");
11434                         }
11435                         else if (ptr->op == OP_WRITE) {
11436                                 struct triple *val;
11437                                 val = get_cv(state, cv, RHS(ptr, 0));
11438                                 
11439                                 set_cv(state, cv, MISC(ptr, 0), 
11440                                         copy_triple(state, val));
11441                                 set_cv(state, cv, ptr, 
11442                                         copy_triple(state, val));
11443                                 ptr = ptr->next;
11444                         }
11445                         else if (ptr->op == OP_READ) {
11446                                 set_cv(state, cv, ptr, 
11447                                         copy_triple(state, 
11448                                                 get_cv(state, cv, RHS(ptr, 0))));
11449                                 ptr = ptr->next;
11450                         }
11451                         else if (triple_is_pure(state, ptr, cv[ptr->id].id)) {
11452                                 struct triple *val, **rhs;
11453                                 val = copy_triple(state, ptr);
11454                                 rhs = triple_rhs(state, val, 0);
11455                                 for(; rhs; rhs = triple_rhs(state, val, rhs)) {
11456                                         if (!*rhs) {
11457                                                 internal_error(state, ptr, "Missing rhs");
11458                                         }
11459                                         *rhs = get_cv(state, cv, *rhs);
11460                                 }
11461                                 simplify(state, val);
11462                                 set_cv(state, cv, ptr, val);
11463                                 ptr = ptr->next;
11464                         }
11465                         else {
11466                                 error(state, ptr, "impure operation in constant expression");
11467                         }
11468                         
11469                 } while(ptr != head);
11470
11471                 /* Get the result value */
11472                 def = get_cv(state, cv, head->prev);
11473                 cv[head->prev->id].val = 0;
11474
11475                 /* Free the temporary values */
11476                 for(i = 0; i < count; i++) {
11477                         if (cv[i].val) {
11478                                 free_triple(state, cv[i].val);
11479                                 cv[i].val = 0;
11480                         }
11481                 }
11482                 xfree(cv);
11483                 /* Free the intermediate expressions */
11484                 while(head->next != head) {
11485                         release_triple(state, head->next);
11486                 }
11487                 free_triple(state, head);
11488         }
11489         if (!is_const(def)) {
11490                 error(state, expr, "Not a constant expression");
11491         }
11492         return def;
11493 }
11494
11495 static struct triple *constant_expr(struct compile_state *state)
11496 {
11497         return eval_const_expr(state, conditional_expr(state));
11498 }
11499
11500 static struct triple *assignment_expr(struct compile_state *state)
11501 {
11502         struct triple *def, *left, *right;
11503         int tok, op, sign;
11504         /* The C grammer in K&R shows assignment expressions
11505          * only taking unary expressions as input on their
11506          * left hand side.  But specifies the precedence of
11507          * assignemnt as the lowest operator except for comma.
11508          *
11509          * Allowing conditional expressions on the left hand side
11510          * of an assignement results in a grammar that accepts
11511          * a larger set of statements than standard C.   As long
11512          * as the subset of the grammar that is standard C behaves
11513          * correctly this should cause no problems.
11514          * 
11515          * For the extra token strings accepted by the grammar
11516          * none of them should produce a valid lvalue, so they
11517          * should not produce functioning programs.
11518          *
11519          * GCC has this bug as well, so surprises should be minimal.
11520          */
11521         def = conditional_expr(state);
11522         left = def;
11523         switch((tok = peek(state))) {
11524         case TOK_EQ:
11525                 lvalue(state, left);
11526                 eat(state, TOK_EQ);
11527                 def = write_expr(state, left, 
11528                         read_expr(state, assignment_expr(state)));
11529                 break;
11530         case TOK_TIMESEQ:
11531         case TOK_DIVEQ:
11532         case TOK_MODEQ:
11533                 lvalue(state, left);
11534                 arithmetic(state, left);
11535                 eat(state, tok);
11536                 right = read_expr(state, assignment_expr(state));
11537                 arithmetic(state, right);
11538
11539                 sign = is_signed(left->type);
11540                 op = -1;
11541                 switch(tok) {
11542                 case TOK_TIMESEQ: op = sign? OP_SMUL : OP_UMUL; break;
11543                 case TOK_DIVEQ:   op = sign? OP_SDIV : OP_UDIV; break;
11544                 case TOK_MODEQ:   op = sign? OP_SMOD : OP_UMOD; break;
11545                 }
11546                 def = write_expr(state, left,
11547                         triple(state, op, left->type, 
11548                                 read_expr(state, left), right));
11549                 break;
11550         case TOK_PLUSEQ:
11551                 lvalue(state, left);
11552                 eat(state, TOK_PLUSEQ);
11553                 def = write_expr(state, left,
11554                         mk_add_expr(state, left, assignment_expr(state)));
11555                 break;
11556         case TOK_MINUSEQ:
11557                 lvalue(state, left);
11558                 eat(state, TOK_MINUSEQ);
11559                 def = write_expr(state, left,
11560                         mk_sub_expr(state, left, assignment_expr(state)));
11561                 break;
11562         case TOK_SLEQ:
11563         case TOK_SREQ:
11564         case TOK_ANDEQ:
11565         case TOK_XOREQ:
11566         case TOK_OREQ:
11567                 lvalue(state, left);
11568                 integral(state, left);
11569                 eat(state, tok);
11570                 right = read_expr(state, assignment_expr(state));
11571                 integral(state, right);
11572                 right = integral_promotion(state, right);
11573                 sign = is_signed(left->type);
11574                 op = -1;
11575                 switch(tok) {
11576                 case TOK_SLEQ:  op = OP_SL; break;
11577                 case TOK_SREQ:  op = sign? OP_SSR: OP_USR; break;
11578                 case TOK_ANDEQ: op = OP_AND; break;
11579                 case TOK_XOREQ: op = OP_XOR; break;
11580                 case TOK_OREQ:  op = OP_OR; break;
11581                 }
11582                 def = write_expr(state, left,
11583                         triple(state, op, left->type, 
11584                                 read_expr(state, left), right));
11585                 break;
11586         }
11587         return def;
11588 }
11589
11590 static struct triple *expr(struct compile_state *state)
11591 {
11592         struct triple *def;
11593         def = assignment_expr(state);
11594         while(peek(state) == TOK_COMMA) {
11595                 eat(state, TOK_COMMA);
11596                 def = mkprog(state, def, assignment_expr(state), 0UL);
11597         }
11598         return def;
11599 }
11600
11601 static void expr_statement(struct compile_state *state, struct triple *first)
11602 {
11603         if (peek(state) != TOK_SEMI) {
11604                 /* lvalue conversions always apply except when certian operators
11605                  * are applied.  I apply the lvalue conversions here
11606                  * as I know no more operators will be applied.
11607                  */
11608                 flatten(state, first, lvalue_conversion(state, expr(state)));
11609         }
11610         eat(state, TOK_SEMI);
11611 }
11612
11613 static void if_statement(struct compile_state *state, struct triple *first)
11614 {
11615         struct triple *test, *jmp1, *jmp2, *middle, *end;
11616
11617         jmp1 = jmp2 = middle = 0;
11618         eat(state, TOK_IF);
11619         eat(state, TOK_LPAREN);
11620         test = expr(state);
11621         bool(state, test);
11622         /* Cleanup and invert the test */
11623         test = lfalse_expr(state, read_expr(state, test));
11624         eat(state, TOK_RPAREN);
11625         /* Generate the needed pieces */
11626         middle = label(state);
11627         jmp1 = branch(state, middle, test);
11628         /* Thread the pieces together */
11629         flatten(state, first, test);
11630         flatten(state, first, jmp1);
11631         flatten(state, first, label(state));
11632         statement(state, first);
11633         if (peek(state) == TOK_ELSE) {
11634                 eat(state, TOK_ELSE);
11635                 /* Generate the rest of the pieces */
11636                 end = label(state);
11637                 jmp2 = branch(state, end, 0);
11638                 /* Thread them together */
11639                 flatten(state, first, jmp2);
11640                 flatten(state, first, middle);
11641                 statement(state, first);
11642                 flatten(state, first, end);
11643         }
11644         else {
11645                 flatten(state, first, middle);
11646         }
11647 }
11648
11649 static void for_statement(struct compile_state *state, struct triple *first)
11650 {
11651         struct triple *head, *test, *tail, *jmp1, *jmp2, *end;
11652         struct triple *label1, *label2, *label3;
11653         struct hash_entry *ident;
11654
11655         eat(state, TOK_FOR);
11656         eat(state, TOK_LPAREN);
11657         head = test = tail = jmp1 = jmp2 = 0;
11658         if (peek(state) != TOK_SEMI) {
11659                 head = expr(state);
11660         } 
11661         eat(state, TOK_SEMI);
11662         if (peek(state) != TOK_SEMI) {
11663                 test = expr(state);
11664                 bool(state, test);
11665                 test = ltrue_expr(state, read_expr(state, test));
11666         }
11667         eat(state, TOK_SEMI);
11668         if (peek(state) != TOK_RPAREN) {
11669                 tail = expr(state);
11670         }
11671         eat(state, TOK_RPAREN);
11672         /* Generate the needed pieces */
11673         label1 = label(state);
11674         label2 = label(state);
11675         label3 = label(state);
11676         if (test) {
11677                 jmp1 = branch(state, label3, 0);
11678                 jmp2 = branch(state, label1, test);
11679         }
11680         else {
11681                 jmp2 = branch(state, label1, 0);
11682         }
11683         end = label(state);
11684         /* Remember where break and continue go */
11685         start_scope(state);
11686         ident = state->i_break;
11687         symbol(state, ident, &ident->sym_ident, end, end->type);
11688         ident = state->i_continue;
11689         symbol(state, ident, &ident->sym_ident, label2, label2->type);
11690         /* Now include the body */
11691         flatten(state, first, head);
11692         flatten(state, first, jmp1);
11693         flatten(state, first, label1);
11694         statement(state, first);
11695         flatten(state, first, label2);
11696         flatten(state, first, tail);
11697         flatten(state, first, label3);
11698         flatten(state, first, test);
11699         flatten(state, first, jmp2);
11700         flatten(state, first, end);
11701         /* Cleanup the break/continue scope */
11702         end_scope(state);
11703 }
11704
11705 static void while_statement(struct compile_state *state, struct triple *first)
11706 {
11707         struct triple *label1, *test, *label2, *jmp1, *jmp2, *end;
11708         struct hash_entry *ident;
11709         eat(state, TOK_WHILE);
11710         eat(state, TOK_LPAREN);
11711         test = expr(state);
11712         bool(state, test);
11713         test = ltrue_expr(state, read_expr(state, test));
11714         eat(state, TOK_RPAREN);
11715         /* Generate the needed pieces */
11716         label1 = label(state);
11717         label2 = label(state);
11718         jmp1 = branch(state, label2, 0);
11719         jmp2 = branch(state, label1, test);
11720         end = label(state);
11721         /* Remember where break and continue go */
11722         start_scope(state);
11723         ident = state->i_break;
11724         symbol(state, ident, &ident->sym_ident, end, end->type);
11725         ident = state->i_continue;
11726         symbol(state, ident, &ident->sym_ident, label2, label2->type);
11727         /* Thread them together */
11728         flatten(state, first, jmp1);
11729         flatten(state, first, label1);
11730         statement(state, first);
11731         flatten(state, first, label2);
11732         flatten(state, first, test);
11733         flatten(state, first, jmp2);
11734         flatten(state, first, end);
11735         /* Cleanup the break/continue scope */
11736         end_scope(state);
11737 }
11738
11739 static void do_statement(struct compile_state *state, struct triple *first)
11740 {
11741         struct triple *label1, *label2, *test, *end;
11742         struct hash_entry *ident;
11743         eat(state, TOK_DO);
11744         /* Generate the needed pieces */
11745         label1 = label(state);
11746         label2 = label(state);
11747         end = label(state);
11748         /* Remember where break and continue go */
11749         start_scope(state);
11750         ident = state->i_break;
11751         symbol(state, ident, &ident->sym_ident, end, end->type);
11752         ident = state->i_continue;
11753         symbol(state, ident, &ident->sym_ident, label2, label2->type);
11754         /* Now include the body */
11755         flatten(state, first, label1);
11756         statement(state, first);
11757         /* Cleanup the break/continue scope */
11758         end_scope(state);
11759         /* Eat the rest of the loop */
11760         eat(state, TOK_WHILE);
11761         eat(state, TOK_LPAREN);
11762         test = read_expr(state, expr(state));
11763         bool(state, test);
11764         eat(state, TOK_RPAREN);
11765         eat(state, TOK_SEMI);
11766         /* Thread the pieces together */
11767         test = ltrue_expr(state, test);
11768         flatten(state, first, label2);
11769         flatten(state, first, test);
11770         flatten(state, first, branch(state, label1, test));
11771         flatten(state, first, end);
11772 }
11773
11774
11775 static void return_statement(struct compile_state *state, struct triple *first)
11776 {
11777         struct triple *jmp, *mv, *dest, *var, *val;
11778         int last;
11779         eat(state, TOK_RETURN);
11780
11781 #warning "FIXME implement a more general excess branch elimination"
11782         val = 0;
11783         /* If we have a return value do some more work */
11784         if (peek(state) != TOK_SEMI) {
11785                 val = read_expr(state, expr(state));
11786         }
11787         eat(state, TOK_SEMI);
11788
11789         /* See if this last statement in a function */
11790         last = ((peek(state) == TOK_RBRACE) && 
11791                 (state->scope_depth == GLOBAL_SCOPE_DEPTH +2));
11792
11793         /* Find the return variable */
11794         var = fresult(state, state->main_function);
11795
11796         /* Find the return destination */
11797         dest = state->i_return->sym_ident->def;
11798         mv = jmp = 0;
11799         /* If needed generate a jump instruction */
11800         if (!last) {
11801                 jmp = branch(state, dest, 0);
11802         }
11803         /* If needed generate an assignment instruction */
11804         if (val) {
11805                 mv = write_expr(state, deref_index(state, var, 1), val);
11806         }
11807         /* Now put the code together */
11808         if (mv) {
11809                 flatten(state, first, mv);
11810                 flatten(state, first, jmp);
11811         }
11812         else if (jmp) {
11813                 flatten(state, first, jmp);
11814         }
11815 }
11816
11817 static void break_statement(struct compile_state *state, struct triple *first)
11818 {
11819         struct triple *dest;
11820         eat(state, TOK_BREAK);
11821         eat(state, TOK_SEMI);
11822         if (!state->i_break->sym_ident) {
11823                 error(state, 0, "break statement not within loop or switch");
11824         }
11825         dest = state->i_break->sym_ident->def;
11826         flatten(state, first, branch(state, dest, 0));
11827 }
11828
11829 static void continue_statement(struct compile_state *state, struct triple *first)
11830 {
11831         struct triple *dest;
11832         eat(state, TOK_CONTINUE);
11833         eat(state, TOK_SEMI);
11834         if (!state->i_continue->sym_ident) {
11835                 error(state, 0, "continue statement outside of a loop");
11836         }
11837         dest = state->i_continue->sym_ident->def;
11838         flatten(state, first, branch(state, dest, 0));
11839 }
11840
11841 static void goto_statement(struct compile_state *state, struct triple *first)
11842 {
11843         struct hash_entry *ident;
11844         eat(state, TOK_GOTO);
11845         ident = eat(state, TOK_IDENT)->ident;
11846         if (!ident->sym_label) {
11847                 /* If this is a forward branch allocate the label now,
11848                  * it will be flattend in the appropriate location later.
11849                  */
11850                 struct triple *ins;
11851                 ins = label(state);
11852                 label_symbol(state, ident, ins, FUNCTION_SCOPE_DEPTH);
11853         }
11854         eat(state, TOK_SEMI);
11855
11856         flatten(state, first, branch(state, ident->sym_label->def, 0));
11857 }
11858
11859 static void labeled_statement(struct compile_state *state, struct triple *first)
11860 {
11861         struct triple *ins;
11862         struct hash_entry *ident;
11863
11864         ident = eat(state, TOK_IDENT)->ident;
11865         if (ident->sym_label && ident->sym_label->def) {
11866                 ins = ident->sym_label->def;
11867                 put_occurance(ins->occurance);
11868                 ins->occurance = new_occurance(state);
11869         }
11870         else {
11871                 ins = label(state);
11872                 label_symbol(state, ident, ins, FUNCTION_SCOPE_DEPTH);
11873         }
11874         if (ins->id & TRIPLE_FLAG_FLATTENED) {
11875                 error(state, 0, "label %s already defined", ident->name);
11876         }
11877         flatten(state, first, ins);
11878
11879         eat(state, TOK_COLON);
11880         statement(state, first);
11881 }
11882
11883 static void switch_statement(struct compile_state *state, struct triple *first)
11884 {
11885         struct triple *value, *top, *end, *dbranch;
11886         struct hash_entry *ident;
11887
11888         /* See if we have a valid switch statement */
11889         eat(state, TOK_SWITCH);
11890         eat(state, TOK_LPAREN);
11891         value = expr(state);
11892         integral(state, value);
11893         value = read_expr(state, value);
11894         eat(state, TOK_RPAREN);
11895         /* Generate the needed pieces */
11896         top = label(state);
11897         end = label(state);
11898         dbranch = branch(state, end, 0);
11899         /* Remember where case branches and break goes */
11900         start_scope(state);
11901         ident = state->i_switch;
11902         symbol(state, ident, &ident->sym_ident, value, value->type);
11903         ident = state->i_case;
11904         symbol(state, ident, &ident->sym_ident, top, top->type);
11905         ident = state->i_break;
11906         symbol(state, ident, &ident->sym_ident, end, end->type);
11907         ident = state->i_default;
11908         symbol(state, ident, &ident->sym_ident, dbranch, dbranch->type);
11909         /* Thread them together */
11910         flatten(state, first, value);
11911         flatten(state, first, top);
11912         flatten(state, first, dbranch);
11913         statement(state, first);
11914         flatten(state, first, end);
11915         /* Cleanup the switch scope */
11916         end_scope(state);
11917 }
11918
11919 static void case_statement(struct compile_state *state, struct triple *first)
11920 {
11921         struct triple *cvalue, *dest, *test, *jmp;
11922         struct triple *ptr, *value, *top, *dbranch;
11923
11924         /* See if w have a valid case statement */
11925         eat(state, TOK_CASE);
11926         cvalue = constant_expr(state);
11927         integral(state, cvalue);
11928         if (cvalue->op != OP_INTCONST) {
11929                 error(state, 0, "integer constant expected");
11930         }
11931         eat(state, TOK_COLON);
11932         if (!state->i_case->sym_ident) {
11933                 error(state, 0, "case statement not within a switch");
11934         }
11935
11936         /* Lookup the interesting pieces */
11937         top = state->i_case->sym_ident->def;
11938         value = state->i_switch->sym_ident->def;
11939         dbranch = state->i_default->sym_ident->def;
11940
11941         /* See if this case label has already been used */
11942         for(ptr = top; ptr != dbranch; ptr = ptr->next) {
11943                 if (ptr->op != OP_EQ) {
11944                         continue;
11945                 }
11946                 if (RHS(ptr, 1)->u.cval == cvalue->u.cval) {
11947                         error(state, 0, "duplicate case %d statement",
11948                                 cvalue->u.cval);
11949                 }
11950         }
11951         /* Generate the needed pieces */
11952         dest = label(state);
11953         test = triple(state, OP_EQ, &int_type, value, cvalue);
11954         jmp = branch(state, dest, test);
11955         /* Thread the pieces together */
11956         flatten(state, dbranch, test);
11957         flatten(state, dbranch, jmp);
11958         flatten(state, dbranch, label(state));
11959         flatten(state, first, dest);
11960         statement(state, first);
11961 }
11962
11963 static void default_statement(struct compile_state *state, struct triple *first)
11964 {
11965         struct triple *dest;
11966         struct triple *dbranch, *end;
11967
11968         /* See if we have a valid default statement */
11969         eat(state, TOK_DEFAULT);
11970         eat(state, TOK_COLON);
11971
11972         if (!state->i_case->sym_ident) {
11973                 error(state, 0, "default statement not within a switch");
11974         }
11975
11976         /* Lookup the interesting pieces */
11977         dbranch = state->i_default->sym_ident->def;
11978         end = state->i_break->sym_ident->def;
11979
11980         /* See if a default statement has already happened */
11981         if (TARG(dbranch, 0) != end) {
11982                 error(state, 0, "duplicate default statement");
11983         }
11984
11985         /* Generate the needed pieces */
11986         dest = label(state);
11987
11988         /* Blame the branch on the default statement */
11989         put_occurance(dbranch->occurance);
11990         dbranch->occurance = new_occurance(state);
11991
11992         /* Thread the pieces together */
11993         TARG(dbranch, 0) = dest;
11994         use_triple(dest, dbranch);
11995         flatten(state, first, dest);
11996         statement(state, first);
11997 }
11998
11999 static void asm_statement(struct compile_state *state, struct triple *first)
12000 {
12001         struct asm_info *info;
12002         struct {
12003                 struct triple *constraint;
12004                 struct triple *expr;
12005         } out_param[MAX_LHS], in_param[MAX_RHS], clob_param[MAX_LHS];
12006         struct triple *def, *asm_str;
12007         int out, in, clobbers, more, colons, i;
12008         int flags;
12009
12010         flags = 0;
12011         eat(state, TOK_ASM);
12012         /* For now ignore the qualifiers */
12013         switch(peek(state)) {
12014         case TOK_CONST:
12015                 eat(state, TOK_CONST);
12016                 break;
12017         case TOK_VOLATILE:
12018                 eat(state, TOK_VOLATILE);
12019                 flags |= TRIPLE_FLAG_VOLATILE;
12020                 break;
12021         }
12022         eat(state, TOK_LPAREN);
12023         asm_str = string_constant(state);
12024
12025         colons = 0;
12026         out = in = clobbers = 0;
12027         /* Outputs */
12028         if ((colons == 0) && (peek(state) == TOK_COLON)) {
12029                 eat(state, TOK_COLON);
12030                 colons++;
12031                 more = (peek(state) == TOK_LIT_STRING);
12032                 while(more) {
12033                         struct triple *var;
12034                         struct triple *constraint;
12035                         char *str;
12036                         more = 0;
12037                         if (out > MAX_LHS) {
12038                                 error(state, 0, "Maximum output count exceeded.");
12039                         }
12040                         constraint = string_constant(state);
12041                         str = constraint->u.blob;
12042                         if (str[0] != '=') {
12043                                 error(state, 0, "Output constraint does not start with =");
12044                         }
12045                         constraint->u.blob = str + 1;
12046                         eat(state, TOK_LPAREN);
12047                         var = conditional_expr(state);
12048                         eat(state, TOK_RPAREN);
12049
12050                         lvalue(state, var);
12051                         out_param[out].constraint = constraint;
12052                         out_param[out].expr       = var;
12053                         if (peek(state) == TOK_COMMA) {
12054                                 eat(state, TOK_COMMA);
12055                                 more = 1;
12056                         }
12057                         out++;
12058                 }
12059         }
12060         /* Inputs */
12061         if ((colons == 1) && (peek(state) == TOK_COLON)) {
12062                 eat(state, TOK_COLON);
12063                 colons++;
12064                 more = (peek(state) == TOK_LIT_STRING);
12065                 while(more) {
12066                         struct triple *val;
12067                         struct triple *constraint;
12068                         char *str;
12069                         more = 0;
12070                         if (in > MAX_RHS) {
12071                                 error(state, 0, "Maximum input count exceeded.");
12072                         }
12073                         constraint = string_constant(state);
12074                         str = constraint->u.blob;
12075                         if (digitp(str[0] && str[1] == '\0')) {
12076                                 int val;
12077                                 val = digval(str[0]);
12078                                 if ((val < 0) || (val >= out)) {
12079                                         error(state, 0, "Invalid input constraint %d", val);
12080                                 }
12081                         }
12082                         eat(state, TOK_LPAREN);
12083                         val = conditional_expr(state);
12084                         eat(state, TOK_RPAREN);
12085
12086                         in_param[in].constraint = constraint;
12087                         in_param[in].expr       = val;
12088                         if (peek(state) == TOK_COMMA) {
12089                                 eat(state, TOK_COMMA);
12090                                 more = 1;
12091                         }
12092                         in++;
12093                 }
12094         }
12095
12096         /* Clobber */
12097         if ((colons == 2) && (peek(state) == TOK_COLON)) {
12098                 eat(state, TOK_COLON);
12099                 colons++;
12100                 more = (peek(state) == TOK_LIT_STRING);
12101                 while(more) {
12102                         struct triple *clobber;
12103                         more = 0;
12104                         if ((clobbers + out) > MAX_LHS) {
12105                                 error(state, 0, "Maximum clobber limit exceeded.");
12106                         }
12107                         clobber = string_constant(state);
12108
12109                         clob_param[clobbers].constraint = clobber;
12110                         if (peek(state) == TOK_COMMA) {
12111                                 eat(state, TOK_COMMA);
12112                                 more = 1;
12113                         }
12114                         clobbers++;
12115                 }
12116         }
12117         eat(state, TOK_RPAREN);
12118         eat(state, TOK_SEMI);
12119
12120
12121         info = xcmalloc(sizeof(*info), "asm_info");
12122         info->str = asm_str->u.blob;
12123         free_triple(state, asm_str);
12124
12125         def = new_triple(state, OP_ASM, &void_type, clobbers + out, in);
12126         def->u.ainfo = info;
12127         def->id |= flags;
12128
12129         /* Find the register constraints */
12130         for(i = 0; i < out; i++) {
12131                 struct triple *constraint;
12132                 constraint = out_param[i].constraint;
12133                 info->tmpl.lhs[i] = arch_reg_constraint(state, 
12134                         out_param[i].expr->type, constraint->u.blob);
12135                 free_triple(state, constraint);
12136         }
12137         for(; i - out < clobbers; i++) {
12138                 struct triple *constraint;
12139                 constraint = clob_param[i - out].constraint;
12140                 info->tmpl.lhs[i] = arch_reg_clobber(state, constraint->u.blob);
12141                 free_triple(state, constraint);
12142         }
12143         for(i = 0; i < in; i++) {
12144                 struct triple *constraint;
12145                 const char *str;
12146                 constraint = in_param[i].constraint;
12147                 str = constraint->u.blob;
12148                 if (digitp(str[0]) && str[1] == '\0') {
12149                         struct reg_info cinfo;
12150                         int val;
12151                         val = digval(str[0]);
12152                         cinfo.reg = info->tmpl.lhs[val].reg;
12153                         cinfo.regcm = arch_type_to_regcm(state, in_param[i].expr->type);
12154                         cinfo.regcm &= info->tmpl.lhs[val].regcm;
12155                         if (cinfo.reg == REG_UNSET) {
12156                                 cinfo.reg = REG_VIRT0 + val;
12157                         }
12158                         if (cinfo.regcm == 0) {
12159                                 error(state, 0, "No registers for %d", val);
12160                         }
12161                         info->tmpl.lhs[val] = cinfo;
12162                         info->tmpl.rhs[i]   = cinfo;
12163                                 
12164                 } else {
12165                         info->tmpl.rhs[i] = arch_reg_constraint(state, 
12166                                 in_param[i].expr->type, str);
12167                 }
12168                 free_triple(state, constraint);
12169         }
12170
12171         /* Now build the helper expressions */
12172         for(i = 0; i < in; i++) {
12173                 RHS(def, i) = read_expr(state, in_param[i].expr);
12174         }
12175         flatten(state, first, def);
12176         for(i = 0; i < (out + clobbers); i++) {
12177                 struct type *type;
12178                 struct triple *piece;
12179                 if (i < out) {
12180                         type = out_param[i].expr->type;
12181                 } else {
12182                         size_t size = arch_reg_size(info->tmpl.lhs[i].reg);
12183                         if (size >= SIZEOF_LONG) {
12184                                 type = &ulong_type;
12185                         } 
12186                         else if (size >= SIZEOF_INT) {
12187                                 type = &uint_type;
12188                         }
12189                         else if (size >= SIZEOF_SHORT) {
12190                                 type = &ushort_type;
12191                         }
12192                         else {
12193                                 type = &uchar_type;
12194                         }
12195                 }
12196                 piece = triple(state, OP_PIECE, type, def, 0);
12197                 piece->u.cval = i;
12198                 LHS(def, i) = piece;
12199                 flatten(state, first, piece);
12200         }
12201         /* And write the helpers to their destinations */
12202         for(i = 0; i < out; i++) {
12203                 struct triple *piece;
12204                 piece = LHS(def, i);
12205                 flatten(state, first,
12206                         write_expr(state, out_param[i].expr, piece));
12207         }
12208 }
12209
12210
12211 static int isdecl(int tok)
12212 {
12213         switch(tok) {
12214         case TOK_AUTO:
12215         case TOK_REGISTER:
12216         case TOK_STATIC:
12217         case TOK_EXTERN:
12218         case TOK_TYPEDEF:
12219         case TOK_CONST:
12220         case TOK_RESTRICT:
12221         case TOK_VOLATILE:
12222         case TOK_VOID:
12223         case TOK_CHAR:
12224         case TOK_SHORT:
12225         case TOK_INT:
12226         case TOK_LONG:
12227         case TOK_FLOAT:
12228         case TOK_DOUBLE:
12229         case TOK_SIGNED:
12230         case TOK_UNSIGNED:
12231         case TOK_STRUCT:
12232         case TOK_UNION:
12233         case TOK_ENUM:
12234         case TOK_TYPE_NAME: /* typedef name */
12235                 return 1;
12236         default:
12237                 return 0;
12238         }
12239 }
12240
12241 static void compound_statement(struct compile_state *state, struct triple *first)
12242 {
12243         eat(state, TOK_LBRACE);
12244         start_scope(state);
12245
12246         /* statement-list opt */
12247         while (peek(state) != TOK_RBRACE) {
12248                 statement(state, first);
12249         }
12250         end_scope(state);
12251         eat(state, TOK_RBRACE);
12252 }
12253
12254 static void statement(struct compile_state *state, struct triple *first)
12255 {
12256         int tok;
12257         tok = peek(state);
12258         if (tok == TOK_LBRACE) {
12259                 compound_statement(state, first);
12260         }
12261         else if (tok == TOK_IF) {
12262                 if_statement(state, first); 
12263         }
12264         else if (tok == TOK_FOR) {
12265                 for_statement(state, first);
12266         }
12267         else if (tok == TOK_WHILE) {
12268                 while_statement(state, first);
12269         }
12270         else if (tok == TOK_DO) {
12271                 do_statement(state, first);
12272         }
12273         else if (tok == TOK_RETURN) {
12274                 return_statement(state, first);
12275         }
12276         else if (tok == TOK_BREAK) {
12277                 break_statement(state, first);
12278         }
12279         else if (tok == TOK_CONTINUE) {
12280                 continue_statement(state, first);
12281         }
12282         else if (tok == TOK_GOTO) {
12283                 goto_statement(state, first);
12284         }
12285         else if (tok == TOK_SWITCH) {
12286                 switch_statement(state, first);
12287         }
12288         else if (tok == TOK_ASM) {
12289                 asm_statement(state, first);
12290         }
12291         else if ((tok == TOK_IDENT) && (peek2(state) == TOK_COLON)) {
12292                 labeled_statement(state, first); 
12293         }
12294         else if (tok == TOK_CASE) {
12295                 case_statement(state, first);
12296         }
12297         else if (tok == TOK_DEFAULT) {
12298                 default_statement(state, first);
12299         }
12300         else if (isdecl(tok)) {
12301                 /* This handles C99 intermixing of statements and decls */
12302                 decl(state, first);
12303         }
12304         else {
12305                 expr_statement(state, first);
12306         }
12307 }
12308
12309 static struct type *param_decl(struct compile_state *state)
12310 {
12311         struct type *type;
12312         struct hash_entry *ident;
12313         /* Cheat so the declarator will know we are not global */
12314         start_scope(state); 
12315         ident = 0;
12316         type = decl_specifiers(state);
12317         type = declarator(state, type, &ident, 0);
12318         type->field_ident = ident;
12319         end_scope(state);
12320         return type;
12321 }
12322
12323 static struct type *param_type_list(struct compile_state *state, struct type *type)
12324 {
12325         struct type *ftype, **next;
12326         ftype = new_type(TYPE_FUNCTION | (type->type & STOR_MASK), type, param_decl(state));
12327         next = &ftype->right;
12328         ftype->elements = 1;
12329         while(peek(state) == TOK_COMMA) {
12330                 eat(state, TOK_COMMA);
12331                 if (peek(state) == TOK_DOTS) {
12332                         eat(state, TOK_DOTS);
12333                         error(state, 0, "variadic functions not supported");
12334                 }
12335                 else {
12336                         *next = new_type(TYPE_PRODUCT, *next, param_decl(state));
12337                         next = &((*next)->right);
12338                         ftype->elements++;
12339                 }
12340         }
12341         return ftype;
12342 }
12343
12344 static struct type *type_name(struct compile_state *state)
12345 {
12346         struct type *type;
12347         type = specifier_qualifier_list(state);
12348         /* abstract-declarator (may consume no tokens) */
12349         type = declarator(state, type, 0, 0);
12350         return type;
12351 }
12352
12353 static struct type *direct_declarator(
12354         struct compile_state *state, struct type *type, 
12355         struct hash_entry **pident, int need_ident)
12356 {
12357         struct hash_entry *ident;
12358         struct type *outer;
12359         int op;
12360         outer = 0;
12361         arrays_complete(state, type);
12362         switch(peek(state)) {
12363         case TOK_IDENT:
12364                 ident = eat(state, TOK_IDENT)->ident;
12365                 if (!ident) {
12366                         error(state, 0, "Unexpected identifier found");
12367                 }
12368                 /* The name of what we are declaring */
12369                 *pident = ident;
12370                 break;
12371         case TOK_LPAREN:
12372                 eat(state, TOK_LPAREN);
12373                 outer = declarator(state, type, pident, need_ident);
12374                 eat(state, TOK_RPAREN);
12375                 break;
12376         default:
12377                 if (need_ident) {
12378                         error(state, 0, "Identifier expected");
12379                 }
12380                 break;
12381         }
12382         do {
12383                 op = 1;
12384                 arrays_complete(state, type);
12385                 switch(peek(state)) {
12386                 case TOK_LPAREN:
12387                         eat(state, TOK_LPAREN);
12388                         type = param_type_list(state, type);
12389                         eat(state, TOK_RPAREN);
12390                         break;
12391                 case TOK_LBRACKET:
12392                 {
12393                         unsigned int qualifiers;
12394                         struct triple *value;
12395                         value = 0;
12396                         eat(state, TOK_LBRACKET);
12397                         if (peek(state) != TOK_RBRACKET) {
12398                                 value = constant_expr(state);
12399                                 integral(state, value);
12400                         }
12401                         eat(state, TOK_RBRACKET);
12402
12403                         qualifiers = type->type & (QUAL_MASK | STOR_MASK);
12404                         type = new_type(TYPE_ARRAY | qualifiers, type, 0);
12405                         if (value) {
12406                                 type->elements = value->u.cval;
12407                                 free_triple(state, value);
12408                         } else {
12409                                 type->elements = ELEMENT_COUNT_UNSPECIFIED;
12410                                 op = 0;
12411                         }
12412                 }
12413                         break;
12414                 default:
12415                         op = 0;
12416                         break;
12417                 }
12418         } while(op);
12419         if (outer) {
12420                 struct type *inner;
12421                 arrays_complete(state, type);
12422                 FINISHME();
12423                 for(inner = outer; inner->left; inner = inner->left)
12424                         ;
12425                 inner->left = type;
12426                 type = outer;
12427         }
12428         return type;
12429 }
12430
12431 static struct type *declarator(
12432         struct compile_state *state, struct type *type, 
12433         struct hash_entry **pident, int need_ident)
12434 {
12435         while(peek(state) == TOK_STAR) {
12436                 eat(state, TOK_STAR);
12437                 type = new_type(TYPE_POINTER | (type->type & STOR_MASK), type, 0);
12438         }
12439         type = direct_declarator(state, type, pident, need_ident);
12440         return type;
12441 }
12442
12443 static struct type *typedef_name(
12444         struct compile_state *state, unsigned int specifiers)
12445 {
12446         struct hash_entry *ident;
12447         struct type *type;
12448         ident = eat(state, TOK_TYPE_NAME)->ident;
12449         type = ident->sym_ident->type;
12450         specifiers |= type->type & QUAL_MASK;
12451         if ((specifiers & (STOR_MASK | QUAL_MASK)) != 
12452                 (type->type & (STOR_MASK | QUAL_MASK))) {
12453                 type = clone_type(specifiers, type);
12454         }
12455         return type;
12456 }
12457
12458 static struct type *enum_specifier(
12459         struct compile_state *state, unsigned int spec)
12460 {
12461         struct hash_entry *ident;
12462         ulong_t base;
12463         int tok;
12464         struct type *enum_type;
12465         enum_type = 0;
12466         ident = 0;
12467         eat(state, TOK_ENUM);
12468         tok = peek(state);
12469         if ((tok == TOK_IDENT) || (tok == TOK_ENUM_CONST) || (tok == TOK_TYPE_NAME)) {
12470                 ident = eat(state, tok)->ident;
12471         }
12472         base = 0;
12473         if (!ident || (peek(state) == TOK_LBRACE)) {
12474                 struct type **next;
12475                 eat(state, TOK_LBRACE);
12476                 enum_type = new_type(TYPE_ENUM | spec, 0, 0);
12477                 enum_type->type_ident = ident;
12478                 next = &enum_type->right;
12479                 do {
12480                         struct hash_entry *eident;
12481                         struct triple *value;
12482                         struct type *entry;
12483                         eident = eat(state, TOK_IDENT)->ident;
12484                         if (eident->sym_ident) {
12485                                 error(state, 0, "%s already declared", 
12486                                         eident->name);
12487                         }
12488                         eident->tok = TOK_ENUM_CONST;
12489                         if (peek(state) == TOK_EQ) {
12490                                 struct triple *val;
12491                                 eat(state, TOK_EQ);
12492                                 val = constant_expr(state);
12493                                 integral(state, val);
12494                                 base = val->u.cval;
12495                         }
12496                         value = int_const(state, &int_type, base);
12497                         symbol(state, eident, &eident->sym_ident, value, &int_type);
12498                         entry = new_type(TYPE_LIST, 0, 0);
12499                         entry->field_ident = eident;
12500                         *next = entry;
12501                         next = &entry->right;
12502                         base += 1;
12503                         if (peek(state) == TOK_COMMA) {
12504                                 eat(state, TOK_COMMA);
12505                         }
12506                 } while(peek(state) != TOK_RBRACE);
12507                 eat(state, TOK_RBRACE);
12508                 if (ident) {
12509                         symbol(state, ident, &ident->sym_tag, 0, enum_type);
12510                 }
12511         }
12512         if (ident && ident->sym_tag &&
12513                 ident->sym_tag->type &&
12514                 ((ident->sym_tag->type->type & TYPE_MASK) == TYPE_ENUM)) {
12515                 enum_type = clone_type(spec, ident->sym_tag->type);
12516         }
12517         else if (ident && !enum_type) {
12518                 error(state, 0, "enum %s undeclared", ident->name);
12519         }
12520         return enum_type;
12521 }
12522
12523 static struct type *struct_declarator(
12524         struct compile_state *state, struct type *type, struct hash_entry **ident)
12525 {
12526         if (peek(state) != TOK_COLON) {
12527                 type = declarator(state, type, ident, 1);
12528         }
12529         if (peek(state) == TOK_COLON) {
12530                 struct triple *value;
12531                 eat(state, TOK_COLON);
12532                 value = constant_expr(state);
12533                 if (value->op != OP_INTCONST) {
12534                         error(state, 0, "Invalid constant expression");
12535                 }
12536                 if (value->u.cval > size_of(state, type)) {
12537                         error(state, 0, "bitfield larger than base type");
12538                 }
12539                 if (!TYPE_INTEGER(type->type) || ((type->type & TYPE_MASK) == TYPE_BITFIELD)) {
12540                         error(state, 0, "bitfield base not an integer type");
12541                 }
12542                 type = new_type(TYPE_BITFIELD, type, 0);
12543                 type->elements = value->u.cval;
12544         }
12545         return type;
12546 }
12547
12548 static struct type *struct_or_union_specifier(
12549         struct compile_state *state, unsigned int spec)
12550 {
12551         struct type *struct_type;
12552         struct hash_entry *ident;
12553         unsigned int type_main;
12554         unsigned int type_join;
12555         int tok;
12556         struct_type = 0;
12557         ident = 0;
12558         switch(peek(state)) {
12559         case TOK_STRUCT:
12560                 eat(state, TOK_STRUCT);
12561                 type_main = TYPE_STRUCT;
12562                 type_join = TYPE_PRODUCT;
12563                 break;
12564         case TOK_UNION:
12565                 eat(state, TOK_UNION);
12566                 type_main = TYPE_UNION;
12567                 type_join = TYPE_OVERLAP;
12568                 break;
12569         default:
12570                 eat(state, TOK_STRUCT);
12571                 type_main = TYPE_STRUCT;
12572                 type_join = TYPE_PRODUCT;
12573                 break;
12574         }
12575         tok = peek(state);
12576         if ((tok == TOK_IDENT) || (tok == TOK_ENUM_CONST) || (tok == TOK_TYPE_NAME)) {
12577                 ident = eat(state, tok)->ident;
12578         }
12579         if (!ident || (peek(state) == TOK_LBRACE)) {
12580                 ulong_t elements;
12581                 struct type **next;
12582                 elements = 0;
12583                 eat(state, TOK_LBRACE);
12584                 next = &struct_type;
12585                 do {
12586                         struct type *base_type;
12587                         int done;
12588                         base_type = specifier_qualifier_list(state);
12589                         do {
12590                                 struct type *type;
12591                                 struct hash_entry *fident;
12592                                 done = 1;
12593                                 type = struct_declarator(state, base_type, &fident);
12594                                 elements++;
12595                                 if (peek(state) == TOK_COMMA) {
12596                                         done = 0;
12597                                         eat(state, TOK_COMMA);
12598                                 }
12599                                 type = clone_type(0, type);
12600                                 type->field_ident = fident;
12601                                 if (*next) {
12602                                         *next = new_type(type_join, *next, type);
12603                                         next = &((*next)->right);
12604                                 } else {
12605                                         *next = type;
12606                                 }
12607                         } while(!done);
12608                         eat(state, TOK_SEMI);
12609                 } while(peek(state) != TOK_RBRACE);
12610                 eat(state, TOK_RBRACE);
12611                 struct_type = new_type(type_main | spec, struct_type, 0);
12612                 struct_type->type_ident = ident;
12613                 struct_type->elements = elements;
12614                 if (ident) {
12615                         symbol(state, ident, &ident->sym_tag, 0, struct_type);
12616                 }
12617         }
12618         if (ident && ident->sym_tag && 
12619                 ident->sym_tag->type && 
12620                 ((ident->sym_tag->type->type & TYPE_MASK) == type_main)) {
12621                 struct_type = clone_type(spec, ident->sym_tag->type);
12622         }
12623         else if (ident && !struct_type) {
12624                 error(state, 0, "%s %s undeclared", 
12625                         (type_main == TYPE_STRUCT)?"struct" : "union",
12626                         ident->name);
12627         }
12628         return struct_type;
12629 }
12630
12631 static unsigned int storage_class_specifier_opt(struct compile_state *state)
12632 {
12633         unsigned int specifiers;
12634         switch(peek(state)) {
12635         case TOK_AUTO:
12636                 eat(state, TOK_AUTO);
12637                 specifiers = STOR_AUTO;
12638                 break;
12639         case TOK_REGISTER:
12640                 eat(state, TOK_REGISTER);
12641                 specifiers = STOR_REGISTER;
12642                 break;
12643         case TOK_STATIC:
12644                 eat(state, TOK_STATIC);
12645                 specifiers = STOR_STATIC;
12646                 break;
12647         case TOK_EXTERN:
12648                 eat(state, TOK_EXTERN);
12649                 specifiers = STOR_EXTERN;
12650                 break;
12651         case TOK_TYPEDEF:
12652                 eat(state, TOK_TYPEDEF);
12653                 specifiers = STOR_TYPEDEF;
12654                 break;
12655         default:
12656                 if (state->scope_depth <= GLOBAL_SCOPE_DEPTH) {
12657                         specifiers = STOR_LOCAL;
12658                 }
12659                 else {
12660                         specifiers = STOR_AUTO;
12661                 }
12662         }
12663         return specifiers;
12664 }
12665
12666 static unsigned int function_specifier_opt(struct compile_state *state)
12667 {
12668         /* Ignore the inline keyword */
12669         unsigned int specifiers;
12670         specifiers = 0;
12671         switch(peek(state)) {
12672         case TOK_INLINE:
12673                 eat(state, TOK_INLINE);
12674                 specifiers = STOR_INLINE;
12675         }
12676         return specifiers;
12677 }
12678
12679 static unsigned int attrib(struct compile_state *state, unsigned int attributes)
12680 {
12681         int tok = peek(state);
12682         switch(tok) {
12683         case TOK_COMMA:
12684         case TOK_LPAREN:
12685                 /* The empty attribute ignore it */
12686                 break;
12687         case TOK_IDENT:
12688         case TOK_ENUM_CONST:
12689         case TOK_TYPE_NAME:
12690         {
12691                 struct hash_entry *ident;
12692                 ident = eat(state, TOK_IDENT)->ident;
12693
12694                 if (ident == state->i_noinline) {
12695                         if (attributes & ATTRIB_ALWAYS_INLINE) {
12696                                 error(state, 0, "both always_inline and noinline attribtes");
12697                         }
12698                         attributes |= ATTRIB_NOINLINE;
12699                 }
12700                 else if (ident == state->i_always_inline) {
12701                         if (attributes & ATTRIB_NOINLINE) {
12702                                 error(state, 0, "both noinline and always_inline attribtes");
12703                         }
12704                         attributes |= ATTRIB_ALWAYS_INLINE;
12705                 }
12706                 else {
12707                         error(state, 0, "Unknown attribute:%s", ident->name);
12708                 }
12709                 break;
12710         }
12711         default:
12712                 error(state, 0, "Unexpected token: %s\n", tokens[tok]);
12713                 break;
12714         }
12715         return attributes;
12716 }
12717
12718 static unsigned int attribute_list(struct compile_state *state, unsigned type)
12719 {
12720         type = attrib(state, type);
12721         while(peek(state) == TOK_COMMA) {
12722                 eat(state, TOK_COMMA);
12723                 type = attrib(state, type);
12724         }
12725         return type;
12726 }
12727
12728 static unsigned int attributes_opt(struct compile_state *state, unsigned type)
12729 {
12730         if (peek(state) == TOK_ATTRIBUTE) {
12731                 eat(state, TOK_ATTRIBUTE);
12732                 eat(state, TOK_LPAREN);
12733                 eat(state, TOK_LPAREN);
12734                 type = attribute_list(state, type);
12735                 eat(state, TOK_RPAREN);
12736                 eat(state, TOK_RPAREN);
12737         }
12738         return type;
12739 }
12740
12741 static unsigned int type_qualifiers(struct compile_state *state)
12742 {
12743         unsigned int specifiers;
12744         int done;
12745         done = 0;
12746         specifiers = QUAL_NONE;
12747         do {
12748                 switch(peek(state)) {
12749                 case TOK_CONST:
12750                         eat(state, TOK_CONST);
12751                         specifiers |= QUAL_CONST;
12752                         break;
12753                 case TOK_VOLATILE:
12754                         eat(state, TOK_VOLATILE);
12755                         specifiers |= QUAL_VOLATILE;
12756                         break;
12757                 case TOK_RESTRICT:
12758                         eat(state, TOK_RESTRICT);
12759                         specifiers |= QUAL_RESTRICT;
12760                         break;
12761                 default:
12762                         done = 1;
12763                         break;
12764                 }
12765         } while(!done);
12766         return specifiers;
12767 }
12768
12769 static struct type *type_specifier(
12770         struct compile_state *state, unsigned int spec)
12771 {
12772         struct type *type;
12773         int tok;
12774         type = 0;
12775         switch((tok = peek(state))) {
12776         case TOK_VOID:
12777                 eat(state, TOK_VOID);
12778                 type = new_type(TYPE_VOID | spec, 0, 0);
12779                 break;
12780         case TOK_CHAR:
12781                 eat(state, TOK_CHAR);
12782                 type = new_type(TYPE_CHAR | spec, 0, 0);
12783                 break;
12784         case TOK_SHORT:
12785                 eat(state, TOK_SHORT);
12786                 if (peek(state) == TOK_INT) {
12787                         eat(state, TOK_INT);
12788                 }
12789                 type = new_type(TYPE_SHORT | spec, 0, 0);
12790                 break;
12791         case TOK_INT:
12792                 eat(state, TOK_INT);
12793                 type = new_type(TYPE_INT | spec, 0, 0);
12794                 break;
12795         case TOK_LONG:
12796                 eat(state, TOK_LONG);
12797                 switch(peek(state)) {
12798                 case TOK_LONG:
12799                         eat(state, TOK_LONG);
12800                         error(state, 0, "long long not supported");
12801                         break;
12802                 case TOK_DOUBLE:
12803                         eat(state, TOK_DOUBLE);
12804                         error(state, 0, "long double not supported");
12805                         break;
12806                 case TOK_INT:
12807                         eat(state, TOK_INT);
12808                         type = new_type(TYPE_LONG | spec, 0, 0);
12809                         break;
12810                 default:
12811                         type = new_type(TYPE_LONG | spec, 0, 0);
12812                         break;
12813                 }
12814                 break;
12815         case TOK_FLOAT:
12816                 eat(state, TOK_FLOAT);
12817                 error(state, 0, "type float not supported");
12818                 break;
12819         case TOK_DOUBLE:
12820                 eat(state, TOK_DOUBLE);
12821                 error(state, 0, "type double not supported");
12822                 break;
12823         case TOK_SIGNED:
12824                 eat(state, TOK_SIGNED);
12825                 switch(peek(state)) {
12826                 case TOK_LONG:
12827                         eat(state, TOK_LONG);
12828                         switch(peek(state)) {
12829                         case TOK_LONG:
12830                                 eat(state, TOK_LONG);
12831                                 error(state, 0, "type long long not supported");
12832                                 break;
12833                         case TOK_INT:
12834                                 eat(state, TOK_INT);
12835                                 type = new_type(TYPE_LONG | spec, 0, 0);
12836                                 break;
12837                         default:
12838                                 type = new_type(TYPE_LONG | spec, 0, 0);
12839                                 break;
12840                         }
12841                         break;
12842                 case TOK_INT:
12843                         eat(state, TOK_INT);
12844                         type = new_type(TYPE_INT | spec, 0, 0);
12845                         break;
12846                 case TOK_SHORT:
12847                         eat(state, TOK_SHORT);
12848                         type = new_type(TYPE_SHORT | spec, 0, 0);
12849                         break;
12850                 case TOK_CHAR:
12851                         eat(state, TOK_CHAR);
12852                         type = new_type(TYPE_CHAR | spec, 0, 0);
12853                         break;
12854                 default:
12855                         type = new_type(TYPE_INT | spec, 0, 0);
12856                         break;
12857                 }
12858                 break;
12859         case TOK_UNSIGNED:
12860                 eat(state, TOK_UNSIGNED);
12861                 switch(peek(state)) {
12862                 case TOK_LONG:
12863                         eat(state, TOK_LONG);
12864                         switch(peek(state)) {
12865                         case TOK_LONG:
12866                                 eat(state, TOK_LONG);
12867                                 error(state, 0, "unsigned long long not supported");
12868                                 break;
12869                         case TOK_INT:
12870                                 eat(state, TOK_INT);
12871                                 type = new_type(TYPE_ULONG | spec, 0, 0);
12872                                 break;
12873                         default:
12874                                 type = new_type(TYPE_ULONG | spec, 0, 0);
12875                                 break;
12876                         }
12877                         break;
12878                 case TOK_INT:
12879                         eat(state, TOK_INT);
12880                         type = new_type(TYPE_UINT | spec, 0, 0);
12881                         break;
12882                 case TOK_SHORT:
12883                         eat(state, TOK_SHORT);
12884                         type = new_type(TYPE_USHORT | spec, 0, 0);
12885                         break;
12886                 case TOK_CHAR:
12887                         eat(state, TOK_CHAR);
12888                         type = new_type(TYPE_UCHAR | spec, 0, 0);
12889                         break;
12890                 default:
12891                         type = new_type(TYPE_UINT | spec, 0, 0);
12892                         break;
12893                 }
12894                 break;
12895                 /* struct or union specifier */
12896         case TOK_STRUCT:
12897         case TOK_UNION:
12898                 type = struct_or_union_specifier(state, spec);
12899                 break;
12900                 /* enum-spefifier */
12901         case TOK_ENUM:
12902                 type = enum_specifier(state, spec);
12903                 break;
12904                 /* typedef name */
12905         case TOK_TYPE_NAME:
12906                 type = typedef_name(state, spec);
12907                 break;
12908         default:
12909                 error(state, 0, "bad type specifier %s", 
12910                         tokens[tok]);
12911                 break;
12912         }
12913         return type;
12914 }
12915
12916 static int istype(int tok)
12917 {
12918         switch(tok) {
12919         case TOK_CONST:
12920         case TOK_RESTRICT:
12921         case TOK_VOLATILE:
12922         case TOK_VOID:
12923         case TOK_CHAR:
12924         case TOK_SHORT:
12925         case TOK_INT:
12926         case TOK_LONG:
12927         case TOK_FLOAT:
12928         case TOK_DOUBLE:
12929         case TOK_SIGNED:
12930         case TOK_UNSIGNED:
12931         case TOK_STRUCT:
12932         case TOK_UNION:
12933         case TOK_ENUM:
12934         case TOK_TYPE_NAME:
12935                 return 1;
12936         default:
12937                 return 0;
12938         }
12939 }
12940
12941
12942 static struct type *specifier_qualifier_list(struct compile_state *state)
12943 {
12944         struct type *type;
12945         unsigned int specifiers = 0;
12946
12947         /* type qualifiers */
12948         specifiers |= type_qualifiers(state);
12949
12950         /* type specifier */
12951         type = type_specifier(state, specifiers);
12952
12953         return type;
12954 }
12955
12956 static int isdecl_specifier(int tok)
12957 {
12958         switch(tok) {
12959                 /* storage class specifier */
12960         case TOK_AUTO:
12961         case TOK_REGISTER:
12962         case TOK_STATIC:
12963         case TOK_EXTERN:
12964         case TOK_TYPEDEF:
12965                 /* type qualifier */
12966         case TOK_CONST:
12967         case TOK_RESTRICT:
12968         case TOK_VOLATILE:
12969                 /* type specifiers */
12970         case TOK_VOID:
12971         case TOK_CHAR:
12972         case TOK_SHORT:
12973         case TOK_INT:
12974         case TOK_LONG:
12975         case TOK_FLOAT:
12976         case TOK_DOUBLE:
12977         case TOK_SIGNED:
12978         case TOK_UNSIGNED:
12979                 /* struct or union specifier */
12980         case TOK_STRUCT:
12981         case TOK_UNION:
12982                 /* enum-spefifier */
12983         case TOK_ENUM:
12984                 /* typedef name */
12985         case TOK_TYPE_NAME:
12986                 /* function specifiers */
12987         case TOK_INLINE:
12988                 return 1;
12989         default:
12990                 return 0;
12991         }
12992 }
12993
12994 static struct type *decl_specifiers(struct compile_state *state)
12995 {
12996         struct type *type;
12997         unsigned int specifiers;
12998         /* I am overly restrictive in the arragement of specifiers supported.
12999          * C is overly flexible in this department it makes interpreting
13000          * the parse tree difficult.
13001          */
13002         specifiers = 0;
13003
13004         /* storage class specifier */
13005         specifiers |= storage_class_specifier_opt(state);
13006
13007         /* function-specifier */
13008         specifiers |= function_specifier_opt(state);
13009
13010         /* attributes */
13011         specifiers |= attributes_opt(state, 0);
13012
13013         /* type qualifier */
13014         specifiers |= type_qualifiers(state);
13015
13016         /* type specifier */
13017         type = type_specifier(state, specifiers);
13018         return type;
13019 }
13020
13021 struct field_info {
13022         struct type *type;
13023         size_t offset;
13024 };
13025
13026 static struct field_info designator(struct compile_state *state, struct type *type)
13027 {
13028         int tok;
13029         struct field_info info;
13030         info.offset = ~0U;
13031         info.type = 0;
13032         do {
13033                 switch(peek(state)) {
13034                 case TOK_LBRACKET:
13035                 {
13036                         struct triple *value;
13037                         if ((type->type & TYPE_MASK) != TYPE_ARRAY) {
13038                                 error(state, 0, "Array designator not in array initializer");
13039                         }
13040                         eat(state, TOK_LBRACKET);
13041                         value = constant_expr(state);
13042                         eat(state, TOK_RBRACKET);
13043
13044                         info.type = type->left;
13045                         info.offset = value->u.cval * size_of(state, info.type);
13046                         break;
13047                 }
13048                 case TOK_DOT:
13049                 {
13050                         struct hash_entry *field;
13051                         if (((type->type & TYPE_MASK) != TYPE_STRUCT) &&
13052                                 ((type->type & TYPE_MASK) != TYPE_UNION))
13053                         {
13054                                 error(state, 0, "Struct designator not in struct initializer");
13055                         }
13056                         eat(state, TOK_DOT);
13057                         field = eat(state, TOK_IDENT)->ident;
13058                         info.offset = field_offset(state, type, field);
13059                         info.type   = field_type(state, type, field);
13060                         break;
13061                 }
13062                 default:
13063                         error(state, 0, "Invalid designator");
13064                 }
13065                 tok = peek(state);
13066         } while((tok == TOK_LBRACKET) || (tok == TOK_DOT));
13067         eat(state, TOK_EQ);
13068         return info;
13069 }
13070
13071 static struct triple *initializer(
13072         struct compile_state *state, struct type *type)
13073 {
13074         struct triple *result;
13075 #warning "FIXME more consistent initializer handling (where should eval_const_expr go?"
13076         if (peek(state) != TOK_LBRACE) {
13077                 result = assignment_expr(state);
13078                 if (((type->type & TYPE_MASK) == TYPE_ARRAY) &&
13079                         (type->elements == ELEMENT_COUNT_UNSPECIFIED) &&
13080                         ((result->type->type & TYPE_MASK) == TYPE_ARRAY) &&
13081                         (result->type->elements != ELEMENT_COUNT_UNSPECIFIED) &&
13082                         (equiv_types(type->left, result->type->left))) {
13083                         type->elements = result->type->elements;
13084                 }
13085                 if (is_lvalue(state, result) && 
13086                         ((result->type->type & TYPE_MASK) == TYPE_ARRAY) &&
13087                         (type->type & TYPE_MASK) != TYPE_ARRAY)
13088                 {
13089                         result = lvalue_conversion(state, result);
13090                 }
13091                 if (!is_init_compatible(state, type, result->type)) {
13092                         error(state, 0, "Incompatible types in initializer");
13093                 }
13094                 if (!equiv_types(type, result->type)) {
13095                         result = mk_cast_expr(state, type, result);
13096                 }
13097         }
13098         else {
13099                 int comma;
13100                 size_t max_offset;
13101                 struct field_info info;
13102                 void *buf;
13103                 if (((type->type & TYPE_MASK) != TYPE_ARRAY) &&
13104                         ((type->type & TYPE_MASK) != TYPE_STRUCT)) {
13105                         internal_error(state, 0, "unknown initializer type");
13106                 }
13107                 info.offset = 0;
13108                 info.type = type->left;
13109                 if ((type->type & TYPE_MASK) == TYPE_STRUCT) {
13110                         info.type = next_field(state, type, 0);
13111                 }
13112                 if (type->elements == ELEMENT_COUNT_UNSPECIFIED) {
13113                         max_offset = 0;
13114                 } else {
13115                         max_offset = size_of(state, type);
13116                 }
13117                 buf = xcmalloc(bits_to_bytes(max_offset), "initializer");
13118                 eat(state, TOK_LBRACE);
13119                 do {
13120                         struct triple *value;
13121                         struct type *value_type;
13122                         size_t value_size;
13123                         void *dest;
13124                         int tok;
13125                         comma = 0;
13126                         tok = peek(state);
13127                         if ((tok == TOK_LBRACKET) || (tok == TOK_DOT)) {
13128                                 info = designator(state, type);
13129                         }
13130                         if ((type->elements != ELEMENT_COUNT_UNSPECIFIED) &&
13131                                 (info.offset >= max_offset)) {
13132                                 error(state, 0, "element beyond bounds");
13133                         }
13134                         value_type = info.type;
13135                         value = eval_const_expr(state, initializer(state, value_type));
13136                         value_size = size_of(state, value_type);
13137                         if (((type->type & TYPE_MASK) == TYPE_ARRAY) &&
13138                                 (type->elements == ELEMENT_COUNT_UNSPECIFIED) &&
13139                                 (max_offset <= info.offset)) {
13140                                 void *old_buf;
13141                                 size_t old_size;
13142                                 old_buf = buf;
13143                                 old_size = max_offset;
13144                                 max_offset = info.offset + value_size;
13145                                 buf = xmalloc(bits_to_bytes(max_offset), "initializer");
13146                                 memcpy(buf, old_buf, bits_to_bytes(old_size));
13147                                 xfree(old_buf);
13148                         }
13149                         dest = ((char *)buf) + bits_to_bytes(info.offset);
13150 #if DEBUG_INITIALIZER
13151                         fprintf(state->errout, "dest = buf + %d max_offset: %d value_size: %d op: %d\n", 
13152                                 dest - buf,
13153                                 bits_to_bytes(max_offset),
13154                                 bits_to_bytes(value_size),
13155                                 value->op);
13156 #endif
13157                         if (value->op == OP_BLOBCONST) {
13158                                 memcpy(dest, value->u.blob, bits_to_bytes(value_size));
13159                         }
13160                         else if ((value->op == OP_INTCONST) && (value_size == SIZEOF_I8)) {
13161 #if DEBUG_INITIALIZER
13162                                 fprintf(state->errout, "byte: %02x\n", value->u.cval & 0xff);
13163 #endif
13164                                 *((uint8_t *)dest) = value->u.cval & 0xff;
13165                         }
13166                         else if ((value->op == OP_INTCONST) && (value_size == SIZEOF_I16)) {
13167                                 *((uint16_t *)dest) = value->u.cval & 0xffff;
13168                         }
13169                         else if ((value->op == OP_INTCONST) && (value_size == SIZEOF_I32)) {
13170                                 *((uint32_t *)dest) = value->u.cval & 0xffffffff;
13171                         }
13172                         else {
13173                                 internal_error(state, 0, "unhandled constant initializer");
13174                         }
13175                         free_triple(state, value);
13176                         if (peek(state) == TOK_COMMA) {
13177                                 eat(state, TOK_COMMA);
13178                                 comma = 1;
13179                         }
13180                         info.offset += value_size;
13181                         if ((type->type & TYPE_MASK) == TYPE_STRUCT) {
13182                                 info.type = next_field(state, type, info.type);
13183                                 info.offset = field_offset(state, type, 
13184                                         info.type->field_ident);
13185                         }
13186                 } while(comma && (peek(state) != TOK_RBRACE));
13187                 if ((type->elements == ELEMENT_COUNT_UNSPECIFIED) &&
13188                         ((type->type & TYPE_MASK) == TYPE_ARRAY)) {
13189                         type->elements = max_offset / size_of(state, type->left);
13190                 }
13191                 eat(state, TOK_RBRACE);
13192                 result = triple(state, OP_BLOBCONST, type, 0, 0);
13193                 result->u.blob = buf;
13194         }
13195         return result;
13196 }
13197
13198 static void resolve_branches(struct compile_state *state, struct triple *first)
13199 {
13200         /* Make a second pass and finish anything outstanding
13201          * with respect to branches.  The only outstanding item
13202          * is to see if there are goto to labels that have not
13203          * been defined and to error about them.
13204          */
13205         int i;
13206         struct triple *ins;
13207         /* Also error on branches that do not use their targets */
13208         ins = first;
13209         do {
13210                 if (!triple_is_ret(state, ins)) {
13211                         struct triple **expr ;
13212                         struct triple_set *set;
13213                         expr = triple_targ(state, ins, 0);
13214                         for(; expr; expr = triple_targ(state, ins, expr)) {
13215                                 struct triple *targ;
13216                                 targ = *expr;
13217                                 for(set = targ?targ->use:0; set; set = set->next) {
13218                                         if (set->member == ins) {
13219                                                 break;
13220                                         }
13221                                 }
13222                                 if (!set) {
13223                                         internal_error(state, ins, "targ not used");
13224                                 }
13225                         }
13226                 }
13227                 ins = ins->next;
13228         } while(ins != first);
13229         /* See if there are goto to labels that have not been defined */
13230         for(i = 0; i < HASH_TABLE_SIZE; i++) {
13231                 struct hash_entry *entry;
13232                 for(entry = state->hash_table[i]; entry; entry = entry->next) {
13233                         struct triple *ins;
13234                         if (!entry->sym_label) {
13235                                 continue;
13236                         }
13237                         ins = entry->sym_label->def;
13238                         if (!(ins->id & TRIPLE_FLAG_FLATTENED)) {
13239                                 error(state, ins, "label `%s' used but not defined",
13240                                         entry->name);
13241                         }
13242                 }
13243         }
13244 }
13245
13246 static struct triple *function_definition(
13247         struct compile_state *state, struct type *type)
13248 {
13249         struct triple *def, *tmp, *first, *end, *retvar, *result, *ret;
13250         struct triple *fname;
13251         struct type *fname_type;
13252         struct hash_entry *ident;
13253         struct type *param, *crtype, *ctype;
13254         int i;
13255         if ((type->type &TYPE_MASK) != TYPE_FUNCTION) {
13256                 error(state, 0, "Invalid function header");
13257         }
13258
13259         /* Verify the function type */
13260         if (((type->right->type & TYPE_MASK) != TYPE_VOID)  &&
13261                 ((type->right->type & TYPE_MASK) != TYPE_PRODUCT) &&
13262                 (type->right->field_ident == 0)) {
13263                 error(state, 0, "Invalid function parameters");
13264         }
13265         param = type->right;
13266         i = 0;
13267         while((param->type & TYPE_MASK) == TYPE_PRODUCT) {
13268                 i++;
13269                 if (!param->left->field_ident) {
13270                         error(state, 0, "No identifier for parameter %d\n", i);
13271                 }
13272                 param = param->right;
13273         }
13274         i++;
13275         if (((param->type & TYPE_MASK) != TYPE_VOID) && !param->field_ident) {
13276                 error(state, 0, "No identifier for paramter %d\n", i);
13277         }
13278         
13279         /* Get a list of statements for this function. */
13280         def = triple(state, OP_LIST, type, 0, 0);
13281
13282         /* Start a new scope for the passed parameters */
13283         start_scope(state);
13284
13285         /* Put a label at the very start of a function */
13286         first = label(state);
13287         RHS(def, 0) = first;
13288
13289         /* Put a label at the very end of a function */
13290         end = label(state);
13291         flatten(state, first, end);
13292         /* Remember where return goes */
13293         ident = state->i_return;
13294         symbol(state, ident, &ident->sym_ident, end, end->type);
13295
13296         /* Get the initial closure type */
13297         ctype = new_type(TYPE_JOIN, &void_type, 0);
13298         ctype->elements = 1;
13299
13300         /* Add a variable for the return value */
13301         crtype = new_type(TYPE_TUPLE, 
13302                 /* Remove all type qualifiers from the return type */
13303                 new_type(TYPE_PRODUCT, ctype, clone_type(0, type->left)), 0);
13304         crtype->elements = 2;
13305         result = flatten(state, end, variable(state, crtype));
13306
13307         /* Allocate a variable for the return address */
13308         retvar = flatten(state, end, variable(state, &void_ptr_type));
13309
13310         /* Add in the return instruction */
13311         ret = triple(state, OP_RET, &void_type, read_expr(state, retvar), 0);
13312         ret = flatten(state, first, ret);
13313
13314         /* Walk through the parameters and create symbol table entries
13315          * for them.
13316          */
13317         param = type->right;
13318         while((param->type & TYPE_MASK) == TYPE_PRODUCT) {
13319                 ident = param->left->field_ident;
13320                 tmp = variable(state, param->left);
13321                 var_symbol(state, ident, tmp);
13322                 flatten(state, end, tmp);
13323                 param = param->right;
13324         }
13325         if ((param->type & TYPE_MASK) != TYPE_VOID) {
13326                 /* And don't forget the last parameter */
13327                 ident = param->field_ident;
13328                 tmp = variable(state, param);
13329                 symbol(state, ident, &ident->sym_ident, tmp, tmp->type);
13330                 flatten(state, end, tmp);
13331         }
13332
13333         /* Add the declaration static const char __func__ [] = "func-name"  */
13334         fname_type = new_type(TYPE_ARRAY, 
13335                 clone_type(QUAL_CONST | STOR_STATIC, &char_type), 0);
13336         fname_type->type |= QUAL_CONST | STOR_STATIC;
13337         fname_type->elements = strlen(state->function) + 1;
13338
13339         fname = triple(state, OP_BLOBCONST, fname_type, 0, 0);
13340         fname->u.blob = (void *)state->function;
13341         fname = flatten(state, end, fname);
13342
13343         ident = state->i___func__;
13344         symbol(state, ident, &ident->sym_ident, fname, fname_type);
13345
13346         /* Remember which function I am compiling.
13347          * Also assume the last defined function is the main function.
13348          */
13349         state->main_function = def;
13350
13351         /* Now get the actual function definition */
13352         compound_statement(state, end);
13353
13354         /* Finish anything unfinished with branches */
13355         resolve_branches(state, first);
13356
13357         /* Remove the parameter scope */
13358         end_scope(state);
13359
13360
13361         /* Remember I have defined a function */
13362         if (!state->functions) {
13363                 state->functions = def;
13364         } else {
13365                 insert_triple(state, state->functions, def);
13366         }
13367         if (state->compiler->debug & DEBUG_INLINE) {
13368                 FILE *fp = state->dbgout;
13369                 fprintf(fp, "\n");
13370                 loc(fp, state, 0);
13371                 fprintf(fp, "\n__________ %s _________\n", __FUNCTION__);
13372                 display_func(state, fp, def);
13373                 fprintf(fp, "__________ %s _________ done\n\n", __FUNCTION__);
13374         }
13375
13376         return def;
13377 }
13378
13379 static struct triple *do_decl(struct compile_state *state, 
13380         struct type *type, struct hash_entry *ident)
13381 {
13382         struct triple *def;
13383         def = 0;
13384         /* Clean up the storage types used */
13385         switch (type->type & STOR_MASK) {
13386         case STOR_AUTO:
13387         case STOR_STATIC:
13388                 /* These are the good types I am aiming for */
13389                 break;
13390         case STOR_REGISTER:
13391                 type->type &= ~STOR_MASK;
13392                 type->type |= STOR_AUTO;
13393                 break;
13394         case STOR_LOCAL:
13395         case STOR_EXTERN:
13396                 type->type &= ~STOR_MASK;
13397                 type->type |= STOR_STATIC;
13398                 break;
13399         case STOR_TYPEDEF:
13400                 if (!ident) {
13401                         error(state, 0, "typedef without name");
13402                 }
13403                 symbol(state, ident, &ident->sym_ident, 0, type);
13404                 ident->tok = TOK_TYPE_NAME;
13405                 return 0;
13406                 break;
13407         default:
13408                 internal_error(state, 0, "Undefined storage class");
13409         }
13410         if ((type->type & TYPE_MASK) == TYPE_FUNCTION) {
13411                 error(state, 0, "Function prototypes not supported");
13412         }
13413         if (ident && 
13414                 ((type->type & STOR_MASK) == STOR_STATIC) &&
13415                 ((type->type & QUAL_CONST) == 0)) {
13416                 error(state, 0, "non const static variables not supported");
13417         }
13418         if (ident) {
13419                 def = variable(state, type);
13420                 var_symbol(state, ident, def);
13421         }
13422         return def;
13423 }
13424
13425 static void decl(struct compile_state *state, struct triple *first)
13426 {
13427         struct type *base_type, *type;
13428         struct hash_entry *ident;
13429         struct triple *def;
13430         int global;
13431         global = (state->scope_depth <= GLOBAL_SCOPE_DEPTH);
13432         base_type = decl_specifiers(state);
13433         ident = 0;
13434         type = declarator(state, base_type, &ident, 0);
13435         type->type = attributes_opt(state, type->type);
13436         if (global && ident && (peek(state) == TOK_LBRACE)) {
13437                 /* function */
13438                 type->type_ident = ident;
13439                 state->function = ident->name;
13440                 def = function_definition(state, type);
13441                 symbol(state, ident, &ident->sym_ident, def, type);
13442                 state->function = 0;
13443         }
13444         else {
13445                 int done;
13446                 flatten(state, first, do_decl(state, type, ident));
13447                 /* type or variable definition */
13448                 do {
13449                         done = 1;
13450                         if (peek(state) == TOK_EQ) {
13451                                 if (!ident) {
13452                                         error(state, 0, "cannot assign to a type");
13453                                 }
13454                                 eat(state, TOK_EQ);
13455                                 flatten(state, first,
13456                                         init_expr(state, 
13457                                                 ident->sym_ident->def, 
13458                                                 initializer(state, type)));
13459                         }
13460                         arrays_complete(state, type);
13461                         if (peek(state) == TOK_COMMA) {
13462                                 eat(state, TOK_COMMA);
13463                                 ident = 0;
13464                                 type = declarator(state, base_type, &ident, 0);
13465                                 flatten(state, first, do_decl(state, type, ident));
13466                                 done = 0;
13467                         }
13468                 } while(!done);
13469                 eat(state, TOK_SEMI);
13470         }
13471 }
13472
13473 static void decls(struct compile_state *state)
13474 {
13475         struct triple *list;
13476         int tok;
13477         list = label(state);
13478         while(1) {
13479                 tok = peek(state);
13480                 if (tok == TOK_EOF) {
13481                         return;
13482                 }
13483                 if (tok == TOK_SPACE) {
13484                         eat(state, TOK_SPACE);
13485                 }
13486                 decl(state, list);
13487                 if (list->next != list) {
13488                         error(state, 0, "global variables not supported");
13489                 }
13490         }
13491 }
13492
13493 /* 
13494  * Function inlining
13495  */
13496 struct triple_reg_set {
13497         struct triple_reg_set *next;
13498         struct triple *member;
13499         struct triple *new;
13500 };
13501 struct reg_block {
13502         struct block *block;
13503         struct triple_reg_set *in;
13504         struct triple_reg_set *out;
13505         int vertex;
13506 };
13507 static void setup_basic_blocks(struct compile_state *, struct basic_blocks *bb);
13508 static void analyze_basic_blocks(struct compile_state *state, struct basic_blocks *bb);
13509 static void free_basic_blocks(struct compile_state *, struct basic_blocks *bb);
13510 static int tdominates(struct compile_state *state, struct triple *dom, struct triple *sub);
13511 static void walk_blocks(struct compile_state *state, struct basic_blocks *bb,
13512         void (*cb)(struct compile_state *state, struct block *block, void *arg),
13513         void *arg);
13514 static void print_block(
13515         struct compile_state *state, struct block *block, void *arg);
13516 static int do_triple_set(struct triple_reg_set **head, 
13517         struct triple *member, struct triple *new_member);
13518 static void do_triple_unset(struct triple_reg_set **head, struct triple *member);
13519 static struct reg_block *compute_variable_lifetimes(
13520         struct compile_state *state, struct basic_blocks *bb);
13521 static void free_variable_lifetimes(struct compile_state *state, 
13522         struct basic_blocks *bb, struct reg_block *blocks);
13523 static void print_live_variables(struct compile_state *state, 
13524         struct basic_blocks *bb, struct reg_block *rb, FILE *fp);
13525
13526
13527 static struct triple *call(struct compile_state *state,
13528         struct triple *retvar, struct triple *ret_addr, 
13529         struct triple *targ, struct triple *ret)
13530 {
13531         struct triple *call;
13532
13533         if (!retvar || !is_lvalue(state, retvar)) {
13534                 internal_error(state, 0, "writing to a non lvalue?");
13535         }
13536         write_compatible(state, retvar->type, &void_ptr_type);
13537
13538         call = new_triple(state, OP_CALL, &void_type, 1, 0);
13539         TARG(call, 0) = targ;
13540         MISC(call, 0) = ret;
13541         if (!targ || (targ->op != OP_LABEL)) {
13542                 internal_error(state, 0, "call not to a label");
13543         }
13544         if (!ret || (ret->op != OP_RET)) {
13545                 internal_error(state, 0, "call not matched with return");
13546         }
13547         return call;
13548 }
13549
13550 static void walk_functions(struct compile_state *state,
13551         void (*cb)(struct compile_state *state, struct triple *func, void *arg),
13552         void *arg)
13553 {
13554         struct triple *func, *first;
13555         func = first = state->functions;
13556         do {
13557                 cb(state, func, arg);
13558                 func = func->next;
13559         } while(func != first);
13560 }
13561
13562 static void reverse_walk_functions(struct compile_state *state,
13563         void (*cb)(struct compile_state *state, struct triple *func, void *arg),
13564         void *arg)
13565 {
13566         struct triple *func, *first;
13567         func = first = state->functions;
13568         do {
13569                 func = func->prev;
13570                 cb(state, func, arg);
13571         } while(func != first);
13572 }
13573
13574
13575 static void mark_live(struct compile_state *state, struct triple *func, void *arg)
13576 {
13577         struct triple *ptr, *first;
13578         if (func->u.cval == 0) {
13579                 return;
13580         }
13581         ptr = first = RHS(func, 0);
13582         do {
13583                 if (ptr->op == OP_FCALL) {
13584                         struct triple *called_func;
13585                         called_func = MISC(ptr, 0);
13586                         /* Mark the called function as used */
13587                         if (!(func->id & TRIPLE_FLAG_FLATTENED)) {
13588                                 called_func->u.cval++;
13589                         }
13590                         /* Remove the called function from the list */
13591                         called_func->prev->next = called_func->next;
13592                         called_func->next->prev = called_func->prev;
13593
13594                         /* Place the called function before me on the list */
13595                         called_func->next       = func;
13596                         called_func->prev       = func->prev;
13597                         called_func->prev->next = called_func;
13598                         called_func->next->prev = called_func;
13599                 }
13600                 ptr = ptr->next;
13601         } while(ptr != first);
13602         func->id |= TRIPLE_FLAG_FLATTENED;
13603 }
13604
13605 static void mark_live_functions(struct compile_state *state)
13606 {
13607         /* Ensure state->main_function is the last function in 
13608          * the list of functions.
13609          */
13610         if ((state->main_function->next != state->functions) ||
13611                 (state->functions->prev != state->main_function)) {
13612                 internal_error(state, 0, 
13613                         "state->main_function is not at the end of the function list ");
13614         }
13615         state->main_function->u.cval = 1;
13616         reverse_walk_functions(state, mark_live, 0);
13617 }
13618
13619 static int local_triple(struct compile_state *state, 
13620         struct triple *func, struct triple *ins)
13621 {
13622         int local = (ins->id & TRIPLE_FLAG_LOCAL);
13623 #if 0
13624         if (!local) {
13625                 FILE *fp = state->errout;
13626                 fprintf(fp, "global: ");
13627                 display_triple(fp, ins);
13628         }
13629 #endif
13630         return local;
13631 }
13632
13633 struct triple *copy_func(struct compile_state *state, struct triple *ofunc, 
13634         struct occurance *base_occurance)
13635 {
13636         struct triple *nfunc;
13637         struct triple *nfirst, *ofirst;
13638         struct triple *new, *old;
13639
13640         if (state->compiler->debug & DEBUG_INLINE) {
13641                 FILE *fp = state->dbgout;
13642                 fprintf(fp, "\n");
13643                 loc(fp, state, 0);
13644                 fprintf(fp, "\n__________ %s _________\n", __FUNCTION__);
13645                 display_func(state, fp, ofunc);
13646                 fprintf(fp, "__________ %s _________ done\n\n", __FUNCTION__);
13647         }
13648
13649         /* Make a new copy of the old function */
13650         nfunc = triple(state, OP_LIST, ofunc->type, 0, 0);
13651         nfirst = 0;
13652         ofirst = old = RHS(ofunc, 0);
13653         do {
13654                 struct triple *new;
13655                 struct occurance *occurance;
13656                 int old_lhs, old_rhs;
13657                 old_lhs = old->lhs;
13658                 old_rhs = old->rhs;
13659                 occurance = inline_occurance(state, base_occurance, old->occurance);
13660                 if (ofunc->u.cval && (old->op == OP_FCALL)) {
13661                         MISC(old, 0)->u.cval += 1;
13662                 }
13663                 new = alloc_triple(state, old->op, old->type, old_lhs, old_rhs,
13664                         occurance);
13665                 if (!triple_stores_block(state, new)) {
13666                         memcpy(&new->u, &old->u, sizeof(new->u));
13667                 }
13668                 if (!nfirst) {
13669                         RHS(nfunc, 0) = nfirst = new;
13670                 }
13671                 else {
13672                         insert_triple(state, nfirst, new);
13673                 }
13674                 new->id |= TRIPLE_FLAG_FLATTENED;
13675                 new->id |= old->id & TRIPLE_FLAG_COPY;
13676                 
13677                 /* During the copy remember new as user of old */
13678                 use_triple(old, new);
13679
13680                 /* Remember which instructions are local */
13681                 old->id |= TRIPLE_FLAG_LOCAL;
13682                 old = old->next;
13683         } while(old != ofirst);
13684
13685         /* Make a second pass to fix up any unresolved references */
13686         old = ofirst;
13687         new = nfirst;
13688         do {
13689                 struct triple **oexpr, **nexpr;
13690                 int count, i;
13691                 /* Lookup where the copy is, to join pointers */
13692                 count = TRIPLE_SIZE(old);
13693                 for(i = 0; i < count; i++) {
13694                         oexpr = &old->param[i];
13695                         nexpr = &new->param[i];
13696                         if (*oexpr && !*nexpr) {
13697                                 if (!local_triple(state, ofunc, *oexpr)) {
13698                                         *nexpr = *oexpr;
13699                                 }
13700                                 else if ((*oexpr)->use) {
13701                                         *nexpr = (*oexpr)->use->member;
13702                                 }
13703                                 if (*nexpr == old) {
13704                                         internal_error(state, 0, "new == old?");
13705                                 }
13706                                 use_triple(*nexpr, new);
13707                         }
13708                         if (!*nexpr && *oexpr) {
13709                                 internal_error(state, 0, "Could not copy %d", i);
13710                         }
13711                 }
13712                 old = old->next;
13713                 new = new->next;
13714         } while((old != ofirst) && (new != nfirst));
13715         
13716         /* Make a third pass to cleanup the extra useses */
13717         old = ofirst;
13718         new = nfirst;
13719         do {
13720                 unuse_triple(old, new);
13721                 /* Forget which instructions are local */
13722                 old->id &= ~TRIPLE_FLAG_LOCAL;
13723                 old = old->next;
13724                 new = new->next;
13725         } while ((old != ofirst) && (new != nfirst));
13726         return nfunc;
13727 }
13728
13729 static void expand_inline_call(
13730         struct compile_state *state, struct triple *me, struct triple *fcall)
13731 {
13732         /* Inline the function call */
13733         struct type *ptype;
13734         struct triple *ofunc, *nfunc, *nfirst, *result, *retvar, *ins;
13735         struct triple *end, *nend;
13736         int pvals, i;
13737
13738         /* Find the triples */
13739         ofunc = MISC(fcall, 0);
13740         if (ofunc->op != OP_LIST) {
13741                 internal_error(state, 0, "improper function");
13742         }
13743         nfunc = copy_func(state, ofunc, fcall->occurance);
13744         /* Prepend the parameter reading into the new function list */
13745         ptype = nfunc->type->right;
13746         pvals = fcall->rhs;
13747         for(i = 0; i < pvals; i++) {
13748                 struct type *atype;
13749                 struct triple *arg, *param;
13750                 atype = ptype;
13751                 if ((ptype->type & TYPE_MASK) == TYPE_PRODUCT) {
13752                         atype = ptype->left;
13753                 }
13754                 param = farg(state, nfunc, i);
13755                 if ((param->type->type & TYPE_MASK) != (atype->type & TYPE_MASK)) {
13756                         internal_error(state, fcall, "param %d type mismatch", i);
13757                 }
13758                 arg = RHS(fcall, i);
13759                 flatten(state, fcall, write_expr(state, param, arg));
13760                 ptype = ptype->right;
13761         }
13762         result = 0;
13763         if ((nfunc->type->left->type & TYPE_MASK) != TYPE_VOID) {
13764                 result = read_expr(state, 
13765                         deref_index(state, fresult(state, nfunc), 1));
13766         }
13767         if (state->compiler->debug & DEBUG_INLINE) {
13768                 FILE *fp = state->dbgout;
13769                 fprintf(fp, "\n");
13770                 loc(fp, state, 0);
13771                 fprintf(fp, "\n__________ %s _________\n", __FUNCTION__);
13772                 display_func(state, fp, nfunc);
13773                 fprintf(fp, "__________ %s _________ done\n\n", __FUNCTION__);
13774         }
13775
13776         /* 
13777          * Get rid of the extra triples 
13778          */
13779         /* Remove the read of the return address */
13780         ins = RHS(nfunc, 0)->prev->prev;
13781         if ((ins->op != OP_READ) || (RHS(ins, 0) != fretaddr(state, nfunc))) {
13782                 internal_error(state, ins, "Not return addres read?");
13783         }
13784         release_triple(state, ins);
13785         /* Remove the return instruction */
13786         ins = RHS(nfunc, 0)->prev;
13787         if (ins->op != OP_RET) {
13788                 internal_error(state, ins, "Not return?");
13789         }
13790         release_triple(state, ins);
13791         /* Remove the retaddres variable */
13792         retvar = fretaddr(state, nfunc);
13793         if ((retvar->lhs != 1) || 
13794                 (retvar->op != OP_ADECL) ||
13795                 (retvar->next->op != OP_PIECE) ||
13796                 (MISC(retvar->next, 0) != retvar)) {
13797                 internal_error(state, retvar, "Not the return address?");
13798         }
13799         release_triple(state, retvar->next);
13800         release_triple(state, retvar);
13801
13802         /* Remove the label at the start of the function */
13803         ins = RHS(nfunc, 0);
13804         if (ins->op != OP_LABEL) {
13805                 internal_error(state, ins, "Not label?");
13806         }
13807         nfirst = ins->next;
13808         free_triple(state, ins);
13809         /* Release the new function header */
13810         RHS(nfunc, 0) = 0;
13811         free_triple(state, nfunc);
13812
13813         /* Append the new function list onto the return list */
13814         end = fcall->prev;
13815         nend = nfirst->prev;
13816         end->next    = nfirst;
13817         nfirst->prev = end;
13818         nend->next   = fcall;
13819         fcall->prev  = nend;
13820
13821         /* Now the result reading code */
13822         if (result) {
13823                 result = flatten(state, fcall, result);
13824                 propogate_use(state, fcall, result);
13825         }
13826
13827         /* Release the original fcall instruction */
13828         release_triple(state, fcall);
13829
13830         return;
13831 }
13832
13833 /*
13834  *
13835  * Type of the result variable.
13836  * 
13837  *                                     result
13838  *                                        |
13839  *                             +----------+------------+
13840  *                             |                       |
13841  *                     union of closures         result_type
13842  *                             |
13843  *          +------------------+---------------+
13844  *          |                                  |
13845  *       closure1                    ...   closuerN
13846  *          |                                  | 
13847  *  +----+--+-+--------+-----+       +----+----+---+-----+
13848  *  |    |    |        |     |       |    |        |     |
13849  * var1 var2 var3 ... varN result   var1 var2 ... varN result
13850  *                           |
13851  *                  +--------+---------+
13852  *                  |                  |
13853  *          union of closures     result_type
13854  *                  |
13855  *            +-----+-------------------+
13856  *            |                         |
13857  *         closure1            ...  closureN
13858  *            |                         |
13859  *  +-----+---+----+----+      +----+---+----+-----+
13860  *  |     |        |    |      |    |        |     |
13861  * var1 var2 ... varN result  var1 var2 ... varN result
13862  */
13863
13864 static int add_closure_type(struct compile_state *state, 
13865         struct triple *func, struct type *closure_type)
13866 {
13867         struct type *type, *ctype, **next;
13868         struct triple *var, *new_var;
13869         int i;
13870
13871 #if 0
13872         FILE *fp = state->errout;
13873         fprintf(fp, "original_type: ");
13874         name_of(fp, fresult(state, func)->type);
13875         fprintf(fp, "\n");
13876 #endif
13877         /* find the original type */
13878         var = fresult(state, func);
13879         type = var->type;
13880         if (type->elements != 2) {
13881                 internal_error(state, var, "bad return type");
13882         }
13883
13884         /* Find the complete closure type and update it */
13885         ctype = type->left->left;
13886         next = &ctype->left;
13887         while(((*next)->type & TYPE_MASK) == TYPE_OVERLAP) {
13888                 next = &(*next)->right;
13889         }
13890         *next = new_type(TYPE_OVERLAP, *next, dup_type(state, closure_type));
13891         ctype->elements += 1;
13892
13893 #if 0
13894         fprintf(fp, "new_type: ");
13895         name_of(fp, type);
13896         fprintf(fp, "\n");
13897         fprintf(fp, "ctype: %p %d bits: %d ", 
13898                 ctype, ctype->elements, reg_size_of(state, ctype));
13899         name_of(fp, ctype);
13900         fprintf(fp, "\n");
13901 #endif
13902         
13903         /* Regenerate the variable with the new type definition */
13904         new_var = pre_triple(state, var, OP_ADECL, type, 0, 0);
13905         new_var->id |= TRIPLE_FLAG_FLATTENED;
13906         for(i = 0; i < new_var->lhs; i++) {
13907                 LHS(new_var, i)->id |= TRIPLE_FLAG_FLATTENED;
13908         }
13909         
13910         /* Point everyone at the new variable */
13911         propogate_use(state, var, new_var);
13912
13913         /* Release the original variable */
13914         for(i = 0; i < var->lhs; i++) {
13915                 release_triple(state, LHS(var, i));
13916         }
13917         release_triple(state, var);
13918         
13919         /* Return the index of the added closure type */
13920         return ctype->elements - 1;
13921 }
13922
13923 static struct triple *closure_expr(struct compile_state *state,
13924         struct triple *func, int closure_idx, int var_idx)
13925 {
13926         return deref_index(state,
13927                 deref_index(state,
13928                         deref_index(state, fresult(state, func), 0),
13929                         closure_idx),
13930                 var_idx);
13931 }
13932
13933
13934 static void insert_triple_set(
13935         struct triple_reg_set **head, struct triple *member)
13936 {
13937         struct triple_reg_set *new;
13938         new = xcmalloc(sizeof(*new), "triple_set");
13939         new->member = member;
13940         new->new    = 0;
13941         new->next   = *head;
13942         *head       = new;
13943 }
13944
13945 static int ordered_triple_set(
13946         struct triple_reg_set **head, struct triple *member)
13947 {
13948         struct triple_reg_set **ptr;
13949         if (!member)
13950                 return 0;
13951         ptr = head;
13952         while(*ptr) {
13953                 if (member == (*ptr)->member) {
13954                         return 0;
13955                 }
13956                 /* keep the list ordered */
13957                 if (member->id < (*ptr)->member->id) {
13958                         break;
13959                 }
13960                 ptr = &(*ptr)->next;
13961         }
13962         insert_triple_set(ptr, member);
13963         return 1;
13964 }
13965
13966
13967 static void free_closure_variables(struct compile_state *state,
13968         struct triple_reg_set **enclose)
13969 {
13970         struct triple_reg_set *entry, *next;
13971         for(entry = *enclose; entry; entry = next) {
13972                 next = entry->next;
13973                 do_triple_unset(enclose, entry->member);
13974         }
13975 }
13976
13977 static int lookup_closure_index(struct compile_state *state,
13978         struct triple *me, struct triple *val)
13979 {
13980         struct triple *first, *ins, *next;
13981         first = RHS(me, 0);
13982         ins = next = first;
13983         do {
13984                 struct triple *result;
13985                 struct triple *index0, *index1, *index2, *read, *write;
13986                 ins = next;
13987                 next = ins->next;
13988                 if (ins->op != OP_CALL) {
13989                         continue;
13990                 }
13991                 /* I am at a previous call point examine it closely */
13992                 if (ins->next->op != OP_LABEL) {
13993                         internal_error(state, ins, "call not followed by label");
13994                 }
13995                 /* Does this call does not enclose any variables? */
13996                 if ((ins->next->next->op != OP_INDEX) ||
13997                         (ins->next->next->u.cval != 0) ||
13998                         (result = MISC(ins->next->next, 0)) ||
13999                         (result->id & TRIPLE_FLAG_LOCAL)) {
14000                         continue;
14001                 }
14002                 index0 = ins->next->next;
14003                 /* The pattern is:
14004                  * 0 index result < 0 >
14005                  * 1 index 0 < ? >
14006                  * 2 index 1 < ? >
14007                  * 3 read  2
14008                  * 4 write 3 var
14009                  */
14010                 for(index0 = ins->next->next;
14011                         (index0->op == OP_INDEX) &&
14012                                 (MISC(index0, 0) == result) &&
14013                                 (index0->u.cval == 0) ; 
14014                         index0 = write->next)
14015                 {
14016                         index1 = index0->next;
14017                         index2 = index1->next;
14018                         read   = index2->next;
14019                         write  = read->next;
14020                         if ((index0->op != OP_INDEX) ||
14021                                 (index1->op != OP_INDEX) ||
14022                                 (index2->op != OP_INDEX) ||
14023                                 (read->op != OP_READ) ||
14024                                 (write->op != OP_WRITE) ||
14025                                 (MISC(index1, 0) != index0) ||
14026                                 (MISC(index2, 0) != index1) ||
14027                                 (RHS(read, 0) != index2) ||
14028                                 (RHS(write, 0) != read)) {
14029                                 internal_error(state, index0, "bad var read");
14030                         }
14031                         if (MISC(write, 0) == val) {
14032                                 return index2->u.cval;
14033                         }
14034                 }
14035         } while(next != first);
14036         return -1;
14037 }
14038
14039 static inline int enclose_triple(struct triple *ins)
14040 {
14041         return (ins && ((ins->type->type & TYPE_MASK) != TYPE_VOID));
14042 }
14043
14044 static void compute_closure_variables(struct compile_state *state,
14045         struct triple *me, struct triple *fcall, struct triple_reg_set **enclose)
14046 {
14047         struct triple_reg_set *set, *vars, **last_var;
14048         struct basic_blocks bb;
14049         struct reg_block *rb;
14050         struct block *block;
14051         struct triple *old_result, *first, *ins;
14052         size_t count, idx;
14053         unsigned long used_indicies;
14054         int i, max_index;
14055 #define MAX_INDICIES (sizeof(used_indicies)*CHAR_BIT)
14056 #define ID_BITS(X) ((X) & (TRIPLE_FLAG_LOCAL -1))
14057         struct { 
14058                 unsigned id;
14059                 int index;
14060         } *info;
14061
14062         
14063         /* Find the basic blocks of this function */
14064         bb.func = me;
14065         bb.first = RHS(me, 0);
14066         old_result = 0;
14067         if (!triple_is_ret(state, bb.first->prev)) {
14068                 bb.func = 0;
14069         } else {
14070                 old_result = fresult(state, me);
14071         }
14072         analyze_basic_blocks(state, &bb);
14073
14074         /* Find which variables are currently alive in a given block */
14075         rb = compute_variable_lifetimes(state, &bb);
14076
14077         /* Find the variables that are currently alive */
14078         block = block_of_triple(state, fcall);
14079         if (!block || (block->vertex <= 0) || (block->vertex > bb.last_vertex)) {
14080                 internal_error(state, fcall, "No reg block? block: %p", block);
14081         }
14082
14083 #if DEBUG_EXPLICIT_CLOSURES
14084         print_live_variables(state, &bb, rb, state->dbgout);
14085         fflush(state->dbgout);
14086 #endif
14087
14088         /* Count the number of triples in the function */
14089         first = RHS(me, 0);
14090         ins = first;
14091         count = 0;
14092         do {
14093                 count++;
14094                 ins = ins->next;
14095         } while(ins != first);
14096
14097         /* Allocate some memory to temorary hold the id info */
14098         info = xcmalloc(sizeof(*info) * (count +1), "info");
14099
14100         /* Mark the local function */
14101         first = RHS(me, 0);
14102         ins = first;
14103         idx = 1;
14104         do {
14105                 info[idx].id = ins->id;
14106                 ins->id = TRIPLE_FLAG_LOCAL | idx;
14107                 idx++;
14108                 ins = ins->next;
14109         } while(ins != first);
14110
14111         /* 
14112          * Build the list of variables to enclose.
14113          *
14114          * A target it to put the same variable in the
14115          * same slot for ever call of a given function.
14116          * After coloring this removes all of the variable
14117          * manipulation code.
14118          *
14119          * The list of variables to enclose is built ordered
14120          * program order because except in corner cases this
14121          * gives me the stability of assignment I need.
14122          *
14123          * To gurantee that stability I lookup the variables
14124          * to see where they have been used before and
14125          * I build my final list with the assigned indicies.
14126          */
14127         vars = 0;
14128         if (enclose_triple(old_result)) {
14129                 ordered_triple_set(&vars, old_result);
14130         }
14131         for(set = rb[block->vertex].out; set; set = set->next) {
14132                 if (!enclose_triple(set->member)) {
14133                         continue;
14134                 }
14135                 if ((set->member == fcall) || (set->member == old_result)) {
14136                         continue;
14137                 }
14138                 if (!local_triple(state, me, set->member)) {
14139                         internal_error(state, set->member, "not local?");
14140                 }
14141                 ordered_triple_set(&vars, set->member);
14142         }
14143
14144         /* Lookup the current indicies of the live varialbe */
14145         used_indicies = 0;
14146         max_index = -1;
14147         for(set = vars; set ; set = set->next) {
14148                 struct triple *ins;
14149                 int index;
14150                 ins = set->member;
14151                 index  = lookup_closure_index(state, me, ins);
14152                 info[ID_BITS(ins->id)].index = index;
14153                 if (index < 0) {
14154                         continue;
14155                 }
14156                 if (index >= MAX_INDICIES) {
14157                         internal_error(state, ins, "index unexpectedly large");
14158                 }
14159                 if (used_indicies & (1 << index)) {
14160                         internal_error(state, ins, "index previously used?");
14161                 }
14162                 /* Remember which indicies have been used */
14163                 used_indicies |= (1 << index);
14164                 if (index > max_index) {
14165                         max_index = index;
14166                 }
14167         }
14168
14169         /* Walk through the live variables and make certain
14170          * everything is assigned an index.
14171          */
14172         for(set = vars; set; set = set->next) {
14173                 struct triple *ins;
14174                 int index;
14175                 ins = set->member;
14176                 index = info[ID_BITS(ins->id)].index;
14177                 if (index >= 0) {
14178                         continue;
14179                 }
14180                 /* Find the lowest unused index value */
14181                 for(index = 0; index < MAX_INDICIES; index++) {
14182                         if (!(used_indicies & (1 << index))) {
14183                                 break;
14184                         }
14185                 }
14186                 if (index == MAX_INDICIES) {
14187                         internal_error(state, ins, "no free indicies?");
14188                 }
14189                 info[ID_BITS(ins->id)].index = index;
14190                 /* Remember which indicies have been used */
14191                 used_indicies |= (1 << index);
14192                 if (index > max_index) {
14193                         max_index = index;
14194                 }
14195         }
14196
14197         /* Build the return list of variables with positions matching
14198          * their indicies.
14199          */
14200         *enclose = 0;
14201         last_var = enclose;
14202         for(i = 0; i <= max_index; i++) {
14203                 struct triple *var;
14204                 var = 0;
14205                 if (used_indicies & (1 << i)) {
14206                         for(set = vars; set; set = set->next) {
14207                                 int index;
14208                                 index = info[ID_BITS(set->member->id)].index;
14209                                 if (index == i) {
14210                                         var = set->member;
14211                                         break;
14212                                 }
14213                         }
14214                         if (!var) {
14215                                 internal_error(state, me, "missing variable");
14216                         }
14217                 }
14218                 insert_triple_set(last_var, var);
14219                 last_var = &(*last_var)->next;
14220         }
14221
14222 #if DEBUG_EXPLICIT_CLOSURES
14223         /* Print out the variables to be enclosed */
14224         loc(state->dbgout, state, fcall);
14225         fprintf(state->dbgout, "Alive: \n");
14226         for(set = *enclose; set; set = set->next) {
14227                 display_triple(state->dbgout, set->member);
14228         }
14229         fflush(state->dbgout);
14230 #endif
14231
14232         /* Clear the marks */
14233         ins = first;
14234         do {
14235                 ins->id = info[ID_BITS(ins->id)].id;
14236                 ins = ins->next;
14237         } while(ins != first);
14238
14239         /* Release the ordered list of live variables */
14240         free_closure_variables(state, &vars);
14241
14242         /* Release the storage of the old ids */
14243         xfree(info);
14244
14245         /* Release the variable lifetime information */
14246         free_variable_lifetimes(state, &bb, rb);
14247
14248         /* Release the basic blocks of this function */
14249         free_basic_blocks(state, &bb);
14250 }
14251
14252 static void expand_function_call(
14253         struct compile_state *state, struct triple *me, struct triple *fcall)
14254 {
14255         /* Generate an ordinary function call */
14256         struct type *closure_type, **closure_next;
14257         struct triple *func, *func_first, *func_last, *retvar;
14258         struct triple *first;
14259         struct type *ptype, *rtype;
14260         struct triple *jmp;
14261         struct triple *ret_addr, *ret_loc, *ret_set;
14262         struct triple_reg_set *enclose, *set;
14263         int closure_idx, pvals, i;
14264
14265 #if DEBUG_EXPLICIT_CLOSURES
14266         FILE *fp = state->dbgout;
14267         fprintf(fp, "\ndisplay_func(me) ptr: %p\n", fcall);
14268         display_func(state, fp, MISC(fcall, 0));
14269         display_func(state, fp, me);
14270         fprintf(fp, "__________ %s _________ done\n\n", __FUNCTION__);
14271 #endif
14272
14273         /* Find the triples */
14274         func = MISC(fcall, 0);
14275         func_first = RHS(func, 0);
14276         retvar = fretaddr(state, func);
14277         func_last  = func_first->prev;
14278         first = fcall->next;
14279
14280         /* Find what I need to enclose */
14281         compute_closure_variables(state, me, fcall, &enclose);
14282
14283         /* Compute the closure type */
14284         closure_type = new_type(TYPE_TUPLE, 0, 0);
14285         closure_type->elements = 0;
14286         closure_next = &closure_type->left;
14287         for(set = enclose; set ; set = set->next) {
14288                 struct type *type;
14289                 type = &void_type;
14290                 if (set->member) {
14291                         type = set->member->type;
14292                 }
14293                 if (!*closure_next) {
14294                         *closure_next = type;
14295                 } else {
14296                         *closure_next = new_type(TYPE_PRODUCT, *closure_next, 
14297                                 type);
14298                         closure_next = &(*closure_next)->right;
14299                 }
14300                 closure_type->elements += 1;
14301         }
14302         if (closure_type->elements == 0) {
14303                 closure_type->type = TYPE_VOID;
14304         }
14305
14306
14307 #if DEBUG_EXPLICIT_CLOSURES
14308         fprintf(state->dbgout, "closure type: ");
14309         name_of(state->dbgout, closure_type);
14310         fprintf(state->dbgout, "\n");
14311 #endif
14312
14313         /* Update the called functions closure variable */
14314         closure_idx = add_closure_type(state, func, closure_type);
14315
14316         /* Generate some needed triples */
14317         ret_loc = label(state);
14318         ret_addr = triple(state, OP_ADDRCONST, &void_ptr_type, ret_loc, 0);
14319
14320         /* Pass the parameters to the new function */
14321         ptype = func->type->right;
14322         pvals = fcall->rhs;
14323         for(i = 0; i < pvals; i++) {
14324                 struct type *atype;
14325                 struct triple *arg, *param;
14326                 atype = ptype;
14327                 if ((ptype->type & TYPE_MASK) == TYPE_PRODUCT) {
14328                         atype = ptype->left;
14329                 }
14330                 param = farg(state, func, i);
14331                 if ((param->type->type & TYPE_MASK) != (atype->type & TYPE_MASK)) {
14332                         internal_error(state, fcall, "param type mismatch");
14333                 }
14334                 arg = RHS(fcall, i);
14335                 flatten(state, first, write_expr(state, param, arg));
14336                 ptype = ptype->right;
14337         }
14338         rtype = func->type->left;
14339
14340         /* Thread the triples together */
14341         ret_loc       = flatten(state, first, ret_loc);
14342
14343         /* Save the active variables in the result variable */
14344         for(i = 0, set = enclose; set ; set = set->next, i++) {
14345                 if (!set->member) {
14346                         continue;
14347                 }
14348                 flatten(state, ret_loc,
14349                         write_expr(state,
14350                                 closure_expr(state, func, closure_idx, i),
14351                                 read_expr(state, set->member)));
14352         }
14353
14354         /* Initialize the return value */
14355         if ((rtype->type & TYPE_MASK) != TYPE_VOID) {
14356                 flatten(state, ret_loc, 
14357                         write_expr(state, 
14358                                 deref_index(state, fresult(state, func), 1),
14359                                 new_triple(state, OP_UNKNOWNVAL, rtype,  0, 0)));
14360         }
14361
14362         ret_addr      = flatten(state, ret_loc, ret_addr);
14363         ret_set       = flatten(state, ret_loc, write_expr(state, retvar, ret_addr));
14364         jmp           = flatten(state, ret_loc, 
14365                 call(state, retvar, ret_addr, func_first, func_last));
14366
14367         /* Find the result */
14368         if ((rtype->type & TYPE_MASK) != TYPE_VOID) {
14369                 struct triple * result;
14370                 result = flatten(state, first, 
14371                         read_expr(state, 
14372                                 deref_index(state, fresult(state, func), 1)));
14373
14374                 propogate_use(state, fcall, result);
14375         }
14376
14377         /* Release the original fcall instruction */
14378         release_triple(state, fcall);
14379
14380         /* Restore the active variables from the result variable */
14381         for(i = 0, set = enclose; set ; set = set->next, i++) {
14382                 struct triple_set *use, *next;
14383                 struct triple *new;
14384                 struct basic_blocks bb;
14385                 if (!set->member || (set->member == fcall)) {
14386                         continue;
14387                 }
14388                 /* Generate an expression for the value */
14389                 new = flatten(state, first,
14390                         read_expr(state, 
14391                                 closure_expr(state, func, closure_idx, i)));
14392
14393
14394                 /* If the original is an lvalue restore the preserved value */
14395                 if (is_lvalue(state, set->member)) {
14396                         flatten(state, first,
14397                                 write_expr(state, set->member, new));
14398                         continue;
14399                 }
14400                 /*
14401                  * If the original is a value update the dominated uses.
14402                  */
14403                 
14404                 /* Analyze the basic blocks so I can see who dominates whom */
14405                 bb.func = me;
14406                 bb.first = RHS(me, 0);
14407                 if (!triple_is_ret(state, bb.first->prev)) {
14408                         bb.func = 0;
14409                 }
14410                 analyze_basic_blocks(state, &bb);
14411                 
14412
14413 #if DEBUG_EXPLICIT_CLOSURES
14414                 fprintf(state->errout, "Updating domindated uses: %p -> %p\n",
14415                         set->member, new);
14416 #endif
14417                 /* If fcall dominates the use update the expression */
14418                 for(use = set->member->use; use; use = next) {
14419                         /* Replace use modifies the use chain and 
14420                          * removes use, so I must take a copy of the
14421                          * next entry early.
14422                          */
14423                         next = use->next;
14424                         if (!tdominates(state, fcall, use->member)) {
14425                                 continue;
14426                         }
14427                         replace_use(state, set->member, new, use->member);
14428                 }
14429
14430                 /* Release the basic blocks, the instructions will be
14431                  * different next time, and flatten/insert_triple does
14432                  * not update the block values so I can't cache the analysis.
14433                  */
14434                 free_basic_blocks(state, &bb);
14435         }
14436
14437         /* Release the closure variable list */
14438         free_closure_variables(state, &enclose);
14439
14440         if (state->compiler->debug & DEBUG_INLINE) {
14441                 FILE *fp = state->dbgout;
14442                 fprintf(fp, "\n");
14443                 loc(fp, state, 0);
14444                 fprintf(fp, "\n__________ %s _________\n", __FUNCTION__);
14445                 display_func(state, fp, func);
14446                 display_func(state, fp, me);
14447                 fprintf(fp, "__________ %s _________ done\n\n", __FUNCTION__);
14448         }
14449
14450         return;
14451 }
14452
14453 static int do_inline(struct compile_state *state, struct triple *func)
14454 {
14455         int do_inline;
14456         int policy;
14457
14458         policy = state->compiler->flags & COMPILER_INLINE_MASK;
14459         switch(policy) {
14460         case COMPILER_INLINE_ALWAYS:
14461                 do_inline = 1;
14462                 if (func->type->type & ATTRIB_NOINLINE) {
14463                         error(state, func, "noinline with always_inline compiler option");
14464                 }
14465                 break;
14466         case COMPILER_INLINE_NEVER:
14467                 do_inline = 0;
14468                 if (func->type->type & ATTRIB_ALWAYS_INLINE) {
14469                         error(state, func, "always_inline with noinline compiler option");
14470                 }
14471                 break;
14472         case COMPILER_INLINE_DEFAULTON:
14473                 switch(func->type->type & STOR_MASK) {
14474                 case STOR_STATIC | STOR_INLINE:
14475                 case STOR_LOCAL  | STOR_INLINE:
14476                 case STOR_EXTERN | STOR_INLINE:
14477                         do_inline = 1;
14478                         break;
14479                 default:
14480                         do_inline = 1;
14481                         break;
14482                 }
14483                 break;
14484         case COMPILER_INLINE_DEFAULTOFF:
14485                 switch(func->type->type & STOR_MASK) {
14486                 case STOR_STATIC | STOR_INLINE:
14487                 case STOR_LOCAL  | STOR_INLINE:
14488                 case STOR_EXTERN | STOR_INLINE:
14489                         do_inline = 1;
14490                         break;
14491                 default:
14492                         do_inline = 0;
14493                         break;
14494                 }
14495                 break;
14496         case COMPILER_INLINE_NOPENALTY:
14497                 switch(func->type->type & STOR_MASK) {
14498                 case STOR_STATIC | STOR_INLINE:
14499                 case STOR_LOCAL  | STOR_INLINE:
14500                 case STOR_EXTERN | STOR_INLINE:
14501                         do_inline = 1;
14502                         break;
14503                 default:
14504                         do_inline = (func->u.cval == 1);
14505                         break;
14506                 }
14507                 break;
14508         default:
14509                 do_inline = 0;
14510                 internal_error(state, 0, "Unimplemented inline policy");
14511                 break;
14512         }
14513         /* Force inlining */
14514         if (func->type->type & ATTRIB_NOINLINE) {
14515                 do_inline = 0;
14516         }
14517         if (func->type->type & ATTRIB_ALWAYS_INLINE) {
14518                 do_inline = 1;
14519         }
14520         return do_inline;
14521 }
14522
14523 static void inline_function(struct compile_state *state, struct triple *me, void *arg)
14524 {
14525         struct triple *first, *ptr, *next;
14526         /* If the function is not used don't bother */
14527         if (me->u.cval <= 0) {
14528                 return;
14529         }
14530         if (state->compiler->debug & DEBUG_CALLS2) {
14531                 FILE *fp = state->dbgout;
14532                 fprintf(fp, "in: %s\n",
14533                         me->type->type_ident->name);
14534         }
14535
14536         first = RHS(me, 0);
14537         ptr = next = first;
14538         do {
14539                 struct triple *func, *prev;
14540                 ptr = next;
14541                 prev = ptr->prev;
14542                 next = ptr->next;
14543                 if (ptr->op != OP_FCALL) {
14544                         continue;
14545                 }
14546                 func = MISC(ptr, 0);
14547                 /* See if the function should be inlined */
14548                 if (!do_inline(state, func)) {
14549                         /* Put a label after the fcall */
14550                         post_triple(state, ptr, OP_LABEL, &void_type, 0, 0);
14551                         continue;
14552                 }
14553                 if (state->compiler->debug & DEBUG_CALLS) {
14554                         FILE *fp = state->dbgout;
14555                         if (state->compiler->debug & DEBUG_CALLS2) {
14556                                 loc(fp, state, ptr);
14557                         }
14558                         fprintf(fp, "inlining %s\n",
14559                                 func->type->type_ident->name);
14560                         fflush(fp);
14561                 }
14562
14563                 /* Update the function use counts */
14564                 func->u.cval -= 1;
14565
14566                 /* Replace the fcall with the called function */
14567                 expand_inline_call(state, me, ptr);
14568
14569                 next = prev->next;
14570         } while (next != first);
14571
14572         ptr = next = first;
14573         do {
14574                 struct triple *prev, *func;
14575                 ptr = next;
14576                 prev = ptr->prev;
14577                 next = ptr->next;
14578                 if (ptr->op != OP_FCALL) {
14579                         continue;
14580                 }
14581                 func = MISC(ptr, 0);
14582                 if (state->compiler->debug & DEBUG_CALLS) {
14583                         FILE *fp = state->dbgout;
14584                         if (state->compiler->debug & DEBUG_CALLS2) {
14585                                 loc(fp, state, ptr);
14586                         }
14587                         fprintf(fp, "calling %s\n",
14588                                 func->type->type_ident->name);
14589                         fflush(fp);
14590                 }
14591                 /* Replace the fcall with the instruction sequence
14592                  * needed to make the call.
14593                  */
14594                 expand_function_call(state, me, ptr);
14595                 next = prev->next;
14596         } while(next != first);
14597 }
14598
14599 static void inline_functions(struct compile_state *state, struct triple *func)
14600 {
14601         inline_function(state, func, 0);
14602         reverse_walk_functions(state, inline_function, 0);
14603 }
14604
14605 static void insert_function(struct compile_state *state,
14606         struct triple *func, void *arg)
14607 {
14608         struct triple *first, *end, *ffirst, *fend;
14609
14610         if (state->compiler->debug & DEBUG_INLINE) {
14611                 FILE *fp = state->errout;
14612                 fprintf(fp, "%s func count: %d\n", 
14613                         func->type->type_ident->name, func->u.cval);
14614         }
14615         if (func->u.cval == 0) {
14616                 return;
14617         }
14618
14619         /* Find the end points of the lists */
14620         first  = arg;
14621         end    = first->prev;
14622         ffirst = RHS(func, 0);
14623         fend   = ffirst->prev;
14624
14625         /* splice the lists together */
14626         end->next    = ffirst;
14627         ffirst->prev = end;
14628         fend->next   = first;
14629         first->prev  = fend;
14630 }
14631
14632 struct triple *input_asm(struct compile_state *state)
14633 {
14634         struct asm_info *info;
14635         struct triple *def;
14636         int i, out;
14637         
14638         info = xcmalloc(sizeof(*info), "asm_info");
14639         info->str = "";
14640
14641         out = sizeof(arch_input_regs)/sizeof(arch_input_regs[0]);
14642         memcpy(&info->tmpl.lhs, arch_input_regs, sizeof(arch_input_regs));
14643
14644         def = new_triple(state, OP_ASM, &void_type, out, 0);
14645         def->u.ainfo = info;
14646         def->id |= TRIPLE_FLAG_VOLATILE;
14647         
14648         for(i = 0; i < out; i++) {
14649                 struct triple *piece;
14650                 piece = triple(state, OP_PIECE, &int_type, def, 0);
14651                 piece->u.cval = i;
14652                 LHS(def, i) = piece;
14653         }
14654
14655         return def;
14656 }
14657
14658 struct triple *output_asm(struct compile_state *state)
14659 {
14660         struct asm_info *info;
14661         struct triple *def;
14662         int in;
14663         
14664         info = xcmalloc(sizeof(*info), "asm_info");
14665         info->str = "";
14666
14667         in = sizeof(arch_output_regs)/sizeof(arch_output_regs[0]);
14668         memcpy(&info->tmpl.rhs, arch_output_regs, sizeof(arch_output_regs));
14669
14670         def = new_triple(state, OP_ASM, &void_type, 0, in);
14671         def->u.ainfo = info;
14672         def->id |= TRIPLE_FLAG_VOLATILE;
14673         
14674         return def;
14675 }
14676
14677 static void join_functions(struct compile_state *state)
14678 {
14679         struct triple *jmp, *start, *end, *call, *in, *out, *func;
14680         struct file_state file;
14681         struct type *pnext, *param;
14682         struct type *result_type, *args_type;
14683         int idx;
14684
14685         /* Be clear the functions have not been joined yet */
14686         state->functions_joined = 0;
14687
14688         /* Dummy file state to get debug handing right */
14689         memset(&file, 0, sizeof(file));
14690         file.basename = "";
14691         file.line = 0;
14692         file.report_line = 0;
14693         file.report_name = file.basename;
14694         file.prev = state->file;
14695         state->file = &file;
14696         state->function = "";
14697
14698         if (!state->main_function) {
14699                 error(state, 0, "No functions to compile\n");
14700         }
14701
14702         /* The type of arguments */
14703         args_type   = state->main_function->type->right;
14704         /* The return type without any specifiers */
14705         result_type = clone_type(0, state->main_function->type->left);
14706
14707
14708         /* Verify the external arguments */
14709         if (registers_of(state, args_type) > ARCH_INPUT_REGS) {
14710                 error(state, state->main_function, 
14711                         "Too many external input arguments");
14712         }
14713         if (registers_of(state, result_type) > ARCH_OUTPUT_REGS) {
14714                 error(state, state->main_function, 
14715                         "Too many external output arguments");
14716         }
14717
14718         /* Lay down the basic program structure */
14719         end           = label(state);
14720         start         = label(state);
14721         start         = flatten(state, state->first, start);
14722         end           = flatten(state, state->first, end);
14723         in            = input_asm(state);
14724         out           = output_asm(state);
14725         call          = new_triple(state, OP_FCALL, result_type, -1, registers_of(state, args_type));
14726         MISC(call, 0) = state->main_function;
14727         in            = flatten(state, state->first, in);
14728         call          = flatten(state, state->first, call);
14729         out           = flatten(state, state->first, out);
14730
14731
14732         /* Read the external input arguments */
14733         pnext = args_type;
14734         idx = 0;
14735         while(pnext && ((pnext->type & TYPE_MASK) != TYPE_VOID)) {
14736                 struct triple *expr;
14737                 param = pnext;
14738                 pnext = 0;
14739                 if ((param->type & TYPE_MASK) == TYPE_PRODUCT) {
14740                         pnext = param->right;
14741                         param = param->left;
14742                 }
14743                 if (registers_of(state, param) != 1) {
14744                         error(state, state->main_function, 
14745                                 "Arg: %d %s requires multiple registers", 
14746                                 idx + 1, param->field_ident->name);
14747                 }
14748                 expr = read_expr(state, LHS(in, idx));
14749                 RHS(call, idx) = expr;
14750                 expr = flatten(state, call, expr);
14751                 use_triple(expr, call);
14752
14753                 idx++;  
14754         }
14755
14756
14757         /* Write the external output arguments */
14758         pnext = result_type;
14759         if ((pnext->type & TYPE_MASK) == TYPE_STRUCT) {
14760                 pnext = result_type->left;
14761         }
14762         for(idx = 0; idx < out->rhs; idx++) {
14763                 struct triple *expr;
14764                 param = pnext;
14765                 pnext = 0;
14766                 if (param && ((param->type & TYPE_MASK) == TYPE_PRODUCT)) {
14767                         pnext = param->right;
14768                         param = param->left;
14769                 }
14770                 if (param && ((param->type & TYPE_MASK) == TYPE_VOID)) {
14771                         param = 0;
14772                 }
14773                 if (param) {
14774                         if (registers_of(state, param) != 1) {
14775                                 error(state, state->main_function,
14776                                         "Result: %d %s requires multiple registers",
14777                                         idx, param->field_ident->name);
14778                         }
14779                         expr = read_expr(state, call);
14780                         if ((result_type->type & TYPE_MASK) == TYPE_STRUCT) {
14781                                 expr = deref_field(state, expr, param->field_ident);
14782                         }
14783                 } else {
14784                         expr = triple(state, OP_UNKNOWNVAL, &int_type, 0, 0);
14785                 }
14786                 flatten(state, out, expr);
14787                 RHS(out, idx) = expr;
14788                 use_triple(expr, out);
14789         }
14790
14791         /* Allocate a dummy containing function */
14792         func = triple(state, OP_LIST, 
14793                 new_type(TYPE_FUNCTION, &void_type, &void_type), 0, 0);
14794         func->type->type_ident = lookup(state, "", 0);
14795         RHS(func, 0) = state->first;
14796         func->u.cval = 1;
14797
14798         /* See which functions are called, and how often */
14799         mark_live_functions(state);
14800         inline_functions(state, func);
14801         walk_functions(state, insert_function, end);
14802
14803         if (start->next != end) {
14804                 jmp = flatten(state, start, branch(state, end, 0));
14805         }
14806
14807         /* OK now the functions have been joined. */
14808         state->functions_joined = 1;
14809
14810         /* Done now cleanup */
14811         state->file = file.prev;
14812         state->function = 0;
14813 }
14814
14815 /*
14816  * Data structurs for optimation.
14817  */
14818
14819
14820 static int do_use_block(
14821         struct block *used, struct block_set **head, struct block *user, 
14822         int front)
14823 {
14824         struct block_set **ptr, *new;
14825         if (!used)
14826                 return 0;
14827         if (!user)
14828                 return 0;
14829         ptr = head;
14830         while(*ptr) {
14831                 if ((*ptr)->member == user) {
14832                         return 0;
14833                 }
14834                 ptr = &(*ptr)->next;
14835         }
14836         new = xcmalloc(sizeof(*new), "block_set");
14837         new->member = user;
14838         if (front) {
14839                 new->next = *head;
14840                 *head = new;
14841         }
14842         else {
14843                 new->next = 0;
14844                 *ptr = new;
14845         }
14846         return 1;
14847 }
14848 static int do_unuse_block(
14849         struct block *used, struct block_set **head, struct block *unuser)
14850 {
14851         struct block_set *use, **ptr;
14852         int count;
14853         count = 0;
14854         ptr = head;
14855         while(*ptr) {
14856                 use = *ptr;
14857                 if (use->member == unuser) {
14858                         *ptr = use->next;
14859                         memset(use, -1, sizeof(*use));
14860                         xfree(use);
14861                         count += 1;
14862                 }
14863                 else {
14864                         ptr = &use->next;
14865                 }
14866         }
14867         return count;
14868 }
14869
14870 static void use_block(struct block *used, struct block *user)
14871 {
14872         int count;
14873         /* Append new to the head of the list, print_block
14874          * depends on this.
14875          */
14876         count = do_use_block(used, &used->use, user, 1); 
14877         used->users += count;
14878 }
14879 static void unuse_block(struct block *used, struct block *unuser)
14880 {
14881         int count;
14882         count = do_unuse_block(used, &used->use, unuser); 
14883         used->users -= count;
14884 }
14885
14886 static void add_block_edge(struct block *block, struct block *edge, int front)
14887 {
14888         int count;
14889         count = do_use_block(block, &block->edges, edge, front);
14890         block->edge_count += count;
14891 }
14892
14893 static void remove_block_edge(struct block *block, struct block *edge)
14894 {
14895         int count;
14896         count = do_unuse_block(block, &block->edges, edge);
14897         block->edge_count -= count;
14898 }
14899
14900 static void idom_block(struct block *idom, struct block *user)
14901 {
14902         do_use_block(idom, &idom->idominates, user, 0);
14903 }
14904
14905 static void unidom_block(struct block *idom, struct block *unuser)
14906 {
14907         do_unuse_block(idom, &idom->idominates, unuser);
14908 }
14909
14910 static void domf_block(struct block *block, struct block *domf)
14911 {
14912         do_use_block(block, &block->domfrontier, domf, 0);
14913 }
14914
14915 static void undomf_block(struct block *block, struct block *undomf)
14916 {
14917         do_unuse_block(block, &block->domfrontier, undomf);
14918 }
14919
14920 static void ipdom_block(struct block *ipdom, struct block *user)
14921 {
14922         do_use_block(ipdom, &ipdom->ipdominates, user, 0);
14923 }
14924
14925 static void unipdom_block(struct block *ipdom, struct block *unuser)
14926 {
14927         do_unuse_block(ipdom, &ipdom->ipdominates, unuser);
14928 }
14929
14930 static void ipdomf_block(struct block *block, struct block *ipdomf)
14931 {
14932         do_use_block(block, &block->ipdomfrontier, ipdomf, 0);
14933 }
14934
14935 static void unipdomf_block(struct block *block, struct block *unipdomf)
14936 {
14937         do_unuse_block(block, &block->ipdomfrontier, unipdomf);
14938 }
14939
14940 static int walk_triples(
14941         struct compile_state *state, 
14942         int (*cb)(struct compile_state *state, struct triple *ptr, void *arg),
14943         void *arg)
14944 {
14945         struct triple *ptr;
14946         int result;
14947         ptr = state->first;
14948         do {
14949                 result = cb(state, ptr, arg);
14950                 if (ptr->next->prev != ptr) {
14951                         internal_error(state, ptr->next, "bad prev");
14952                 }
14953                 ptr = ptr->next;
14954         } while((result == 0) && (ptr != state->first));
14955         return result;
14956 }
14957
14958 #define PRINT_LIST 1
14959 static int do_print_triple(struct compile_state *state, struct triple *ins, void *arg)
14960 {
14961         FILE *fp = arg;
14962         int op;
14963         op = ins->op;
14964         if (op == OP_LIST) {
14965 #if !PRINT_LIST
14966                 return 0;
14967 #endif
14968         }
14969         if ((op == OP_LABEL) && (ins->use)) {
14970                 fprintf(fp, "\n%p:\n", ins);
14971         }
14972         display_triple(fp, ins);
14973
14974         if (triple_is_branch(state, ins) && ins->use && 
14975                 (ins->op != OP_RET) && (ins->op != OP_FCALL)) {
14976                 internal_error(state, ins, "branch used?");
14977         }
14978         if (triple_is_branch(state, ins)) {
14979                 fprintf(fp, "\n");
14980         }
14981         return 0;
14982 }
14983
14984 static void print_triples(struct compile_state *state)
14985 {
14986         if (state->compiler->debug & DEBUG_TRIPLES) {
14987                 FILE *fp = state->dbgout;
14988                 fprintf(fp, "--------------- triples ---------------\n");
14989                 walk_triples(state, do_print_triple, fp);
14990                 fprintf(fp, "\n");
14991         }
14992 }
14993
14994 struct cf_block {
14995         struct block *block;
14996 };
14997 static void find_cf_blocks(struct cf_block *cf, struct block *block)
14998 {
14999         struct block_set *edge;
15000         if (!block || (cf[block->vertex].block == block)) {
15001                 return;
15002         }
15003         cf[block->vertex].block = block;
15004         for(edge = block->edges; edge; edge = edge->next) {
15005                 find_cf_blocks(cf, edge->member);
15006         }
15007 }
15008
15009 static void print_control_flow(struct compile_state *state,
15010         FILE *fp, struct basic_blocks *bb)
15011 {
15012         struct cf_block *cf;
15013         int i;
15014         fprintf(fp, "\ncontrol flow\n");
15015         cf = xcmalloc(sizeof(*cf) * (bb->last_vertex + 1), "cf_block");
15016         find_cf_blocks(cf, bb->first_block);
15017
15018         for(i = 1; i <= bb->last_vertex; i++) {
15019                 struct block *block;
15020                 struct block_set *edge;
15021                 block = cf[i].block;
15022                 if (!block)
15023                         continue;
15024                 fprintf(fp, "(%p) %d:", block, block->vertex);
15025                 for(edge = block->edges; edge; edge = edge->next) {
15026                         fprintf(fp, " %d", edge->member->vertex);
15027                 }
15028                 fprintf(fp, "\n");
15029         }
15030
15031         xfree(cf);
15032 }
15033
15034 static void free_basic_block(struct compile_state *state, struct block *block)
15035 {
15036         struct block_set *edge, *entry;
15037         struct block *child;
15038         if (!block) {
15039                 return;
15040         }
15041         if (block->vertex == -1) {
15042                 return;
15043         }
15044         block->vertex = -1;
15045         for(edge = block->edges; edge; edge = edge->next) {
15046                 if (edge->member) {
15047                         unuse_block(edge->member, block);
15048                 }
15049         }
15050         if (block->idom) {
15051                 unidom_block(block->idom, block);
15052         }
15053         block->idom = 0;
15054         if (block->ipdom) {
15055                 unipdom_block(block->ipdom, block);
15056         }
15057         block->ipdom = 0;
15058         while((entry = block->use)) {
15059                 child = entry->member;
15060                 unuse_block(block, child);
15061                 if (child && (child->vertex != -1)) {
15062                         for(edge = child->edges; edge; edge = edge->next) {
15063                                 edge->member = 0;
15064                         }
15065                 }
15066         }
15067         while((entry = block->idominates)) {
15068                 child = entry->member;
15069                 unidom_block(block, child);
15070                 if (child && (child->vertex != -1)) {
15071                         child->idom = 0;
15072                 }
15073         }
15074         while((entry = block->domfrontier)) {
15075                 child = entry->member;
15076                 undomf_block(block, child);
15077         }
15078         while((entry = block->ipdominates)) {
15079                 child = entry->member;
15080                 unipdom_block(block, child);
15081                 if (child && (child->vertex != -1)) {
15082                         child->ipdom = 0;
15083                 }
15084         }
15085         while((entry = block->ipdomfrontier)) {
15086                 child = entry->member;
15087                 unipdomf_block(block, child);
15088         }
15089         if (block->users != 0) {
15090                 internal_error(state, 0, "block still has users");
15091         }
15092         while((edge = block->edges)) {
15093                 child = edge->member;
15094                 remove_block_edge(block, child);
15095                 
15096                 if (child && (child->vertex != -1)) {
15097                         free_basic_block(state, child);
15098                 }
15099         }
15100         memset(block, -1, sizeof(*block));
15101         xfree(block);
15102 }
15103
15104 static void free_basic_blocks(struct compile_state *state, 
15105         struct basic_blocks *bb)
15106 {
15107         struct triple *first, *ins;
15108         free_basic_block(state, bb->first_block);
15109         bb->last_vertex = 0;
15110         bb->first_block = bb->last_block = 0;
15111         first = bb->first;
15112         ins = first;
15113         do {
15114                 if (triple_stores_block(state, ins)) {
15115                         ins->u.block = 0;
15116                 }
15117                 ins = ins->next;
15118         } while(ins != first);
15119         
15120 }
15121
15122 static struct block *basic_block(struct compile_state *state, 
15123         struct basic_blocks *bb, struct triple *first)
15124 {
15125         struct block *block;
15126         struct triple *ptr;
15127         if (!triple_is_label(state, first)) {
15128                 internal_error(state, first, "block does not start with a label");
15129         }
15130         /* See if this basic block has already been setup */
15131         if (first->u.block != 0) {
15132                 return first->u.block;
15133         }
15134         /* Allocate another basic block structure */
15135         bb->last_vertex += 1;
15136         block = xcmalloc(sizeof(*block), "block");
15137         block->first = block->last = first;
15138         block->vertex = bb->last_vertex;
15139         ptr = first;
15140         do {
15141                 if ((ptr != first) && triple_is_label(state, ptr) && (ptr->use)) { 
15142                         break;
15143                 }
15144                 block->last = ptr;
15145                 /* If ptr->u is not used remember where the baic block is */
15146                 if (triple_stores_block(state, ptr)) {
15147                         ptr->u.block = block;
15148                 }
15149                 if (triple_is_branch(state, ptr)) {
15150                         break;
15151                 }
15152                 ptr = ptr->next;
15153         } while (ptr != bb->first);
15154         if ((ptr == bb->first) ||
15155                 ((ptr->next == bb->first) && (
15156                         triple_is_end(state, ptr) || 
15157                         triple_is_ret(state, ptr))))
15158         {
15159                 /* The block has no outflowing edges */
15160         }
15161         else if (triple_is_label(state, ptr)) {
15162                 struct block *next;
15163                 next = basic_block(state, bb, ptr);
15164                 add_block_edge(block, next, 0);
15165                 use_block(next, block);
15166         }
15167         else if (triple_is_branch(state, ptr)) {
15168                 struct triple **expr, *first;
15169                 struct block *child;
15170                 /* Find the branch targets.
15171                  * I special case the first branch as that magically
15172                  * avoids some difficult cases for the register allocator.
15173                  */
15174                 expr = triple_edge_targ(state, ptr, 0);
15175                 if (!expr) {
15176                         internal_error(state, ptr, "branch without targets");
15177                 }
15178                 first = *expr;
15179                 expr = triple_edge_targ(state, ptr, expr);
15180                 for(; expr; expr = triple_edge_targ(state, ptr, expr)) {
15181                         if (!*expr) continue;
15182                         child = basic_block(state, bb, *expr);
15183                         use_block(child, block);
15184                         add_block_edge(block, child, 0);
15185                 }
15186                 if (first) {
15187                         child = basic_block(state, bb, first);
15188                         use_block(child, block);
15189                         add_block_edge(block, child, 1);
15190
15191                         /* Be certain the return block of a call is
15192                          * in a basic block.  When it is not find
15193                          * start of the block, insert a label if
15194                          * necessary and build the basic block.
15195                          * Then add a fake edge from the start block
15196                          * to the return block of the function.
15197                          */
15198                         if (state->functions_joined && triple_is_call(state, ptr)
15199                                 && !block_of_triple(state, MISC(ptr, 0))) {
15200                                 struct block *tail;
15201                                 struct triple *start;
15202                                 start = triple_to_block_start(state, MISC(ptr, 0));
15203                                 if (!triple_is_label(state, start)) {
15204                                         start = pre_triple(state,
15205                                                 start, OP_LABEL, &void_type, 0, 0);
15206                                 }
15207                                 tail = basic_block(state, bb, start);
15208                                 add_block_edge(child, tail, 0);
15209                                 use_block(tail, child);
15210                         }
15211                 }
15212         }
15213         else {
15214                 internal_error(state, 0, "Bad basic block split");
15215         }
15216 #if 0
15217 {
15218         struct block_set *edge;
15219         FILE *fp = state->errout;
15220         fprintf(fp, "basic_block: %10p [%2d] ( %10p - %10p )",
15221                 block, block->vertex, 
15222                 block->first, block->last);
15223         for(edge = block->edges; edge; edge = edge->next) {
15224                 fprintf(fp, " %10p [%2d]",
15225                         edge->member ? edge->member->first : 0,
15226                         edge->member ? edge->member->vertex : -1);
15227         }
15228         fprintf(fp, "\n");
15229 }
15230 #endif
15231         return block;
15232 }
15233
15234
15235 static void walk_blocks(struct compile_state *state, struct basic_blocks *bb,
15236         void (*cb)(struct compile_state *state, struct block *block, void *arg),
15237         void *arg)
15238 {
15239         struct triple *ptr, *first;
15240         struct block *last_block;
15241         last_block = 0;
15242         first = bb->first;
15243         ptr = first;
15244         do {
15245                 if (triple_stores_block(state, ptr)) {
15246                         struct block *block;
15247                         block = ptr->u.block;
15248                         if (block && (block != last_block)) {
15249                                 cb(state, block, arg);
15250                         }
15251                         last_block = block;
15252                 }
15253                 ptr = ptr->next;
15254         } while(ptr != first);
15255 }
15256
15257 static void print_block(
15258         struct compile_state *state, struct block *block, void *arg)
15259 {
15260         struct block_set *user, *edge;
15261         struct triple *ptr;
15262         FILE *fp = arg;
15263
15264         fprintf(fp, "\nblock: %p (%d) ",
15265                 block, 
15266                 block->vertex);
15267
15268         for(edge = block->edges; edge; edge = edge->next) {
15269                 fprintf(fp, " %p<-%p",
15270                         edge->member,
15271                         (edge->member && edge->member->use)?
15272                         edge->member->use->member : 0);
15273         }
15274         fprintf(fp, "\n");
15275         if (block->first->op == OP_LABEL) {
15276                 fprintf(fp, "%p:\n", block->first);
15277         }
15278         for(ptr = block->first; ; ) {
15279                 display_triple(fp, ptr);
15280                 if (ptr == block->last)
15281                         break;
15282                 ptr = ptr->next;
15283                 if (ptr == block->first) {
15284                         internal_error(state, 0, "missing block last?");
15285                 }
15286         }
15287         fprintf(fp, "users %d: ", block->users);
15288         for(user = block->use; user; user = user->next) {
15289                 fprintf(fp, "%p (%d) ", 
15290                         user->member,
15291                         user->member->vertex);
15292         }
15293         fprintf(fp,"\n\n");
15294 }
15295
15296
15297 static void romcc_print_blocks(struct compile_state *state, FILE *fp)
15298 {
15299         fprintf(fp, "--------------- blocks ---------------\n");
15300         walk_blocks(state, &state->bb, print_block, fp);
15301 }
15302 static void print_blocks(struct compile_state *state, const char *func, FILE *fp)
15303 {
15304         if (state->compiler->debug & DEBUG_BASIC_BLOCKS) {
15305                 fprintf(fp, "After %s\n", func);
15306                 romcc_print_blocks(state, fp);
15307                 if (state->compiler->debug & DEBUG_FDOMINATORS) {
15308                         print_dominators(state, fp, &state->bb);
15309                         print_dominance_frontiers(state, fp, &state->bb);
15310                 }
15311                 print_control_flow(state, fp, &state->bb);
15312         }
15313 }
15314
15315 static void prune_nonblock_triples(struct compile_state *state, 
15316         struct basic_blocks *bb)
15317 {
15318         struct block *block;
15319         struct triple *first, *ins, *next;
15320         /* Delete the triples not in a basic block */
15321         block = 0;
15322         first = bb->first;
15323         ins = first;
15324         do {
15325                 next = ins->next;
15326                 if (ins->op == OP_LABEL) {
15327                         block = ins->u.block;
15328                 }
15329                 if (!block) {
15330                         struct triple_set *use;
15331                         for(use = ins->use; use; use = use->next) {
15332                                 struct block *block;
15333                                 block = block_of_triple(state, use->member);
15334                                 if (block != 0) {
15335                                         internal_error(state, ins, "pruning used ins?");
15336                                 }
15337                         }
15338                         release_triple(state, ins);
15339                 }
15340                 if (block && block->last == ins) {
15341                         block = 0;
15342                 }
15343                 ins = next;
15344         } while(ins != first);
15345 }
15346
15347 static void setup_basic_blocks(struct compile_state *state, 
15348         struct basic_blocks *bb)
15349 {
15350         if (!triple_stores_block(state, bb->first)) {
15351                 internal_error(state, 0, "ins will not store block?");
15352         }
15353         /* Initialize the state */
15354         bb->first_block = bb->last_block = 0;
15355         bb->last_vertex = 0;
15356         free_basic_blocks(state, bb);
15357
15358         /* Find the basic blocks */
15359         bb->first_block = basic_block(state, bb, bb->first);
15360
15361         /* Be certain the last instruction of a function, or the
15362          * entire program is in a basic block.  When it is not find 
15363          * the start of the block, insert a label if necessary and build 
15364          * basic block.  Then add a fake edge from the start block
15365          * to the final block.
15366          */
15367         if (!block_of_triple(state, bb->first->prev)) {
15368                 struct triple *start;
15369                 struct block *tail;
15370                 start = triple_to_block_start(state, bb->first->prev);
15371                 if (!triple_is_label(state, start)) {
15372                         start = pre_triple(state,
15373                                 start, OP_LABEL, &void_type, 0, 0);
15374                 }
15375                 tail = basic_block(state, bb, start);
15376                 add_block_edge(bb->first_block, tail, 0);
15377                 use_block(tail, bb->first_block);
15378         }
15379         
15380         /* Find the last basic block.
15381          */
15382         bb->last_block = block_of_triple(state, bb->first->prev);
15383
15384         /* Delete the triples not in a basic block */
15385         prune_nonblock_triples(state, bb);
15386
15387 #if 0
15388         /* If we are debugging print what I have just done */
15389         if (state->compiler->debug & DEBUG_BASIC_BLOCKS) {
15390                 print_blocks(state, state->dbgout);
15391                 print_control_flow(state, bb);
15392         }
15393 #endif
15394 }
15395
15396
15397 struct sdom_block {
15398         struct block *block;
15399         struct sdom_block *sdominates;
15400         struct sdom_block *sdom_next;
15401         struct sdom_block *sdom;
15402         struct sdom_block *label;
15403         struct sdom_block *parent;
15404         struct sdom_block *ancestor;
15405         int vertex;
15406 };
15407
15408
15409 static void unsdom_block(struct sdom_block *block)
15410 {
15411         struct sdom_block **ptr;
15412         if (!block->sdom_next) {
15413                 return;
15414         }
15415         ptr = &block->sdom->sdominates;
15416         while(*ptr) {
15417                 if ((*ptr) == block) {
15418                         *ptr = block->sdom_next;
15419                         return;
15420                 }
15421                 ptr = &(*ptr)->sdom_next;
15422         }
15423 }
15424
15425 static void sdom_block(struct sdom_block *sdom, struct sdom_block *block)
15426 {
15427         unsdom_block(block);
15428         block->sdom = sdom;
15429         block->sdom_next = sdom->sdominates;
15430         sdom->sdominates = block;
15431 }
15432
15433
15434
15435 static int initialize_sdblock(struct sdom_block *sd,
15436         struct block *parent, struct block *block, int vertex)
15437 {
15438         struct block_set *edge;
15439         if (!block || (sd[block->vertex].block == block)) {
15440                 return vertex;
15441         }
15442         vertex += 1;
15443         /* Renumber the blocks in a convinient fashion */
15444         block->vertex = vertex;
15445         sd[vertex].block    = block;
15446         sd[vertex].sdom     = &sd[vertex];
15447         sd[vertex].label    = &sd[vertex];
15448         sd[vertex].parent   = parent? &sd[parent->vertex] : 0;
15449         sd[vertex].ancestor = 0;
15450         sd[vertex].vertex   = vertex;
15451         for(edge = block->edges; edge; edge = edge->next) {
15452                 vertex = initialize_sdblock(sd, block, edge->member, vertex);
15453         }
15454         return vertex;
15455 }
15456
15457 static int initialize_spdblock(
15458         struct compile_state *state, struct sdom_block *sd,
15459         struct block *parent, struct block *block, int vertex)
15460 {
15461         struct block_set *user;
15462         if (!block || (sd[block->vertex].block == block)) {
15463                 return vertex;
15464         }
15465         vertex += 1;
15466         /* Renumber the blocks in a convinient fashion */
15467         block->vertex = vertex;
15468         sd[vertex].block    = block;
15469         sd[vertex].sdom     = &sd[vertex];
15470         sd[vertex].label    = &sd[vertex];
15471         sd[vertex].parent   = parent? &sd[parent->vertex] : 0;
15472         sd[vertex].ancestor = 0;
15473         sd[vertex].vertex   = vertex;
15474         for(user = block->use; user; user = user->next) {
15475                 vertex = initialize_spdblock(state, sd, block, user->member, vertex);
15476         }
15477         return vertex;
15478 }
15479
15480 static int setup_spdblocks(struct compile_state *state, 
15481         struct basic_blocks *bb, struct sdom_block *sd)
15482 {
15483         struct block *block;
15484         int vertex;
15485         /* Setup as many sdpblocks as possible without using fake edges */
15486         vertex = initialize_spdblock(state, sd, 0, bb->last_block, 0);
15487
15488         /* Walk through the graph and find unconnected blocks.  Add a
15489          * fake edge from the unconnected blocks to the end of the
15490          * graph. 
15491          */
15492         block = bb->first_block->last->next->u.block;
15493         for(; block && block != bb->first_block; block = block->last->next->u.block) {
15494                 if (sd[block->vertex].block == block) {
15495                         continue;
15496                 }
15497 #if DEBUG_SDP_BLOCKS
15498                 {
15499                         FILE *fp = state->errout;
15500                         fprintf(fp, "Adding %d\n", vertex +1);
15501                 }
15502 #endif
15503                 add_block_edge(block, bb->last_block, 0);
15504                 use_block(bb->last_block, block);
15505
15506                 vertex = initialize_spdblock(state, sd, bb->last_block, block, vertex);
15507         }
15508         return vertex;
15509 }
15510
15511 static void compress_ancestors(struct sdom_block *v)
15512 {
15513         /* This procedure assumes ancestor(v) != 0 */
15514         /* if (ancestor(ancestor(v)) != 0) {
15515          *      compress(ancestor(ancestor(v)));
15516          *      if (semi(label(ancestor(v))) < semi(label(v))) {
15517          *              label(v) = label(ancestor(v));
15518          *      }
15519          *      ancestor(v) = ancestor(ancestor(v));
15520          * }
15521          */
15522         if (!v->ancestor) {
15523                 return;
15524         }
15525         if (v->ancestor->ancestor) {
15526                 compress_ancestors(v->ancestor->ancestor);
15527                 if (v->ancestor->label->sdom->vertex < v->label->sdom->vertex) {
15528                         v->label = v->ancestor->label;
15529                 }
15530                 v->ancestor = v->ancestor->ancestor;
15531         }
15532 }
15533
15534 static void compute_sdom(struct compile_state *state, 
15535         struct basic_blocks *bb, struct sdom_block *sd)
15536 {
15537         int i;
15538         /* // step 2 
15539          *  for each v <= pred(w) {
15540          *      u = EVAL(v);
15541          *      if (semi[u] < semi[w] { 
15542          *              semi[w] = semi[u]; 
15543          *      } 
15544          * }
15545          * add w to bucket(vertex(semi[w]));
15546          * LINK(parent(w), w);
15547          *
15548          * // step 3
15549          * for each v <= bucket(parent(w)) {
15550          *      delete v from bucket(parent(w));
15551          *      u = EVAL(v);
15552          *      dom(v) = (semi[u] < semi[v]) ? u : parent(w);
15553          * }
15554          */
15555         for(i = bb->last_vertex; i >= 2; i--) {
15556                 struct sdom_block *v, *parent, *next;
15557                 struct block_set *user;
15558                 struct block *block;
15559                 block = sd[i].block;
15560                 parent = sd[i].parent;
15561                 /* Step 2 */
15562                 for(user = block->use; user; user = user->next) {
15563                         struct sdom_block *v, *u;
15564                         v = &sd[user->member->vertex];
15565                         u = !(v->ancestor)? v : (compress_ancestors(v), v->label);
15566                         if (u->sdom->vertex < sd[i].sdom->vertex) {
15567                                 sd[i].sdom = u->sdom;
15568                         }
15569                 }
15570                 sdom_block(sd[i].sdom, &sd[i]);
15571                 sd[i].ancestor = parent;
15572                 /* Step 3 */
15573                 for(v = parent->sdominates; v; v = next) {
15574                         struct sdom_block *u;
15575                         next = v->sdom_next;
15576                         unsdom_block(v);
15577                         u = (!v->ancestor) ? v : (compress_ancestors(v), v->label);
15578                         v->block->idom = (u->sdom->vertex < v->sdom->vertex)? 
15579                                 u->block : parent->block;
15580                 }
15581         }
15582 }
15583
15584 static void compute_spdom(struct compile_state *state, 
15585         struct basic_blocks *bb, struct sdom_block *sd)
15586 {
15587         int i;
15588         /* // step 2 
15589          *  for each v <= pred(w) {
15590          *      u = EVAL(v);
15591          *      if (semi[u] < semi[w] { 
15592          *              semi[w] = semi[u]; 
15593          *      } 
15594          * }
15595          * add w to bucket(vertex(semi[w]));
15596          * LINK(parent(w), w);
15597          *
15598          * // step 3
15599          * for each v <= bucket(parent(w)) {
15600          *      delete v from bucket(parent(w));
15601          *      u = EVAL(v);
15602          *      dom(v) = (semi[u] < semi[v]) ? u : parent(w);
15603          * }
15604          */
15605         for(i = bb->last_vertex; i >= 2; i--) {
15606                 struct sdom_block *u, *v, *parent, *next;
15607                 struct block_set *edge;
15608                 struct block *block;
15609                 block = sd[i].block;
15610                 parent = sd[i].parent;
15611                 /* Step 2 */
15612                 for(edge = block->edges; edge; edge = edge->next) {
15613                         v = &sd[edge->member->vertex];
15614                         u = !(v->ancestor)? v : (compress_ancestors(v), v->label);
15615                         if (u->sdom->vertex < sd[i].sdom->vertex) {
15616                                 sd[i].sdom = u->sdom;
15617                         }
15618                 }
15619                 sdom_block(sd[i].sdom, &sd[i]);
15620                 sd[i].ancestor = parent;
15621                 /* Step 3 */
15622                 for(v = parent->sdominates; v; v = next) {
15623                         struct sdom_block *u;
15624                         next = v->sdom_next;
15625                         unsdom_block(v);
15626                         u = (!v->ancestor) ? v : (compress_ancestors(v), v->label);
15627                         v->block->ipdom = (u->sdom->vertex < v->sdom->vertex)? 
15628                                 u->block : parent->block;
15629                 }
15630         }
15631 }
15632
15633 static void compute_idom(struct compile_state *state, 
15634         struct basic_blocks *bb, struct sdom_block *sd)
15635 {
15636         int i;
15637         for(i = 2; i <= bb->last_vertex; i++) {
15638                 struct block *block;
15639                 block = sd[i].block;
15640                 if (block->idom->vertex != sd[i].sdom->vertex) {
15641                         block->idom = block->idom->idom;
15642                 }
15643                 idom_block(block->idom, block);
15644         }
15645         sd[1].block->idom = 0;
15646 }
15647
15648 static void compute_ipdom(struct compile_state *state, 
15649         struct basic_blocks *bb, struct sdom_block *sd)
15650 {
15651         int i;
15652         for(i = 2; i <= bb->last_vertex; i++) {
15653                 struct block *block;
15654                 block = sd[i].block;
15655                 if (block->ipdom->vertex != sd[i].sdom->vertex) {
15656                         block->ipdom = block->ipdom->ipdom;
15657                 }
15658                 ipdom_block(block->ipdom, block);
15659         }
15660         sd[1].block->ipdom = 0;
15661 }
15662
15663         /* Theorem 1:
15664          *   Every vertex of a flowgraph G = (V, E, r) except r has
15665          *   a unique immediate dominator.  
15666          *   The edges {(idom(w), w) |w <= V - {r}} form a directed tree
15667          *   rooted at r, called the dominator tree of G, such that 
15668          *   v dominates w if and only if v is a proper ancestor of w in
15669          *   the dominator tree.
15670          */
15671         /* Lemma 1:  
15672          *   If v and w are vertices of G such that v <= w,
15673          *   than any path from v to w must contain a common ancestor
15674          *   of v and w in T.
15675          */
15676         /* Lemma 2:  For any vertex w != r, idom(w) -> w */
15677         /* Lemma 3:  For any vertex w != r, sdom(w) -> w */
15678         /* Lemma 4:  For any vertex w != r, idom(w) -> sdom(w) */
15679         /* Theorem 2:
15680          *   Let w != r.  Suppose every u for which sdom(w) -> u -> w satisfies
15681          *   sdom(u) >= sdom(w).  Then idom(w) = sdom(w).
15682          */
15683         /* Theorem 3:
15684          *   Let w != r and let u be a vertex for which sdom(u) is 
15685          *   minimum amoung vertices u satisfying sdom(w) -> u -> w.
15686          *   Then sdom(u) <= sdom(w) and idom(u) = idom(w).
15687          */
15688         /* Lemma 5:  Let vertices v,w satisfy v -> w.
15689          *           Then v -> idom(w) or idom(w) -> idom(v)
15690          */
15691
15692 static void find_immediate_dominators(struct compile_state *state,
15693         struct basic_blocks *bb)
15694 {
15695         struct sdom_block *sd;
15696         /* w->sdom = min{v| there is a path v = v0,v1,...,vk = w such that:
15697          *           vi > w for (1 <= i <= k - 1}
15698          */
15699         /* Theorem 4:
15700          *   For any vertex w != r.
15701          *   sdom(w) = min(
15702          *                 {v|(v,w) <= E  and v < w } U 
15703          *                 {sdom(u) | u > w and there is an edge (v, w) such that u -> v})
15704          */
15705         /* Corollary 1:
15706          *   Let w != r and let u be a vertex for which sdom(u) is 
15707          *   minimum amoung vertices u satisfying sdom(w) -> u -> w.
15708          *   Then:
15709          *                   { sdom(w) if sdom(w) = sdom(u),
15710          *        idom(w) = {
15711          *                   { idom(u) otherwise
15712          */
15713         /* The algorithm consists of the following 4 steps.
15714          * Step 1.  Carry out a depth-first search of the problem graph.  
15715          *    Number the vertices from 1 to N as they are reached during
15716          *    the search.  Initialize the variables used in succeeding steps.
15717          * Step 2.  Compute the semidominators of all vertices by applying
15718          *    theorem 4.   Carry out the computation vertex by vertex in
15719          *    decreasing order by number.
15720          * Step 3.  Implicitly define the immediate dominator of each vertex
15721          *    by applying Corollary 1.
15722          * Step 4.  Explicitly define the immediate dominator of each vertex,
15723          *    carrying out the computation vertex by vertex in increasing order
15724          *    by number.
15725          */
15726         /* Step 1 initialize the basic block information */
15727         sd = xcmalloc(sizeof(*sd) * (bb->last_vertex + 1), "sdom_state");
15728         initialize_sdblock(sd, 0, bb->first_block, 0);
15729 #if 0
15730         sd[1].size  = 0;
15731         sd[1].label = 0;
15732         sd[1].sdom  = 0;
15733 #endif
15734         /* Step 2 compute the semidominators */
15735         /* Step 3 implicitly define the immediate dominator of each vertex */
15736         compute_sdom(state, bb, sd);
15737         /* Step 4 explicitly define the immediate dominator of each vertex */
15738         compute_idom(state, bb, sd);
15739         xfree(sd);
15740 }
15741
15742 static void find_post_dominators(struct compile_state *state,
15743         struct basic_blocks *bb)
15744 {
15745         struct sdom_block *sd;
15746         int vertex;
15747         /* Step 1 initialize the basic block information */
15748         sd = xcmalloc(sizeof(*sd) * (bb->last_vertex + 1), "sdom_state");
15749
15750         vertex = setup_spdblocks(state, bb, sd);
15751         if (vertex != bb->last_vertex) {
15752                 internal_error(state, 0, "missing %d blocks",
15753                         bb->last_vertex - vertex);
15754         }
15755
15756         /* Step 2 compute the semidominators */
15757         /* Step 3 implicitly define the immediate dominator of each vertex */
15758         compute_spdom(state, bb, sd);
15759         /* Step 4 explicitly define the immediate dominator of each vertex */
15760         compute_ipdom(state, bb, sd);
15761         xfree(sd);
15762 }
15763
15764
15765
15766 static void find_block_domf(struct compile_state *state, struct block *block)
15767 {
15768         struct block *child;
15769         struct block_set *user, *edge;
15770         if (block->domfrontier != 0) {
15771                 internal_error(state, block->first, "domfrontier present?");
15772         }
15773         for(user = block->idominates; user; user = user->next) {
15774                 child = user->member;
15775                 if (child->idom != block) {
15776                         internal_error(state, block->first, "bad idom");
15777                 }
15778                 find_block_domf(state, child);
15779         }
15780         for(edge = block->edges; edge; edge = edge->next) {
15781                 if (edge->member->idom != block) {
15782                         domf_block(block, edge->member);
15783                 }
15784         }
15785         for(user = block->idominates; user; user = user->next) {
15786                 struct block_set *frontier;
15787                 child = user->member;
15788                 for(frontier = child->domfrontier; frontier; frontier = frontier->next) {
15789                         if (frontier->member->idom != block) {
15790                                 domf_block(block, frontier->member);
15791                         }
15792                 }
15793         }
15794 }
15795
15796 static void find_block_ipdomf(struct compile_state *state, struct block *block)
15797 {
15798         struct block *child;
15799         struct block_set *user;
15800         if (block->ipdomfrontier != 0) {
15801                 internal_error(state, block->first, "ipdomfrontier present?");
15802         }
15803         for(user = block->ipdominates; user; user = user->next) {
15804                 child = user->member;
15805                 if (child->ipdom != block) {
15806                         internal_error(state, block->first, "bad ipdom");
15807                 }
15808                 find_block_ipdomf(state, child);
15809         }
15810         for(user = block->use; user; user = user->next) {
15811                 if (user->member->ipdom != block) {
15812                         ipdomf_block(block, user->member);
15813                 }
15814         }
15815         for(user = block->ipdominates; user; user = user->next) {
15816                 struct block_set *frontier;
15817                 child = user->member;
15818                 for(frontier = child->ipdomfrontier; frontier; frontier = frontier->next) {
15819                         if (frontier->member->ipdom != block) {
15820                                 ipdomf_block(block, frontier->member);
15821                         }
15822                 }
15823         }
15824 }
15825
15826 static void print_dominated(
15827         struct compile_state *state, struct block *block, void *arg)
15828 {
15829         struct block_set *user;
15830         FILE *fp = arg;
15831
15832         fprintf(fp, "%d:", block->vertex);
15833         for(user = block->idominates; user; user = user->next) {
15834                 fprintf(fp, " %d", user->member->vertex);
15835                 if (user->member->idom != block) {
15836                         internal_error(state, user->member->first, "bad idom");
15837                 }
15838         }
15839         fprintf(fp,"\n");
15840 }
15841
15842 static void print_dominated2(
15843         struct compile_state *state, FILE *fp, int depth, struct block *block)
15844 {
15845         struct block_set *user;
15846         struct triple *ins;
15847         struct occurance *ptr, *ptr2;
15848         const char *filename1, *filename2;
15849         int equal_filenames;
15850         int i;
15851         for(i = 0; i < depth; i++) {
15852                 fprintf(fp, "   ");
15853         }
15854         fprintf(fp, "%3d: %p (%p - %p) @", 
15855                 block->vertex, block, block->first, block->last);
15856         ins = block->first;
15857         while(ins != block->last && (ins->occurance->line == 0)) {
15858                 ins = ins->next;
15859         }
15860         ptr = ins->occurance;
15861         ptr2 = block->last->occurance;
15862         filename1 = ptr->filename? ptr->filename : "";
15863         filename2 = ptr2->filename? ptr2->filename : "";
15864         equal_filenames = (strcmp(filename1, filename2) == 0);
15865         if ((ptr == ptr2) || (equal_filenames && ptr->line == ptr2->line)) {
15866                 fprintf(fp, " %s:%d", ptr->filename, ptr->line);
15867         } else if (equal_filenames) {
15868                 fprintf(fp, " %s:(%d - %d)",
15869                         ptr->filename, ptr->line, ptr2->line);
15870         } else {
15871                 fprintf(fp, " (%s:%d - %s:%d)",
15872                         ptr->filename, ptr->line,
15873                         ptr2->filename, ptr2->line);
15874         }
15875         fprintf(fp, "\n");
15876         for(user = block->idominates; user; user = user->next) {
15877                 print_dominated2(state, fp, depth + 1, user->member);
15878         }
15879 }
15880
15881 static void print_dominators(struct compile_state *state, FILE *fp, struct basic_blocks *bb)
15882 {
15883         fprintf(fp, "\ndominates\n");
15884         walk_blocks(state, bb, print_dominated, fp);
15885         fprintf(fp, "dominates\n");
15886         print_dominated2(state, fp, 0, bb->first_block);
15887 }
15888
15889
15890 static int print_frontiers(
15891         struct compile_state *state, FILE *fp, struct block *block, int vertex)
15892 {
15893         struct block_set *user, *edge;
15894
15895         if (!block || (block->vertex != vertex + 1)) {
15896                 return vertex;
15897         }
15898         vertex += 1;
15899
15900         fprintf(fp, "%d:", block->vertex);
15901         for(user = block->domfrontier; user; user = user->next) {
15902                 fprintf(fp, " %d", user->member->vertex);
15903         }
15904         fprintf(fp, "\n");
15905         
15906         for(edge = block->edges; edge; edge = edge->next) {
15907                 vertex = print_frontiers(state, fp, edge->member, vertex);
15908         }
15909         return vertex;
15910 }
15911 static void print_dominance_frontiers(struct compile_state *state,
15912         FILE *fp, struct basic_blocks *bb)
15913 {
15914         fprintf(fp, "\ndominance frontiers\n");
15915         print_frontiers(state, fp, bb->first_block, 0);
15916         
15917 }
15918
15919 static void analyze_idominators(struct compile_state *state, struct basic_blocks *bb)
15920 {
15921         /* Find the immediate dominators */
15922         find_immediate_dominators(state, bb);
15923         /* Find the dominance frontiers */
15924         find_block_domf(state, bb->first_block);
15925         /* If debuging print the print what I have just found */
15926         if (state->compiler->debug & DEBUG_FDOMINATORS) {
15927                 print_dominators(state, state->dbgout, bb);
15928                 print_dominance_frontiers(state, state->dbgout, bb);
15929                 print_control_flow(state, state->dbgout, bb);
15930         }
15931 }
15932
15933
15934 static void print_ipdominated(
15935         struct compile_state *state, struct block *block, void *arg)
15936 {
15937         struct block_set *user;
15938         FILE *fp = arg;
15939
15940         fprintf(fp, "%d:", block->vertex);
15941         for(user = block->ipdominates; user; user = user->next) {
15942                 fprintf(fp, " %d", user->member->vertex);
15943                 if (user->member->ipdom != block) {
15944                         internal_error(state, user->member->first, "bad ipdom");
15945                 }
15946         }
15947         fprintf(fp, "\n");
15948 }
15949
15950 static void print_ipdominators(struct compile_state *state, FILE *fp,
15951         struct basic_blocks *bb)
15952 {
15953         fprintf(fp, "\nipdominates\n");
15954         walk_blocks(state, bb, print_ipdominated, fp);
15955 }
15956
15957 static int print_pfrontiers(
15958         struct compile_state *state, FILE *fp, struct block *block, int vertex)
15959 {
15960         struct block_set *user;
15961
15962         if (!block || (block->vertex != vertex + 1)) {
15963                 return vertex;
15964         }
15965         vertex += 1;
15966
15967         fprintf(fp, "%d:", block->vertex);
15968         for(user = block->ipdomfrontier; user; user = user->next) {
15969                 fprintf(fp, " %d", user->member->vertex);
15970         }
15971         fprintf(fp, "\n");
15972         for(user = block->use; user; user = user->next) {
15973                 vertex = print_pfrontiers(state, fp, user->member, vertex);
15974         }
15975         return vertex;
15976 }
15977 static void print_ipdominance_frontiers(struct compile_state *state,
15978         FILE *fp, struct basic_blocks *bb)
15979 {
15980         fprintf(fp, "\nipdominance frontiers\n");
15981         print_pfrontiers(state, fp, bb->last_block, 0);
15982         
15983 }
15984
15985 static void analyze_ipdominators(struct compile_state *state,
15986         struct basic_blocks *bb)
15987 {
15988         /* Find the post dominators */
15989         find_post_dominators(state, bb);
15990         /* Find the control dependencies (post dominance frontiers) */
15991         find_block_ipdomf(state, bb->last_block);
15992         /* If debuging print the print what I have just found */
15993         if (state->compiler->debug & DEBUG_RDOMINATORS) {
15994                 print_ipdominators(state, state->dbgout, bb);
15995                 print_ipdominance_frontiers(state, state->dbgout, bb);
15996                 print_control_flow(state, state->dbgout, bb);
15997         }
15998 }
15999
16000 static int bdominates(struct compile_state *state,
16001         struct block *dom, struct block *sub)
16002 {
16003         while(sub && (sub != dom)) {
16004                 sub = sub->idom;
16005         }
16006         return sub == dom;
16007 }
16008
16009 static int tdominates(struct compile_state *state,
16010         struct triple *dom, struct triple *sub)
16011 {
16012         struct block *bdom, *bsub;
16013         int result;
16014         bdom = block_of_triple(state, dom);
16015         bsub = block_of_triple(state, sub);
16016         if (bdom != bsub) {
16017                 result = bdominates(state, bdom, bsub);
16018         } 
16019         else {
16020                 struct triple *ins;
16021                 if (!bdom || !bsub) {
16022                         internal_error(state, dom, "huh?");
16023                 }
16024                 ins = sub;
16025                 while((ins != bsub->first) && (ins != dom)) {
16026                         ins = ins->prev;
16027                 }
16028                 result = (ins == dom);
16029         }
16030         return result;
16031 }
16032
16033 static void analyze_basic_blocks(
16034         struct compile_state *state, struct basic_blocks *bb)
16035 {
16036         setup_basic_blocks(state, bb);
16037         analyze_idominators(state, bb);
16038         analyze_ipdominators(state, bb);
16039 }
16040
16041 static void insert_phi_operations(struct compile_state *state)
16042 {
16043         size_t size;
16044         struct triple *first;
16045         int *has_already, *work;
16046         struct block *work_list, **work_list_tail;
16047         int iter;
16048         struct triple *var, *vnext;
16049
16050         size = sizeof(int) * (state->bb.last_vertex + 1);
16051         has_already = xcmalloc(size, "has_already");
16052         work =        xcmalloc(size, "work");
16053         iter = 0;
16054
16055         first = state->first;
16056         for(var = first->next; var != first ; var = vnext) {
16057                 struct block *block;
16058                 struct triple_set *user, *unext;
16059                 vnext = var->next;
16060
16061                 if (!triple_is_auto_var(state, var) || !var->use) {
16062                         continue;
16063                 }
16064                         
16065                 iter += 1;
16066                 work_list = 0;
16067                 work_list_tail = &work_list;
16068                 for(user = var->use; user; user = unext) {
16069                         unext = user->next;
16070                         if (MISC(var, 0) == user->member) {
16071                                 continue;
16072                         }
16073                         if (user->member->op == OP_READ) {
16074                                 continue;
16075                         }
16076                         if (user->member->op != OP_WRITE) {
16077                                 internal_error(state, user->member, 
16078                                         "bad variable access");
16079                         }
16080                         block = user->member->u.block;
16081                         if (!block) {
16082                                 warning(state, user->member, "dead code");
16083                                 release_triple(state, user->member);
16084                                 continue;
16085                         }
16086                         if (work[block->vertex] >= iter) {
16087                                 continue;
16088                         }
16089                         work[block->vertex] = iter;
16090                         *work_list_tail = block;
16091                         block->work_next = 0;
16092                         work_list_tail = &block->work_next;
16093                 }
16094                 for(block = work_list; block; block = block->work_next) {
16095                         struct block_set *df;
16096                         for(df = block->domfrontier; df; df = df->next) {
16097                                 struct triple *phi;
16098                                 struct block *front;
16099                                 int in_edges;
16100                                 front = df->member;
16101
16102                                 if (has_already[front->vertex] >= iter) {
16103                                         continue;
16104                                 }
16105                                 /* Count how many edges flow into this block */
16106                                 in_edges = front->users;
16107                                 /* Insert a phi function for this variable */
16108                                 get_occurance(var->occurance);
16109                                 phi = alloc_triple(
16110                                         state, OP_PHI, var->type, -1, in_edges, 
16111                                         var->occurance);
16112                                 phi->u.block = front;
16113                                 MISC(phi, 0) = var;
16114                                 use_triple(var, phi);
16115 #if 1
16116                                 if (phi->rhs != in_edges) {
16117                                         internal_error(state, phi, "phi->rhs: %d != in_edges: %d",
16118                                                 phi->rhs, in_edges);
16119                                 }
16120 #endif
16121                                 /* Insert the phi functions immediately after the label */
16122                                 insert_triple(state, front->first->next, phi);
16123                                 if (front->first == front->last) {
16124                                         front->last = front->first->next;
16125                                 }
16126                                 has_already[front->vertex] = iter;
16127                                 transform_to_arch_instruction(state, phi);
16128
16129                                 /* If necessary plan to visit the basic block */
16130                                 if (work[front->vertex] >= iter) {
16131                                         continue;
16132                                 }
16133                                 work[front->vertex] = iter;
16134                                 *work_list_tail = front;
16135                                 front->work_next = 0;
16136                                 work_list_tail = &front->work_next;
16137                         }
16138                 }
16139         }
16140         xfree(has_already);
16141         xfree(work);
16142 }
16143
16144
16145 struct stack {
16146         struct triple_set *top;
16147         unsigned orig_id;
16148 };
16149
16150 static int count_auto_vars(struct compile_state *state)
16151 {
16152         struct triple *first, *ins;
16153         int auto_vars = 0;
16154         first = state->first;
16155         ins = first;
16156         do {
16157                 if (triple_is_auto_var(state, ins)) {
16158                         auto_vars += 1;
16159                 }
16160                 ins = ins->next;
16161         } while(ins != first);
16162         return auto_vars;
16163 }
16164
16165 static void number_auto_vars(struct compile_state *state, struct stack *stacks)
16166 {
16167         struct triple *first, *ins;
16168         int auto_vars = 0;
16169         first = state->first;
16170         ins = first;
16171         do {
16172                 if (triple_is_auto_var(state, ins)) {
16173                         auto_vars += 1;
16174                         stacks[auto_vars].orig_id = ins->id;
16175                         ins->id = auto_vars;
16176                 }
16177                 ins = ins->next;
16178         } while(ins != first);
16179 }
16180
16181 static void restore_auto_vars(struct compile_state *state, struct stack *stacks)
16182 {
16183         struct triple *first, *ins;
16184         first = state->first;
16185         ins = first;
16186         do {
16187                 if (triple_is_auto_var(state, ins)) {
16188                         ins->id = stacks[ins->id].orig_id;
16189                 }
16190                 ins = ins->next;
16191         } while(ins != first);
16192 }
16193
16194 static struct triple *peek_triple(struct stack *stacks, struct triple *var)
16195 {
16196         struct triple_set *head;
16197         struct triple *top_val;
16198         top_val = 0;
16199         head = stacks[var->id].top;
16200         if (head) {
16201                 top_val = head->member;
16202         }
16203         return top_val;
16204 }
16205
16206 static void push_triple(struct stack *stacks, struct triple *var, struct triple *val)
16207 {
16208         struct triple_set *new;
16209         /* Append new to the head of the list,
16210          * it's the only sensible behavoir for a stack.
16211          */
16212         new = xcmalloc(sizeof(*new), "triple_set");
16213         new->member = val;
16214         new->next   = stacks[var->id].top;
16215         stacks[var->id].top = new;
16216 }
16217
16218 static void pop_triple(struct stack *stacks, struct triple *var, struct triple *oldval)
16219 {
16220         struct triple_set *set, **ptr;
16221         ptr = &stacks[var->id].top;
16222         while(*ptr) {
16223                 set = *ptr;
16224                 if (set->member == oldval) {
16225                         *ptr = set->next;
16226                         xfree(set);
16227                         /* Only free one occurance from the stack */
16228                         return;
16229                 }
16230                 else {
16231                         ptr = &set->next;
16232                 }
16233         }
16234 }
16235
16236 /*
16237  * C(V)
16238  * S(V)
16239  */
16240 static void fixup_block_phi_variables(
16241         struct compile_state *state, struct stack *stacks, struct block *parent, struct block *block)
16242 {
16243         struct block_set *set;
16244         struct triple *ptr;
16245         int edge;
16246         if (!parent || !block)
16247                 return;
16248         /* Find the edge I am coming in on */
16249         edge = 0;
16250         for(set = block->use; set; set = set->next, edge++) {
16251                 if (set->member == parent) {
16252                         break;
16253                 }
16254         }
16255         if (!set) {
16256                 internal_error(state, 0, "phi input is not on a control predecessor");
16257         }
16258         for(ptr = block->first; ; ptr = ptr->next) {
16259                 if (ptr->op == OP_PHI) {
16260                         struct triple *var, *val, **slot;
16261                         var = MISC(ptr, 0);
16262                         if (!var) {
16263                                 internal_error(state, ptr, "no var???");
16264                         }
16265                         /* Find the current value of the variable */
16266                         val = peek_triple(stacks, var);
16267                         if (val && ((val->op == OP_WRITE) || (val->op == OP_READ))) {
16268                                 internal_error(state, val, "bad value in phi");
16269                         }
16270                         if (edge >= ptr->rhs) {
16271                                 internal_error(state, ptr, "edges > phi rhs");
16272                         }
16273                         slot = &RHS(ptr, edge);
16274                         if ((*slot != 0) && (*slot != val)) {
16275                                 internal_error(state, ptr, "phi already bound on this edge");
16276                         }
16277                         *slot = val;
16278                         use_triple(val, ptr);
16279                 }
16280                 if (ptr == block->last) {
16281                         break;
16282                 }
16283         }
16284 }
16285
16286
16287 static void rename_block_variables(
16288         struct compile_state *state, struct stack *stacks, struct block *block)
16289 {
16290         struct block_set *user, *edge;
16291         struct triple *ptr, *next, *last;
16292         int done;
16293         if (!block)
16294                 return;
16295         last = block->first;
16296         done = 0;
16297         for(ptr = block->first; !done; ptr = next) {
16298                 next = ptr->next;
16299                 if (ptr == block->last) {
16300                         done = 1;
16301                 }
16302                 /* RHS(A) */
16303                 if (ptr->op == OP_READ) {
16304                         struct triple *var, *val;
16305                         var = RHS(ptr, 0);
16306                         if (!triple_is_auto_var(state, var)) {
16307                                 internal_error(state, ptr, "read of non auto var!");
16308                         }
16309                         unuse_triple(var, ptr);
16310                         /* Find the current value of the variable */
16311                         val = peek_triple(stacks, var);
16312                         if (!val) {
16313                                 /* Let the optimizer at variables that are not initially
16314                                  * set.  But give it a bogus value so things seem to
16315                                  * work by accident.  This is useful for bitfields because
16316                                  * setting them always involves a read-modify-write.
16317                                  */
16318                                 if (TYPE_ARITHMETIC(ptr->type->type)) {
16319                                         val = pre_triple(state, ptr, OP_INTCONST, ptr->type, 0, 0);
16320                                         val->u.cval = 0xdeadbeaf;
16321                                 } else {
16322                                         val = pre_triple(state, ptr, OP_UNKNOWNVAL, ptr->type, 0, 0);
16323                                 }
16324                         }
16325                         if (!val) {
16326                                 error(state, ptr, "variable used without being set");
16327                         }
16328                         if ((val->op == OP_WRITE) || (val->op == OP_READ)) {
16329                                 internal_error(state, val, "bad value in read");
16330                         }
16331                         propogate_use(state, ptr, val);
16332                         release_triple(state, ptr);
16333                         continue;
16334                 }
16335                 /* LHS(A) */
16336                 if (ptr->op == OP_WRITE) {
16337                         struct triple *var, *val, *tval;
16338                         var = MISC(ptr, 0);
16339                         if (!triple_is_auto_var(state, var)) {
16340                                 internal_error(state, ptr, "write to non auto var!");
16341                         }
16342                         tval = val = RHS(ptr, 0);
16343                         if ((val->op == OP_WRITE) || (val->op == OP_READ) ||
16344                                 triple_is_auto_var(state, val)) {
16345                                 internal_error(state, ptr, "bad value in write");
16346                         }
16347                         /* Insert a cast if the types differ */
16348                         if (!is_subset_type(ptr->type, val->type)) {
16349                                 if (val->op == OP_INTCONST) {
16350                                         tval = pre_triple(state, ptr, OP_INTCONST, ptr->type, 0, 0);
16351                                         tval->u.cval = val->u.cval;
16352                                 }
16353                                 else {
16354                                         tval = pre_triple(state, ptr, OP_CONVERT, ptr->type, val, 0);
16355                                         use_triple(val, tval);
16356                                 }
16357                                 transform_to_arch_instruction(state, tval);
16358                                 unuse_triple(val, ptr);
16359                                 RHS(ptr, 0) = tval;
16360                                 use_triple(tval, ptr);
16361                         }
16362                         propogate_use(state, ptr, tval);
16363                         unuse_triple(var, ptr);
16364                         /* Push OP_WRITE ptr->right onto a stack of variable uses */
16365                         push_triple(stacks, var, tval);
16366                 }
16367                 if (ptr->op == OP_PHI) {
16368                         struct triple *var;
16369                         var = MISC(ptr, 0);
16370                         if (!triple_is_auto_var(state, var)) {
16371                                 internal_error(state, ptr, "phi references non auto var!");
16372                         }
16373                         /* Push OP_PHI onto a stack of variable uses */
16374                         push_triple(stacks, var, ptr);
16375                 }
16376                 last = ptr;
16377         }
16378         block->last = last;
16379
16380         /* Fixup PHI functions in the cf successors */
16381         for(edge = block->edges; edge; edge = edge->next) {
16382                 fixup_block_phi_variables(state, stacks, block, edge->member);
16383         }
16384         /* rename variables in the dominated nodes */
16385         for(user = block->idominates; user; user = user->next) {
16386                 rename_block_variables(state, stacks, user->member);
16387         }
16388         /* pop the renamed variable stack */
16389         last = block->first;
16390         done = 0;
16391         for(ptr = block->first; !done ; ptr = next) {
16392                 next = ptr->next;
16393                 if (ptr == block->last) {
16394                         done = 1;
16395                 }
16396                 if (ptr->op == OP_WRITE) {
16397                         struct triple *var;
16398                         var = MISC(ptr, 0);
16399                         /* Pop OP_WRITE ptr->right from the stack of variable uses */
16400                         pop_triple(stacks, var, RHS(ptr, 0));
16401                         release_triple(state, ptr);
16402                         continue;
16403                 }
16404                 if (ptr->op == OP_PHI) {
16405                         struct triple *var;
16406                         var = MISC(ptr, 0);
16407                         /* Pop OP_WRITE ptr->right from the stack of variable uses */
16408                         pop_triple(stacks, var, ptr);
16409                 }
16410                 last = ptr;
16411         }
16412         block->last = last;
16413 }
16414
16415 static void rename_variables(struct compile_state *state)
16416 {
16417         struct stack *stacks;
16418         int auto_vars;
16419
16420         /* Allocate stacks for the Variables */
16421         auto_vars = count_auto_vars(state);
16422         stacks = xcmalloc(sizeof(stacks[0])*(auto_vars + 1), "auto var stacks");
16423
16424         /* Give each auto_var a stack */
16425         number_auto_vars(state, stacks);
16426
16427         /* Rename the variables */
16428         rename_block_variables(state, stacks, state->bb.first_block);
16429
16430         /* Remove the stacks from the auto_vars */
16431         restore_auto_vars(state, stacks);
16432         xfree(stacks);
16433 }
16434
16435 static void prune_block_variables(struct compile_state *state,
16436         struct block *block)
16437 {
16438         struct block_set *user;
16439         struct triple *next, *ptr;
16440         int done;
16441
16442         done = 0;
16443         for(ptr = block->first; !done; ptr = next) {
16444                 /* Be extremely careful I am deleting the list
16445                  * as I walk trhough it.
16446                  */
16447                 next = ptr->next;
16448                 if (ptr == block->last) {
16449                         done = 1;
16450                 }
16451                 if (triple_is_auto_var(state, ptr)) {
16452                         struct triple_set *user, *next;
16453                         for(user = ptr->use; user; user = next) {
16454                                 struct triple *use;
16455                                 next = user->next;
16456                                 use = user->member;
16457                                 if (MISC(ptr, 0) == user->member) {
16458                                         continue;
16459                                 }
16460                                 if (use->op != OP_PHI) {
16461                                         internal_error(state, use, "decl still used");
16462                                 }
16463                                 if (MISC(use, 0) != ptr) {
16464                                         internal_error(state, use, "bad phi use of decl");
16465                                 }
16466                                 unuse_triple(ptr, use);
16467                                 MISC(use, 0) = 0;
16468                         }
16469                         if ((ptr->u.cval == 0) && (MISC(ptr, 0)->lhs == 1)) {
16470                                 /* Delete the adecl */
16471                                 release_triple(state, MISC(ptr, 0));
16472                                 /* And the piece */
16473                                 release_triple(state, ptr);
16474                         }
16475                         continue;
16476                 }
16477         }
16478         for(user = block->idominates; user; user = user->next) {
16479                 prune_block_variables(state, user->member);
16480         }
16481 }
16482
16483 struct phi_triple {
16484         struct triple *phi;
16485         unsigned orig_id;
16486         int alive;
16487 };
16488
16489 static void keep_phi(struct compile_state *state, struct phi_triple *live, struct triple *phi)
16490 {
16491         struct triple **slot;
16492         int zrhs, i;
16493         if (live[phi->id].alive) {
16494                 return;
16495         }
16496         live[phi->id].alive = 1;
16497         zrhs = phi->rhs;
16498         slot = &RHS(phi, 0);
16499         for(i = 0; i < zrhs; i++) {
16500                 struct triple *used;
16501                 used = slot[i];
16502                 if (used && (used->op == OP_PHI)) {
16503                         keep_phi(state, live, used);
16504                 }
16505         }
16506 }
16507
16508 static void prune_unused_phis(struct compile_state *state)
16509 {
16510         struct triple *first, *phi;
16511         struct phi_triple *live;
16512         int phis, i;
16513         
16514         /* Find the first instruction */
16515         first = state->first;
16516
16517         /* Count how many phi functions I need to process */
16518         phis = 0;
16519         for(phi = first->next; phi != first; phi = phi->next) {
16520                 if (phi->op == OP_PHI) {
16521                         phis += 1;
16522                 }
16523         }
16524         
16525         /* Mark them all dead */
16526         live = xcmalloc(sizeof(*live) * (phis + 1), "phi_triple");
16527         phis = 0;
16528         for(phi = first->next; phi != first; phi = phi->next) {
16529                 if (phi->op != OP_PHI) {
16530                         continue;
16531                 }
16532                 live[phis].alive   = 0;
16533                 live[phis].orig_id = phi->id;
16534                 live[phis].phi     = phi;
16535                 phi->id = phis;
16536                 phis += 1;
16537         }
16538         
16539         /* Mark phis alive that are used by non phis */
16540         for(i = 0; i < phis; i++) {
16541                 struct triple_set *set;
16542                 for(set = live[i].phi->use; !live[i].alive && set; set = set->next) {
16543                         if (set->member->op != OP_PHI) {
16544                                 keep_phi(state, live, live[i].phi);
16545                                 break;
16546                         }
16547                 }
16548         }
16549
16550         /* Delete the extraneous phis */
16551         for(i = 0; i < phis; i++) {
16552                 struct triple **slot;
16553                 int zrhs, j;
16554                 if (!live[i].alive) {
16555                         release_triple(state, live[i].phi);
16556                         continue;
16557                 }
16558                 phi = live[i].phi;
16559                 slot = &RHS(phi, 0);
16560                 zrhs = phi->rhs;
16561                 for(j = 0; j < zrhs; j++) {
16562                         if(!slot[j]) {
16563                                 struct triple *unknown;
16564                                 get_occurance(phi->occurance);
16565                                 unknown = flatten(state, state->global_pool,
16566                                         alloc_triple(state, OP_UNKNOWNVAL,
16567                                                 phi->type, 0, 0, phi->occurance));
16568                                 slot[j] = unknown;
16569                                 use_triple(unknown, phi);
16570                                 transform_to_arch_instruction(state, unknown);
16571 #if 0                           
16572                                 warning(state, phi, "variable not set at index %d on all paths to use", j);
16573 #endif
16574                         }
16575                 }
16576         }
16577         xfree(live);
16578 }
16579
16580 static void transform_to_ssa_form(struct compile_state *state)
16581 {
16582         insert_phi_operations(state);
16583         rename_variables(state);
16584
16585         prune_block_variables(state, state->bb.first_block);
16586         prune_unused_phis(state);
16587
16588         print_blocks(state, __func__, state->dbgout);
16589 }
16590
16591
16592 static void clear_vertex(
16593         struct compile_state *state, struct block *block, void *arg)
16594 {
16595         /* Clear the current blocks vertex and the vertex of all
16596          * of the current blocks neighbors in case there are malformed
16597          * blocks with now instructions at this point.
16598          */
16599         struct block_set *user, *edge;
16600         block->vertex = 0;
16601         for(edge = block->edges; edge; edge = edge->next) {
16602                 edge->member->vertex = 0;
16603         }
16604         for(user = block->use; user; user = user->next) {
16605                 user->member->vertex = 0;
16606         }
16607 }
16608
16609 static void mark_live_block(
16610         struct compile_state *state, struct block *block, int *next_vertex)
16611 {
16612         /* See if this is a block that has not been marked */
16613         if (block->vertex != 0) {
16614                 return;
16615         }
16616         block->vertex = *next_vertex;
16617         *next_vertex += 1;
16618         if (triple_is_branch(state, block->last)) {
16619                 struct triple **targ;
16620                 targ = triple_edge_targ(state, block->last, 0);
16621                 for(; targ; targ = triple_edge_targ(state, block->last, targ)) {
16622                         if (!*targ) {
16623                                 continue;
16624                         }
16625                         if (!triple_stores_block(state, *targ)) {
16626                                 internal_error(state, 0, "bad targ");
16627                         }
16628                         mark_live_block(state, (*targ)->u.block, next_vertex);
16629                 }
16630                 /* Ensure the last block of a function remains alive */
16631                 if (triple_is_call(state, block->last)) {
16632                         mark_live_block(state, MISC(block->last, 0)->u.block, next_vertex);
16633                 }
16634         }
16635         else if (block->last->next != state->first) {
16636                 struct triple *ins;
16637                 ins = block->last->next;
16638                 if (!triple_stores_block(state, ins)) {
16639                         internal_error(state, 0, "bad block start");
16640                 }
16641                 mark_live_block(state, ins->u.block, next_vertex);
16642         }
16643 }
16644
16645 static void transform_from_ssa_form(struct compile_state *state)
16646 {
16647         /* To get out of ssa form we insert moves on the incoming
16648          * edges to blocks containting phi functions.
16649          */
16650         struct triple *first;
16651         struct triple *phi, *var, *next;
16652         int next_vertex;
16653
16654         /* Walk the control flow to see which blocks remain alive */
16655         walk_blocks(state, &state->bb, clear_vertex, 0);
16656         next_vertex = 1;
16657         mark_live_block(state, state->bb.first_block, &next_vertex);
16658
16659         /* Walk all of the operations to find the phi functions */
16660         first = state->first;
16661         for(phi = first->next; phi != first ; phi = next) {
16662                 struct block_set *set;
16663                 struct block *block;
16664                 struct triple **slot;
16665                 struct triple *var;
16666                 struct triple_set *use, *use_next;
16667                 int edge, writers, readers;
16668                 next = phi->next;
16669                 if (phi->op != OP_PHI) {
16670                         continue;
16671                 }
16672
16673                 block = phi->u.block;
16674                 slot  = &RHS(phi, 0);
16675
16676                 /* If this phi is in a dead block just forget it */
16677                 if (block->vertex == 0) {
16678                         release_triple(state, phi);
16679                         continue;
16680                 }
16681
16682                 /* Forget uses from code in dead blocks */
16683                 for(use = phi->use; use; use = use_next) {
16684                         struct block *ublock;
16685                         struct triple **expr;
16686                         use_next = use->next;
16687                         ublock = block_of_triple(state, use->member);
16688                         if ((use->member == phi) || (ublock->vertex != 0)) {
16689                                 continue;
16690                         }
16691                         expr = triple_rhs(state, use->member, 0);
16692                         for(; expr; expr = triple_rhs(state, use->member, expr)) {
16693                                 if (*expr == phi) {
16694                                         *expr = 0;
16695                                 }
16696                         }
16697                         unuse_triple(phi, use->member);
16698                 }
16699                 /* A variable to replace the phi function */
16700                 if (registers_of(state, phi->type) != 1) {
16701                         internal_error(state, phi, "phi->type does not fit in a single register!");
16702                 }
16703                 var = post_triple(state, phi, OP_ADECL, phi->type, 0, 0);
16704                 var = var->next; /* point at the var */
16705                         
16706                 /* Replaces use of phi with var */
16707                 propogate_use(state, phi, var);
16708
16709                 /* Count the readers */
16710                 readers = 0;
16711                 for(use = var->use; use; use = use->next) {
16712                         if (use->member != MISC(var, 0)) {
16713                                 readers++;
16714                         }
16715                 }
16716
16717                 /* Walk all of the incoming edges/blocks and insert moves.
16718                  */
16719                 writers = 0;
16720                 for(edge = 0, set = block->use; set; set = set->next, edge++) {
16721                         struct block *eblock, *vblock;
16722                         struct triple *move;
16723                         struct triple *val, *base;
16724                         eblock = set->member;
16725                         val = slot[edge];
16726                         slot[edge] = 0;
16727                         unuse_triple(val, phi);
16728                         vblock = block_of_triple(state, val);
16729
16730                         /* If we don't have a value that belongs in an OP_WRITE
16731                          * continue on.
16732                          */
16733                         if (!val || (val == &unknown_triple) || (val == phi)
16734                                 || (vblock && (vblock->vertex == 0))) {
16735                                 continue;
16736                         }
16737                         /* If the value should never occur error */
16738                         if (!vblock) {
16739                                 internal_error(state, val, "no vblock?");
16740                                 continue;
16741                         }
16742
16743                         /* If the value occurs in a dead block see if a replacement
16744                          * block can be found.
16745                          */
16746                         while(eblock && (eblock->vertex == 0)) {
16747                                 eblock = eblock->idom;
16748                         }
16749                         /* If not continue on with the next value. */
16750                         if (!eblock || (eblock->vertex == 0)) {
16751                                 continue;
16752                         }
16753
16754                         /* If we have an empty incoming block ignore it. */
16755                         if (!eblock->first) {
16756                                 internal_error(state, 0, "empty block?");
16757                         }
16758                         
16759                         /* Make certain the write is placed in the edge block... */
16760                         /* Walk through the edge block backwards to find an
16761                          * appropriate location for the OP_WRITE.
16762                          */
16763                         for(base = eblock->last; base != eblock->first; base = base->prev) {
16764                                 struct triple **expr;
16765                                 if (base->op == OP_PIECE) {
16766                                         base = MISC(base, 0);
16767                                 }
16768                                 if ((base == var) || (base == val)) {
16769                                         goto out;
16770                                 }
16771                                 expr = triple_lhs(state, base, 0);
16772                                 for(; expr; expr = triple_lhs(state, base, expr)) {
16773                                         if ((*expr) == val) {
16774                                                 goto out;
16775                                         }
16776                                 }
16777                                 expr = triple_rhs(state, base, 0);
16778                                 for(; expr; expr = triple_rhs(state, base, expr)) {
16779                                         if ((*expr) == var) {
16780                                                 goto out;
16781                                         }
16782                                 }
16783                         }
16784                 out:
16785                         if (triple_is_branch(state, base)) {
16786                                 internal_error(state, base,
16787                                         "Could not insert write to phi");
16788                         }
16789                         move = post_triple(state, base, OP_WRITE, var->type, val, var);
16790                         use_triple(val, move);
16791                         use_triple(var, move);
16792                         writers++;
16793                 }
16794                 if (!writers && readers) {
16795                         internal_error(state, var, "no value written to in use phi?");
16796                 }
16797                 /* If var is not used free it */
16798                 if (!writers) {
16799                         release_triple(state, MISC(var, 0));
16800                         release_triple(state, var);
16801                 }
16802                 /* Release the phi function */
16803                 release_triple(state, phi);
16804         }
16805         
16806         /* Walk all of the operations to find the adecls */
16807         for(var = first->next; var != first ; var = var->next) {
16808                 struct triple_set *use, *use_next;
16809                 if (!triple_is_auto_var(state, var)) {
16810                         continue;
16811                 }
16812
16813                 /* Walk through all of the rhs uses of var and
16814                  * replace them with read of var.
16815                  */
16816                 for(use = var->use; use; use = use_next) {
16817                         struct triple *read, *user;
16818                         struct triple **slot;
16819                         int zrhs, i, used;
16820                         use_next = use->next;
16821                         user = use->member;
16822                         
16823                         /* Generate a read of var */
16824                         read = pre_triple(state, user, OP_READ, var->type, var, 0);
16825                         use_triple(var, read);
16826
16827                         /* Find the rhs uses and see if they need to be replaced */
16828                         used = 0;
16829                         zrhs = user->rhs;
16830                         slot = &RHS(user, 0);
16831                         for(i = 0; i < zrhs; i++) {
16832                                 if (slot[i] == var) {
16833                                         slot[i] = read;
16834                                         used = 1;
16835                                 }
16836                         }
16837                         /* If we did use it cleanup the uses */
16838                         if (used) {
16839                                 unuse_triple(var, user);
16840                                 use_triple(read, user);
16841                         } 
16842                         /* If we didn't use it release the extra triple */
16843                         else {
16844                                 release_triple(state, read);
16845                         }
16846                 }
16847         }
16848 }
16849
16850 #define HI() if (state->compiler->debug & DEBUG_REBUILD_SSA_FORM) { \
16851         FILE *fp = state->dbgout; \
16852         fprintf(fp, "@ %s:%d\n", __FILE__, __LINE__); romcc_print_blocks(state, fp); \
16853         } 
16854
16855 static void rebuild_ssa_form(struct compile_state *state)
16856 {
16857 HI();
16858         transform_from_ssa_form(state);
16859 HI();
16860         state->bb.first = state->first;
16861         free_basic_blocks(state, &state->bb);
16862         analyze_basic_blocks(state, &state->bb);
16863 HI();
16864         insert_phi_operations(state);
16865 HI();
16866         rename_variables(state);
16867 HI();
16868         
16869         prune_block_variables(state, state->bb.first_block);
16870 HI();
16871         prune_unused_phis(state);
16872 HI();
16873 }
16874 #undef HI
16875
16876 /* 
16877  * Register conflict resolution
16878  * =========================================================
16879  */
16880
16881 static struct reg_info find_def_color(
16882         struct compile_state *state, struct triple *def)
16883 {
16884         struct triple_set *set;
16885         struct reg_info info;
16886         info.reg = REG_UNSET;
16887         info.regcm = 0;
16888         if (!triple_is_def(state, def)) {
16889                 return info;
16890         }
16891         info = arch_reg_lhs(state, def, 0);
16892         if (info.reg >= MAX_REGISTERS) {
16893                 info.reg = REG_UNSET;
16894         }
16895         for(set = def->use; set; set = set->next) {
16896                 struct reg_info tinfo;
16897                 int i;
16898                 i = find_rhs_use(state, set->member, def);
16899                 if (i < 0) {
16900                         continue;
16901                 }
16902                 tinfo = arch_reg_rhs(state, set->member, i);
16903                 if (tinfo.reg >= MAX_REGISTERS) {
16904                         tinfo.reg = REG_UNSET;
16905                 }
16906                 if ((tinfo.reg != REG_UNSET) && 
16907                         (info.reg != REG_UNSET) &&
16908                         (tinfo.reg != info.reg)) {
16909                         internal_error(state, def, "register conflict");
16910                 }
16911                 if ((info.regcm & tinfo.regcm) == 0) {
16912                         internal_error(state, def, "regcm conflict %x & %x == 0",
16913                                 info.regcm, tinfo.regcm);
16914                 }
16915                 if (info.reg == REG_UNSET) {
16916                         info.reg = tinfo.reg;
16917                 }
16918                 info.regcm &= tinfo.regcm;
16919         }
16920         if (info.reg >= MAX_REGISTERS) {
16921                 internal_error(state, def, "register out of range");
16922         }
16923         return info;
16924 }
16925
16926 static struct reg_info find_lhs_pre_color(
16927         struct compile_state *state, struct triple *ins, int index)
16928 {
16929         struct reg_info info;
16930         int zlhs, zrhs, i;
16931         zrhs = ins->rhs;
16932         zlhs = ins->lhs;
16933         if (!zlhs && triple_is_def(state, ins)) {
16934                 zlhs = 1;
16935         }
16936         if (index >= zlhs) {
16937                 internal_error(state, ins, "Bad lhs %d", index);
16938         }
16939         info = arch_reg_lhs(state, ins, index);
16940         for(i = 0; i < zrhs; i++) {
16941                 struct reg_info rinfo;
16942                 rinfo = arch_reg_rhs(state, ins, i);
16943                 if ((info.reg == rinfo.reg) &&
16944                         (rinfo.reg >= MAX_REGISTERS)) {
16945                         struct reg_info tinfo;
16946                         tinfo = find_lhs_pre_color(state, RHS(ins, index), 0);
16947                         info.reg = tinfo.reg;
16948                         info.regcm &= tinfo.regcm;
16949                         break;
16950                 }
16951         }
16952         if (info.reg >= MAX_REGISTERS) {
16953                 info.reg = REG_UNSET;
16954         }
16955         return info;
16956 }
16957
16958 static struct reg_info find_rhs_post_color(
16959         struct compile_state *state, struct triple *ins, int index);
16960
16961 static struct reg_info find_lhs_post_color(
16962         struct compile_state *state, struct triple *ins, int index)
16963 {
16964         struct triple_set *set;
16965         struct reg_info info;
16966         struct triple *lhs;
16967 #if DEBUG_TRIPLE_COLOR
16968         fprintf(state->errout, "find_lhs_post_color(%p, %d)\n",
16969                 ins, index);
16970 #endif
16971         if ((index == 0) && triple_is_def(state, ins)) {
16972                 lhs = ins;
16973         }
16974         else if (index < ins->lhs) {
16975                 lhs = LHS(ins, index);
16976         }
16977         else {
16978                 internal_error(state, ins, "Bad lhs %d", index);
16979                 lhs = 0;
16980         }
16981         info = arch_reg_lhs(state, ins, index);
16982         if (info.reg >= MAX_REGISTERS) {
16983                 info.reg = REG_UNSET;
16984         }
16985         for(set = lhs->use; set; set = set->next) {
16986                 struct reg_info rinfo;
16987                 struct triple *user;
16988                 int zrhs, i;
16989                 user = set->member;
16990                 zrhs = user->rhs;
16991                 for(i = 0; i < zrhs; i++) {
16992                         if (RHS(user, i) != lhs) {
16993                                 continue;
16994                         }
16995                         rinfo = find_rhs_post_color(state, user, i);
16996                         if ((info.reg != REG_UNSET) &&
16997                                 (rinfo.reg != REG_UNSET) &&
16998                                 (info.reg != rinfo.reg)) {
16999                                 internal_error(state, ins, "register conflict");
17000                         }
17001                         if ((info.regcm & rinfo.regcm) == 0) {
17002                                 internal_error(state, ins, "regcm conflict %x & %x == 0",
17003                                         info.regcm, rinfo.regcm);
17004                         }
17005                         if (info.reg == REG_UNSET) {
17006                                 info.reg = rinfo.reg;
17007                         }
17008                         info.regcm &= rinfo.regcm;
17009                 }
17010         }
17011 #if DEBUG_TRIPLE_COLOR
17012         fprintf(state->errout, "find_lhs_post_color(%p, %d) -> ( %d, %x)\n",
17013                 ins, index, info.reg, info.regcm);
17014 #endif
17015         return info;
17016 }
17017
17018 static struct reg_info find_rhs_post_color(
17019         struct compile_state *state, struct triple *ins, int index)
17020 {
17021         struct reg_info info, rinfo;
17022         int zlhs, i;
17023 #if DEBUG_TRIPLE_COLOR
17024         fprintf(state->errout, "find_rhs_post_color(%p, %d)\n",
17025                 ins, index);
17026 #endif
17027         rinfo = arch_reg_rhs(state, ins, index);
17028         zlhs = ins->lhs;
17029         if (!zlhs && triple_is_def(state, ins)) {
17030                 zlhs = 1;
17031         }
17032         info = rinfo;
17033         if (info.reg >= MAX_REGISTERS) {
17034                 info.reg = REG_UNSET;
17035         }
17036         for(i = 0; i < zlhs; i++) {
17037                 struct reg_info linfo;
17038                 linfo = arch_reg_lhs(state, ins, i);
17039                 if ((linfo.reg == rinfo.reg) &&
17040                         (linfo.reg >= MAX_REGISTERS)) {
17041                         struct reg_info tinfo;
17042                         tinfo = find_lhs_post_color(state, ins, i);
17043                         if (tinfo.reg >= MAX_REGISTERS) {
17044                                 tinfo.reg = REG_UNSET;
17045                         }
17046                         info.regcm &= linfo.regcm;
17047                         info.regcm &= tinfo.regcm;
17048                         if (info.reg != REG_UNSET) {
17049                                 internal_error(state, ins, "register conflict");
17050                         }
17051                         if (info.regcm == 0) {
17052                                 internal_error(state, ins, "regcm conflict");
17053                         }
17054                         info.reg = tinfo.reg;
17055                 }
17056         }
17057 #if DEBUG_TRIPLE_COLOR
17058         fprintf(state->errout, "find_rhs_post_color(%p, %d) -> ( %d, %x)\n",
17059                 ins, index, info.reg, info.regcm);
17060 #endif
17061         return info;
17062 }
17063
17064 static struct reg_info find_lhs_color(
17065         struct compile_state *state, struct triple *ins, int index)
17066 {
17067         struct reg_info pre, post, info;
17068 #if DEBUG_TRIPLE_COLOR
17069         fprintf(state->errout, "find_lhs_color(%p, %d)\n",
17070                 ins, index);
17071 #endif
17072         pre = find_lhs_pre_color(state, ins, index);
17073         post = find_lhs_post_color(state, ins, index);
17074         if ((pre.reg != post.reg) &&
17075                 (pre.reg != REG_UNSET) &&
17076                 (post.reg != REG_UNSET)) {
17077                 internal_error(state, ins, "register conflict");
17078         }
17079         info.regcm = pre.regcm & post.regcm;
17080         info.reg = pre.reg;
17081         if (info.reg == REG_UNSET) {
17082                 info.reg = post.reg;
17083         }
17084 #if DEBUG_TRIPLE_COLOR
17085         fprintf(state->errout, "find_lhs_color(%p, %d) -> ( %d, %x) ... (%d, %x) (%d, %x)\n",
17086                 ins, index, info.reg, info.regcm,
17087                 pre.reg, pre.regcm, post.reg, post.regcm);
17088 #endif
17089         return info;
17090 }
17091
17092 static struct triple *post_copy(struct compile_state *state, struct triple *ins)
17093 {
17094         struct triple_set *entry, *next;
17095         struct triple *out;
17096         struct reg_info info, rinfo;
17097
17098         info = arch_reg_lhs(state, ins, 0);
17099         out = post_triple(state, ins, OP_COPY, ins->type, ins, 0);
17100         use_triple(RHS(out, 0), out);
17101         /* Get the users of ins to use out instead */
17102         for(entry = ins->use; entry; entry = next) {
17103                 int i;
17104                 next = entry->next;
17105                 if (entry->member == out) {
17106                         continue;
17107                 }
17108                 i = find_rhs_use(state, entry->member, ins);
17109                 if (i < 0) {
17110                         continue;
17111                 }
17112                 rinfo = arch_reg_rhs(state, entry->member, i);
17113                 if ((info.reg == REG_UNNEEDED) && (rinfo.reg == REG_UNNEEDED)) {
17114                         continue;
17115                 }
17116                 replace_rhs_use(state, ins, out, entry->member);
17117         }
17118         transform_to_arch_instruction(state, out);
17119         return out;
17120 }
17121
17122 static struct triple *typed_pre_copy(
17123         struct compile_state *state, struct type *type, struct triple *ins, int index)
17124 {
17125         /* Carefully insert enough operations so that I can
17126          * enter any operation with a GPR32.
17127          */
17128         struct triple *in;
17129         struct triple **expr;
17130         unsigned classes;
17131         struct reg_info info;
17132         int op;
17133         if (ins->op == OP_PHI) {
17134                 internal_error(state, ins, "pre_copy on a phi?");
17135         }
17136         classes = arch_type_to_regcm(state, type);
17137         info = arch_reg_rhs(state, ins, index);
17138         expr = &RHS(ins, index);
17139         if ((info.regcm & classes) == 0) {
17140                 FILE *fp = state->errout;
17141                 fprintf(fp, "src_type: ");
17142                 name_of(fp, ins->type);
17143                 fprintf(fp, "\ndst_type: ");
17144                 name_of(fp, type);
17145                 fprintf(fp, "\n");
17146                 internal_error(state, ins, "pre_copy with no register classes");
17147         }
17148         op = OP_COPY;
17149         if (!equiv_types(type, (*expr)->type)) {
17150                 op = OP_CONVERT;
17151         }
17152         in = pre_triple(state, ins, op, type, *expr, 0);
17153         unuse_triple(*expr, ins);
17154         *expr = in;
17155         use_triple(RHS(in, 0), in);
17156         use_triple(in, ins);
17157         transform_to_arch_instruction(state, in);
17158         return in;
17159         
17160 }
17161 static struct triple *pre_copy(
17162         struct compile_state *state, struct triple *ins, int index)
17163 {
17164         return typed_pre_copy(state, RHS(ins, index)->type, ins, index);
17165 }
17166
17167
17168 static void insert_copies_to_phi(struct compile_state *state)
17169 {
17170         /* To get out of ssa form we insert moves on the incoming
17171          * edges to blocks containting phi functions.
17172          */
17173         struct triple *first;
17174         struct triple *phi;
17175
17176         /* Walk all of the operations to find the phi functions */
17177         first = state->first;
17178         for(phi = first->next; phi != first ; phi = phi->next) {
17179                 struct block_set *set;
17180                 struct block *block;
17181                 struct triple **slot, *copy;
17182                 int edge;
17183                 if (phi->op != OP_PHI) {
17184                         continue;
17185                 }
17186                 phi->id |= TRIPLE_FLAG_POST_SPLIT;
17187                 block = phi->u.block;
17188                 slot  = &RHS(phi, 0);
17189                 /* Phi's that feed into mandatory live range joins
17190                  * cause nasty complications.  Insert a copy of
17191                  * the phi value so I never have to deal with
17192                  * that in the rest of the code.
17193                  */
17194                 copy = post_copy(state, phi);
17195                 copy->id |= TRIPLE_FLAG_PRE_SPLIT;
17196                 /* Walk all of the incoming edges/blocks and insert moves.
17197                  */
17198                 for(edge = 0, set = block->use; set; set = set->next, edge++) {
17199                         struct block *eblock;
17200                         struct triple *move;
17201                         struct triple *val;
17202                         struct triple *ptr;
17203                         eblock = set->member;
17204                         val = slot[edge];
17205
17206                         if (val == phi) {
17207                                 continue;
17208                         }
17209
17210                         get_occurance(val->occurance);
17211                         move = build_triple(state, OP_COPY, val->type, val, 0,
17212                                 val->occurance);
17213                         move->u.block = eblock;
17214                         move->id |= TRIPLE_FLAG_PRE_SPLIT;
17215                         use_triple(val, move);
17216                         
17217                         slot[edge] = move;
17218                         unuse_triple(val, phi);
17219                         use_triple(move, phi);
17220
17221                         /* Walk up the dominator tree until I have found the appropriate block */
17222                         while(eblock && !tdominates(state, val, eblock->last)) {
17223                                 eblock = eblock->idom;
17224                         }
17225                         if (!eblock) {
17226                                 internal_error(state, phi, "Cannot find block dominated by %p",
17227                                         val);
17228                         }
17229
17230                         /* Walk through the block backwards to find
17231                          * an appropriate location for the OP_COPY.
17232                          */
17233                         for(ptr = eblock->last; ptr != eblock->first; ptr = ptr->prev) {
17234                                 struct triple **expr;
17235                                 if (ptr->op == OP_PIECE) {
17236                                         ptr = MISC(ptr, 0);
17237                                 }
17238                                 if ((ptr == phi) || (ptr == val)) {
17239                                         goto out;
17240                                 }
17241                                 expr = triple_lhs(state, ptr, 0);
17242                                 for(;expr; expr = triple_lhs(state, ptr, expr)) {
17243                                         if ((*expr) == val) {
17244                                                 goto out;
17245                                         }
17246                                 }
17247                                 expr = triple_rhs(state, ptr, 0);
17248                                 for(;expr; expr = triple_rhs(state, ptr, expr)) {
17249                                         if ((*expr) == phi) {
17250                                                 goto out;
17251                                         }
17252                                 }
17253                         }
17254                 out:
17255                         if (triple_is_branch(state, ptr)) {
17256                                 internal_error(state, ptr,
17257                                         "Could not insert write to phi");
17258                         }
17259                         insert_triple(state, after_lhs(state, ptr), move);
17260                         if (eblock->last == after_lhs(state, ptr)->prev) {
17261                                 eblock->last = move;
17262                         }
17263                         transform_to_arch_instruction(state, move);
17264                 }
17265         }
17266         print_blocks(state, __func__, state->dbgout);
17267 }
17268
17269 struct triple_reg_set;
17270 struct reg_block;
17271
17272
17273 static int do_triple_set(struct triple_reg_set **head, 
17274         struct triple *member, struct triple *new_member)
17275 {
17276         struct triple_reg_set **ptr, *new;
17277         if (!member)
17278                 return 0;
17279         ptr = head;
17280         while(*ptr) {
17281                 if ((*ptr)->member == member) {
17282                         return 0;
17283                 }
17284                 ptr = &(*ptr)->next;
17285         }
17286         new = xcmalloc(sizeof(*new), "triple_set");
17287         new->member = member;
17288         new->new    = new_member;
17289         new->next   = *head;
17290         *head       = new;
17291         return 1;
17292 }
17293
17294 static void do_triple_unset(struct triple_reg_set **head, struct triple *member)
17295 {
17296         struct triple_reg_set *entry, **ptr;
17297         ptr = head;
17298         while(*ptr) {
17299                 entry = *ptr;
17300                 if (entry->member == member) {
17301                         *ptr = entry->next;
17302                         xfree(entry);
17303                         return;
17304                 }
17305                 else {
17306                         ptr = &entry->next;
17307                 }
17308         }
17309 }
17310
17311 static int in_triple(struct reg_block *rb, struct triple *in)
17312 {
17313         return do_triple_set(&rb->in, in, 0);
17314 }
17315 static void unin_triple(struct reg_block *rb, struct triple *unin)
17316 {
17317         do_triple_unset(&rb->in, unin);
17318 }
17319
17320 static int out_triple(struct reg_block *rb, struct triple *out)
17321 {
17322         return do_triple_set(&rb->out, out, 0);
17323 }
17324 static void unout_triple(struct reg_block *rb, struct triple *unout)
17325 {
17326         do_triple_unset(&rb->out, unout);
17327 }
17328
17329 static int initialize_regblock(struct reg_block *blocks,
17330         struct block *block, int vertex)
17331 {
17332         struct block_set *user;
17333         if (!block || (blocks[block->vertex].block == block)) {
17334                 return vertex;
17335         }
17336         vertex += 1;
17337         /* Renumber the blocks in a convinient fashion */
17338         block->vertex = vertex;
17339         blocks[vertex].block    = block;
17340         blocks[vertex].vertex   = vertex;
17341         for(user = block->use; user; user = user->next) {
17342                 vertex = initialize_regblock(blocks, user->member, vertex);
17343         }
17344         return vertex;
17345 }
17346
17347 static struct triple *part_to_piece(struct compile_state *state, struct triple *ins)
17348 {
17349 /* Part to piece is a best attempt and it cannot be correct all by
17350  * itself.  If various values are read as different sizes in different
17351  * parts of the code this function cannot work.  Or rather it cannot
17352  * work in conjunction with compute_variable_liftimes.  As the
17353  * analysis will get confused.
17354  */
17355         struct triple *base;
17356         unsigned reg;
17357         if (!is_lvalue(state, ins)) {
17358                 return ins;
17359         }
17360         base = 0;
17361         reg = 0;
17362         while(ins && triple_is_part(state, ins) && (ins->op != OP_PIECE)) {
17363                 base = MISC(ins, 0);
17364                 switch(ins->op) {
17365                 case OP_INDEX:
17366                         reg += index_reg_offset(state, base->type, ins->u.cval)/REG_SIZEOF_REG;
17367                         break;
17368                 case OP_DOT:
17369                         reg += field_reg_offset(state, base->type, ins->u.field)/REG_SIZEOF_REG;
17370                         break;
17371                 default:
17372                         internal_error(state, ins, "unhandled part");
17373                         break;
17374                 }
17375                 ins = base;
17376         }
17377         if (base) {
17378                 if (reg > base->lhs) {
17379                         internal_error(state, base, "part out of range?");
17380                 }
17381                 ins = LHS(base, reg);
17382         }
17383         return ins;
17384 }
17385
17386 static int this_def(struct compile_state *state, 
17387         struct triple *ins, struct triple *other)
17388 {
17389         if (ins == other) {
17390                 return 1;
17391         }
17392         if (ins->op == OP_WRITE) {
17393                 ins = part_to_piece(state, MISC(ins, 0));
17394         }
17395         return ins == other;
17396 }
17397
17398 static int phi_in(struct compile_state *state, struct reg_block *blocks,
17399         struct reg_block *rb, struct block *suc)
17400 {
17401         /* Read the conditional input set of a successor block
17402          * (i.e. the input to the phi nodes) and place it in the
17403          * current blocks output set.
17404          */
17405         struct block_set *set;
17406         struct triple *ptr;
17407         int edge;
17408         int done, change;
17409         change = 0;
17410         /* Find the edge I am coming in on */
17411         for(edge = 0, set = suc->use; set; set = set->next, edge++) {
17412                 if (set->member == rb->block) {
17413                         break;
17414                 }
17415         }
17416         if (!set) {
17417                 internal_error(state, 0, "Not coming on a control edge?");
17418         }
17419         for(done = 0, ptr = suc->first; !done; ptr = ptr->next) {
17420                 struct triple **slot, *expr, *ptr2;
17421                 int out_change, done2;
17422                 done = (ptr == suc->last);
17423                 if (ptr->op != OP_PHI) {
17424                         continue;
17425                 }
17426                 slot = &RHS(ptr, 0);
17427                 expr = slot[edge];
17428                 out_change = out_triple(rb, expr);
17429                 if (!out_change) {
17430                         continue;
17431                 }
17432                 /* If we don't define the variable also plast it
17433                  * in the current blocks input set.
17434                  */
17435                 ptr2 = rb->block->first;
17436                 for(done2 = 0; !done2; ptr2 = ptr2->next) {
17437                         if (this_def(state, ptr2, expr)) {
17438                                 break;
17439                         }
17440                         done2 = (ptr2 == rb->block->last);
17441                 }
17442                 if (!done2) {
17443                         continue;
17444                 }
17445                 change |= in_triple(rb, expr);
17446         }
17447         return change;
17448 }
17449
17450 static int reg_in(struct compile_state *state, struct reg_block *blocks,
17451         struct reg_block *rb, struct block *suc)
17452 {
17453         struct triple_reg_set *in_set;
17454         int change;
17455         change = 0;
17456         /* Read the input set of a successor block
17457          * and place it in the current blocks output set.
17458          */
17459         in_set = blocks[suc->vertex].in;
17460         for(; in_set; in_set = in_set->next) {
17461                 int out_change, done;
17462                 struct triple *first, *last, *ptr;
17463                 out_change = out_triple(rb, in_set->member);
17464                 if (!out_change) {
17465                         continue;
17466                 }
17467                 /* If we don't define the variable also place it
17468                  * in the current blocks input set.
17469                  */
17470                 first = rb->block->first;
17471                 last = rb->block->last;
17472                 done = 0;
17473                 for(ptr = first; !done; ptr = ptr->next) {
17474                         if (this_def(state, ptr, in_set->member)) {
17475                                 break;
17476                         }
17477                         done = (ptr == last);
17478                 }
17479                 if (!done) {
17480                         continue;
17481                 }
17482                 change |= in_triple(rb, in_set->member);
17483         }
17484         change |= phi_in(state, blocks, rb, suc);
17485         return change;
17486 }
17487
17488 static int use_in(struct compile_state *state, struct reg_block *rb)
17489 {
17490         /* Find the variables we use but don't define and add
17491          * it to the current blocks input set.
17492          */
17493 #warning "FIXME is this O(N^2) algorithm bad?"
17494         struct block *block;
17495         struct triple *ptr;
17496         int done;
17497         int change;
17498         block = rb->block;
17499         change = 0;
17500         for(done = 0, ptr = block->last; !done; ptr = ptr->prev) {
17501                 struct triple **expr;
17502                 done = (ptr == block->first);
17503                 /* The variable a phi function uses depends on the
17504                  * control flow, and is handled in phi_in, not
17505                  * here.
17506                  */
17507                 if (ptr->op == OP_PHI) {
17508                         continue;
17509                 }
17510                 expr = triple_rhs(state, ptr, 0);
17511                 for(;expr; expr = triple_rhs(state, ptr, expr)) {
17512                         struct triple *rhs, *test;
17513                         int tdone;
17514                         rhs = part_to_piece(state, *expr);
17515                         if (!rhs) {
17516                                 continue;
17517                         }
17518
17519                         /* See if rhs is defined in this block.
17520                          * A write counts as a definition.
17521                          */
17522                         for(tdone = 0, test = ptr; !tdone; test = test->prev) {
17523                                 tdone = (test == block->first);
17524                                 if (this_def(state, test, rhs)) {
17525                                         rhs = 0;
17526                                         break;
17527                                 }
17528                         }
17529                         /* If I still have a valid rhs add it to in */
17530                         change |= in_triple(rb, rhs);
17531                 }
17532         }
17533         return change;
17534 }
17535
17536 static struct reg_block *compute_variable_lifetimes(
17537         struct compile_state *state, struct basic_blocks *bb)
17538 {
17539         struct reg_block *blocks;
17540         int change;
17541         blocks = xcmalloc(
17542                 sizeof(*blocks)*(bb->last_vertex + 1), "reg_block");
17543         initialize_regblock(blocks, bb->last_block, 0);
17544         do {
17545                 int i;
17546                 change = 0;
17547                 for(i = 1; i <= bb->last_vertex; i++) {
17548                         struct block_set *edge;
17549                         struct reg_block *rb;
17550                         rb = &blocks[i];
17551                         /* Add the all successor's input set to in */
17552                         for(edge = rb->block->edges; edge; edge = edge->next) {
17553                                 change |= reg_in(state, blocks, rb, edge->member);
17554                         }
17555                         /* Add use to in... */
17556                         change |= use_in(state, rb);
17557                 }
17558         } while(change);
17559         return blocks;
17560 }
17561
17562 static void free_variable_lifetimes(struct compile_state *state, 
17563         struct basic_blocks *bb, struct reg_block *blocks)
17564 {
17565         int i;
17566         /* free in_set && out_set on each block */
17567         for(i = 1; i <= bb->last_vertex; i++) {
17568                 struct triple_reg_set *entry, *next;
17569                 struct reg_block *rb;
17570                 rb = &blocks[i];
17571                 for(entry = rb->in; entry ; entry = next) {
17572                         next = entry->next;
17573                         do_triple_unset(&rb->in, entry->member);
17574                 }
17575                 for(entry = rb->out; entry; entry = next) {
17576                         next = entry->next;
17577                         do_triple_unset(&rb->out, entry->member);
17578                 }
17579         }
17580         xfree(blocks);
17581
17582 }
17583
17584 typedef void (*wvl_cb_t)(
17585         struct compile_state *state, 
17586         struct reg_block *blocks, struct triple_reg_set *live, 
17587         struct reg_block *rb, struct triple *ins, void *arg);
17588
17589 static void walk_variable_lifetimes(struct compile_state *state,
17590         struct basic_blocks *bb, struct reg_block *blocks, 
17591         wvl_cb_t cb, void *arg)
17592 {
17593         int i;
17594         
17595         for(i = 1; i <= state->bb.last_vertex; i++) {
17596                 struct triple_reg_set *live;
17597                 struct triple_reg_set *entry, *next;
17598                 struct triple *ptr, *prev;
17599                 struct reg_block *rb;
17600                 struct block *block;
17601                 int done;
17602
17603                 /* Get the blocks */
17604                 rb = &blocks[i];
17605                 block = rb->block;
17606
17607                 /* Copy out into live */
17608                 live = 0;
17609                 for(entry = rb->out; entry; entry = next) {
17610                         next = entry->next;
17611                         do_triple_set(&live, entry->member, entry->new);
17612                 }
17613                 /* Walk through the basic block calculating live */
17614                 for(done = 0, ptr = block->last; !done; ptr = prev) {
17615                         struct triple **expr;
17616
17617                         prev = ptr->prev;
17618                         done = (ptr == block->first);
17619
17620                         /* Ensure the current definition is in live */
17621                         if (triple_is_def(state, ptr)) {
17622                                 do_triple_set(&live, ptr, 0);
17623                         }
17624
17625                         /* Inform the callback function of what is
17626                          * going on.
17627                          */
17628                          cb(state, blocks, live, rb, ptr, arg);
17629                         
17630                         /* Remove the current definition from live */
17631                         do_triple_unset(&live, ptr);
17632
17633                         /* Add the current uses to live.
17634                          *
17635                          * It is safe to skip phi functions because they do
17636                          * not have any block local uses, and the block
17637                          * output sets already properly account for what
17638                          * control flow depedent uses phi functions do have.
17639                          */
17640                         if (ptr->op == OP_PHI) {
17641                                 continue;
17642                         }
17643                         expr = triple_rhs(state, ptr, 0);
17644                         for(;expr; expr = triple_rhs(state, ptr, expr)) {
17645                                 /* If the triple is not a definition skip it. */
17646                                 if (!*expr || !triple_is_def(state, *expr)) {
17647                                         continue;
17648                                 }
17649                                 do_triple_set(&live, *expr, 0);
17650                         }
17651                 }
17652                 /* Free live */
17653                 for(entry = live; entry; entry = next) {
17654                         next = entry->next;
17655                         do_triple_unset(&live, entry->member);
17656                 }
17657         }
17658 }
17659
17660 struct print_live_variable_info {
17661         struct reg_block *rb;
17662         FILE *fp;
17663 };
17664 static void print_live_variables_block(
17665         struct compile_state *state, struct block *block, void *arg)
17666
17667 {
17668         struct print_live_variable_info *info = arg;
17669         struct block_set *edge;
17670         FILE *fp = info->fp;
17671         struct reg_block *rb;
17672         struct triple *ptr;
17673         int phi_present;
17674         int done;
17675         rb = &info->rb[block->vertex];
17676
17677         fprintf(fp, "\nblock: %p (%d),",
17678                 block,  block->vertex);
17679         for(edge = block->edges; edge; edge = edge->next) {
17680                 fprintf(fp, " %p<-%p",
17681                         edge->member, 
17682                         edge->member && edge->member->use?edge->member->use->member : 0);
17683         }
17684         fprintf(fp, "\n");
17685         if (rb->in) {
17686                 struct triple_reg_set *in_set;
17687                 fprintf(fp, "        in:");
17688                 for(in_set = rb->in; in_set; in_set = in_set->next) {
17689                         fprintf(fp, " %-10p", in_set->member);
17690                 }
17691                 fprintf(fp, "\n");
17692         }
17693         phi_present = 0;
17694         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
17695                 done = (ptr == block->last);
17696                 if (ptr->op == OP_PHI) {
17697                         phi_present = 1;
17698                         break;
17699                 }
17700         }
17701         if (phi_present) {
17702                 int edge;
17703                 for(edge = 0; edge < block->users; edge++) {
17704                         fprintf(fp, "     in(%d):", edge);
17705                         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
17706                                 struct triple **slot;
17707                                 done = (ptr == block->last);
17708                                 if (ptr->op != OP_PHI) {
17709                                         continue;
17710                                 }
17711                                 slot = &RHS(ptr, 0);
17712                                 fprintf(fp, " %-10p", slot[edge]);
17713                         }
17714                         fprintf(fp, "\n");
17715                 }
17716         }
17717         if (block->first->op == OP_LABEL) {
17718                 fprintf(fp, "%p:\n", block->first);
17719         }
17720         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
17721                 done = (ptr == block->last);
17722                 display_triple(fp, ptr);
17723         }
17724         if (rb->out) {
17725                 struct triple_reg_set *out_set;
17726                 fprintf(fp, "       out:");
17727                 for(out_set = rb->out; out_set; out_set = out_set->next) {
17728                         fprintf(fp, " %-10p", out_set->member);
17729                 }
17730                 fprintf(fp, "\n");
17731         }
17732         fprintf(fp, "\n");
17733 }
17734
17735 static void print_live_variables(struct compile_state *state, 
17736         struct basic_blocks *bb, struct reg_block *rb, FILE *fp)
17737 {
17738         struct print_live_variable_info info;
17739         info.rb = rb;
17740         info.fp = fp;
17741         fprintf(fp, "\nlive variables by block\n");
17742         walk_blocks(state, bb, print_live_variables_block, &info);
17743
17744 }
17745
17746
17747 static int count_triples(struct compile_state *state)
17748 {
17749         struct triple *first, *ins;
17750         int triples = 0;
17751         first = state->first;
17752         ins = first;
17753         do {
17754                 triples++;
17755                 ins = ins->next;
17756         } while (ins != first);
17757         return triples;
17758 }
17759
17760
17761 struct dead_triple {
17762         struct triple *triple;
17763         struct dead_triple *work_next;
17764         struct block *block;
17765         int old_id;
17766         int flags;
17767 #define TRIPLE_FLAG_ALIVE 1
17768 #define TRIPLE_FLAG_FREE  1
17769 };
17770
17771 static void print_dead_triples(struct compile_state *state, 
17772         struct dead_triple *dtriple)
17773 {
17774         struct triple *first, *ins;
17775         struct dead_triple *dt;
17776         FILE *fp;
17777         if (!(state->compiler->debug & DEBUG_TRIPLES)) {
17778                 return;
17779         }
17780         fp = state->dbgout;
17781         fprintf(fp, "--------------- dtriples ---------------\n");
17782         first = state->first;
17783         ins = first;
17784         do {
17785                 dt = &dtriple[ins->id];
17786                 if ((ins->op == OP_LABEL) && (ins->use)) {
17787                         fprintf(fp, "\n%p:\n", ins);
17788                 }
17789                 fprintf(fp, "%c", 
17790                         (dt->flags & TRIPLE_FLAG_ALIVE)?' ': '-');
17791                 display_triple(fp, ins);
17792                 if (triple_is_branch(state, ins)) {
17793                         fprintf(fp, "\n");
17794                 }
17795                 ins = ins->next;
17796         } while(ins != first);
17797         fprintf(fp, "\n");
17798 }
17799
17800
17801 static void awaken(
17802         struct compile_state *state,
17803         struct dead_triple *dtriple, struct triple **expr,
17804         struct dead_triple ***work_list_tail)
17805 {
17806         struct triple *triple;
17807         struct dead_triple *dt;
17808         if (!expr) {
17809                 return;
17810         }
17811         triple = *expr;
17812         if (!triple) {
17813                 return;
17814         }
17815         if (triple->id <= 0)  {
17816                 internal_error(state, triple, "bad triple id: %d",
17817                         triple->id);
17818         }
17819         if (triple->op == OP_NOOP) {
17820                 internal_error(state, triple, "awakening noop?");
17821                 return;
17822         }
17823         dt = &dtriple[triple->id];
17824         if (!(dt->flags & TRIPLE_FLAG_ALIVE)) {
17825                 dt->flags |= TRIPLE_FLAG_ALIVE;
17826                 if (!dt->work_next) {
17827                         **work_list_tail = dt;
17828                         *work_list_tail = &dt->work_next;
17829                 }
17830         }
17831 }
17832
17833 static void eliminate_inefectual_code(struct compile_state *state)
17834 {
17835         struct block *block;
17836         struct dead_triple *dtriple, *work_list, **work_list_tail, *dt;
17837         int triples, i;
17838         struct triple *first, *final, *ins;
17839
17840         if (!(state->compiler->flags & COMPILER_ELIMINATE_INEFECTUAL_CODE)) {
17841                 return;
17842         }
17843
17844         /* Setup the work list */
17845         work_list = 0;
17846         work_list_tail = &work_list;
17847
17848         first = state->first;
17849         final = state->first->prev;
17850
17851         /* Count how many triples I have */
17852         triples = count_triples(state);
17853
17854         /* Now put then in an array and mark all of the triples dead */
17855         dtriple = xcmalloc(sizeof(*dtriple) * (triples + 1), "dtriples");
17856         
17857         ins = first;
17858         i = 1;
17859         block = 0;
17860         do {
17861                 dtriple[i].triple = ins;
17862                 dtriple[i].block  = block_of_triple(state, ins);
17863                 dtriple[i].flags  = 0;
17864                 dtriple[i].old_id = ins->id;
17865                 ins->id = i;
17866                 /* See if it is an operation we always keep */
17867                 if (!triple_is_pure(state, ins, dtriple[i].old_id)) {
17868                         awaken(state, dtriple, &ins, &work_list_tail);
17869                 }
17870                 i++;
17871                 ins = ins->next;
17872         } while(ins != first);
17873         while(work_list) {
17874                 struct block *block;
17875                 struct dead_triple *dt;
17876                 struct block_set *user;
17877                 struct triple **expr;
17878                 dt = work_list;
17879                 work_list = dt->work_next;
17880                 if (!work_list) {
17881                         work_list_tail = &work_list;
17882                 }
17883                 /* Make certain the block the current instruction is in lives */
17884                 block = block_of_triple(state, dt->triple);
17885                 awaken(state, dtriple, &block->first, &work_list_tail);
17886                 if (triple_is_branch(state, block->last)) {
17887                         awaken(state, dtriple, &block->last, &work_list_tail);
17888                 } else {
17889                         awaken(state, dtriple, &block->last->next, &work_list_tail);
17890                 }
17891
17892                 /* Wake up the data depencencies of this triple */
17893                 expr = 0;
17894                 do {
17895                         expr = triple_rhs(state, dt->triple, expr);
17896                         awaken(state, dtriple, expr, &work_list_tail);
17897                 } while(expr);
17898                 do {
17899                         expr = triple_lhs(state, dt->triple, expr);
17900                         awaken(state, dtriple, expr, &work_list_tail);
17901                 } while(expr);
17902                 do {
17903                         expr = triple_misc(state, dt->triple, expr);
17904                         awaken(state, dtriple, expr, &work_list_tail);
17905                 } while(expr);
17906                 /* Wake up the forward control dependencies */
17907                 do {
17908                         expr = triple_targ(state, dt->triple, expr);
17909                         awaken(state, dtriple, expr, &work_list_tail);
17910                 } while(expr);
17911                 /* Wake up the reverse control dependencies of this triple */
17912                 for(user = dt->block->ipdomfrontier; user; user = user->next) {
17913                         struct triple *last;
17914                         last = user->member->last;
17915                         while((last->op == OP_NOOP) && (last != user->member->first)) {
17916                                 internal_warning(state, last, "awakening noop?");
17917                                 last = last->prev;
17918                         }
17919                         awaken(state, dtriple, &last, &work_list_tail);
17920                 }
17921         }
17922         print_dead_triples(state, dtriple);
17923         for(dt = &dtriple[1]; dt <= &dtriple[triples]; dt++) {
17924                 if ((dt->triple->op == OP_NOOP) && 
17925                         (dt->flags & TRIPLE_FLAG_ALIVE)) {
17926                         internal_error(state, dt->triple, "noop effective?");
17927                 }
17928                 dt->triple->id = dt->old_id;    /* Restore the color */
17929                 if (!(dt->flags & TRIPLE_FLAG_ALIVE)) {
17930                         release_triple(state, dt->triple);
17931                 }
17932         }
17933         xfree(dtriple);
17934
17935         rebuild_ssa_form(state);
17936
17937         print_blocks(state, __func__, state->dbgout);
17938 }
17939
17940
17941 static void insert_mandatory_copies(struct compile_state *state)
17942 {
17943         struct triple *ins, *first;
17944
17945         /* The object is with a minimum of inserted copies,
17946          * to resolve in fundamental register conflicts between
17947          * register value producers and consumers.
17948          * Theoretically we may be greater than minimal when we
17949          * are inserting copies before instructions but that
17950          * case should be rare.
17951          */
17952         first = state->first;
17953         ins = first;
17954         do {
17955                 struct triple_set *entry, *next;
17956                 struct triple *tmp;
17957                 struct reg_info info;
17958                 unsigned reg, regcm;
17959                 int do_post_copy, do_pre_copy;
17960                 tmp = 0;
17961                 if (!triple_is_def(state, ins)) {
17962                         goto next;
17963                 }
17964                 /* Find the architecture specific color information */
17965                 info = find_lhs_pre_color(state, ins, 0);
17966                 if (info.reg >= MAX_REGISTERS) {
17967                         info.reg = REG_UNSET;
17968                 }
17969
17970                 reg = REG_UNSET;
17971                 regcm = arch_type_to_regcm(state, ins->type);
17972                 do_post_copy = do_pre_copy = 0;
17973
17974                 /* Walk through the uses of ins and check for conflicts */
17975                 for(entry = ins->use; entry; entry = next) {
17976                         struct reg_info rinfo;
17977                         int i;
17978                         next = entry->next;
17979                         i = find_rhs_use(state, entry->member, ins);
17980                         if (i < 0) {
17981                                 continue;
17982                         }
17983                         
17984                         /* Find the users color requirements */
17985                         rinfo = arch_reg_rhs(state, entry->member, i);
17986                         if (rinfo.reg >= MAX_REGISTERS) {
17987                                 rinfo.reg = REG_UNSET;
17988                         }
17989                         
17990                         /* See if I need a pre_copy */
17991                         if (rinfo.reg != REG_UNSET) {
17992                                 if ((reg != REG_UNSET) && (reg != rinfo.reg)) {
17993                                         do_pre_copy = 1;
17994                                 }
17995                                 reg = rinfo.reg;
17996                         }
17997                         regcm &= rinfo.regcm;
17998                         regcm = arch_regcm_normalize(state, regcm);
17999                         if (regcm == 0) {
18000                                 do_pre_copy = 1;
18001                         }
18002                         /* Always use pre_copies for constants.
18003                          * They do not take up any registers until a
18004                          * copy places them in one.
18005                          */
18006                         if ((info.reg == REG_UNNEEDED) && 
18007                                 (rinfo.reg != REG_UNNEEDED)) {
18008                                 do_pre_copy = 1;
18009                         }
18010                 }
18011                 do_post_copy =
18012                         !do_pre_copy &&
18013                         (((info.reg != REG_UNSET) && 
18014                                 (reg != REG_UNSET) &&
18015                                 (info.reg != reg)) ||
18016                         ((info.regcm & regcm) == 0));
18017
18018                 reg = info.reg;
18019                 regcm = info.regcm;
18020                 /* Walk through the uses of ins and do a pre_copy or see if a post_copy is warranted */
18021                 for(entry = ins->use; entry; entry = next) {
18022                         struct reg_info rinfo;
18023                         int i;
18024                         next = entry->next;
18025                         i = find_rhs_use(state, entry->member, ins);
18026                         if (i < 0) {
18027                                 continue;
18028                         }
18029                         
18030                         /* Find the users color requirements */
18031                         rinfo = arch_reg_rhs(state, entry->member, i);
18032                         if (rinfo.reg >= MAX_REGISTERS) {
18033                                 rinfo.reg = REG_UNSET;
18034                         }
18035
18036                         /* Now see if it is time to do the pre_copy */
18037                         if (rinfo.reg != REG_UNSET) {
18038                                 if (((reg != REG_UNSET) && (reg != rinfo.reg)) ||
18039                                         ((regcm & rinfo.regcm) == 0) ||
18040                                         /* Don't let a mandatory coalesce sneak
18041                                          * into a operation that is marked to prevent
18042                                          * coalescing.
18043                                          */
18044                                         ((reg != REG_UNNEEDED) &&
18045                                         ((ins->id & TRIPLE_FLAG_POST_SPLIT) ||
18046                                         (entry->member->id & TRIPLE_FLAG_PRE_SPLIT)))
18047                                         ) {
18048                                         if (do_pre_copy) {
18049                                                 struct triple *user;
18050                                                 user = entry->member;
18051                                                 if (RHS(user, i) != ins) {
18052                                                         internal_error(state, user, "bad rhs");
18053                                                 }
18054                                                 tmp = pre_copy(state, user, i);
18055                                                 tmp->id |= TRIPLE_FLAG_PRE_SPLIT;
18056                                                 continue;
18057                                         } else {
18058                                                 do_post_copy = 1;
18059                                         }
18060                                 }
18061                                 reg = rinfo.reg;
18062                         }
18063                         if ((regcm & rinfo.regcm) == 0) {
18064                                 if (do_pre_copy) {
18065                                         struct triple *user;
18066                                         user = entry->member;
18067                                         if (RHS(user, i) != ins) {
18068                                                 internal_error(state, user, "bad rhs");
18069                                         }
18070                                         tmp = pre_copy(state, user, i);
18071                                         tmp->id |= TRIPLE_FLAG_PRE_SPLIT;
18072                                         continue;
18073                                 } else {
18074                                         do_post_copy = 1;
18075                                 }
18076                         }
18077                         regcm &= rinfo.regcm;
18078                         
18079                 }
18080                 if (do_post_copy) {
18081                         struct reg_info pre, post;
18082                         tmp = post_copy(state, ins);
18083                         tmp->id |= TRIPLE_FLAG_PRE_SPLIT;
18084                         pre = arch_reg_lhs(state, ins, 0);
18085                         post = arch_reg_lhs(state, tmp, 0);
18086                         if ((pre.reg == post.reg) && (pre.regcm == post.regcm)) {
18087                                 internal_error(state, tmp, "useless copy");
18088                         }
18089                 }
18090         next:
18091                 ins = ins->next;
18092         } while(ins != first);
18093
18094         print_blocks(state, __func__, state->dbgout);
18095 }
18096
18097
18098 struct live_range_edge;
18099 struct live_range_def;
18100 struct live_range {
18101         struct live_range_edge *edges;
18102         struct live_range_def *defs;
18103 /* Note. The list pointed to by defs is kept in order.
18104  * That is baring splits in the flow control
18105  * defs dominates defs->next wich dominates defs->next->next
18106  * etc.
18107  */
18108         unsigned color;
18109         unsigned classes;
18110         unsigned degree;
18111         unsigned length;
18112         struct live_range *group_next, **group_prev;
18113 };
18114
18115 struct live_range_edge {
18116         struct live_range_edge *next;
18117         struct live_range *node;
18118 };
18119
18120 struct live_range_def {
18121         struct live_range_def *next;
18122         struct live_range_def *prev;
18123         struct live_range *lr;
18124         struct triple *def;
18125         unsigned orig_id;
18126 };
18127
18128 #define LRE_HASH_SIZE 2048
18129 struct lre_hash {
18130         struct lre_hash *next;
18131         struct live_range *left;
18132         struct live_range *right;
18133 };
18134
18135
18136 struct reg_state {
18137         struct lre_hash *hash[LRE_HASH_SIZE];
18138         struct reg_block *blocks;
18139         struct live_range_def *lrd;
18140         struct live_range *lr;
18141         struct live_range *low, **low_tail;
18142         struct live_range *high, **high_tail;
18143         unsigned defs;
18144         unsigned ranges;
18145         int passes, max_passes;
18146 };
18147
18148
18149 struct print_interference_block_info {
18150         struct reg_state *rstate;
18151         FILE *fp;
18152         int need_edges;
18153 };
18154 static void print_interference_block(
18155         struct compile_state *state, struct block *block, void *arg)
18156
18157 {
18158         struct print_interference_block_info *info = arg;
18159         struct reg_state *rstate = info->rstate;
18160         struct block_set *edge;
18161         FILE *fp = info->fp;
18162         struct reg_block *rb;
18163         struct triple *ptr;
18164         int phi_present;
18165         int done;
18166         rb = &rstate->blocks[block->vertex];
18167
18168         fprintf(fp, "\nblock: %p (%d),",
18169                 block,  block->vertex);
18170         for(edge = block->edges; edge; edge = edge->next) {
18171                 fprintf(fp, " %p<-%p",
18172                         edge->member, 
18173                         edge->member && edge->member->use?edge->member->use->member : 0);
18174         }
18175         fprintf(fp, "\n");
18176         if (rb->in) {
18177                 struct triple_reg_set *in_set;
18178                 fprintf(fp, "        in:");
18179                 for(in_set = rb->in; in_set; in_set = in_set->next) {
18180                         fprintf(fp, " %-10p", in_set->member);
18181                 }
18182                 fprintf(fp, "\n");
18183         }
18184         phi_present = 0;
18185         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
18186                 done = (ptr == block->last);
18187                 if (ptr->op == OP_PHI) {
18188                         phi_present = 1;
18189                         break;
18190                 }
18191         }
18192         if (phi_present) {
18193                 int edge;
18194                 for(edge = 0; edge < block->users; edge++) {
18195                         fprintf(fp, "     in(%d):", edge);
18196                         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
18197                                 struct triple **slot;
18198                                 done = (ptr == block->last);
18199                                 if (ptr->op != OP_PHI) {
18200                                         continue;
18201                                 }
18202                                 slot = &RHS(ptr, 0);
18203                                 fprintf(fp, " %-10p", slot[edge]);
18204                         }
18205                         fprintf(fp, "\n");
18206                 }
18207         }
18208         if (block->first->op == OP_LABEL) {
18209                 fprintf(fp, "%p:\n", block->first);
18210         }
18211         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
18212                 struct live_range *lr;
18213                 unsigned id;
18214                 int op;
18215                 op = ptr->op;
18216                 done = (ptr == block->last);
18217                 lr = rstate->lrd[ptr->id].lr;
18218                 
18219                 id = ptr->id;
18220                 ptr->id = rstate->lrd[id].orig_id;
18221                 SET_REG(ptr->id, lr->color);
18222                 display_triple(fp, ptr);
18223                 ptr->id = id;
18224
18225                 if (triple_is_def(state, ptr) && (lr->defs == 0)) {
18226                         internal_error(state, ptr, "lr has no defs!");
18227                 }
18228                 if (info->need_edges) {
18229                         if (lr->defs) {
18230                                 struct live_range_def *lrd;
18231                                 fprintf(fp, "       range:");
18232                                 lrd = lr->defs;
18233                                 do {
18234                                         fprintf(fp, " %-10p", lrd->def);
18235                                         lrd = lrd->next;
18236                                 } while(lrd != lr->defs);
18237                                 fprintf(fp, "\n");
18238                         }
18239                         if (lr->edges > 0) {
18240                                 struct live_range_edge *edge;
18241                                 fprintf(fp, "       edges:");
18242                                 for(edge = lr->edges; edge; edge = edge->next) {
18243                                         struct live_range_def *lrd;
18244                                         lrd = edge->node->defs;
18245                                         do {
18246                                                 fprintf(fp, " %-10p", lrd->def);
18247                                                 lrd = lrd->next;
18248                                         } while(lrd != edge->node->defs);
18249                                         fprintf(fp, "|");
18250                                 }
18251                                 fprintf(fp, "\n");
18252                         }
18253                 }
18254                 /* Do a bunch of sanity checks */
18255                 valid_ins(state, ptr);
18256                 if ((ptr->id < 0) || (ptr->id > rstate->defs)) {
18257                         internal_error(state, ptr, "Invalid triple id: %d",
18258                                 ptr->id);
18259                 }
18260         }
18261         if (rb->out) {
18262                 struct triple_reg_set *out_set;
18263                 fprintf(fp, "       out:");
18264                 for(out_set = rb->out; out_set; out_set = out_set->next) {
18265                         fprintf(fp, " %-10p", out_set->member);
18266                 }
18267                 fprintf(fp, "\n");
18268         }
18269         fprintf(fp, "\n");
18270 }
18271
18272 static void print_interference_blocks(
18273         struct compile_state *state, struct reg_state *rstate, FILE *fp, int need_edges)
18274 {
18275         struct print_interference_block_info info;
18276         info.rstate = rstate;
18277         info.fp = fp;
18278         info.need_edges = need_edges;
18279         fprintf(fp, "\nlive variables by block\n");
18280         walk_blocks(state, &state->bb, print_interference_block, &info);
18281
18282 }
18283
18284 static unsigned regc_max_size(struct compile_state *state, int classes)
18285 {
18286         unsigned max_size;
18287         int i;
18288         max_size = 0;
18289         for(i = 0; i < MAX_REGC; i++) {
18290                 if (classes & (1 << i)) {
18291                         unsigned size;
18292                         size = arch_regc_size(state, i);
18293                         if (size > max_size) {
18294                                 max_size = size;
18295                         }
18296                 }
18297         }
18298         return max_size;
18299 }
18300
18301 static int reg_is_reg(struct compile_state *state, int reg1, int reg2)
18302 {
18303         unsigned equivs[MAX_REG_EQUIVS];
18304         int i;
18305         if ((reg1 < 0) || (reg1 >= MAX_REGISTERS)) {
18306                 internal_error(state, 0, "invalid register");
18307         }
18308         if ((reg2 < 0) || (reg2 >= MAX_REGISTERS)) {
18309                 internal_error(state, 0, "invalid register");
18310         }
18311         arch_reg_equivs(state, equivs, reg1);
18312         for(i = 0; (i < MAX_REG_EQUIVS) && equivs[i] != REG_UNSET; i++) {
18313                 if (equivs[i] == reg2) {
18314                         return 1;
18315                 }
18316         }
18317         return 0;
18318 }
18319
18320 static void reg_fill_used(struct compile_state *state, char *used, int reg)
18321 {
18322         unsigned equivs[MAX_REG_EQUIVS];
18323         int i;
18324         if (reg == REG_UNNEEDED) {
18325                 return;
18326         }
18327         arch_reg_equivs(state, equivs, reg);
18328         for(i = 0; (i < MAX_REG_EQUIVS) && equivs[i] != REG_UNSET; i++) {
18329                 used[equivs[i]] = 1;
18330         }
18331         return;
18332 }
18333
18334 static void reg_inc_used(struct compile_state *state, char *used, int reg)
18335 {
18336         unsigned equivs[MAX_REG_EQUIVS];
18337         int i;
18338         if (reg == REG_UNNEEDED) {
18339                 return;
18340         }
18341         arch_reg_equivs(state, equivs, reg);
18342         for(i = 0; (i < MAX_REG_EQUIVS) && equivs[i] != REG_UNSET; i++) {
18343                 used[equivs[i]] += 1;
18344         }
18345         return;
18346 }
18347
18348 static unsigned int hash_live_edge(
18349         struct live_range *left, struct live_range *right)
18350 {
18351         unsigned int hash, val;
18352         unsigned long lval, rval;
18353         lval = ((unsigned long)left)/sizeof(struct live_range);
18354         rval = ((unsigned long)right)/sizeof(struct live_range);
18355         hash = 0;
18356         while(lval) {
18357                 val = lval & 0xff;
18358                 lval >>= 8;
18359                 hash = (hash *263) + val;
18360         }
18361         while(rval) {
18362                 val = rval & 0xff;
18363                 rval >>= 8;
18364                 hash = (hash *263) + val;
18365         }
18366         hash = hash & (LRE_HASH_SIZE - 1);
18367         return hash;
18368 }
18369
18370 static struct lre_hash **lre_probe(struct reg_state *rstate,
18371         struct live_range *left, struct live_range *right)
18372 {
18373         struct lre_hash **ptr;
18374         unsigned int index;
18375         /* Ensure left <= right */
18376         if (left > right) {
18377                 struct live_range *tmp;
18378                 tmp = left;
18379                 left = right;
18380                 right = tmp;
18381         }
18382         index = hash_live_edge(left, right);
18383         
18384         ptr = &rstate->hash[index];
18385         while(*ptr) {
18386                 if (((*ptr)->left == left) && ((*ptr)->right == right)) {
18387                         break;
18388                 }
18389                 ptr = &(*ptr)->next;
18390         }
18391         return ptr;
18392 }
18393
18394 static int interfere(struct reg_state *rstate,
18395         struct live_range *left, struct live_range *right)
18396 {
18397         struct lre_hash **ptr;
18398         ptr = lre_probe(rstate, left, right);
18399         return ptr && *ptr;
18400 }
18401
18402 static void add_live_edge(struct reg_state *rstate, 
18403         struct live_range *left, struct live_range *right)
18404 {
18405         /* FIXME the memory allocation overhead is noticeable here... */
18406         struct lre_hash **ptr, *new_hash;
18407         struct live_range_edge *edge;
18408
18409         if (left == right) {
18410                 return;
18411         }
18412         if ((left == &rstate->lr[0]) || (right == &rstate->lr[0])) {
18413                 return;
18414         }
18415         /* Ensure left <= right */
18416         if (left > right) {
18417                 struct live_range *tmp;
18418                 tmp = left;
18419                 left = right;
18420                 right = tmp;
18421         }
18422         ptr = lre_probe(rstate, left, right);
18423         if (*ptr) {
18424                 return;
18425         }
18426 #if 0
18427         fprintf(state->errout, "new_live_edge(%p, %p)\n",
18428                 left, right);
18429 #endif
18430         new_hash = xmalloc(sizeof(*new_hash), "lre_hash");
18431         new_hash->next  = *ptr;
18432         new_hash->left  = left;
18433         new_hash->right = right;
18434         *ptr = new_hash;
18435
18436         edge = xmalloc(sizeof(*edge), "live_range_edge");
18437         edge->next   = left->edges;
18438         edge->node   = right;
18439         left->edges  = edge;
18440         left->degree += 1;
18441         
18442         edge = xmalloc(sizeof(*edge), "live_range_edge");
18443         edge->next    = right->edges;
18444         edge->node    = left;
18445         right->edges  = edge;
18446         right->degree += 1;
18447 }
18448
18449 static void remove_live_edge(struct reg_state *rstate,
18450         struct live_range *left, struct live_range *right)
18451 {
18452         struct live_range_edge *edge, **ptr;
18453         struct lre_hash **hptr, *entry;
18454         hptr = lre_probe(rstate, left, right);
18455         if (!hptr || !*hptr) {
18456                 return;
18457         }
18458         entry = *hptr;
18459         *hptr = entry->next;
18460         xfree(entry);
18461
18462         for(ptr = &left->edges; *ptr; ptr = &(*ptr)->next) {
18463                 edge = *ptr;
18464                 if (edge->node == right) {
18465                         *ptr = edge->next;
18466                         memset(edge, 0, sizeof(*edge));
18467                         xfree(edge);
18468                         right->degree--;
18469                         break;
18470                 }
18471         }
18472         for(ptr = &right->edges; *ptr; ptr = &(*ptr)->next) {
18473                 edge = *ptr;
18474                 if (edge->node == left) {
18475                         *ptr = edge->next;
18476                         memset(edge, 0, sizeof(*edge));
18477                         xfree(edge);
18478                         left->degree--;
18479                         break;
18480                 }
18481         }
18482 }
18483
18484 static void remove_live_edges(struct reg_state *rstate, struct live_range *range)
18485 {
18486         struct live_range_edge *edge, *next;
18487         for(edge = range->edges; edge; edge = next) {
18488                 next = edge->next;
18489                 remove_live_edge(rstate, range, edge->node);
18490         }
18491 }
18492
18493 static void transfer_live_edges(struct reg_state *rstate, 
18494         struct live_range *dest, struct live_range *src)
18495 {
18496         struct live_range_edge *edge, *next;
18497         for(edge = src->edges; edge; edge = next) {
18498                 struct live_range *other;
18499                 next = edge->next;
18500                 other = edge->node;
18501                 remove_live_edge(rstate, src, other);
18502                 add_live_edge(rstate, dest, other);
18503         }
18504 }
18505
18506
18507 /* Interference graph...
18508  * 
18509  * new(n) --- Return a graph with n nodes but no edges.
18510  * add(g,x,y) --- Return a graph including g with an between x and y
18511  * interfere(g, x, y) --- Return true if there exists an edge between the nodes
18512  *                x and y in the graph g
18513  * degree(g, x) --- Return the degree of the node x in the graph g
18514  * neighbors(g, x, f) --- Apply function f to each neighbor of node x in the graph g
18515  *
18516  * Implement with a hash table && a set of adjcency vectors.
18517  * The hash table supports constant time implementations of add and interfere.
18518  * The adjacency vectors support an efficient implementation of neighbors.
18519  */
18520
18521 /* 
18522  *     +---------------------------------------------------+
18523  *     |         +--------------+                          |
18524  *     v         v              |                          |
18525  * renumber -> build graph -> colalesce -> spill_costs -> simplify -> select 
18526  *
18527  * -- In simplify implment optimistic coloring... (No backtracking)
18528  * -- Implement Rematerialization it is the only form of spilling we can perform
18529  *    Essentially this means dropping a constant from a register because
18530  *    we can regenerate it later.
18531  *
18532  * --- Very conservative colalescing (don't colalesce just mark the opportunities)
18533  *     coalesce at phi points...
18534  * --- Bias coloring if at all possible do the coalesing a compile time.
18535  *
18536  *
18537  */
18538
18539 static void different_colored(
18540         struct compile_state *state, struct reg_state *rstate, 
18541         struct triple *parent, struct triple *ins)
18542 {
18543         struct live_range *lr;
18544         struct triple **expr;
18545         lr = rstate->lrd[ins->id].lr;
18546         expr = triple_rhs(state, ins, 0);
18547         for(;expr; expr = triple_rhs(state, ins, expr)) {
18548                 struct live_range *lr2;
18549                 if (!*expr || (*expr == parent) || (*expr == ins)) {
18550                         continue;
18551                 }
18552                 lr2 = rstate->lrd[(*expr)->id].lr;
18553                 if (lr->color == lr2->color) {
18554                         internal_error(state, ins, "live range too big");
18555                 }
18556         }
18557 }
18558
18559
18560 static struct live_range *coalesce_ranges(
18561         struct compile_state *state, struct reg_state *rstate,
18562         struct live_range *lr1, struct live_range *lr2)
18563 {
18564         struct live_range_def *head, *mid1, *mid2, *end, *lrd;
18565         unsigned color;
18566         unsigned classes;
18567         if (lr1 == lr2) {
18568                 return lr1;
18569         }
18570         if (!lr1->defs || !lr2->defs) {
18571                 internal_error(state, 0,
18572                         "cannot coalese dead live ranges");
18573         }
18574         if ((lr1->color == REG_UNNEEDED) ||
18575                 (lr2->color == REG_UNNEEDED)) {
18576                 internal_error(state, 0, 
18577                         "cannot coalesce live ranges without a possible color");
18578         }
18579         if ((lr1->color != lr2->color) &&
18580                 (lr1->color != REG_UNSET) &&
18581                 (lr2->color != REG_UNSET)) {
18582                 internal_error(state, lr1->defs->def, 
18583                         "cannot coalesce live ranges of different colors");
18584         }
18585         color = lr1->color;
18586         if (color == REG_UNSET) {
18587                 color = lr2->color;
18588         }
18589         classes = lr1->classes & lr2->classes;
18590         if (!classes) {
18591                 internal_error(state, lr1->defs->def,
18592                         "cannot coalesce live ranges with dissimilar register classes");
18593         }
18594         if (state->compiler->debug & DEBUG_COALESCING) {
18595                 FILE *fp = state->errout;
18596                 fprintf(fp, "coalescing:");
18597                 lrd = lr1->defs;
18598                 do {
18599                         fprintf(fp, " %p", lrd->def);
18600                         lrd = lrd->next;
18601                 } while(lrd != lr1->defs);
18602                 fprintf(fp, " |");
18603                 lrd = lr2->defs;
18604                 do {
18605                         fprintf(fp, " %p", lrd->def);
18606                         lrd = lrd->next;
18607                 } while(lrd != lr2->defs);
18608                 fprintf(fp, "\n");
18609         }
18610         /* If there is a clear dominate live range put it in lr1,
18611          * For purposes of this test phi functions are
18612          * considered dominated by the definitions that feed into
18613          * them. 
18614          */
18615         if ((lr1->defs->prev->def->op == OP_PHI) ||
18616                 ((lr2->defs->prev->def->op != OP_PHI) &&
18617                 tdominates(state, lr2->defs->def, lr1->defs->def))) {
18618                 struct live_range *tmp;
18619                 tmp = lr1;
18620                 lr1 = lr2;
18621                 lr2 = tmp;
18622         }
18623 #if 0
18624         if (lr1->defs->orig_id  & TRIPLE_FLAG_POST_SPLIT) {
18625                 fprintf(state->errout, "lr1 post\n");
18626         }
18627         if (lr1->defs->orig_id & TRIPLE_FLAG_PRE_SPLIT) {
18628                 fprintf(state->errout, "lr1 pre\n");
18629         }
18630         if (lr2->defs->orig_id  & TRIPLE_FLAG_POST_SPLIT) {
18631                 fprintf(state->errout, "lr2 post\n");
18632         }
18633         if (lr2->defs->orig_id & TRIPLE_FLAG_PRE_SPLIT) {
18634                 fprintf(state->errout, "lr2 pre\n");
18635         }
18636 #endif
18637 #if 0
18638         fprintf(state->errout, "coalesce color1(%p): %3d color2(%p) %3d\n",
18639                 lr1->defs->def,
18640                 lr1->color,
18641                 lr2->defs->def,
18642                 lr2->color);
18643 #endif
18644         
18645         /* Append lr2 onto lr1 */
18646 #warning "FIXME should this be a merge instead of a splice?"
18647         /* This FIXME item applies to the correctness of live_range_end 
18648          * and to the necessity of making multiple passes of coalesce_live_ranges.
18649          * A failure to find some coalesce opportunities in coaleace_live_ranges
18650          * does not impact the correct of the compiler just the efficiency with
18651          * which registers are allocated.
18652          */
18653         head = lr1->defs;
18654         mid1 = lr1->defs->prev;
18655         mid2 = lr2->defs;
18656         end  = lr2->defs->prev;
18657         
18658         head->prev = end;
18659         end->next  = head;
18660
18661         mid1->next = mid2;
18662         mid2->prev = mid1;
18663
18664         /* Fixup the live range in the added live range defs */
18665         lrd = head;
18666         do {
18667                 lrd->lr = lr1;
18668                 lrd = lrd->next;
18669         } while(lrd != head);
18670
18671         /* Mark lr2 as free. */
18672         lr2->defs = 0;
18673         lr2->color = REG_UNNEEDED;
18674         lr2->classes = 0;
18675
18676         if (!lr1->defs) {
18677                 internal_error(state, 0, "lr1->defs == 0 ?");
18678         }
18679
18680         lr1->color   = color;
18681         lr1->classes = classes;
18682
18683         /* Keep the graph in sync by transfering the edges from lr2 to lr1 */
18684         transfer_live_edges(rstate, lr1, lr2);
18685
18686         return lr1;
18687 }
18688
18689 static struct live_range_def *live_range_head(
18690         struct compile_state *state, struct live_range *lr,
18691         struct live_range_def *last)
18692 {
18693         struct live_range_def *result;
18694         result = 0;
18695         if (last == 0) {
18696                 result = lr->defs;
18697         }
18698         else if (!tdominates(state, lr->defs->def, last->next->def)) {
18699                 result = last->next;
18700         }
18701         return result;
18702 }
18703
18704 static struct live_range_def *live_range_end(
18705         struct compile_state *state, struct live_range *lr,
18706         struct live_range_def *last)
18707 {
18708         struct live_range_def *result;
18709         result = 0;
18710         if (last == 0) {
18711                 result = lr->defs->prev;
18712         }
18713         else if (!tdominates(state, last->prev->def, lr->defs->prev->def)) {
18714                 result = last->prev;
18715         }
18716         return result;
18717 }
18718
18719
18720 static void initialize_live_ranges(
18721         struct compile_state *state, struct reg_state *rstate)
18722 {
18723         struct triple *ins, *first;
18724         size_t count, size;
18725         int i, j;
18726
18727         first = state->first;
18728         /* First count how many instructions I have.
18729          */
18730         count = count_triples(state);
18731         /* Potentially I need one live range definitions for each
18732          * instruction.
18733          */
18734         rstate->defs = count;
18735         /* Potentially I need one live range for each instruction
18736          * plus an extra for the dummy live range.
18737          */
18738         rstate->ranges = count + 1;
18739         size = sizeof(rstate->lrd[0]) * rstate->defs;
18740         rstate->lrd = xcmalloc(size, "live_range_def");
18741         size = sizeof(rstate->lr[0]) * rstate->ranges;
18742         rstate->lr  = xcmalloc(size, "live_range");
18743
18744         /* Setup the dummy live range */
18745         rstate->lr[0].classes = 0;
18746         rstate->lr[0].color = REG_UNSET;
18747         rstate->lr[0].defs = 0;
18748         i = j = 0;
18749         ins = first;
18750         do {
18751                 /* If the triple is a variable give it a live range */
18752                 if (triple_is_def(state, ins)) {
18753                         struct reg_info info;
18754                         /* Find the architecture specific color information */
18755                         info = find_def_color(state, ins);
18756                         i++;
18757                         rstate->lr[i].defs    = &rstate->lrd[j];
18758                         rstate->lr[i].color   = info.reg;
18759                         rstate->lr[i].classes = info.regcm;
18760                         rstate->lr[i].degree  = 0;
18761                         rstate->lrd[j].lr = &rstate->lr[i];
18762                 } 
18763                 /* Otherwise give the triple the dummy live range. */
18764                 else {
18765                         rstate->lrd[j].lr = &rstate->lr[0];
18766                 }
18767
18768                 /* Initalize the live_range_def */
18769                 rstate->lrd[j].next    = &rstate->lrd[j];
18770                 rstate->lrd[j].prev    = &rstate->lrd[j];
18771                 rstate->lrd[j].def     = ins;
18772                 rstate->lrd[j].orig_id = ins->id;
18773                 ins->id = j;
18774
18775                 j++;
18776                 ins = ins->next;
18777         } while(ins != first);
18778         rstate->ranges = i;
18779
18780         /* Make a second pass to handle achitecture specific register
18781          * constraints.
18782          */
18783         ins = first;
18784         do {
18785                 int zlhs, zrhs, i, j;
18786                 if (ins->id > rstate->defs) {
18787                         internal_error(state, ins, "bad id");
18788                 }
18789                 
18790                 /* Walk through the template of ins and coalesce live ranges */
18791                 zlhs = ins->lhs;
18792                 if ((zlhs == 0) && triple_is_def(state, ins)) {
18793                         zlhs = 1;
18794                 }
18795                 zrhs = ins->rhs;
18796
18797                 if (state->compiler->debug & DEBUG_COALESCING2) {
18798                         fprintf(state->errout, "mandatory coalesce: %p %d %d\n",
18799                                 ins, zlhs, zrhs);
18800                 }
18801
18802                 for(i = 0; i < zlhs; i++) {
18803                         struct reg_info linfo;
18804                         struct live_range_def *lhs;
18805                         linfo = arch_reg_lhs(state, ins, i);
18806                         if (linfo.reg < MAX_REGISTERS) {
18807                                 continue;
18808                         }
18809                         if (triple_is_def(state, ins)) {
18810                                 lhs = &rstate->lrd[ins->id];
18811                         } else {
18812                                 lhs = &rstate->lrd[LHS(ins, i)->id];
18813                         }
18814
18815                         if (state->compiler->debug & DEBUG_COALESCING2) {
18816                                 fprintf(state->errout, "coalesce lhs(%d): %p %d\n",
18817                                         i, lhs, linfo.reg);
18818                         }
18819
18820                         for(j = 0; j < zrhs; j++) {
18821                                 struct reg_info rinfo;
18822                                 struct live_range_def *rhs;
18823                                 rinfo = arch_reg_rhs(state, ins, j);
18824                                 if (rinfo.reg < MAX_REGISTERS) {
18825                                         continue;
18826                                 }
18827                                 rhs = &rstate->lrd[RHS(ins, j)->id];
18828
18829                                 if (state->compiler->debug & DEBUG_COALESCING2) {
18830                                         fprintf(state->errout, "coalesce rhs(%d): %p %d\n",
18831                                                 j, rhs, rinfo.reg);
18832                                 }
18833
18834                                 if (rinfo.reg == linfo.reg) {
18835                                         coalesce_ranges(state, rstate, 
18836                                                 lhs->lr, rhs->lr);
18837                                 }
18838                         }
18839                 }
18840                 ins = ins->next;
18841         } while(ins != first);
18842 }
18843
18844 static void graph_ins(
18845         struct compile_state *state, 
18846         struct reg_block *blocks, struct triple_reg_set *live, 
18847         struct reg_block *rb, struct triple *ins, void *arg)
18848 {
18849         struct reg_state *rstate = arg;
18850         struct live_range *def;
18851         struct triple_reg_set *entry;
18852
18853         /* If the triple is not a definition
18854          * we do not have a definition to add to
18855          * the interference graph.
18856          */
18857         if (!triple_is_def(state, ins)) {
18858                 return;
18859         }
18860         def = rstate->lrd[ins->id].lr;
18861         
18862         /* Create an edge between ins and everything that is
18863          * alive, unless the live_range cannot share
18864          * a physical register with ins.
18865          */
18866         for(entry = live; entry; entry = entry->next) {
18867                 struct live_range *lr;
18868                 if ((entry->member->id < 0) || (entry->member->id > rstate->defs)) {
18869                         internal_error(state, 0, "bad entry?");
18870                 }
18871                 lr = rstate->lrd[entry->member->id].lr;
18872                 if (def == lr) {
18873                         continue;
18874                 }
18875                 if (!arch_regcm_intersect(def->classes, lr->classes)) {
18876                         continue;
18877                 }
18878                 add_live_edge(rstate, def, lr);
18879         }
18880         return;
18881 }
18882
18883 static struct live_range *get_verify_live_range(
18884         struct compile_state *state, struct reg_state *rstate, struct triple *ins)
18885 {
18886         struct live_range *lr;
18887         struct live_range_def *lrd;
18888         int ins_found;
18889         if ((ins->id < 0) || (ins->id > rstate->defs)) {
18890                 internal_error(state, ins, "bad ins?");
18891         }
18892         lr = rstate->lrd[ins->id].lr;
18893         ins_found = 0;
18894         lrd = lr->defs;
18895         do {
18896                 if (lrd->def == ins) {
18897                         ins_found = 1;
18898                 }
18899                 lrd = lrd->next;
18900         } while(lrd != lr->defs);
18901         if (!ins_found) {
18902                 internal_error(state, ins, "ins not in live range");
18903         }
18904         return lr;
18905 }
18906
18907 static void verify_graph_ins(
18908         struct compile_state *state, 
18909         struct reg_block *blocks, struct triple_reg_set *live, 
18910         struct reg_block *rb, struct triple *ins, void *arg)
18911 {
18912         struct reg_state *rstate = arg;
18913         struct triple_reg_set *entry1, *entry2;
18914
18915
18916         /* Compare live against edges and make certain the code is working */
18917         for(entry1 = live; entry1; entry1 = entry1->next) {
18918                 struct live_range *lr1;
18919                 lr1 = get_verify_live_range(state, rstate, entry1->member);
18920                 for(entry2 = live; entry2; entry2 = entry2->next) {
18921                         struct live_range *lr2;
18922                         struct live_range_edge *edge2;
18923                         int lr1_found;
18924                         int lr2_degree;
18925                         if (entry2 == entry1) {
18926                                 continue;
18927                         }
18928                         lr2 = get_verify_live_range(state, rstate, entry2->member);
18929                         if (lr1 == lr2) {
18930                                 internal_error(state, entry2->member, 
18931                                         "live range with 2 values simultaneously alive");
18932                         }
18933                         if (!arch_regcm_intersect(lr1->classes, lr2->classes)) {
18934                                 continue;
18935                         }
18936                         if (!interfere(rstate, lr1, lr2)) {
18937                                 internal_error(state, entry2->member, 
18938                                         "edges don't interfere?");
18939                         }
18940                                 
18941                         lr1_found = 0;
18942                         lr2_degree = 0;
18943                         for(edge2 = lr2->edges; edge2; edge2 = edge2->next) {
18944                                 lr2_degree++;
18945                                 if (edge2->node == lr1) {
18946                                         lr1_found = 1;
18947                                 }
18948                         }
18949                         if (lr2_degree != lr2->degree) {
18950                                 internal_error(state, entry2->member,
18951                                         "computed degree: %d does not match reported degree: %d\n",
18952                                         lr2_degree, lr2->degree);
18953                         }
18954                         if (!lr1_found) {
18955                                 internal_error(state, entry2->member, "missing edge");
18956                         }
18957                 }
18958         }
18959         return;
18960 }
18961
18962
18963 static void print_interference_ins(
18964         struct compile_state *state, 
18965         struct reg_block *blocks, struct triple_reg_set *live, 
18966         struct reg_block *rb, struct triple *ins, void *arg)
18967 {
18968         struct reg_state *rstate = arg;
18969         struct live_range *lr;
18970         unsigned id;
18971         FILE *fp = state->dbgout;
18972
18973         lr = rstate->lrd[ins->id].lr;
18974         id = ins->id;
18975         ins->id = rstate->lrd[id].orig_id;
18976         SET_REG(ins->id, lr->color);
18977         display_triple(state->dbgout, ins);
18978         ins->id = id;
18979
18980         if (lr->defs) {
18981                 struct live_range_def *lrd;
18982                 fprintf(fp, "       range:");
18983                 lrd = lr->defs;
18984                 do {
18985                         fprintf(fp, " %-10p", lrd->def);
18986                         lrd = lrd->next;
18987                 } while(lrd != lr->defs);
18988                 fprintf(fp, "\n");
18989         }
18990         if (live) {
18991                 struct triple_reg_set *entry;
18992                 fprintf(fp, "        live:");
18993                 for(entry = live; entry; entry = entry->next) {
18994                         fprintf(fp, " %-10p", entry->member);
18995                 }
18996                 fprintf(fp, "\n");
18997         }
18998         if (lr->edges) {
18999                 struct live_range_edge *entry;
19000                 fprintf(fp, "       edges:");
19001                 for(entry = lr->edges; entry; entry = entry->next) {
19002                         struct live_range_def *lrd;
19003                         lrd = entry->node->defs;
19004                         do {
19005                                 fprintf(fp, " %-10p", lrd->def);
19006                                 lrd = lrd->next;
19007                         } while(lrd != entry->node->defs);
19008                         fprintf(fp, "|");
19009                 }
19010                 fprintf(fp, "\n");
19011         }
19012         if (triple_is_branch(state, ins)) {
19013                 fprintf(fp, "\n");
19014         }
19015         return;
19016 }
19017
19018 static int coalesce_live_ranges(
19019         struct compile_state *state, struct reg_state *rstate)
19020 {
19021         /* At the point where a value is moved from one
19022          * register to another that value requires two
19023          * registers, thus increasing register pressure.
19024          * Live range coaleescing reduces the register
19025          * pressure by keeping a value in one register
19026          * longer.
19027          *
19028          * In the case of a phi function all paths leading
19029          * into it must be allocated to the same register
19030          * otherwise the phi function may not be removed.
19031          *
19032          * Forcing a value to stay in a single register
19033          * for an extended period of time does have
19034          * limitations when applied to non homogenous
19035          * register pool.  
19036          *
19037          * The two cases I have identified are:
19038          * 1) Two forced register assignments may
19039          *    collide.
19040          * 2) Registers may go unused because they
19041          *    are only good for storing the value
19042          *    and not manipulating it.
19043          *
19044          * Because of this I need to split live ranges,
19045          * even outside of the context of coalesced live
19046          * ranges.  The need to split live ranges does
19047          * impose some constraints on live range coalescing.
19048          *
19049          * - Live ranges may not be coalesced across phi
19050          *   functions.  This creates a 2 headed live
19051          *   range that cannot be sanely split.
19052          *
19053          * - phi functions (coalesced in initialize_live_ranges) 
19054          *   are handled as pre split live ranges so we will
19055          *   never attempt to split them.
19056          */
19057         int coalesced;
19058         int i;
19059
19060         coalesced = 0;
19061         for(i = 0; i <= rstate->ranges; i++) {
19062                 struct live_range *lr1;
19063                 struct live_range_def *lrd1;
19064                 lr1 = &rstate->lr[i];
19065                 if (!lr1->defs) {
19066                         continue;
19067                 }
19068                 lrd1 = live_range_end(state, lr1, 0);
19069                 for(; lrd1; lrd1 = live_range_end(state, lr1, lrd1)) {
19070                         struct triple_set *set;
19071                         if (lrd1->def->op != OP_COPY) {
19072                                 continue;
19073                         }
19074                         /* Skip copies that are the result of a live range split. */
19075                         if (lrd1->orig_id & TRIPLE_FLAG_POST_SPLIT) {
19076                                 continue;
19077                         }
19078                         for(set = lrd1->def->use; set; set = set->next) {
19079                                 struct live_range_def *lrd2;
19080                                 struct live_range *lr2, *res;
19081
19082                                 lrd2 = &rstate->lrd[set->member->id];
19083
19084                                 /* Don't coalesce with instructions
19085                                  * that are the result of a live range
19086                                  * split.
19087                                  */
19088                                 if (lrd2->orig_id & TRIPLE_FLAG_PRE_SPLIT) {
19089                                         continue;
19090                                 }
19091                                 lr2 = rstate->lrd[set->member->id].lr;
19092                                 if (lr1 == lr2) {
19093                                         continue;
19094                                 }
19095                                 if ((lr1->color != lr2->color) &&
19096                                         (lr1->color != REG_UNSET) &&
19097                                         (lr2->color != REG_UNSET)) {
19098                                         continue;
19099                                 }
19100                                 if ((lr1->classes & lr2->classes) == 0) {
19101                                         continue;
19102                                 }
19103                                 
19104                                 if (interfere(rstate, lr1, lr2)) {
19105                                         continue;
19106                                 }
19107
19108                                 res = coalesce_ranges(state, rstate, lr1, lr2);
19109                                 coalesced += 1;
19110                                 if (res != lr1) {
19111                                         goto next;
19112                                 }
19113                         }
19114                 }
19115         next:
19116                 ;
19117         }
19118         return coalesced;
19119 }
19120
19121
19122 static void fix_coalesce_conflicts(struct compile_state *state,
19123         struct reg_block *blocks, struct triple_reg_set *live,
19124         struct reg_block *rb, struct triple *ins, void *arg)
19125 {
19126         int *conflicts = arg;
19127         int zlhs, zrhs, i, j;
19128
19129         /* See if we have a mandatory coalesce operation between
19130          * a lhs and a rhs value.  If so and the rhs value is also
19131          * alive then this triple needs to be pre copied.  Otherwise
19132          * we would have two definitions in the same live range simultaneously
19133          * alive.
19134          */
19135         zlhs = ins->lhs;
19136         if ((zlhs == 0) && triple_is_def(state, ins)) {
19137                 zlhs = 1;
19138         }
19139         zrhs = ins->rhs;
19140         for(i = 0; i < zlhs; i++) {
19141                 struct reg_info linfo;
19142                 linfo = arch_reg_lhs(state, ins, i);
19143                 if (linfo.reg < MAX_REGISTERS) {
19144                         continue;
19145                 }
19146                 for(j = 0; j < zrhs; j++) {
19147                         struct reg_info rinfo;
19148                         struct triple *rhs;
19149                         struct triple_reg_set *set;
19150                         int found;
19151                         found = 0;
19152                         rinfo = arch_reg_rhs(state, ins, j);
19153                         if (rinfo.reg != linfo.reg) {
19154                                 continue;
19155                         }
19156                         rhs = RHS(ins, j);
19157                         for(set = live; set && !found; set = set->next) {
19158                                 if (set->member == rhs) {
19159                                         found = 1;
19160                                 }
19161                         }
19162                         if (found) {
19163                                 struct triple *copy;
19164                                 copy = pre_copy(state, ins, j);
19165                                 copy->id |= TRIPLE_FLAG_PRE_SPLIT;
19166                                 (*conflicts)++;
19167                         }
19168                 }
19169         }
19170         return;
19171 }
19172
19173 static int correct_coalesce_conflicts(
19174         struct compile_state *state, struct reg_block *blocks)
19175 {
19176         int conflicts;
19177         conflicts = 0;
19178         walk_variable_lifetimes(state, &state->bb, blocks, 
19179                 fix_coalesce_conflicts, &conflicts);
19180         return conflicts;
19181 }
19182
19183 static void replace_set_use(struct compile_state *state,
19184         struct triple_reg_set *head, struct triple *orig, struct triple *new)
19185 {
19186         struct triple_reg_set *set;
19187         for(set = head; set; set = set->next) {
19188                 if (set->member == orig) {
19189                         set->member = new;
19190                 }
19191         }
19192 }
19193
19194 static void replace_block_use(struct compile_state *state, 
19195         struct reg_block *blocks, struct triple *orig, struct triple *new)
19196 {
19197         int i;
19198 #warning "WISHLIST visit just those blocks that need it *"
19199         for(i = 1; i <= state->bb.last_vertex; i++) {
19200                 struct reg_block *rb;
19201                 rb = &blocks[i];
19202                 replace_set_use(state, rb->in, orig, new);
19203                 replace_set_use(state, rb->out, orig, new);
19204         }
19205 }
19206
19207 static void color_instructions(struct compile_state *state)
19208 {
19209         struct triple *ins, *first;
19210         first = state->first;
19211         ins = first;
19212         do {
19213                 if (triple_is_def(state, ins)) {
19214                         struct reg_info info;
19215                         info = find_lhs_color(state, ins, 0);
19216                         if (info.reg >= MAX_REGISTERS) {
19217                                 info.reg = REG_UNSET;
19218                         }
19219                         SET_INFO(ins->id, info);
19220                 }
19221                 ins = ins->next;
19222         } while(ins != first);
19223 }
19224
19225 static struct reg_info read_lhs_color(
19226         struct compile_state *state, struct triple *ins, int index)
19227 {
19228         struct reg_info info;
19229         if ((index == 0) && triple_is_def(state, ins)) {
19230                 info.reg   = ID_REG(ins->id);
19231                 info.regcm = ID_REGCM(ins->id);
19232         }
19233         else if (index < ins->lhs) {
19234                 info = read_lhs_color(state, LHS(ins, index), 0);
19235         }
19236         else {
19237                 internal_error(state, ins, "Bad lhs %d", index);
19238                 info.reg = REG_UNSET;
19239                 info.regcm = 0;
19240         }
19241         return info;
19242 }
19243
19244 static struct triple *resolve_tangle(
19245         struct compile_state *state, struct triple *tangle)
19246 {
19247         struct reg_info info, uinfo;
19248         struct triple_set *set, *next;
19249         struct triple *copy;
19250
19251 #warning "WISHLIST recalculate all affected instructions colors"
19252         info = find_lhs_color(state, tangle, 0);
19253         for(set = tangle->use; set; set = next) {
19254                 struct triple *user;
19255                 int i, zrhs;
19256                 next = set->next;
19257                 user = set->member;
19258                 zrhs = user->rhs;
19259                 for(i = 0; i < zrhs; i++) {
19260                         if (RHS(user, i) != tangle) {
19261                                 continue;
19262                         }
19263                         uinfo = find_rhs_post_color(state, user, i);
19264                         if (uinfo.reg == info.reg) {
19265                                 copy = pre_copy(state, user, i);
19266                                 copy->id |= TRIPLE_FLAG_PRE_SPLIT;
19267                                 SET_INFO(copy->id, uinfo);
19268                         }
19269                 }
19270         }
19271         copy = 0;
19272         uinfo = find_lhs_pre_color(state, tangle, 0);
19273         if (uinfo.reg == info.reg) {
19274                 struct reg_info linfo;
19275                 copy = post_copy(state, tangle);
19276                 copy->id |= TRIPLE_FLAG_PRE_SPLIT;
19277                 linfo = find_lhs_color(state, copy, 0);
19278                 SET_INFO(copy->id, linfo);
19279         }
19280         info = find_lhs_color(state, tangle, 0);
19281         SET_INFO(tangle->id, info);
19282         
19283         return copy;
19284 }
19285
19286
19287 static void fix_tangles(struct compile_state *state,
19288         struct reg_block *blocks, struct triple_reg_set *live,
19289         struct reg_block *rb, struct triple *ins, void *arg)
19290 {
19291         int *tangles = arg;
19292         struct triple *tangle;
19293         do {
19294                 char used[MAX_REGISTERS];
19295                 struct triple_reg_set *set;
19296                 tangle = 0;
19297
19298                 /* Find out which registers have multiple uses at this point */
19299                 memset(used, 0, sizeof(used));
19300                 for(set = live; set; set = set->next) {
19301                         struct reg_info info;
19302                         info = read_lhs_color(state, set->member, 0);
19303                         if (info.reg == REG_UNSET) {
19304                                 continue;
19305                         }
19306                         reg_inc_used(state, used, info.reg);
19307                 }
19308                 
19309                 /* Now find the least dominated definition of a register in
19310                  * conflict I have seen so far.
19311                  */
19312                 for(set = live; set; set = set->next) {
19313                         struct reg_info info;
19314                         info = read_lhs_color(state, set->member, 0);
19315                         if (used[info.reg] < 2) {
19316                                 continue;
19317                         }
19318                         /* Changing copies that feed into phi functions
19319                          * is incorrect.
19320                          */
19321                         if (set->member->use && 
19322                                 (set->member->use->member->op == OP_PHI)) {
19323                                 continue;
19324                         }
19325                         if (!tangle || tdominates(state, set->member, tangle)) {
19326                                 tangle = set->member;
19327                         }
19328                 }
19329                 /* If I have found a tangle resolve it */
19330                 if (tangle) {
19331                         struct triple *post_copy;
19332                         (*tangles)++;
19333                         post_copy = resolve_tangle(state, tangle);
19334                         if (post_copy) {
19335                                 replace_block_use(state, blocks, tangle, post_copy);
19336                         }
19337                         if (post_copy && (tangle != ins)) {
19338                                 replace_set_use(state, live, tangle, post_copy);
19339                         }
19340                 }
19341         } while(tangle);
19342         return;
19343 }
19344
19345 static int correct_tangles(
19346         struct compile_state *state, struct reg_block *blocks)
19347 {
19348         int tangles;
19349         tangles = 0;
19350         color_instructions(state);
19351         walk_variable_lifetimes(state, &state->bb, blocks, 
19352                 fix_tangles, &tangles);
19353         return tangles;
19354 }
19355
19356
19357 static void ids_from_rstate(struct compile_state *state, struct reg_state *rstate);
19358 static void cleanup_rstate(struct compile_state *state, struct reg_state *rstate);
19359
19360 struct triple *find_constrained_def(
19361         struct compile_state *state, struct live_range *range, struct triple *constrained)
19362 {
19363         struct live_range_def *lrd, *lrd_next;
19364         lrd_next = range->defs;
19365         do {
19366                 struct reg_info info;
19367                 unsigned regcm;
19368
19369                 lrd = lrd_next;
19370                 lrd_next = lrd->next;
19371
19372                 regcm = arch_type_to_regcm(state, lrd->def->type);
19373                 info = find_lhs_color(state, lrd->def, 0);
19374                 regcm      = arch_regcm_reg_normalize(state, regcm);
19375                 info.regcm = arch_regcm_reg_normalize(state, info.regcm);
19376                 /* If the 2 register class masks are equal then
19377                  * the current register class is not constrained.
19378                  */
19379                 if (regcm == info.regcm) {
19380                         continue;
19381                 }
19382                 
19383                 /* If there is just one use.
19384                  * That use cannot accept a larger register class.
19385                  * There are no intervening definitions except
19386                  * definitions that feed into that use.
19387                  * Then a triple is not constrained.
19388                  * FIXME handle this case!
19389                  */
19390 #warning "FIXME ignore cases that cannot be fixed (a definition followed by a use)"
19391                 
19392
19393                 /* Of the constrained live ranges deal with the
19394                  * least dominated one first.
19395                  */
19396                 if (state->compiler->debug & DEBUG_RANGE_CONFLICTS) {
19397                         fprintf(state->errout, "canidate: %p %-8s regcm: %x %x\n",
19398                                 lrd->def, tops(lrd->def->op), regcm, info.regcm);
19399                 }
19400                 if (!constrained || 
19401                         tdominates(state, lrd->def, constrained))
19402                 {
19403                         constrained = lrd->def;
19404                 }
19405         } while(lrd_next != range->defs);
19406         return constrained;
19407 }
19408
19409 static int split_constrained_ranges(
19410         struct compile_state *state, struct reg_state *rstate, 
19411         struct live_range *range)
19412 {
19413         /* Walk through the edges in conflict and our current live
19414          * range, and find definitions that are more severly constrained
19415          * than they type of data they contain require.
19416          * 
19417          * Then pick one of those ranges and relax the constraints.
19418          */
19419         struct live_range_edge *edge;
19420         struct triple *constrained;
19421
19422         constrained = 0;
19423         for(edge = range->edges; edge; edge = edge->next) {
19424                 constrained = find_constrained_def(state, edge->node, constrained);
19425         }
19426 #warning "FIXME should I call find_constrained_def here only if no previous constrained def was found?"
19427         if (!constrained) {
19428                 constrained = find_constrained_def(state, range, constrained);
19429         }
19430
19431         if (state->compiler->debug & DEBUG_RANGE_CONFLICTS) {
19432                 fprintf(state->errout, "constrained: ");
19433                 display_triple(state->errout, constrained);
19434         }
19435         if (constrained) {
19436                 ids_from_rstate(state, rstate);
19437                 cleanup_rstate(state, rstate);
19438                 resolve_tangle(state, constrained);
19439         }
19440         return !!constrained;
19441 }
19442         
19443 static int split_ranges(
19444         struct compile_state *state, struct reg_state *rstate,
19445         char *used, struct live_range *range)
19446 {
19447         int split;
19448         if (state->compiler->debug & DEBUG_RANGE_CONFLICTS) {
19449                 fprintf(state->errout, "split_ranges %d %s %p\n", 
19450                         rstate->passes, tops(range->defs->def->op), range->defs->def);
19451         }
19452         if ((range->color == REG_UNNEEDED) ||
19453                 (rstate->passes >= rstate->max_passes)) {
19454                 return 0;
19455         }
19456         split = split_constrained_ranges(state, rstate, range);
19457
19458         /* Ideally I would split the live range that will not be used
19459          * for the longest period of time in hopes that this will 
19460          * (a) allow me to spill a register or
19461          * (b) allow me to place a value in another register.
19462          *
19463          * So far I don't have a test case for this, the resolving
19464          * of mandatory constraints has solved all of my
19465          * know issues.  So I have choosen not to write any
19466          * code until I cat get a better feel for cases where
19467          * it would be useful to have.
19468          *
19469          */
19470 #warning "WISHLIST implement live range splitting..."
19471         
19472         if (!split && (state->compiler->debug & DEBUG_RANGE_CONFLICTS2)) {
19473                 FILE *fp = state->errout;
19474                 print_interference_blocks(state, rstate, fp, 0);
19475                 print_dominators(state, fp, &state->bb);
19476         }
19477         return split;
19478 }
19479
19480 static FILE *cgdebug_fp(struct compile_state *state)
19481 {
19482         FILE *fp;
19483         fp = 0;
19484         if (!fp && (state->compiler->debug & DEBUG_COLOR_GRAPH2)) {
19485                 fp = state->errout;
19486         }
19487         if (!fp && (state->compiler->debug & DEBUG_COLOR_GRAPH)) {
19488                 fp = state->dbgout;
19489         }
19490         return fp;
19491 }
19492
19493 static void cgdebug_printf(struct compile_state *state, const char *fmt, ...)
19494 {
19495         FILE *fp;
19496         fp = cgdebug_fp(state);
19497         if (fp) {
19498                 va_list args;
19499                 va_start(args, fmt);
19500                 vfprintf(fp, fmt, args);
19501                 va_end(args);
19502         }
19503 }
19504
19505 static void cgdebug_flush(struct compile_state *state)
19506 {
19507         FILE *fp;
19508         fp = cgdebug_fp(state);
19509         if (fp) {
19510                 fflush(fp);
19511         }
19512 }
19513
19514 static void cgdebug_loc(struct compile_state *state, struct triple *ins)
19515 {
19516         FILE *fp;
19517         fp = cgdebug_fp(state);
19518         if (fp) {
19519                 loc(fp, state, ins);
19520         }
19521 }
19522
19523 static int select_free_color(struct compile_state *state, 
19524         struct reg_state *rstate, struct live_range *range)
19525 {
19526         struct triple_set *entry;
19527         struct live_range_def *lrd;
19528         struct live_range_def *phi;
19529         struct live_range_edge *edge;
19530         char used[MAX_REGISTERS];
19531         struct triple **expr;
19532
19533         /* Instead of doing just the trivial color select here I try
19534          * a few extra things because a good color selection will help reduce
19535          * copies.
19536          */
19537
19538         /* Find the registers currently in use */
19539         memset(used, 0, sizeof(used));
19540         for(edge = range->edges; edge; edge = edge->next) {
19541                 if (edge->node->color == REG_UNSET) {
19542                         continue;
19543                 }
19544                 reg_fill_used(state, used, edge->node->color);
19545         }
19546
19547         if (state->compiler->debug & DEBUG_COLOR_GRAPH2) {
19548                 int i;
19549                 i = 0;
19550                 for(edge = range->edges; edge; edge = edge->next) {
19551                         i++;
19552                 }
19553                 cgdebug_printf(state, "\n%s edges: %d", 
19554                         tops(range->defs->def->op), i);
19555                 cgdebug_loc(state, range->defs->def);
19556                 cgdebug_printf(state, "\n");
19557                 for(i = 0; i < MAX_REGISTERS; i++) {
19558                         if (used[i]) {
19559                                 cgdebug_printf(state, "used: %s\n",
19560                                         arch_reg_str(i));
19561                         }
19562                 }
19563         }       
19564
19565         /* If a color is already assigned see if it will work */
19566         if (range->color != REG_UNSET) {
19567                 struct live_range_def *lrd;
19568                 if (!used[range->color]) {
19569                         return 1;
19570                 }
19571                 for(edge = range->edges; edge; edge = edge->next) {
19572                         if (edge->node->color != range->color) {
19573                                 continue;
19574                         }
19575                         warning(state, edge->node->defs->def, "edge: ");
19576                         lrd = edge->node->defs;
19577                         do {
19578                                 warning(state, lrd->def, " %p %s",
19579                                         lrd->def, tops(lrd->def->op));
19580                                 lrd = lrd->next;
19581                         } while(lrd != edge->node->defs);
19582                 }
19583                 lrd = range->defs;
19584                 warning(state, range->defs->def, "def: ");
19585                 do {
19586                         warning(state, lrd->def, " %p %s",
19587                                 lrd->def, tops(lrd->def->op));
19588                         lrd = lrd->next;
19589                 } while(lrd != range->defs);
19590                 internal_error(state, range->defs->def,
19591                         "live range with already used color %s",
19592                         arch_reg_str(range->color));
19593         }
19594
19595         /* If I feed into an expression reuse it's color.
19596          * This should help remove copies in the case of 2 register instructions
19597          * and phi functions.
19598          */
19599         phi = 0;
19600         lrd = live_range_end(state, range, 0);
19601         for(; (range->color == REG_UNSET) && lrd ; lrd = live_range_end(state, range, lrd)) {
19602                 entry = lrd->def->use;
19603                 for(;(range->color == REG_UNSET) && entry; entry = entry->next) {
19604                         struct live_range_def *insd;
19605                         unsigned regcm;
19606                         insd = &rstate->lrd[entry->member->id];
19607                         if (insd->lr->defs == 0) {
19608                                 continue;
19609                         }
19610                         if (!phi && (insd->def->op == OP_PHI) &&
19611                                 !interfere(rstate, range, insd->lr)) {
19612                                 phi = insd;
19613                         }
19614                         if (insd->lr->color == REG_UNSET) {
19615                                 continue;
19616                         }
19617                         regcm = insd->lr->classes;
19618                         if (((regcm & range->classes) == 0) ||
19619                                 (used[insd->lr->color])) {
19620                                 continue;
19621                         }
19622                         if (interfere(rstate, range, insd->lr)) {
19623                                 continue;
19624                         }
19625                         range->color = insd->lr->color;
19626                 }
19627         }
19628         /* If I feed into a phi function reuse it's color or the color
19629          * of something else that feeds into the phi function.
19630          */
19631         if (phi) {
19632                 if (phi->lr->color != REG_UNSET) {
19633                         if (used[phi->lr->color]) {
19634                                 range->color = phi->lr->color;
19635                         }
19636                 }
19637                 else {
19638                         expr = triple_rhs(state, phi->def, 0);
19639                         for(; expr; expr = triple_rhs(state, phi->def, expr)) {
19640                                 struct live_range *lr;
19641                                 unsigned regcm;
19642                                 if (!*expr) {
19643                                         continue;
19644                                 }
19645                                 lr = rstate->lrd[(*expr)->id].lr;
19646                                 if (lr->color == REG_UNSET) {
19647                                         continue;
19648                                 }
19649                                 regcm = lr->classes;
19650                                 if (((regcm & range->classes) == 0) ||
19651                                         (used[lr->color])) {
19652                                         continue;
19653                                 }
19654                                 if (interfere(rstate, range, lr)) {
19655                                         continue;
19656                                 }
19657                                 range->color = lr->color;
19658                         }
19659                 }
19660         }
19661         /* If I don't interfere with a rhs node reuse it's color */
19662         lrd = live_range_head(state, range, 0);
19663         for(; (range->color == REG_UNSET) && lrd ; lrd = live_range_head(state, range, lrd)) {
19664                 expr = triple_rhs(state, lrd->def, 0);
19665                 for(; expr; expr = triple_rhs(state, lrd->def, expr)) {
19666                         struct live_range *lr;
19667                         unsigned regcm;
19668                         if (!*expr) {
19669                                 continue;
19670                         }
19671                         lr = rstate->lrd[(*expr)->id].lr;
19672                         if (lr->color == REG_UNSET) {
19673                                 continue;
19674                         }
19675                         regcm = lr->classes;
19676                         if (((regcm & range->classes) == 0) ||
19677                                 (used[lr->color])) {
19678                                 continue;
19679                         }
19680                         if (interfere(rstate, range, lr)) {
19681                                 continue;
19682                         }
19683                         range->color = lr->color;
19684                         break;
19685                 }
19686         }
19687         /* If I have not opportunitically picked a useful color
19688          * pick the first color that is free.
19689          */
19690         if (range->color == REG_UNSET) {
19691                 range->color = 
19692                         arch_select_free_register(state, used, range->classes);
19693         }
19694         if (range->color == REG_UNSET) {
19695                 struct live_range_def *lrd;
19696                 int i;
19697                 if (split_ranges(state, rstate, used, range)) {
19698                         return 0;
19699                 }
19700                 for(edge = range->edges; edge; edge = edge->next) {
19701                         warning(state, edge->node->defs->def, "edge reg %s",
19702                                 arch_reg_str(edge->node->color));
19703                         lrd = edge->node->defs;
19704                         do {
19705                                 warning(state, lrd->def, " %s %p",
19706                                         tops(lrd->def->op), lrd->def);
19707                                 lrd = lrd->next;
19708                         } while(lrd != edge->node->defs);
19709                 }
19710                 warning(state, range->defs->def, "range: ");
19711                 lrd = range->defs;
19712                 do {
19713                         warning(state, lrd->def, " %s %p",
19714                                 tops(lrd->def->op), lrd->def);
19715                         lrd = lrd->next;
19716                 } while(lrd != range->defs);
19717                         
19718                 warning(state, range->defs->def, "classes: %x",
19719                         range->classes);
19720                 for(i = 0; i < MAX_REGISTERS; i++) {
19721                         if (used[i]) {
19722                                 warning(state, range->defs->def, "used: %s",
19723                                         arch_reg_str(i));
19724                         }
19725                 }
19726                 error(state, range->defs->def, "too few registers");
19727         }
19728         range->classes &= arch_reg_regcm(state, range->color);
19729         if ((range->color == REG_UNSET) || (range->classes == 0)) {
19730                 internal_error(state, range->defs->def, "select_free_color did not?");
19731         }
19732         return 1;
19733 }
19734
19735 static int color_graph(struct compile_state *state, struct reg_state *rstate)
19736 {
19737         int colored;
19738         struct live_range_edge *edge;
19739         struct live_range *range;
19740         if (rstate->low) {
19741                 cgdebug_printf(state, "Lo: ");
19742                 range = rstate->low;
19743                 if (*range->group_prev != range) {
19744                         internal_error(state, 0, "lo: *prev != range?");
19745                 }
19746                 *range->group_prev = range->group_next;
19747                 if (range->group_next) {
19748                         range->group_next->group_prev = range->group_prev;
19749                 }
19750                 if (&range->group_next == rstate->low_tail) {
19751                         rstate->low_tail = range->group_prev;
19752                 }
19753                 if (rstate->low == range) {
19754                         internal_error(state, 0, "low: next != prev?");
19755                 }
19756         }
19757         else if (rstate->high) {
19758                 cgdebug_printf(state, "Hi: ");
19759                 range = rstate->high;
19760                 if (*range->group_prev != range) {
19761                         internal_error(state, 0, "hi: *prev != range?");
19762                 }
19763                 *range->group_prev = range->group_next;
19764                 if (range->group_next) {
19765                         range->group_next->group_prev = range->group_prev;
19766                 }
19767                 if (&range->group_next == rstate->high_tail) {
19768                         rstate->high_tail = range->group_prev;
19769                 }
19770                 if (rstate->high == range) {
19771                         internal_error(state, 0, "high: next != prev?");
19772                 }
19773         }
19774         else {
19775                 return 1;
19776         }
19777         cgdebug_printf(state, " %d\n", range - rstate->lr);
19778         range->group_prev = 0;
19779         for(edge = range->edges; edge; edge = edge->next) {
19780                 struct live_range *node;
19781                 node = edge->node;
19782                 /* Move nodes from the high to the low list */
19783                 if (node->group_prev && (node->color == REG_UNSET) &&
19784                         (node->degree == regc_max_size(state, node->classes))) {
19785                         if (*node->group_prev != node) {
19786                                 internal_error(state, 0, "move: *prev != node?");
19787                         }
19788                         *node->group_prev = node->group_next;
19789                         if (node->group_next) {
19790                                 node->group_next->group_prev = node->group_prev;
19791                         }
19792                         if (&node->group_next == rstate->high_tail) {
19793                                 rstate->high_tail = node->group_prev;
19794                         }
19795                         cgdebug_printf(state, "Moving...%d to low\n", node - rstate->lr);
19796                         node->group_prev  = rstate->low_tail;
19797                         node->group_next  = 0;
19798                         *rstate->low_tail = node;
19799                         rstate->low_tail  = &node->group_next;
19800                         if (*node->group_prev != node) {
19801                                 internal_error(state, 0, "move2: *prev != node?");
19802                         }
19803                 }
19804                 node->degree -= 1;
19805         }
19806         colored = color_graph(state, rstate);
19807         if (colored) {
19808                 cgdebug_printf(state, "Coloring %d @", range - rstate->lr);
19809                 cgdebug_loc(state, range->defs->def);
19810                 cgdebug_flush(state);
19811                 colored = select_free_color(state, rstate, range);
19812                 if (colored) {
19813                         cgdebug_printf(state, " %s\n", arch_reg_str(range->color));
19814                 }
19815         }
19816         return colored;
19817 }
19818
19819 static void verify_colors(struct compile_state *state, struct reg_state *rstate)
19820 {
19821         struct live_range *lr;
19822         struct live_range_edge *edge;
19823         struct triple *ins, *first;
19824         char used[MAX_REGISTERS];
19825         first = state->first;
19826         ins = first;
19827         do {
19828                 if (triple_is_def(state, ins)) {
19829                         if ((ins->id < 0) || (ins->id > rstate->defs)) {
19830                                 internal_error(state, ins, 
19831                                         "triple without a live range def");
19832                         }
19833                         lr = rstate->lrd[ins->id].lr;
19834                         if (lr->color == REG_UNSET) {
19835                                 internal_error(state, ins,
19836                                         "triple without a color");
19837                         }
19838                         /* Find the registers used by the edges */
19839                         memset(used, 0, sizeof(used));
19840                         for(edge = lr->edges; edge; edge = edge->next) {
19841                                 if (edge->node->color == REG_UNSET) {
19842                                         internal_error(state, 0,
19843                                                 "live range without a color");
19844                         }
19845                                 reg_fill_used(state, used, edge->node->color);
19846                         }
19847                         if (used[lr->color]) {
19848                                 internal_error(state, ins,
19849                                         "triple with already used color");
19850                         }
19851                 }
19852                 ins = ins->next;
19853         } while(ins != first);
19854 }
19855
19856 static void color_triples(struct compile_state *state, struct reg_state *rstate)
19857 {
19858         struct live_range_def *lrd;
19859         struct live_range *lr;
19860         struct triple *first, *ins;
19861         first = state->first;
19862         ins = first;
19863         do {
19864                 if ((ins->id < 0) || (ins->id > rstate->defs)) {
19865                         internal_error(state, ins, 
19866                                 "triple without a live range");
19867                 }
19868                 lrd = &rstate->lrd[ins->id];
19869                 lr = lrd->lr;
19870                 ins->id = lrd->orig_id;
19871                 SET_REG(ins->id, lr->color);
19872                 ins = ins->next;
19873         } while (ins != first);
19874 }
19875
19876 static struct live_range *merge_sort_lr(
19877         struct live_range *first, struct live_range *last)
19878 {
19879         struct live_range *mid, *join, **join_tail, *pick;
19880         size_t size;
19881         size = (last - first) + 1;
19882         if (size >= 2) {
19883                 mid = first + size/2;
19884                 first = merge_sort_lr(first, mid -1);
19885                 mid   = merge_sort_lr(mid, last);
19886                 
19887                 join = 0;
19888                 join_tail = &join;
19889                 /* merge the two lists */
19890                 while(first && mid) {
19891                         if ((first->degree < mid->degree) ||
19892                                 ((first->degree == mid->degree) &&
19893                                         (first->length < mid->length))) {
19894                                 pick = first;
19895                                 first = first->group_next;
19896                                 if (first) {
19897                                         first->group_prev = 0;
19898                                 }
19899                         }
19900                         else {
19901                                 pick = mid;
19902                                 mid = mid->group_next;
19903                                 if (mid) {
19904                                         mid->group_prev = 0;
19905                                 }
19906                         }
19907                         pick->group_next = 0;
19908                         pick->group_prev = join_tail;
19909                         *join_tail = pick;
19910                         join_tail = &pick->group_next;
19911                 }
19912                 /* Splice the remaining list */
19913                 pick = (first)? first : mid;
19914                 *join_tail = pick;
19915                 if (pick) { 
19916                         pick->group_prev = join_tail;
19917                 }
19918         }
19919         else {
19920                 if (!first->defs) {
19921                         first = 0;
19922                 }
19923                 join = first;
19924         }
19925         return join;
19926 }
19927
19928 static void ids_from_rstate(struct compile_state *state, 
19929         struct reg_state *rstate)
19930 {
19931         struct triple *ins, *first;
19932         if (!rstate->defs) {
19933                 return;
19934         }
19935         /* Display the graph if desired */
19936         if (state->compiler->debug & DEBUG_INTERFERENCE) {
19937                 FILE *fp = state->dbgout;
19938                 print_interference_blocks(state, rstate, fp, 0);
19939                 print_control_flow(state, fp, &state->bb);
19940                 fflush(fp);
19941         }
19942         first = state->first;
19943         ins = first;
19944         do {
19945                 if (ins->id) {
19946                         struct live_range_def *lrd;
19947                         lrd = &rstate->lrd[ins->id];
19948                         ins->id = lrd->orig_id;
19949                 }
19950                 ins = ins->next;
19951         } while(ins != first);
19952 }
19953
19954 static void cleanup_live_edges(struct reg_state *rstate)
19955 {
19956         int i;
19957         /* Free the edges on each node */
19958         for(i = 1; i <= rstate->ranges; i++) {
19959                 remove_live_edges(rstate, &rstate->lr[i]);
19960         }
19961 }
19962
19963 static void cleanup_rstate(struct compile_state *state, struct reg_state *rstate)
19964 {
19965         cleanup_live_edges(rstate);
19966         xfree(rstate->lrd);
19967         xfree(rstate->lr);
19968
19969         /* Free the variable lifetime information */
19970         if (rstate->blocks) {
19971                 free_variable_lifetimes(state, &state->bb, rstate->blocks);
19972         }
19973         rstate->defs = 0;
19974         rstate->ranges = 0;
19975         rstate->lrd = 0;
19976         rstate->lr = 0;
19977         rstate->blocks = 0;
19978 }
19979
19980 static void verify_consistency(struct compile_state *state);
19981 static void allocate_registers(struct compile_state *state)
19982 {
19983         struct reg_state rstate;
19984         int colored;
19985
19986         /* Clear out the reg_state */
19987         memset(&rstate, 0, sizeof(rstate));
19988         rstate.max_passes = state->compiler->max_allocation_passes;
19989
19990         do {
19991                 struct live_range **point, **next;
19992                 int conflicts;
19993                 int tangles;
19994                 int coalesced;
19995
19996                 if (state->compiler->debug & DEBUG_RANGE_CONFLICTS) {
19997                         FILE *fp = state->errout;
19998                         fprintf(fp, "pass: %d\n", rstate.passes);
19999                         fflush(fp);
20000                 }
20001
20002                 /* Restore ids */
20003                 ids_from_rstate(state, &rstate);
20004
20005                 /* Cleanup the temporary data structures */
20006                 cleanup_rstate(state, &rstate);
20007
20008                 /* Compute the variable lifetimes */
20009                 rstate.blocks = compute_variable_lifetimes(state, &state->bb);
20010
20011                 /* Fix invalid mandatory live range coalesce conflicts */
20012                 conflicts = correct_coalesce_conflicts(state, rstate.blocks);
20013
20014                 /* Fix two simultaneous uses of the same register.
20015                  * In a few pathlogical cases a partial untangle moves
20016                  * the tangle to a part of the graph we won't revisit.
20017                  * So we keep looping until we have no more tangle fixes
20018                  * to apply.
20019                  */
20020                 do {
20021                         tangles = correct_tangles(state, rstate.blocks);
20022                 } while(tangles);
20023
20024                 
20025                 print_blocks(state, "resolve_tangles", state->dbgout);
20026                 verify_consistency(state);
20027                 
20028                 /* Allocate and initialize the live ranges */
20029                 initialize_live_ranges(state, &rstate);
20030
20031                 /* Note currently doing coalescing in a loop appears to 
20032                  * buys me nothing.  The code is left this way in case
20033                  * there is some value in it.  Or if a future bugfix
20034                  * yields some benefit.
20035                  */
20036                 do {
20037                         if (state->compiler->debug & DEBUG_COALESCING) {
20038                                 fprintf(state->errout, "coalescing\n");
20039                         }
20040
20041                         /* Remove any previous live edge calculations */
20042                         cleanup_live_edges(&rstate);
20043
20044                         /* Compute the interference graph */
20045                         walk_variable_lifetimes(
20046                                 state, &state->bb, rstate.blocks, 
20047                                 graph_ins, &rstate);
20048                         
20049                         /* Display the interference graph if desired */
20050                         if (state->compiler->debug & DEBUG_INTERFERENCE) {
20051                                 print_interference_blocks(state, &rstate, state->dbgout, 1);
20052                                 fprintf(state->dbgout, "\nlive variables by instruction\n");
20053                                 walk_variable_lifetimes(
20054                                         state, &state->bb, rstate.blocks, 
20055                                         print_interference_ins, &rstate);
20056                         }
20057                         
20058                         coalesced = coalesce_live_ranges(state, &rstate);
20059
20060                         if (state->compiler->debug & DEBUG_COALESCING) {
20061                                 fprintf(state->errout, "coalesced: %d\n", coalesced);
20062                         }
20063                 } while(coalesced);
20064
20065 #if DEBUG_CONSISTENCY > 1
20066 # if 0
20067                 fprintf(state->errout, "verify_graph_ins...\n");
20068 # endif
20069                 /* Verify the interference graph */
20070                 walk_variable_lifetimes(
20071                         state, &state->bb, rstate.blocks, 
20072                         verify_graph_ins, &rstate);
20073 # if 0
20074                 fprintf(state->errout, "verify_graph_ins done\n");
20075 #endif
20076 #endif
20077                         
20078                 /* Build the groups low and high.  But with the nodes
20079                  * first sorted by degree order.
20080                  */
20081                 rstate.low_tail  = &rstate.low;
20082                 rstate.high_tail = &rstate.high;
20083                 rstate.high = merge_sort_lr(&rstate.lr[1], &rstate.lr[rstate.ranges]);
20084                 if (rstate.high) {
20085                         rstate.high->group_prev = &rstate.high;
20086                 }
20087                 for(point = &rstate.high; *point; point = &(*point)->group_next)
20088                         ;
20089                 rstate.high_tail = point;
20090                 /* Walk through the high list and move everything that needs
20091                  * to be onto low.
20092                  */
20093                 for(point = &rstate.high; *point; point = next) {
20094                         struct live_range *range;
20095                         next = &(*point)->group_next;
20096                         range = *point;
20097                         
20098                         /* If it has a low degree or it already has a color
20099                          * place the node in low.
20100                          */
20101                         if ((range->degree < regc_max_size(state, range->classes)) ||
20102                                 (range->color != REG_UNSET)) {
20103                                 cgdebug_printf(state, "Lo: %5d degree %5d%s\n", 
20104                                         range - rstate.lr, range->degree,
20105                                         (range->color != REG_UNSET) ? " (colored)": "");
20106                                 *range->group_prev = range->group_next;
20107                                 if (range->group_next) {
20108                                         range->group_next->group_prev = range->group_prev;
20109                                 }
20110                                 if (&range->group_next == rstate.high_tail) {
20111                                         rstate.high_tail = range->group_prev;
20112                                 }
20113                                 range->group_prev  = rstate.low_tail;
20114                                 range->group_next  = 0;
20115                                 *rstate.low_tail   = range;
20116                                 rstate.low_tail    = &range->group_next;
20117                                 next = point;
20118                         }
20119                         else {
20120                                 cgdebug_printf(state, "hi: %5d degree %5d%s\n", 
20121                                         range - rstate.lr, range->degree,
20122                                         (range->color != REG_UNSET) ? " (colored)": "");
20123                         }
20124                 }
20125                 /* Color the live_ranges */
20126                 colored = color_graph(state, &rstate);
20127                 rstate.passes++;
20128         } while (!colored);
20129
20130         /* Verify the graph was properly colored */
20131         verify_colors(state, &rstate);
20132
20133         /* Move the colors from the graph to the triples */
20134         color_triples(state, &rstate);
20135
20136         /* Cleanup the temporary data structures */
20137         cleanup_rstate(state, &rstate);
20138
20139         /* Display the new graph */
20140         print_blocks(state, __func__, state->dbgout);
20141 }
20142
20143 /* Sparce Conditional Constant Propogation
20144  * =========================================
20145  */
20146 struct ssa_edge;
20147 struct flow_block;
20148 struct lattice_node {
20149         unsigned old_id;
20150         struct triple *def;
20151         struct ssa_edge *out;
20152         struct flow_block *fblock;
20153         struct triple *val;
20154         /* lattice high   val == def
20155          * lattice const  is_const(val)
20156          * lattice low    other
20157          */
20158 };
20159 struct ssa_edge {
20160         struct lattice_node *src;
20161         struct lattice_node *dst;
20162         struct ssa_edge *work_next;
20163         struct ssa_edge *work_prev;
20164         struct ssa_edge *out_next;
20165 };
20166 struct flow_edge {
20167         struct flow_block *src;
20168         struct flow_block *dst;
20169         struct flow_edge *work_next;
20170         struct flow_edge *work_prev;
20171         struct flow_edge *in_next;
20172         struct flow_edge *out_next;
20173         int executable;
20174 };
20175 #define MAX_FLOW_BLOCK_EDGES 3
20176 struct flow_block {
20177         struct block *block;
20178         struct flow_edge *in;
20179         struct flow_edge *out;
20180         struct flow_edge *edges;
20181 };
20182
20183 struct scc_state {
20184         int ins_count;
20185         struct lattice_node *lattice;
20186         struct ssa_edge     *ssa_edges;
20187         struct flow_block   *flow_blocks;
20188         struct flow_edge    *flow_work_list;
20189         struct ssa_edge     *ssa_work_list;
20190 };
20191
20192
20193 static int is_scc_const(struct compile_state *state, struct triple *ins)
20194 {
20195         return ins && (triple_is_ubranch(state, ins) || is_const(ins));
20196 }
20197
20198 static int is_lattice_hi(struct compile_state *state, struct lattice_node *lnode)
20199 {
20200         return !is_scc_const(state, lnode->val) && (lnode->val == lnode->def);
20201 }
20202
20203 static int is_lattice_const(struct compile_state *state, struct lattice_node *lnode)
20204 {
20205         return is_scc_const(state, lnode->val);
20206 }
20207
20208 static int is_lattice_lo(struct compile_state *state, struct lattice_node *lnode)
20209 {
20210         return (lnode->val != lnode->def) && !is_scc_const(state, lnode->val);
20211 }
20212
20213 static void scc_add_fedge(struct compile_state *state, struct scc_state *scc, 
20214         struct flow_edge *fedge)
20215 {
20216         if (state->compiler->debug & DEBUG_SCC_TRANSFORM2) {
20217                 fprintf(state->errout, "adding fedge: %p (%4d -> %5d)\n",
20218                         fedge,
20219                         fedge->src->block?fedge->src->block->last->id: 0,
20220                         fedge->dst->block?fedge->dst->block->first->id: 0);
20221         }
20222         if ((fedge == scc->flow_work_list) ||
20223                 (fedge->work_next != fedge) ||
20224                 (fedge->work_prev != fedge)) {
20225
20226                 if (state->compiler->debug & DEBUG_SCC_TRANSFORM2) {
20227                         fprintf(state->errout, "dupped fedge: %p\n",
20228                                 fedge);
20229                 }
20230                 return;
20231         }
20232         if (!scc->flow_work_list) {
20233                 scc->flow_work_list = fedge;
20234                 fedge->work_next = fedge->work_prev = fedge;
20235         }
20236         else {
20237                 struct flow_edge *ftail;
20238                 ftail = scc->flow_work_list->work_prev;
20239                 fedge->work_next = ftail->work_next;
20240                 fedge->work_prev = ftail;
20241                 fedge->work_next->work_prev = fedge;
20242                 fedge->work_prev->work_next = fedge;
20243         }
20244 }
20245
20246 static struct flow_edge *scc_next_fedge(
20247         struct compile_state *state, struct scc_state *scc)
20248 {
20249         struct flow_edge *fedge;
20250         fedge = scc->flow_work_list;
20251         if (fedge) {
20252                 fedge->work_next->work_prev = fedge->work_prev;
20253                 fedge->work_prev->work_next = fedge->work_next;
20254                 if (fedge->work_next != fedge) {
20255                         scc->flow_work_list = fedge->work_next;
20256                 } else {
20257                         scc->flow_work_list = 0;
20258                 }
20259                 fedge->work_next = fedge->work_prev = fedge;
20260         }
20261         return fedge;
20262 }
20263
20264 static void scc_add_sedge(struct compile_state *state, struct scc_state *scc,
20265         struct ssa_edge *sedge)
20266 {
20267         if (state->compiler->debug & DEBUG_SCC_TRANSFORM2) {
20268                 fprintf(state->errout, "adding sedge: %5d (%4d -> %5d)\n",
20269                         sedge - scc->ssa_edges,
20270                         sedge->src->def->id,
20271                         sedge->dst->def->id);
20272         }
20273         if ((sedge == scc->ssa_work_list) ||
20274                 (sedge->work_next != sedge) ||
20275                 (sedge->work_prev != sedge)) {
20276
20277                 if (state->compiler->debug & DEBUG_SCC_TRANSFORM2) {
20278                         fprintf(state->errout, "dupped sedge: %5d\n",
20279                                 sedge - scc->ssa_edges);
20280                 }
20281                 return;
20282         }
20283         if (!scc->ssa_work_list) {
20284                 scc->ssa_work_list = sedge;
20285                 sedge->work_next = sedge->work_prev = sedge;
20286         }
20287         else {
20288                 struct ssa_edge *stail;
20289                 stail = scc->ssa_work_list->work_prev;
20290                 sedge->work_next = stail->work_next;
20291                 sedge->work_prev = stail;
20292                 sedge->work_next->work_prev = sedge;
20293                 sedge->work_prev->work_next = sedge;
20294         }
20295 }
20296
20297 static struct ssa_edge *scc_next_sedge(
20298         struct compile_state *state, struct scc_state *scc)
20299 {
20300         struct ssa_edge *sedge;
20301         sedge = scc->ssa_work_list;
20302         if (sedge) {
20303                 sedge->work_next->work_prev = sedge->work_prev;
20304                 sedge->work_prev->work_next = sedge->work_next;
20305                 if (sedge->work_next != sedge) {
20306                         scc->ssa_work_list = sedge->work_next;
20307                 } else {
20308                         scc->ssa_work_list = 0;
20309                 }
20310                 sedge->work_next = sedge->work_prev = sedge;
20311         }
20312         return sedge;
20313 }
20314
20315 static void initialize_scc_state(
20316         struct compile_state *state, struct scc_state *scc)
20317 {
20318         int ins_count, ssa_edge_count;
20319         int ins_index, ssa_edge_index, fblock_index;
20320         struct triple *first, *ins;
20321         struct block *block;
20322         struct flow_block *fblock;
20323
20324         memset(scc, 0, sizeof(*scc));
20325
20326         /* Inialize pass zero find out how much memory we need */
20327         first = state->first;
20328         ins = first;
20329         ins_count = ssa_edge_count = 0;
20330         do {
20331                 struct triple_set *edge;
20332                 ins_count += 1;
20333                 for(edge = ins->use; edge; edge = edge->next) {
20334                         ssa_edge_count++;
20335                 }
20336                 ins = ins->next;
20337         } while(ins != first);
20338         if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
20339                 fprintf(state->errout, "ins_count: %d ssa_edge_count: %d vertex_count: %d\n",
20340                         ins_count, ssa_edge_count, state->bb.last_vertex);
20341         }
20342         scc->ins_count   = ins_count;
20343         scc->lattice     = 
20344                 xcmalloc(sizeof(*scc->lattice)*(ins_count + 1), "lattice");
20345         scc->ssa_edges   = 
20346                 xcmalloc(sizeof(*scc->ssa_edges)*(ssa_edge_count + 1), "ssa_edges");
20347         scc->flow_blocks = 
20348                 xcmalloc(sizeof(*scc->flow_blocks)*(state->bb.last_vertex + 1), 
20349                         "flow_blocks");
20350
20351         /* Initialize pass one collect up the nodes */
20352         fblock = 0;
20353         block = 0;
20354         ins_index = ssa_edge_index = fblock_index = 0;
20355         ins = first;
20356         do {
20357                 if ((ins->op == OP_LABEL) && (block != ins->u.block)) {
20358                         block = ins->u.block;
20359                         if (!block) {
20360                                 internal_error(state, ins, "label without block");
20361                         }
20362                         fblock_index += 1;
20363                         block->vertex = fblock_index;
20364                         fblock = &scc->flow_blocks[fblock_index];
20365                         fblock->block = block;
20366                         fblock->edges = xcmalloc(sizeof(*fblock->edges)*block->edge_count,
20367                                 "flow_edges");
20368                 }
20369                 {
20370                         struct lattice_node *lnode;
20371                         ins_index += 1;
20372                         lnode = &scc->lattice[ins_index];
20373                         lnode->def = ins;
20374                         lnode->out = 0;
20375                         lnode->fblock = fblock;
20376                         lnode->val = ins; /* LATTICE HIGH */
20377                         if (lnode->val->op == OP_UNKNOWNVAL) {
20378                                 lnode->val = 0; /* LATTICE LOW by definition */
20379                         }
20380                         lnode->old_id = ins->id;
20381                         ins->id = ins_index;
20382                 }
20383                 ins = ins->next;
20384         } while(ins != first);
20385         /* Initialize pass two collect up the edges */
20386         block = 0;
20387         fblock = 0;
20388         ins = first;
20389         do {
20390                 {
20391                         struct triple_set *edge;
20392                         struct ssa_edge **stail;
20393                         struct lattice_node *lnode;
20394                         lnode = &scc->lattice[ins->id];
20395                         lnode->out = 0;
20396                         stail = &lnode->out;
20397                         for(edge = ins->use; edge; edge = edge->next) {
20398                                 struct ssa_edge *sedge;
20399                                 ssa_edge_index += 1;
20400                                 sedge = &scc->ssa_edges[ssa_edge_index];
20401                                 *stail = sedge;
20402                                 stail = &sedge->out_next;
20403                                 sedge->src = lnode;
20404                                 sedge->dst = &scc->lattice[edge->member->id];
20405                                 sedge->work_next = sedge->work_prev = sedge;
20406                                 sedge->out_next = 0;
20407                         }
20408                 }
20409                 if ((ins->op == OP_LABEL) && (block != ins->u.block)) {
20410                         struct flow_edge *fedge, **ftail;
20411                         struct block_set *bedge;
20412                         block = ins->u.block;
20413                         fblock = &scc->flow_blocks[block->vertex];
20414                         fblock->in = 0;
20415                         fblock->out = 0;
20416                         ftail = &fblock->out;
20417
20418                         fedge = fblock->edges;
20419                         bedge = block->edges;
20420                         for(; bedge; bedge = bedge->next, fedge++) {
20421                                 fedge->dst = &scc->flow_blocks[bedge->member->vertex];
20422                                 if (fedge->dst->block != bedge->member) {
20423                                         internal_error(state, 0, "block mismatch");
20424                                 }
20425                                 *ftail = fedge;
20426                                 ftail = &fedge->out_next;
20427                                 fedge->out_next = 0;
20428                         }
20429                         for(fedge = fblock->out; fedge; fedge = fedge->out_next) {
20430                                 fedge->src = fblock;
20431                                 fedge->work_next = fedge->work_prev = fedge;
20432                                 fedge->executable = 0;
20433                         }
20434                 }
20435                 ins = ins->next;
20436         } while (ins != first);
20437         block = 0;
20438         fblock = 0;
20439         ins = first;
20440         do {
20441                 if ((ins->op  == OP_LABEL) && (block != ins->u.block)) {
20442                         struct flow_edge **ftail;
20443                         struct block_set *bedge;
20444                         block = ins->u.block;
20445                         fblock = &scc->flow_blocks[block->vertex];
20446                         ftail = &fblock->in;
20447                         for(bedge = block->use; bedge; bedge = bedge->next) {
20448                                 struct block *src_block;
20449                                 struct flow_block *sfblock;
20450                                 struct flow_edge *sfedge;
20451                                 src_block = bedge->member;
20452                                 sfblock = &scc->flow_blocks[src_block->vertex];
20453                                 for(sfedge = sfblock->out; sfedge; sfedge = sfedge->out_next) {
20454                                         if (sfedge->dst == fblock) {
20455                                                 break;
20456                                         }
20457                                 }
20458                                 if (!sfedge) {
20459                                         internal_error(state, 0, "edge mismatch");
20460                                 }
20461                                 *ftail = sfedge;
20462                                 ftail = &sfedge->in_next;
20463                                 sfedge->in_next = 0;
20464                         }
20465                 }
20466                 ins = ins->next;
20467         } while(ins != first);
20468         /* Setup a dummy block 0 as a node above the start node */
20469         {
20470                 struct flow_block *fblock, *dst;
20471                 struct flow_edge *fedge;
20472                 fblock = &scc->flow_blocks[0];
20473                 fblock->block = 0;
20474                 fblock->edges = xcmalloc(sizeof(*fblock->edges)*1, "flow_edges");
20475                 fblock->in = 0;
20476                 fblock->out = fblock->edges;
20477                 dst = &scc->flow_blocks[state->bb.first_block->vertex];
20478                 fedge = fblock->edges;
20479                 fedge->src        = fblock;
20480                 fedge->dst        = dst;
20481                 fedge->work_next  = fedge;
20482                 fedge->work_prev  = fedge;
20483                 fedge->in_next    = fedge->dst->in;
20484                 fedge->out_next   = 0;
20485                 fedge->executable = 0;
20486                 fedge->dst->in = fedge;
20487                 
20488                 /* Initialize the work lists */
20489                 scc->flow_work_list = 0;
20490                 scc->ssa_work_list  = 0;
20491                 scc_add_fedge(state, scc, fedge);
20492         }
20493         if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
20494                 fprintf(state->errout, "ins_index: %d ssa_edge_index: %d fblock_index: %d\n",
20495                         ins_index, ssa_edge_index, fblock_index);
20496         }
20497 }
20498
20499         
20500 static void free_scc_state(
20501         struct compile_state *state, struct scc_state *scc)
20502 {
20503         int i;
20504         for(i = 0; i < state->bb.last_vertex + 1; i++) {
20505                 struct flow_block *fblock;
20506                 fblock = &scc->flow_blocks[i];
20507                 if (fblock->edges) {
20508                         xfree(fblock->edges);
20509                         fblock->edges = 0;
20510                 }
20511         }
20512         xfree(scc->flow_blocks);
20513         xfree(scc->ssa_edges);
20514         xfree(scc->lattice);
20515         
20516 }
20517
20518 static struct lattice_node *triple_to_lattice(
20519         struct compile_state *state, struct scc_state *scc, struct triple *ins)
20520 {
20521         if (ins->id <= 0) {
20522                 internal_error(state, ins, "bad id");
20523         }
20524         return &scc->lattice[ins->id];
20525 }
20526
20527 static struct triple *preserve_lval(
20528         struct compile_state *state, struct lattice_node *lnode)
20529 {
20530         struct triple *old;
20531         /* Preserve the original value */
20532         if (lnode->val) {
20533                 old = dup_triple(state, lnode->val);
20534                 if (lnode->val != lnode->def) {
20535                         xfree(lnode->val);
20536                 }
20537                 lnode->val = 0;
20538         } else {
20539                 old = 0;
20540         }
20541         return old;
20542 }
20543
20544 static int lval_changed(struct compile_state *state, 
20545         struct triple *old, struct lattice_node *lnode)
20546 {
20547         int changed;
20548         /* See if the lattice value has changed */
20549         changed = 1;
20550         if (!old && !lnode->val) {
20551                 changed = 0;
20552         }
20553         if (changed &&
20554                 lnode->val && old &&
20555                 (memcmp(lnode->val->param, old->param,
20556                         TRIPLE_SIZE(lnode->val) * sizeof(lnode->val->param[0])) == 0) &&
20557                 (memcmp(&lnode->val->u, &old->u, sizeof(old->u)) == 0)) {
20558                 changed = 0;
20559         }
20560         if (old) {
20561                 xfree(old);
20562         }
20563         return changed;
20564
20565 }
20566
20567 static void scc_debug_lnode(
20568         struct compile_state *state, struct scc_state *scc,
20569         struct lattice_node *lnode, int changed)
20570 {
20571         if ((state->compiler->debug & DEBUG_SCC_TRANSFORM2) && lnode->val) {
20572                 display_triple_changes(state->errout, lnode->val, lnode->def);
20573         }
20574         if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
20575                 FILE *fp = state->errout;
20576                 struct triple *val, **expr;
20577                 val = lnode->val? lnode->val : lnode->def;
20578                 fprintf(fp, "%p %s %3d %10s (",
20579                         lnode->def, 
20580                         ((lnode->def->op == OP_PHI)? "phi: ": "expr:"),
20581                         lnode->def->id,
20582                         tops(lnode->def->op));
20583                 expr = triple_rhs(state, lnode->def, 0);
20584                 for(;expr;expr = triple_rhs(state, lnode->def, expr)) {
20585                         if (*expr) {
20586                                 fprintf(fp, " %d", (*expr)->id);
20587                         }
20588                 }
20589                 if (val->op == OP_INTCONST) {
20590                         fprintf(fp, " <0x%08lx>", (unsigned long)(val->u.cval));
20591                 }
20592                 fprintf(fp, " ) -> %s %s\n",
20593                         (is_lattice_hi(state, lnode)? "hi":
20594                                 is_lattice_const(state, lnode)? "const" : "lo"),
20595                         changed? "changed" : ""
20596                         );
20597         }
20598 }
20599
20600 static int compute_lnode_val(struct compile_state *state, struct scc_state *scc,
20601         struct lattice_node *lnode)
20602 {
20603         int changed;
20604         struct triple *old, *scratch;
20605         struct triple **dexpr, **vexpr;
20606         int count, i;
20607         
20608         /* Store the original value */
20609         old = preserve_lval(state, lnode);
20610
20611         /* Reinitialize the value */
20612         lnode->val = scratch = dup_triple(state, lnode->def);
20613         scratch->id = lnode->old_id;
20614         scratch->next     = scratch;
20615         scratch->prev     = scratch;
20616         scratch->use      = 0;
20617
20618         count = TRIPLE_SIZE(scratch);
20619         for(i = 0; i < count; i++) {
20620                 dexpr = &lnode->def->param[i];
20621                 vexpr = &scratch->param[i];
20622                 *vexpr = *dexpr;
20623                 if (((i < TRIPLE_MISC_OFF(scratch)) ||
20624                         (i >= TRIPLE_TARG_OFF(scratch))) &&
20625                         *dexpr) {
20626                         struct lattice_node *tmp;
20627                         tmp = triple_to_lattice(state, scc, *dexpr);
20628                         *vexpr = (tmp->val)? tmp->val : tmp->def;
20629                 }
20630         }
20631         if (triple_is_branch(state, scratch)) {
20632                 scratch->next = lnode->def->next;
20633         }
20634         /* Recompute the value */
20635 #warning "FIXME see if simplify does anything bad"
20636         /* So far it looks like only the strength reduction
20637          * optimization are things I need to worry about.
20638          */
20639         simplify(state, scratch);
20640         /* Cleanup my value */
20641         if (scratch->use) {
20642                 internal_error(state, lnode->def, "scratch used?");
20643         }
20644         if ((scratch->prev != scratch) ||
20645                 ((scratch->next != scratch) &&
20646                         (!triple_is_branch(state, lnode->def) ||
20647                                 (scratch->next != lnode->def->next)))) {
20648                 internal_error(state, lnode->def, "scratch in list?");
20649         }
20650         /* undo any uses... */
20651         count = TRIPLE_SIZE(scratch);
20652         for(i = 0; i < count; i++) {
20653                 vexpr = &scratch->param[i];
20654                 if (*vexpr) {
20655                         unuse_triple(*vexpr, scratch);
20656                 }
20657         }
20658         if (lnode->val->op == OP_UNKNOWNVAL) {
20659                 lnode->val = 0; /* Lattice low by definition */
20660         }
20661         /* Find the case when I am lattice high */
20662         if (lnode->val && 
20663                 (lnode->val->op == lnode->def->op) &&
20664                 (memcmp(lnode->val->param, lnode->def->param, 
20665                         count * sizeof(lnode->val->param[0])) == 0) &&
20666                 (memcmp(&lnode->val->u, &lnode->def->u, sizeof(lnode->def->u)) == 0)) {
20667                 lnode->val = lnode->def;
20668         }
20669         /* Only allow lattice high when all of my inputs
20670          * are also lattice high.  Occassionally I can
20671          * have constants with a lattice low input, so
20672          * I do not need to check that case.
20673          */
20674         if (is_lattice_hi(state, lnode)) {
20675                 struct lattice_node *tmp;
20676                 int rhs;
20677                 rhs = lnode->val->rhs;
20678                 for(i = 0; i < rhs; i++) {
20679                         tmp = triple_to_lattice(state, scc, RHS(lnode->val, i));
20680                         if (!is_lattice_hi(state, tmp)) {
20681                                 lnode->val = 0;
20682                                 break;
20683                         }
20684                 }
20685         }
20686         /* Find the cases that are always lattice lo */
20687         if (lnode->val && 
20688                 triple_is_def(state, lnode->val) &&
20689                 !triple_is_pure(state, lnode->val, lnode->old_id)) {
20690                 lnode->val = 0;
20691         }
20692         /* See if the lattice value has changed */
20693         changed = lval_changed(state, old, lnode);
20694         /* See if this value should not change */
20695         if ((lnode->val != lnode->def) && 
20696                 ((      !triple_is_def(state, lnode->def)  &&
20697                         !triple_is_cbranch(state, lnode->def)) ||
20698                         (lnode->def->op == OP_PIECE))) {
20699 #warning "FIXME constant propogate through expressions with multiple left hand sides"
20700                 if (changed) {
20701                         internal_warning(state, lnode->def, "non def changes value?");
20702                 }
20703                 lnode->val = 0;
20704         }
20705
20706         /* See if we need to free the scratch value */
20707         if (lnode->val != scratch) {
20708                 xfree(scratch);
20709         }
20710         
20711         return changed;
20712 }
20713
20714
20715 static void scc_visit_cbranch(struct compile_state *state, struct scc_state *scc,
20716         struct lattice_node *lnode)
20717 {
20718         struct lattice_node *cond;
20719         struct flow_edge *left, *right;
20720         int changed;
20721
20722         /* Update the branch value */
20723         changed = compute_lnode_val(state, scc, lnode);
20724         scc_debug_lnode(state, scc, lnode, changed);
20725
20726         /* This only applies to conditional branches */
20727         if (!triple_is_cbranch(state, lnode->def)) {
20728                 internal_error(state, lnode->def, "not a conditional branch");
20729         }
20730
20731         if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
20732                 struct flow_edge *fedge;
20733                 FILE *fp = state->errout;
20734                 fprintf(fp, "%s: %d (",
20735                         tops(lnode->def->op),
20736                         lnode->def->id);
20737                 
20738                 for(fedge = lnode->fblock->out; fedge; fedge = fedge->out_next) {
20739                         fprintf(fp, " %d", fedge->dst->block->vertex);
20740                 }
20741                 fprintf(fp, " )");
20742                 if (lnode->def->rhs > 0) {
20743                         fprintf(fp, " <- %d",
20744                                 RHS(lnode->def, 0)->id);
20745                 }
20746                 fprintf(fp, "\n");
20747         }
20748         cond = triple_to_lattice(state, scc, RHS(lnode->def,0));
20749         for(left = cond->fblock->out; left; left = left->out_next) {
20750                 if (left->dst->block->first == lnode->def->next) {
20751                         break;
20752                 }
20753         }
20754         if (!left) {
20755                 internal_error(state, lnode->def, "Cannot find left branch edge");
20756         }
20757         for(right = cond->fblock->out; right; right = right->out_next) {
20758                 if (right->dst->block->first == TARG(lnode->def, 0)) {
20759                         break;
20760                 }
20761         }
20762         if (!right) {
20763                 internal_error(state, lnode->def, "Cannot find right branch edge");
20764         }
20765         /* I should only come here if the controlling expressions value
20766          * has changed, which means it must be either a constant or lo.
20767          */
20768         if (is_lattice_hi(state, cond)) {
20769                 internal_error(state, cond->def, "condition high?");
20770                 return;
20771         }
20772         if (is_lattice_lo(state, cond)) {
20773                 scc_add_fedge(state, scc, left);
20774                 scc_add_fedge(state, scc, right);
20775         }
20776         else if (cond->val->u.cval) {
20777                 scc_add_fedge(state, scc, right);
20778         } else {
20779                 scc_add_fedge(state, scc, left);
20780         }
20781
20782 }
20783
20784
20785 static void scc_add_sedge_dst(struct compile_state *state, 
20786         struct scc_state *scc, struct ssa_edge *sedge)
20787 {
20788         if (triple_is_cbranch(state, sedge->dst->def)) {
20789                 scc_visit_cbranch(state, scc, sedge->dst);
20790         }
20791         else if (triple_is_def(state, sedge->dst->def)) {
20792                 scc_add_sedge(state, scc, sedge);
20793         }
20794 }
20795
20796 static void scc_visit_phi(struct compile_state *state, struct scc_state *scc, 
20797         struct lattice_node *lnode)
20798 {
20799         struct lattice_node *tmp;
20800         struct triple **slot, *old;
20801         struct flow_edge *fedge;
20802         int changed;
20803         int index;
20804         if (lnode->def->op != OP_PHI) {
20805                 internal_error(state, lnode->def, "not phi");
20806         }
20807         /* Store the original value */
20808         old = preserve_lval(state, lnode);
20809
20810         /* default to lattice high */
20811         lnode->val = lnode->def;
20812         slot = &RHS(lnode->def, 0);
20813         index = 0;
20814         for(fedge = lnode->fblock->in; fedge; index++, fedge = fedge->in_next) {
20815                 if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
20816                         fprintf(state->errout, "Examining edge: %d vertex: %d executable: %d\n", 
20817                                 index,
20818                                 fedge->dst->block->vertex,
20819                                 fedge->executable
20820                                 );
20821                 }
20822                 if (!fedge->executable) {
20823                         continue;
20824                 }
20825                 if (!slot[index]) {
20826                         internal_error(state, lnode->def, "no phi value");
20827                 }
20828                 tmp = triple_to_lattice(state, scc, slot[index]);
20829                 /* meet(X, lattice low) = lattice low */
20830                 if (is_lattice_lo(state, tmp)) {
20831                         lnode->val = 0;
20832                 }
20833                 /* meet(X, lattice high) = X */
20834                 else if (is_lattice_hi(state, tmp)) {
20835                         lnode->val = lnode->val;
20836                 }
20837                 /* meet(lattice high, X) = X */
20838                 else if (is_lattice_hi(state, lnode)) {
20839                         lnode->val = dup_triple(state, tmp->val);
20840                         /* Only change the type if necessary */
20841                         if (!is_subset_type(lnode->def->type, tmp->val->type)) {
20842                                 lnode->val->type = lnode->def->type;
20843                         }
20844                 }
20845                 /* meet(const, const) = const or lattice low */
20846                 else if (!constants_equal(state, lnode->val, tmp->val)) {
20847                         lnode->val = 0;
20848                 }
20849
20850                 /* meet(lattice low, X) = lattice low */
20851                 if (is_lattice_lo(state, lnode)) {
20852                         lnode->val = 0;
20853                         break;
20854                 }
20855         }
20856         changed = lval_changed(state, old, lnode);
20857         scc_debug_lnode(state, scc, lnode, changed);
20858
20859         /* If the lattice value has changed update the work lists. */
20860         if (changed) {
20861                 struct ssa_edge *sedge;
20862                 for(sedge = lnode->out; sedge; sedge = sedge->out_next) {
20863                         scc_add_sedge_dst(state, scc, sedge);
20864                 }
20865         }
20866 }
20867
20868
20869 static void scc_visit_expr(struct compile_state *state, struct scc_state *scc,
20870         struct lattice_node *lnode)
20871 {
20872         int changed;
20873
20874         if (!triple_is_def(state, lnode->def)) {
20875                 internal_warning(state, lnode->def, "not visiting an expression?");
20876         }
20877         changed = compute_lnode_val(state, scc, lnode);
20878         scc_debug_lnode(state, scc, lnode, changed);
20879
20880         if (changed) {
20881                 struct ssa_edge *sedge;
20882                 for(sedge = lnode->out; sedge; sedge = sedge->out_next) {
20883                         scc_add_sedge_dst(state, scc, sedge);
20884                 }
20885         }
20886 }
20887
20888 static void scc_writeback_values(
20889         struct compile_state *state, struct scc_state *scc)
20890 {
20891         struct triple *first, *ins;
20892         first = state->first;
20893         ins = first;
20894         do {
20895                 struct lattice_node *lnode;
20896                 lnode = triple_to_lattice(state, scc, ins);
20897                 if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
20898                         if (is_lattice_hi(state, lnode) &&
20899                                 (lnode->val->op != OP_NOOP))
20900                         {
20901                                 struct flow_edge *fedge;
20902                                 int executable;
20903                                 executable = 0;
20904                                 for(fedge = lnode->fblock->in; 
20905                                     !executable && fedge; fedge = fedge->in_next) {
20906                                         executable |= fedge->executable;
20907                                 }
20908                                 if (executable) {
20909                                         internal_warning(state, lnode->def,
20910                                                 "lattice node %d %s->%s still high?",
20911                                                 ins->id, 
20912                                                 tops(lnode->def->op),
20913                                                 tops(lnode->val->op));
20914                                 }
20915                         }
20916                 }
20917
20918                 /* Restore id */
20919                 ins->id = lnode->old_id;
20920                 if (lnode->val && (lnode->val != ins)) {
20921                         /* See if it something I know how to write back */
20922                         switch(lnode->val->op) {
20923                         case OP_INTCONST:
20924                                 mkconst(state, ins, lnode->val->u.cval);
20925                                 break;
20926                         case OP_ADDRCONST:
20927                                 mkaddr_const(state, ins, 
20928                                         MISC(lnode->val, 0), lnode->val->u.cval);
20929                                 break;
20930                         default:
20931                                 /* By default don't copy the changes,
20932                                  * recompute them in place instead.
20933                                  */
20934                                 simplify(state, ins);
20935                                 break;
20936                         }
20937                         if (is_const(lnode->val) &&
20938                                 !constants_equal(state, lnode->val, ins)) {
20939                                 internal_error(state, 0, "constants not equal");
20940                         }
20941                         /* Free the lattice nodes */
20942                         xfree(lnode->val);
20943                         lnode->val = 0;
20944                 }
20945                 ins = ins->next;
20946         } while(ins != first);
20947 }
20948
20949 static void scc_transform(struct compile_state *state)
20950 {
20951         struct scc_state scc;
20952         if (!(state->compiler->flags & COMPILER_SCC_TRANSFORM)) {
20953                 return;
20954         }
20955
20956         initialize_scc_state(state, &scc);
20957
20958         while(scc.flow_work_list || scc.ssa_work_list) {
20959                 struct flow_edge *fedge;
20960                 struct ssa_edge *sedge;
20961                 struct flow_edge *fptr;
20962                 while((fedge = scc_next_fedge(state, &scc))) {
20963                         struct block *block;
20964                         struct triple *ptr;
20965                         struct flow_block *fblock;
20966                         int reps;
20967                         int done;
20968                         if (fedge->executable) {
20969                                 continue;
20970                         }
20971                         if (!fedge->dst) {
20972                                 internal_error(state, 0, "fedge without dst");
20973                         }
20974                         if (!fedge->src) {
20975                                 internal_error(state, 0, "fedge without src");
20976                         }
20977                         fedge->executable = 1;
20978                         fblock = fedge->dst;
20979                         block = fblock->block;
20980                         reps = 0;
20981                         for(fptr = fblock->in; fptr; fptr = fptr->in_next) {
20982                                 if (fptr->executable) {
20983                                         reps++;
20984                                 }
20985                         }
20986                         
20987                         if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
20988                                 fprintf(state->errout, "vertex: %d reps: %d\n", 
20989                                         block->vertex, reps);
20990                         }
20991
20992                         done = 0;
20993                         for(ptr = block->first; !done; ptr = ptr->next) {
20994                                 struct lattice_node *lnode;
20995                                 done = (ptr == block->last);
20996                                 lnode = &scc.lattice[ptr->id];
20997                                 if (ptr->op == OP_PHI) {
20998                                         scc_visit_phi(state, &scc, lnode);
20999                                 }
21000                                 else if ((reps == 1) && triple_is_def(state, ptr))
21001                                 {
21002                                         scc_visit_expr(state, &scc, lnode);
21003                                 }
21004                         }
21005                         /* Add unconditional branch edges */
21006                         if (!triple_is_cbranch(state, fblock->block->last)) {
21007                                 struct flow_edge *out;
21008                                 for(out = fblock->out; out; out = out->out_next) {
21009                                         scc_add_fedge(state, &scc, out);
21010                                 }
21011                         }
21012                 }
21013                 while((sedge = scc_next_sedge(state, &scc))) {
21014                         struct lattice_node *lnode;
21015                         struct flow_block *fblock;
21016                         lnode = sedge->dst;
21017                         fblock = lnode->fblock;
21018
21019                         if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
21020                                 fprintf(state->errout, "sedge: %5d (%5d -> %5d)\n",
21021                                         sedge - scc.ssa_edges,
21022                                         sedge->src->def->id,
21023                                         sedge->dst->def->id);
21024                         }
21025
21026                         if (lnode->def->op == OP_PHI) {
21027                                 scc_visit_phi(state, &scc, lnode);
21028                         }
21029                         else {
21030                                 for(fptr = fblock->in; fptr; fptr = fptr->in_next) {
21031                                         if (fptr->executable) {
21032                                                 break;
21033                                         }
21034                                 }
21035                                 if (fptr) {
21036                                         scc_visit_expr(state, &scc, lnode);
21037                                 }
21038                         }
21039                 }
21040         }
21041         
21042         scc_writeback_values(state, &scc);
21043         free_scc_state(state, &scc);
21044         rebuild_ssa_form(state);
21045         
21046         print_blocks(state, __func__, state->dbgout);
21047 }
21048
21049
21050 static void transform_to_arch_instructions(struct compile_state *state)
21051 {
21052         struct triple *ins, *first;
21053         first = state->first;
21054         ins = first;
21055         do {
21056                 ins = transform_to_arch_instruction(state, ins);
21057         } while(ins != first);
21058         
21059         print_blocks(state, __func__, state->dbgout);
21060 }
21061
21062 #if DEBUG_CONSISTENCY
21063 static void verify_uses(struct compile_state *state)
21064 {
21065         struct triple *first, *ins;
21066         struct triple_set *set;
21067         first = state->first;
21068         ins = first;
21069         do {
21070                 struct triple **expr;
21071                 expr = triple_rhs(state, ins, 0);
21072                 for(; expr; expr = triple_rhs(state, ins, expr)) {
21073                         struct triple *rhs;
21074                         rhs = *expr;
21075                         for(set = rhs?rhs->use:0; set; set = set->next) {
21076                                 if (set->member == ins) {
21077                                         break;
21078                                 }
21079                         }
21080                         if (!set) {
21081                                 internal_error(state, ins, "rhs not used");
21082                         }
21083                 }
21084                 expr = triple_lhs(state, ins, 0);
21085                 for(; expr; expr = triple_lhs(state, ins, expr)) {
21086                         struct triple *lhs;
21087                         lhs = *expr;
21088                         for(set =  lhs?lhs->use:0; set; set = set->next) {
21089                                 if (set->member == ins) {
21090                                         break;
21091                                 }
21092                         }
21093                         if (!set) {
21094                                 internal_error(state, ins, "lhs not used");
21095                         }
21096                 }
21097                 expr = triple_misc(state, ins, 0);
21098                 if (ins->op != OP_PHI) {
21099                         for(; expr; expr = triple_targ(state, ins, expr)) {
21100                                 struct triple *misc;
21101                                 misc = *expr;
21102                                 for(set = misc?misc->use:0; set; set = set->next) {
21103                                         if (set->member == ins) {
21104                                                 break;
21105                                         }
21106                                 }
21107                                 if (!set) {
21108                                         internal_error(state, ins, "misc not used");
21109                                 }
21110                         }
21111                 }
21112                 if (!triple_is_ret(state, ins)) {
21113                         expr = triple_targ(state, ins, 0);
21114                         for(; expr; expr = triple_targ(state, ins, expr)) {
21115                                 struct triple *targ;
21116                                 targ = *expr;
21117                                 for(set = targ?targ->use:0; set; set = set->next) {
21118                                         if (set->member == ins) {
21119                                                 break;
21120                                         }
21121                                 }
21122                                 if (!set) {
21123                                         internal_error(state, ins, "targ not used");
21124                                 }
21125                         }
21126                 }
21127                 ins = ins->next;
21128         } while(ins != first);
21129         
21130 }
21131 static void verify_blocks_present(struct compile_state *state)
21132 {
21133         struct triple *first, *ins;
21134         if (!state->bb.first_block) {
21135                 return;
21136         }
21137         first = state->first;
21138         ins = first;
21139         do {
21140                 valid_ins(state, ins);
21141                 if (triple_stores_block(state, ins)) {
21142                         if (!ins->u.block) {
21143                                 internal_error(state, ins, 
21144                                         "%p not in a block?", ins);
21145                         }
21146                 }
21147                 ins = ins->next;
21148         } while(ins != first);
21149         
21150         
21151 }
21152
21153 static int edge_present(struct compile_state *state, struct block *block, struct triple *edge)
21154 {
21155         struct block_set *bedge;
21156         struct block *targ;
21157         targ = block_of_triple(state, edge);
21158         for(bedge = block->edges; bedge; bedge = bedge->next) {
21159                 if (bedge->member == targ) {
21160                         return 1;
21161                 }
21162         }
21163         return 0;
21164 }
21165
21166 static void verify_blocks(struct compile_state *state)
21167 {
21168         struct triple *ins;
21169         struct block *block;
21170         int blocks;
21171         block = state->bb.first_block;
21172         if (!block) {
21173                 return;
21174         }
21175         blocks = 0;
21176         do {
21177                 int users;
21178                 struct block_set *user, *edge;
21179                 blocks++;
21180                 for(ins = block->first; ins != block->last->next; ins = ins->next) {
21181                         if (triple_stores_block(state, ins) && (ins->u.block != block)) {
21182                                 internal_error(state, ins, "inconsitent block specified");
21183                         }
21184                         valid_ins(state, ins);
21185                 }
21186                 users = 0;
21187                 for(user = block->use; user; user = user->next) {
21188                         users++;
21189                         if (!user->member->first) {
21190                                 internal_error(state, block->first, "user is empty");
21191                         }
21192                         if ((block == state->bb.last_block) &&
21193                                 (user->member == state->bb.first_block)) {
21194                                 continue;
21195                         }
21196                         for(edge = user->member->edges; edge; edge = edge->next) {
21197                                 if (edge->member == block) {
21198                                         break;
21199                                 }
21200                         }
21201                         if (!edge) {
21202                                 internal_error(state, user->member->first,
21203                                         "user does not use block");
21204                         }
21205                 }
21206                 if (triple_is_branch(state, block->last)) {
21207                         struct triple **expr;
21208                         expr = triple_edge_targ(state, block->last, 0);
21209                         for(;expr; expr = triple_edge_targ(state, block->last, expr)) {
21210                                 if (*expr && !edge_present(state, block, *expr)) {
21211                                         internal_error(state, block->last, "no edge to targ");
21212                                 }
21213                         }
21214                 }
21215                 if (!triple_is_ubranch(state, block->last) &&
21216                         (block != state->bb.last_block) &&
21217                         !edge_present(state, block, block->last->next)) {
21218                         internal_error(state, block->last, "no edge to block->last->next");
21219                 }
21220                 for(edge = block->edges; edge; edge = edge->next) {
21221                         for(user = edge->member->use; user; user = user->next) {
21222                                 if (user->member == block) {
21223                                         break;
21224                                 }
21225                         }
21226                         if (!user || user->member != block) {
21227                                 internal_error(state, block->first,
21228                                         "block does not use edge");
21229                         }
21230                         if (!edge->member->first) {
21231                                 internal_error(state, block->first, "edge block is empty");
21232                         }
21233                 }
21234                 if (block->users != users) {
21235                         internal_error(state, block->first, 
21236                                 "computed users %d != stored users %d",
21237                                 users, block->users);
21238                 }
21239                 if (!triple_stores_block(state, block->last->next)) {
21240                         internal_error(state, block->last->next, 
21241                                 "cannot find next block");
21242                 }
21243                 block = block->last->next->u.block;
21244                 if (!block) {
21245                         internal_error(state, block->last->next,
21246                                 "bad next block");
21247                 }
21248         } while(block != state->bb.first_block);
21249         if (blocks != state->bb.last_vertex) {
21250                 internal_error(state, 0, "computed blocks: %d != stored blocks %d",
21251                         blocks, state->bb.last_vertex);
21252         }
21253 }
21254
21255 static void verify_domination(struct compile_state *state)
21256 {
21257         struct triple *first, *ins;
21258         struct triple_set *set;
21259         if (!state->bb.first_block) {
21260                 return;
21261         }
21262         
21263         first = state->first;
21264         ins = first;
21265         do {
21266                 for(set = ins->use; set; set = set->next) {
21267                         struct triple **slot;
21268                         struct triple *use_point;
21269                         int i, zrhs;
21270                         use_point = 0;
21271                         zrhs = set->member->rhs;
21272                         slot = &RHS(set->member, 0);
21273                         /* See if the use is on the right hand side */
21274                         for(i = 0; i < zrhs; i++) {
21275                                 if (slot[i] == ins) {
21276                                         break;
21277                                 }
21278                         }
21279                         if (i < zrhs) {
21280                                 use_point = set->member;
21281                                 if (set->member->op == OP_PHI) {
21282                                         struct block_set *bset;
21283                                         int edge;
21284                                         bset = set->member->u.block->use;
21285                                         for(edge = 0; bset && (edge < i); edge++) {
21286                                                 bset = bset->next;
21287                                         }
21288                                         if (!bset) {
21289                                                 internal_error(state, set->member, 
21290                                                         "no edge for phi rhs %d", i);
21291                                         }
21292                                         use_point = bset->member->last;
21293                                 }
21294                         }
21295                         if (use_point &&
21296                                 !tdominates(state, ins, use_point)) {
21297                                 if (is_const(ins)) {
21298                                         internal_warning(state, ins, 
21299                                         "non dominated rhs use point %p?", use_point);
21300                                 }
21301                                 else {
21302                                         internal_error(state, ins, 
21303                                                 "non dominated rhs use point %p?", use_point);
21304                                 }
21305                         }
21306                 }
21307                 ins = ins->next;
21308         } while(ins != first);
21309 }
21310
21311 static void verify_rhs(struct compile_state *state)
21312 {
21313         struct triple *first, *ins;
21314         first = state->first;
21315         ins = first;
21316         do {
21317                 struct triple **slot;
21318                 int zrhs, i;
21319                 zrhs = ins->rhs;
21320                 slot = &RHS(ins, 0);
21321                 for(i = 0; i < zrhs; i++) {
21322                         if (slot[i] == 0) {
21323                                 internal_error(state, ins,
21324                                         "missing rhs %d on %s",
21325                                         i, tops(ins->op));
21326                         }
21327                         if ((ins->op != OP_PHI) && (slot[i] == ins)) {
21328                                 internal_error(state, ins,
21329                                         "ins == rhs[%d] on %s",
21330                                         i, tops(ins->op));
21331                         }
21332                 }
21333                 ins = ins->next;
21334         } while(ins != first);
21335 }
21336
21337 static void verify_piece(struct compile_state *state)
21338 {
21339         struct triple *first, *ins;
21340         first = state->first;
21341         ins = first;
21342         do {
21343                 struct triple *ptr;
21344                 int lhs, i;
21345                 lhs = ins->lhs;
21346                 for(ptr = ins->next, i = 0; i < lhs; i++, ptr = ptr->next) {
21347                         if (ptr != LHS(ins, i)) {
21348                                 internal_error(state, ins, "malformed lhs on %s",
21349                                         tops(ins->op));
21350                         }
21351                         if (ptr->op != OP_PIECE) {
21352                                 internal_error(state, ins, "bad lhs op %s at %d on %s",
21353                                         tops(ptr->op), i, tops(ins->op));
21354                         }
21355                         if (ptr->u.cval != i) {
21356                                 internal_error(state, ins, "bad u.cval of %d %d expected",
21357                                         ptr->u.cval, i);
21358                         }
21359                 }
21360                 ins = ins->next;
21361         } while(ins != first);
21362 }
21363
21364 static void verify_ins_colors(struct compile_state *state)
21365 {
21366         struct triple *first, *ins;
21367         
21368         first = state->first;
21369         ins = first;
21370         do {
21371                 ins = ins->next;
21372         } while(ins != first);
21373 }
21374
21375 static void verify_unknown(struct compile_state *state)
21376 {
21377         struct triple *first, *ins;
21378         if (    (unknown_triple.next != &unknown_triple) ||
21379                 (unknown_triple.prev != &unknown_triple) ||
21380 #if 0
21381                 (unknown_triple.use != 0) ||
21382 #endif
21383                 (unknown_triple.op != OP_UNKNOWNVAL) ||
21384                 (unknown_triple.lhs != 0) ||
21385                 (unknown_triple.rhs != 0) ||
21386                 (unknown_triple.misc != 0) ||
21387                 (unknown_triple.targ != 0) ||
21388                 (unknown_triple.template_id != 0) ||
21389                 (unknown_triple.id != -1) ||
21390                 (unknown_triple.type != &unknown_type) ||
21391                 (unknown_triple.occurance != &dummy_occurance) ||
21392                 (unknown_triple.param[0] != 0) ||
21393                 (unknown_triple.param[1] != 0)) {
21394                 internal_error(state, &unknown_triple, "unknown_triple corrupted!");
21395         }
21396         if (    (dummy_occurance.count != 2) ||
21397                 (strcmp(dummy_occurance.filename, __FILE__) != 0) ||
21398                 (strcmp(dummy_occurance.function, "") != 0) ||
21399                 (dummy_occurance.col != 0) ||
21400                 (dummy_occurance.parent != 0)) {
21401                 internal_error(state, &unknown_triple, "dummy_occurance corrupted!");
21402         }
21403         if (    (unknown_type.type != TYPE_UNKNOWN)) {
21404                 internal_error(state, &unknown_triple, "unknown_type corrupted!");
21405         }
21406         first = state->first;
21407         ins = first;
21408         do {
21409                 int params, i;
21410                 if (ins == &unknown_triple) {
21411                         internal_error(state, ins, "unknown triple in list");
21412                 }
21413                 params = TRIPLE_SIZE(ins);
21414                 for(i = 0; i < params; i++) {
21415                         if (ins->param[i] == &unknown_triple) {
21416                                 internal_error(state, ins, "unknown triple used!");
21417                         }
21418                 }
21419                 ins = ins->next;
21420         } while(ins != first);
21421 }
21422
21423 static void verify_types(struct compile_state *state)
21424 {
21425         struct triple *first, *ins;
21426         first = state->first;
21427         ins = first;
21428         do {
21429                 struct type *invalid;
21430                 invalid = invalid_type(state, ins->type);
21431                 if (invalid) {
21432                         FILE *fp = state->errout;
21433                         fprintf(fp, "type: ");
21434                         name_of(fp, ins->type);
21435                         fprintf(fp, "\n");
21436                         fprintf(fp, "invalid type: ");
21437                         name_of(fp, invalid);
21438                         fprintf(fp, "\n");
21439                         internal_error(state, ins, "invalid ins type");
21440                 }
21441         } while(ins != first);
21442 }
21443
21444 static void verify_copy(struct compile_state *state)
21445 {
21446         struct triple *first, *ins, *next;
21447         first = state->first;
21448         next = ins = first;
21449         do {
21450                 ins = next;
21451                 next = ins->next;
21452                 if (ins->op != OP_COPY) {
21453                         continue;
21454                 }
21455                 if (!equiv_types(ins->type, RHS(ins, 0)->type)) {
21456                         FILE *fp = state->errout;
21457                         fprintf(fp, "src type: ");
21458                         name_of(fp, RHS(ins, 0)->type);
21459                         fprintf(fp, "\n");
21460                         fprintf(fp, "dst type: ");
21461                         name_of(fp, ins->type);
21462                         fprintf(fp, "\n");
21463                         internal_error(state, ins, "type mismatch in copy");
21464                 }
21465         } while(next != first);
21466 }
21467
21468 static void verify_consistency(struct compile_state *state)
21469 {
21470         verify_unknown(state);
21471         verify_uses(state);
21472         verify_blocks_present(state);
21473         verify_blocks(state);
21474         verify_domination(state);
21475         verify_rhs(state);
21476         verify_piece(state);
21477         verify_ins_colors(state);
21478         verify_types(state);
21479         verify_copy(state);
21480         if (state->compiler->debug & DEBUG_VERIFICATION) {
21481                 fprintf(state->dbgout, "consistency verified\n");
21482         }
21483 }
21484 #else 
21485 static void verify_consistency(struct compile_state *state) {}
21486 #endif /* DEBUG_CONSISTENCY */
21487
21488 static void optimize(struct compile_state *state)
21489 {
21490         /* Join all of the functions into one giant function */
21491         join_functions(state);
21492
21493         /* Dump what the instruction graph intially looks like */
21494         print_triples(state);
21495
21496         /* Replace structures with simpler data types */
21497         decompose_compound_types(state);
21498         print_triples(state);
21499
21500         verify_consistency(state);
21501         /* Analyze the intermediate code */
21502         state->bb.first = state->first;
21503         analyze_basic_blocks(state, &state->bb);
21504
21505         /* Transform the code to ssa form. */
21506         /*
21507          * The transformation to ssa form puts a phi function
21508          * on each of edge of a dominance frontier where that
21509          * phi function might be needed.  At -O2 if we don't
21510          * eleminate the excess phi functions we can get an
21511          * exponential code size growth.  So I kill the extra
21512          * phi functions early and I kill them often.
21513          */
21514         transform_to_ssa_form(state);
21515         verify_consistency(state);
21516
21517         /* Remove dead code */
21518         eliminate_inefectual_code(state);
21519         verify_consistency(state);
21520
21521         /* Do strength reduction and simple constant optimizations */
21522         simplify_all(state);
21523         verify_consistency(state);
21524         /* Propogate constants throughout the code */
21525         scc_transform(state);
21526         verify_consistency(state);
21527 #warning "WISHLIST implement single use constants (least possible register pressure)"
21528 #warning "WISHLIST implement induction variable elimination"
21529         /* Select architecture instructions and an initial partial
21530          * coloring based on architecture constraints.
21531          */
21532         transform_to_arch_instructions(state);
21533         verify_consistency(state);
21534
21535         /* Remove dead code */
21536         eliminate_inefectual_code(state);
21537         verify_consistency(state);
21538
21539         /* Color all of the variables to see if they will fit in registers */
21540         insert_copies_to_phi(state);
21541         verify_consistency(state);
21542
21543         insert_mandatory_copies(state);
21544         verify_consistency(state);
21545
21546         allocate_registers(state);
21547         verify_consistency(state);
21548
21549         /* Remove the optimization information.
21550          * This is more to check for memory consistency than to free memory.
21551          */
21552         free_basic_blocks(state, &state->bb);
21553 }
21554
21555 static void print_op_asm(struct compile_state *state,
21556         struct triple *ins, FILE *fp)
21557 {
21558         struct asm_info *info;
21559         const char *ptr;
21560         unsigned lhs, rhs, i;
21561         info = ins->u.ainfo;
21562         lhs = ins->lhs;
21563         rhs = ins->rhs;
21564         /* Don't count the clobbers in lhs */
21565         for(i = 0; i < lhs; i++) {
21566                 if (LHS(ins, i)->type == &void_type) {
21567                         break;
21568                 }
21569         }
21570         lhs = i;
21571         fprintf(fp, "#ASM\n");
21572         fputc('\t', fp);
21573         for(ptr = info->str; *ptr; ptr++) {
21574                 char *next;
21575                 unsigned long param;
21576                 struct triple *piece;
21577                 if (*ptr != '%') {
21578                         fputc(*ptr, fp);
21579                         continue;
21580                 }
21581                 ptr++;
21582                 if (*ptr == '%') {
21583                         fputc('%', fp);
21584                         continue;
21585                 }
21586                 param = strtoul(ptr, &next, 10);
21587                 if (ptr == next) {
21588                         error(state, ins, "Invalid asm template");
21589                 }
21590                 if (param >= (lhs + rhs)) {
21591                         error(state, ins, "Invalid param %%%u in asm template",
21592                                 param);
21593                 }
21594                 piece = (param < lhs)? LHS(ins, param) : RHS(ins, param - lhs);
21595                 fprintf(fp, "%s", 
21596                         arch_reg_str(ID_REG(piece->id)));
21597                 ptr = next -1;
21598         }
21599         fprintf(fp, "\n#NOT ASM\n");
21600 }
21601
21602
21603 /* Only use the low x86 byte registers.  This allows me
21604  * allocate the entire register when a byte register is used.
21605  */
21606 #define X86_4_8BIT_GPRS 1
21607
21608 /* x86 featrues */
21609 #define X86_MMX_REGS  (1<<0)
21610 #define X86_XMM_REGS  (1<<1)
21611 #define X86_NOOP_COPY (1<<2)
21612
21613 /* The x86 register classes */
21614 #define REGC_FLAGS       0
21615 #define REGC_GPR8        1
21616 #define REGC_GPR16       2
21617 #define REGC_GPR32       3
21618 #define REGC_DIVIDEND64  4
21619 #define REGC_DIVIDEND32  5
21620 #define REGC_MMX         6
21621 #define REGC_XMM         7
21622 #define REGC_GPR32_8     8
21623 #define REGC_GPR16_8     9
21624 #define REGC_GPR8_LO    10
21625 #define REGC_IMM32      11
21626 #define REGC_IMM16      12
21627 #define REGC_IMM8       13
21628 #define LAST_REGC  REGC_IMM8
21629 #if LAST_REGC >= MAX_REGC
21630 #error "MAX_REGC is to low"
21631 #endif
21632
21633 /* Register class masks */
21634 #define REGCM_FLAGS      (1 << REGC_FLAGS)
21635 #define REGCM_GPR8       (1 << REGC_GPR8)
21636 #define REGCM_GPR16      (1 << REGC_GPR16)
21637 #define REGCM_GPR32      (1 << REGC_GPR32)
21638 #define REGCM_DIVIDEND64 (1 << REGC_DIVIDEND64)
21639 #define REGCM_DIVIDEND32 (1 << REGC_DIVIDEND32)
21640 #define REGCM_MMX        (1 << REGC_MMX)
21641 #define REGCM_XMM        (1 << REGC_XMM)
21642 #define REGCM_GPR32_8    (1 << REGC_GPR32_8)
21643 #define REGCM_GPR16_8    (1 << REGC_GPR16_8)
21644 #define REGCM_GPR8_LO    (1 << REGC_GPR8_LO)
21645 #define REGCM_IMM32      (1 << REGC_IMM32)
21646 #define REGCM_IMM16      (1 << REGC_IMM16)
21647 #define REGCM_IMM8       (1 << REGC_IMM8)
21648 #define REGCM_ALL        ((1 << (LAST_REGC + 1)) - 1)
21649 #define REGCM_IMMALL    (REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8)
21650
21651 /* The x86 registers */
21652 #define REG_EFLAGS  2
21653 #define REGC_FLAGS_FIRST REG_EFLAGS
21654 #define REGC_FLAGS_LAST  REG_EFLAGS
21655 #define REG_AL      3
21656 #define REG_BL      4
21657 #define REG_CL      5
21658 #define REG_DL      6
21659 #define REG_AH      7
21660 #define REG_BH      8
21661 #define REG_CH      9
21662 #define REG_DH      10
21663 #define REGC_GPR8_LO_FIRST REG_AL
21664 #define REGC_GPR8_LO_LAST  REG_DL
21665 #define REGC_GPR8_FIRST  REG_AL
21666 #define REGC_GPR8_LAST   REG_DH
21667 #define REG_AX     11
21668 #define REG_BX     12
21669 #define REG_CX     13
21670 #define REG_DX     14
21671 #define REG_SI     15
21672 #define REG_DI     16
21673 #define REG_BP     17
21674 #define REG_SP     18
21675 #define REGC_GPR16_FIRST REG_AX
21676 #define REGC_GPR16_LAST  REG_SP
21677 #define REG_EAX    19
21678 #define REG_EBX    20
21679 #define REG_ECX    21
21680 #define REG_EDX    22
21681 #define REG_ESI    23
21682 #define REG_EDI    24
21683 #define REG_EBP    25
21684 #define REG_ESP    26
21685 #define REGC_GPR32_FIRST REG_EAX
21686 #define REGC_GPR32_LAST  REG_ESP
21687 #define REG_EDXEAX 27
21688 #define REGC_DIVIDEND64_FIRST REG_EDXEAX
21689 #define REGC_DIVIDEND64_LAST  REG_EDXEAX
21690 #define REG_DXAX   28
21691 #define REGC_DIVIDEND32_FIRST REG_DXAX
21692 #define REGC_DIVIDEND32_LAST  REG_DXAX
21693 #define REG_MMX0   29
21694 #define REG_MMX1   30
21695 #define REG_MMX2   31
21696 #define REG_MMX3   32
21697 #define REG_MMX4   33
21698 #define REG_MMX5   34
21699 #define REG_MMX6   35
21700 #define REG_MMX7   36
21701 #define REGC_MMX_FIRST REG_MMX0
21702 #define REGC_MMX_LAST  REG_MMX7
21703 #define REG_XMM0   37
21704 #define REG_XMM1   38
21705 #define REG_XMM2   39
21706 #define REG_XMM3   40
21707 #define REG_XMM4   41
21708 #define REG_XMM5   42
21709 #define REG_XMM6   43
21710 #define REG_XMM7   44
21711 #define REGC_XMM_FIRST REG_XMM0
21712 #define REGC_XMM_LAST  REG_XMM7
21713 #warning "WISHLIST figure out how to use pinsrw and pextrw to better use extended regs"
21714 #define LAST_REG   REG_XMM7
21715
21716 #define REGC_GPR32_8_FIRST REG_EAX
21717 #define REGC_GPR32_8_LAST  REG_EDX
21718 #define REGC_GPR16_8_FIRST REG_AX
21719 #define REGC_GPR16_8_LAST  REG_DX
21720
21721 #define REGC_IMM8_FIRST    -1
21722 #define REGC_IMM8_LAST     -1
21723 #define REGC_IMM16_FIRST   -2
21724 #define REGC_IMM16_LAST    -1
21725 #define REGC_IMM32_FIRST   -4
21726 #define REGC_IMM32_LAST    -1
21727
21728 #if LAST_REG >= MAX_REGISTERS
21729 #error "MAX_REGISTERS to low"
21730 #endif
21731
21732
21733 static unsigned regc_size[LAST_REGC +1] = {
21734         [REGC_FLAGS]      = REGC_FLAGS_LAST      - REGC_FLAGS_FIRST + 1,
21735         [REGC_GPR8]       = REGC_GPR8_LAST       - REGC_GPR8_FIRST + 1,
21736         [REGC_GPR16]      = REGC_GPR16_LAST      - REGC_GPR16_FIRST + 1,
21737         [REGC_GPR32]      = REGC_GPR32_LAST      - REGC_GPR32_FIRST + 1,
21738         [REGC_DIVIDEND64] = REGC_DIVIDEND64_LAST - REGC_DIVIDEND64_FIRST + 1,
21739         [REGC_DIVIDEND32] = REGC_DIVIDEND32_LAST - REGC_DIVIDEND32_FIRST + 1,
21740         [REGC_MMX]        = REGC_MMX_LAST        - REGC_MMX_FIRST + 1,
21741         [REGC_XMM]        = REGC_XMM_LAST        - REGC_XMM_FIRST + 1,
21742         [REGC_GPR32_8]    = REGC_GPR32_8_LAST    - REGC_GPR32_8_FIRST + 1,
21743         [REGC_GPR16_8]    = REGC_GPR16_8_LAST    - REGC_GPR16_8_FIRST + 1,
21744         [REGC_GPR8_LO]    = REGC_GPR8_LO_LAST    - REGC_GPR8_LO_FIRST + 1,
21745         [REGC_IMM32]      = 0,
21746         [REGC_IMM16]      = 0,
21747         [REGC_IMM8]       = 0,
21748 };
21749
21750 static const struct {
21751         int first, last;
21752 } regcm_bound[LAST_REGC + 1] = {
21753         [REGC_FLAGS]      = { REGC_FLAGS_FIRST,      REGC_FLAGS_LAST },
21754         [REGC_GPR8]       = { REGC_GPR8_FIRST,       REGC_GPR8_LAST },
21755         [REGC_GPR16]      = { REGC_GPR16_FIRST,      REGC_GPR16_LAST },
21756         [REGC_GPR32]      = { REGC_GPR32_FIRST,      REGC_GPR32_LAST },
21757         [REGC_DIVIDEND64] = { REGC_DIVIDEND64_FIRST, REGC_DIVIDEND64_LAST },
21758         [REGC_DIVIDEND32] = { REGC_DIVIDEND32_FIRST, REGC_DIVIDEND32_LAST },
21759         [REGC_MMX]        = { REGC_MMX_FIRST,        REGC_MMX_LAST },
21760         [REGC_XMM]        = { REGC_XMM_FIRST,        REGC_XMM_LAST },
21761         [REGC_GPR32_8]    = { REGC_GPR32_8_FIRST,    REGC_GPR32_8_LAST },
21762         [REGC_GPR16_8]    = { REGC_GPR16_8_FIRST,    REGC_GPR16_8_LAST },
21763         [REGC_GPR8_LO]    = { REGC_GPR8_LO_FIRST,    REGC_GPR8_LO_LAST },
21764         [REGC_IMM32]      = { REGC_IMM32_FIRST,      REGC_IMM32_LAST },
21765         [REGC_IMM16]      = { REGC_IMM16_FIRST,      REGC_IMM16_LAST },
21766         [REGC_IMM8]       = { REGC_IMM8_FIRST,       REGC_IMM8_LAST },
21767 };
21768
21769 #if ARCH_INPUT_REGS != 4
21770 #error ARCH_INPUT_REGS size mismatch
21771 #endif
21772 static const struct reg_info arch_input_regs[ARCH_INPUT_REGS] = {
21773         { .reg = REG_EAX, .regcm = REGCM_GPR32 },
21774         { .reg = REG_EBX, .regcm = REGCM_GPR32 },
21775         { .reg = REG_ECX, .regcm = REGCM_GPR32 },
21776         { .reg = REG_EDX, .regcm = REGCM_GPR32 },
21777 };
21778
21779 #if ARCH_OUTPUT_REGS != 4
21780 #error ARCH_INPUT_REGS size mismatch
21781 #endif
21782 static const struct reg_info arch_output_regs[ARCH_OUTPUT_REGS] = {
21783         { .reg = REG_EAX, .regcm = REGCM_GPR32 },
21784         { .reg = REG_EBX, .regcm = REGCM_GPR32 },
21785         { .reg = REG_ECX, .regcm = REGCM_GPR32 },
21786         { .reg = REG_EDX, .regcm = REGCM_GPR32 },
21787 };
21788
21789 static void init_arch_state(struct arch_state *arch)
21790 {
21791         memset(arch, 0, sizeof(*arch));
21792         arch->features = 0;
21793 }
21794
21795 static const struct compiler_flag arch_flags[] = {
21796         { "mmx",       X86_MMX_REGS },
21797         { "sse",       X86_XMM_REGS },
21798         { "noop-copy", X86_NOOP_COPY },
21799         { 0,     0 },
21800 };
21801 static const struct compiler_flag arch_cpus[] = {
21802         { "i386", 0 },
21803         { "p2",   X86_MMX_REGS },
21804         { "p3",   X86_MMX_REGS | X86_XMM_REGS },
21805         { "p4",   X86_MMX_REGS | X86_XMM_REGS },
21806         { "k7",   X86_MMX_REGS },
21807         { "k8",   X86_MMX_REGS | X86_XMM_REGS },
21808         { "c3",   X86_MMX_REGS },
21809         { "c3-2", X86_MMX_REGS | X86_XMM_REGS }, /* Nehemiah */
21810         {  0,     0 }
21811 };
21812 static int arch_encode_flag(struct arch_state *arch, const char *flag)
21813 {
21814         int result;
21815         int act;
21816
21817         act = 1;
21818         result = -1;
21819         if (strncmp(flag, "no-", 3) == 0) {
21820                 flag += 3;
21821                 act = 0;
21822         }
21823         if (act && strncmp(flag, "cpu=", 4) == 0) {
21824                 flag += 4;
21825                 result = set_flag(arch_cpus, &arch->features, 1, flag);
21826         }
21827         else {
21828                 result = set_flag(arch_flags, &arch->features, act, flag);
21829         }
21830         return result;
21831 }
21832
21833 static void arch_usage(FILE *fp)
21834 {
21835         flag_usage(fp, arch_flags, "-m", "-mno-");
21836         flag_usage(fp, arch_cpus, "-mcpu=", 0);
21837 }
21838
21839 static unsigned arch_regc_size(struct compile_state *state, int class)
21840 {
21841         if ((class < 0) || (class > LAST_REGC)) {
21842                 return 0;
21843         }
21844         return regc_size[class];
21845 }
21846
21847 static int arch_regcm_intersect(unsigned regcm1, unsigned regcm2)
21848 {
21849         /* See if two register classes may have overlapping registers */
21850         unsigned gpr_mask = REGCM_GPR8 | REGCM_GPR8_LO | REGCM_GPR16_8 | REGCM_GPR16 |
21851                 REGCM_GPR32_8 | REGCM_GPR32 | 
21852                 REGCM_DIVIDEND32 | REGCM_DIVIDEND64;
21853
21854         /* Special case for the immediates */
21855         if ((regcm1 & (REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8)) &&
21856                 ((regcm1 & ~(REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8)) == 0) &&
21857                 (regcm2 & (REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8)) &&
21858                 ((regcm2 & ~(REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8)) == 0)) { 
21859                 return 0;
21860         }
21861         return (regcm1 & regcm2) ||
21862                 ((regcm1 & gpr_mask) && (regcm2 & gpr_mask));
21863 }
21864
21865 static void arch_reg_equivs(
21866         struct compile_state *state, unsigned *equiv, int reg)
21867 {
21868         if ((reg < 0) || (reg > LAST_REG)) {
21869                 internal_error(state, 0, "invalid register");
21870         }
21871         *equiv++ = reg;
21872         switch(reg) {
21873         case REG_AL:
21874 #if X86_4_8BIT_GPRS
21875                 *equiv++ = REG_AH;
21876 #endif
21877                 *equiv++ = REG_AX;
21878                 *equiv++ = REG_EAX;
21879                 *equiv++ = REG_DXAX;
21880                 *equiv++ = REG_EDXEAX;
21881                 break;
21882         case REG_AH:
21883 #if X86_4_8BIT_GPRS
21884                 *equiv++ = REG_AL;
21885 #endif
21886                 *equiv++ = REG_AX;
21887                 *equiv++ = REG_EAX;
21888                 *equiv++ = REG_DXAX;
21889                 *equiv++ = REG_EDXEAX;
21890                 break;
21891         case REG_BL:  
21892 #if X86_4_8BIT_GPRS
21893                 *equiv++ = REG_BH;
21894 #endif
21895                 *equiv++ = REG_BX;
21896                 *equiv++ = REG_EBX;
21897                 break;
21898
21899         case REG_BH:
21900 #if X86_4_8BIT_GPRS
21901                 *equiv++ = REG_BL;
21902 #endif
21903                 *equiv++ = REG_BX;
21904                 *equiv++ = REG_EBX;
21905                 break;
21906         case REG_CL:
21907 #if X86_4_8BIT_GPRS
21908                 *equiv++ = REG_CH;
21909 #endif
21910                 *equiv++ = REG_CX;
21911                 *equiv++ = REG_ECX;
21912                 break;
21913
21914         case REG_CH:
21915 #if X86_4_8BIT_GPRS
21916                 *equiv++ = REG_CL;
21917 #endif
21918                 *equiv++ = REG_CX;
21919                 *equiv++ = REG_ECX;
21920                 break;
21921         case REG_DL:
21922 #if X86_4_8BIT_GPRS
21923                 *equiv++ = REG_DH;
21924 #endif
21925                 *equiv++ = REG_DX;
21926                 *equiv++ = REG_EDX;
21927                 *equiv++ = REG_DXAX;
21928                 *equiv++ = REG_EDXEAX;
21929                 break;
21930         case REG_DH:
21931 #if X86_4_8BIT_GPRS
21932                 *equiv++ = REG_DL;
21933 #endif
21934                 *equiv++ = REG_DX;
21935                 *equiv++ = REG_EDX;
21936                 *equiv++ = REG_DXAX;
21937                 *equiv++ = REG_EDXEAX;
21938                 break;
21939         case REG_AX:
21940                 *equiv++ = REG_AL;
21941                 *equiv++ = REG_AH;
21942                 *equiv++ = REG_EAX;
21943                 *equiv++ = REG_DXAX;
21944                 *equiv++ = REG_EDXEAX;
21945                 break;
21946         case REG_BX:
21947                 *equiv++ = REG_BL;
21948                 *equiv++ = REG_BH;
21949                 *equiv++ = REG_EBX;
21950                 break;
21951         case REG_CX:  
21952                 *equiv++ = REG_CL;
21953                 *equiv++ = REG_CH;
21954                 *equiv++ = REG_ECX;
21955                 break;
21956         case REG_DX:  
21957                 *equiv++ = REG_DL;
21958                 *equiv++ = REG_DH;
21959                 *equiv++ = REG_EDX;
21960                 *equiv++ = REG_DXAX;
21961                 *equiv++ = REG_EDXEAX;
21962                 break;
21963         case REG_SI:  
21964                 *equiv++ = REG_ESI;
21965                 break;
21966         case REG_DI:
21967                 *equiv++ = REG_EDI;
21968                 break;
21969         case REG_BP:
21970                 *equiv++ = REG_EBP;
21971                 break;
21972         case REG_SP:
21973                 *equiv++ = REG_ESP;
21974                 break;
21975         case REG_EAX:
21976                 *equiv++ = REG_AL;
21977                 *equiv++ = REG_AH;
21978                 *equiv++ = REG_AX;
21979                 *equiv++ = REG_DXAX;
21980                 *equiv++ = REG_EDXEAX;
21981                 break;
21982         case REG_EBX:
21983                 *equiv++ = REG_BL;
21984                 *equiv++ = REG_BH;
21985                 *equiv++ = REG_BX;
21986                 break;
21987         case REG_ECX:
21988                 *equiv++ = REG_CL;
21989                 *equiv++ = REG_CH;
21990                 *equiv++ = REG_CX;
21991                 break;
21992         case REG_EDX:
21993                 *equiv++ = REG_DL;
21994                 *equiv++ = REG_DH;
21995                 *equiv++ = REG_DX;
21996                 *equiv++ = REG_DXAX;
21997                 *equiv++ = REG_EDXEAX;
21998                 break;
21999         case REG_ESI: 
22000                 *equiv++ = REG_SI;
22001                 break;
22002         case REG_EDI: 
22003                 *equiv++ = REG_DI;
22004                 break;
22005         case REG_EBP: 
22006                 *equiv++ = REG_BP;
22007                 break;
22008         case REG_ESP: 
22009                 *equiv++ = REG_SP;
22010                 break;
22011         case REG_DXAX: 
22012                 *equiv++ = REG_AL;
22013                 *equiv++ = REG_AH;
22014                 *equiv++ = REG_DL;
22015                 *equiv++ = REG_DH;
22016                 *equiv++ = REG_AX;
22017                 *equiv++ = REG_DX;
22018                 *equiv++ = REG_EAX;
22019                 *equiv++ = REG_EDX;
22020                 *equiv++ = REG_EDXEAX;
22021                 break;
22022         case REG_EDXEAX: 
22023                 *equiv++ = REG_AL;
22024                 *equiv++ = REG_AH;
22025                 *equiv++ = REG_DL;
22026                 *equiv++ = REG_DH;
22027                 *equiv++ = REG_AX;
22028                 *equiv++ = REG_DX;
22029                 *equiv++ = REG_EAX;
22030                 *equiv++ = REG_EDX;
22031                 *equiv++ = REG_DXAX;
22032                 break;
22033         }
22034         *equiv++ = REG_UNSET; 
22035 }
22036
22037 static unsigned arch_avail_mask(struct compile_state *state)
22038 {
22039         unsigned avail_mask;
22040         /* REGCM_GPR8 is not available */
22041         avail_mask = REGCM_GPR8_LO | REGCM_GPR16_8 | REGCM_GPR16 | 
22042                 REGCM_GPR32 | REGCM_GPR32_8 | 
22043                 REGCM_DIVIDEND32 | REGCM_DIVIDEND64 |
22044                 REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8 | REGCM_FLAGS;
22045         if (state->arch->features & X86_MMX_REGS) {
22046                 avail_mask |= REGCM_MMX;
22047         }
22048         if (state->arch->features & X86_XMM_REGS) {
22049                 avail_mask |= REGCM_XMM;
22050         }
22051         return avail_mask;
22052 }
22053
22054 static unsigned arch_regcm_normalize(struct compile_state *state, unsigned regcm)
22055 {
22056         unsigned mask, result;
22057         int class, class2;
22058         result = regcm;
22059
22060         for(class = 0, mask = 1; mask; mask <<= 1, class++) {
22061                 if ((result & mask) == 0) {
22062                         continue;
22063                 }
22064                 if (class > LAST_REGC) {
22065                         result &= ~mask;
22066                 }
22067                 for(class2 = 0; class2 <= LAST_REGC; class2++) {
22068                         if ((regcm_bound[class2].first >= regcm_bound[class].first) &&
22069                                 (regcm_bound[class2].last <= regcm_bound[class].last)) {
22070                                 result |= (1 << class2);
22071                         }
22072                 }
22073         }
22074         result &= arch_avail_mask(state);
22075         return result;
22076 }
22077
22078 static unsigned arch_regcm_reg_normalize(struct compile_state *state, unsigned regcm)
22079 {
22080         /* Like arch_regcm_normalize except immediate register classes are excluded */
22081         regcm = arch_regcm_normalize(state, regcm);
22082         /* Remove the immediate register classes */
22083         regcm &= ~(REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8);
22084         return regcm;
22085         
22086 }
22087
22088 static unsigned arch_reg_regcm(struct compile_state *state, int reg)
22089 {
22090         unsigned mask;
22091         int class;
22092         mask = 0;
22093         for(class = 0; class <= LAST_REGC; class++) {
22094                 if ((reg >= regcm_bound[class].first) &&
22095                         (reg <= regcm_bound[class].last)) {
22096                         mask |= (1 << class);
22097                 }
22098         }
22099         if (!mask) {
22100                 internal_error(state, 0, "reg %d not in any class", reg);
22101         }
22102         return mask;
22103 }
22104
22105 static struct reg_info arch_reg_constraint(
22106         struct compile_state *state, struct type *type, const char *constraint)
22107 {
22108         static const struct {
22109                 char class;
22110                 unsigned int mask;
22111                 unsigned int reg;
22112         } constraints[] = {
22113                 { 'r', REGCM_GPR32,   REG_UNSET },
22114                 { 'g', REGCM_GPR32,   REG_UNSET },
22115                 { 'p', REGCM_GPR32,   REG_UNSET },
22116                 { 'q', REGCM_GPR8_LO, REG_UNSET },
22117                 { 'Q', REGCM_GPR32_8, REG_UNSET },
22118                 { 'x', REGCM_XMM,     REG_UNSET },
22119                 { 'y', REGCM_MMX,     REG_UNSET },
22120                 { 'a', REGCM_GPR32,   REG_EAX },
22121                 { 'b', REGCM_GPR32,   REG_EBX },
22122                 { 'c', REGCM_GPR32,   REG_ECX },
22123                 { 'd', REGCM_GPR32,   REG_EDX },
22124                 { 'D', REGCM_GPR32,   REG_EDI },
22125                 { 'S', REGCM_GPR32,   REG_ESI },
22126                 { '\0', 0, REG_UNSET },
22127         };
22128         unsigned int regcm;
22129         unsigned int mask, reg;
22130         struct reg_info result;
22131         const char *ptr;
22132         regcm = arch_type_to_regcm(state, type);
22133         reg = REG_UNSET;
22134         mask = 0;
22135         for(ptr = constraint; *ptr; ptr++) {
22136                 int i;
22137                 if (*ptr ==  ' ') {
22138                         continue;
22139                 }
22140                 for(i = 0; constraints[i].class != '\0'; i++) {
22141                         if (constraints[i].class == *ptr) {
22142                                 break;
22143                         }
22144                 }
22145                 if (constraints[i].class == '\0') {
22146                         error(state, 0, "invalid register constraint ``%c''", *ptr);
22147                         break;
22148                 }
22149                 if ((constraints[i].mask & regcm) == 0) {
22150                         error(state, 0, "invalid register class %c specified",
22151                                 *ptr);
22152                 }
22153                 mask |= constraints[i].mask;
22154                 if (constraints[i].reg != REG_UNSET) {
22155                         if ((reg != REG_UNSET) && (reg != constraints[i].reg)) {
22156                                 error(state, 0, "Only one register may be specified");
22157                         }
22158                         reg = constraints[i].reg;
22159                 }
22160         }
22161         result.reg = reg;
22162         result.regcm = mask;
22163         return result;
22164 }
22165
22166 static struct reg_info arch_reg_clobber(
22167         struct compile_state *state, const char *clobber)
22168 {
22169         struct reg_info result;
22170         if (strcmp(clobber, "memory") == 0) {
22171                 result.reg = REG_UNSET;
22172                 result.regcm = 0;
22173         }
22174         else if (strcmp(clobber, "eax") == 0) {
22175                 result.reg = REG_EAX;
22176                 result.regcm = REGCM_GPR32;
22177         }
22178         else if (strcmp(clobber, "ebx") == 0) {
22179                 result.reg = REG_EBX;
22180                 result.regcm = REGCM_GPR32;
22181         }
22182         else if (strcmp(clobber, "ecx") == 0) {
22183                 result.reg = REG_ECX;
22184                 result.regcm = REGCM_GPR32;
22185         }
22186         else if (strcmp(clobber, "edx") == 0) {
22187                 result.reg = REG_EDX;
22188                 result.regcm = REGCM_GPR32;
22189         }
22190         else if (strcmp(clobber, "esi") == 0) {
22191                 result.reg = REG_ESI;
22192                 result.regcm = REGCM_GPR32;
22193         }
22194         else if (strcmp(clobber, "edi") == 0) {
22195                 result.reg = REG_EDI;
22196                 result.regcm = REGCM_GPR32;
22197         }
22198         else if (strcmp(clobber, "ebp") == 0) {
22199                 result.reg = REG_EBP;
22200                 result.regcm = REGCM_GPR32;
22201         }
22202         else if (strcmp(clobber, "esp") == 0) {
22203                 result.reg = REG_ESP;
22204                 result.regcm = REGCM_GPR32;
22205         }
22206         else if (strcmp(clobber, "cc") == 0) {
22207                 result.reg = REG_EFLAGS;
22208                 result.regcm = REGCM_FLAGS;
22209         }
22210         else if ((strncmp(clobber, "xmm", 3) == 0)  &&
22211                 octdigitp(clobber[3]) && (clobber[4] == '\0')) {
22212                 result.reg = REG_XMM0 + octdigval(clobber[3]);
22213                 result.regcm = REGCM_XMM;
22214         }
22215         else if ((strncmp(clobber, "mm", 2) == 0) &&
22216                 octdigitp(clobber[3]) && (clobber[4] == '\0')) {
22217                 result.reg = REG_MMX0 + octdigval(clobber[3]);
22218                 result.regcm = REGCM_MMX;
22219         }
22220         else {
22221                 error(state, 0, "unknown register name `%s' in asm",
22222                         clobber);
22223                 result.reg = REG_UNSET;
22224                 result.regcm = 0;
22225         }
22226         return result;
22227 }
22228
22229 static int do_select_reg(struct compile_state *state, 
22230         char *used, int reg, unsigned classes)
22231 {
22232         unsigned mask;
22233         if (used[reg]) {
22234                 return REG_UNSET;
22235         }
22236         mask = arch_reg_regcm(state, reg);
22237         return (classes & mask) ? reg : REG_UNSET;
22238 }
22239
22240 static int arch_select_free_register(
22241         struct compile_state *state, char *used, int classes)
22242 {
22243         /* Live ranges with the most neighbors are colored first.
22244          *
22245          * Generally it does not matter which colors are given
22246          * as the register allocator attempts to color live ranges
22247          * in an order where you are guaranteed not to run out of colors.
22248          *
22249          * Occasionally the register allocator cannot find an order
22250          * of register selection that will find a free color.  To
22251          * increase the odds the register allocator will work when
22252          * it guesses first give out registers from register classes
22253          * least likely to run out of registers.
22254          * 
22255          */
22256         int i, reg;
22257         reg = REG_UNSET;
22258         for(i = REGC_XMM_FIRST; (reg == REG_UNSET) && (i <= REGC_XMM_LAST); i++) {
22259                 reg = do_select_reg(state, used, i, classes);
22260         }
22261         for(i = REGC_MMX_FIRST; (reg == REG_UNSET) && (i <= REGC_MMX_LAST); i++) {
22262                 reg = do_select_reg(state, used, i, classes);
22263         }
22264         for(i = REGC_GPR32_LAST; (reg == REG_UNSET) && (i >= REGC_GPR32_FIRST); i--) {
22265                 reg = do_select_reg(state, used, i, classes);
22266         }
22267         for(i = REGC_GPR16_FIRST; (reg == REG_UNSET) && (i <= REGC_GPR16_LAST); i++) {
22268                 reg = do_select_reg(state, used, i, classes);
22269         }
22270         for(i = REGC_GPR8_FIRST; (reg == REG_UNSET) && (i <= REGC_GPR8_LAST); i++) {
22271                 reg = do_select_reg(state, used, i, classes);
22272         }
22273         for(i = REGC_GPR8_LO_FIRST; (reg == REG_UNSET) && (i <= REGC_GPR8_LO_LAST); i++) {
22274                 reg = do_select_reg(state, used, i, classes);
22275         }
22276         for(i = REGC_DIVIDEND32_FIRST; (reg == REG_UNSET) && (i <= REGC_DIVIDEND32_LAST); i++) {
22277                 reg = do_select_reg(state, used, i, classes);
22278         }
22279         for(i = REGC_DIVIDEND64_FIRST; (reg == REG_UNSET) && (i <= REGC_DIVIDEND64_LAST); i++) {
22280                 reg = do_select_reg(state, used, i, classes);
22281         }
22282         for(i = REGC_FLAGS_FIRST; (reg == REG_UNSET) && (i <= REGC_FLAGS_LAST); i++) {
22283                 reg = do_select_reg(state, used, i, classes);
22284         }
22285         return reg;
22286 }
22287
22288
22289 static unsigned arch_type_to_regcm(struct compile_state *state, struct type *type) 
22290 {
22291 #warning "FIXME force types smaller (if legal) before I get here"
22292         unsigned mask;
22293         mask = 0;
22294         switch(type->type & TYPE_MASK) {
22295         case TYPE_ARRAY:
22296         case TYPE_VOID: 
22297                 mask = 0; 
22298                 break;
22299         case TYPE_CHAR:
22300         case TYPE_UCHAR:
22301                 mask = REGCM_GPR8 | REGCM_GPR8_LO |
22302                         REGCM_GPR16 | REGCM_GPR16_8 | 
22303                         REGCM_GPR32 | REGCM_GPR32_8 |
22304                         REGCM_DIVIDEND32 | REGCM_DIVIDEND64 |
22305                         REGCM_MMX | REGCM_XMM |
22306                         REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8;
22307                 break;
22308         case TYPE_SHORT:
22309         case TYPE_USHORT:
22310                 mask =  REGCM_GPR16 | REGCM_GPR16_8 |
22311                         REGCM_GPR32 | REGCM_GPR32_8 |
22312                         REGCM_DIVIDEND32 | REGCM_DIVIDEND64 |
22313                         REGCM_MMX | REGCM_XMM |
22314                         REGCM_IMM32 | REGCM_IMM16;
22315                 break;
22316         case TYPE_ENUM:
22317         case TYPE_INT:
22318         case TYPE_UINT:
22319         case TYPE_LONG:
22320         case TYPE_ULONG:
22321         case TYPE_POINTER:
22322                 mask =  REGCM_GPR32 | REGCM_GPR32_8 |
22323                         REGCM_DIVIDEND32 | REGCM_DIVIDEND64 |
22324                         REGCM_MMX | REGCM_XMM |
22325                         REGCM_IMM32;
22326                 break;
22327         case TYPE_JOIN:
22328         case TYPE_UNION:
22329                 mask = arch_type_to_regcm(state, type->left);
22330                 break;
22331         case TYPE_OVERLAP:
22332                 mask = arch_type_to_regcm(state, type->left) &
22333                         arch_type_to_regcm(state, type->right);
22334                 break;
22335         case TYPE_BITFIELD:
22336                 mask = arch_type_to_regcm(state, type->left);
22337                 break;
22338         default:
22339                 fprintf(state->errout, "type: ");
22340                 name_of(state->errout, type);
22341                 fprintf(state->errout, "\n");
22342                 internal_error(state, 0, "no register class for type");
22343                 break;
22344         }
22345         mask = arch_regcm_normalize(state, mask);
22346         return mask;
22347 }
22348
22349 static int is_imm32(struct triple *imm)
22350 {
22351         return ((imm->op == OP_INTCONST) && (imm->u.cval <= 0xffffffffUL)) ||
22352                 (imm->op == OP_ADDRCONST);
22353         
22354 }
22355 static int is_imm16(struct triple *imm)
22356 {
22357         return ((imm->op == OP_INTCONST) && (imm->u.cval <= 0xffff));
22358 }
22359 static int is_imm8(struct triple *imm)
22360 {
22361         return ((imm->op == OP_INTCONST) && (imm->u.cval <= 0xff));
22362 }
22363
22364 static int get_imm32(struct triple *ins, struct triple **expr)
22365 {
22366         struct triple *imm;
22367         imm = *expr;
22368         while(imm->op == OP_COPY) {
22369                 imm = RHS(imm, 0);
22370         }
22371         if (!is_imm32(imm)) {
22372                 return 0;
22373         }
22374         unuse_triple(*expr, ins);
22375         use_triple(imm, ins);
22376         *expr = imm;
22377         return 1;
22378 }
22379
22380 static int get_imm8(struct triple *ins, struct triple **expr)
22381 {
22382         struct triple *imm;
22383         imm = *expr;
22384         while(imm->op == OP_COPY) {
22385                 imm = RHS(imm, 0);
22386         }
22387         if (!is_imm8(imm)) {
22388                 return 0;
22389         }
22390         unuse_triple(*expr, ins);
22391         use_triple(imm, ins);
22392         *expr = imm;
22393         return 1;
22394 }
22395
22396 #define TEMPLATE_NOP           0
22397 #define TEMPLATE_INTCONST8     1
22398 #define TEMPLATE_INTCONST32    2
22399 #define TEMPLATE_UNKNOWNVAL    3
22400 #define TEMPLATE_COPY8_REG     5
22401 #define TEMPLATE_COPY16_REG    6
22402 #define TEMPLATE_COPY32_REG    7
22403 #define TEMPLATE_COPY_IMM8     8
22404 #define TEMPLATE_COPY_IMM16    9
22405 #define TEMPLATE_COPY_IMM32   10
22406 #define TEMPLATE_PHI8         11
22407 #define TEMPLATE_PHI16        12
22408 #define TEMPLATE_PHI32        13
22409 #define TEMPLATE_STORE8       14
22410 #define TEMPLATE_STORE16      15
22411 #define TEMPLATE_STORE32      16
22412 #define TEMPLATE_LOAD8        17
22413 #define TEMPLATE_LOAD16       18
22414 #define TEMPLATE_LOAD32       19
22415 #define TEMPLATE_BINARY8_REG  20
22416 #define TEMPLATE_BINARY16_REG 21
22417 #define TEMPLATE_BINARY32_REG 22
22418 #define TEMPLATE_BINARY8_IMM  23
22419 #define TEMPLATE_BINARY16_IMM 24
22420 #define TEMPLATE_BINARY32_IMM 25
22421 #define TEMPLATE_SL8_CL       26
22422 #define TEMPLATE_SL16_CL      27
22423 #define TEMPLATE_SL32_CL      28
22424 #define TEMPLATE_SL8_IMM      29
22425 #define TEMPLATE_SL16_IMM     30
22426 #define TEMPLATE_SL32_IMM     31
22427 #define TEMPLATE_UNARY8       32
22428 #define TEMPLATE_UNARY16      33
22429 #define TEMPLATE_UNARY32      34
22430 #define TEMPLATE_CMP8_REG     35
22431 #define TEMPLATE_CMP16_REG    36
22432 #define TEMPLATE_CMP32_REG    37
22433 #define TEMPLATE_CMP8_IMM     38
22434 #define TEMPLATE_CMP16_IMM    39
22435 #define TEMPLATE_CMP32_IMM    40
22436 #define TEMPLATE_TEST8        41
22437 #define TEMPLATE_TEST16       42
22438 #define TEMPLATE_TEST32       43
22439 #define TEMPLATE_SET          44
22440 #define TEMPLATE_JMP          45
22441 #define TEMPLATE_RET          46
22442 #define TEMPLATE_INB_DX       47
22443 #define TEMPLATE_INB_IMM      48
22444 #define TEMPLATE_INW_DX       49
22445 #define TEMPLATE_INW_IMM      50
22446 #define TEMPLATE_INL_DX       51
22447 #define TEMPLATE_INL_IMM      52
22448 #define TEMPLATE_OUTB_DX      53
22449 #define TEMPLATE_OUTB_IMM     54
22450 #define TEMPLATE_OUTW_DX      55
22451 #define TEMPLATE_OUTW_IMM     56
22452 #define TEMPLATE_OUTL_DX      57
22453 #define TEMPLATE_OUTL_IMM     58
22454 #define TEMPLATE_BSF          59
22455 #define TEMPLATE_RDMSR        60
22456 #define TEMPLATE_WRMSR        61
22457 #define TEMPLATE_UMUL8        62
22458 #define TEMPLATE_UMUL16       63
22459 #define TEMPLATE_UMUL32       64
22460 #define TEMPLATE_DIV8         65
22461 #define TEMPLATE_DIV16        66
22462 #define TEMPLATE_DIV32        67
22463 #define LAST_TEMPLATE       TEMPLATE_DIV32
22464 #if LAST_TEMPLATE >= MAX_TEMPLATES
22465 #error "MAX_TEMPLATES to low"
22466 #endif
22467
22468 #define COPY8_REGCM     (REGCM_DIVIDEND64 | REGCM_DIVIDEND32 | REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO | REGCM_MMX | REGCM_XMM)
22469 #define COPY16_REGCM    (REGCM_DIVIDEND64 | REGCM_DIVIDEND32 | REGCM_GPR32 | REGCM_GPR16 | REGCM_MMX | REGCM_XMM)  
22470 #define COPY32_REGCM    (REGCM_DIVIDEND64 | REGCM_DIVIDEND32 | REGCM_GPR32 | REGCM_MMX | REGCM_XMM)
22471
22472
22473 static struct ins_template templates[] = {
22474         [TEMPLATE_NOP]      = {
22475                 .lhs = { 
22476                         [ 0] = { REG_UNNEEDED, REGCM_IMMALL },
22477                         [ 1] = { REG_UNNEEDED, REGCM_IMMALL },
22478                         [ 2] = { REG_UNNEEDED, REGCM_IMMALL },
22479                         [ 3] = { REG_UNNEEDED, REGCM_IMMALL },
22480                         [ 4] = { REG_UNNEEDED, REGCM_IMMALL },
22481                         [ 5] = { REG_UNNEEDED, REGCM_IMMALL },
22482                         [ 6] = { REG_UNNEEDED, REGCM_IMMALL },
22483                         [ 7] = { REG_UNNEEDED, REGCM_IMMALL },
22484                         [ 8] = { REG_UNNEEDED, REGCM_IMMALL },
22485                         [ 9] = { REG_UNNEEDED, REGCM_IMMALL },
22486                         [10] = { REG_UNNEEDED, REGCM_IMMALL },
22487                         [11] = { REG_UNNEEDED, REGCM_IMMALL },
22488                         [12] = { REG_UNNEEDED, REGCM_IMMALL },
22489                         [13] = { REG_UNNEEDED, REGCM_IMMALL },
22490                         [14] = { REG_UNNEEDED, REGCM_IMMALL },
22491                         [15] = { REG_UNNEEDED, REGCM_IMMALL },
22492                         [16] = { REG_UNNEEDED, REGCM_IMMALL },
22493                         [17] = { REG_UNNEEDED, REGCM_IMMALL },
22494                         [18] = { REG_UNNEEDED, REGCM_IMMALL },
22495                         [19] = { REG_UNNEEDED, REGCM_IMMALL },
22496                         [20] = { REG_UNNEEDED, REGCM_IMMALL },
22497                         [21] = { REG_UNNEEDED, REGCM_IMMALL },
22498                         [22] = { REG_UNNEEDED, REGCM_IMMALL },
22499                         [23] = { REG_UNNEEDED, REGCM_IMMALL },
22500                         [24] = { REG_UNNEEDED, REGCM_IMMALL },
22501                         [25] = { REG_UNNEEDED, REGCM_IMMALL },
22502                         [26] = { REG_UNNEEDED, REGCM_IMMALL },
22503                         [27] = { REG_UNNEEDED, REGCM_IMMALL },
22504                         [28] = { REG_UNNEEDED, REGCM_IMMALL },
22505                         [29] = { REG_UNNEEDED, REGCM_IMMALL },
22506                         [30] = { REG_UNNEEDED, REGCM_IMMALL },
22507                         [31] = { REG_UNNEEDED, REGCM_IMMALL },
22508                         [32] = { REG_UNNEEDED, REGCM_IMMALL },
22509                         [33] = { REG_UNNEEDED, REGCM_IMMALL },
22510                         [34] = { REG_UNNEEDED, REGCM_IMMALL },
22511                         [35] = { REG_UNNEEDED, REGCM_IMMALL },
22512                         [36] = { REG_UNNEEDED, REGCM_IMMALL },
22513                         [37] = { REG_UNNEEDED, REGCM_IMMALL },
22514                         [38] = { REG_UNNEEDED, REGCM_IMMALL },
22515                         [39] = { REG_UNNEEDED, REGCM_IMMALL },
22516                         [40] = { REG_UNNEEDED, REGCM_IMMALL },
22517                         [41] = { REG_UNNEEDED, REGCM_IMMALL },
22518                         [42] = { REG_UNNEEDED, REGCM_IMMALL },
22519                         [43] = { REG_UNNEEDED, REGCM_IMMALL },
22520                         [44] = { REG_UNNEEDED, REGCM_IMMALL },
22521                         [45] = { REG_UNNEEDED, REGCM_IMMALL },
22522                         [46] = { REG_UNNEEDED, REGCM_IMMALL },
22523                         [47] = { REG_UNNEEDED, REGCM_IMMALL },
22524                         [48] = { REG_UNNEEDED, REGCM_IMMALL },
22525                         [49] = { REG_UNNEEDED, REGCM_IMMALL },
22526                         [50] = { REG_UNNEEDED, REGCM_IMMALL },
22527                         [51] = { REG_UNNEEDED, REGCM_IMMALL },
22528                         [52] = { REG_UNNEEDED, REGCM_IMMALL },
22529                         [53] = { REG_UNNEEDED, REGCM_IMMALL },
22530                         [54] = { REG_UNNEEDED, REGCM_IMMALL },
22531                         [55] = { REG_UNNEEDED, REGCM_IMMALL },
22532                         [56] = { REG_UNNEEDED, REGCM_IMMALL },
22533                         [57] = { REG_UNNEEDED, REGCM_IMMALL },
22534                         [58] = { REG_UNNEEDED, REGCM_IMMALL },
22535                         [59] = { REG_UNNEEDED, REGCM_IMMALL },
22536                         [60] = { REG_UNNEEDED, REGCM_IMMALL },
22537                         [61] = { REG_UNNEEDED, REGCM_IMMALL },
22538                         [62] = { REG_UNNEEDED, REGCM_IMMALL },
22539                         [63] = { REG_UNNEEDED, REGCM_IMMALL },
22540                 },
22541         },
22542         [TEMPLATE_INTCONST8] = { 
22543                 .lhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
22544         },
22545         [TEMPLATE_INTCONST32] = { 
22546                 .lhs = { [0] = { REG_UNNEEDED, REGCM_IMM32 } },
22547         },
22548         [TEMPLATE_UNKNOWNVAL] = {
22549                 .lhs = { [0] = { REG_UNSET, COPY32_REGCM } },
22550         },
22551         [TEMPLATE_COPY8_REG] = {
22552                 .lhs = { [0] = { REG_UNSET, COPY8_REGCM } },
22553                 .rhs = { [0] = { REG_UNSET, COPY8_REGCM }  },
22554         },
22555         [TEMPLATE_COPY16_REG] = {
22556                 .lhs = { [0] = { REG_UNSET, COPY16_REGCM } },
22557                 .rhs = { [0] = { REG_UNSET, COPY16_REGCM }  },
22558         },
22559         [TEMPLATE_COPY32_REG] = {
22560                 .lhs = { [0] = { REG_UNSET, COPY32_REGCM } },
22561                 .rhs = { [0] = { REG_UNSET, COPY32_REGCM }  },
22562         },
22563         [TEMPLATE_COPY_IMM8] = {
22564                 .lhs = { [0] = { REG_UNSET, COPY8_REGCM } },
22565                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
22566         },
22567         [TEMPLATE_COPY_IMM16] = {
22568                 .lhs = { [0] = { REG_UNSET, COPY16_REGCM } },
22569                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM16 | REGCM_IMM8 } },
22570         },
22571         [TEMPLATE_COPY_IMM32] = {
22572                 .lhs = { [0] = { REG_UNSET, COPY32_REGCM } },
22573                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8 } },
22574         },
22575         [TEMPLATE_PHI8] = { 
22576                 .lhs = { [0] = { REG_VIRT0, COPY8_REGCM } },
22577                 .rhs = { [0] = { REG_VIRT0, COPY8_REGCM } },
22578         },
22579         [TEMPLATE_PHI16] = { 
22580                 .lhs = { [0] = { REG_VIRT0, COPY16_REGCM } },
22581                 .rhs = { [0] = { REG_VIRT0, COPY16_REGCM } }, 
22582         },
22583         [TEMPLATE_PHI32] = { 
22584                 .lhs = { [0] = { REG_VIRT0, COPY32_REGCM } },
22585                 .rhs = { [0] = { REG_VIRT0, COPY32_REGCM } }, 
22586         },
22587         [TEMPLATE_STORE8] = {
22588                 .rhs = { 
22589                         [0] = { REG_UNSET, REGCM_GPR32 },
22590                         [1] = { REG_UNSET, REGCM_GPR8_LO },
22591                 },
22592         },
22593         [TEMPLATE_STORE16] = {
22594                 .rhs = { 
22595                         [0] = { REG_UNSET, REGCM_GPR32 },
22596                         [1] = { REG_UNSET, REGCM_GPR16 },
22597                 },
22598         },
22599         [TEMPLATE_STORE32] = {
22600                 .rhs = { 
22601                         [0] = { REG_UNSET, REGCM_GPR32 },
22602                         [1] = { REG_UNSET, REGCM_GPR32 },
22603                 },
22604         },
22605         [TEMPLATE_LOAD8] = {
22606                 .lhs = { [0] = { REG_UNSET, REGCM_GPR8_LO } },
22607                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
22608         },
22609         [TEMPLATE_LOAD16] = {
22610                 .lhs = { [0] = { REG_UNSET, REGCM_GPR16 } },
22611                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
22612         },
22613         [TEMPLATE_LOAD32] = {
22614                 .lhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
22615                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
22616         },
22617         [TEMPLATE_BINARY8_REG] = {
22618                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
22619                 .rhs = { 
22620                         [0] = { REG_VIRT0, REGCM_GPR8_LO },
22621                         [1] = { REG_UNSET, REGCM_GPR8_LO },
22622                 },
22623         },
22624         [TEMPLATE_BINARY16_REG] = {
22625                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
22626                 .rhs = { 
22627                         [0] = { REG_VIRT0, REGCM_GPR16 },
22628                         [1] = { REG_UNSET, REGCM_GPR16 },
22629                 },
22630         },
22631         [TEMPLATE_BINARY32_REG] = {
22632                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
22633                 .rhs = { 
22634                         [0] = { REG_VIRT0, REGCM_GPR32 },
22635                         [1] = { REG_UNSET, REGCM_GPR32 },
22636                 },
22637         },
22638         [TEMPLATE_BINARY8_IMM] = {
22639                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
22640                 .rhs = { 
22641                         [0] = { REG_VIRT0,    REGCM_GPR8_LO },
22642                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
22643                 },
22644         },
22645         [TEMPLATE_BINARY16_IMM] = {
22646                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
22647                 .rhs = { 
22648                         [0] = { REG_VIRT0,    REGCM_GPR16 },
22649                         [1] = { REG_UNNEEDED, REGCM_IMM16 },
22650                 },
22651         },
22652         [TEMPLATE_BINARY32_IMM] = {
22653                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
22654                 .rhs = { 
22655                         [0] = { REG_VIRT0,    REGCM_GPR32 },
22656                         [1] = { REG_UNNEEDED, REGCM_IMM32 },
22657                 },
22658         },
22659         [TEMPLATE_SL8_CL] = {
22660                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
22661                 .rhs = { 
22662                         [0] = { REG_VIRT0, REGCM_GPR8_LO },
22663                         [1] = { REG_CL, REGCM_GPR8_LO },
22664                 },
22665         },
22666         [TEMPLATE_SL16_CL] = {
22667                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
22668                 .rhs = { 
22669                         [0] = { REG_VIRT0, REGCM_GPR16 },
22670                         [1] = { REG_CL, REGCM_GPR8_LO },
22671                 },
22672         },
22673         [TEMPLATE_SL32_CL] = {
22674                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
22675                 .rhs = { 
22676                         [0] = { REG_VIRT0, REGCM_GPR32 },
22677                         [1] = { REG_CL, REGCM_GPR8_LO },
22678                 },
22679         },
22680         [TEMPLATE_SL8_IMM] = {
22681                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
22682                 .rhs = { 
22683                         [0] = { REG_VIRT0,    REGCM_GPR8_LO },
22684                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
22685                 },
22686         },
22687         [TEMPLATE_SL16_IMM] = {
22688                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
22689                 .rhs = { 
22690                         [0] = { REG_VIRT0,    REGCM_GPR16 },
22691                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
22692                 },
22693         },
22694         [TEMPLATE_SL32_IMM] = {
22695                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
22696                 .rhs = { 
22697                         [0] = { REG_VIRT0,    REGCM_GPR32 },
22698                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
22699                 },
22700         },
22701         [TEMPLATE_UNARY8] = {
22702                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
22703                 .rhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
22704         },
22705         [TEMPLATE_UNARY16] = {
22706                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
22707                 .rhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
22708         },
22709         [TEMPLATE_UNARY32] = {
22710                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
22711                 .rhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
22712         },
22713         [TEMPLATE_CMP8_REG] = {
22714                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22715                 .rhs = {
22716                         [0] = { REG_UNSET, REGCM_GPR8_LO },
22717                         [1] = { REG_UNSET, REGCM_GPR8_LO },
22718                 },
22719         },
22720         [TEMPLATE_CMP16_REG] = {
22721                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22722                 .rhs = {
22723                         [0] = { REG_UNSET, REGCM_GPR16 },
22724                         [1] = { REG_UNSET, REGCM_GPR16 },
22725                 },
22726         },
22727         [TEMPLATE_CMP32_REG] = {
22728                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22729                 .rhs = {
22730                         [0] = { REG_UNSET, REGCM_GPR32 },
22731                         [1] = { REG_UNSET, REGCM_GPR32 },
22732                 },
22733         },
22734         [TEMPLATE_CMP8_IMM] = {
22735                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22736                 .rhs = {
22737                         [0] = { REG_UNSET, REGCM_GPR8_LO },
22738                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
22739                 },
22740         },
22741         [TEMPLATE_CMP16_IMM] = {
22742                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22743                 .rhs = {
22744                         [0] = { REG_UNSET, REGCM_GPR16 },
22745                         [1] = { REG_UNNEEDED, REGCM_IMM16 },
22746                 },
22747         },
22748         [TEMPLATE_CMP32_IMM] = {
22749                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22750                 .rhs = {
22751                         [0] = { REG_UNSET, REGCM_GPR32 },
22752                         [1] = { REG_UNNEEDED, REGCM_IMM32 },
22753                 },
22754         },
22755         [TEMPLATE_TEST8] = {
22756                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22757                 .rhs = { [0] = { REG_UNSET, REGCM_GPR8_LO } },
22758         },
22759         [TEMPLATE_TEST16] = {
22760                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22761                 .rhs = { [0] = { REG_UNSET, REGCM_GPR16 } },
22762         },
22763         [TEMPLATE_TEST32] = {
22764                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22765                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
22766         },
22767         [TEMPLATE_SET] = {
22768                 .lhs = { [0] = { REG_UNSET, REGCM_GPR8_LO } },
22769                 .rhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22770         },
22771         [TEMPLATE_JMP] = {
22772                 .rhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22773         },
22774         [TEMPLATE_RET] = {
22775                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
22776         },
22777         [TEMPLATE_INB_DX] = {
22778                 .lhs = { [0] = { REG_AL,  REGCM_GPR8_LO } },  
22779                 .rhs = { [0] = { REG_DX, REGCM_GPR16 } },
22780         },
22781         [TEMPLATE_INB_IMM] = {
22782                 .lhs = { [0] = { REG_AL,  REGCM_GPR8_LO } },  
22783                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
22784         },
22785         [TEMPLATE_INW_DX]  = { 
22786                 .lhs = { [0] = { REG_AX,  REGCM_GPR16 } }, 
22787                 .rhs = { [0] = { REG_DX, REGCM_GPR16 } },
22788         },
22789         [TEMPLATE_INW_IMM] = { 
22790                 .lhs = { [0] = { REG_AX,  REGCM_GPR16 } }, 
22791                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
22792         },
22793         [TEMPLATE_INL_DX]  = {
22794                 .lhs = { [0] = { REG_EAX, REGCM_GPR32 } },
22795                 .rhs = { [0] = { REG_DX, REGCM_GPR16 } },
22796         },
22797         [TEMPLATE_INL_IMM] = {
22798                 .lhs = { [0] = { REG_EAX, REGCM_GPR32 } },
22799                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
22800         },
22801         [TEMPLATE_OUTB_DX] = { 
22802                 .rhs = {
22803                         [0] = { REG_AL,  REGCM_GPR8_LO },
22804                         [1] = { REG_DX, REGCM_GPR16 },
22805                 },
22806         },
22807         [TEMPLATE_OUTB_IMM] = { 
22808                 .rhs = {
22809                         [0] = { REG_AL,  REGCM_GPR8_LO },  
22810                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
22811                 },
22812         },
22813         [TEMPLATE_OUTW_DX] = { 
22814                 .rhs = {
22815                         [0] = { REG_AX,  REGCM_GPR16 },
22816                         [1] = { REG_DX, REGCM_GPR16 },
22817                 },
22818         },
22819         [TEMPLATE_OUTW_IMM] = {
22820                 .rhs = {
22821                         [0] = { REG_AX,  REGCM_GPR16 }, 
22822                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
22823                 },
22824         },
22825         [TEMPLATE_OUTL_DX] = { 
22826                 .rhs = {
22827                         [0] = { REG_EAX, REGCM_GPR32 },
22828                         [1] = { REG_DX, REGCM_GPR16 },
22829                 },
22830         },
22831         [TEMPLATE_OUTL_IMM] = { 
22832                 .rhs = {
22833                         [0] = { REG_EAX, REGCM_GPR32 }, 
22834                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
22835                 },
22836         },
22837         [TEMPLATE_BSF] = {
22838                 .lhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
22839                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
22840         },
22841         [TEMPLATE_RDMSR] = {
22842                 .lhs = { 
22843                         [0] = { REG_EAX, REGCM_GPR32 },
22844                         [1] = { REG_EDX, REGCM_GPR32 },
22845                 },
22846                 .rhs = { [0] = { REG_ECX, REGCM_GPR32 } },
22847         },
22848         [TEMPLATE_WRMSR] = {
22849                 .rhs = {
22850                         [0] = { REG_ECX, REGCM_GPR32 },
22851                         [1] = { REG_EAX, REGCM_GPR32 },
22852                         [2] = { REG_EDX, REGCM_GPR32 },
22853                 },
22854         },
22855         [TEMPLATE_UMUL8] = {
22856                 .lhs = { [0] = { REG_AX, REGCM_GPR16 } },
22857                 .rhs = { 
22858                         [0] = { REG_AL, REGCM_GPR8_LO },
22859                         [1] = { REG_UNSET, REGCM_GPR8_LO },
22860                 },
22861         },
22862         [TEMPLATE_UMUL16] = {
22863                 .lhs = { [0] = { REG_DXAX, REGCM_DIVIDEND32 } },
22864                 .rhs = { 
22865                         [0] = { REG_AX, REGCM_GPR16 },
22866                         [1] = { REG_UNSET, REGCM_GPR16 },
22867                 },
22868         },
22869         [TEMPLATE_UMUL32] = {
22870                 .lhs = { [0] = { REG_EDXEAX, REGCM_DIVIDEND64 } },
22871                 .rhs = { 
22872                         [0] = { REG_EAX, REGCM_GPR32 },
22873                         [1] = { REG_UNSET, REGCM_GPR32 },
22874                 },
22875         },
22876         [TEMPLATE_DIV8] = {
22877                 .lhs = { 
22878                         [0] = { REG_AL, REGCM_GPR8_LO },
22879                         [1] = { REG_AH, REGCM_GPR8 },
22880                 },
22881                 .rhs = {
22882                         [0] = { REG_AX, REGCM_GPR16 },
22883                         [1] = { REG_UNSET, REGCM_GPR8_LO },
22884                 },
22885         },
22886         [TEMPLATE_DIV16] = {
22887                 .lhs = { 
22888                         [0] = { REG_AX, REGCM_GPR16 },
22889                         [1] = { REG_DX, REGCM_GPR16 },
22890                 },
22891                 .rhs = {
22892                         [0] = { REG_DXAX, REGCM_DIVIDEND32 },
22893                         [1] = { REG_UNSET, REGCM_GPR16 },
22894                 },
22895         },
22896         [TEMPLATE_DIV32] = {
22897                 .lhs = { 
22898                         [0] = { REG_EAX, REGCM_GPR32 },
22899                         [1] = { REG_EDX, REGCM_GPR32 },
22900                 },
22901                 .rhs = {
22902                         [0] = { REG_EDXEAX, REGCM_DIVIDEND64 },
22903                         [1] = { REG_UNSET, REGCM_GPR32 },
22904                 },
22905         },
22906 };
22907
22908 static void fixup_branch(struct compile_state *state,
22909         struct triple *branch, int jmp_op, int cmp_op, struct type *cmp_type,
22910         struct triple *left, struct triple *right)
22911 {
22912         struct triple *test;
22913         if (!left) {
22914                 internal_error(state, branch, "no branch test?");
22915         }
22916         test = pre_triple(state, branch,
22917                 cmp_op, cmp_type, left, right);
22918         test->template_id = TEMPLATE_TEST32; 
22919         if (cmp_op == OP_CMP) {
22920                 test->template_id = TEMPLATE_CMP32_REG;
22921                 if (get_imm32(test, &RHS(test, 1))) {
22922                         test->template_id = TEMPLATE_CMP32_IMM;
22923                 }
22924         }
22925         use_triple(RHS(test, 0), test);
22926         use_triple(RHS(test, 1), test);
22927         unuse_triple(RHS(branch, 0), branch);
22928         RHS(branch, 0) = test;
22929         branch->op = jmp_op;
22930         branch->template_id = TEMPLATE_JMP;
22931         use_triple(RHS(branch, 0), branch);
22932 }
22933
22934 static void fixup_branches(struct compile_state *state,
22935         struct triple *cmp, struct triple *use, int jmp_op)
22936 {
22937         struct triple_set *entry, *next;
22938         for(entry = use->use; entry; entry = next) {
22939                 next = entry->next;
22940                 if (entry->member->op == OP_COPY) {
22941                         fixup_branches(state, cmp, entry->member, jmp_op);
22942                 }
22943                 else if (entry->member->op == OP_CBRANCH) {
22944                         struct triple *branch;
22945                         struct triple *left, *right;
22946                         left = right = 0;
22947                         left = RHS(cmp, 0);
22948                         if (cmp->rhs > 1) {
22949                                 right = RHS(cmp, 1);
22950                         }
22951                         branch = entry->member;
22952                         fixup_branch(state, branch, jmp_op, 
22953                                 cmp->op, cmp->type, left, right);
22954                 }
22955         }
22956 }
22957
22958 static void bool_cmp(struct compile_state *state, 
22959         struct triple *ins, int cmp_op, int jmp_op, int set_op)
22960 {
22961         struct triple_set *entry, *next;
22962         struct triple *set, *convert;
22963
22964         /* Put a barrier up before the cmp which preceeds the
22965          * copy instruction.  If a set actually occurs this gives
22966          * us a chance to move variables in registers out of the way.
22967          */
22968
22969         /* Modify the comparison operator */
22970         ins->op = cmp_op;
22971         ins->template_id = TEMPLATE_TEST32;
22972         if (cmp_op == OP_CMP) {
22973                 ins->template_id = TEMPLATE_CMP32_REG;
22974                 if (get_imm32(ins, &RHS(ins, 1))) {
22975                         ins->template_id =  TEMPLATE_CMP32_IMM;
22976                 }
22977         }
22978         /* Generate the instruction sequence that will transform the
22979          * result of the comparison into a logical value.
22980          */
22981         set = post_triple(state, ins, set_op, &uchar_type, ins, 0);
22982         use_triple(ins, set);
22983         set->template_id = TEMPLATE_SET;
22984
22985         convert = set;
22986         if (!equiv_types(ins->type, set->type)) {
22987                 convert = post_triple(state, set, OP_CONVERT, ins->type, set, 0);
22988                 use_triple(set, convert);
22989                 convert->template_id = TEMPLATE_COPY32_REG;
22990         }
22991
22992         for(entry = ins->use; entry; entry = next) {
22993                 next = entry->next;
22994                 if (entry->member == set) {
22995                         continue;
22996                 }
22997                 replace_rhs_use(state, ins, convert, entry->member);
22998         }
22999         fixup_branches(state, ins, convert, jmp_op);
23000 }
23001
23002 struct reg_info arch_reg_lhs(struct compile_state *state, struct triple *ins, int index)
23003 {
23004         struct ins_template *template;
23005         struct reg_info result;
23006         int zlhs;
23007         if (ins->op == OP_PIECE) {
23008                 index = ins->u.cval;
23009                 ins = MISC(ins, 0);
23010         }
23011         zlhs = ins->lhs;
23012         if (triple_is_def(state, ins)) {
23013                 zlhs = 1;
23014         }
23015         if (index >= zlhs) {
23016                 internal_error(state, ins, "index %d out of range for %s",
23017                         index, tops(ins->op));
23018         }
23019         switch(ins->op) {
23020         case OP_ASM:
23021                 template = &ins->u.ainfo->tmpl;
23022                 break;
23023         default:
23024                 if (ins->template_id > LAST_TEMPLATE) {
23025                         internal_error(state, ins, "bad template number %d", 
23026                                 ins->template_id);
23027                 }
23028                 template = &templates[ins->template_id];
23029                 break;
23030         }
23031         result = template->lhs[index];
23032         result.regcm = arch_regcm_normalize(state, result.regcm);
23033         if (result.reg != REG_UNNEEDED) {
23034                 result.regcm &= ~(REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8);
23035         }
23036         if (result.regcm == 0) {
23037                 internal_error(state, ins, "lhs %d regcm == 0", index);
23038         }
23039         return result;
23040 }
23041
23042 struct reg_info arch_reg_rhs(struct compile_state *state, struct triple *ins, int index)
23043 {
23044         struct reg_info result;
23045         struct ins_template *template;
23046         if ((index > ins->rhs) ||
23047                 (ins->op == OP_PIECE)) {
23048                 internal_error(state, ins, "index %d out of range for %s\n",
23049                         index, tops(ins->op));
23050         }
23051         switch(ins->op) {
23052         case OP_ASM:
23053                 template = &ins->u.ainfo->tmpl;
23054                 break;
23055         case OP_PHI:
23056                 index = 0;
23057                 /* Fall through */
23058         default:
23059                 if (ins->template_id > LAST_TEMPLATE) {
23060                         internal_error(state, ins, "bad template number %d", 
23061                                 ins->template_id);
23062                 }
23063                 template = &templates[ins->template_id];
23064                 break;
23065         }
23066         result = template->rhs[index];
23067         result.regcm = arch_regcm_normalize(state, result.regcm);
23068         if (result.regcm == 0) {
23069                 internal_error(state, ins, "rhs %d regcm == 0", index);
23070         }
23071         return result;
23072 }
23073
23074 static struct triple *mod_div(struct compile_state *state,
23075         struct triple *ins, int div_op, int index)
23076 {
23077         struct triple *div, *piece0, *piece1;
23078         
23079         /* Generate the appropriate division instruction */
23080         div = post_triple(state, ins, div_op, ins->type, 0, 0);
23081         RHS(div, 0) = RHS(ins, 0);
23082         RHS(div, 1) = RHS(ins, 1);
23083         piece0 = LHS(div, 0);
23084         piece1 = LHS(div, 1);
23085         div->template_id  = TEMPLATE_DIV32;
23086         use_triple(RHS(div, 0), div);
23087         use_triple(RHS(div, 1), div);
23088         use_triple(LHS(div, 0), div);
23089         use_triple(LHS(div, 1), div);
23090
23091         /* Replate uses of ins with the appropriate piece of the div */
23092         propogate_use(state, ins, LHS(div, index));
23093         release_triple(state, ins);
23094
23095         /* Return the address of the next instruction */
23096         return piece1->next;
23097 }
23098
23099 static int noop_adecl(struct triple *adecl)
23100 {
23101         struct triple_set *use;
23102         /* It's a noop if it doesn't specify stoorage */
23103         if (adecl->lhs == 0) {
23104                 return 1;
23105         }
23106         /* Is the adecl used? If not it's a noop */
23107         for(use = adecl->use; use ; use = use->next) {
23108                 if ((use->member->op != OP_PIECE) ||
23109                         (MISC(use->member, 0) != adecl)) {
23110                         return 0;
23111                 }
23112         }
23113         return 1;
23114 }
23115
23116 static struct triple *x86_deposit(struct compile_state *state, struct triple *ins)
23117 {
23118         struct triple *mask, *nmask, *shift;
23119         struct triple *val, *val_mask, *val_shift;
23120         struct triple *targ, *targ_mask;
23121         struct triple *new;
23122         ulong_t the_mask, the_nmask;
23123
23124         targ = RHS(ins, 0);
23125         val = RHS(ins, 1);
23126
23127         /* Get constant for the mask value */
23128         the_mask = 1;
23129         the_mask <<= ins->u.bitfield.size;
23130         the_mask -= 1;
23131         the_mask <<= ins->u.bitfield.offset;
23132         mask = pre_triple(state, ins, OP_INTCONST, &uint_type, 0, 0);
23133         mask->u.cval = the_mask;
23134
23135         /* Get the inverted mask value */
23136         the_nmask = ~the_mask;
23137         nmask = pre_triple(state, ins, OP_INTCONST, &uint_type, 0, 0);
23138         nmask->u.cval = the_nmask;
23139
23140         /* Get constant for the shift value */
23141         shift = pre_triple(state, ins, OP_INTCONST, &uint_type, 0, 0);
23142         shift->u.cval = ins->u.bitfield.offset;
23143
23144         /* Shift and mask the source value */
23145         val_shift = val;
23146         if (shift->u.cval != 0) {
23147                 val_shift = pre_triple(state, ins, OP_SL, val->type, val, shift);
23148                 use_triple(val, val_shift);
23149                 use_triple(shift, val_shift);
23150         }
23151         val_mask = val_shift;
23152         if (is_signed(val->type)) {
23153                 val_mask = pre_triple(state, ins, OP_AND, val->type, val_shift, mask);
23154                 use_triple(val_shift, val_mask);
23155                 use_triple(mask, val_mask);
23156         }
23157
23158         /* Mask the target value */
23159         targ_mask = pre_triple(state, ins, OP_AND, targ->type, targ, nmask);
23160         use_triple(targ, targ_mask);
23161         use_triple(nmask, targ_mask);
23162
23163         /* Now combined them together */
23164         new = pre_triple(state, ins, OP_OR, targ->type, targ_mask, val_mask);
23165         use_triple(targ_mask, new);
23166         use_triple(val_mask, new);
23167
23168         /* Move all of the users over to the new expression */
23169         propogate_use(state, ins, new);
23170
23171         /* Delete the original triple */
23172         release_triple(state, ins);
23173
23174         /* Restart the transformation at mask */
23175         return mask;
23176 }
23177
23178 static struct triple *x86_extract(struct compile_state *state, struct triple *ins)
23179 {
23180         struct triple *mask, *shift;
23181         struct triple *val, *val_mask, *val_shift;
23182         ulong_t the_mask;
23183
23184         val = RHS(ins, 0);
23185
23186         /* Get constant for the mask value */
23187         the_mask = 1;
23188         the_mask <<= ins->u.bitfield.size;
23189         the_mask -= 1;
23190         mask = pre_triple(state, ins, OP_INTCONST, &int_type, 0, 0);
23191         mask->u.cval = the_mask;
23192
23193         /* Get constant for the right shift value */
23194         shift = pre_triple(state, ins, OP_INTCONST, &int_type, 0, 0);
23195         shift->u.cval = ins->u.bitfield.offset;
23196
23197         /* Shift arithmetic right, to correct the sign */
23198         val_shift = val;
23199         if (shift->u.cval != 0) {
23200                 int op;
23201                 if (ins->op == OP_SEXTRACT) {
23202                         op = OP_SSR;
23203                 } else {
23204                         op = OP_USR;
23205                 }
23206                 val_shift = pre_triple(state, ins, op, val->type, val, shift);
23207                 use_triple(val, val_shift);
23208                 use_triple(shift, val_shift);
23209         }
23210
23211         /* Finally mask the value */
23212         val_mask = pre_triple(state, ins, OP_AND, ins->type, val_shift, mask);
23213         use_triple(val_shift, val_mask);
23214         use_triple(mask,      val_mask);
23215
23216         /* Move all of the users over to the new expression */
23217         propogate_use(state, ins, val_mask);
23218
23219         /* Release the original instruction */
23220         release_triple(state, ins);
23221
23222         return mask;
23223
23224 }
23225
23226 static struct triple *transform_to_arch_instruction(
23227         struct compile_state *state, struct triple *ins)
23228 {
23229         /* Transform from generic 3 address instructions
23230          * to archtecture specific instructions.
23231          * And apply architecture specific constraints to instructions.
23232          * Copies are inserted to preserve the register flexibility
23233          * of 3 address instructions.
23234          */
23235         struct triple *next, *value;
23236         size_t size;
23237         next = ins->next;
23238         switch(ins->op) {
23239         case OP_INTCONST:
23240                 ins->template_id = TEMPLATE_INTCONST32;
23241                 if (ins->u.cval < 256) {
23242                         ins->template_id = TEMPLATE_INTCONST8;
23243                 }
23244                 break;
23245         case OP_ADDRCONST:
23246                 ins->template_id = TEMPLATE_INTCONST32;
23247                 break;
23248         case OP_UNKNOWNVAL:
23249                 ins->template_id = TEMPLATE_UNKNOWNVAL;
23250                 break;
23251         case OP_NOOP:
23252         case OP_SDECL:
23253         case OP_BLOBCONST:
23254         case OP_LABEL:
23255                 ins->template_id = TEMPLATE_NOP;
23256                 break;
23257         case OP_COPY:
23258         case OP_CONVERT:
23259                 size = size_of(state, ins->type);
23260                 value = RHS(ins, 0);
23261                 if (is_imm8(value) && (size <= SIZEOF_I8)) {
23262                         ins->template_id = TEMPLATE_COPY_IMM8;
23263                 }
23264                 else if (is_imm16(value) && (size <= SIZEOF_I16)) {
23265                         ins->template_id = TEMPLATE_COPY_IMM16;
23266                 }
23267                 else if (is_imm32(value) && (size <= SIZEOF_I32)) {
23268                         ins->template_id = TEMPLATE_COPY_IMM32;
23269                 }
23270                 else if (is_const(value)) {
23271                         internal_error(state, ins, "bad constant passed to copy");
23272                 }
23273                 else if (size <= SIZEOF_I8) {
23274                         ins->template_id = TEMPLATE_COPY8_REG;
23275                 }
23276                 else if (size <= SIZEOF_I16) {
23277                         ins->template_id = TEMPLATE_COPY16_REG;
23278                 }
23279                 else if (size <= SIZEOF_I32) {
23280                         ins->template_id = TEMPLATE_COPY32_REG;
23281                 }
23282                 else {
23283                         internal_error(state, ins, "bad type passed to copy");
23284                 }
23285                 break;
23286         case OP_PHI:
23287                 size = size_of(state, ins->type);
23288                 if (size <= SIZEOF_I8) {
23289                         ins->template_id = TEMPLATE_PHI8;
23290                 }
23291                 else if (size <= SIZEOF_I16) {
23292                         ins->template_id = TEMPLATE_PHI16;
23293                 }
23294                 else if (size <= SIZEOF_I32) {
23295                         ins->template_id = TEMPLATE_PHI32;
23296                 }
23297                 else {
23298                         internal_error(state, ins, "bad type passed to phi");
23299                 }
23300                 break;
23301         case OP_ADECL:
23302                 /* Adecls should always be treated as dead code and
23303                  * removed.  If we are not optimizing they may linger.
23304                  */
23305                 if (!noop_adecl(ins)) {
23306                         internal_error(state, ins, "adecl remains?");
23307                 }
23308                 ins->template_id = TEMPLATE_NOP;
23309                 next = after_lhs(state, ins);
23310                 break;
23311         case OP_STORE:
23312                 switch(ins->type->type & TYPE_MASK) {
23313                 case TYPE_CHAR:    case TYPE_UCHAR:
23314                         ins->template_id = TEMPLATE_STORE8;
23315                         break;
23316                 case TYPE_SHORT:   case TYPE_USHORT:
23317                         ins->template_id = TEMPLATE_STORE16;
23318                         break;
23319                 case TYPE_INT:     case TYPE_UINT:
23320                 case TYPE_LONG:    case TYPE_ULONG:
23321                 case TYPE_POINTER:
23322                         ins->template_id = TEMPLATE_STORE32;
23323                         break;
23324                 default:
23325                         internal_error(state, ins, "unknown type in store");
23326                         break;
23327                 }
23328                 break;
23329         case OP_LOAD:
23330                 switch(ins->type->type & TYPE_MASK) {
23331                 case TYPE_CHAR:   case TYPE_UCHAR:
23332                 case TYPE_SHORT:  case TYPE_USHORT:
23333                 case TYPE_INT:    case TYPE_UINT:
23334                 case TYPE_LONG:   case TYPE_ULONG:
23335                 case TYPE_POINTER:
23336                         break;
23337                 default:
23338                         internal_error(state, ins, "unknown type in load");
23339                         break;
23340                 }
23341                 ins->template_id = TEMPLATE_LOAD32;
23342                 break;
23343         case OP_ADD:
23344         case OP_SUB:
23345         case OP_AND:
23346         case OP_XOR:
23347         case OP_OR:
23348         case OP_SMUL:
23349                 ins->template_id = TEMPLATE_BINARY32_REG;
23350                 if (get_imm32(ins, &RHS(ins, 1))) {
23351                         ins->template_id = TEMPLATE_BINARY32_IMM;
23352                 }
23353                 break;
23354         case OP_SDIVT:
23355         case OP_UDIVT:
23356                 ins->template_id = TEMPLATE_DIV32;
23357                 next = after_lhs(state, ins);
23358                 break;
23359         case OP_UMUL:
23360                 ins->template_id = TEMPLATE_UMUL32;
23361                 break;
23362         case OP_UDIV:
23363                 next = mod_div(state, ins, OP_UDIVT, 0);
23364                 break;
23365         case OP_SDIV:
23366                 next = mod_div(state, ins, OP_SDIVT, 0);
23367                 break;
23368         case OP_UMOD:
23369                 next = mod_div(state, ins, OP_UDIVT, 1);
23370                 break;
23371         case OP_SMOD:
23372                 next = mod_div(state, ins, OP_SDIVT, 1);
23373                 break;
23374         case OP_SL:
23375         case OP_SSR:
23376         case OP_USR:
23377                 ins->template_id = TEMPLATE_SL32_CL;
23378                 if (get_imm8(ins, &RHS(ins, 1))) {
23379                         ins->template_id = TEMPLATE_SL32_IMM;
23380                 } else if (size_of(state, RHS(ins, 1)->type) > SIZEOF_CHAR) {
23381                         typed_pre_copy(state, &uchar_type, ins, 1);
23382                 }
23383                 break;
23384         case OP_INVERT:
23385         case OP_NEG:
23386                 ins->template_id = TEMPLATE_UNARY32;
23387                 break;
23388         case OP_EQ: 
23389                 bool_cmp(state, ins, OP_CMP, OP_JMP_EQ, OP_SET_EQ); 
23390                 break;
23391         case OP_NOTEQ:
23392                 bool_cmp(state, ins, OP_CMP, OP_JMP_NOTEQ, OP_SET_NOTEQ);
23393                 break;
23394         case OP_SLESS:
23395                 bool_cmp(state, ins, OP_CMP, OP_JMP_SLESS, OP_SET_SLESS);
23396                 break;
23397         case OP_ULESS:
23398                 bool_cmp(state, ins, OP_CMP, OP_JMP_ULESS, OP_SET_ULESS);
23399                 break;
23400         case OP_SMORE:
23401                 bool_cmp(state, ins, OP_CMP, OP_JMP_SMORE, OP_SET_SMORE);
23402                 break;
23403         case OP_UMORE:
23404                 bool_cmp(state, ins, OP_CMP, OP_JMP_UMORE, OP_SET_UMORE);
23405                 break;
23406         case OP_SLESSEQ:
23407                 bool_cmp(state, ins, OP_CMP, OP_JMP_SLESSEQ, OP_SET_SLESSEQ);
23408                 break;
23409         case OP_ULESSEQ:
23410                 bool_cmp(state, ins, OP_CMP, OP_JMP_ULESSEQ, OP_SET_ULESSEQ);
23411                 break;
23412         case OP_SMOREEQ:
23413                 bool_cmp(state, ins, OP_CMP, OP_JMP_SMOREEQ, OP_SET_SMOREEQ);
23414                 break;
23415         case OP_UMOREEQ:
23416                 bool_cmp(state, ins, OP_CMP, OP_JMP_UMOREEQ, OP_SET_UMOREEQ);
23417                 break;
23418         case OP_LTRUE:
23419                 bool_cmp(state, ins, OP_TEST, OP_JMP_NOTEQ, OP_SET_NOTEQ);
23420                 break;
23421         case OP_LFALSE:
23422                 bool_cmp(state, ins, OP_TEST, OP_JMP_EQ, OP_SET_EQ);
23423                 break;
23424         case OP_BRANCH:
23425                 ins->op = OP_JMP;
23426                 ins->template_id = TEMPLATE_NOP;
23427                 break;
23428         case OP_CBRANCH:
23429                 fixup_branch(state, ins, OP_JMP_NOTEQ, OP_TEST, 
23430                         RHS(ins, 0)->type, RHS(ins, 0), 0);
23431                 break;
23432         case OP_CALL:
23433                 ins->template_id = TEMPLATE_NOP;
23434                 break;
23435         case OP_RET:
23436                 ins->template_id = TEMPLATE_RET;
23437                 break;
23438         case OP_INB:
23439         case OP_INW:
23440         case OP_INL:
23441                 switch(ins->op) {
23442                 case OP_INB: ins->template_id = TEMPLATE_INB_DX; break;
23443                 case OP_INW: ins->template_id = TEMPLATE_INW_DX; break;
23444                 case OP_INL: ins->template_id = TEMPLATE_INL_DX; break;
23445                 }
23446                 if (get_imm8(ins, &RHS(ins, 0))) {
23447                         ins->template_id += 1;
23448                 }
23449                 break;
23450         case OP_OUTB:
23451         case OP_OUTW:
23452         case OP_OUTL:
23453                 switch(ins->op) {
23454                 case OP_OUTB: ins->template_id = TEMPLATE_OUTB_DX; break;
23455                 case OP_OUTW: ins->template_id = TEMPLATE_OUTW_DX; break;
23456                 case OP_OUTL: ins->template_id = TEMPLATE_OUTL_DX; break;
23457                 }
23458                 if (get_imm8(ins, &RHS(ins, 1))) {
23459                         ins->template_id += 1;
23460                 }
23461                 break;
23462         case OP_BSF:
23463         case OP_BSR:
23464                 ins->template_id = TEMPLATE_BSF;
23465                 break;
23466         case OP_RDMSR:
23467                 ins->template_id = TEMPLATE_RDMSR;
23468                 next = after_lhs(state, ins);
23469                 break;
23470         case OP_WRMSR:
23471                 ins->template_id = TEMPLATE_WRMSR;
23472                 break;
23473         case OP_HLT:
23474                 ins->template_id = TEMPLATE_NOP;
23475                 break;
23476         case OP_ASM:
23477                 ins->template_id = TEMPLATE_NOP;
23478                 next = after_lhs(state, ins);
23479                 break;
23480                 /* Already transformed instructions */
23481         case OP_TEST:
23482                 ins->template_id = TEMPLATE_TEST32;
23483                 break;
23484         case OP_CMP:
23485                 ins->template_id = TEMPLATE_CMP32_REG;
23486                 if (get_imm32(ins, &RHS(ins, 1))) {
23487                         ins->template_id = TEMPLATE_CMP32_IMM;
23488                 }
23489                 break;
23490         case OP_JMP:
23491                 ins->template_id = TEMPLATE_NOP;
23492                 break;
23493         case OP_JMP_EQ:      case OP_JMP_NOTEQ:
23494         case OP_JMP_SLESS:   case OP_JMP_ULESS:
23495         case OP_JMP_SMORE:   case OP_JMP_UMORE:
23496         case OP_JMP_SLESSEQ: case OP_JMP_ULESSEQ:
23497         case OP_JMP_SMOREEQ: case OP_JMP_UMOREEQ:
23498                 ins->template_id = TEMPLATE_JMP;
23499                 break;
23500         case OP_SET_EQ:      case OP_SET_NOTEQ:
23501         case OP_SET_SLESS:   case OP_SET_ULESS:
23502         case OP_SET_SMORE:   case OP_SET_UMORE:
23503         case OP_SET_SLESSEQ: case OP_SET_ULESSEQ:
23504         case OP_SET_SMOREEQ: case OP_SET_UMOREEQ:
23505                 ins->template_id = TEMPLATE_SET;
23506                 break;
23507         case OP_DEPOSIT:
23508                 next = x86_deposit(state, ins);
23509                 break;
23510         case OP_SEXTRACT:
23511         case OP_UEXTRACT:
23512                 next = x86_extract(state, ins);
23513                 break;
23514                 /* Unhandled instructions */
23515         case OP_PIECE:
23516         default:
23517                 internal_error(state, ins, "unhandled ins: %d %s",
23518                         ins->op, tops(ins->op));
23519                 break;
23520         }
23521         return next;
23522 }
23523
23524 static long next_label(struct compile_state *state)
23525 {
23526         static long label_counter = 1000;
23527         return ++label_counter;
23528 }
23529 static void generate_local_labels(struct compile_state *state)
23530 {
23531         struct triple *first, *label;
23532         first = state->first;
23533         label = first;
23534         do {
23535                 if ((label->op == OP_LABEL) || 
23536                         (label->op == OP_SDECL)) {
23537                         if (label->use) {
23538                                 label->u.cval = next_label(state);
23539                         } else {
23540                                 label->u.cval = 0;
23541                         }
23542                         
23543                 }
23544                 label = label->next;
23545         } while(label != first);
23546 }
23547
23548 static int check_reg(struct compile_state *state, 
23549         struct triple *triple, int classes)
23550 {
23551         unsigned mask;
23552         int reg;
23553         reg = ID_REG(triple->id);
23554         if (reg == REG_UNSET) {
23555                 internal_error(state, triple, "register not set");
23556         }
23557         mask = arch_reg_regcm(state, reg);
23558         if (!(classes & mask)) {
23559                 internal_error(state, triple, "reg %d in wrong class",
23560                         reg);
23561         }
23562         return reg;
23563 }
23564
23565
23566 #if REG_XMM7 != 44
23567 #error "Registers have renumberd fix arch_reg_str"
23568 #endif
23569 static const char *arch_regs[] = {
23570         "%unset",
23571         "%unneeded",
23572         "%eflags",
23573         "%al", "%bl", "%cl", "%dl", "%ah", "%bh", "%ch", "%dh",
23574         "%ax", "%bx", "%cx", "%dx", "%si", "%di", "%bp", "%sp",
23575         "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi", "%ebp", "%esp",
23576         "%edx:%eax",
23577         "%dx:%ax",
23578         "%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7",
23579         "%xmm0", "%xmm1", "%xmm2", "%xmm3", 
23580         "%xmm4", "%xmm5", "%xmm6", "%xmm7",
23581 };
23582 static const char *arch_reg_str(int reg)
23583 {
23584         if (!((reg >= REG_EFLAGS) && (reg <= REG_XMM7))) {
23585                 reg = 0;
23586         }
23587         return arch_regs[reg];
23588 }
23589
23590 static const char *reg(struct compile_state *state, struct triple *triple,
23591         int classes)
23592 {
23593         int reg;
23594         reg = check_reg(state, triple, classes);
23595         return arch_reg_str(reg);
23596 }
23597
23598 static int arch_reg_size(int reg)
23599 {
23600         int size;
23601         size = 0;
23602         if (reg == REG_EFLAGS) {
23603                 size = 32;
23604         }
23605         else if ((reg >= REG_AL) && (reg <= REG_DH)) {
23606                 size = 8;
23607         }
23608         else if ((reg >= REG_AX) && (reg <= REG_SP)) {
23609                 size = 16;
23610         }
23611         else if ((reg >= REG_EAX) && (reg <= REG_ESP)) {
23612                 size = 32;
23613         }
23614         else if (reg == REG_EDXEAX) {
23615                 size = 64;
23616         }
23617         else if (reg == REG_DXAX) {
23618                 size = 32;
23619         }
23620         else if ((reg >= REG_MMX0) && (reg <= REG_MMX7)) {
23621                 size = 64;
23622         }
23623         else if ((reg >= REG_XMM0) && (reg <= REG_XMM7)) {
23624                 size = 128;
23625         }
23626         return size;
23627 }
23628
23629 static int reg_size(struct compile_state *state, struct triple *ins)
23630 {
23631         int reg;
23632         reg = ID_REG(ins->id);
23633         if (reg == REG_UNSET) {
23634                 internal_error(state, ins, "register not set");
23635         }
23636         return arch_reg_size(reg);
23637 }
23638         
23639
23640
23641 const char *type_suffix(struct compile_state *state, struct type *type)
23642 {
23643         const char *suffix;
23644         switch(size_of(state, type)) {
23645         case SIZEOF_I8:  suffix = "b"; break;
23646         case SIZEOF_I16: suffix = "w"; break;
23647         case SIZEOF_I32: suffix = "l"; break;
23648         default:
23649                 internal_error(state, 0, "unknown suffix");
23650                 suffix = 0;
23651                 break;
23652         }
23653         return suffix;
23654 }
23655
23656 static void print_const_val(
23657         struct compile_state *state, struct triple *ins, FILE *fp)
23658 {
23659         switch(ins->op) {
23660         case OP_INTCONST:
23661                 fprintf(fp, " $%ld ", 
23662                         (long)(ins->u.cval));
23663                 break;
23664         case OP_ADDRCONST:
23665                 if ((MISC(ins, 0)->op != OP_SDECL) &&
23666                         (MISC(ins, 0)->op != OP_LABEL))
23667                 {
23668                         internal_error(state, ins, "bad base for addrconst");
23669                 }
23670                 if (MISC(ins, 0)->u.cval <= 0) {
23671                         internal_error(state, ins, "unlabeled constant");
23672                 }
23673                 fprintf(fp, " $L%s%lu+%lu ",
23674                         state->compiler->label_prefix, 
23675                         (unsigned long)(MISC(ins, 0)->u.cval),
23676                         (unsigned long)(ins->u.cval));
23677                 break;
23678         default:
23679                 internal_error(state, ins, "unknown constant type");
23680                 break;
23681         }
23682 }
23683
23684 static void print_const(struct compile_state *state,
23685         struct triple *ins, FILE *fp)
23686 {
23687         switch(ins->op) {
23688         case OP_INTCONST:
23689                 switch(ins->type->type & TYPE_MASK) {
23690                 case TYPE_CHAR:
23691                 case TYPE_UCHAR:
23692                         fprintf(fp, ".byte 0x%02lx\n", 
23693                                 (unsigned long)(ins->u.cval));
23694                         break;
23695                 case TYPE_SHORT:
23696                 case TYPE_USHORT:
23697                         fprintf(fp, ".short 0x%04lx\n", 
23698                                 (unsigned long)(ins->u.cval));
23699                         break;
23700                 case TYPE_INT:
23701                 case TYPE_UINT:
23702                 case TYPE_LONG:
23703                 case TYPE_ULONG:
23704                 case TYPE_POINTER:
23705                         fprintf(fp, ".int %lu\n", 
23706                                 (unsigned long)(ins->u.cval));
23707                         break;
23708                 default:
23709                         fprintf(state->errout, "type: ");
23710                         name_of(state->errout, ins->type);
23711                         fprintf(state->errout, "\n");
23712                         internal_error(state, ins, "Unknown constant type. Val: %lu",
23713                                 (unsigned long)(ins->u.cval));
23714                 }
23715                 
23716                 break;
23717         case OP_ADDRCONST:
23718                 if ((MISC(ins, 0)->op != OP_SDECL) &&
23719                         (MISC(ins, 0)->op != OP_LABEL)) {
23720                         internal_error(state, ins, "bad base for addrconst");
23721                 }
23722                 if (MISC(ins, 0)->u.cval <= 0) {
23723                         internal_error(state, ins, "unlabeled constant");
23724                 }
23725                 fprintf(fp, ".int L%s%lu+%lu\n",
23726                         state->compiler->label_prefix,
23727                         (unsigned long)(MISC(ins, 0)->u.cval),
23728                         (unsigned long)(ins->u.cval));
23729                 break;
23730         case OP_BLOBCONST:
23731         {
23732                 unsigned char *blob;
23733                 size_t size, i;
23734                 size = size_of_in_bytes(state, ins->type);
23735                 blob = ins->u.blob;
23736                 for(i = 0; i < size; i++) {
23737                         fprintf(fp, ".byte 0x%02x\n",
23738                                 blob[i]);
23739                 }
23740                 break;
23741         }
23742         default:
23743                 internal_error(state, ins, "Unknown constant type");
23744                 break;
23745         }
23746 }
23747
23748 #define TEXT_SECTION ".rom.text"
23749 #define DATA_SECTION ".rom.data"
23750
23751 static long get_const_pool_ref(
23752         struct compile_state *state, struct triple *ins, size_t size, FILE *fp)
23753 {
23754         size_t fill_bytes;
23755         long ref;
23756         ref = next_label(state);
23757         fprintf(fp, ".section \"" DATA_SECTION "\"\n");
23758         fprintf(fp, ".balign %d\n", align_of_in_bytes(state, ins->type));
23759         fprintf(fp, "L%s%lu:\n", state->compiler->label_prefix, ref);
23760         print_const(state, ins, fp);
23761         fill_bytes = bits_to_bytes(size - size_of(state, ins->type));
23762         if (fill_bytes) {
23763                 fprintf(fp, ".fill %d, 1, 0\n", fill_bytes);
23764         }
23765         fprintf(fp, ".section \"" TEXT_SECTION "\"\n");
23766         return ref;
23767 }
23768
23769 static long get_mask_pool_ref(
23770         struct compile_state *state, struct triple *ins, unsigned long mask, FILE *fp)
23771 {
23772         long ref;
23773         if (mask == 0xff) {
23774                 ref = 1;
23775         }
23776         else if (mask == 0xffff) {
23777                 ref = 2;
23778         }
23779         else {
23780                 ref = 0;
23781                 internal_error(state, ins, "unhandled mask value");
23782         }
23783         return ref;
23784 }
23785
23786 static void print_binary_op(struct compile_state *state,
23787         const char *op, struct triple *ins, FILE *fp) 
23788 {
23789         unsigned mask;
23790         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO;
23791         if (ID_REG(RHS(ins, 0)->id) != ID_REG(ins->id)) {
23792                 internal_error(state, ins, "invalid register assignment");
23793         }
23794         if (is_const(RHS(ins, 1))) {
23795                 fprintf(fp, "\t%s ", op);
23796                 print_const_val(state, RHS(ins, 1), fp);
23797                 fprintf(fp, ", %s\n",
23798                         reg(state, RHS(ins, 0), mask));
23799         }
23800         else {
23801                 unsigned lmask, rmask;
23802                 int lreg, rreg;
23803                 lreg = check_reg(state, RHS(ins, 0), mask);
23804                 rreg = check_reg(state, RHS(ins, 1), mask);
23805                 lmask = arch_reg_regcm(state, lreg);
23806                 rmask = arch_reg_regcm(state, rreg);
23807                 mask = lmask & rmask;
23808                 fprintf(fp, "\t%s %s, %s\n",
23809                         op,
23810                         reg(state, RHS(ins, 1), mask),
23811                         reg(state, RHS(ins, 0), mask));
23812         }
23813 }
23814 static void print_unary_op(struct compile_state *state, 
23815         const char *op, struct triple *ins, FILE *fp)
23816 {
23817         unsigned mask;
23818         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO;
23819         fprintf(fp, "\t%s %s\n",
23820                 op,
23821                 reg(state, RHS(ins, 0), mask));
23822 }
23823
23824 static void print_op_shift(struct compile_state *state,
23825         const char *op, struct triple *ins, FILE *fp)
23826 {
23827         unsigned mask;
23828         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO;
23829         if (ID_REG(RHS(ins, 0)->id) != ID_REG(ins->id)) {
23830                 internal_error(state, ins, "invalid register assignment");
23831         }
23832         if (is_const(RHS(ins, 1))) {
23833                 fprintf(fp, "\t%s ", op);
23834                 print_const_val(state, RHS(ins, 1), fp);
23835                 fprintf(fp, ", %s\n",
23836                         reg(state, RHS(ins, 0), mask));
23837         }
23838         else {
23839                 fprintf(fp, "\t%s %s, %s\n",
23840                         op,
23841                         reg(state, RHS(ins, 1), REGCM_GPR8_LO),
23842                         reg(state, RHS(ins, 0), mask));
23843         }
23844 }
23845
23846 static void print_op_in(struct compile_state *state, struct triple *ins, FILE *fp)
23847 {
23848         const char *op;
23849         int mask;
23850         int dreg;
23851         mask = 0;
23852         switch(ins->op) {
23853         case OP_INB: op = "inb", mask = REGCM_GPR8_LO; break;
23854         case OP_INW: op = "inw", mask = REGCM_GPR16; break;
23855         case OP_INL: op = "inl", mask = REGCM_GPR32; break;
23856         default:
23857                 internal_error(state, ins, "not an in operation");
23858                 op = 0;
23859                 break;
23860         }
23861         dreg = check_reg(state, ins, mask);
23862         if (!reg_is_reg(state, dreg, REG_EAX)) {
23863                 internal_error(state, ins, "dst != %%eax");
23864         }
23865         if (is_const(RHS(ins, 0))) {
23866                 fprintf(fp, "\t%s ", op);
23867                 print_const_val(state, RHS(ins, 0), fp);
23868                 fprintf(fp, ", %s\n",
23869                         reg(state, ins, mask));
23870         }
23871         else {
23872                 int addr_reg;
23873                 addr_reg = check_reg(state, RHS(ins, 0), REGCM_GPR16);
23874                 if (!reg_is_reg(state, addr_reg, REG_DX)) {
23875                         internal_error(state, ins, "src != %%dx");
23876                 }
23877                 fprintf(fp, "\t%s %s, %s\n",
23878                         op, 
23879                         reg(state, RHS(ins, 0), REGCM_GPR16),
23880                         reg(state, ins, mask));
23881         }
23882 }
23883
23884 static void print_op_out(struct compile_state *state, struct triple *ins, FILE *fp)
23885 {
23886         const char *op;
23887         int mask;
23888         int lreg;
23889         mask = 0;
23890         switch(ins->op) {
23891         case OP_OUTB: op = "outb", mask = REGCM_GPR8_LO; break;
23892         case OP_OUTW: op = "outw", mask = REGCM_GPR16; break;
23893         case OP_OUTL: op = "outl", mask = REGCM_GPR32; break;
23894         default:
23895                 internal_error(state, ins, "not an out operation");
23896                 op = 0;
23897                 break;
23898         }
23899         lreg = check_reg(state, RHS(ins, 0), mask);
23900         if (!reg_is_reg(state, lreg, REG_EAX)) {
23901                 internal_error(state, ins, "src != %%eax");
23902         }
23903         if (is_const(RHS(ins, 1))) {
23904                 fprintf(fp, "\t%s %s,", 
23905                         op, reg(state, RHS(ins, 0), mask));
23906                 print_const_val(state, RHS(ins, 1), fp);
23907                 fprintf(fp, "\n");
23908         }
23909         else {
23910                 int addr_reg;
23911                 addr_reg = check_reg(state, RHS(ins, 1), REGCM_GPR16);
23912                 if (!reg_is_reg(state, addr_reg, REG_DX)) {
23913                         internal_error(state, ins, "dst != %%dx");
23914                 }
23915                 fprintf(fp, "\t%s %s, %s\n",
23916                         op, 
23917                         reg(state, RHS(ins, 0), mask),
23918                         reg(state, RHS(ins, 1), REGCM_GPR16));
23919         }
23920 }
23921
23922 static void print_op_move(struct compile_state *state,
23923         struct triple *ins, FILE *fp)
23924 {
23925         /* op_move is complex because there are many types
23926          * of registers we can move between.
23927          * Because OP_COPY will be introduced in arbitrary locations
23928          * OP_COPY must not affect flags.
23929          * OP_CONVERT can change the flags and it is the only operation
23930          * where it is expected the types in the registers can change.
23931          */
23932         int omit_copy = 1; /* Is it o.k. to omit a noop copy? */
23933         struct triple *dst, *src;
23934         if (state->arch->features & X86_NOOP_COPY) {
23935                 omit_copy = 0;
23936         }
23937         if ((ins->op == OP_COPY) || (ins->op == OP_CONVERT)) {
23938                 src = RHS(ins, 0);
23939                 dst = ins;
23940         }
23941         else {
23942                 internal_error(state, ins, "unknown move operation");
23943                 src = dst = 0;
23944         }
23945         if (reg_size(state, dst) < size_of(state, dst->type)) {
23946                 internal_error(state, ins, "Invalid destination register");
23947         }
23948         if (!equiv_types(src->type, dst->type) && (dst->op == OP_COPY)) {
23949                 fprintf(state->errout, "src type: ");
23950                 name_of(state->errout, src->type);
23951                 fprintf(state->errout, "\n");
23952                 fprintf(state->errout, "dst type: ");
23953                 name_of(state->errout, dst->type);
23954                 fprintf(state->errout, "\n");
23955                 internal_error(state, ins, "Type mismatch for OP_COPY");
23956         }
23957
23958         if (!is_const(src)) {
23959                 int src_reg, dst_reg;
23960                 int src_regcm, dst_regcm;
23961                 src_reg   = ID_REG(src->id);
23962                 dst_reg   = ID_REG(dst->id);
23963                 src_regcm = arch_reg_regcm(state, src_reg);
23964                 dst_regcm = arch_reg_regcm(state, dst_reg);
23965                 /* If the class is the same just move the register */
23966                 if (src_regcm & dst_regcm & 
23967                         (REGCM_GPR8_LO | REGCM_GPR16 | REGCM_GPR32)) {
23968                         if ((src_reg != dst_reg) || !omit_copy) {
23969                                 fprintf(fp, "\tmov %s, %s\n",
23970                                         reg(state, src, src_regcm),
23971                                         reg(state, dst, dst_regcm));
23972                         }
23973                 }
23974                 /* Move 32bit to 16bit */
23975                 else if ((src_regcm & REGCM_GPR32) &&
23976                         (dst_regcm & REGCM_GPR16)) {
23977                         src_reg = (src_reg - REGC_GPR32_FIRST) + REGC_GPR16_FIRST;
23978                         if ((src_reg != dst_reg) || !omit_copy) {
23979                                 fprintf(fp, "\tmovw %s, %s\n",
23980                                         arch_reg_str(src_reg), 
23981                                         arch_reg_str(dst_reg));
23982                         }
23983                 }
23984                 /* Move from 32bit gprs to 16bit gprs */
23985                 else if ((src_regcm & REGCM_GPR32) &&
23986                         (dst_regcm & REGCM_GPR16)) {
23987                         dst_reg = (dst_reg - REGC_GPR16_FIRST) + REGC_GPR32_FIRST;
23988                         if ((src_reg != dst_reg) || !omit_copy) {
23989                                 fprintf(fp, "\tmov %s, %s\n",
23990                                         arch_reg_str(src_reg),
23991                                         arch_reg_str(dst_reg));
23992                         }
23993                 }
23994                 /* Move 32bit to 8bit */
23995                 else if ((src_regcm & REGCM_GPR32_8) &&
23996                         (dst_regcm & REGCM_GPR8_LO))
23997                 {
23998                         src_reg = (src_reg - REGC_GPR32_8_FIRST) + REGC_GPR8_FIRST;
23999                         if ((src_reg != dst_reg) || !omit_copy) {
24000                                 fprintf(fp, "\tmovb %s, %s\n",
24001                                         arch_reg_str(src_reg),
24002                                         arch_reg_str(dst_reg));
24003                         }
24004                 }
24005                 /* Move 16bit to 8bit */
24006                 else if ((src_regcm & REGCM_GPR16_8) &&
24007                         (dst_regcm & REGCM_GPR8_LO))
24008                 {
24009                         src_reg = (src_reg - REGC_GPR16_8_FIRST) + REGC_GPR8_FIRST;
24010                         if ((src_reg != dst_reg) || !omit_copy) {
24011                                 fprintf(fp, "\tmovb %s, %s\n",
24012                                         arch_reg_str(src_reg),
24013                                         arch_reg_str(dst_reg));
24014                         }
24015                 }
24016                 /* Move 8/16bit to 16/32bit */
24017                 else if ((src_regcm & (REGCM_GPR8_LO | REGCM_GPR16)) && 
24018                         (dst_regcm & (REGCM_GPR16 | REGCM_GPR32))) {
24019                         const char *op;
24020                         op = is_signed(src->type)? "movsx": "movzx";
24021                         fprintf(fp, "\t%s %s, %s\n",
24022                                 op,
24023                                 reg(state, src, src_regcm),
24024                                 reg(state, dst, dst_regcm));
24025                 }
24026                 /* Move between sse registers */
24027                 else if ((src_regcm & dst_regcm & REGCM_XMM)) {
24028                         if ((src_reg != dst_reg) || !omit_copy) {
24029                                 fprintf(fp, "\tmovdqa %s, %s\n",
24030                                         reg(state, src, src_regcm),
24031                                         reg(state, dst, dst_regcm));
24032                         }
24033                 }
24034                 /* Move between mmx registers */
24035                 else if ((src_regcm & dst_regcm & REGCM_MMX)) {
24036                         if ((src_reg != dst_reg) || !omit_copy) {
24037                                 fprintf(fp, "\tmovq %s, %s\n",
24038                                         reg(state, src, src_regcm),
24039                                         reg(state, dst, dst_regcm));
24040                         }
24041                 }
24042                 /* Move from sse to mmx registers */
24043                 else if ((src_regcm & REGCM_XMM) && (dst_regcm & REGCM_MMX)) {
24044                         fprintf(fp, "\tmovdq2q %s, %s\n",
24045                                 reg(state, src, src_regcm),
24046                                 reg(state, dst, dst_regcm));
24047                 }
24048                 /* Move from mmx to sse registers */
24049                 else if ((src_regcm & REGCM_MMX) && (dst_regcm & REGCM_XMM)) {
24050                         fprintf(fp, "\tmovq2dq %s, %s\n",
24051                                 reg(state, src, src_regcm),
24052                                 reg(state, dst, dst_regcm));
24053                 }
24054                 /* Move between 32bit gprs & mmx/sse registers */
24055                 else if ((src_regcm & (REGCM_GPR32 | REGCM_MMX | REGCM_XMM)) &&
24056                         (dst_regcm & (REGCM_GPR32 | REGCM_MMX | REGCM_XMM))) {
24057                         fprintf(fp, "\tmovd %s, %s\n",
24058                                 reg(state, src, src_regcm),
24059                                 reg(state, dst, dst_regcm));
24060                 }
24061                 /* Move from 16bit gprs &  mmx/sse registers */
24062                 else if ((src_regcm & REGCM_GPR16) &&
24063                         (dst_regcm & (REGCM_MMX | REGCM_XMM))) {
24064                         const char *op;
24065                         int mid_reg;
24066                         op = is_signed(src->type)? "movsx":"movzx";
24067                         mid_reg = (src_reg - REGC_GPR16_FIRST) + REGC_GPR32_FIRST;
24068                         fprintf(fp, "\t%s %s, %s\n\tmovd %s, %s\n",
24069                                 op,
24070                                 arch_reg_str(src_reg),
24071                                 arch_reg_str(mid_reg),
24072                                 arch_reg_str(mid_reg),
24073                                 arch_reg_str(dst_reg));
24074                 }
24075                 /* Move from mmx/sse registers to 16bit gprs */
24076                 else if ((src_regcm & (REGCM_MMX | REGCM_XMM)) &&
24077                         (dst_regcm & REGCM_GPR16)) {
24078                         dst_reg = (dst_reg - REGC_GPR16_FIRST) + REGC_GPR32_FIRST;
24079                         fprintf(fp, "\tmovd %s, %s\n",
24080                                 arch_reg_str(src_reg),
24081                                 arch_reg_str(dst_reg));
24082                 }
24083                 /* Move from gpr to 64bit dividend */
24084                 else if ((src_regcm & (REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO))  &&
24085                         (dst_regcm & REGCM_DIVIDEND64)) {
24086                         const char *extend;
24087                         extend = is_signed(src->type)? "cltd":"movl $0, %edx";
24088                         fprintf(fp, "\tmov %s, %%eax\n\t%s\n",
24089                                 arch_reg_str(src_reg), 
24090                                 extend);
24091                 }
24092                 /* Move from 64bit gpr to gpr */
24093                 else if ((src_regcm & REGCM_DIVIDEND64) &&
24094                         (dst_regcm & (REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO))) {
24095                         if (dst_regcm & REGCM_GPR32) {
24096                                 src_reg = REG_EAX;
24097                         } 
24098                         else if (dst_regcm & REGCM_GPR16) {
24099                                 src_reg = REG_AX;
24100                         }
24101                         else if (dst_regcm & REGCM_GPR8_LO) {
24102                                 src_reg = REG_AL;
24103                         }
24104                         fprintf(fp, "\tmov %s, %s\n",
24105                                 arch_reg_str(src_reg),
24106                                 arch_reg_str(dst_reg));
24107                 }
24108                 /* Move from mmx/sse registers to 64bit gpr */
24109                 else if ((src_regcm & (REGCM_MMX | REGCM_XMM)) &&
24110                         (dst_regcm & REGCM_DIVIDEND64)) {
24111                         const char *extend;
24112                         extend = is_signed(src->type)? "cltd": "movl $0, %edx";
24113                         fprintf(fp, "\tmovd %s, %%eax\n\t%s\n",
24114                                 arch_reg_str(src_reg),
24115                                 extend);
24116                 }
24117                 /* Move from 64bit gpr to mmx/sse register */
24118                 else if ((src_regcm & REGCM_DIVIDEND64) &&
24119                         (dst_regcm & (REGCM_XMM | REGCM_MMX))) {
24120                         fprintf(fp, "\tmovd %%eax, %s\n",
24121                                 arch_reg_str(dst_reg));
24122                 }
24123 #if X86_4_8BIT_GPRS
24124                 /* Move from 8bit gprs to  mmx/sse registers */
24125                 else if ((src_regcm & REGCM_GPR8_LO) && (src_reg <= REG_DL) &&
24126                         (dst_regcm & (REGCM_MMX | REGCM_XMM))) {
24127                         const char *op;
24128                         int mid_reg;
24129                         op = is_signed(src->type)? "movsx":"movzx";
24130                         mid_reg = (src_reg - REGC_GPR8_FIRST) + REGC_GPR32_FIRST;
24131                         fprintf(fp, "\t%s %s, %s\n\tmovd %s, %s\n",
24132                                 op,
24133                                 reg(state, src, src_regcm),
24134                                 arch_reg_str(mid_reg),
24135                                 arch_reg_str(mid_reg),
24136                                 reg(state, dst, dst_regcm));
24137                 }
24138                 /* Move from mmx/sse registers and 8bit gprs */
24139                 else if ((src_regcm & (REGCM_MMX | REGCM_XMM)) &&
24140                         (dst_regcm & REGCM_GPR8_LO) && (dst_reg <= REG_DL)) {
24141                         int mid_reg;
24142                         mid_reg = (dst_reg - REGC_GPR8_FIRST) + REGC_GPR32_FIRST;
24143                         fprintf(fp, "\tmovd %s, %s\n",
24144                                 reg(state, src, src_regcm),
24145                                 arch_reg_str(mid_reg));
24146                 }
24147                 /* Move from 32bit gprs to 8bit gprs */
24148                 else if ((src_regcm & REGCM_GPR32) &&
24149                         (dst_regcm & REGCM_GPR8_LO)) {
24150                         dst_reg = (dst_reg - REGC_GPR8_FIRST) + REGC_GPR32_FIRST;
24151                         if ((src_reg != dst_reg) || !omit_copy) {
24152                                 fprintf(fp, "\tmov %s, %s\n",
24153                                         arch_reg_str(src_reg),
24154                                         arch_reg_str(dst_reg));
24155                         }
24156                 }
24157                 /* Move from 16bit gprs to 8bit gprs */
24158                 else if ((src_regcm & REGCM_GPR16) &&
24159                         (dst_regcm & REGCM_GPR8_LO)) {
24160                         dst_reg = (dst_reg - REGC_GPR8_FIRST) + REGC_GPR16_FIRST;
24161                         if ((src_reg != dst_reg) || !omit_copy) {
24162                                 fprintf(fp, "\tmov %s, %s\n",
24163                                         arch_reg_str(src_reg),
24164                                         arch_reg_str(dst_reg));
24165                         }
24166                 }
24167 #endif /* X86_4_8BIT_GPRS */
24168                 /* Move from %eax:%edx to %eax:%edx */
24169                 else if ((src_regcm & REGCM_DIVIDEND64) &&
24170                         (dst_regcm & REGCM_DIVIDEND64) &&
24171                         (src_reg == dst_reg)) {
24172                         if (!omit_copy) {
24173                                 fprintf(fp, "\t/*mov %s, %s*/\n",
24174                                         arch_reg_str(src_reg),
24175                                         arch_reg_str(dst_reg));
24176                         }
24177                 }
24178                 else {
24179                         if ((src_regcm & ~REGCM_FLAGS) == 0) {
24180                                 internal_error(state, ins, "attempt to copy from %%eflags!");
24181                         }
24182                         internal_error(state, ins, "unknown copy type");
24183                 }
24184         }
24185         else {
24186                 size_t dst_size;
24187                 int dst_reg;
24188                 int dst_regcm;
24189                 dst_size = size_of(state, dst->type);
24190                 dst_reg = ID_REG(dst->id);
24191                 dst_regcm = arch_reg_regcm(state, dst_reg);
24192                 if (dst_regcm & (REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO)) {
24193                         fprintf(fp, "\tmov ");
24194                         print_const_val(state, src, fp);
24195                         fprintf(fp, ", %s\n",
24196                                 reg(state, dst, REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO));
24197                 }
24198                 else if (dst_regcm & REGCM_DIVIDEND64) {
24199                         if (dst_size > SIZEOF_I32) {
24200                                 internal_error(state, ins, "%dbit constant...", dst_size);
24201                         }
24202                         fprintf(fp, "\tmov $0, %%edx\n");
24203                         fprintf(fp, "\tmov ");
24204                         print_const_val(state, src, fp);
24205                         fprintf(fp, ", %%eax\n");
24206                 }
24207                 else if (dst_regcm & REGCM_DIVIDEND32) {
24208                         if (dst_size > SIZEOF_I16) {
24209                                 internal_error(state, ins, "%dbit constant...", dst_size);
24210                         }
24211                         fprintf(fp, "\tmov $0, %%dx\n");
24212                         fprintf(fp, "\tmov ");
24213                         print_const_val(state, src, fp);
24214                         fprintf(fp, ", %%ax");
24215                 }
24216                 else if (dst_regcm & (REGCM_XMM | REGCM_MMX)) {
24217                         long ref;
24218                         if (dst_size > SIZEOF_I32) {
24219                                 internal_error(state, ins, "%d bit constant...", dst_size);
24220                         }
24221                         ref = get_const_pool_ref(state, src, SIZEOF_I32, fp);
24222                         fprintf(fp, "\tmovd L%s%lu, %s\n",
24223                                 state->compiler->label_prefix, ref,
24224                                 reg(state, dst, (REGCM_XMM | REGCM_MMX)));
24225                 }
24226                 else {
24227                         internal_error(state, ins, "unknown copy immediate type");
24228                 }
24229         }
24230         /* Leave now if this is not a type conversion */
24231         if (ins->op != OP_CONVERT) {
24232                 return;
24233         }
24234         /* Now make certain I have not logically overflowed the destination */
24235         if ((size_of(state, src->type) > size_of(state, dst->type)) &&
24236                 (size_of(state, dst->type) < reg_size(state, dst)))
24237         {
24238                 unsigned long mask;
24239                 int dst_reg;
24240                 int dst_regcm;
24241                 if (size_of(state, dst->type) >= 32) {
24242                         fprintf(state->errout, "dst type: ");
24243                         name_of(state->errout, dst->type);
24244                         fprintf(state->errout, "\n");
24245                         internal_error(state, dst, "unhandled dst type size");
24246                 }
24247                 mask = 1;
24248                 mask <<= size_of(state, dst->type);
24249                 mask -= 1;
24250
24251                 dst_reg = ID_REG(dst->id);
24252                 dst_regcm = arch_reg_regcm(state, dst_reg);
24253
24254                 if (dst_regcm & (REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO)) {
24255                         fprintf(fp, "\tand $0x%lx, %s\n",
24256                                 mask, reg(state, dst, REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO));
24257                 }
24258                 else if (dst_regcm & REGCM_MMX) {
24259                         long ref;
24260                         ref = get_mask_pool_ref(state, dst, mask, fp);
24261                         fprintf(fp, "\tpand L%s%lu, %s\n",
24262                                 state->compiler->label_prefix, ref,
24263                                 reg(state, dst, REGCM_MMX));
24264                 }
24265                 else if (dst_regcm & REGCM_XMM) {
24266                         long ref;
24267                         ref = get_mask_pool_ref(state, dst, mask, fp);
24268                         fprintf(fp, "\tpand L%s%lu, %s\n",
24269                                 state->compiler->label_prefix, ref,
24270                                 reg(state, dst, REGCM_XMM));
24271                 }
24272                 else {
24273                         fprintf(state->errout, "dst type: ");
24274                         name_of(state->errout, dst->type);
24275                         fprintf(state->errout, "\n");
24276                         fprintf(state->errout, "dst: %s\n", reg(state, dst, REGCM_ALL));
24277                         internal_error(state, dst, "failed to trunc value: mask %lx", mask);
24278                 }
24279         }
24280         /* Make certain I am properly sign extended */
24281         if ((size_of(state, src->type) < size_of(state, dst->type)) &&
24282                 (is_signed(src->type)))
24283         {
24284                 int bits, reg_bits, shift_bits;
24285                 int dst_reg;
24286                 int dst_regcm;
24287
24288                 bits = size_of(state, src->type);
24289                 reg_bits = reg_size(state, dst);
24290                 if (reg_bits > 32) {
24291                         reg_bits = 32;
24292                 }
24293                 shift_bits = reg_bits - size_of(state, src->type);
24294                 dst_reg = ID_REG(dst->id);
24295                 dst_regcm = arch_reg_regcm(state, dst_reg);
24296
24297                 if (shift_bits < 0) {
24298                         internal_error(state, dst, "negative shift?");
24299                 }
24300
24301                 if (dst_regcm & (REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO)) {
24302                         fprintf(fp, "\tshl $%d, %s\n", 
24303                                 shift_bits, 
24304                                 reg(state, dst, REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO));
24305                         fprintf(fp, "\tsar $%d, %s\n", 
24306                                 shift_bits, 
24307                                 reg(state, dst, REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO));
24308                 }
24309                 else if (dst_regcm & (REGCM_MMX | REGCM_XMM)) {
24310                         fprintf(fp, "\tpslld $%d, %s\n",
24311                                 shift_bits, 
24312                                 reg(state, dst, REGCM_MMX | REGCM_XMM));
24313                         fprintf(fp, "\tpsrad $%d, %s\n",
24314                                 shift_bits, 
24315                                 reg(state, dst, REGCM_MMX | REGCM_XMM));
24316                 }
24317                 else {
24318                         fprintf(state->errout, "dst type: ");
24319                         name_of(state->errout, dst->type);
24320                         fprintf(state->errout, "\n");
24321                         fprintf(state->errout, "dst: %s\n", reg(state, dst, REGCM_ALL));
24322                         internal_error(state, dst, "failed to signed extend value");
24323                 }
24324         }
24325 }
24326
24327 static void print_op_load(struct compile_state *state,
24328         struct triple *ins, FILE *fp)
24329 {
24330         struct triple *dst, *src;
24331         const char *op;
24332         dst = ins;
24333         src = RHS(ins, 0);
24334         if (is_const(src) || is_const(dst)) {
24335                 internal_error(state, ins, "unknown load operation");
24336         }
24337         switch(ins->type->type & TYPE_MASK) {
24338         case TYPE_CHAR:   op = "movsbl"; break;
24339         case TYPE_UCHAR:  op = "movzbl"; break;
24340         case TYPE_SHORT:  op = "movswl"; break;
24341         case TYPE_USHORT: op = "movzwl"; break;
24342         case TYPE_INT:    case TYPE_UINT:
24343         case TYPE_LONG:   case TYPE_ULONG:
24344         case TYPE_POINTER:
24345                 op = "movl"; 
24346                 break;
24347         default:
24348                 internal_error(state, ins, "unknown type in load");
24349                 op = "<invalid opcode>";
24350                 break;
24351         }
24352         fprintf(fp, "\t%s (%s), %s\n",
24353                 op, 
24354                 reg(state, src, REGCM_GPR32),
24355                 reg(state, dst, REGCM_GPR32));
24356 }
24357
24358
24359 static void print_op_store(struct compile_state *state,
24360         struct triple *ins, FILE *fp)
24361 {
24362         struct triple *dst, *src;
24363         dst = RHS(ins, 0);
24364         src = RHS(ins, 1);
24365         if (is_const(src) && (src->op == OP_INTCONST)) {
24366                 long_t value;
24367                 value = (long_t)(src->u.cval);
24368                 fprintf(fp, "\tmov%s $%ld, (%s)\n",
24369                         type_suffix(state, src->type),
24370                         (long)(value),
24371                         reg(state, dst, REGCM_GPR32));
24372         }
24373         else if (is_const(dst) && (dst->op == OP_INTCONST)) {
24374                 fprintf(fp, "\tmov%s %s, 0x%08lx\n",
24375                         type_suffix(state, src->type),
24376                         reg(state, src, REGCM_GPR8_LO | REGCM_GPR16 | REGCM_GPR32),
24377                         (unsigned long)(dst->u.cval));
24378         }
24379         else {
24380                 if (is_const(src) || is_const(dst)) {
24381                         internal_error(state, ins, "unknown store operation");
24382                 }
24383                 fprintf(fp, "\tmov%s %s, (%s)\n",
24384                         type_suffix(state, src->type),
24385                         reg(state, src, REGCM_GPR8_LO | REGCM_GPR16 | REGCM_GPR32),
24386                         reg(state, dst, REGCM_GPR32));
24387         }
24388         
24389         
24390 }
24391
24392 static void print_op_smul(struct compile_state *state,
24393         struct triple *ins, FILE *fp)
24394 {
24395         if (!is_const(RHS(ins, 1))) {
24396                 fprintf(fp, "\timul %s, %s\n",
24397                         reg(state, RHS(ins, 1), REGCM_GPR32),
24398                         reg(state, RHS(ins, 0), REGCM_GPR32));
24399         }
24400         else {
24401                 fprintf(fp, "\timul ");
24402                 print_const_val(state, RHS(ins, 1), fp);
24403                 fprintf(fp, ", %s\n", reg(state, RHS(ins, 0), REGCM_GPR32));
24404         }
24405 }
24406
24407 static void print_op_cmp(struct compile_state *state,
24408         struct triple *ins, FILE *fp)
24409 {
24410         unsigned mask;
24411         int dreg;
24412         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO;
24413         dreg = check_reg(state, ins, REGCM_FLAGS);
24414         if (!reg_is_reg(state, dreg, REG_EFLAGS)) {
24415                 internal_error(state, ins, "bad dest register for cmp");
24416         }
24417         if (is_const(RHS(ins, 1))) {
24418                 fprintf(fp, "\tcmp ");
24419                 print_const_val(state, RHS(ins, 1), fp);
24420                 fprintf(fp, ", %s\n", reg(state, RHS(ins, 0), mask));
24421         }
24422         else {
24423                 unsigned lmask, rmask;
24424                 int lreg, rreg;
24425                 lreg = check_reg(state, RHS(ins, 0), mask);
24426                 rreg = check_reg(state, RHS(ins, 1), mask);
24427                 lmask = arch_reg_regcm(state, lreg);
24428                 rmask = arch_reg_regcm(state, rreg);
24429                 mask = lmask & rmask;
24430                 fprintf(fp, "\tcmp %s, %s\n",
24431                         reg(state, RHS(ins, 1), mask),
24432                         reg(state, RHS(ins, 0), mask));
24433         }
24434 }
24435
24436 static void print_op_test(struct compile_state *state,
24437         struct triple *ins, FILE *fp)
24438 {
24439         unsigned mask;
24440         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO;
24441         fprintf(fp, "\ttest %s, %s\n",
24442                 reg(state, RHS(ins, 0), mask),
24443                 reg(state, RHS(ins, 0), mask));
24444 }
24445
24446 static void print_op_branch(struct compile_state *state,
24447         struct triple *branch, FILE *fp)
24448 {
24449         const char *bop = "j";
24450         if ((branch->op == OP_JMP) || (branch->op == OP_CALL)) {
24451                 if (branch->rhs != 0) {
24452                         internal_error(state, branch, "jmp with condition?");
24453                 }
24454                 bop = "jmp";
24455         }
24456         else {
24457                 struct triple *ptr;
24458                 if (branch->rhs != 1) {
24459                         internal_error(state, branch, "jmpcc without condition?");
24460                 }
24461                 check_reg(state, RHS(branch, 0), REGCM_FLAGS);
24462                 if ((RHS(branch, 0)->op != OP_CMP) &&
24463                         (RHS(branch, 0)->op != OP_TEST)) {
24464                         internal_error(state, branch, "bad branch test");
24465                 }
24466 #warning "FIXME I have observed instructions between the test and branch instructions"
24467                 ptr = RHS(branch, 0);
24468                 for(ptr = RHS(branch, 0)->next; ptr != branch; ptr = ptr->next) {
24469                         if (ptr->op != OP_COPY) {
24470                                 internal_error(state, branch, "branch does not follow test");
24471                         }
24472                 }
24473                 switch(branch->op) {
24474                 case OP_JMP_EQ:       bop = "jz";  break;
24475                 case OP_JMP_NOTEQ:    bop = "jnz"; break;
24476                 case OP_JMP_SLESS:    bop = "jl";  break;
24477                 case OP_JMP_ULESS:    bop = "jb";  break;
24478                 case OP_JMP_SMORE:    bop = "jg";  break;
24479                 case OP_JMP_UMORE:    bop = "ja";  break;
24480                 case OP_JMP_SLESSEQ:  bop = "jle"; break;
24481                 case OP_JMP_ULESSEQ:  bop = "jbe"; break;
24482                 case OP_JMP_SMOREEQ:  bop = "jge"; break;
24483                 case OP_JMP_UMOREEQ:  bop = "jae"; break;
24484                 default:
24485                         internal_error(state, branch, "Invalid branch op");
24486                         break;
24487                 }
24488                 
24489         }
24490 #if 1
24491         if (branch->op == OP_CALL) {
24492                 fprintf(fp, "\t/* call */\n");
24493         }
24494 #endif
24495         fprintf(fp, "\t%s L%s%lu\n",
24496                 bop, 
24497                 state->compiler->label_prefix,
24498                 (unsigned long)(TARG(branch, 0)->u.cval));
24499 }
24500
24501 static void print_op_ret(struct compile_state *state,
24502         struct triple *branch, FILE *fp)
24503 {
24504         fprintf(fp, "\tjmp *%s\n",
24505                 reg(state, RHS(branch, 0), REGCM_GPR32));
24506 }
24507
24508 static void print_op_set(struct compile_state *state,
24509         struct triple *set, FILE *fp)
24510 {
24511         const char *sop = "set";
24512         if (set->rhs != 1) {
24513                 internal_error(state, set, "setcc without condition?");
24514         }
24515         check_reg(state, RHS(set, 0), REGCM_FLAGS);
24516         if ((RHS(set, 0)->op != OP_CMP) &&
24517                 (RHS(set, 0)->op != OP_TEST)) {
24518                 internal_error(state, set, "bad set test");
24519         }
24520         if (RHS(set, 0)->next != set) {
24521                 internal_error(state, set, "set does not follow test");
24522         }
24523         switch(set->op) {
24524         case OP_SET_EQ:       sop = "setz";  break;
24525         case OP_SET_NOTEQ:    sop = "setnz"; break;
24526         case OP_SET_SLESS:    sop = "setl";  break;
24527         case OP_SET_ULESS:    sop = "setb";  break;
24528         case OP_SET_SMORE:    sop = "setg";  break;
24529         case OP_SET_UMORE:    sop = "seta";  break;
24530         case OP_SET_SLESSEQ:  sop = "setle"; break;
24531         case OP_SET_ULESSEQ:  sop = "setbe"; break;
24532         case OP_SET_SMOREEQ:  sop = "setge"; break;
24533         case OP_SET_UMOREEQ:  sop = "setae"; break;
24534         default:
24535                 internal_error(state, set, "Invalid set op");
24536                 break;
24537         }
24538         fprintf(fp, "\t%s %s\n",
24539                 sop, reg(state, set, REGCM_GPR8_LO));
24540 }
24541
24542 static void print_op_bit_scan(struct compile_state *state, 
24543         struct triple *ins, FILE *fp) 
24544 {
24545         const char *op;
24546         switch(ins->op) {
24547         case OP_BSF: op = "bsf"; break;
24548         case OP_BSR: op = "bsr"; break;
24549         default: 
24550                 internal_error(state, ins, "unknown bit scan");
24551                 op = 0;
24552                 break;
24553         }
24554         fprintf(fp, 
24555                 "\t%s %s, %s\n"
24556                 "\tjnz 1f\n"
24557                 "\tmovl $-1, %s\n"
24558                 "1:\n",
24559                 op,
24560                 reg(state, RHS(ins, 0), REGCM_GPR32),
24561                 reg(state, ins, REGCM_GPR32),
24562                 reg(state, ins, REGCM_GPR32));
24563 }
24564
24565
24566 static void print_sdecl(struct compile_state *state,
24567         struct triple *ins, FILE *fp)
24568 {
24569         fprintf(fp, ".section \"" DATA_SECTION "\"\n");
24570         fprintf(fp, ".balign %d\n", align_of_in_bytes(state, ins->type));
24571         fprintf(fp, "L%s%lu:\n", 
24572                 state->compiler->label_prefix, (unsigned long)(ins->u.cval));
24573         print_const(state, MISC(ins, 0), fp);
24574         fprintf(fp, ".section \"" TEXT_SECTION "\"\n");
24575                 
24576 }
24577
24578 static void print_instruction(struct compile_state *state,
24579         struct triple *ins, FILE *fp)
24580 {
24581         /* Assumption: after I have exted the register allocator
24582          * everything is in a valid register. 
24583          */
24584         switch(ins->op) {
24585         case OP_ASM:
24586                 print_op_asm(state, ins, fp);
24587                 break;
24588         case OP_ADD:    print_binary_op(state, "add", ins, fp); break;
24589         case OP_SUB:    print_binary_op(state, "sub", ins, fp); break;
24590         case OP_AND:    print_binary_op(state, "and", ins, fp); break;
24591         case OP_XOR:    print_binary_op(state, "xor", ins, fp); break;
24592         case OP_OR:     print_binary_op(state, "or",  ins, fp); break;
24593         case OP_SL:     print_op_shift(state, "shl", ins, fp); break;
24594         case OP_USR:    print_op_shift(state, "shr", ins, fp); break;
24595         case OP_SSR:    print_op_shift(state, "sar", ins, fp); break;
24596         case OP_POS:    break;
24597         case OP_NEG:    print_unary_op(state, "neg", ins, fp); break;
24598         case OP_INVERT: print_unary_op(state, "not", ins, fp); break;
24599         case OP_NOOP:
24600         case OP_INTCONST:
24601         case OP_ADDRCONST:
24602         case OP_BLOBCONST:
24603                 /* Don't generate anything here for constants */
24604         case OP_PHI:
24605                 /* Don't generate anything for variable declarations. */
24606                 break;
24607         case OP_UNKNOWNVAL:
24608                 fprintf(fp, " /* unknown %s */\n",
24609                         reg(state, ins, REGCM_ALL));
24610                 break;
24611         case OP_SDECL:
24612                 print_sdecl(state, ins, fp);
24613                 break;
24614         case OP_COPY:   
24615         case OP_CONVERT:
24616                 print_op_move(state, ins, fp);
24617                 break;
24618         case OP_LOAD:
24619                 print_op_load(state, ins, fp);
24620                 break;
24621         case OP_STORE:
24622                 print_op_store(state, ins, fp);
24623                 break;
24624         case OP_SMUL:
24625                 print_op_smul(state, ins, fp);
24626                 break;
24627         case OP_CMP:    print_op_cmp(state, ins, fp); break;
24628         case OP_TEST:   print_op_test(state, ins, fp); break;
24629         case OP_JMP:
24630         case OP_JMP_EQ:      case OP_JMP_NOTEQ:
24631         case OP_JMP_SLESS:   case OP_JMP_ULESS:
24632         case OP_JMP_SMORE:   case OP_JMP_UMORE:
24633         case OP_JMP_SLESSEQ: case OP_JMP_ULESSEQ:
24634         case OP_JMP_SMOREEQ: case OP_JMP_UMOREEQ:
24635         case OP_CALL:
24636                 print_op_branch(state, ins, fp);
24637                 break;
24638         case OP_RET:
24639                 print_op_ret(state, ins, fp);
24640                 break;
24641         case OP_SET_EQ:      case OP_SET_NOTEQ:
24642         case OP_SET_SLESS:   case OP_SET_ULESS:
24643         case OP_SET_SMORE:   case OP_SET_UMORE:
24644         case OP_SET_SLESSEQ: case OP_SET_ULESSEQ:
24645         case OP_SET_SMOREEQ: case OP_SET_UMOREEQ:
24646                 print_op_set(state, ins, fp);
24647                 break;
24648         case OP_INB:  case OP_INW:  case OP_INL:
24649                 print_op_in(state, ins, fp); 
24650                 break;
24651         case OP_OUTB: case OP_OUTW: case OP_OUTL:
24652                 print_op_out(state, ins, fp); 
24653                 break;
24654         case OP_BSF:
24655         case OP_BSR:
24656                 print_op_bit_scan(state, ins, fp);
24657                 break;
24658         case OP_RDMSR:
24659                 after_lhs(state, ins);
24660                 fprintf(fp, "\trdmsr\n");
24661                 break;
24662         case OP_WRMSR:
24663                 fprintf(fp, "\twrmsr\n");
24664                 break;
24665         case OP_HLT:
24666                 fprintf(fp, "\thlt\n");
24667                 break;
24668         case OP_SDIVT:
24669                 fprintf(fp, "\tidiv %s\n", reg(state, RHS(ins, 1), REGCM_GPR32));
24670                 break;
24671         case OP_UDIVT:
24672                 fprintf(fp, "\tdiv %s\n", reg(state, RHS(ins, 1), REGCM_GPR32));
24673                 break;
24674         case OP_UMUL:
24675                 fprintf(fp, "\tmul %s\n", reg(state, RHS(ins, 1), REGCM_GPR32));
24676                 break;
24677         case OP_LABEL:
24678                 if (!ins->use) {
24679                         return;
24680                 }
24681                 fprintf(fp, "L%s%lu:\n", 
24682                         state->compiler->label_prefix, (unsigned long)(ins->u.cval));
24683                 break;
24684         case OP_ADECL:
24685                 /* Ignore adecls with no registers error otherwise */
24686                 if (!noop_adecl(ins)) {
24687                         internal_error(state, ins, "adecl remains?");
24688                 }
24689                 break;
24690                 /* Ignore OP_PIECE */
24691         case OP_PIECE:
24692                 break;
24693                 /* Operations that should never get here */
24694         case OP_SDIV: case OP_UDIV:
24695         case OP_SMOD: case OP_UMOD:
24696         case OP_LTRUE:   case OP_LFALSE:  case OP_EQ:      case OP_NOTEQ:
24697         case OP_SLESS:   case OP_ULESS:   case OP_SMORE:   case OP_UMORE:
24698         case OP_SLESSEQ: case OP_ULESSEQ: case OP_SMOREEQ: case OP_UMOREEQ:
24699         default:
24700                 internal_error(state, ins, "unknown op: %d %s",
24701                         ins->op, tops(ins->op));
24702                 break;
24703         }
24704 }
24705
24706 static void print_instructions(struct compile_state *state)
24707 {
24708         struct triple *first, *ins;
24709         int print_location;
24710         struct occurance *last_occurance;
24711         FILE *fp;
24712         int max_inline_depth;
24713         max_inline_depth = 0;
24714         print_location = 1;
24715         last_occurance = 0;
24716         fp = state->output;
24717         /* Masks for common sizes */
24718         fprintf(fp, ".section \"" DATA_SECTION "\"\n");
24719         fprintf(fp, ".balign 16\n");
24720         fprintf(fp, "L%s1:\n", state->compiler->label_prefix);
24721         fprintf(fp, ".int 0xff, 0, 0, 0\n");
24722         fprintf(fp, "L%s2:\n", state->compiler->label_prefix);
24723         fprintf(fp, ".int 0xffff, 0, 0, 0\n");
24724         fprintf(fp, ".section \"" TEXT_SECTION "\"\n");
24725         first = state->first;
24726         ins = first;
24727         do {
24728                 if (print_location && 
24729                         last_occurance != ins->occurance) {
24730                         if (!ins->occurance->parent) {
24731                                 fprintf(fp, "\t/* %s,%s:%d.%d */\n",
24732                                         ins->occurance->function,
24733                                         ins->occurance->filename,
24734                                         ins->occurance->line,
24735                                         ins->occurance->col);
24736                         }
24737                         else {
24738                                 struct occurance *ptr;
24739                                 int inline_depth;
24740                                 fprintf(fp, "\t/*\n");
24741                                 inline_depth = 0;
24742                                 for(ptr = ins->occurance; ptr; ptr = ptr->parent) {
24743                                         inline_depth++;
24744                                         fprintf(fp, "\t * %s,%s:%d.%d\n",
24745                                                 ptr->function,
24746                                                 ptr->filename,
24747                                                 ptr->line,
24748                                                 ptr->col);
24749                                 }
24750                                 fprintf(fp, "\t */\n");
24751                                 if (inline_depth > max_inline_depth) {
24752                                         max_inline_depth = inline_depth;
24753                                 }
24754                         }
24755                         if (last_occurance) {
24756                                 put_occurance(last_occurance);
24757                         }
24758                         get_occurance(ins->occurance);
24759                         last_occurance = ins->occurance;
24760                 }
24761
24762                 print_instruction(state, ins, fp);
24763                 ins = ins->next;
24764         } while(ins != first);
24765         if (print_location) {
24766                 fprintf(fp, "/* max inline depth %d */\n",
24767                         max_inline_depth);
24768         }
24769 }
24770
24771 static void generate_code(struct compile_state *state)
24772 {
24773         generate_local_labels(state);
24774         print_instructions(state);
24775         
24776 }
24777
24778 static void print_preprocessed_tokens(struct compile_state *state)
24779 {
24780         int tok;
24781         FILE *fp;
24782         int line;
24783         const char *filename;
24784         fp = state->output;
24785         filename = 0;
24786         line = 0;
24787         for(;;) {
24788                 struct file_state *file;
24789                 struct token *tk;
24790                 const char *token_str;
24791                 tok = peek(state);
24792                 if (tok == TOK_EOF) {
24793                         break;
24794                 }
24795                 tk = eat(state, tok);
24796                 token_str = 
24797                         tk->ident ? tk->ident->name :
24798                         tk->str_len ? tk->val.str :
24799                         tokens[tk->tok];
24800
24801                 file = state->file;
24802                 while(file->macro && file->prev) {
24803                         file = file->prev;
24804                 }
24805                 if (!file->macro && 
24806                         ((file->line != line) || (file->basename != filename))) 
24807                 {
24808                         int i, col;
24809                         if ((file->basename == filename) &&
24810                                 (line < file->line)) {
24811                                 while(line < file->line) {
24812                                         fprintf(fp, "\n");
24813                                         line++;
24814                                 }
24815                         }
24816                         else {
24817                                 fprintf(fp, "\n#line %d \"%s\"\n",
24818                                         file->line, file->basename);
24819                         }
24820                         line = file->line;
24821                         filename = file->basename;
24822                         col = get_col(file) - strlen(token_str);
24823                         for(i = 0; i < col; i++) {
24824                                 fprintf(fp, " ");
24825                         }
24826                 }
24827                 
24828                 fprintf(fp, "%s ", token_str);
24829                 
24830                 if (state->compiler->debug & DEBUG_TOKENS) {
24831                         loc(state->dbgout, state, 0);
24832                         fprintf(state->dbgout, "%s <- `%s'\n",
24833                                 tokens[tok], token_str);
24834                 }
24835         }
24836 }
24837
24838 static void compile(const char *filename, 
24839         struct compiler_state *compiler, struct arch_state *arch)
24840 {
24841         int i;
24842         struct compile_state state;
24843         struct triple *ptr;
24844         memset(&state, 0, sizeof(state));
24845         state.compiler = compiler;
24846         state.arch     = arch;
24847         state.file = 0;
24848         for(i = 0; i < sizeof(state.token)/sizeof(state.token[0]); i++) {
24849                 memset(&state.token[i], 0, sizeof(state.token[i]));
24850                 state.token[i].tok = -1;
24851         }
24852         /* Remember the output descriptors */
24853         state.errout = stderr;
24854         state.dbgout = stdout;
24855         /* Remember the output filename */
24856         state.output    = fopen(state.compiler->ofilename, "w");
24857         if (!state.output) {
24858                 error(&state, 0, "Cannot open output file %s\n",
24859                         state.compiler->ofilename);
24860         }
24861         /* Make certain a good cleanup happens */
24862         exit_state = &state;
24863         atexit(exit_cleanup);
24864
24865         /* Prep the preprocessor */
24866         state.if_depth = 0;
24867         memset(state.if_bytes, 0, sizeof(state.if_bytes));
24868         /* register the C keywords */
24869         register_keywords(&state);
24870         /* register the keywords the macro preprocessor knows */
24871         register_macro_keywords(&state);
24872         /* generate some builtin macros */
24873         register_builtin_macros(&state);
24874         /* Memorize where some special keywords are. */
24875         state.i_switch        = lookup(&state, "switch", 6);
24876         state.i_case          = lookup(&state, "case", 4);
24877         state.i_continue      = lookup(&state, "continue", 8);
24878         state.i_break         = lookup(&state, "break", 5);
24879         state.i_default       = lookup(&state, "default", 7);
24880         state.i_return        = lookup(&state, "return", 6);
24881         /* Memorize where predefined macros are. */
24882         state.i___VA_ARGS__   = lookup(&state, "__VA_ARGS__", 11);
24883         state.i___FILE__      = lookup(&state, "__FILE__", 8);
24884         state.i___LINE__      = lookup(&state, "__LINE__", 8);
24885         /* Memorize where predefined identifiers are. */
24886         state.i___func__      = lookup(&state, "__func__", 8);
24887         /* Memorize where some attribute keywords are. */
24888         state.i_noinline      = lookup(&state, "noinline", 8);
24889         state.i_always_inline = lookup(&state, "always_inline", 13);
24890
24891         /* Process the command line macros */
24892         process_cmdline_macros(&state);
24893
24894         /* Allocate beginning bounding labels for the function list */
24895         state.first = label(&state);
24896         state.first->id |= TRIPLE_FLAG_VOLATILE;
24897         use_triple(state.first, state.first);
24898         ptr = label(&state);
24899         ptr->id |= TRIPLE_FLAG_VOLATILE;
24900         use_triple(ptr, ptr);
24901         flatten(&state, state.first, ptr);
24902
24903         /* Allocate a label for the pool of global variables */
24904         state.global_pool = label(&state);
24905         state.global_pool->id |= TRIPLE_FLAG_VOLATILE;
24906         flatten(&state, state.first, state.global_pool);
24907
24908         /* Enter the globl definition scope */
24909         start_scope(&state);
24910         register_builtins(&state);
24911         compile_file(&state, filename, 1);
24912
24913         /* Stop if all we want is preprocessor output */
24914         if (state.compiler->flags & COMPILER_PP_ONLY) {
24915                 print_preprocessed_tokens(&state);
24916                 return;
24917         }
24918
24919         decls(&state);
24920
24921         /* Exit the global definition scope */
24922         end_scope(&state);
24923
24924         /* Now that basic compilation has happened 
24925          * optimize the intermediate code 
24926          */
24927         optimize(&state);
24928
24929         generate_code(&state);
24930         if (state.compiler->debug) {
24931                 fprintf(state.errout, "done\n");
24932         }
24933         exit_state = 0;
24934 }
24935
24936 static void version(FILE *fp)
24937 {
24938         fprintf(fp, "romcc " VERSION " released " RELEASE_DATE "\n");
24939 }
24940
24941 static void usage(void)
24942 {
24943         FILE *fp = stdout;
24944         version(fp);
24945         fprintf(fp,
24946                 "\nUsage: romcc [options] <source>.c\n"
24947                 "Compile a C source file generating a binary that does not implicilty use RAM\n"
24948                 "Options: \n"
24949                 "-o <output file name>\n"
24950                 "-f<option>            Specify a generic compiler option\n"
24951                 "-m<option>            Specify a arch dependent option\n"
24952                 "--                    Specify this is the last option\n"
24953                 "\nGeneric compiler options:\n"
24954         );
24955         compiler_usage(fp);
24956         fprintf(fp,
24957                 "\nArchitecture compiler options:\n"
24958         );
24959         arch_usage(fp);
24960         fprintf(fp,
24961                 "\n"
24962         );
24963 }
24964
24965 static void arg_error(char *fmt, ...)
24966 {
24967         va_list args;
24968         va_start(args, fmt);
24969         vfprintf(stderr, fmt, args);
24970         va_end(args);
24971         usage();
24972         exit(1);
24973 }
24974
24975 int main(int argc, char **argv)
24976 {
24977         const char *filename;
24978         struct compiler_state compiler;
24979         struct arch_state arch;
24980         int all_opts;
24981         
24982         
24983         /* I don't want any surprises */
24984         setlocale(LC_ALL, "C");
24985
24986         init_compiler_state(&compiler);
24987         init_arch_state(&arch);
24988         filename = 0;
24989         all_opts = 0;
24990         while(argc > 1) {
24991                 if (!all_opts && (strcmp(argv[1], "-o") == 0) && (argc > 2)) {
24992                         compiler.ofilename = argv[2];
24993                         argv += 2;
24994                         argc -= 2;
24995                 }
24996                 else if (!all_opts && argv[1][0] == '-') {
24997                         int result;
24998                         result = -1;
24999                         if (strcmp(argv[1], "--") == 0) {
25000                                 result = 0;
25001                                 all_opts = 1;
25002                         }
25003                         else if (strncmp(argv[1], "-E", 2) == 0) {
25004                                 result = compiler_encode_flag(&compiler, argv[1]);
25005                         }
25006                         else if (strncmp(argv[1], "-O", 2) == 0) {
25007                                 result = compiler_encode_flag(&compiler, argv[1]);
25008                         }
25009                         else if (strncmp(argv[1], "-I", 2) == 0) {
25010                                 result = compiler_encode_flag(&compiler, argv[1]);
25011                         }
25012                         else if (strncmp(argv[1], "-D", 2) == 0) {
25013                                 result = compiler_encode_flag(&compiler, argv[1]);
25014                         }
25015                         else if (strncmp(argv[1], "-U", 2) == 0) {
25016                                 result = compiler_encode_flag(&compiler, argv[1]);
25017                         }
25018                         else if (strncmp(argv[1], "--label-prefix=", 15) == 0) {
25019                                 result = compiler_encode_flag(&compiler, argv[1]+2);
25020                         }
25021                         else if (strncmp(argv[1], "-f", 2) == 0) {
25022                                 result = compiler_encode_flag(&compiler, argv[1]+2);
25023                         }
25024                         else if (strncmp(argv[1], "-m", 2) == 0) {
25025                                 result = arch_encode_flag(&arch, argv[1]+2);
25026                         }
25027                         if (result < 0) {
25028                                 arg_error("Invalid option specified: %s\n",
25029                                         argv[1]);
25030                         }
25031                         argv++;
25032                         argc--;
25033                 }
25034                 else {
25035                         if (filename) {
25036                                 arg_error("Only one filename may be specified\n");
25037                         }
25038                         filename = argv[1];
25039                         argv++;
25040                         argc--;
25041                 }
25042         }
25043         if (!filename) {
25044                 arg_error("No filename specified\n");
25045         }
25046         compile(filename, &compiler, &arch);
25047
25048         return 0;
25049 }