- reverting back to original romcc.c before hdama checkin broke all
[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 "68"
7 #define RELEASE_DATE "15 November 2004"
8 #define VERSION VERSION_MAJOR "." VERSION_MINOR
9
10 #include <stdarg.h>
11 #include <errno.h>
12 #include <stdint.h>
13 #include <stdlib.h>
14 #include <stdio.h>
15 #include <sys/types.h>
16 #include <sys/stat.h>
17 #include <fcntl.h>
18 #include <unistd.h>
19 #include <stdio.h>
20 #include <string.h>
21 #include <limits.h>
22 #include <locale.h>
23 #include <time.h>
24
25 #define MAX_CWD_SIZE 4096
26 #define MAX_ALLOCATION_PASSES 100
27
28 #define DEBUG_CONSISTENCY 1
29 #define DEBUG_SDP_BLOCKS 0
30 #define DEBUG_TRIPLE_COLOR 0
31
32 #define DEBUG_DISPLAY_USES 1
33 #define DEBUG_DISPLAY_TYPES 1
34 #define DEBUG_REPLACE_CLOSURE_TYPE_HIRES 0
35 #define DEBUG_DECOMPOSE_PRINT_TUPLES 0
36 #define DEBUG_DECOMPOSE_HIRES  0
37 #define DEBUG_INITIALIZER 0
38 #define DEBUG_UPDATE_CLOSURE_TYPE 0
39 #define DEBUG_LOCAL_TRIPLE 0
40 #define DEBUG_BASIC_BLOCKS_VERBOSE 0
41 #define DEBUG_CPS_RENAME_VARIABLES_HIRES 0
42 #define DEBUG_SIMPLIFY_HIRES 0
43 #define DEBUG_SHRINKING 0
44 #define DEBUG_COALESCE_HITCHES 0
45 #define DEBUG_CODE_ELIMINATION 0
46
47 #define DEBUG_EXPLICIT_CLOSURES 0
48
49 #warning "FIXME give clear error messages about unused variables"
50 #warning "FIXME properly handle multi dimensional arrays"
51 #warning "FIXME handle multiple register sizes"
52
53 /*  Control flow graph of a loop without goto.
54  * 
55  *        AAA
56  *   +---/
57  *  /
58  * / +--->CCC
59  * | |    / \
60  * | |  DDD EEE    break;
61  * | |    \    \
62  * | |    FFF   \
63  *  \|    / \    \
64  *   |\ GGG HHH   |   continue;
65  *   | \  \   |   |
66  *   |  \ III |  /
67  *   |   \ | /  / 
68  *   |    vvv  /  
69  *   +----BBB /   
70  *         | /
71  *         vv
72  *        JJJ
73  *
74  * 
75  *             AAA
76  *     +-----+  |  +----+
77  *     |      \ | /     |
78  *     |       BBB  +-+ |
79  *     |       / \ /  | |
80  *     |     CCC JJJ / /
81  *     |     / \    / / 
82  *     |   DDD EEE / /  
83  *     |    |   +-/ /
84  *     |   FFF     /    
85  *     |   / \    /     
86  *     | GGG HHH /      
87  *     |  |   +-/
88  *     | III
89  *     +--+ 
90  *
91  * 
92  * DFlocal(X) = { Y <- Succ(X) | idom(Y) != X }
93  * DFup(Z)    = { Y <- DF(Z) | idom(Y) != X }
94  *
95  *
96  * [] == DFlocal(X) U DF(X)
97  * () == DFup(X)
98  *
99  * Dominator graph of the same nodes.
100  *
101  *           AAA     AAA: [ ] ()
102  *          /   \
103  *        BBB    JJJ BBB: [ JJJ ] ( JJJ )  JJJ: [ ] ()
104  *         |
105  *        CCC        CCC: [ ] ( BBB, JJJ )
106  *        / \
107  *     DDD   EEE     DDD: [ ] ( BBB ) EEE: [ JJJ ] ()
108  *      |
109  *     FFF           FFF: [ ] ( BBB )
110  *     / \         
111  *  GGG   HHH        GGG: [ ] ( BBB ) HHH: [ BBB ] ()
112  *   |
113  *  III              III: [ BBB ] ()
114  *
115  *
116  * BBB and JJJ are definitely the dominance frontier.
117  * Where do I place phi functions and how do I make that decision.
118  *   
119  */
120 static void die(char *fmt, ...)
121 {
122         va_list args;
123
124         va_start(args, fmt);
125         vfprintf(stderr, fmt, args);
126         va_end(args);
127         fflush(stdout);
128         fflush(stderr);
129         exit(1);
130 }
131
132 static void *xmalloc(size_t size, const char *name)
133 {
134         void *buf;
135         buf = malloc(size);
136         if (!buf) {
137                 die("Cannot malloc %ld bytes to hold %s: %s\n",
138                         size + 0UL, name, strerror(errno));
139         }
140         return buf;
141 }
142
143 static void *xcmalloc(size_t size, const char *name)
144 {
145         void *buf;
146         buf = xmalloc(size, name);
147         memset(buf, 0, size);
148         return buf;
149 }
150
151 static void *xrealloc(void *ptr, size_t size, const char *name)
152 {
153         void *buf;
154         buf = realloc(ptr, size);
155         if (!buf) {
156                 die("Cannot realloc %ld bytes to hold %s: %s\n",
157                         size + 0UL, name, strerror(errno));
158         }
159         return buf;
160 }
161
162 static void xfree(const void *ptr)
163 {
164         free((void *)ptr);
165 }
166
167 static char *xstrdup(const char *str)
168 {
169         char *new;
170         int len;
171         len = strlen(str);
172         new = xmalloc(len + 1, "xstrdup string");
173         memcpy(new, str, len);
174         new[len] = '\0';
175         return new;
176 }
177
178 static void xchdir(const char *path)
179 {
180         if (chdir(path) != 0) {
181                 die("chdir to `%s' failed: %s\n",
182                         path, strerror(errno));
183         }
184 }
185
186 static int exists(const char *dirname, const char *filename)
187 {
188         char cwd[MAX_CWD_SIZE];
189         int does_exist;
190
191         if (getcwd(cwd, sizeof(cwd)) == 0) {
192                 die("cwd buffer to small");
193         }
194
195         does_exist = 1;
196         if (chdir(dirname) != 0) {
197                 does_exist = 0;
198         }
199         if (does_exist && (access(filename, O_RDONLY) < 0)) {
200                 if ((errno != EACCES) && (errno != EROFS)) {
201                         does_exist = 0;
202                 }
203         }
204         xchdir(cwd);
205         return does_exist;
206 }
207
208
209 static char *slurp_file(const char *dirname, const char *filename, off_t *r_size)
210 {
211         char cwd[MAX_CWD_SIZE];
212         int fd;
213         char *buf;
214         off_t size, progress;
215         ssize_t result;
216         struct stat stats;
217         
218         if (!filename) {
219                 *r_size = 0;
220                 return 0;
221         }
222         if (getcwd(cwd, sizeof(cwd)) == 0) {
223                 die("cwd buffer to small");
224         }
225         xchdir(dirname);
226         fd = open(filename, O_RDONLY);
227         xchdir(cwd);
228         if (fd < 0) {
229                 die("Cannot open '%s' : %s\n",
230                         filename, strerror(errno));
231         }
232         result = fstat(fd, &stats);
233         if (result < 0) {
234                 die("Cannot stat: %s: %s\n",
235                         filename, strerror(errno));
236         }
237         size = stats.st_size;
238         *r_size = size +1;
239         buf = xmalloc(size +2, filename);
240         buf[size] = '\n'; /* Make certain the file is newline terminated */
241         buf[size+1] = '\0'; /* Null terminate the file for good measure */
242         progress = 0;
243         while(progress < size) {
244                 result = read(fd, buf + progress, size - progress);
245                 if (result < 0) {
246                         if ((errno == EINTR) || (errno == EAGAIN))
247                                 continue;
248                         die("read on %s of %ld bytes failed: %s\n",
249                                 filename, (size - progress)+ 0UL, strerror(errno));
250                 }
251                 progress += result;
252         }
253         result = close(fd);
254         if (result < 0) {
255                 die("Close of %s failed: %s\n",
256                         filename, strerror(errno));
257         }
258         return buf;
259 }
260
261 /* Types on the destination platform */
262 #warning "FIXME this assumes 32bit x86 is the destination"
263 typedef int8_t   schar_t;
264 typedef uint8_t  uchar_t;
265 typedef int8_t   char_t;
266 typedef int16_t  short_t;
267 typedef uint16_t ushort_t;
268 typedef int32_t  int_t;
269 typedef uint32_t uint_t;
270 typedef int32_t  long_t;
271 typedef uint32_t ulong_t;
272
273 #define SCHAR_T_MIN (-128)
274 #define SCHAR_T_MAX 127
275 #define UCHAR_T_MAX 255
276 #define CHAR_T_MIN  SCHAR_T_MIN
277 #define CHAR_T_MAX  SCHAR_T_MAX
278 #define SHRT_T_MIN  (-32768)
279 #define SHRT_T_MAX  32767
280 #define USHRT_T_MAX 65535
281 #define INT_T_MIN   (-LONG_T_MAX - 1)
282 #define INT_T_MAX   2147483647
283 #define UINT_T_MAX  4294967295U
284 #define LONG_T_MIN  (-LONG_T_MAX - 1)
285 #define LONG_T_MAX  2147483647
286 #define ULONG_T_MAX 4294967295U
287
288 #define SIZEOF_I8    8
289 #define SIZEOF_I16   16
290 #define SIZEOF_I32   32
291 #define SIZEOF_I64   64
292
293 #define SIZEOF_CHAR    8
294 #define SIZEOF_SHORT   16
295 #define SIZEOF_INT     32
296 #define SIZEOF_LONG    (sizeof(long_t)*SIZEOF_CHAR)
297
298
299 #define ALIGNOF_CHAR    8
300 #define ALIGNOF_SHORT   16
301 #define ALIGNOF_INT     32
302 #define ALIGNOF_LONG    (sizeof(long_t)*SIZEOF_CHAR)
303
304 #define REG_SIZEOF_REG     32
305 #define REG_SIZEOF_CHAR    REG_SIZEOF_REG
306 #define REG_SIZEOF_SHORT   REG_SIZEOF_REG
307 #define REG_SIZEOF_INT     REG_SIZEOF_REG
308 #define REG_SIZEOF_LONG    REG_SIZEOF_REG
309
310 #define REG_ALIGNOF_REG     REG_SIZEOF_REG
311 #define REG_ALIGNOF_CHAR    REG_SIZEOF_REG
312 #define REG_ALIGNOF_SHORT   REG_SIZEOF_REG
313 #define REG_ALIGNOF_INT     REG_SIZEOF_REG
314 #define REG_ALIGNOF_LONG    REG_SIZEOF_REG
315
316 /* Additional definitions for clarity.
317  * I currently assume a long is the largest native
318  * machine word and that a pointer fits into it.
319  */
320 #define SIZEOF_WORD     SIZEOF_LONG
321 #define SIZEOF_POINTER  SIZEOF_LONG
322 #define ALIGNOF_WORD    ALIGNOF_LONG
323 #define ALIGNOF_POINTER ALIGNOF_LONG
324 #define REG_SIZEOF_POINTER  REG_SIZEOF_LONG
325 #define REG_ALIGNOF_POINTER REG_ALIGNOF_LONG
326
327 struct file_state {
328         struct file_state *prev;
329         const char *basename;
330         char *dirname;
331         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                         tokp = next_char(file, tokp, 1);
4032                         if (c == '\n') {
4033                                 break;
4034                         }
4035                 }
4036         }
4037         /* Comments */
4038         else if ((c == '/') && (c1 == '*')) {
4039                 tokp = next_char(file, tokp, 2);
4040                 c = c2;
4041                 while((c1 = get_char(file, tokp)) != -1) {
4042                         tokp = next_char(file, tokp, 1);
4043                         if ((c == '*') && (c1 == '/')) {
4044                                 tok = TOK_SPACE;
4045                                 break;
4046                         }
4047                         c = c1;
4048                 }
4049                 if (tok == TOK_UNKNOWN) {
4050                         error(state, 0, "unterminated comment");
4051                 }
4052         }
4053         /* string constants */
4054         else if ((c == '"') || ((c == 'L') && (c1 == '"'))) {
4055                 int wchar, multiline;
4056
4057                 wchar = 0;
4058                 multiline = 0;
4059                 if (c == 'L') {
4060                         wchar = 1;
4061                         tokp = next_char(file, tokp, 1);
4062                 }
4063                 while((c = get_char(file, tokp)) != -1) {
4064                         tokp = next_char(file, tokp, 1);
4065                         if (c == '\n') {
4066                                 multiline = 1;
4067                         }
4068                         else if (c == '\\') {
4069                                 tokp = next_char(file, tokp, 1);
4070                         }
4071                         else if (c == '"') {
4072                                 tok = TOK_LIT_STRING;
4073                                 break;
4074                         }
4075                 }
4076                 if (tok == TOK_UNKNOWN) {
4077                         error(state, 0, "unterminated string constant");
4078                 }
4079                 if (multiline) {
4080                         warning(state, 0, "multiline string constant");
4081                 }
4082
4083                 /* Save the string value */
4084                 save_string(file, tk, token, tokp, "literal string");
4085         }
4086         /* character constants */
4087         else if ((c == '\'') || ((c == 'L') && (c1 == '\''))) {
4088                 int wchar, multiline;
4089
4090                 wchar = 0;
4091                 multiline = 0;
4092                 if (c == 'L') {
4093                         wchar = 1;
4094                         tokp = next_char(file, tokp, 1);
4095                 }
4096                 while((c = get_char(file, tokp)) != -1) {
4097                         tokp = next_char(file, tokp, 1);
4098                         if (c == '\n') {
4099                                 multiline = 1;
4100                         }
4101                         else if (c == '\\') {
4102                                 tokp = next_char(file, tokp, 1);
4103                         }
4104                         else if (c == '\'') {
4105                                 tok = TOK_LIT_CHAR;
4106                                 break;
4107                         }
4108                 }
4109                 if (tok == TOK_UNKNOWN) {
4110                         error(state, 0, "unterminated character constant");
4111                 }
4112                 if (multiline) {
4113                         warning(state, 0, "multiline character constant");
4114                 }
4115
4116                 /* Save the character value */
4117                 save_string(file, tk, token, tokp, "literal character");
4118         }
4119         /* integer and floating constants 
4120          * Integer Constants
4121          * {digits}
4122          * 0[Xx]{hexdigits}
4123          * 0{octdigit}+
4124          * 
4125          * Floating constants
4126          * {digits}.{digits}[Ee][+-]?{digits}
4127          * {digits}.{digits}
4128          * {digits}[Ee][+-]?{digits}
4129          * .{digits}[Ee][+-]?{digits}
4130          * .{digits}
4131          */
4132         else if (digitp(c) || ((c == '.') && (digitp(c1)))) {
4133                 const char *next;
4134                 int is_float;
4135                 int cn;
4136                 is_float = 0;
4137                 if (c != '.') {
4138                         next = after_digits(file, tokp);
4139                 }
4140                 else {
4141                         next = token;
4142                 }
4143                 cn = get_char(file, next);
4144                 if (cn == '.') {
4145                         next = next_char(file, next, 1);
4146                         next = after_digits(file, next);
4147                         is_float = 1;
4148                 }
4149                 cn = get_char(file, next);
4150                 if ((cn == 'e') || (cn == 'E')) {
4151                         const char *new;
4152                         next = next_char(file, next, 1);
4153                         cn = get_char(file, next);
4154                         if ((cn == '+') || (cn == '-')) {
4155                                 next = next_char(file, next, 1);
4156                         }
4157                         new = after_digits(file, next);
4158                         is_float |= (new != next);
4159                         next = new;
4160                 }
4161                 if (is_float) {
4162                         tok = TOK_LIT_FLOAT;
4163                         cn = get_char(file, next);
4164                         if ((cn  == 'f') || (cn == 'F') || (cn == 'l') || (cn == 'L')) {
4165                                 next = next_char(file, next, 1);
4166                         }
4167                 }
4168                 if (!is_float && digitp(c)) {
4169                         tok = TOK_LIT_INT;
4170                         if ((c == '0') && ((c1 == 'x') || (c1 == 'X'))) {
4171                                 next = next_char(file, tokp, 1);
4172                                 next = after_hexdigits(file, next);
4173                         }
4174                         else if (c == '0') {
4175                                 next = after_octdigits(file, tokp);
4176                         }
4177                         else {
4178                                 next = after_digits(file, tokp);
4179                         }
4180                         /* crazy integer suffixes */
4181                         cn = get_char(file, next);
4182                         if ((cn == 'u') || (cn == 'U')) {
4183                                 next = next_char(file, next, 1);
4184                                 cn = get_char(file, next);
4185                                 if ((cn == 'l') || (cn == 'L')) {
4186                                         next = next_char(file, next, 1);
4187                                         cn = get_char(file, next);
4188                                 }
4189                                 if ((cn == 'l') || (cn == 'L')) {
4190                                         next = next_char(file, next, 1);
4191                                 }
4192                         }
4193                         else if ((cn == 'l') || (cn == 'L')) {
4194                                 next = next_char(file, next, 1);
4195                                 cn = get_char(file, next);
4196                                 if ((cn == 'l') || (cn == 'L')) {
4197                                         next = next_char(file, next, 1);
4198                                         cn = get_char(file, next);
4199                                 }
4200                                 if ((cn == 'u') || (cn == 'U')) {
4201                                         next = next_char(file, next, 1);
4202                                 }
4203                         }
4204                 }
4205                 tokp = next;
4206
4207                 /* Save the integer/floating point value */
4208                 save_string(file, tk, token, tokp, "literal number");
4209         }
4210         /* identifiers */
4211         else if (letterp(c)) {
4212                 tok = TOK_IDENT;
4213
4214                 /* Find and save the identifier string */
4215                 tokp = after_alnums(file, tokp);
4216                 save_string(file, tk, token, tokp, "identifier");
4217
4218                 /* Look up to see which identifier it is */
4219                 tk->ident = lookup(state, tk->val.str, tk->str_len);
4220
4221                 /* Free the identifier string */
4222                 tk->str_len = 0;
4223                 xfree(tk->val.str);
4224
4225                 /* See if this identifier can be macro expanded */
4226                 tk->val.notmacro = 0;
4227                 c = get_char(file, tokp);
4228                 if (c == '$') {
4229                         tokp = next_char(file, tokp, 1);
4230                         tk->val.notmacro = 1;
4231                 }
4232         }
4233         /* C99 alternate macro characters */
4234         else if ((c == '%') && (c1 == ':') && (c2 == '%') && (c3 == ':')) { 
4235                 eat += 3;
4236                 tok = TOK_CONCATENATE; 
4237         }
4238         else if ((c == '.') && (c1 == '.') && (c2 == '.')) { eat += 2; tok = TOK_DOTS; }
4239         else if ((c == '<') && (c1 == '<') && (c2 == '=')) { eat += 2; tok = TOK_SLEQ; }
4240         else if ((c == '>') && (c1 == '>') && (c2 == '=')) { eat += 2; tok = TOK_SREQ; }
4241         else if ((c == '*') && (c1 == '=')) { eat += 1; tok = TOK_TIMESEQ; }
4242         else if ((c == '/') && (c1 == '=')) { eat += 1; tok = TOK_DIVEQ; }
4243         else if ((c == '%') && (c1 == '=')) { eat += 1; tok = TOK_MODEQ; }
4244         else if ((c == '+') && (c1 == '=')) { eat += 1; tok = TOK_PLUSEQ; }
4245         else if ((c == '-') && (c1 == '=')) { eat += 1; tok = TOK_MINUSEQ; }
4246         else if ((c == '&') && (c1 == '=')) { eat += 1; tok = TOK_ANDEQ; }
4247         else if ((c == '^') && (c1 == '=')) { eat += 1; tok = TOK_XOREQ; }
4248         else if ((c == '|') && (c1 == '=')) { eat += 1; tok = TOK_OREQ; }
4249         else if ((c == '=') && (c1 == '=')) { eat += 1; tok = TOK_EQEQ; }
4250         else if ((c == '!') && (c1 == '=')) { eat += 1; tok = TOK_NOTEQ; }
4251         else if ((c == '|') && (c1 == '|')) { eat += 1; tok = TOK_LOGOR; }
4252         else if ((c == '&') && (c1 == '&')) { eat += 1; tok = TOK_LOGAND; }
4253         else if ((c == '<') && (c1 == '=')) { eat += 1; tok = TOK_LESSEQ; }
4254         else if ((c == '>') && (c1 == '=')) { eat += 1; tok = TOK_MOREEQ; }
4255         else if ((c == '<') && (c1 == '<')) { eat += 1; tok = TOK_SL; }
4256         else if ((c == '>') && (c1 == '>')) { eat += 1; tok = TOK_SR; }
4257         else if ((c == '+') && (c1 == '+')) { eat += 1; tok = TOK_PLUSPLUS; }
4258         else if ((c == '-') && (c1 == '-')) { eat += 1; tok = TOK_MINUSMINUS; }
4259         else if ((c == '-') && (c1 == '>')) { eat += 1; tok = TOK_ARROW; }
4260         else if ((c == '<') && (c1 == ':')) { eat += 1; tok = TOK_LBRACKET; }
4261         else if ((c == ':') && (c1 == '>')) { eat += 1; tok = TOK_RBRACKET; }
4262         else if ((c == '<') && (c1 == '%')) { eat += 1; tok = TOK_LBRACE; }
4263         else if ((c == '%') && (c1 == '>')) { eat += 1; tok = TOK_RBRACE; }
4264         else if ((c == '%') && (c1 == ':')) { eat += 1; tok = TOK_MACRO; }
4265         else if ((c == '#') && (c1 == '#')) { eat += 1; tok = TOK_CONCATENATE; }
4266         else if (c == ';') { tok = TOK_SEMI; }
4267         else if (c == '{') { tok = TOK_LBRACE; }
4268         else if (c == '}') { tok = TOK_RBRACE; }
4269         else if (c == ',') { tok = TOK_COMMA; }
4270         else if (c == '=') { tok = TOK_EQ; }
4271         else if (c == ':') { tok = TOK_COLON; }
4272         else if (c == '[') { tok = TOK_LBRACKET; }
4273         else if (c == ']') { tok = TOK_RBRACKET; }
4274         else if (c == '(') { tok = TOK_LPAREN; }
4275         else if (c == ')') { tok = TOK_RPAREN; }
4276         else if (c == '*') { tok = TOK_STAR; }
4277         else if (c == '>') { tok = TOK_MORE; }
4278         else if (c == '<') { tok = TOK_LESS; }
4279         else if (c == '?') { tok = TOK_QUEST; }
4280         else if (c == '|') { tok = TOK_OR; }
4281         else if (c == '&') { tok = TOK_AND; }
4282         else if (c == '^') { tok = TOK_XOR; }
4283         else if (c == '+') { tok = TOK_PLUS; }
4284         else if (c == '-') { tok = TOK_MINUS; }
4285         else if (c == '/') { tok = TOK_DIV; }
4286         else if (c == '%') { tok = TOK_MOD; }
4287         else if (c == '!') { tok = TOK_BANG; }
4288         else if (c == '.') { tok = TOK_DOT; }
4289         else if (c == '~') { tok = TOK_TILDE; }
4290         else if (c == '#') { tok = TOK_MACRO; }
4291         else if (c == '\n') { tok = TOK_EOL; }
4292
4293         tokp = next_char(file, tokp, eat);
4294         eat_chars(file, tokp);
4295         tk->tok = tok;
4296         tk->pos = token;
4297 }
4298
4299 static void check_tok(struct compile_state *state, struct token *tk, int tok)
4300 {
4301         if (tk->tok != tok) {
4302                 const char *name1, *name2;
4303                 name1 = tokens[tk->tok];
4304                 name2 = "";
4305                 if ((tk->tok == TOK_IDENT) || (tk->tok == TOK_MIDENT)) {
4306                         name2 = tk->ident->name;
4307                 }
4308                 error(state, 0, "\tfound %s %s expected %s",
4309                         name1, name2, tokens[tok]);
4310         }
4311 }
4312
4313 struct macro_arg_value {
4314         struct hash_entry *ident;
4315         unsigned char *value;
4316         size_t len;
4317 };
4318 static struct macro_arg_value *read_macro_args(
4319         struct compile_state *state, struct macro *macro, 
4320         struct file_state *file, struct token *tk)
4321 {
4322         struct macro_arg_value *argv;
4323         struct macro_arg *arg;
4324         int paren_depth;
4325         int i;
4326
4327         if (macro->argc == 0) {
4328                 do {
4329                         raw_next_token(state, file, tk);
4330                 } while(tk->tok == TOK_SPACE);
4331                 return NULL;
4332         }
4333         argv = xcmalloc(sizeof(*argv) * macro->argc, "macro args");
4334         for(i = 0, arg = macro->args; arg; arg = arg->next, i++) {
4335                 argv[i].value = 0;
4336                 argv[i].len   = 0;
4337                 argv[i].ident = arg->ident;
4338         }
4339         paren_depth = 0;
4340         i = 0;
4341         
4342         for(;;) {
4343                 const char *start;
4344                 size_t len;
4345                 start = file->pos;
4346                 raw_next_token(state, file, tk);
4347                 
4348                 if (!paren_depth && (tk->tok == TOK_COMMA) &&
4349                         (argv[i].ident != state->i___VA_ARGS__)) 
4350                 {
4351                         i++;
4352                         if (i >= macro->argc) {
4353                                 error(state, 0, "too many args to %s\n",
4354                                         macro->ident->name);
4355                         }
4356                         continue;
4357                 }
4358                 
4359                 if (tk->tok == TOK_LPAREN) {
4360                         paren_depth++;
4361                 }
4362                 
4363                 if (tk->tok == TOK_RPAREN) {
4364                         if (paren_depth == 0) {
4365                                 break;
4366                         }
4367                         paren_depth--;
4368                 }
4369                 if (tk->tok == TOK_EOF) {
4370                         error(state, 0, "End of file encountered while parsing macro arguments");
4371                 }
4372
4373                 len = char_strlen(file, start, file->pos);
4374                 argv[i].value = xrealloc(
4375                         argv[i].value, argv[i].len + len, "macro args");
4376                 char_strcpy(argv[i].value + argv[i].len, file, start, file->pos);
4377                 argv[i].len += len;
4378         }
4379         if (i != macro->argc -1) {
4380                 error(state, 0, "missing %s arg %d\n", 
4381                         macro->ident->name, i +2);
4382         }
4383         return argv;
4384 }
4385
4386
4387 static void free_macro_args(struct macro *macro, struct macro_arg_value *argv)
4388 {
4389         int i;
4390         for(i = 0; i < macro->argc; i++) {
4391                 xfree(argv[i].value);
4392         }
4393         xfree(argv);
4394 }
4395
4396 struct macro_buf {
4397         char *str;
4398         size_t len, pos;
4399 };
4400
4401 static void grow_macro_buf(struct compile_state *state,
4402         const char *id, struct macro_buf *buf,
4403         size_t grow)
4404 {
4405         if ((buf->pos + grow) >= buf->len) {
4406                 buf->str = xrealloc(buf->str, buf->len + grow, id);
4407                 buf->len += grow;
4408         }
4409 }
4410
4411 static void append_macro_text(struct compile_state *state,
4412         const char *id, struct macro_buf *buf,
4413         const char *fstart, size_t flen)
4414 {
4415         grow_macro_buf(state, id, buf, flen);
4416         memcpy(buf->str + buf->pos, fstart, flen);
4417 #if 0
4418         fprintf(state->errout, "append: `%*.*s' `%*.*s'\n",
4419                 buf->pos, buf->pos, buf->str,
4420                 flen, flen, buf->str + buf->pos);
4421 #endif
4422         buf->pos += flen;
4423 }
4424
4425
4426 static void append_macro_chars(struct compile_state *state,
4427         const char *id, struct macro_buf *buf,
4428         struct file_state *file, const char *start, const char *end)
4429 {
4430         size_t flen;
4431         flen = char_strlen(file, start, end);
4432         grow_macro_buf(state, id, buf, flen);
4433         char_strcpy(buf->str + buf->pos, file, start, end);
4434 #if 0
4435         fprintf(state->errout, "append: `%*.*s' `%*.*s'\n",
4436                 buf->pos, buf->pos, buf->str,
4437                 flen, flen, buf->str + buf->pos);
4438 #endif
4439         buf->pos += flen;
4440 }
4441
4442 static int compile_macro(struct compile_state *state, 
4443         struct file_state **filep, struct token *tk);
4444
4445 static void macro_expand_args(struct compile_state *state, 
4446         struct macro *macro, struct macro_arg_value *argv, struct token *tk)
4447 {
4448         int i;
4449         
4450         for(i = 0; i < macro->argc; i++) {
4451                 struct file_state fmacro, *file;
4452                 struct macro_buf buf;
4453
4454                 fmacro.prev        = 0;
4455                 fmacro.basename    = argv[i].ident->name;
4456                 fmacro.dirname     = "";
4457                 fmacro.buf         = argv[i].value;
4458                 fmacro.size        = argv[i].len;
4459                 fmacro.pos         = fmacro.buf;
4460                 fmacro.line        = 1;
4461                 fmacro.line_start  = fmacro.buf;
4462                 fmacro.report_line = 1;
4463                 fmacro.report_name = fmacro.basename;
4464                 fmacro.report_dir  = fmacro.dirname;
4465                 fmacro.macro       = 1;
4466                 fmacro.trigraphs   = 0;
4467                 fmacro.join_lines  = 0;
4468
4469                 buf.len = argv[i].len;
4470                 buf.str = xmalloc(buf.len, argv[i].ident->name);
4471                 buf.pos = 0;
4472
4473                 file = &fmacro;
4474                 for(;;) {
4475                         raw_next_token(state, file, tk);
4476                         
4477                         /* If we have recursed into another macro body
4478                          * get out of it.
4479                          */
4480                         if (tk->tok == TOK_EOF) {
4481                                 struct file_state *old;
4482                                 old = file;
4483                                 file = file->prev;
4484                                 if (!file) {
4485                                         break;
4486                                 }
4487                                 /* old->basename is used keep it */
4488                                 xfree(old->dirname);
4489                                 xfree(old->buf);
4490                                 xfree(old);
4491                                 continue;
4492                         }
4493                         else if (tk->ident && tk->ident->sym_define) {
4494                                 if (compile_macro(state, &file, tk)) {
4495                                         continue;
4496                                 }
4497                         }
4498
4499                         append_macro_chars(state, macro->ident->name, &buf,
4500                                 file, tk->pos, file->pos);
4501                 }
4502                         
4503                 xfree(argv[i].value);
4504                 argv[i].value = buf.str;
4505                 argv[i].len   = buf.pos;
4506         }
4507         return;
4508 }
4509
4510 static void expand_macro(struct compile_state *state,
4511         struct macro *macro, struct macro_buf *buf,
4512         struct macro_arg_value *argv, struct token *tk)
4513 {
4514         struct file_state fmacro;
4515         const char space[] = " ";
4516         const char *fstart;
4517         size_t flen;
4518         int i, j;
4519
4520         /* Place the macro body in a dummy file */
4521         fmacro.prev        = 0;
4522         fmacro.basename    = macro->ident->name;
4523         fmacro.dirname     = "";
4524         fmacro.buf         = macro->buf;
4525         fmacro.size        = macro->buf_len;
4526         fmacro.pos         = fmacro.buf;
4527         fmacro.line        = 1;
4528         fmacro.line_start  = fmacro.buf;
4529         fmacro.report_line = 1;
4530         fmacro.report_name = fmacro.basename;
4531         fmacro.report_dir  = fmacro.dirname;
4532         fmacro.macro       = 1;
4533         fmacro.trigraphs   = 0;
4534         fmacro.join_lines  = 0;
4535         
4536         /* Allocate a buffer to hold the macro expansion */
4537         buf->len = macro->buf_len + 3;
4538         buf->str = xmalloc(buf->len, macro->ident->name);
4539         buf->pos = 0;
4540         
4541         fstart = fmacro.pos;
4542         raw_next_token(state, &fmacro, tk);
4543         while(tk->tok != TOK_EOF) {
4544                 flen = fmacro.pos - fstart;
4545                 switch(tk->tok) {
4546                 case TOK_IDENT:
4547                         for(i = 0; i < macro->argc; i++) {
4548                                 if (argv[i].ident == tk->ident) {
4549                                         break;
4550                                 }
4551                         }
4552                         if (i >= macro->argc) {
4553                                 break;
4554                         }
4555                         /* Substitute macro parameter */
4556                         fstart = argv[i].value;
4557                         flen   = argv[i].len;
4558                         break;
4559                 case TOK_MACRO:
4560                         if (macro->argc < 0) {
4561                                 break;
4562                         }
4563                         do {
4564                                 raw_next_token(state, &fmacro, tk);
4565                         } while(tk->tok == TOK_SPACE);
4566                         check_tok(state, tk, TOK_IDENT);
4567                         for(i = 0; i < macro->argc; i++) {
4568                                 if (argv[i].ident == tk->ident) {
4569                                         break;
4570                                 }
4571                         }
4572                         if (i >= macro->argc) {
4573                                 error(state, 0, "parameter `%s' not found",
4574                                         tk->ident->name);
4575                         }
4576                         /* Stringize token */
4577                         append_macro_text(state, macro->ident->name, buf, "\"", 1);
4578                         for(j = 0; j < argv[i].len; j++) {
4579                                 char *str = argv[i].value + j;
4580                                 size_t len = 1;
4581                                 if (*str == '\\') {
4582                                         str = "\\";
4583                                         len = 2;
4584                                 } 
4585                                 else if (*str == '"') {
4586                                         str = "\\\"";
4587                                         len = 2;
4588                                 }
4589                                 append_macro_text(state, macro->ident->name, buf, str, len);
4590                         }
4591                         append_macro_text(state, macro->ident->name, buf, "\"", 1);
4592                         fstart = 0;
4593                         flen   = 0;
4594                         break;
4595                 case TOK_CONCATENATE:
4596                         /* Concatenate tokens */
4597                         /* Delete the previous whitespace token */
4598                         if (buf->str[buf->pos - 1] == ' ') {
4599                                 buf->pos -= 1;
4600                         }
4601                         /* Skip the next sequence of whitspace tokens */
4602                         do {
4603                                 fstart = fmacro.pos;
4604                                 raw_next_token(state, &fmacro, tk);
4605                         } while(tk->tok == TOK_SPACE);
4606                         /* Restart at the top of the loop.
4607                          * I need to process the non white space token.
4608                          */
4609                         continue;
4610                         break;
4611                 case TOK_SPACE:
4612                         /* Collapse multiple spaces into one */
4613                         if (buf->str[buf->pos - 1] != ' ') {
4614                                 fstart = space;
4615                                 flen   = 1;
4616                         } else {
4617                                 fstart = 0;
4618                                 flen   = 0;
4619                         }
4620                         break;
4621                 default:
4622                         break;
4623                 }
4624
4625                 append_macro_text(state, macro->ident->name, buf, fstart, flen);
4626                 
4627                 fstart = fmacro.pos;
4628                 raw_next_token(state, &fmacro, tk);
4629         }
4630 }
4631
4632 static void tag_macro_name(struct compile_state *state,
4633         struct macro *macro, struct macro_buf *buf,
4634         struct token *tk)
4635 {
4636         /* Guard all instances of the macro name in the replacement
4637          * text from further macro expansion.
4638          */
4639         struct file_state fmacro;
4640         const char *fstart;
4641         size_t flen;
4642
4643         /* Put the old macro expansion buffer in a file */
4644         fmacro.prev        = 0;
4645         fmacro.basename    = macro->ident->name;
4646         fmacro.dirname     = "";
4647         fmacro.buf         = buf->str;
4648         fmacro.size        = buf->pos;
4649         fmacro.pos         = fmacro.buf;
4650         fmacro.line        = 1;
4651         fmacro.line_start  = fmacro.buf;
4652         fmacro.report_line = 1;
4653         fmacro.report_name = fmacro.basename;
4654         fmacro.report_dir  = fmacro.dirname;
4655         fmacro.macro       = 1;
4656         fmacro.trigraphs   = 0;
4657         fmacro.join_lines  = 0;
4658         
4659         /* Allocate a new macro expansion buffer */
4660         buf->len = macro->buf_len + 3;
4661         buf->str = xmalloc(buf->len, macro->ident->name);
4662         buf->pos = 0;
4663         
4664         fstart = fmacro.pos;
4665         raw_next_token(state, &fmacro, tk);
4666         while(tk->tok != TOK_EOF) {
4667                 flen = fmacro.pos - fstart;
4668                 if ((tk->tok == TOK_IDENT) &&
4669                         (tk->ident == macro->ident) &&
4670                         (tk->val.notmacro == 0)) 
4671                 {
4672                         append_macro_text(state, macro->ident->name, buf, fstart, flen);
4673                         fstart = "$";
4674                         flen   = 1;
4675                 }
4676
4677                 append_macro_text(state, macro->ident->name, buf, fstart, flen);
4678                 
4679                 fstart = fmacro.pos;
4680                 raw_next_token(state, &fmacro, tk);
4681         }
4682         xfree(fmacro.buf);
4683 }
4684
4685 static int compile_macro(struct compile_state *state, 
4686         struct file_state **filep, struct token *tk)
4687 {
4688         struct file_state *file;
4689         struct hash_entry *ident;
4690         struct macro *macro;
4691         struct macro_arg_value *argv;
4692         struct macro_buf buf;
4693
4694 #if 0
4695         fprintf(state->errout, "macro: %s\n", tk->ident->name);
4696 #endif
4697         ident = tk->ident;
4698         macro = ident->sym_define;
4699
4700         /* If this token comes from a macro expansion ignore it */
4701         if (tk->val.notmacro) {
4702                 return 0;
4703         }
4704         /* If I am a function like macro and the identifier is not followed
4705          * by a left parenthesis, do nothing.
4706          */
4707         if ((macro->argc >= 0) && (get_char(*filep, (*filep)->pos) != '(')) {
4708                 return 0;
4709         }
4710
4711         /* Read in the macro arguments */
4712         argv = 0;
4713         if (macro->argc >= 0) {
4714                 raw_next_token(state, *filep, tk);
4715                 check_tok(state, tk, TOK_LPAREN);
4716
4717                 argv = read_macro_args(state, macro, *filep, tk);
4718
4719                 check_tok(state, tk, TOK_RPAREN);
4720         }
4721         /* Macro expand the macro arguments */
4722         macro_expand_args(state, macro, argv, tk);
4723
4724         buf.str = 0;
4725         buf.len = 0;
4726         buf.pos = 0;
4727         if (ident == state->i___FILE__) {
4728                 buf.len = strlen(state->file->basename) + 1 + 2 + 3;
4729                 buf.str = xmalloc(buf.len, ident->name);
4730                 sprintf(buf.str, "\"%s\"", state->file->basename);
4731                 buf.pos = strlen(buf.str);
4732         }
4733         else if (ident == state->i___LINE__) {
4734                 buf.len = 30;
4735                 buf.str = xmalloc(buf.len, ident->name);
4736                 sprintf(buf.str, "%d", state->file->line);
4737                 buf.pos = strlen(buf.str);
4738         }
4739         else {
4740                 expand_macro(state, macro, &buf, argv, tk);
4741         }
4742         /* Tag the macro name with a $ so it will no longer
4743          * be regonized as a canidate for macro expansion.
4744          */
4745         tag_macro_name(state, macro, &buf, tk);
4746
4747 #if 0
4748         fprintf(state->errout, "%s: %d -> `%*.*s'\n",
4749                 ident->name, buf.pos, buf.pos, (int)(buf.pos), buf.str);
4750 #endif
4751
4752         free_macro_args(macro, argv);
4753
4754         file = xmalloc(sizeof(*file), "file_state");
4755         file->prev        = *filep;
4756         file->basename    = xstrdup(ident->name);
4757         file->dirname     = xstrdup("");
4758         file->buf         = buf.str;
4759         file->size        = buf.pos;
4760         file->pos         = file->buf;
4761         file->line        = 1;
4762         file->line_start  = file->pos;
4763         file->report_line = 1;
4764         file->report_name = file->basename;
4765         file->report_dir  = file->dirname;
4766         file->macro       = 1;
4767         file->trigraphs   = 0;
4768         file->join_lines  = 0;
4769         *filep = file;
4770         return 1;
4771 }
4772
4773 static void eat_tokens(struct compile_state *state, int targ_tok)
4774 {
4775         if (state->eat_depth > 0) {
4776                 internal_error(state, 0, "Already eating...");
4777         }
4778         state->eat_depth = state->if_depth;
4779         state->eat_targ = targ_tok;
4780 }
4781 static int if_eat(struct compile_state *state)
4782 {
4783         return state->eat_depth > 0;
4784 }
4785 static int if_value(struct compile_state *state)
4786 {
4787         int index, offset;
4788         index = state->if_depth / CHAR_BIT;
4789         offset = state->if_depth % CHAR_BIT;
4790         return !!(state->if_bytes[index] & (1 << (offset)));
4791 }
4792 static void set_if_value(struct compile_state *state, int value) 
4793 {
4794         int index, offset;
4795         index = state->if_depth / CHAR_BIT;
4796         offset = state->if_depth % CHAR_BIT;
4797
4798         state->if_bytes[index] &= ~(1 << offset);
4799         if (value) {
4800                 state->if_bytes[index] |= (1 << offset);
4801         }
4802 }
4803 static void in_if(struct compile_state *state, const char *name)
4804 {
4805         if (state->if_depth <= 0) {
4806                 error(state, 0, "%s without #if", name);
4807         }
4808 }
4809 static void enter_if(struct compile_state *state)
4810 {
4811         state->if_depth += 1;
4812         if (state->if_depth > MAX_PP_IF_DEPTH) {
4813                 error(state, 0, "#if depth too great");
4814         }
4815 }
4816 static void reenter_if(struct compile_state *state, const char *name)
4817 {
4818         in_if(state, name);
4819         if ((state->eat_depth == state->if_depth) &&
4820                 (state->eat_targ == TOK_MELSE)) {
4821                 state->eat_depth = 0;
4822                 state->eat_targ = 0;
4823         }
4824 }
4825 static void enter_else(struct compile_state *state, const char *name)
4826 {
4827         in_if(state, name);
4828         if ((state->eat_depth == state->if_depth) &&
4829                 (state->eat_targ == TOK_MELSE)) {
4830                 state->eat_depth = 0;
4831                 state->eat_targ = 0;
4832         }
4833 }
4834 static void exit_if(struct compile_state *state, const char *name)
4835 {
4836         in_if(state, name);
4837         if (state->eat_depth == state->if_depth) {
4838                 state->eat_depth = 0;
4839                 state->eat_targ = 0;
4840         }
4841         state->if_depth -= 1;
4842 }
4843
4844 static void raw_token(struct compile_state *state, struct token *tk)
4845 {
4846         struct file_state *file;
4847         int rescan;
4848
4849         file = state->file;
4850         raw_next_token(state, file, tk);
4851         do {
4852                 rescan = 0;
4853                 file = state->file;
4854                 /* Exit out of an include directive or macro call */
4855                 if ((tk->tok == TOK_EOF) && 
4856                         (file != state->macro_file) && file->prev) 
4857                 {
4858                         state->file = file->prev;
4859                         /* file->basename is used keep it */
4860                         xfree(file->dirname);
4861                         xfree(file->buf);
4862                         xfree(file);
4863                         file = 0;
4864                         raw_next_token(state, state->file, tk);
4865                         rescan = 1;
4866                 }
4867         } while(rescan);
4868 }
4869
4870 static void pp_token(struct compile_state *state, struct token *tk)
4871 {
4872         struct file_state *file;
4873         int rescan;
4874
4875         raw_token(state, tk);
4876         do {
4877                 rescan = 0;
4878                 file = state->file;
4879                 if (tk->tok == TOK_SPACE) {
4880                         raw_token(state, tk);
4881                         rescan = 1;
4882                 }
4883                 else if (tk->tok == TOK_IDENT) {
4884                         if (state->token_base == 0) {
4885                                 ident_to_keyword(state, tk);
4886                         } else {
4887                                 ident_to_macro(state, tk);
4888                         }
4889                 }
4890         } while(rescan);
4891 }
4892
4893 static void preprocess(struct compile_state *state, struct token *tk);
4894
4895 static void token(struct compile_state *state, struct token *tk)
4896 {
4897         int rescan;
4898         pp_token(state, tk);
4899         do {
4900                 rescan = 0;
4901                 /* Process a macro directive */
4902                 if (tk->tok == TOK_MACRO) {
4903                         /* Only match preprocessor directives at the start of a line */
4904                         const char *ptr;
4905                         ptr = state->file->line_start;
4906                         while((ptr < tk->pos)
4907                                 && spacep(get_char(state->file, ptr)))
4908                         {
4909                                 ptr = next_char(state->file, ptr, 1);
4910                         }
4911                         if (ptr == tk->pos) {
4912                                 preprocess(state, tk);
4913                                 rescan = 1;
4914                         }
4915                 }
4916                 /* Expand a macro call */
4917                 else if (tk->ident && tk->ident->sym_define) {
4918                         rescan = compile_macro(state, &state->file, tk);
4919                         if (rescan) {
4920                                 pp_token(state, tk);
4921                         }
4922                 }
4923                 /* Eat tokens disabled by the preprocessor 
4924                  * (Unless we are parsing a preprocessor directive 
4925                  */
4926                 else if (if_eat(state) && (state->token_base == 0)) {
4927                         pp_token(state, tk);
4928                         rescan = 1;
4929                 }
4930                 /* Make certain EOL only shows up in preprocessor directives */
4931                 else if ((tk->tok == TOK_EOL) && (state->token_base == 0)) {
4932                         pp_token(state, tk);
4933                         rescan = 1;
4934                 }
4935                 /* Error on unknown tokens */
4936                 else if (tk->tok == TOK_UNKNOWN) {
4937                         error(state, 0, "unknown token");
4938                 }
4939         } while(rescan);
4940 }
4941
4942
4943 static inline struct token *get_token(struct compile_state *state, int offset)
4944 {
4945         int index;
4946         index = state->token_base + offset;
4947         if (index >= sizeof(state->token)/sizeof(state->token[0])) {
4948                 internal_error(state, 0, "token array to small");
4949         }
4950         return &state->token[index];
4951 }
4952
4953 static struct token *do_eat_token(struct compile_state *state, int tok)
4954 {
4955         struct token *tk;
4956         int i;
4957         check_tok(state, get_token(state, 1), tok);
4958         
4959         /* Free the old token value */
4960         tk = get_token(state, 0);
4961         if (tk->str_len) {
4962                 memset((void *)tk->val.str, -1, tk->str_len);
4963                 xfree(tk->val.str);
4964         }
4965         /* Overwrite the old token with newer tokens */
4966         for(i = state->token_base; i < sizeof(state->token)/sizeof(state->token[0]) - 1; i++) {
4967                 state->token[i] = state->token[i + 1];
4968         }
4969         /* Clear the last token */
4970         memset(&state->token[i], 0, sizeof(state->token[i]));
4971         state->token[i].tok = -1;
4972
4973         /* Return the token */
4974         return tk;
4975 }
4976
4977 static int raw_peek(struct compile_state *state)
4978 {
4979         struct token *tk1;
4980         tk1 = get_token(state, 1);
4981         if (tk1->tok == -1) {
4982                 raw_token(state, tk1);
4983         }
4984         return tk1->tok;
4985 }
4986
4987 static struct token *raw_eat(struct compile_state *state, int tok)
4988 {
4989         raw_peek(state);
4990         return do_eat_token(state, tok);
4991 }
4992
4993 static int pp_peek(struct compile_state *state)
4994 {
4995         struct token *tk1;
4996         tk1 = get_token(state, 1);
4997         if (tk1->tok == -1) {
4998                 pp_token(state, tk1);
4999         }
5000         return tk1->tok;
5001 }
5002
5003 static struct token *pp_eat(struct compile_state *state, int tok)
5004 {
5005         pp_peek(state);
5006         return do_eat_token(state, tok);
5007 }
5008
5009 static int peek(struct compile_state *state)
5010 {
5011         struct token *tk1;
5012         tk1 = get_token(state, 1);
5013         if (tk1->tok == -1) {
5014                 token(state, tk1);
5015         }
5016         return tk1->tok;
5017 }
5018
5019 static int peek2(struct compile_state *state)
5020 {
5021         struct token *tk1, *tk2;
5022         tk1 = get_token(state, 1);
5023         tk2 = get_token(state, 2);
5024         if (tk1->tok == -1) {
5025                 token(state, tk1);
5026         }
5027         if (tk2->tok == -1) {
5028                 token(state, tk2);
5029         }
5030         return tk2->tok;
5031 }
5032
5033 static struct token *eat(struct compile_state *state, int tok)
5034 {
5035         peek(state);
5036         return do_eat_token(state, tok);
5037 }
5038
5039 static void compile_file(struct compile_state *state, const char *filename, int local)
5040 {
5041         char cwd[MAX_CWD_SIZE];
5042         const char *subdir, *base;
5043         int subdir_len;
5044         struct file_state *file;
5045         char *basename;
5046         file = xmalloc(sizeof(*file), "file_state");
5047
5048         base = strrchr(filename, '/');
5049         subdir = filename;
5050         if (base != 0) {
5051                 subdir_len = base - filename;
5052                 base++;
5053         }
5054         else {
5055                 base = filename;
5056                 subdir_len = 0;
5057         }
5058         basename = xmalloc(strlen(base) +1, "basename");
5059         strcpy(basename, base);
5060         file->basename = basename;
5061
5062         if (getcwd(cwd, sizeof(cwd)) == 0) {
5063                 die("cwd buffer to small");
5064         }
5065         if (subdir[0] == '/') {
5066                 file->dirname = xmalloc(subdir_len + 1, "dirname");
5067                 memcpy(file->dirname, subdir, subdir_len);
5068                 file->dirname[subdir_len] = '\0';
5069         }
5070         else {
5071                 const char *dir;
5072                 int dirlen;
5073                 const char **path;
5074                 /* Find the appropriate directory... */
5075                 dir = 0;
5076                 if (!state->file && exists(cwd, filename)) {
5077                         dir = cwd;
5078                 }
5079                 if (local && state->file && exists(state->file->dirname, filename)) {
5080                         dir = state->file->dirname;
5081                 }
5082                 for(path = state->compiler->include_paths; !dir && *path; path++) {
5083                         if (exists(*path, filename)) {
5084                                 dir = *path;
5085                         }
5086                 }
5087                 if (!dir) {
5088                         error(state, 0, "Cannot open `%s'\n", filename);
5089                 }
5090                 dirlen = strlen(dir);
5091                 file->dirname = xmalloc(dirlen + 1 + subdir_len + 1, "dirname");
5092                 memcpy(file->dirname, dir, dirlen);
5093                 file->dirname[dirlen] = '/';
5094                 memcpy(file->dirname + dirlen + 1, subdir, subdir_len);
5095                 file->dirname[dirlen + 1 + subdir_len] = '\0';
5096         }
5097         file->buf = slurp_file(file->dirname, file->basename, &file->size);
5098
5099         file->pos = file->buf;
5100         file->line_start = file->pos;
5101         file->line = 1;
5102
5103         file->report_line = 1;
5104         file->report_name = file->basename;
5105         file->report_dir  = file->dirname;
5106         file->macro       = 0;
5107         file->trigraphs   = (state->compiler->flags & COMPILER_TRIGRAPHS)? 1: 0;
5108         file->join_lines  = 1;
5109
5110         file->prev = state->file;
5111         state->file = file;
5112 }
5113
5114 static struct triple *constant_expr(struct compile_state *state);
5115 static void integral(struct compile_state *state, struct triple *def);
5116
5117 static int mcexpr(struct compile_state *state)
5118 {
5119         struct triple *cvalue;
5120         cvalue = constant_expr(state);
5121         integral(state, cvalue);
5122         if (cvalue->op != OP_INTCONST) {
5123                 error(state, 0, "integer constant expected");
5124         }
5125         return cvalue->u.cval != 0;
5126 }
5127
5128 static void preprocess(struct compile_state *state, struct token *current_token)
5129 {
5130         /* Doing much more with the preprocessor would require
5131          * a parser and a major restructuring.
5132          * Postpone that for later.
5133          */
5134         int old_token_base;
5135         int tok;
5136         
5137         state->macro_file = state->file;
5138
5139         old_token_base = state->token_base;
5140         state->token_base = current_token - state->token;
5141
5142         tok = pp_peek(state);
5143         switch(tok) {
5144         case TOK_LIT_INT:
5145         {
5146                 struct token *tk;
5147                 int override_line;
5148                 tk = pp_eat(state, TOK_LIT_INT);
5149                 override_line = strtoul(tk->val.str, 0, 10);
5150                 /* I have a preprocessor  line marker parse it */
5151                 if (pp_peek(state) == TOK_LIT_STRING) {
5152                         const char *token, *base;
5153                         char *name, *dir;
5154                         int name_len, dir_len;
5155                         tk = pp_eat(state, TOK_LIT_STRING);
5156                         name = xmalloc(tk->str_len, "report_name");
5157                         token = tk->val.str + 1;
5158                         base = strrchr(token, '/');
5159                         name_len = tk->str_len -2;
5160                         if (base != 0) {
5161                                 dir_len = base - token;
5162                                 base++;
5163                                 name_len -= base - token;
5164                         } else {
5165                                 dir_len = 0;
5166                                 base = token;
5167                         }
5168                         memcpy(name, base, name_len);
5169                         name[name_len] = '\0';
5170                         dir = xmalloc(dir_len + 1, "report_dir");
5171                         memcpy(dir, token, dir_len);
5172                         dir[dir_len] = '\0';
5173                         state->file->report_line = override_line - 1;
5174                         state->file->report_name = name;
5175                         state->file->report_dir = dir;
5176                         state->file->macro      = 0;
5177                 }
5178                 break;
5179         }
5180         case TOK_MLINE:
5181         {
5182                 struct token *tk;
5183                 pp_eat(state, TOK_MLINE);
5184                 tk = eat(state, TOK_LIT_INT);
5185                 state->file->report_line = strtoul(tk->val.str, 0, 10) -1;
5186                 if (pp_peek(state) == TOK_LIT_STRING) {
5187                         const char *token, *base;
5188                         char *name, *dir;
5189                         int name_len, dir_len;
5190                         tk = pp_eat(state, TOK_LIT_STRING);
5191                         name = xmalloc(tk->str_len, "report_name");
5192                         token = tk->val.str + 1;
5193                         base = strrchr(token, '/');
5194                         name_len = tk->str_len - 2;
5195                         if (base != 0) {
5196                                 dir_len = base - token;
5197                                 base++;
5198                                 name_len -= base - token;
5199                         } else {
5200                                 dir_len = 0;
5201                                 base = token;
5202                         }
5203                         memcpy(name, base, name_len);
5204                         name[name_len] = '\0';
5205                         dir = xmalloc(dir_len + 1, "report_dir");
5206                         memcpy(dir, token, dir_len);
5207                         dir[dir_len] = '\0';
5208                         state->file->report_name = name;
5209                         state->file->report_dir = dir;
5210                         state->file->macro      = 0;
5211                 }
5212                 break;
5213         }
5214         case TOK_MUNDEF:
5215         {
5216                 struct hash_entry *ident;
5217                 pp_eat(state, TOK_MUNDEF);
5218                 if (if_eat(state))  /* quit early when #if'd out */
5219                         break;
5220                 
5221                 ident = pp_eat(state, TOK_MIDENT)->ident;
5222
5223                 undef_macro(state, ident);
5224                 break;
5225         }
5226         case TOK_MPRAGMA:
5227                 pp_eat(state, TOK_MPRAGMA);
5228                 if (if_eat(state))  /* quit early when #if'd out */
5229                         break;
5230                 warning(state, 0, "Ignoring pragma"); 
5231                 break;
5232         case TOK_MELIF:
5233                 pp_eat(state, TOK_MELIF);
5234                 reenter_if(state, "#elif");
5235                 if (if_eat(state))   /* quit early when #if'd out */
5236                         break;
5237                 /* If the #if was taken the #elif just disables the following code */
5238                 if (if_value(state)) {
5239                         eat_tokens(state, TOK_MENDIF);
5240                 }
5241                 /* If the previous #if was not taken see if the #elif enables the 
5242                  * trailing code.
5243                  */
5244                 else {
5245                         set_if_value(state, mcexpr(state));
5246                         if (!if_value(state)) {
5247                                 eat_tokens(state, TOK_MELSE);
5248                         }
5249                 }
5250                 break;
5251         case TOK_MIF:
5252                 pp_eat(state, TOK_MIF);
5253                 enter_if(state);
5254                 if (if_eat(state))  /* quit early when #if'd out */
5255                         break;
5256                 set_if_value(state, mcexpr(state));
5257                 if (!if_value(state)) {
5258                         eat_tokens(state, TOK_MELSE);
5259                 }
5260                 break;
5261         case TOK_MIFNDEF:
5262         {
5263                 struct hash_entry *ident;
5264
5265                 pp_eat(state, TOK_MIFNDEF);
5266                 enter_if(state);
5267                 if (if_eat(state))  /* quit early when #if'd out */
5268                         break;
5269                 ident = pp_eat(state, TOK_MIDENT)->ident;
5270                 set_if_value(state, ident->sym_define == 0);
5271                 if (!if_value(state)) {
5272                         eat_tokens(state, TOK_MELSE);
5273                 }
5274                 break;
5275         }
5276         case TOK_MIFDEF:
5277         {
5278                 struct hash_entry *ident;
5279                 pp_eat(state, TOK_MIFDEF);
5280                 enter_if(state);
5281                 if (if_eat(state))  /* quit early when #if'd out */
5282                         break;
5283                 ident = pp_eat(state, TOK_MIDENT)->ident;
5284                 set_if_value(state, ident->sym_define != 0);
5285                 if (!if_value(state)) {
5286                         eat_tokens(state, TOK_MELSE);
5287                 }
5288                 break;
5289         }
5290         case TOK_MELSE:
5291                 pp_eat(state, TOK_MELSE);
5292                 enter_else(state, "#else");
5293                 if (!if_eat(state) && if_value(state)) {
5294                         eat_tokens(state, TOK_MENDIF);
5295                 }
5296                 break;
5297         case TOK_MENDIF:
5298                 pp_eat(state, TOK_MENDIF);
5299                 exit_if(state, "#endif");
5300                 break;
5301         case TOK_MDEFINE:
5302         {
5303                 struct hash_entry *ident;
5304                 struct macro_arg *args, **larg;
5305                 const char *mstart, *mend;
5306                 int argc;
5307
5308                 pp_eat(state, TOK_MDEFINE);
5309                 if (if_eat(state))  /* quit early when #if'd out */
5310                         break;
5311                 ident = pp_eat(state, TOK_MIDENT)->ident;
5312                 argc = -1;
5313                 args = 0;
5314                 larg = &args;
5315
5316                 /* Parse macro parameters */
5317                 if (raw_peek(state) == TOK_LPAREN) {
5318                         raw_eat(state, TOK_LPAREN);
5319                         argc += 1;
5320
5321                         for(;;) {
5322                                 struct macro_arg *narg, *arg;
5323                                 struct hash_entry *aident;
5324                                 int tok;
5325
5326                                 tok = pp_peek(state);
5327                                 if (!args && (tok == TOK_RPAREN)) {
5328                                         break;
5329                                 }
5330                                 else if (tok == TOK_DOTS) {
5331                                         pp_eat(state, TOK_DOTS);
5332                                         aident = state->i___VA_ARGS__;
5333                                 } 
5334                                 else {
5335                                         aident = pp_eat(state, TOK_MIDENT)->ident;
5336                                 }
5337                                 
5338                                 narg = xcmalloc(sizeof(*arg), "macro arg");
5339                                 narg->ident = aident;
5340
5341                                 /* Verify I don't have a duplicate identifier */
5342                                 for(arg = args; arg; arg = arg->next) {
5343                                         if (arg->ident == narg->ident) {
5344                                                 error(state, 0, "Duplicate macro arg `%s'",
5345                                                         narg->ident->name);
5346                                         }
5347                                 }
5348                                 /* Add the new argument to the end of the list */
5349                                 *larg = narg;
5350                                 larg = &narg->next;
5351                                 argc += 1;
5352
5353                                 if ((aident == state->i___VA_ARGS__) ||
5354                                         (pp_peek(state) != TOK_COMMA)) {
5355                                         break;
5356                                 }
5357                                 pp_eat(state, TOK_COMMA);
5358                         }
5359                         pp_eat(state, TOK_RPAREN);
5360                 }
5361                 /* Remove leading whitespace */
5362                 while(raw_peek(state) == TOK_SPACE) {
5363                         raw_eat(state, TOK_SPACE);
5364                 }
5365
5366                 /* Remember the start of the macro body */
5367                 tok = raw_peek(state);
5368                 mend = mstart = get_token(state, 1)->pos;
5369
5370                 /* Find the end of the macro */
5371                 for(tok = raw_peek(state); tok != TOK_EOL; tok = raw_peek(state)) {
5372                         raw_eat(state, tok);
5373                         /* Remember the end of the last non space token */
5374                         raw_peek(state);
5375                         if (tok != TOK_SPACE) {
5376                                 mend = get_token(state, 1)->pos;
5377                         }
5378                 }
5379                 
5380                 /* Now that I have found the body defined the token */
5381                 do_define_macro(state, ident,
5382                         char_strdup(state->file, mstart, mend, "macro buf"),
5383                         argc, args);
5384                 break;
5385         }
5386         case TOK_MERROR:
5387         {
5388                 const char *start, *end;
5389                 int len;
5390                 
5391                 pp_eat(state, TOK_MERROR);
5392                 /* Find the start of the line */
5393                 raw_peek(state);
5394                 start = get_token(state, 1)->pos;
5395
5396                 /* Find the end of the line */
5397                 while((tok = raw_peek(state)) != TOK_EOL) {
5398                         raw_eat(state, tok);
5399                 }
5400                 end = get_token(state, 1)->pos;
5401                 len = end - start;
5402                 if (!if_eat(state)) {
5403                         error(state, 0, "%*.*s", len, len, start);
5404                 }
5405                 break;
5406         }
5407         case TOK_MWARNING:
5408         {
5409                 const char *start, *end;
5410                 int len;
5411                 
5412                 pp_eat(state, TOK_MWARNING);
5413
5414                 /* Find the start of the line */
5415                 raw_peek(state);
5416                 start = get_token(state, 1)->pos;
5417                  
5418                 /* Find the end of the line */
5419                 while((tok = raw_peek(state)) != TOK_EOL) {
5420                         raw_eat(state, tok);
5421                 }
5422                 end = get_token(state, 1)->pos;
5423                 len = end - start;
5424                 if (!if_eat(state)) {
5425                         warning(state, 0, "%*.*s", len, len, start);
5426                 }
5427                 break;
5428         }
5429         case TOK_MINCLUDE:
5430         {
5431                 char *name;
5432                 int local;
5433                 local = 0;
5434                 name = 0;
5435
5436                 pp_eat(state, TOK_MINCLUDE);
5437                 tok = peek(state);
5438                 if (tok == TOK_LIT_STRING) {
5439                         struct token *tk;
5440                         const char *token;
5441                         int name_len;
5442                         tk = eat(state, TOK_LIT_STRING);
5443                         name = xmalloc(tk->str_len, "include");
5444                         token = tk->val.str +1;
5445                         name_len = tk->str_len -2;
5446                         if (*token == '"') {
5447                                 token++;
5448                                 name_len--;
5449                         }
5450                         memcpy(name, token, name_len);
5451                         name[name_len] = '\0';
5452                         local = 1;
5453                 }
5454                 else if (tok == TOK_LESS) {
5455                         struct macro_buf buf;
5456                         eat(state, TOK_LESS);
5457
5458                         buf.len = 40;
5459                         buf.str = xmalloc(buf.len, "include");
5460                         buf.pos = 0;
5461
5462                         tok = peek(state);
5463                         while((tok != TOK_MORE) &&
5464                                 (tok != TOK_EOL) && (tok != TOK_EOF))
5465                         {
5466                                 struct token *tk;
5467                                 tk = eat(state, tok);
5468                                 append_macro_chars(state, "include", &buf,
5469                                         state->file, tk->pos, state->file->pos);
5470                                 tok = peek(state);
5471                         }
5472                         append_macro_text(state, "include", &buf, "\0", 1);
5473                         if (peek(state) != TOK_MORE) {
5474                                 error(state, 0, "Unterminated include directive");
5475                         }
5476                         eat(state, TOK_MORE);
5477                         local = 0;
5478                         name = buf.str;
5479                 }
5480                 else {
5481                         error(state, 0, "Invalid include directive");
5482                 }
5483                 /* Error if there are any tokens after the include */
5484                 if (pp_peek(state) != TOK_EOL) {
5485                         error(state, 0, "garbage after include directive");
5486                 }
5487                 if (!if_eat(state)) {
5488                         compile_file(state, name, local);
5489                 }
5490                 xfree(name);
5491                 break;
5492         }
5493         case TOK_EOL:
5494                 /* Ignore # without a follwing ident */
5495                 break;
5496         default:
5497         {
5498                 const char *name1, *name2;
5499                 name1 = tokens[tok];
5500                 name2 = "";
5501                 if (tok == TOK_MIDENT) {
5502                         name2 = get_token(state, 1)->ident->name;
5503                 }
5504                 error(state, 0, "Invalid preprocessor directive: %s %s", 
5505                         name1, name2);
5506                 break;
5507         }
5508         }
5509         /* Consume the rest of the macro line */
5510         do {
5511                 tok = pp_peek(state);
5512                 pp_eat(state, tok);
5513         } while((tok != TOK_EOF) && (tok != TOK_EOL));
5514         state->token_base = old_token_base;
5515         state->macro_file = NULL;
5516         return;
5517 }
5518
5519 /* Type helper functions */
5520
5521 static struct type *new_type(
5522         unsigned int type, struct type *left, struct type *right)
5523 {
5524         struct type *result;
5525         result = xmalloc(sizeof(*result), "type");
5526         result->type = type;
5527         result->left = left;
5528         result->right = right;
5529         result->field_ident = 0;
5530         result->type_ident = 0;
5531         result->elements = 0;
5532         return result;
5533 }
5534
5535 static struct type *clone_type(unsigned int specifiers, struct type *old)
5536 {
5537         struct type *result;
5538         result = xmalloc(sizeof(*result), "type");
5539         memcpy(result, old, sizeof(*result));
5540         result->type &= TYPE_MASK;
5541         result->type |= specifiers;
5542         return result;
5543 }
5544
5545 static struct type *dup_type(struct compile_state *state, struct type *orig)
5546 {
5547         struct type *new;
5548         new = xcmalloc(sizeof(*new), "type");
5549         new->type = orig->type;
5550         new->field_ident = orig->field_ident;
5551         new->type_ident  = orig->type_ident;
5552         new->elements    = orig->elements;
5553         if (orig->left) {
5554                 new->left = dup_type(state, orig->left);
5555         }
5556         if (orig->right) {
5557                 new->right = dup_type(state, orig->right);
5558         }
5559         return new;
5560 }
5561
5562
5563 static struct type *invalid_type(struct compile_state *state, struct type *type)
5564 {
5565         struct type *invalid, *member;
5566         invalid = 0;
5567         if (!type) {
5568                 internal_error(state, 0, "type missing?");
5569         }
5570         switch(type->type & TYPE_MASK) {
5571         case TYPE_VOID:
5572         case TYPE_CHAR:         case TYPE_UCHAR:
5573         case TYPE_SHORT:        case TYPE_USHORT:
5574         case TYPE_INT:          case TYPE_UINT:
5575         case TYPE_LONG:         case TYPE_ULONG:
5576         case TYPE_LLONG:        case TYPE_ULLONG:
5577         case TYPE_POINTER:
5578         case TYPE_ENUM:
5579                 break;
5580         case TYPE_BITFIELD:
5581                 invalid = invalid_type(state, type->left);
5582                 break;
5583         case TYPE_ARRAY:
5584                 invalid = invalid_type(state, type->left);
5585                 break;
5586         case TYPE_STRUCT:
5587         case TYPE_TUPLE:
5588                 member = type->left;
5589                 while(member && (invalid == 0) && 
5590                         ((member->type & TYPE_MASK) == TYPE_PRODUCT)) {
5591                         invalid = invalid_type(state, member->left);
5592                         member = member->right;
5593                 }
5594                 if (!invalid) {
5595                         invalid = invalid_type(state, member);
5596                 }
5597                 break;
5598         case TYPE_UNION:
5599         case TYPE_JOIN:
5600                 member = type->left;
5601                 while(member && (invalid == 0) &&
5602                         ((member->type & TYPE_MASK) == TYPE_OVERLAP)) {
5603                         invalid = invalid_type(state, member->left);
5604                         member = member->right;
5605                 }
5606                 if (!invalid) {
5607                         invalid = invalid_type(state, member);
5608                 }
5609                 break;
5610         default:
5611                 invalid = type;
5612                 break;
5613         }
5614         return invalid;
5615         
5616 }
5617
5618 #define MASK_UCHAR(X)    ((X) & ((ulong_t)0xff))
5619 #define MASK_USHORT(X)   ((X) & (((ulong_t)1 << (SIZEOF_SHORT)) - 1))
5620 static inline ulong_t mask_uint(ulong_t x)
5621 {
5622         if (SIZEOF_INT < SIZEOF_LONG) {
5623                 ulong_t mask = (((ulong_t)1) << ((ulong_t)(SIZEOF_INT))) -1;
5624                 x &= mask;
5625         }
5626         return x;
5627 }
5628 #define MASK_UINT(X)      (mask_uint(X))
5629 #define MASK_ULONG(X)    (X)
5630
5631 static struct type void_type    = { .type  = TYPE_VOID };
5632 static struct type char_type    = { .type  = TYPE_CHAR };
5633 static struct type uchar_type   = { .type  = TYPE_UCHAR };
5634 static struct type short_type   = { .type  = TYPE_SHORT };
5635 static struct type ushort_type  = { .type  = TYPE_USHORT };
5636 static struct type int_type     = { .type  = TYPE_INT };
5637 static struct type uint_type    = { .type  = TYPE_UINT };
5638 static struct type long_type    = { .type  = TYPE_LONG };
5639 static struct type ulong_type   = { .type  = TYPE_ULONG };
5640 static struct type unknown_type = { .type  = TYPE_UNKNOWN };
5641
5642 static struct type void_ptr_type  = {
5643         .type = TYPE_POINTER,
5644         .left = &void_type,
5645 };
5646
5647 static struct type void_func_type = { 
5648         .type  = TYPE_FUNCTION,
5649         .left  = &void_type,
5650         .right = &void_type,
5651 };
5652
5653 static size_t bits_to_bytes(size_t size)
5654 {
5655         return (size + SIZEOF_CHAR - 1)/SIZEOF_CHAR;
5656 }
5657
5658 static struct triple *variable(struct compile_state *state, struct type *type)
5659 {
5660         struct triple *result;
5661         if ((type->type & STOR_MASK) != STOR_PERM) {
5662                 result = triple(state, OP_ADECL, type, 0, 0);
5663                 generate_lhs_pieces(state, result);
5664         }
5665         else {
5666                 result = triple(state, OP_SDECL, type, 0, 0);
5667         }
5668         return result;
5669 }
5670
5671 static void stor_of(FILE *fp, struct type *type)
5672 {
5673         switch(type->type & STOR_MASK) {
5674         case STOR_AUTO:
5675                 fprintf(fp, "auto ");
5676                 break;
5677         case STOR_STATIC:
5678                 fprintf(fp, "static ");
5679                 break;
5680         case STOR_LOCAL:
5681                 fprintf(fp, "local ");
5682                 break;
5683         case STOR_EXTERN:
5684                 fprintf(fp, "extern ");
5685                 break;
5686         case STOR_REGISTER:
5687                 fprintf(fp, "register ");
5688                 break;
5689         case STOR_TYPEDEF:
5690                 fprintf(fp, "typedef ");
5691                 break;
5692         case STOR_INLINE | STOR_LOCAL:
5693                 fprintf(fp, "inline ");
5694                 break;
5695         case STOR_INLINE | STOR_STATIC:
5696                 fprintf(fp, "static inline");
5697                 break;
5698         case STOR_INLINE | STOR_EXTERN:
5699                 fprintf(fp, "extern inline");
5700                 break;
5701         default:
5702                 fprintf(fp, "stor:%x", type->type & STOR_MASK);
5703                 break;
5704         }
5705 }
5706 static void qual_of(FILE *fp, struct type *type)
5707 {
5708         if (type->type & QUAL_CONST) {
5709                 fprintf(fp, " const");
5710         }
5711         if (type->type & QUAL_VOLATILE) {
5712                 fprintf(fp, " volatile");
5713         }
5714         if (type->type & QUAL_RESTRICT) {
5715                 fprintf(fp, " restrict");
5716         }
5717 }
5718
5719 static void name_of(FILE *fp, struct type *type)
5720 {
5721         unsigned int base_type;
5722         base_type = type->type & TYPE_MASK;
5723         if ((base_type != TYPE_PRODUCT) && (base_type != TYPE_OVERLAP)) {
5724                 stor_of(fp, type);
5725         }
5726         switch(base_type) {
5727         case TYPE_VOID:
5728                 fprintf(fp, "void");
5729                 qual_of(fp, type);
5730                 break;
5731         case TYPE_CHAR:
5732                 fprintf(fp, "signed char");
5733                 qual_of(fp, type);
5734                 break;
5735         case TYPE_UCHAR:
5736                 fprintf(fp, "unsigned char");
5737                 qual_of(fp, type);
5738                 break;
5739         case TYPE_SHORT:
5740                 fprintf(fp, "signed short");
5741                 qual_of(fp, type);
5742                 break;
5743         case TYPE_USHORT:
5744                 fprintf(fp, "unsigned short");
5745                 qual_of(fp, type);
5746                 break;
5747         case TYPE_INT:
5748                 fprintf(fp, "signed int");
5749                 qual_of(fp, type);
5750                 break;
5751         case TYPE_UINT:
5752                 fprintf(fp, "unsigned int");
5753                 qual_of(fp, type);
5754                 break;
5755         case TYPE_LONG:
5756                 fprintf(fp, "signed long");
5757                 qual_of(fp, type);
5758                 break;
5759         case TYPE_ULONG:
5760                 fprintf(fp, "unsigned long");
5761                 qual_of(fp, type);
5762                 break;
5763         case TYPE_POINTER:
5764                 name_of(fp, type->left);
5765                 fprintf(fp, " * ");
5766                 qual_of(fp, type);
5767                 break;
5768         case TYPE_PRODUCT:
5769                 name_of(fp, type->left);
5770                 fprintf(fp, ", ");
5771                 name_of(fp, type->right);
5772                 break;
5773         case TYPE_OVERLAP:
5774                 name_of(fp, type->left);
5775                 fprintf(fp, ",| ");
5776                 name_of(fp, type->right);
5777                 break;
5778         case TYPE_ENUM:
5779                 fprintf(fp, "enum %s", 
5780                         (type->type_ident)? type->type_ident->name : "");
5781                 qual_of(fp, type);
5782                 break;
5783         case TYPE_STRUCT:
5784                 fprintf(fp, "struct %s { ", 
5785                         (type->type_ident)? type->type_ident->name : "");
5786                 name_of(fp, type->left);
5787                 fprintf(fp, " } ");
5788                 qual_of(fp, type);
5789                 break;
5790         case TYPE_UNION:
5791                 fprintf(fp, "union %s { ", 
5792                         (type->type_ident)? type->type_ident->name : "");
5793                 name_of(fp, type->left);
5794                 fprintf(fp, " } ");
5795                 qual_of(fp, type);
5796                 break;
5797         case TYPE_FUNCTION:
5798                 name_of(fp, type->left);
5799                 fprintf(fp, " (*)(");
5800                 name_of(fp, type->right);
5801                 fprintf(fp, ")");
5802                 break;
5803         case TYPE_ARRAY:
5804                 name_of(fp, type->left);
5805                 fprintf(fp, " [%ld]", (long)(type->elements));
5806                 break;
5807         case TYPE_TUPLE:
5808                 fprintf(fp, "tuple { "); 
5809                 name_of(fp, type->left);
5810                 fprintf(fp, " } ");
5811                 qual_of(fp, type);
5812                 break;
5813         case TYPE_JOIN:
5814                 fprintf(fp, "join { ");
5815                 name_of(fp, type->left);
5816                 fprintf(fp, " } ");
5817                 qual_of(fp, type);
5818                 break;
5819         case TYPE_BITFIELD:
5820                 name_of(fp, type->left);
5821                 fprintf(fp, " : %d ", type->elements);
5822                 qual_of(fp, type);
5823                 break;
5824         case TYPE_UNKNOWN:
5825                 fprintf(fp, "unknown_t");
5826                 break;
5827         default:
5828                 fprintf(fp, "????: %x", base_type);
5829                 break;
5830         }
5831         if (type->field_ident && type->field_ident->name) {
5832                 fprintf(fp, " .%s", type->field_ident->name);
5833         }
5834 }
5835
5836 static size_t align_of(struct compile_state *state, struct type *type)
5837 {
5838         size_t align;
5839         align = 0;
5840         switch(type->type & TYPE_MASK) {
5841         case TYPE_VOID:
5842                 align = 1;
5843                 break;
5844         case TYPE_BITFIELD:
5845                 align = 1;
5846                 break;
5847         case TYPE_CHAR:
5848         case TYPE_UCHAR:
5849                 align = ALIGNOF_CHAR;
5850                 break;
5851         case TYPE_SHORT:
5852         case TYPE_USHORT:
5853                 align = ALIGNOF_SHORT;
5854                 break;
5855         case TYPE_INT:
5856         case TYPE_UINT:
5857         case TYPE_ENUM:
5858                 align = ALIGNOF_INT;
5859                 break;
5860         case TYPE_LONG:
5861         case TYPE_ULONG:
5862                 align = ALIGNOF_LONG;
5863                 break;
5864         case TYPE_POINTER:
5865                 align = ALIGNOF_POINTER;
5866                 break;
5867         case TYPE_PRODUCT:
5868         case TYPE_OVERLAP:
5869         {
5870                 size_t left_align, right_align;
5871                 left_align  = align_of(state, type->left);
5872                 right_align = align_of(state, type->right);
5873                 align = (left_align >= right_align) ? left_align : right_align;
5874                 break;
5875         }
5876         case TYPE_ARRAY:
5877                 align = align_of(state, type->left);
5878                 break;
5879         case TYPE_STRUCT:
5880         case TYPE_TUPLE:
5881         case TYPE_UNION:
5882         case TYPE_JOIN:
5883                 align = align_of(state, type->left);
5884                 break;
5885         default:
5886                 error(state, 0, "alignof not yet defined for type\n");
5887                 break;
5888         }
5889         return align;
5890 }
5891
5892 static size_t reg_align_of(struct compile_state *state, struct type *type)
5893 {
5894         size_t align;
5895         align = 0;
5896         switch(type->type & TYPE_MASK) {
5897         case TYPE_VOID:
5898                 align = 1;
5899                 break;
5900         case TYPE_BITFIELD:
5901                 align = 1;
5902                 break;
5903         case TYPE_CHAR:
5904         case TYPE_UCHAR:
5905                 align = REG_ALIGNOF_CHAR;
5906                 break;
5907         case TYPE_SHORT:
5908         case TYPE_USHORT:
5909                 align = REG_ALIGNOF_SHORT;
5910                 break;
5911         case TYPE_INT:
5912         case TYPE_UINT:
5913         case TYPE_ENUM:
5914                 align = REG_ALIGNOF_INT;
5915                 break;
5916         case TYPE_LONG:
5917         case TYPE_ULONG:
5918                 align = REG_ALIGNOF_LONG;
5919                 break;
5920         case TYPE_POINTER:
5921                 align = REG_ALIGNOF_POINTER;
5922                 break;
5923         case TYPE_PRODUCT:
5924         case TYPE_OVERLAP:
5925         {
5926                 size_t left_align, right_align;
5927                 left_align  = reg_align_of(state, type->left);
5928                 right_align = reg_align_of(state, type->right);
5929                 align = (left_align >= right_align) ? left_align : right_align;
5930                 break;
5931         }
5932         case TYPE_ARRAY:
5933                 align = reg_align_of(state, type->left);
5934                 break;
5935         case TYPE_STRUCT:
5936         case TYPE_UNION:
5937         case TYPE_TUPLE:
5938         case TYPE_JOIN:
5939                 align = reg_align_of(state, type->left);
5940                 break;
5941         default:
5942                 error(state, 0, "alignof not yet defined for type\n");
5943                 break;
5944         }
5945         return align;
5946 }
5947
5948 static size_t align_of_in_bytes(struct compile_state *state, struct type *type)
5949 {
5950         return bits_to_bytes(align_of(state, type));
5951 }
5952 static size_t size_of(struct compile_state *state, struct type *type);
5953 static size_t reg_size_of(struct compile_state *state, struct type *type);
5954
5955 static size_t needed_padding(struct compile_state *state, 
5956         struct type *type, size_t offset)
5957 {
5958         size_t padding, align;
5959         align = align_of(state, type);
5960         /* Align to the next machine word if the bitfield does completely
5961          * fit into the current word.
5962          */
5963         if ((type->type & TYPE_MASK) == TYPE_BITFIELD) {
5964                 size_t size;
5965                 size = size_of(state, type);
5966                 if ((offset + type->elements)/size != offset/size) {
5967                         align = size;
5968                 }
5969         }
5970         padding = 0;
5971         if (offset % align) {
5972                 padding = align - (offset % align);
5973         }
5974         return padding;
5975 }
5976
5977 static size_t reg_needed_padding(struct compile_state *state, 
5978         struct type *type, size_t offset)
5979 {
5980         size_t padding, align;
5981         align = reg_align_of(state, type);
5982         /* Align to the next register word if the bitfield does completely
5983          * fit into the current register.
5984          */
5985         if (((type->type & TYPE_MASK) == TYPE_BITFIELD) &&
5986                 (((offset + type->elements)/REG_SIZEOF_REG) != (offset/REG_SIZEOF_REG))) 
5987         {
5988                 align = REG_SIZEOF_REG;
5989         }
5990         padding = 0;
5991         if (offset % align) {
5992                 padding = align - (offset % align);
5993         }
5994         return padding;
5995 }
5996
5997 static size_t size_of(struct compile_state *state, struct type *type)
5998 {
5999         size_t size;
6000         size = 0;
6001         switch(type->type & TYPE_MASK) {
6002         case TYPE_VOID:
6003                 size = 0;
6004                 break;
6005         case TYPE_BITFIELD:
6006                 size = type->elements;
6007                 break;
6008         case TYPE_CHAR:
6009         case TYPE_UCHAR:
6010                 size = SIZEOF_CHAR;
6011                 break;
6012         case TYPE_SHORT:
6013         case TYPE_USHORT:
6014                 size = SIZEOF_SHORT;
6015                 break;
6016         case TYPE_INT:
6017         case TYPE_UINT:
6018         case TYPE_ENUM:
6019                 size = SIZEOF_INT;
6020                 break;
6021         case TYPE_LONG:
6022         case TYPE_ULONG:
6023                 size = SIZEOF_LONG;
6024                 break;
6025         case TYPE_POINTER:
6026                 size = SIZEOF_POINTER;
6027                 break;
6028         case TYPE_PRODUCT:
6029         {
6030                 size_t pad;
6031                 size = 0;
6032                 while((type->type & TYPE_MASK) == TYPE_PRODUCT) {
6033                         pad = needed_padding(state, type->left, size);
6034                         size = size + pad + size_of(state, type->left);
6035                         type = type->right;
6036                 }
6037                 pad = needed_padding(state, type, size);
6038                 size = size + pad + size_of(state, type);
6039                 break;
6040         }
6041         case TYPE_OVERLAP:
6042         {
6043                 size_t size_left, size_right;
6044                 size_left = size_of(state, type->left);
6045                 size_right = size_of(state, type->right);
6046                 size = (size_left >= size_right)? size_left : size_right;
6047                 break;
6048         }
6049         case TYPE_ARRAY:
6050                 if (type->elements == ELEMENT_COUNT_UNSPECIFIED) {
6051                         internal_error(state, 0, "Invalid array type");
6052                 } else {
6053                         size = size_of(state, type->left) * type->elements;
6054                 }
6055                 break;
6056         case TYPE_STRUCT:
6057         case TYPE_TUPLE:
6058         {
6059                 size_t pad;
6060                 size = size_of(state, type->left);
6061                 /* Pad structures so their size is a multiples of their alignment */
6062                 pad = needed_padding(state, type, size);
6063                 size = size + pad;
6064                 break;
6065         }
6066         case TYPE_UNION:
6067         case TYPE_JOIN:
6068         {
6069                 size_t pad;
6070                 size = size_of(state, type->left);
6071                 /* Pad unions so their size is a multiple of their alignment */
6072                 pad = needed_padding(state, type, size);
6073                 size = size + pad;
6074                 break;
6075         }
6076         default:
6077                 internal_error(state, 0, "sizeof not yet defined for type");
6078                 break;
6079         }
6080         return size;
6081 }
6082
6083 static size_t reg_size_of(struct compile_state *state, struct type *type)
6084 {
6085         size_t size;
6086         size = 0;
6087         switch(type->type & TYPE_MASK) {
6088         case TYPE_VOID:
6089                 size = 0;
6090                 break;
6091         case TYPE_BITFIELD:
6092                 size = type->elements;
6093                 break;
6094         case TYPE_CHAR:
6095         case TYPE_UCHAR:
6096                 size = REG_SIZEOF_CHAR;
6097                 break;
6098         case TYPE_SHORT:
6099         case TYPE_USHORT:
6100                 size = REG_SIZEOF_SHORT;
6101                 break;
6102         case TYPE_INT:
6103         case TYPE_UINT:
6104         case TYPE_ENUM:
6105                 size = REG_SIZEOF_INT;
6106                 break;
6107         case TYPE_LONG:
6108         case TYPE_ULONG:
6109                 size = REG_SIZEOF_LONG;
6110                 break;
6111         case TYPE_POINTER:
6112                 size = REG_SIZEOF_POINTER;
6113                 break;
6114         case TYPE_PRODUCT:
6115         {
6116                 size_t pad;
6117                 size = 0;
6118                 while((type->type & TYPE_MASK) == TYPE_PRODUCT) {
6119                         pad = reg_needed_padding(state, type->left, size);
6120                         size = size + pad + reg_size_of(state, type->left);
6121                         type = type->right;
6122                 }
6123                 pad = reg_needed_padding(state, type, size);
6124                 size = size + pad + reg_size_of(state, type);
6125                 break;
6126         }
6127         case TYPE_OVERLAP:
6128         {
6129                 size_t size_left, size_right;
6130                 size_left  = reg_size_of(state, type->left);
6131                 size_right = reg_size_of(state, type->right);
6132                 size = (size_left >= size_right)? size_left : size_right;
6133                 break;
6134         }
6135         case TYPE_ARRAY:
6136                 if (type->elements == ELEMENT_COUNT_UNSPECIFIED) {
6137                         internal_error(state, 0, "Invalid array type");
6138                 } else {
6139                         size = reg_size_of(state, type->left) * type->elements;
6140                 }
6141                 break;
6142         case TYPE_STRUCT:
6143         case TYPE_TUPLE:
6144         {
6145                 size_t pad;
6146                 size = reg_size_of(state, type->left);
6147                 /* Pad structures so their size is a multiples of their alignment */
6148                 pad = reg_needed_padding(state, type, size);
6149                 size = size + pad;
6150                 break;
6151         }
6152         case TYPE_UNION:
6153         case TYPE_JOIN:
6154         {
6155                 size_t pad;
6156                 size = reg_size_of(state, type->left);
6157                 /* Pad unions so their size is a multiple of their alignment */
6158                 pad = reg_needed_padding(state, type, size);
6159                 size = size + pad;
6160                 break;
6161         }
6162         default:
6163                 internal_error(state, 0, "sizeof not yet defined for type");
6164                 break;
6165         }
6166         return size;
6167 }
6168
6169 static size_t registers_of(struct compile_state *state, struct type *type)
6170 {
6171         size_t registers;
6172         registers = reg_size_of(state, type);
6173         registers += REG_SIZEOF_REG - 1;
6174         registers /= REG_SIZEOF_REG;
6175         return registers;
6176 }
6177
6178 static size_t size_of_in_bytes(struct compile_state *state, struct type *type)
6179 {
6180         return bits_to_bytes(size_of(state, type));
6181 }
6182
6183 static size_t field_offset(struct compile_state *state, 
6184         struct type *type, struct hash_entry *field)
6185 {
6186         struct type *member;
6187         size_t size;
6188
6189         size = 0;
6190         member = 0;
6191         if ((type->type & TYPE_MASK) == TYPE_STRUCT) {
6192                 member = type->left;
6193                 while(member && ((member->type & TYPE_MASK) == TYPE_PRODUCT)) {
6194                         size += needed_padding(state, member->left, size);
6195                         if (member->left->field_ident == field) {
6196                                 member = member->left;
6197                                 break;
6198                         }
6199                         size += size_of(state, member->left);
6200                         member = member->right;
6201                 }
6202                 size += needed_padding(state, member, size);
6203         }
6204         else if ((type->type & TYPE_MASK) == TYPE_UNION) {
6205                 member = type->left;
6206                 while(member && ((member->type & TYPE_MASK) == TYPE_OVERLAP)) {
6207                         if (member->left->field_ident == field) {
6208                                 member = member->left;
6209                                 break;
6210                         }
6211                         member = member->right;
6212                 }
6213         }
6214         else {
6215                 internal_error(state, 0, "field_offset only works on structures and unions");
6216         }
6217
6218         if (!member || (member->field_ident != field)) {
6219                 error(state, 0, "member %s not present", field->name);
6220         }
6221         return size;
6222 }
6223
6224 static size_t field_reg_offset(struct compile_state *state, 
6225         struct type *type, struct hash_entry *field)
6226 {
6227         struct type *member;
6228         size_t size;
6229
6230         size = 0;
6231         member = 0;
6232         if ((type->type & TYPE_MASK) == TYPE_STRUCT) {
6233                 member = type->left;
6234                 while(member && ((member->type & TYPE_MASK) == TYPE_PRODUCT)) {
6235                         size += reg_needed_padding(state, member->left, size);
6236                         if (member->left->field_ident == field) {
6237                                 member = member->left;
6238                                 break;
6239                         }
6240                         size += reg_size_of(state, member->left);
6241                         member = member->right;
6242                 }
6243         }
6244         else if ((type->type & TYPE_MASK) == TYPE_UNION) {
6245                 member = type->left;
6246                 while(member && ((member->type & TYPE_MASK) == TYPE_OVERLAP)) {
6247                         if (member->left->field_ident == field) {
6248                                 member = member->left;
6249                                 break;
6250                         }
6251                         member = member->right;
6252                 }
6253         }
6254         else {
6255                 internal_error(state, 0, "field_reg_offset only works on structures and unions");
6256         }
6257
6258         size += reg_needed_padding(state, member, size);
6259         if (!member || (member->field_ident != field)) {
6260                 error(state, 0, "member %s not present", field->name);
6261         }
6262         return size;
6263 }
6264
6265 static struct type *field_type(struct compile_state *state, 
6266         struct type *type, struct hash_entry *field)
6267 {
6268         struct type *member;
6269
6270         member = 0;
6271         if ((type->type & TYPE_MASK) == TYPE_STRUCT) {
6272                 member = type->left;
6273                 while(member && ((member->type & TYPE_MASK) == TYPE_PRODUCT)) {
6274                         if (member->left->field_ident == field) {
6275                                 member = member->left;
6276                                 break;
6277                         }
6278                         member = member->right;
6279                 }
6280         }
6281         else if ((type->type & TYPE_MASK) == TYPE_UNION) {
6282                 member = type->left;
6283                 while(member && ((member->type & TYPE_MASK) == TYPE_OVERLAP)) {
6284                         if (member->left->field_ident == field) {
6285                                 member = member->left;
6286                                 break;
6287                         }
6288                         member = member->right;
6289                 }
6290         }
6291         else {
6292                 internal_error(state, 0, "field_type only works on structures and unions");
6293         }
6294         
6295         if (!member || (member->field_ident != field)) {
6296                 error(state, 0, "member %s not present", field->name);
6297         }
6298         return member;
6299 }
6300
6301 static size_t index_offset(struct compile_state *state, 
6302         struct type *type, ulong_t index)
6303 {
6304         struct type *member;
6305         size_t size;
6306         size = 0;
6307         if ((type->type & TYPE_MASK) == TYPE_ARRAY) {
6308                 size = size_of(state, type->left) * index;
6309         }
6310         else if ((type->type & TYPE_MASK) == TYPE_TUPLE) {
6311                 ulong_t i;
6312                 member = type->left;
6313                 i = 0;
6314                 while(member && ((member->type & TYPE_MASK) == TYPE_PRODUCT)) {
6315                         size += needed_padding(state, member->left, size);
6316                         if (i == index) {
6317                                 member = member->left;
6318                                 break;
6319                         }
6320                         size += size_of(state, member->left);
6321                         i++;
6322                         member = member->right;
6323                 }
6324                 size += needed_padding(state, member, size);
6325                 if (i != index) {
6326                         internal_error(state, 0, "Missing member index: %u", index);
6327                 }
6328         }
6329         else if ((type->type & TYPE_MASK) == TYPE_JOIN) {
6330                 ulong_t i;
6331                 size = 0;
6332                 member = type->left;
6333                 i = 0;
6334                 while(member && ((member->type & TYPE_MASK) == TYPE_OVERLAP)) {
6335                         if (i == index) {
6336                                 member = member->left;
6337                                 break;
6338                         }
6339                         i++;
6340                         member = member->right;
6341                 }
6342                 if (i != index) {
6343                         internal_error(state, 0, "Missing member index: %u", index);
6344                 }
6345         }
6346         else {
6347                 internal_error(state, 0, 
6348                         "request for index %u in something not an array, tuple or join",
6349                         index);
6350         }
6351         return size;
6352 }
6353
6354 static size_t index_reg_offset(struct compile_state *state, 
6355         struct type *type, ulong_t index)
6356 {
6357         struct type *member;
6358         size_t size;
6359         size = 0;
6360         if ((type->type & TYPE_MASK) == TYPE_ARRAY) {
6361                 size = reg_size_of(state, type->left) * index;
6362         }
6363         else if ((type->type & TYPE_MASK) == TYPE_TUPLE) {
6364                 ulong_t i;
6365                 member = type->left;
6366                 i = 0;
6367                 while(member && ((member->type & TYPE_MASK) == TYPE_PRODUCT)) {
6368                         size += reg_needed_padding(state, member->left, size);
6369                         if (i == index) {
6370                                 member = member->left;
6371                                 break;
6372                         }
6373                         size += reg_size_of(state, member->left);
6374                         i++;
6375                         member = member->right;
6376                 }
6377                 size += reg_needed_padding(state, member, size);
6378                 if (i != index) {
6379                         internal_error(state, 0, "Missing member index: %u", index);
6380                 }
6381                 
6382         }
6383         else if ((type->type & TYPE_MASK) == TYPE_JOIN) {
6384                 ulong_t i;
6385                 size = 0;
6386                 member = type->left;
6387                 i = 0;
6388                 while(member && ((member->type & TYPE_MASK) == TYPE_OVERLAP)) {
6389                         if (i == index) {
6390                                 member = member->left;
6391                                 break;
6392                         }
6393                         i++;
6394                         member = member->right;
6395                 }
6396                 if (i != index) {
6397                         internal_error(state, 0, "Missing member index: %u", index);
6398                 }
6399         }
6400         else {
6401                 internal_error(state, 0, 
6402                         "request for index %u in something not an array, tuple or join",
6403                         index);
6404         }
6405         return size;
6406 }
6407
6408 static struct type *index_type(struct compile_state *state,
6409         struct type *type, ulong_t index)
6410 {
6411         struct type *member;
6412         if (index >= type->elements) {
6413                 internal_error(state, 0, "Invalid element %u requested", index);
6414         }
6415         if ((type->type & TYPE_MASK) == TYPE_ARRAY) {
6416                 member = type->left;
6417         }
6418         else if ((type->type & TYPE_MASK) == TYPE_TUPLE) {
6419                 ulong_t i;
6420                 member = type->left;
6421                 i = 0;
6422                 while(member && ((member->type & TYPE_MASK) == TYPE_PRODUCT)) {
6423                         if (i == index) {
6424                                 member = member->left;
6425                                 break;
6426                         }
6427                         i++;
6428                         member = member->right;
6429                 }
6430                 if (i != index) {
6431                         internal_error(state, 0, "Missing member index: %u", index);
6432                 }
6433         }
6434         else if ((type->type & TYPE_MASK) == TYPE_JOIN) {
6435                 ulong_t i;
6436                 member = type->left;
6437                 i = 0;
6438                 while(member && ((member->type & TYPE_MASK) == TYPE_OVERLAP)) {
6439                         if (i == index) {
6440                                 member = member->left;
6441                                 break;
6442                         }
6443                         i++;
6444                         member = member->right;
6445                 }
6446                 if (i != index) {
6447                         internal_error(state, 0, "Missing member index: %u", index);
6448                 }
6449         }
6450         else {
6451                 member = 0;
6452                 internal_error(state, 0, 
6453                         "request for index %u in something not an array, tuple or join",
6454                         index);
6455         }
6456         return member;
6457 }
6458
6459 static struct type *unpack_type(struct compile_state *state, struct type *type)
6460 {
6461         /* If I have a single register compound type not a bit-field
6462          * find the real type.
6463          */
6464         struct type *start_type;
6465         size_t size;
6466         /* Get out early if I need multiple registers for this type */
6467         size = reg_size_of(state, type);
6468         if (size > REG_SIZEOF_REG) {
6469                 return type;
6470         }
6471         /* Get out early if I don't need any registers for this type */
6472         if (size == 0) {
6473                 return &void_type;
6474         }
6475         /* Loop until I have no more layers I can remove */
6476         do {
6477                 start_type = type;
6478                 switch(type->type & TYPE_MASK) {
6479                 case TYPE_ARRAY:
6480                         /* If I have a single element the unpacked type
6481                          * is that element.
6482                          */
6483                         if (type->elements == 1) {
6484                                 type = type->left;
6485                         }
6486                         break;
6487                 case TYPE_STRUCT:
6488                 case TYPE_TUPLE:
6489                         /* If I have a single element the unpacked type
6490                          * is that element.
6491                          */
6492                         if (type->elements == 1) {
6493                                 type = type->left;
6494                         }
6495                         /* If I have multiple elements the unpacked
6496                          * type is the non-void element.
6497                          */
6498                         else {
6499                                 struct type *next, *member;
6500                                 struct type *sub_type;
6501                                 sub_type = 0;
6502                                 next = type->left;
6503                                 while(next) {
6504                                         member = next;
6505                                         next = 0;
6506                                         if ((member->type & TYPE_MASK) == TYPE_PRODUCT) {
6507                                                 next = member->right;
6508                                                 member = member->left;
6509                                         }
6510                                         if (reg_size_of(state, member) > 0) {
6511                                                 if (sub_type) {
6512                                                         internal_error(state, 0, "true compound type in a register");
6513                                                 }
6514                                                 sub_type = member;
6515                                         }
6516                                 }
6517                                 if (sub_type) {
6518                                         type = sub_type;
6519                                 }
6520                         }
6521                         break;
6522
6523                 case TYPE_UNION:
6524                 case TYPE_JOIN:
6525                         /* If I have a single element the unpacked type
6526                          * is that element.
6527                          */
6528                         if (type->elements == 1) {
6529                                 type = type->left;
6530                         }
6531                         /* I can't in general unpack union types */
6532                         break;
6533                 default:
6534                         /* If I'm not a compound type I can't unpack it */
6535                         break;
6536                 }
6537         } while(start_type != type);
6538         switch(type->type & TYPE_MASK) {
6539         case TYPE_STRUCT:
6540         case TYPE_ARRAY:
6541         case TYPE_TUPLE:
6542                 internal_error(state, 0, "irredicible type?");
6543                 break;
6544         }
6545         return type;
6546 }
6547
6548 static int equiv_types(struct type *left, struct type *right);
6549 static int is_compound_type(struct type *type);
6550
6551 static struct type *reg_type(
6552         struct compile_state *state, struct type *type, int reg_offset)
6553 {
6554         struct type *member;
6555         size_t size;
6556 #if 1
6557         struct type *invalid;
6558         invalid = invalid_type(state, type);
6559         if (invalid) {
6560                 fprintf(state->errout, "type: ");
6561                 name_of(state->errout, type);
6562                 fprintf(state->errout, "\n");
6563                 fprintf(state->errout, "invalid: ");
6564                 name_of(state->errout, invalid);
6565                 fprintf(state->errout, "\n");
6566                 internal_error(state, 0, "bad input type?");
6567         }
6568 #endif
6569
6570         size = reg_size_of(state, type);
6571         if (reg_offset > size) {
6572                 member = 0;
6573                 fprintf(state->errout, "type: ");
6574                 name_of(state->errout, type);
6575                 fprintf(state->errout, "\n");
6576                 internal_error(state, 0, "offset outside of type");
6577         }
6578         else {
6579                 switch(type->type & TYPE_MASK) {
6580                         /* Don't do anything with the basic types */
6581                 case TYPE_VOID:
6582                 case TYPE_CHAR:         case TYPE_UCHAR:
6583                 case TYPE_SHORT:        case TYPE_USHORT:
6584                 case TYPE_INT:          case TYPE_UINT:
6585                 case TYPE_LONG:         case TYPE_ULONG:
6586                 case TYPE_LLONG:        case TYPE_ULLONG:
6587                 case TYPE_FLOAT:        case TYPE_DOUBLE:
6588                 case TYPE_LDOUBLE:
6589                 case TYPE_POINTER:
6590                 case TYPE_ENUM:
6591                 case TYPE_BITFIELD:
6592                         member = type;
6593                         break;
6594                 case TYPE_ARRAY:
6595                         member = type->left;
6596                         size = reg_size_of(state, member);
6597                         if (size > REG_SIZEOF_REG) {
6598                                 member = reg_type(state, member, reg_offset % size);
6599                         }
6600                         break;
6601                 case TYPE_STRUCT:
6602                 case TYPE_TUPLE:
6603                 {
6604                         size_t offset;
6605                         offset = 0;
6606                         member = type->left;
6607                         while(member && ((member->type & TYPE_MASK) == TYPE_PRODUCT)) {
6608                                 size = reg_size_of(state, member->left);
6609                                 offset += reg_needed_padding(state, member->left, offset);
6610                                 if ((offset + size) > reg_offset) {
6611                                         member = member->left;
6612                                         break;
6613                                 }
6614                                 offset += size;
6615                                 member = member->right;
6616                         }
6617                         offset += reg_needed_padding(state, member, offset);
6618                         member = reg_type(state, member, reg_offset - offset);
6619                         break;
6620                 }
6621                 case TYPE_UNION:
6622                 case TYPE_JOIN:
6623                 {
6624                         struct type *join, **jnext, *mnext;
6625                         join = new_type(TYPE_JOIN, 0, 0);
6626                         jnext = &join->left;
6627                         mnext = type->left;
6628                         while(mnext) {
6629                                 size_t size;
6630                                 member = mnext;
6631                                 mnext = 0;
6632                                 if ((member->type & TYPE_MASK) == TYPE_OVERLAP) {
6633                                         mnext = member->right;
6634                                         member = member->left;
6635                                 }
6636                                 size = reg_size_of(state, member);
6637                                 if (size > reg_offset) {
6638                                         struct type *part, *hunt;
6639                                         part = reg_type(state, member, reg_offset);
6640                                         /* See if this type is already in the union */
6641                                         hunt = join->left;
6642                                         while(hunt) {
6643                                                 struct type *test = hunt;
6644                                                 hunt = 0;
6645                                                 if ((test->type & TYPE_MASK) == TYPE_OVERLAP) {
6646                                                         hunt = test->right;
6647                                                         test = test->left;
6648                                                 }
6649                                                 if (equiv_types(part, test)) {
6650                                                         goto next;
6651                                                 }
6652                                         }
6653                                         /* Nope add it */
6654                                         if (!*jnext) {
6655                                                 *jnext = part;
6656                                         } else {
6657                                                 *jnext = new_type(TYPE_OVERLAP, *jnext, part);
6658                                                 jnext = &(*jnext)->right;
6659                                         }
6660                                         join->elements++;
6661                                 }
6662                         next:
6663                                 ;
6664                         }
6665                         if (join->elements == 0) {
6666                                 internal_error(state, 0, "No elements?");
6667                         }
6668                         member = join;
6669                         break;
6670                 }
6671                 default:
6672                         member = 0;
6673                         fprintf(state->errout, "type: ");
6674                         name_of(state->errout, type);
6675                         fprintf(state->errout, "\n");
6676                         internal_error(state, 0, "reg_type not yet defined for type");
6677                         
6678                 }
6679         }
6680         /* If I have a single register compound type not a bit-field
6681          * find the real type.
6682          */
6683         member = unpack_type(state, member);
6684                 ;
6685         size  = reg_size_of(state, member);
6686         if (size > REG_SIZEOF_REG) {
6687                 internal_error(state, 0, "Cannot find type of single register");
6688         }
6689 #if 1
6690         invalid = invalid_type(state, member);
6691         if (invalid) {
6692                 fprintf(state->errout, "type: ");
6693                 name_of(state->errout, member);
6694                 fprintf(state->errout, "\n");
6695                 fprintf(state->errout, "invalid: ");
6696                 name_of(state->errout, invalid);
6697                 fprintf(state->errout, "\n");
6698                 internal_error(state, 0, "returning bad type?");
6699         }
6700 #endif
6701         return member;
6702 }
6703
6704 static struct type *next_field(struct compile_state *state,
6705         struct type *type, struct type *prev_member) 
6706 {
6707         struct type *member;
6708         if ((type->type & TYPE_MASK) != TYPE_STRUCT) {
6709                 internal_error(state, 0, "next_field only works on structures");
6710         }
6711         member = type->left;
6712         while((member->type & TYPE_MASK) == TYPE_PRODUCT) {
6713                 if (!prev_member) {
6714                         member = member->left;
6715                         break;
6716                 }
6717                 if (member->left == prev_member) {
6718                         prev_member = 0;
6719                 }
6720                 member = member->right;
6721         }
6722         if (member == prev_member) {
6723                 prev_member = 0;
6724         }
6725         if (prev_member) {
6726                 internal_error(state, 0, "prev_member %s not present", 
6727                         prev_member->field_ident->name);
6728         }
6729         return member;
6730 }
6731
6732 typedef void (*walk_type_fields_cb_t)(struct compile_state *state, struct type *type, 
6733         size_t ret_offset, size_t mem_offset, void *arg);
6734
6735 static void walk_type_fields(struct compile_state *state,
6736         struct type *type, size_t reg_offset, size_t mem_offset,
6737         walk_type_fields_cb_t cb, void *arg);
6738
6739 static void walk_struct_fields(struct compile_state *state,
6740         struct type *type, size_t reg_offset, size_t mem_offset,
6741         walk_type_fields_cb_t cb, void *arg)
6742 {
6743         struct type *tptr;
6744         ulong_t i;
6745         if ((type->type & TYPE_MASK) != TYPE_STRUCT) {
6746                 internal_error(state, 0, "walk_struct_fields only works on structures");
6747         }
6748         tptr = type->left;
6749         for(i = 0; i < type->elements; i++) {
6750                 struct type *mtype;
6751                 mtype = tptr;
6752                 if ((mtype->type & TYPE_MASK) == TYPE_PRODUCT) {
6753                         mtype = mtype->left;
6754                 }
6755                 walk_type_fields(state, mtype, 
6756                         reg_offset + 
6757                         field_reg_offset(state, type, mtype->field_ident),
6758                         mem_offset + 
6759                         field_offset(state, type, mtype->field_ident),
6760                         cb, arg);
6761                 tptr = tptr->right;
6762         }
6763         
6764 }
6765
6766 static void walk_type_fields(struct compile_state *state,
6767         struct type *type, size_t reg_offset, size_t mem_offset,
6768         walk_type_fields_cb_t cb, void *arg)
6769 {
6770         switch(type->type & TYPE_MASK) {
6771         case TYPE_STRUCT:
6772                 walk_struct_fields(state, type, reg_offset, mem_offset, cb, arg);
6773                 break;
6774         case TYPE_CHAR:
6775         case TYPE_UCHAR:
6776         case TYPE_SHORT:
6777         case TYPE_USHORT:
6778         case TYPE_INT:
6779         case TYPE_UINT:
6780         case TYPE_LONG:
6781         case TYPE_ULONG:
6782                 cb(state, type, reg_offset, mem_offset, arg);
6783                 break;
6784         case TYPE_VOID:
6785                 break;
6786         default:
6787                 internal_error(state, 0, "walk_type_fields not yet implemented for type");
6788         }
6789 }
6790
6791 static void arrays_complete(struct compile_state *state, struct type *type)
6792 {
6793         if ((type->type & TYPE_MASK) == TYPE_ARRAY) {
6794                 if (type->elements == ELEMENT_COUNT_UNSPECIFIED) {
6795                         error(state, 0, "array size not specified");
6796                 }
6797                 arrays_complete(state, type->left);
6798         }
6799 }
6800
6801 static unsigned int get_basic_type(struct type *type)
6802 {
6803         unsigned int basic;
6804         basic = type->type & TYPE_MASK;
6805         /* Convert enums to ints */
6806         if (basic == TYPE_ENUM) {
6807                 basic = TYPE_INT;
6808         }
6809         /* Convert bitfields to standard types */
6810         else if (basic == TYPE_BITFIELD) {
6811                 if (type->elements <= SIZEOF_CHAR) {
6812                         basic = TYPE_CHAR;
6813                 }
6814                 else if (type->elements <= SIZEOF_SHORT) {
6815                         basic = TYPE_SHORT;
6816                 }
6817                 else if (type->elements <= SIZEOF_INT) {
6818                         basic = TYPE_INT;
6819                 }
6820                 else if (type->elements <= SIZEOF_LONG) {
6821                         basic = TYPE_LONG;
6822                 }
6823                 if (!TYPE_SIGNED(type->left->type)) {
6824                         basic += 1;
6825                 }
6826         }
6827         return basic;
6828 }
6829
6830 static unsigned int do_integral_promotion(unsigned int type)
6831 {
6832         if (TYPE_INTEGER(type) && (TYPE_RANK(type) < TYPE_RANK(TYPE_INT))) {
6833                 type = TYPE_INT;
6834         }
6835         return type;
6836 }
6837
6838 static unsigned int do_arithmetic_conversion(
6839         unsigned int left, unsigned int right)
6840 {
6841         if ((left == TYPE_LDOUBLE) || (right == TYPE_LDOUBLE)) {
6842                 return TYPE_LDOUBLE;
6843         }
6844         else if ((left == TYPE_DOUBLE) || (right == TYPE_DOUBLE)) {
6845                 return TYPE_DOUBLE;
6846         }
6847         else if ((left == TYPE_FLOAT) || (right == TYPE_FLOAT)) {
6848                 return TYPE_FLOAT;
6849         }
6850         left = do_integral_promotion(left);
6851         right = do_integral_promotion(right);
6852         /* If both operands have the same size done */
6853         if (left == right) {
6854                 return left;
6855         }
6856         /* If both operands have the same signedness pick the larger */
6857         else if (!!TYPE_UNSIGNED(left) == !!TYPE_UNSIGNED(right)) {
6858                 return (TYPE_RANK(left) >= TYPE_RANK(right)) ? left : right;
6859         }
6860         /* If the signed type can hold everything use it */
6861         else if (TYPE_SIGNED(left) && (TYPE_RANK(left) > TYPE_RANK(right))) {
6862                 return left;
6863         }
6864         else if (TYPE_SIGNED(right) && (TYPE_RANK(right) > TYPE_RANK(left))) {
6865                 return right;
6866         }
6867         /* Convert to the unsigned type with the same rank as the signed type */
6868         else if (TYPE_SIGNED(left)) {
6869                 return TYPE_MKUNSIGNED(left);
6870         }
6871         else {
6872                 return TYPE_MKUNSIGNED(right);
6873         }
6874 }
6875
6876 /* see if two types are the same except for qualifiers */
6877 static int equiv_types(struct type *left, struct type *right)
6878 {
6879         unsigned int type;
6880         /* Error if the basic types do not match */
6881         if ((left->type & TYPE_MASK) != (right->type & TYPE_MASK)) {
6882                 return 0;
6883         }
6884         type = left->type & TYPE_MASK;
6885         /* If the basic types match and it is a void type we are done */
6886         if (type == TYPE_VOID) {
6887                 return 1;
6888         }
6889         /* For bitfields we need to compare the sizes */
6890         else if (type == TYPE_BITFIELD) {
6891                 return (left->elements == right->elements) &&
6892                         (TYPE_SIGNED(left->left->type) == TYPE_SIGNED(right->left->type));
6893         }
6894         /* if the basic types match and it is an arithmetic type we are done */
6895         else if (TYPE_ARITHMETIC(type)) {
6896                 return 1;
6897         }
6898         /* If it is a pointer type recurse and keep testing */
6899         else if (type == TYPE_POINTER) {
6900                 return equiv_types(left->left, right->left);
6901         }
6902         else if (type == TYPE_ARRAY) {
6903                 return (left->elements == right->elements) &&
6904                         equiv_types(left->left, right->left);
6905         }
6906         /* test for struct equality */
6907         else if (type == TYPE_STRUCT) {
6908                 return left->type_ident == right->type_ident;
6909         }
6910         /* test for union equality */
6911         else if (type == TYPE_UNION) {
6912                 return left->type_ident == right->type_ident;
6913         }
6914         /* Test for equivalent functions */
6915         else if (type == TYPE_FUNCTION) {
6916                 return equiv_types(left->left, right->left) &&
6917                         equiv_types(left->right, right->right);
6918         }
6919         /* We only see TYPE_PRODUCT as part of function equivalence matching */
6920         /* We also see TYPE_PRODUCT as part of of tuple equivalence matchin */
6921         else if (type == TYPE_PRODUCT) {
6922                 return equiv_types(left->left, right->left) &&
6923                         equiv_types(left->right, right->right);
6924         }
6925         /* We should see TYPE_OVERLAP when comparing joins */
6926         else if (type == TYPE_OVERLAP) {
6927                 return equiv_types(left->left, right->left) &&
6928                         equiv_types(left->right, right->right);
6929         }
6930         /* Test for equivalence of tuples */
6931         else if (type == TYPE_TUPLE) {
6932                 return (left->elements == right->elements) &&
6933                         equiv_types(left->left, right->left);
6934         }
6935         /* Test for equivalence of joins */
6936         else if (type == TYPE_JOIN) {
6937                 return (left->elements == right->elements) &&
6938                         equiv_types(left->left, right->left);
6939         }
6940         else {
6941                 return 0;
6942         }
6943 }
6944
6945 static int equiv_ptrs(struct type *left, struct type *right)
6946 {
6947         if (((left->type & TYPE_MASK) != TYPE_POINTER) ||
6948                 ((right->type & TYPE_MASK) != TYPE_POINTER)) {
6949                 return 0;
6950         }
6951         return equiv_types(left->left, right->left);
6952 }
6953
6954 static struct type *compatible_types(struct type *left, struct type *right)
6955 {
6956         struct type *result;
6957         unsigned int type, qual_type;
6958         /* Error if the basic types do not match */
6959         if ((left->type & TYPE_MASK) != (right->type & TYPE_MASK)) {
6960                 return 0;
6961         }
6962         type = left->type & TYPE_MASK;
6963         qual_type = (left->type & ~STOR_MASK) | (right->type & ~STOR_MASK);
6964         result = 0;
6965         /* if the basic types match and it is an arithmetic type we are done */
6966         if (TYPE_ARITHMETIC(type)) {
6967                 result = new_type(qual_type, 0, 0);
6968         }
6969         /* If it is a pointer type recurse and keep testing */
6970         else if (type == TYPE_POINTER) {
6971                 result = compatible_types(left->left, right->left);
6972                 if (result) {
6973                         result = new_type(qual_type, result, 0);
6974                 }
6975         }
6976         /* test for struct equality */
6977         else if (type == TYPE_STRUCT) {
6978                 if (left->type_ident == right->type_ident) {
6979                         result = left;
6980                 }
6981         }
6982         /* test for union equality */
6983         else if (type == TYPE_UNION) {
6984                 if (left->type_ident == right->type_ident) {
6985                         result = left;
6986                 }
6987         }
6988         /* Test for equivalent functions */
6989         else if (type == TYPE_FUNCTION) {
6990                 struct type *lf, *rf;
6991                 lf = compatible_types(left->left, right->left);
6992                 rf = compatible_types(left->right, right->right);
6993                 if (lf && rf) {
6994                         result = new_type(qual_type, lf, rf);
6995                 }
6996         }
6997         /* We only see TYPE_PRODUCT as part of function equivalence matching */
6998         else if (type == TYPE_PRODUCT) {
6999                 struct type *lf, *rf;
7000                 lf = compatible_types(left->left, right->left);
7001                 rf = compatible_types(left->right, right->right);
7002                 if (lf && rf) {
7003                         result = new_type(qual_type, lf, rf);
7004                 }
7005         }
7006         else {
7007                 /* Nothing else is compatible */
7008         }
7009         return result;
7010 }
7011
7012 /* See if left is a equivalent to right or right is a union member of left */
7013 static int is_subset_type(struct type *left, struct type *right)
7014 {
7015         if (equiv_types(left, right)) {
7016                 return 1;
7017         }
7018         if ((left->type & TYPE_MASK) == TYPE_JOIN) {
7019                 struct type *member, *mnext;
7020                 mnext = left->left;
7021                 while(mnext) {
7022                         member = mnext;
7023                         mnext = 0;
7024                         if ((member->type & TYPE_MASK) == TYPE_OVERLAP) {
7025                                 mnext = member->right;
7026                                 member = member->left;
7027                         }
7028                         if (is_subset_type( member, right)) {
7029                                 return 1;
7030                         }
7031                 }
7032         }
7033         return 0;
7034 }
7035
7036 static struct type *compatible_ptrs(struct type *left, struct type *right)
7037 {
7038         struct type *result;
7039         if (((left->type & TYPE_MASK) != TYPE_POINTER) ||
7040                 ((right->type & TYPE_MASK) != TYPE_POINTER)) {
7041                 return 0;
7042         }
7043         result = compatible_types(left->left, right->left);
7044         if (result) {
7045                 unsigned int qual_type;
7046                 qual_type = (left->type & ~STOR_MASK) | (right->type & ~STOR_MASK);
7047                 result = new_type(qual_type, result, 0);
7048         }
7049         return result;
7050         
7051 }
7052 static struct triple *integral_promotion(
7053         struct compile_state *state, struct triple *def)
7054 {
7055         struct type *type;
7056         type = def->type;
7057         /* As all operations are carried out in registers
7058          * the values are converted on load I just convert
7059          * logical type of the operand.
7060          */
7061         if (TYPE_INTEGER(type->type)) {
7062                 unsigned int int_type;
7063                 int_type = type->type & ~TYPE_MASK;
7064                 int_type |= do_integral_promotion(get_basic_type(type));
7065                 if (int_type != type->type) {
7066                         if (def->op != OP_LOAD) {
7067                                 def->type = new_type(int_type, 0, 0);
7068                         }
7069                         else {
7070                                 def = triple(state, OP_CONVERT, 
7071                                         new_type(int_type, 0, 0), def, 0);
7072                         }
7073                 }
7074         }
7075         return def;
7076 }
7077
7078
7079 static void arithmetic(struct compile_state *state, struct triple *def)
7080 {
7081         if (!TYPE_ARITHMETIC(def->type->type)) {
7082                 error(state, 0, "arithmetic type expexted");
7083         }
7084 }
7085
7086 static void ptr_arithmetic(struct compile_state *state, struct triple *def)
7087 {
7088         if (!TYPE_PTR(def->type->type) && !TYPE_ARITHMETIC(def->type->type)) {
7089                 error(state, def, "pointer or arithmetic type expected");
7090         }
7091 }
7092
7093 static int is_integral(struct triple *ins)
7094 {
7095         return TYPE_INTEGER(ins->type->type);
7096 }
7097
7098 static void integral(struct compile_state *state, struct triple *def)
7099 {
7100         if (!is_integral(def)) {
7101                 error(state, 0, "integral type expected");
7102         }
7103 }
7104
7105
7106 static void bool(struct compile_state *state, struct triple *def)
7107 {
7108         if (!TYPE_ARITHMETIC(def->type->type) &&
7109                 ((def->type->type & TYPE_MASK) != TYPE_POINTER)) {
7110                 error(state, 0, "arithmetic or pointer type expected");
7111         }
7112 }
7113
7114 static int is_signed(struct type *type)
7115 {
7116         if ((type->type & TYPE_MASK) == TYPE_BITFIELD) {
7117                 type = type->left;
7118         }
7119         return !!TYPE_SIGNED(type->type);
7120 }
7121 static int is_compound_type(struct type *type)
7122 {
7123         int is_compound;
7124         switch((type->type & TYPE_MASK)) {
7125         case TYPE_ARRAY:
7126         case TYPE_STRUCT:
7127         case TYPE_TUPLE:
7128         case TYPE_UNION:
7129         case TYPE_JOIN: 
7130                 is_compound = 1;
7131                 break;
7132         default:
7133                 is_compound = 0;
7134                 break;
7135         }
7136         return is_compound;
7137 }
7138
7139 /* Is this value located in a register otherwise it must be in memory */
7140 static int is_in_reg(struct compile_state *state, struct triple *def)
7141 {
7142         int in_reg;
7143         if (def->op == OP_ADECL) {
7144                 in_reg = 1;
7145         }
7146         else if ((def->op == OP_SDECL) || (def->op == OP_DEREF)) {
7147                 in_reg = 0;
7148         }
7149         else if (triple_is_part(state, def)) {
7150                 in_reg = is_in_reg(state, MISC(def, 0));
7151         }
7152         else {
7153                 internal_error(state, def, "unknown expr storage location");
7154                 in_reg = -1;
7155         }
7156         return in_reg;
7157 }
7158
7159 /* Is this an auto or static variable location? Something that can
7160  * be assigned to.  Otherwise it must must be a pure value, a temporary.
7161  */
7162 static int is_lvalue(struct compile_state *state, struct triple *def)
7163 {
7164         int ret;
7165         ret = 0;
7166         if (!def) {
7167                 return 0;
7168         }
7169         if ((def->op == OP_ADECL) || 
7170                 (def->op == OP_SDECL) || 
7171                 (def->op == OP_DEREF) ||
7172                 (def->op == OP_BLOBCONST) ||
7173                 (def->op == OP_LIST)) {
7174                 ret = 1;
7175         }
7176         else if (triple_is_part(state, def)) {
7177                 ret = is_lvalue(state, MISC(def, 0));
7178         }
7179         return ret;
7180 }
7181
7182 static void clvalue(struct compile_state *state, struct triple *def)
7183 {
7184         if (!def) {
7185                 internal_error(state, def, "nothing where lvalue expected?");
7186         }
7187         if (!is_lvalue(state, def)) { 
7188                 error(state, def, "lvalue expected");
7189         }
7190 }
7191 static void lvalue(struct compile_state *state, struct triple *def)
7192 {
7193         clvalue(state, def);
7194         if (def->type->type & QUAL_CONST) {
7195                 error(state, def, "modifable lvalue expected");
7196         }
7197 }
7198
7199 static int is_pointer(struct triple *def)
7200 {
7201         return (def->type->type & TYPE_MASK) == TYPE_POINTER;
7202 }
7203
7204 static void pointer(struct compile_state *state, struct triple *def)
7205 {
7206         if (!is_pointer(def)) {
7207                 error(state, def, "pointer expected");
7208         }
7209 }
7210
7211 static struct triple *int_const(
7212         struct compile_state *state, struct type *type, ulong_t value)
7213 {
7214         struct triple *result;
7215         switch(type->type & TYPE_MASK) {
7216         case TYPE_CHAR:
7217         case TYPE_INT:   case TYPE_UINT:
7218         case TYPE_LONG:  case TYPE_ULONG:
7219                 break;
7220         default:
7221                 internal_error(state, 0, "constant for unknown type");
7222         }
7223         result = triple(state, OP_INTCONST, type, 0, 0);
7224         result->u.cval = value;
7225         return result;
7226 }
7227
7228
7229 static struct triple *read_expr(struct compile_state *state, struct triple *def);
7230
7231 static struct triple *do_mk_addr_expr(struct compile_state *state, 
7232         struct triple *expr, struct type *type, ulong_t offset)
7233 {
7234         struct triple *result;
7235         struct type *ptr_type;
7236         clvalue(state, expr);
7237
7238         ptr_type = new_type(TYPE_POINTER | (type->type & QUAL_MASK), type, 0);
7239
7240         
7241         result = 0;
7242         if (expr->op == OP_ADECL) {
7243                 error(state, expr, "address of auto variables not supported");
7244         }
7245         else if (expr->op == OP_SDECL) {
7246                 result = triple(state, OP_ADDRCONST, ptr_type, 0, 0);
7247                 MISC(result, 0) = expr;
7248                 result->u.cval = offset;
7249         }
7250         else if (expr->op == OP_DEREF) {
7251                 result = triple(state, OP_ADD, ptr_type,
7252                         RHS(expr, 0),
7253                         int_const(state, &ulong_type, offset));
7254         }
7255         else if (expr->op == OP_BLOBCONST) {
7256                 FINISHME();
7257                 internal_error(state, expr, "not yet implemented");
7258         }
7259         else if (expr->op == OP_LIST) {
7260                 error(state, 0, "Function addresses not supported");
7261         }
7262         else if (triple_is_part(state, expr)) {
7263                 struct triple *part;
7264                 part = expr;
7265                 expr = MISC(expr, 0);
7266                 if (part->op == OP_DOT) {
7267                         offset += bits_to_bytes(
7268                                 field_offset(state, expr->type, part->u.field));
7269                 }
7270                 else if (part->op == OP_INDEX) {
7271                         offset += bits_to_bytes(
7272                                 index_offset(state, expr->type, part->u.cval));
7273                 }
7274                 else {
7275                         internal_error(state, part, "unhandled part type");
7276                 }
7277                 result = do_mk_addr_expr(state, expr, type, offset);
7278         }
7279         if (!result) {
7280                 internal_error(state, expr, "cannot take address of expression");
7281         }
7282         return result;
7283 }
7284
7285 static struct triple *mk_addr_expr(
7286         struct compile_state *state, struct triple *expr, ulong_t offset)
7287 {
7288         return do_mk_addr_expr(state, expr, expr->type, offset);
7289 }
7290
7291 static struct triple *mk_deref_expr(
7292         struct compile_state *state, struct triple *expr)
7293 {
7294         struct type *base_type;
7295         pointer(state, expr);
7296         base_type = expr->type->left;
7297         return triple(state, OP_DEREF, base_type, expr, 0);
7298 }
7299
7300 /* lvalue conversions always apply except when certain operators
7301  * are applied.  So I apply apply it when I know no more
7302  * operators will be applied.
7303  */
7304 static struct triple *lvalue_conversion(struct compile_state *state, struct triple *def)
7305 {
7306         /* Tranform an array to a pointer to the first element */
7307         if ((def->type->type & TYPE_MASK) == TYPE_ARRAY) {
7308                 struct type *type;
7309                 type = new_type(
7310                         TYPE_POINTER | (def->type->type & QUAL_MASK),
7311                         def->type->left, 0);
7312                 if ((def->op == OP_SDECL) || IS_CONST_OP(def->op)) {
7313                         struct triple *addrconst;
7314                         if ((def->op != OP_SDECL) && (def->op != OP_BLOBCONST)) {
7315                                 internal_error(state, def, "bad array constant");
7316                         }
7317                         addrconst = triple(state, OP_ADDRCONST, type, 0, 0);
7318                         MISC(addrconst, 0) = def;
7319                         def = addrconst;
7320                 }
7321                 else {
7322                         def = triple(state, OP_CONVERT, type, def, 0);
7323                 }
7324         }
7325         /* Transform a function to a pointer to it */
7326         else if ((def->type->type & TYPE_MASK) == TYPE_FUNCTION) {
7327                 def = mk_addr_expr(state, def, 0);
7328         }
7329         return def;
7330 }
7331
7332 static struct triple *deref_field(
7333         struct compile_state *state, struct triple *expr, struct hash_entry *field)
7334 {
7335         struct triple *result;
7336         struct type *type, *member;
7337         ulong_t offset;
7338         if (!field) {
7339                 internal_error(state, 0, "No field passed to deref_field");
7340         }
7341         result = 0;
7342         type = expr->type;
7343         if (((type->type & TYPE_MASK) != TYPE_STRUCT) &&
7344                 ((type->type & TYPE_MASK) != TYPE_UNION)) {
7345                 error(state, 0, "request for member %s in something not a struct or union",
7346                         field->name);
7347         }
7348         member = field_type(state, type, field);
7349         if ((type->type & STOR_MASK) == STOR_PERM) {
7350                 /* Do the pointer arithmetic to get a deref the field */
7351                 offset = bits_to_bytes(field_offset(state, type, field));
7352                 result = do_mk_addr_expr(state, expr, member, offset);
7353                 result = mk_deref_expr(state, result);
7354         }
7355         else {
7356                 /* Find the variable for the field I want. */
7357                 result = triple(state, OP_DOT, member, expr, 0);
7358                 result->u.field = field;
7359         }
7360         return result;
7361 }
7362
7363 static struct triple *deref_index(
7364         struct compile_state *state, struct triple *expr, size_t index)
7365 {
7366         struct triple *result;
7367         struct type *type, *member;
7368         ulong_t offset;
7369
7370         result = 0;
7371         type = expr->type;
7372         member = index_type(state, type, index);
7373
7374         if ((type->type & STOR_MASK) == STOR_PERM) {
7375                 offset = bits_to_bytes(index_offset(state, type, index));
7376                 result = do_mk_addr_expr(state, expr, member, offset);
7377                 result = mk_deref_expr(state, result);
7378         }
7379         else {
7380                 result = triple(state, OP_INDEX, member, expr, 0);
7381                 result->u.cval = index;
7382         }
7383         return result;
7384 }
7385
7386 static struct triple *read_expr(struct compile_state *state, struct triple *def)
7387 {
7388         int op;
7389         if  (!def) {
7390                 return 0;
7391         }
7392 #warning "CHECK_ME is this the only place I need to do lvalue conversions?"
7393         /* Transform lvalues into something we can read */
7394         def = lvalue_conversion(state, def);
7395         if (!is_lvalue(state, def)) {
7396                 return def;
7397         }
7398         if (is_in_reg(state, def)) {
7399                 op = OP_READ;
7400         } else {
7401                 if (def->op == OP_SDECL) {
7402                         def = mk_addr_expr(state, def, 0);
7403                         def = mk_deref_expr(state, def);
7404                 }
7405                 op = OP_LOAD;
7406         }
7407         def = triple(state, op, def->type, def, 0);
7408         if (def->type->type & QUAL_VOLATILE) {
7409                 def->id |= TRIPLE_FLAG_VOLATILE;
7410         }
7411         return def;
7412 }
7413
7414 int is_write_compatible(struct compile_state *state, 
7415         struct type *dest, struct type *rval)
7416 {
7417         int compatible = 0;
7418         /* Both operands have arithmetic type */
7419         if (TYPE_ARITHMETIC(dest->type) && TYPE_ARITHMETIC(rval->type)) {
7420                 compatible = 1;
7421         }
7422         /* One operand is a pointer and the other is a pointer to void */
7423         else if (((dest->type & TYPE_MASK) == TYPE_POINTER) &&
7424                 ((rval->type & TYPE_MASK) == TYPE_POINTER) &&
7425                 (((dest->left->type & TYPE_MASK) == TYPE_VOID) ||
7426                         ((rval->left->type & TYPE_MASK) == TYPE_VOID))) {
7427                 compatible = 1;
7428         }
7429         /* If both types are the same without qualifiers we are good */
7430         else if (equiv_ptrs(dest, rval)) {
7431                 compatible = 1;
7432         }
7433         /* test for struct/union equality  */
7434         else if (equiv_types(dest, rval)) {
7435                 compatible = 1;
7436         }
7437         return compatible;
7438 }
7439
7440 static void write_compatible(struct compile_state *state,
7441         struct type *dest, struct type *rval)
7442 {
7443         if (!is_write_compatible(state, dest, rval)) {
7444                 FILE *fp = state->errout;
7445                 fprintf(fp, "dest: ");
7446                 name_of(fp, dest);
7447                 fprintf(fp,"\nrval: ");
7448                 name_of(fp, rval);
7449                 fprintf(fp, "\n");
7450                 error(state, 0, "Incompatible types in assignment");
7451         }
7452 }
7453
7454 static int is_init_compatible(struct compile_state *state,
7455         struct type *dest, struct type *rval)
7456 {
7457         int compatible = 0;
7458         if (is_write_compatible(state, dest, rval)) {
7459                 compatible = 1;
7460         }
7461         else if (equiv_types(dest, rval)) {
7462                 compatible = 1;
7463         }
7464         return compatible;
7465 }
7466
7467 static struct triple *write_expr(
7468         struct compile_state *state, struct triple *dest, struct triple *rval)
7469 {
7470         struct triple *def;
7471         int op;
7472
7473         def = 0;
7474         if (!rval) {
7475                 internal_error(state, 0, "missing rval");
7476         }
7477
7478         if (rval->op == OP_LIST) {
7479                 internal_error(state, 0, "expression of type OP_LIST?");
7480         }
7481         if (!is_lvalue(state, dest)) {
7482                 internal_error(state, 0, "writing to a non lvalue?");
7483         }
7484         if (dest->type->type & QUAL_CONST) {
7485                 internal_error(state, 0, "modifable lvalue expexted");
7486         }
7487
7488         write_compatible(state, dest->type, rval->type);
7489         if (!equiv_types(dest->type, rval->type)) {
7490                 rval = triple(state, OP_CONVERT, dest->type, rval, 0);
7491         }
7492
7493         /* Now figure out which assignment operator to use */
7494         op = -1;
7495         if (is_in_reg(state, dest)) {
7496                 def = triple(state, OP_WRITE, dest->type, rval, dest);
7497                 if (MISC(def, 0) != dest) {
7498                         internal_error(state, def, "huh?");
7499                 }
7500                 if (RHS(def, 0) != rval) {
7501                         internal_error(state, def, "huh?");
7502                 }
7503         } else {
7504                 def = triple(state, OP_STORE, dest->type, dest, rval);
7505         }
7506         if (def->type->type & QUAL_VOLATILE) {
7507                 def->id |= TRIPLE_FLAG_VOLATILE;
7508         }
7509         return def;
7510 }
7511
7512 static struct triple *init_expr(
7513         struct compile_state *state, struct triple *dest, struct triple *rval)
7514 {
7515         struct triple *def;
7516
7517         def = 0;
7518         if (!rval) {
7519                 internal_error(state, 0, "missing rval");
7520         }
7521         if ((dest->type->type & STOR_MASK) != STOR_PERM) {
7522                 rval = read_expr(state, rval);
7523                 def = write_expr(state, dest, rval);
7524         }
7525         else {
7526                 /* Fill in the array size if necessary */
7527                 if (((dest->type->type & TYPE_MASK) == TYPE_ARRAY) &&
7528                         ((rval->type->type & TYPE_MASK) == TYPE_ARRAY)) {
7529                         if (dest->type->elements == ELEMENT_COUNT_UNSPECIFIED) {
7530                                 dest->type->elements = rval->type->elements;
7531                         }
7532                 }
7533                 if (!equiv_types(dest->type, rval->type)) {
7534                         error(state, 0, "Incompatible types in inializer");
7535                 }
7536                 MISC(dest, 0) = rval;
7537                 insert_triple(state, dest, rval);
7538                 rval->id |= TRIPLE_FLAG_FLATTENED;
7539                 use_triple(MISC(dest, 0), dest);
7540         }
7541         return def;
7542 }
7543
7544 struct type *arithmetic_result(
7545         struct compile_state *state, struct triple *left, struct triple *right)
7546 {
7547         struct type *type;
7548         /* Sanity checks to ensure I am working with arithmetic types */
7549         arithmetic(state, left);
7550         arithmetic(state, right);
7551         type = new_type(
7552                 do_arithmetic_conversion(
7553                         get_basic_type(left->type),
7554                         get_basic_type(right->type)),
7555                 0, 0);
7556         return type;
7557 }
7558
7559 struct type *ptr_arithmetic_result(
7560         struct compile_state *state, struct triple *left, struct triple *right)
7561 {
7562         struct type *type;
7563         /* Sanity checks to ensure I am working with the proper types */
7564         ptr_arithmetic(state, left);
7565         arithmetic(state, right);
7566         if (TYPE_ARITHMETIC(left->type->type) && 
7567                 TYPE_ARITHMETIC(right->type->type)) {
7568                 type = arithmetic_result(state, left, right);
7569         }
7570         else if (TYPE_PTR(left->type->type)) {
7571                 type = left->type;
7572         }
7573         else {
7574                 internal_error(state, 0, "huh?");
7575                 type = 0;
7576         }
7577         return type;
7578 }
7579
7580 /* boolean helper function */
7581
7582 static struct triple *ltrue_expr(struct compile_state *state, 
7583         struct triple *expr)
7584 {
7585         switch(expr->op) {
7586         case OP_LTRUE:   case OP_LFALSE:  case OP_EQ:      case OP_NOTEQ:
7587         case OP_SLESS:   case OP_ULESS:   case OP_SMORE:   case OP_UMORE:
7588         case OP_SLESSEQ: case OP_ULESSEQ: case OP_SMOREEQ: case OP_UMOREEQ:
7589                 /* If the expression is already boolean do nothing */
7590                 break;
7591         default:
7592                 expr = triple(state, OP_LTRUE, &int_type, expr, 0);
7593                 break;
7594         }
7595         return expr;
7596 }
7597
7598 static struct triple *lfalse_expr(struct compile_state *state, 
7599         struct triple *expr)
7600 {
7601         return triple(state, OP_LFALSE, &int_type, expr, 0);
7602 }
7603
7604 static struct triple *mkland_expr(
7605         struct compile_state *state,
7606         struct triple *left, struct triple *right)
7607 {
7608         struct triple *def, *val, *var, *jmp, *mid, *end;
7609         struct triple *lstore, *rstore;
7610
7611         /* Generate some intermediate triples */
7612         end = label(state);
7613         var = variable(state, &int_type);
7614         
7615         /* Store the left hand side value */
7616         lstore = write_expr(state, var, left);
7617
7618         /* Jump if the value is false */
7619         jmp =  branch(state, end, 
7620                 lfalse_expr(state, read_expr(state, var)));
7621         mid = label(state);
7622         
7623         /* Store the right hand side value */
7624         rstore = write_expr(state, var, right);
7625
7626         /* An expression for the computed value */
7627         val = read_expr(state, var);
7628
7629         /* Generate the prog for a logical and */
7630         def = mkprog(state, var, lstore, jmp, mid, rstore, end, val, 0);
7631         
7632         return def;
7633 }
7634
7635 static struct triple *mklor_expr(
7636         struct compile_state *state,
7637         struct triple *left, struct triple *right)
7638 {
7639         struct triple *def, *val, *var, *jmp, *mid, *end;
7640
7641         /* Generate some intermediate triples */
7642         end = label(state);
7643         var = variable(state, &int_type);
7644         
7645         /* Store the left hand side value */
7646         left = write_expr(state, var, left);
7647         
7648         /* Jump if the value is true */
7649         jmp = branch(state, end, read_expr(state, var));
7650         mid = label(state);
7651         
7652         /* Store the right hand side value */
7653         right = write_expr(state, var, right);
7654                 
7655         /* An expression for the computed value*/
7656         val = read_expr(state, var);
7657
7658         /* Generate the prog for a logical or */
7659         def = mkprog(state, var, left, jmp, mid, right, end, val, 0);
7660
7661         return def;
7662 }
7663
7664 static struct triple *mkcond_expr(
7665         struct compile_state *state, 
7666         struct triple *test, struct triple *left, struct triple *right)
7667 {
7668         struct triple *def, *val, *var, *jmp1, *jmp2, *top, *mid, *end;
7669         struct type *result_type;
7670         unsigned int left_type, right_type;
7671         bool(state, test);
7672         left_type = left->type->type;
7673         right_type = right->type->type;
7674         result_type = 0;
7675         /* Both operands have arithmetic type */
7676         if (TYPE_ARITHMETIC(left_type) && TYPE_ARITHMETIC(right_type)) {
7677                 result_type = arithmetic_result(state, left, right);
7678         }
7679         /* Both operands have void type */
7680         else if (((left_type & TYPE_MASK) == TYPE_VOID) &&
7681                 ((right_type & TYPE_MASK) == TYPE_VOID)) {
7682                 result_type = &void_type;
7683         }
7684         /* pointers to the same type... */
7685         else if ((result_type = compatible_ptrs(left->type, right->type))) {
7686                 ;
7687         }
7688         /* Both operands are pointers and left is a pointer to void */
7689         else if (((left_type & TYPE_MASK) == TYPE_POINTER) &&
7690                 ((right_type & TYPE_MASK) == TYPE_POINTER) &&
7691                 ((left->type->left->type & TYPE_MASK) == TYPE_VOID)) {
7692                 result_type = right->type;
7693         }
7694         /* Both operands are pointers and right is a pointer to void */
7695         else if (((left_type & TYPE_MASK) == TYPE_POINTER) &&
7696                 ((right_type & TYPE_MASK) == TYPE_POINTER) &&
7697                 ((right->type->left->type & TYPE_MASK) == TYPE_VOID)) {
7698                 result_type = left->type;
7699         }
7700         if (!result_type) {
7701                 error(state, 0, "Incompatible types in conditional expression");
7702         }
7703         /* Generate some intermediate triples */
7704         mid = label(state);
7705         end = label(state);
7706         var = variable(state, result_type);
7707
7708         /* Branch if the test is false */
7709         jmp1 = branch(state, mid, lfalse_expr(state, read_expr(state, test)));
7710         top = label(state);
7711
7712         /* Store the left hand side value */
7713         left = write_expr(state, var, left);
7714
7715         /* Branch to the end */
7716         jmp2 = branch(state, end, 0);
7717
7718         /* Store the right hand side value */
7719         right = write_expr(state, var, right);
7720         
7721         /* An expression for the computed value */
7722         val = read_expr(state, var);
7723
7724         /* Generate the prog for a conditional expression */
7725         def = mkprog(state, var, jmp1, top, left, jmp2, mid, right, end, val, 0);
7726
7727         return def;
7728 }
7729
7730
7731 static int expr_depth(struct compile_state *state, struct triple *ins)
7732 {
7733 #warning "FIXME move optimal ordering of subexpressions into the optimizer"
7734         int count;
7735         count = 0;
7736         if (!ins || (ins->id & TRIPLE_FLAG_FLATTENED)) {
7737                 count = 0;
7738         }
7739         else if (ins->op == OP_DEREF) {
7740                 count = expr_depth(state, RHS(ins, 0)) - 1;
7741         }
7742         else if (ins->op == OP_VAL) {
7743                 count = expr_depth(state, RHS(ins, 0)) - 1;
7744         }
7745         else if (ins->op == OP_FCALL) {
7746                 /* Don't figure the depth of a call just guess it is huge */
7747                 count = 1000;
7748         }
7749         else {
7750                 struct triple **expr;
7751                 expr = triple_rhs(state, ins, 0);
7752                 for(;expr; expr = triple_rhs(state, ins, expr)) {
7753                         if (*expr) {
7754                                 int depth;
7755                                 depth = expr_depth(state, *expr);
7756                                 if (depth > count) {
7757                                         count = depth;
7758                                 }
7759                         }
7760                 }
7761         }
7762         return count + 1;
7763 }
7764
7765 static struct triple *flatten_generic(
7766         struct compile_state *state, struct triple *first, struct triple *ptr,
7767         int ignored)
7768 {
7769         struct rhs_vector {
7770                 int depth;
7771                 struct triple **ins;
7772         } vector[MAX_RHS];
7773         int i, rhs, lhs;
7774         /* Only operations with just a rhs and a lhs should come here */
7775         rhs = ptr->rhs;
7776         lhs = ptr->lhs;
7777         if (TRIPLE_SIZE(ptr) != lhs + rhs + ignored) {
7778                 internal_error(state, ptr, "unexpected args for: %d %s",
7779                         ptr->op, tops(ptr->op));
7780         }
7781         /* Find the depth of the rhs elements */
7782         for(i = 0; i < rhs; i++) {
7783                 vector[i].ins = &RHS(ptr, i);
7784                 vector[i].depth = expr_depth(state, *vector[i].ins);
7785         }
7786         /* Selection sort the rhs */
7787         for(i = 0; i < rhs; i++) {
7788                 int j, max = i;
7789                 for(j = i + 1; j < rhs; j++ ) {
7790                         if (vector[j].depth > vector[max].depth) {
7791                                 max = j;
7792                         }
7793                 }
7794                 if (max != i) {
7795                         struct rhs_vector tmp;
7796                         tmp = vector[i];
7797                         vector[i] = vector[max];
7798                         vector[max] = tmp;
7799                 }
7800         }
7801         /* Now flatten the rhs elements */
7802         for(i = 0; i < rhs; i++) {
7803                 *vector[i].ins = flatten(state, first, *vector[i].ins);
7804                 use_triple(*vector[i].ins, ptr);
7805         }
7806         if (lhs) {
7807                 insert_triple(state, first, ptr);
7808                 ptr->id |= TRIPLE_FLAG_FLATTENED;
7809                 ptr->id &= ~TRIPLE_FLAG_LOCAL;
7810                 
7811                 /* Now flatten the lhs elements */
7812                 for(i = 0; i < lhs; i++) {
7813                         struct triple **ins = &LHS(ptr, i);
7814                         *ins = flatten(state, first, *ins);
7815                         use_triple(*ins, ptr);
7816                 }
7817         }
7818         return ptr;
7819 }
7820
7821 static struct triple *flatten_prog(
7822         struct compile_state *state, struct triple *first, struct triple *ptr)
7823 {
7824         struct triple *head, *body, *val;
7825         head = RHS(ptr, 0);
7826         RHS(ptr, 0) = 0;
7827         val  = head->prev;
7828         body = head->next;
7829         release_triple(state, head);
7830         release_triple(state, ptr);
7831         val->next        = first;
7832         body->prev       = first->prev;
7833         body->prev->next = body;
7834         val->next->prev  = val;
7835
7836         if (triple_is_cbranch(state, body->prev) ||
7837                 triple_is_call(state, body->prev)) {
7838                 unuse_triple(first, body->prev);
7839                 use_triple(body, body->prev);
7840         }
7841         
7842         if (!(val->id & TRIPLE_FLAG_FLATTENED)) {
7843                 internal_error(state, val, "val not flattened?");
7844         }
7845
7846         return val;
7847 }
7848
7849
7850 static struct triple *flatten_part(
7851         struct compile_state *state, struct triple *first, struct triple *ptr)
7852 {
7853         if (!triple_is_part(state, ptr)) {
7854                 internal_error(state, ptr,  "not a part");
7855         }
7856         if (ptr->rhs || ptr->lhs || ptr->targ || (ptr->misc != 1)) {
7857                 internal_error(state, ptr, "unexpected args for: %d %s",
7858                         ptr->op, tops(ptr->op));
7859         }
7860         MISC(ptr, 0) = flatten(state, first, MISC(ptr, 0));
7861         use_triple(MISC(ptr, 0), ptr);
7862         return flatten_generic(state, first, ptr, 1);
7863 }
7864
7865 static struct triple *flatten(
7866         struct compile_state *state, struct triple *first, struct triple *ptr)
7867 {
7868         struct triple *orig_ptr;
7869         if (!ptr)
7870                 return 0;
7871         do {
7872                 orig_ptr = ptr;
7873                 /* Only flatten triples once */
7874                 if (ptr->id & TRIPLE_FLAG_FLATTENED) {
7875                         return ptr;
7876                 }
7877                 switch(ptr->op) {
7878                 case OP_VAL:
7879                         RHS(ptr, 0) = flatten(state, first, RHS(ptr, 0));
7880                         return MISC(ptr, 0);
7881                         break;
7882                 case OP_PROG:
7883                         ptr = flatten_prog(state, first, ptr);
7884                         break;
7885                 case OP_FCALL:
7886                         ptr = flatten_generic(state, first, ptr, 1);
7887                         insert_triple(state, first, ptr);
7888                         ptr->id |= TRIPLE_FLAG_FLATTENED;
7889                         ptr->id &= ~TRIPLE_FLAG_LOCAL;
7890                         if (ptr->next != ptr) {
7891                                 use_triple(ptr->next, ptr);
7892                         }
7893                         break;
7894                 case OP_READ:
7895                 case OP_LOAD:
7896                         RHS(ptr, 0) = flatten(state, first, RHS(ptr, 0));
7897                         use_triple(RHS(ptr, 0), ptr);
7898                         break;
7899                 case OP_WRITE:
7900                         ptr = flatten_generic(state, first, ptr, 1);
7901                         MISC(ptr, 0) = flatten(state, first, MISC(ptr, 0));
7902                         use_triple(MISC(ptr, 0), ptr);
7903                         break;
7904                 case OP_BRANCH:
7905                         use_triple(TARG(ptr, 0), ptr);
7906                         break;
7907                 case OP_CBRANCH:
7908                         RHS(ptr, 0) = flatten(state, first, RHS(ptr, 0));
7909                         use_triple(RHS(ptr, 0), ptr);
7910                         use_triple(TARG(ptr, 0), ptr);
7911                         insert_triple(state, first, ptr);
7912                         ptr->id |= TRIPLE_FLAG_FLATTENED;
7913                         ptr->id &= ~TRIPLE_FLAG_LOCAL;
7914                         if (ptr->next != ptr) {
7915                                 use_triple(ptr->next, ptr);
7916                         }
7917                         break;
7918                 case OP_CALL:
7919                         MISC(ptr, 0) = flatten(state, first, MISC(ptr, 0));
7920                         use_triple(MISC(ptr, 0), ptr);
7921                         use_triple(TARG(ptr, 0), ptr);
7922                         insert_triple(state, first, ptr);
7923                         ptr->id |= TRIPLE_FLAG_FLATTENED;
7924                         ptr->id &= ~TRIPLE_FLAG_LOCAL;
7925                         if (ptr->next != ptr) {
7926                                 use_triple(ptr->next, ptr);
7927                         }
7928                         break;
7929                 case OP_RET:
7930                         RHS(ptr, 0) = flatten(state, first, RHS(ptr, 0));
7931                         use_triple(RHS(ptr, 0), ptr);
7932                         break;
7933                 case OP_BLOBCONST:
7934                         insert_triple(state, state->global_pool, ptr);
7935                         ptr->id |= TRIPLE_FLAG_FLATTENED;
7936                         ptr->id &= ~TRIPLE_FLAG_LOCAL;
7937                         ptr = triple(state, OP_SDECL, ptr->type, ptr, 0);
7938                         use_triple(MISC(ptr, 0), ptr);
7939                         break;
7940                 case OP_DEREF:
7941                         /* Since OP_DEREF is just a marker delete it when I flatten it */
7942                         ptr = RHS(ptr, 0);
7943                         RHS(orig_ptr, 0) = 0;
7944                         free_triple(state, orig_ptr);
7945                         break;
7946                 case OP_DOT:
7947                         if (RHS(ptr, 0)->op == OP_DEREF) {
7948                                 struct triple *base, *left;
7949                                 ulong_t offset;
7950                                 base = MISC(ptr, 0);
7951                                 offset = bits_to_bytes(field_offset(state, base->type, ptr->u.field));
7952                                 left = RHS(base, 0);
7953                                 ptr = triple(state, OP_ADD, left->type, 
7954                                         read_expr(state, left),
7955                                         int_const(state, &ulong_type, offset));
7956                                 free_triple(state, base);
7957                         }
7958                         else {
7959                                 ptr = flatten_part(state, first, ptr);
7960                         }
7961                         break;
7962                 case OP_INDEX:
7963                         if (RHS(ptr, 0)->op == OP_DEREF) {
7964                                 struct triple *base, *left;
7965                                 ulong_t offset;
7966                                 base = MISC(ptr, 0);
7967                                 offset = bits_to_bytes(index_offset(state, base->type, ptr->u.cval));
7968                                 left = RHS(base, 0);
7969                                 ptr = triple(state, OP_ADD, left->type,
7970                                         read_expr(state, left),
7971                                         int_const(state, &long_type, offset));
7972                                 free_triple(state, base);
7973                         }
7974                         else {
7975                                 ptr = flatten_part(state, first, ptr);
7976                         }
7977                         break;
7978                 case OP_PIECE:
7979                         ptr = flatten_part(state, first, ptr);
7980                         use_triple(ptr, MISC(ptr, 0));
7981                         break;
7982                 case OP_ADDRCONST:
7983                         MISC(ptr, 0) = flatten(state, first, MISC(ptr, 0));
7984                         use_triple(MISC(ptr, 0), ptr);
7985                         break;
7986                 case OP_SDECL:
7987                         first = state->global_pool;
7988                         MISC(ptr, 0) = flatten(state, first, MISC(ptr, 0));
7989                         use_triple(MISC(ptr, 0), ptr);
7990                         insert_triple(state, first, ptr);
7991                         ptr->id |= TRIPLE_FLAG_FLATTENED;
7992                         ptr->id &= ~TRIPLE_FLAG_LOCAL;
7993                         return ptr;
7994                 case OP_ADECL:
7995                         ptr = flatten_generic(state, first, ptr, 0);
7996                         break;
7997                 default:
7998                         /* Flatten the easy cases we don't override */
7999                         ptr = flatten_generic(state, first, ptr, 0);
8000                         break;
8001                 }
8002         } while(ptr && (ptr != orig_ptr));
8003         if (ptr && !(ptr->id & TRIPLE_FLAG_FLATTENED)) {
8004                 insert_triple(state, first, ptr);
8005                 ptr->id |= TRIPLE_FLAG_FLATTENED;
8006                 ptr->id &= ~TRIPLE_FLAG_LOCAL;
8007         }
8008         return ptr;
8009 }
8010
8011 static void release_expr(struct compile_state *state, struct triple *expr)
8012 {
8013         struct triple *head;
8014         head = label(state);
8015         flatten(state, head, expr);
8016         while(head->next != head) {
8017                 release_triple(state, head->next);
8018         }
8019         free_triple(state, head);
8020 }
8021
8022 static int replace_rhs_use(struct compile_state *state,
8023         struct triple *orig, struct triple *new, struct triple *use)
8024 {
8025         struct triple **expr;
8026         int found;
8027         found = 0;
8028         expr = triple_rhs(state, use, 0);
8029         for(;expr; expr = triple_rhs(state, use, expr)) {
8030                 if (*expr == orig) {
8031                         *expr = new;
8032                         found = 1;
8033                 }
8034         }
8035         if (found) {
8036                 unuse_triple(orig, use);
8037                 use_triple(new, use);
8038         }
8039         return found;
8040 }
8041
8042 static int replace_lhs_use(struct compile_state *state,
8043         struct triple *orig, struct triple *new, struct triple *use)
8044 {
8045         struct triple **expr;
8046         int found;
8047         found = 0;
8048         expr = triple_lhs(state, use, 0);
8049         for(;expr; expr = triple_lhs(state, use, expr)) {
8050                 if (*expr == orig) {
8051                         *expr = new;
8052                         found = 1;
8053                 }
8054         }
8055         if (found) {
8056                 unuse_triple(orig, use);
8057                 use_triple(new, use);
8058         }
8059         return found;
8060 }
8061
8062 static int replace_misc_use(struct compile_state *state,
8063         struct triple *orig, struct triple *new, struct triple *use)
8064 {
8065         struct triple **expr;
8066         int found;
8067         found = 0;
8068         expr = triple_misc(state, use, 0);
8069         for(;expr; expr = triple_misc(state, use, expr)) {
8070                 if (*expr == orig) {
8071                         *expr = new;
8072                         found = 1;
8073                 }
8074         }
8075         if (found) {
8076                 unuse_triple(orig, use);
8077                 use_triple(new, use);
8078         }
8079         return found;
8080 }
8081
8082 static int replace_targ_use(struct compile_state *state,
8083         struct triple *orig, struct triple *new, struct triple *use)
8084 {
8085         struct triple **expr;
8086         int found;
8087         found = 0;
8088         expr = triple_targ(state, use, 0);
8089         for(;expr; expr = triple_targ(state, use, expr)) {
8090                 if (*expr == orig) {
8091                         *expr = new;
8092                         found = 1;
8093                 }
8094         }
8095         if (found) {
8096                 unuse_triple(orig, use);
8097                 use_triple(new, use);
8098         }
8099         return found;
8100 }
8101
8102 static void replace_use(struct compile_state *state,
8103         struct triple *orig, struct triple *new, struct triple *use)
8104 {
8105         int found;
8106         found = 0;
8107         found |= replace_rhs_use(state, orig, new, use);
8108         found |= replace_lhs_use(state, orig, new, use);
8109         found |= replace_misc_use(state, orig, new, use);
8110         found |= replace_targ_use(state, orig, new, use);
8111         if (!found) {
8112                 internal_error(state, use, "use without use");
8113         }
8114 }
8115
8116 static void propogate_use(struct compile_state *state,
8117         struct triple *orig, struct triple *new)
8118 {
8119         struct triple_set *user, *next;
8120         for(user = orig->use; user; user = next) {
8121                 /* Careful replace_use modifies the use chain and
8122                  * removes use.  So we must get a copy of the next
8123                  * entry early.
8124                  */
8125                 next = user->next;
8126                 replace_use(state, orig, new, user->member);
8127         }
8128         if (orig->use) {
8129                 internal_error(state, orig, "used after propogate_use");
8130         }
8131 }
8132
8133 /*
8134  * Code generators
8135  * ===========================
8136  */
8137
8138 static struct triple *mk_cast_expr(
8139         struct compile_state *state, struct type *type, struct triple *expr)
8140 {
8141         struct triple *def;
8142         def = read_expr(state, expr);
8143         def = triple(state, OP_CONVERT, type, def, 0);
8144         return def;
8145 }
8146
8147 static struct triple *mk_add_expr(
8148         struct compile_state *state, struct triple *left, struct triple *right)
8149 {
8150         struct type *result_type;
8151         /* Put pointer operands on the left */
8152         if (is_pointer(right)) {
8153                 struct triple *tmp;
8154                 tmp = left;
8155                 left = right;
8156                 right = tmp;
8157         }
8158         left  = read_expr(state, left);
8159         right = read_expr(state, right);
8160         result_type = ptr_arithmetic_result(state, left, right);
8161         if (is_pointer(left)) {
8162                 struct type *ptr_math;
8163                 int op;
8164                 if (is_signed(right->type)) {
8165                         ptr_math = &long_type;
8166                         op = OP_SMUL;
8167                 } else {
8168                         ptr_math = &ulong_type;
8169                         op = OP_UMUL;
8170                 }
8171                 if (!equiv_types(right->type, ptr_math)) {
8172                         right = mk_cast_expr(state, ptr_math, right);
8173                 }
8174                 right = triple(state, op, ptr_math, right, 
8175                         int_const(state, ptr_math, 
8176                                 size_of_in_bytes(state, left->type->left)));
8177         }
8178         return triple(state, OP_ADD, result_type, left, right);
8179 }
8180
8181 static struct triple *mk_sub_expr(
8182         struct compile_state *state, struct triple *left, struct triple *right)
8183 {
8184         struct type *result_type;
8185         result_type = ptr_arithmetic_result(state, left, right);
8186         left  = read_expr(state, left);
8187         right = read_expr(state, right);
8188         if (is_pointer(left)) {
8189                 struct type *ptr_math;
8190                 int op;
8191                 if (is_signed(right->type)) {
8192                         ptr_math = &long_type;
8193                         op = OP_SMUL;
8194                 } else {
8195                         ptr_math = &ulong_type;
8196                         op = OP_UMUL;
8197                 }
8198                 if (!equiv_types(right->type, ptr_math)) {
8199                         right = mk_cast_expr(state, ptr_math, right);
8200                 }
8201                 right = triple(state, op, ptr_math, right, 
8202                         int_const(state, ptr_math, 
8203                                 size_of_in_bytes(state, left->type->left)));
8204         }
8205         return triple(state, OP_SUB, result_type, left, right);
8206 }
8207
8208 static struct triple *mk_pre_inc_expr(
8209         struct compile_state *state, struct triple *def)
8210 {
8211         struct triple *val;
8212         lvalue(state, def);
8213         val = mk_add_expr(state, def, int_const(state, &int_type, 1));
8214         return triple(state, OP_VAL, def->type,
8215                 write_expr(state, def, val),
8216                 val);
8217 }
8218
8219 static struct triple *mk_pre_dec_expr(
8220         struct compile_state *state, struct triple *def)
8221 {
8222         struct triple *val;
8223         lvalue(state, def);
8224         val = mk_sub_expr(state, def, int_const(state, &int_type, 1));
8225         return triple(state, OP_VAL, def->type,
8226                 write_expr(state, def, val),
8227                 val);
8228 }
8229
8230 static struct triple *mk_post_inc_expr(
8231         struct compile_state *state, struct triple *def)
8232 {
8233         struct triple *val;
8234         lvalue(state, def);
8235         val = read_expr(state, def);
8236         return triple(state, OP_VAL, def->type,
8237                 write_expr(state, def,
8238                         mk_add_expr(state, val, int_const(state, &int_type, 1)))
8239                 , val);
8240 }
8241
8242 static struct triple *mk_post_dec_expr(
8243         struct compile_state *state, struct triple *def)
8244 {
8245         struct triple *val;
8246         lvalue(state, def);
8247         val = read_expr(state, def);
8248         return triple(state, OP_VAL, def->type, 
8249                 write_expr(state, def,
8250                         mk_sub_expr(state, val, int_const(state, &int_type, 1)))
8251                 , val);
8252 }
8253
8254 static struct triple *mk_subscript_expr(
8255         struct compile_state *state, struct triple *left, struct triple *right)
8256 {
8257         left  = read_expr(state, left);
8258         right = read_expr(state, right);
8259         if (!is_pointer(left) && !is_pointer(right)) {
8260                 error(state, left, "subscripted value is not a pointer");
8261         }
8262         return mk_deref_expr(state, mk_add_expr(state, left, right));
8263 }
8264
8265
8266 /*
8267  * Compile time evaluation
8268  * ===========================
8269  */
8270 static int is_const(struct triple *ins)
8271 {
8272         return IS_CONST_OP(ins->op);
8273 }
8274
8275 static int is_simple_const(struct triple *ins)
8276 {
8277         /* Is this a constant that u.cval has the value.
8278          * Or equivalently is this a constant that read_const
8279          * works on.
8280          * So far only OP_INTCONST qualifies.  
8281          */
8282         return (ins->op == OP_INTCONST);
8283 }
8284
8285 static int constants_equal(struct compile_state *state, 
8286         struct triple *left, struct triple *right)
8287 {
8288         int equal;
8289         if ((left->op == OP_UNKNOWNVAL) || (right->op == OP_UNKNOWNVAL)) {
8290                 equal = 0;
8291         }
8292         else if (!is_const(left) || !is_const(right)) {
8293                 equal = 0;
8294         }
8295         else if (left->op != right->op) {
8296                 equal = 0;
8297         }
8298         else if (!equiv_types(left->type, right->type)) {
8299                 equal = 0;
8300         }
8301         else {
8302                 equal = 0;
8303                 switch(left->op) {
8304                 case OP_INTCONST:
8305                         if (left->u.cval == right->u.cval) {
8306                                 equal = 1;
8307                         }
8308                         break;
8309                 case OP_BLOBCONST:
8310                 {
8311                         size_t lsize, rsize, bytes;
8312                         lsize = size_of(state, left->type);
8313                         rsize = size_of(state, right->type);
8314                         if (lsize != rsize) {
8315                                 break;
8316                         }
8317                         bytes = bits_to_bytes(lsize);
8318                         if (memcmp(left->u.blob, right->u.blob, bytes) == 0) {
8319                                 equal = 1;
8320                         }
8321                         break;
8322                 }
8323                 case OP_ADDRCONST:
8324                         if ((MISC(left, 0) == MISC(right, 0)) &&
8325                                 (left->u.cval == right->u.cval)) {
8326                                 equal = 1;
8327                         }
8328                         break;
8329                 default:
8330                         internal_error(state, left, "uknown constant type");
8331                         break;
8332                 }
8333         }
8334         return equal;
8335 }
8336
8337 static int is_zero(struct triple *ins)
8338 {
8339         return is_simple_const(ins) && (ins->u.cval == 0);
8340 }
8341
8342 static int is_one(struct triple *ins)
8343 {
8344         return is_simple_const(ins) && (ins->u.cval == 1);
8345 }
8346
8347 static long_t bit_count(ulong_t value)
8348 {
8349         int count;
8350         int i;
8351         count = 0;
8352         for(i = (sizeof(ulong_t)*8) -1; i >= 0; i--) {
8353                 ulong_t mask;
8354                 mask = 1;
8355                 mask <<= i;
8356                 if (value & mask) {
8357                         count++;
8358                 }
8359         }
8360         return count;
8361         
8362 }
8363 static long_t bsr(ulong_t value)
8364 {
8365         int i;
8366         for(i = (sizeof(ulong_t)*8) -1; i >= 0; i--) {
8367                 ulong_t mask;
8368                 mask = 1;
8369                 mask <<= i;
8370                 if (value & mask) {
8371                         return i;
8372                 }
8373         }
8374         return -1;
8375 }
8376
8377 static long_t bsf(ulong_t value)
8378 {
8379         int i;
8380         for(i = 0; i < (sizeof(ulong_t)*8); i++) {
8381                 ulong_t mask;
8382                 mask = 1;
8383                 mask <<= 1;
8384                 if (value & mask) {
8385                         return i;
8386                 }
8387         }
8388         return -1;
8389 }
8390
8391 static long_t ilog2(ulong_t value)
8392 {
8393         return bsr(value);
8394 }
8395
8396 static long_t tlog2(struct triple *ins)
8397 {
8398         return ilog2(ins->u.cval);
8399 }
8400
8401 static int is_pow2(struct triple *ins)
8402 {
8403         ulong_t value, mask;
8404         long_t log;
8405         if (!is_const(ins)) {
8406                 return 0;
8407         }
8408         value = ins->u.cval;
8409         log = ilog2(value);
8410         if (log == -1) {
8411                 return 0;
8412         }
8413         mask = 1;
8414         mask <<= log;
8415         return  ((value & mask) == value);
8416 }
8417
8418 static ulong_t read_const(struct compile_state *state,
8419         struct triple *ins, struct triple *rhs)
8420 {
8421         switch(rhs->type->type &TYPE_MASK) {
8422         case TYPE_CHAR:   
8423         case TYPE_SHORT:
8424         case TYPE_INT:
8425         case TYPE_LONG:
8426         case TYPE_UCHAR:   
8427         case TYPE_USHORT:  
8428         case TYPE_UINT:
8429         case TYPE_ULONG:
8430         case TYPE_POINTER:
8431         case TYPE_BITFIELD:
8432                 break;
8433         default:
8434                 fprintf(state->errout, "type: ");
8435                 name_of(state->errout, rhs->type);
8436                 fprintf(state->errout, "\n");
8437                 internal_warning(state, rhs, "bad type to read_const");
8438                 break;
8439         }
8440         if (!is_simple_const(rhs)) {
8441                 internal_error(state, rhs, "bad op to read_const");
8442         }
8443         return rhs->u.cval;
8444 }
8445
8446 static long_t read_sconst(struct compile_state *state,
8447         struct triple *ins, struct triple *rhs)
8448 {
8449         return (long_t)(rhs->u.cval);
8450 }
8451
8452 int const_ltrue(struct compile_state *state, struct triple *ins, struct triple *rhs)
8453 {
8454         if (!is_const(rhs)) {
8455                 internal_error(state, 0, "non const passed to const_true");
8456         }
8457         return !is_zero(rhs);
8458 }
8459
8460 int const_eq(struct compile_state *state, struct triple *ins,
8461         struct triple *left, struct triple *right)
8462 {
8463         int result;
8464         if (!is_const(left) || !is_const(right)) {
8465                 internal_warning(state, ins, "non const passed to const_eq");
8466                 result = -1;
8467         }
8468         else if (left == right) {
8469                 result = 1;
8470         }
8471         else if (is_simple_const(left) && is_simple_const(right)) {
8472                 ulong_t lval, rval;
8473                 lval = read_const(state, ins, left);
8474                 rval = read_const(state, ins, right);
8475                 result = (lval == rval);
8476         }
8477         else if ((left->op == OP_ADDRCONST) && 
8478                 (right->op == OP_ADDRCONST)) {
8479                 result = (MISC(left, 0) == MISC(right, 0)) &&
8480                         (left->u.cval == right->u.cval);
8481         }
8482         else {
8483                 internal_warning(state, ins, "incomparable constants passed to const_eq");
8484                 result = -1;
8485         }
8486         return result;
8487         
8488 }
8489
8490 int const_ucmp(struct compile_state *state, struct triple *ins,
8491         struct triple *left, struct triple *right)
8492 {
8493         int result;
8494         if (!is_const(left) || !is_const(right)) {
8495                 internal_warning(state, ins, "non const past to const_ucmp");
8496                 result = -2;
8497         }
8498         else if (left == right) {
8499                 result = 0;
8500         }
8501         else if (is_simple_const(left) && is_simple_const(right)) {
8502                 ulong_t lval, rval;
8503                 lval = read_const(state, ins, left);
8504                 rval = read_const(state, ins, right);
8505                 result = 0;
8506                 if (lval > rval) {
8507                         result = 1;
8508                 } else if (rval > lval) {
8509                         result = -1;
8510                 }
8511         }
8512         else if ((left->op == OP_ADDRCONST) && 
8513                 (right->op == OP_ADDRCONST) &&
8514                 (MISC(left, 0) == MISC(right, 0))) {
8515                 result = 0;
8516                 if (left->u.cval > right->u.cval) {
8517                         result = 1;
8518                 } else if (left->u.cval < right->u.cval) {
8519                         result = -1;
8520                 }
8521         }
8522         else {
8523                 internal_warning(state, ins, "incomparable constants passed to const_ucmp");
8524                 result = -2;
8525         }
8526         return result;
8527 }
8528
8529 int const_scmp(struct compile_state *state, struct triple *ins,
8530         struct triple *left, struct triple *right)
8531 {
8532         int result;
8533         if (!is_const(left) || !is_const(right)) {
8534                 internal_warning(state, ins, "non const past to ucmp_const");
8535                 result = -2;
8536         }
8537         else if (left == right) {
8538                 result = 0;
8539         }
8540         else if (is_simple_const(left) && is_simple_const(right)) {
8541                 long_t lval, rval;
8542                 lval = read_sconst(state, ins, left);
8543                 rval = read_sconst(state, ins, right);
8544                 result = 0;
8545                 if (lval > rval) {
8546                         result = 1;
8547                 } else if (rval > lval) {
8548                         result = -1;
8549                 }
8550         }
8551         else {
8552                 internal_warning(state, ins, "incomparable constants passed to const_scmp");
8553                 result = -2;
8554         }
8555         return result;
8556 }
8557
8558 static void unuse_rhs(struct compile_state *state, struct triple *ins)
8559 {
8560         struct triple **expr;
8561         expr = triple_rhs(state, ins, 0);
8562         for(;expr;expr = triple_rhs(state, ins, expr)) {
8563                 if (*expr) {
8564                         unuse_triple(*expr, ins);
8565                         *expr = 0;
8566                 }
8567         }
8568 }
8569
8570 static void unuse_lhs(struct compile_state *state, struct triple *ins)
8571 {
8572         struct triple **expr;
8573         expr = triple_lhs(state, ins, 0);
8574         for(;expr;expr = triple_lhs(state, ins, expr)) {
8575                 unuse_triple(*expr, ins);
8576                 *expr = 0;
8577         }
8578 }
8579
8580 static void unuse_misc(struct compile_state *state, struct triple *ins)
8581 {
8582         struct triple **expr;
8583         expr = triple_misc(state, ins, 0);
8584         for(;expr;expr = triple_misc(state, ins, expr)) {
8585                 unuse_triple(*expr, ins);
8586                 *expr = 0;
8587         }
8588 }
8589
8590 static void unuse_targ(struct compile_state *state, struct triple *ins)
8591 {
8592         int i;
8593         struct triple **slot;
8594         slot = &TARG(ins, 0);
8595         for(i = 0; i < ins->targ; i++) {
8596                 unuse_triple(slot[i], ins);
8597                 slot[i] = 0;
8598         }
8599 }
8600
8601 static void check_lhs(struct compile_state *state, struct triple *ins)
8602 {
8603         struct triple **expr;
8604         expr = triple_lhs(state, ins, 0);
8605         for(;expr;expr = triple_lhs(state, ins, expr)) {
8606                 internal_error(state, ins, "unexpected lhs");
8607         }
8608         
8609 }
8610
8611 static void check_misc(struct compile_state *state, struct triple *ins)
8612 {
8613         struct triple **expr;
8614         expr = triple_misc(state, ins, 0);
8615         for(;expr;expr = triple_misc(state, ins, expr)) {
8616                 if (*expr) {
8617                         internal_error(state, ins, "unexpected misc");
8618                 }
8619         }
8620 }
8621
8622 static void check_targ(struct compile_state *state, struct triple *ins)
8623 {
8624         struct triple **expr;
8625         expr = triple_targ(state, ins, 0);
8626         for(;expr;expr = triple_targ(state, ins, expr)) {
8627                 internal_error(state, ins, "unexpected targ");
8628         }
8629 }
8630
8631 static void wipe_ins(struct compile_state *state, struct triple *ins)
8632 {
8633         /* Becareful which instructions you replace the wiped
8634          * instruction with, as there are not enough slots
8635          * in all instructions to hold all others.
8636          */
8637         check_targ(state, ins);
8638         check_misc(state, ins);
8639         unuse_rhs(state, ins);
8640         unuse_lhs(state, ins);
8641         ins->lhs  = 0;
8642         ins->rhs  = 0;
8643         ins->misc = 0;
8644         ins->targ = 0;
8645 }
8646
8647 static void wipe_branch(struct compile_state *state, struct triple *ins)
8648 {
8649         /* Becareful which instructions you replace the wiped
8650          * instruction with, as there are not enough slots
8651          * in all instructions to hold all others.
8652          */
8653         unuse_rhs(state, ins);
8654         unuse_lhs(state, ins);
8655         unuse_misc(state, ins);
8656         unuse_targ(state, ins);
8657         ins->lhs  = 0;
8658         ins->rhs  = 0;
8659         ins->misc = 0;
8660         ins->targ = 0;
8661 }
8662
8663 static void mkcopy(struct compile_state *state, 
8664         struct triple *ins, struct triple *rhs)
8665 {
8666         struct block *block;
8667         if (!equiv_types(ins->type, rhs->type)) {
8668                 FILE *fp = state->errout;
8669                 fprintf(fp, "src type: ");
8670                 name_of(fp, rhs->type);
8671                 fprintf(fp, "\ndst type: ");
8672                 name_of(fp, ins->type);
8673                 fprintf(fp, "\n");
8674                 internal_error(state, ins, "mkcopy type mismatch");
8675         }
8676         block = block_of_triple(state, ins);
8677         wipe_ins(state, ins);
8678         ins->op = OP_COPY;
8679         ins->rhs  = 1;
8680         ins->u.block = block;
8681         RHS(ins, 0) = rhs;
8682         use_triple(RHS(ins, 0), ins);
8683 }
8684
8685 static void mkconst(struct compile_state *state, 
8686         struct triple *ins, ulong_t value)
8687 {
8688         if (!is_integral(ins) && !is_pointer(ins)) {
8689                 fprintf(state->errout, "type: ");
8690                 name_of(state->errout, ins->type);
8691                 fprintf(state->errout, "\n");
8692                 internal_error(state, ins, "unknown type to make constant value: %ld",
8693                         value);
8694         }
8695         wipe_ins(state, ins);
8696         ins->op = OP_INTCONST;
8697         ins->u.cval = value;
8698 }
8699
8700 static void mkaddr_const(struct compile_state *state,
8701         struct triple *ins, struct triple *sdecl, ulong_t value)
8702 {
8703         if ((sdecl->op != OP_SDECL) && (sdecl->op != OP_LABEL)) {
8704                 internal_error(state, ins, "bad base for addrconst");
8705         }
8706         wipe_ins(state, ins);
8707         ins->op = OP_ADDRCONST;
8708         ins->misc = 1;
8709         MISC(ins, 0) = sdecl;
8710         ins->u.cval = value;
8711         use_triple(sdecl, ins);
8712 }
8713
8714 #if DEBUG_DECOMPOSE_PRINT_TUPLES
8715 static void print_tuple(struct compile_state *state, 
8716         struct triple *ins, struct triple *tuple)
8717 {
8718         FILE *fp = state->dbgout;
8719         fprintf(fp, "%5s %p tuple: %p ", tops(ins->op), ins, tuple);
8720         name_of(fp, tuple->type);
8721         if (tuple->lhs > 0) {
8722                 fprintf(fp, " lhs: ");
8723                 name_of(fp, LHS(tuple, 0)->type);
8724         }
8725         fprintf(fp, "\n");
8726         
8727 }
8728 #endif
8729
8730 static struct triple *decompose_with_tuple(struct compile_state *state, 
8731         struct triple *ins, struct triple *tuple)
8732 {
8733         struct triple *next;
8734         next = ins->next;
8735         flatten(state, next, tuple);
8736 #if DEBUG_DECOMPOSE_PRINT_TUPLES
8737         print_tuple(state, ins, tuple);
8738 #endif
8739
8740         if (!is_compound_type(tuple->type) && (tuple->lhs > 0)) {
8741                 struct triple *tmp;
8742                 if (tuple->lhs != 1) {
8743                         internal_error(state, tuple, "plain type in multiple registers?");
8744                 }
8745                 tmp = LHS(tuple, 0);
8746                 release_triple(state, tuple);
8747                 tuple = tmp;
8748         }
8749
8750         propogate_use(state, ins, tuple);
8751         release_triple(state, ins);
8752         
8753         return next;
8754 }
8755
8756 static struct triple *decompose_unknownval(struct compile_state *state,
8757         struct triple *ins)
8758 {
8759         struct triple *tuple;
8760         ulong_t i;
8761
8762 #if DEBUG_DECOMPOSE_HIRES
8763         FILE *fp = state->dbgout;
8764         fprintf(fp, "unknown type: ");
8765         name_of(fp, ins->type);
8766         fprintf(fp, "\n");
8767 #endif
8768
8769         get_occurance(ins->occurance);
8770         tuple = alloc_triple(state, OP_TUPLE, ins->type, -1, -1, 
8771                 ins->occurance);
8772
8773         for(i = 0; i < tuple->lhs; i++) {
8774                 struct type *piece_type;
8775                 struct triple *unknown;
8776
8777                 piece_type = reg_type(state, ins->type, i * REG_SIZEOF_REG);
8778                 get_occurance(tuple->occurance);
8779                 unknown = alloc_triple(state, OP_UNKNOWNVAL, piece_type, 0, 0,
8780                         tuple->occurance);
8781                 LHS(tuple, i) = unknown;
8782         }
8783         return decompose_with_tuple(state, ins, tuple);
8784 }
8785
8786
8787 static struct triple *decompose_read(struct compile_state *state, 
8788         struct triple *ins)
8789 {
8790         struct triple *tuple, *lval;
8791         ulong_t i;
8792
8793         lval = RHS(ins, 0);
8794
8795         if (lval->op == OP_PIECE) {
8796                 return ins->next;
8797         }
8798         get_occurance(ins->occurance);
8799         tuple = alloc_triple(state, OP_TUPLE, lval->type, -1, -1,
8800                 ins->occurance);
8801
8802         if ((tuple->lhs != lval->lhs) &&
8803                 (!triple_is_def(state, lval) || (tuple->lhs != 1))) 
8804         {
8805                 internal_error(state, ins, "lhs size inconsistency?");
8806         }
8807         for(i = 0; i < tuple->lhs; i++) {
8808                 struct triple *piece, *read, *bitref;
8809                 if ((i != 0) || !triple_is_def(state, lval)) {
8810                         piece = LHS(lval, i);
8811                 } else {
8812                         piece = lval;
8813                 }
8814
8815                 /* See if the piece is really a bitref */
8816                 bitref = 0;
8817                 if (piece->op == OP_BITREF) {
8818                         bitref = piece;
8819                         piece = RHS(bitref, 0);
8820                 }
8821
8822                 get_occurance(tuple->occurance);
8823                 read = alloc_triple(state, OP_READ, piece->type, -1, -1, 
8824                         tuple->occurance);
8825                 RHS(read, 0) = piece;
8826
8827                 if (bitref) {
8828                         struct triple *extract;
8829                         int op;
8830                         if (is_signed(bitref->type->left)) {
8831                                 op = OP_SEXTRACT;
8832                         } else {
8833                                 op = OP_UEXTRACT;
8834                         }
8835                         get_occurance(tuple->occurance);
8836                         extract = alloc_triple(state, op, bitref->type, -1, -1,
8837                                 tuple->occurance);
8838                         RHS(extract, 0) = read;
8839                         extract->u.bitfield.size   = bitref->u.bitfield.size;
8840                         extract->u.bitfield.offset = bitref->u.bitfield.offset;
8841
8842                         read = extract;
8843                 }
8844
8845                 LHS(tuple, i) = read;
8846         }
8847         return decompose_with_tuple(state, ins, tuple);
8848 }
8849
8850 static struct triple *decompose_write(struct compile_state *state, 
8851         struct triple *ins)
8852 {
8853         struct triple *tuple, *lval, *val;
8854         ulong_t i;
8855         
8856         lval = MISC(ins, 0);
8857         val = RHS(ins, 0);
8858         get_occurance(ins->occurance);
8859         tuple = alloc_triple(state, OP_TUPLE, ins->type, -1, -1,
8860                 ins->occurance);
8861
8862         if ((tuple->lhs != lval->lhs) &&
8863                 (!triple_is_def(state, lval) || tuple->lhs != 1)) 
8864         {
8865                 internal_error(state, ins, "lhs size inconsistency?");
8866         }
8867         for(i = 0; i < tuple->lhs; i++) {
8868                 struct triple *piece, *write, *pval, *bitref;
8869                 if ((i != 0) || !triple_is_def(state, lval)) {
8870                         piece = LHS(lval, i);
8871                 } else {
8872                         piece = lval;
8873                 }
8874                 if ((i == 0) && (tuple->lhs == 1) && (val->lhs == 0)) {
8875                         pval = val;
8876                 }
8877                 else {
8878                         if (i > val->lhs) {
8879                                 internal_error(state, ins, "lhs size inconsistency?");
8880                         }
8881                         pval = LHS(val, i);
8882                 }
8883                 
8884                 /* See if the piece is really a bitref */
8885                 bitref = 0;
8886                 if (piece->op == OP_BITREF) {
8887                         struct triple *read, *deposit;
8888                         bitref = piece;
8889                         piece = RHS(bitref, 0);
8890
8891                         /* Read the destination register */
8892                         get_occurance(tuple->occurance);
8893                         read = alloc_triple(state, OP_READ, piece->type, -1, -1,
8894                                 tuple->occurance);
8895                         RHS(read, 0) = piece;
8896
8897                         /* Deposit the new bitfield value */
8898                         get_occurance(tuple->occurance);
8899                         deposit = alloc_triple(state, OP_DEPOSIT, piece->type, -1, -1,
8900                                 tuple->occurance);
8901                         RHS(deposit, 0) = read;
8902                         RHS(deposit, 1) = pval;
8903                         deposit->u.bitfield.size   = bitref->u.bitfield.size;
8904                         deposit->u.bitfield.offset = bitref->u.bitfield.offset;
8905
8906                         /* Now write the newly generated value */
8907                         pval = deposit;
8908                 }
8909
8910                 get_occurance(tuple->occurance);
8911                 write = alloc_triple(state, OP_WRITE, piece->type, -1, -1, 
8912                         tuple->occurance);
8913                 MISC(write, 0) = piece;
8914                 RHS(write, 0) = pval;
8915                 LHS(tuple, i) = write;
8916         }
8917         return decompose_with_tuple(state, ins, tuple);
8918 }
8919
8920 struct decompose_load_info {
8921         struct occurance *occurance;
8922         struct triple *lval;
8923         struct triple *tuple;
8924 };
8925 static void decompose_load_cb(struct compile_state *state,
8926         struct type *type, size_t reg_offset, size_t mem_offset, void *arg)
8927 {
8928         struct decompose_load_info *info = arg;
8929         struct triple *load;
8930         
8931         if (reg_offset > info->tuple->lhs) {
8932                 internal_error(state, info->tuple, "lhs to small?");
8933         }
8934         get_occurance(info->occurance);
8935         load = alloc_triple(state, OP_LOAD, type, -1, -1, info->occurance);
8936         RHS(load, 0) = mk_addr_expr(state, info->lval, mem_offset);
8937         LHS(info->tuple, reg_offset/REG_SIZEOF_REG) = load;
8938 }
8939
8940 static struct triple *decompose_load(struct compile_state *state, 
8941         struct triple *ins)
8942 {
8943         struct triple *tuple;
8944         struct decompose_load_info info;
8945
8946         if (!is_compound_type(ins->type)) {
8947                 return ins->next;
8948         }
8949         get_occurance(ins->occurance);
8950         tuple = alloc_triple(state, OP_TUPLE, ins->type, -1, -1,
8951                 ins->occurance);
8952
8953         info.occurance = ins->occurance;
8954         info.lval      = RHS(ins, 0);
8955         info.tuple     = tuple;
8956         walk_type_fields(state, ins->type, 0, 0, decompose_load_cb, &info);
8957
8958         return decompose_with_tuple(state, ins, tuple);
8959 }
8960
8961
8962 struct decompose_store_info {
8963         struct occurance *occurance;
8964         struct triple *lval;
8965         struct triple *val;
8966         struct triple *tuple;
8967 };
8968 static void decompose_store_cb(struct compile_state *state,
8969         struct type *type, size_t reg_offset, size_t mem_offset, void *arg)
8970 {
8971         struct decompose_store_info *info = arg;
8972         struct triple *store;
8973         
8974         if (reg_offset > info->tuple->lhs) {
8975                 internal_error(state, info->tuple, "lhs to small?");
8976         }
8977         get_occurance(info->occurance);
8978         store = alloc_triple(state, OP_STORE, type, -1, -1, info->occurance);
8979         RHS(store, 0) = mk_addr_expr(state, info->lval, mem_offset);
8980         RHS(store, 1) = LHS(info->val, reg_offset);
8981         LHS(info->tuple, reg_offset/REG_SIZEOF_REG) = store;
8982 }
8983
8984 static struct triple *decompose_store(struct compile_state *state, 
8985         struct triple *ins)
8986 {
8987         struct triple *tuple;
8988         struct decompose_store_info info;
8989
8990         if (!is_compound_type(ins->type)) {
8991                 return ins->next;
8992         }
8993         get_occurance(ins->occurance);
8994         tuple = alloc_triple(state, OP_TUPLE, ins->type, -1, -1,
8995                 ins->occurance);
8996
8997         info.occurance = ins->occurance;
8998         info.lval      = RHS(ins, 0);
8999         info.val       = RHS(ins, 1);
9000         info.tuple     = tuple;
9001         walk_type_fields(state, ins->type, 0, 0, decompose_store_cb, &info);
9002
9003         return decompose_with_tuple(state, ins, tuple);
9004 }
9005
9006 static struct triple *decompose_dot(struct compile_state *state, 
9007         struct triple *ins)
9008 {
9009         struct triple *tuple, *lval;
9010         struct type *type;
9011         size_t reg_offset;
9012         int i, idx;
9013
9014         lval = MISC(ins, 0);
9015         reg_offset = field_reg_offset(state, lval->type, ins->u.field);
9016         idx  = reg_offset/REG_SIZEOF_REG;
9017         type = field_type(state, lval->type, ins->u.field);
9018 #if DEBUG_DECOMPOSE_HIRES
9019         {
9020                 FILE *fp = state->dbgout;
9021                 fprintf(fp, "field type: ");
9022                 name_of(fp, type);
9023                 fprintf(fp, "\n");
9024         }
9025 #endif
9026
9027         get_occurance(ins->occurance);
9028         tuple = alloc_triple(state, OP_TUPLE, type, -1, -1, 
9029                 ins->occurance);
9030
9031         if (((ins->type->type & TYPE_MASK) == TYPE_BITFIELD) &&
9032                 (tuple->lhs != 1))
9033         {
9034                 internal_error(state, ins, "multi register bitfield?");
9035         }
9036
9037         for(i = 0; i < tuple->lhs; i++, idx++) {
9038                 struct triple *piece;
9039                 if (!triple_is_def(state, lval)) {
9040                         if (idx > lval->lhs) {
9041                                 internal_error(state, ins, "inconsistent lhs count");
9042                         }
9043                         piece = LHS(lval, idx);
9044                 } else {
9045                         if (idx != 0) {
9046                                 internal_error(state, ins, "bad reg_offset into def");
9047                         }
9048                         if (i != 0) {
9049                                 internal_error(state, ins, "bad reg count from def");
9050                         }
9051                         piece = lval;
9052                 }
9053
9054                 /* Remember the offset of the bitfield */
9055                 if ((type->type & TYPE_MASK) == TYPE_BITFIELD) {
9056                         get_occurance(ins->occurance);
9057                         piece = build_triple(state, OP_BITREF, type, piece, 0,
9058                                 ins->occurance);
9059                         piece->u.bitfield.size   = size_of(state, type);
9060                         piece->u.bitfield.offset = reg_offset % REG_SIZEOF_REG;
9061                 }
9062                 else if ((reg_offset % REG_SIZEOF_REG) != 0) {
9063                         internal_error(state, ins, 
9064                                 "request for a nonbitfield sub register?");
9065                 }
9066
9067                 LHS(tuple, i) = piece;
9068         }
9069
9070         return decompose_with_tuple(state, ins, tuple);
9071 }
9072
9073 static struct triple *decompose_index(struct compile_state *state, 
9074         struct triple *ins)
9075 {
9076         struct triple *tuple, *lval;
9077         struct type *type;
9078         int i, idx;
9079
9080         lval = MISC(ins, 0);
9081         idx = index_reg_offset(state, lval->type, ins->u.cval)/REG_SIZEOF_REG;
9082         type = index_type(state, lval->type, ins->u.cval);
9083 #if DEBUG_DECOMPOSE_HIRES
9084 {
9085         FILE *fp = state->dbgout;
9086         fprintf(fp, "index type: ");
9087         name_of(fp, type);
9088         fprintf(fp, "\n");
9089 }
9090 #endif
9091
9092         get_occurance(ins->occurance);
9093         tuple = alloc_triple(state, OP_TUPLE, type, -1, -1, 
9094                 ins->occurance);
9095
9096         for(i = 0; i < tuple->lhs; i++, idx++) {
9097                 struct triple *piece;
9098                 if (!triple_is_def(state, lval)) {
9099                         if (idx > lval->lhs) {
9100                                 internal_error(state, ins, "inconsistent lhs count");
9101                         }
9102                         piece = LHS(lval, idx);
9103                 } else {
9104                         if (idx != 0) {
9105                                 internal_error(state, ins, "bad reg_offset into def");
9106                         }
9107                         if (i != 0) {
9108                                 internal_error(state, ins, "bad reg count from def");
9109                         }
9110                         piece = lval;
9111                 }
9112                 LHS(tuple, i) = piece;
9113         }
9114
9115         return decompose_with_tuple(state, ins, tuple);
9116 }
9117
9118 static void decompose_compound_types(struct compile_state *state)
9119 {
9120         struct triple *ins, *next, *first;
9121         FILE *fp;
9122         fp = state->dbgout;
9123         first = state->first;
9124         ins = first;
9125
9126         /* Pass one expand compound values into pseudo registers.
9127          */
9128         next = first;
9129         do {
9130                 ins = next;
9131                 next = ins->next;
9132                 switch(ins->op) {
9133                 case OP_UNKNOWNVAL:
9134                         next = decompose_unknownval(state, ins);
9135                         break;
9136
9137                 case OP_READ:
9138                         next = decompose_read(state, ins);
9139                         break;
9140
9141                 case OP_WRITE:
9142                         next = decompose_write(state, ins);
9143                         break;
9144
9145
9146                 /* Be very careful with the load/store logic. These
9147                  * operations must convert from the in register layout
9148                  * to the in memory layout, which is nontrivial.
9149                  */
9150                 case OP_LOAD:
9151                         next = decompose_load(state, ins);
9152                         break;
9153                 case OP_STORE:
9154                         next = decompose_store(state, ins);
9155                         break;
9156
9157                 case OP_DOT:
9158                         next = decompose_dot(state, ins);
9159                         break;
9160                 case OP_INDEX:
9161                         next = decompose_index(state, ins);
9162                         break;
9163                         
9164                 }
9165 #if DEBUG_DECOMPOSE_HIRES
9166                 fprintf(fp, "decompose next: %p \n", next);
9167                 fflush(fp);
9168                 fprintf(fp, "next->op: %d %s\n",
9169                         next->op, tops(next->op));
9170                 /* High resolution debugging mode */
9171                 print_triples(state);
9172 #endif
9173         } while (next != first);
9174
9175         /* Pass two remove the tuples.
9176          */
9177         ins = first;
9178         do {
9179                 next = ins->next;
9180                 if (ins->op == OP_TUPLE) {
9181                         if (ins->use) {
9182                                 internal_error(state, ins, "tuple used");
9183                         }
9184                         else {
9185                                 release_triple(state, ins);
9186                         }
9187                 } 
9188                 ins = next;
9189         } while(ins != first);
9190         ins = first;
9191         do {
9192                 next = ins->next;
9193                 if (ins->op == OP_BITREF) {
9194                         if (ins->use) {
9195                                 internal_error(state, ins, "bitref used");
9196                         } 
9197                         else {
9198                                 release_triple(state, ins);
9199                         }
9200                 }
9201                 ins = next;
9202         } while(ins != first);
9203
9204         /* Pass three verify the state and set ->id to 0.
9205          */
9206         next = first;
9207         do {
9208                 ins = next;
9209                 next = ins->next;
9210                 ins->id &= ~TRIPLE_FLAG_FLATTENED;
9211                 if (triple_stores_block(state, ins)) {
9212                         ins->u.block = 0;
9213                 }
9214                 if (triple_is_def(state, ins)) {
9215                         if (reg_size_of(state, ins->type) > REG_SIZEOF_REG) {
9216                                 internal_error(state, ins, "multi register value remains?");
9217                         }
9218                 }
9219                 if (ins->op == OP_DOT) {
9220                         internal_error(state, ins, "OP_DOT remains?");
9221                 }
9222                 if (ins->op == OP_INDEX) {
9223                         internal_error(state, ins, "OP_INDEX remains?");
9224                 }
9225                 if (ins->op == OP_BITREF) {
9226                         internal_error(state, ins, "OP_BITREF remains?");
9227                 }
9228                 if (ins->op == OP_TUPLE) {
9229                         internal_error(state, ins, "OP_TUPLE remains?");
9230                 }
9231         } while(next != first);
9232 }
9233
9234 /* For those operations that cannot be simplified */
9235 static void simplify_noop(struct compile_state *state, struct triple *ins)
9236 {
9237         return;
9238 }
9239
9240 static void simplify_smul(struct compile_state *state, struct triple *ins)
9241 {
9242         if (is_const(RHS(ins, 0)) && !is_const(RHS(ins, 1))) {
9243                 struct triple *tmp;
9244                 tmp = RHS(ins, 0);
9245                 RHS(ins, 0) = RHS(ins, 1);
9246                 RHS(ins, 1) = tmp;
9247         }
9248         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
9249                 long_t left, right;
9250                 left  = read_sconst(state, ins, RHS(ins, 0));
9251                 right = read_sconst(state, ins, RHS(ins, 1));
9252                 mkconst(state, ins, left * right);
9253         }
9254         else if (is_zero(RHS(ins, 1))) {
9255                 mkconst(state, ins, 0);
9256         }
9257         else if (is_one(RHS(ins, 1))) {
9258                 mkcopy(state, ins, RHS(ins, 0));
9259         }
9260         else if (is_pow2(RHS(ins, 1))) {
9261                 struct triple *val;
9262                 val = int_const(state, ins->type, tlog2(RHS(ins, 1)));
9263                 ins->op = OP_SL;
9264                 insert_triple(state, state->global_pool, val);
9265                 unuse_triple(RHS(ins, 1), ins);
9266                 use_triple(val, ins);
9267                 RHS(ins, 1) = val;
9268         }
9269 }
9270
9271 static void simplify_umul(struct compile_state *state, struct triple *ins)
9272 {
9273         if (is_const(RHS(ins, 0)) && !is_const(RHS(ins, 1))) {
9274                 struct triple *tmp;
9275                 tmp = RHS(ins, 0);
9276                 RHS(ins, 0) = RHS(ins, 1);
9277                 RHS(ins, 1) = tmp;
9278         }
9279         if (is_simple_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9280                 ulong_t left, right;
9281                 left  = read_const(state, ins, RHS(ins, 0));
9282                 right = read_const(state, ins, RHS(ins, 1));
9283                 mkconst(state, ins, left * right);
9284         }
9285         else if (is_zero(RHS(ins, 1))) {
9286                 mkconst(state, ins, 0);
9287         }
9288         else if (is_one(RHS(ins, 1))) {
9289                 mkcopy(state, ins, RHS(ins, 0));
9290         }
9291         else if (is_pow2(RHS(ins, 1))) {
9292                 struct triple *val;
9293                 val = int_const(state, ins->type, tlog2(RHS(ins, 1)));
9294                 ins->op = OP_SL;
9295                 insert_triple(state, state->global_pool, val);
9296                 unuse_triple(RHS(ins, 1), ins);
9297                 use_triple(val, ins);
9298                 RHS(ins, 1) = val;
9299         }
9300 }
9301
9302 static void simplify_sdiv(struct compile_state *state, struct triple *ins)
9303 {
9304         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
9305                 long_t left, right;
9306                 left  = read_sconst(state, ins, RHS(ins, 0));
9307                 right = read_sconst(state, ins, RHS(ins, 1));
9308                 mkconst(state, ins, left / right);
9309         }
9310         else if (is_zero(RHS(ins, 0))) {
9311                 mkconst(state, ins, 0);
9312         }
9313         else if (is_zero(RHS(ins, 1))) {
9314                 error(state, ins, "division by zero");
9315         }
9316         else if (is_one(RHS(ins, 1))) {
9317                 mkcopy(state, ins, RHS(ins, 0));
9318         }
9319         else if (is_pow2(RHS(ins, 1))) {
9320                 struct triple *val;
9321                 val = int_const(state, ins->type, tlog2(RHS(ins, 1)));
9322                 ins->op = OP_SSR;
9323                 insert_triple(state, state->global_pool, val);
9324                 unuse_triple(RHS(ins, 1), ins);
9325                 use_triple(val, ins);
9326                 RHS(ins, 1) = val;
9327         }
9328 }
9329
9330 static void simplify_udiv(struct compile_state *state, struct triple *ins)
9331 {
9332         if (is_simple_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9333                 ulong_t left, right;
9334                 left  = read_const(state, ins, RHS(ins, 0));
9335                 right = read_const(state, ins, RHS(ins, 1));
9336                 mkconst(state, ins, left / right);
9337         }
9338         else if (is_zero(RHS(ins, 0))) {
9339                 mkconst(state, ins, 0);
9340         }
9341         else if (is_zero(RHS(ins, 1))) {
9342                 error(state, ins, "division by zero");
9343         }
9344         else if (is_one(RHS(ins, 1))) {
9345                 mkcopy(state, ins, RHS(ins, 0));
9346         }
9347         else if (is_pow2(RHS(ins, 1))) {
9348                 struct triple *val;
9349                 val = int_const(state, ins->type, tlog2(RHS(ins, 1)));
9350                 ins->op = OP_USR;
9351                 insert_triple(state, state->global_pool, val);
9352                 unuse_triple(RHS(ins, 1), ins);
9353                 use_triple(val, ins);
9354                 RHS(ins, 1) = val;
9355         }
9356 }
9357
9358 static void simplify_smod(struct compile_state *state, struct triple *ins)
9359 {
9360         if (is_simple_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9361                 long_t left, right;
9362                 left  = read_const(state, ins, RHS(ins, 0));
9363                 right = read_const(state, ins, RHS(ins, 1));
9364                 mkconst(state, ins, left % right);
9365         }
9366         else if (is_zero(RHS(ins, 0))) {
9367                 mkconst(state, ins, 0);
9368         }
9369         else if (is_zero(RHS(ins, 1))) {
9370                 error(state, ins, "division by zero");
9371         }
9372         else if (is_one(RHS(ins, 1))) {
9373                 mkconst(state, ins, 0);
9374         }
9375         else if (is_pow2(RHS(ins, 1))) {
9376                 struct triple *val;
9377                 val = int_const(state, ins->type, RHS(ins, 1)->u.cval - 1);
9378                 ins->op = OP_AND;
9379                 insert_triple(state, state->global_pool, val);
9380                 unuse_triple(RHS(ins, 1), ins);
9381                 use_triple(val, ins);
9382                 RHS(ins, 1) = val;
9383         }
9384 }
9385
9386 static void simplify_umod(struct compile_state *state, struct triple *ins)
9387 {
9388         if (is_simple_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9389                 ulong_t left, right;
9390                 left  = read_const(state, ins, RHS(ins, 0));
9391                 right = read_const(state, ins, RHS(ins, 1));
9392                 mkconst(state, ins, left % right);
9393         }
9394         else if (is_zero(RHS(ins, 0))) {
9395                 mkconst(state, ins, 0);
9396         }
9397         else if (is_zero(RHS(ins, 1))) {
9398                 error(state, ins, "division by zero");
9399         }
9400         else if (is_one(RHS(ins, 1))) {
9401                 mkconst(state, ins, 0);
9402         }
9403         else if (is_pow2(RHS(ins, 1))) {
9404                 struct triple *val;
9405                 val = int_const(state, ins->type, RHS(ins, 1)->u.cval - 1);
9406                 ins->op = OP_AND;
9407                 insert_triple(state, state->global_pool, val);
9408                 unuse_triple(RHS(ins, 1), ins);
9409                 use_triple(val, ins);
9410                 RHS(ins, 1) = val;
9411         }
9412 }
9413
9414 static void simplify_add(struct compile_state *state, struct triple *ins)
9415 {
9416         /* start with the pointer on the left */
9417         if (is_pointer(RHS(ins, 1))) {
9418                 struct triple *tmp;
9419                 tmp = RHS(ins, 0);
9420                 RHS(ins, 0) = RHS(ins, 1);
9421                 RHS(ins, 1) = tmp;
9422         }
9423         if (is_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9424                 if (RHS(ins, 0)->op == OP_INTCONST) {
9425                         ulong_t left, right;
9426                         left  = read_const(state, ins, RHS(ins, 0));
9427                         right = read_const(state, ins, RHS(ins, 1));
9428                         mkconst(state, ins, left + right);
9429                 }
9430                 else if (RHS(ins, 0)->op == OP_ADDRCONST) {
9431                         struct triple *sdecl;
9432                         ulong_t left, right;
9433                         sdecl = MISC(RHS(ins, 0), 0);
9434                         left  = RHS(ins, 0)->u.cval;
9435                         right = RHS(ins, 1)->u.cval;
9436                         mkaddr_const(state, ins, sdecl, left + right);
9437                 }
9438                 else {
9439                         internal_warning(state, ins, "Optimize me!");
9440                 }
9441         }
9442         else if (is_const(RHS(ins, 0)) && !is_const(RHS(ins, 1))) {
9443                 struct triple *tmp;
9444                 tmp = RHS(ins, 1);
9445                 RHS(ins, 1) = RHS(ins, 0);
9446                 RHS(ins, 0) = tmp;
9447         }
9448 }
9449
9450 static void simplify_sub(struct compile_state *state, struct triple *ins)
9451 {
9452         if (is_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9453                 if (RHS(ins, 0)->op == OP_INTCONST) {
9454                         ulong_t left, right;
9455                         left  = read_const(state, ins, RHS(ins, 0));
9456                         right = read_const(state, ins, RHS(ins, 1));
9457                         mkconst(state, ins, left - right);
9458                 }
9459                 else if (RHS(ins, 0)->op == OP_ADDRCONST) {
9460                         struct triple *sdecl;
9461                         ulong_t left, right;
9462                         sdecl = MISC(RHS(ins, 0), 0);
9463                         left  = RHS(ins, 0)->u.cval;
9464                         right = RHS(ins, 1)->u.cval;
9465                         mkaddr_const(state, ins, sdecl, left - right);
9466                 }
9467                 else {
9468                         internal_warning(state, ins, "Optimize me!");
9469                 }
9470         }
9471 }
9472
9473 static void simplify_sl(struct compile_state *state, struct triple *ins)
9474 {
9475         if (is_simple_const(RHS(ins, 1))) {
9476                 ulong_t right;
9477                 right = read_const(state, ins, RHS(ins, 1));
9478                 if (right >= (size_of(state, ins->type))) {
9479                         warning(state, ins, "left shift count >= width of type");
9480                 }
9481         }
9482         if (is_simple_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9483                 ulong_t left, right;
9484                 left  = read_const(state, ins, RHS(ins, 0));
9485                 right = read_const(state, ins, RHS(ins, 1));
9486                 mkconst(state, ins,  left << right);
9487         }
9488 }
9489
9490 static void simplify_usr(struct compile_state *state, struct triple *ins)
9491 {
9492         if (is_simple_const(RHS(ins, 1))) {
9493                 ulong_t right;
9494                 right = read_const(state, ins, RHS(ins, 1));
9495                 if (right >= (size_of(state, ins->type))) {
9496                         warning(state, ins, "right shift count >= width of type");
9497                 }
9498         }
9499         if (is_simple_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9500                 ulong_t left, right;
9501                 left  = read_const(state, ins, RHS(ins, 0));
9502                 right = read_const(state, ins, RHS(ins, 1));
9503                 mkconst(state, ins, left >> right);
9504         }
9505 }
9506
9507 static void simplify_ssr(struct compile_state *state, struct triple *ins)
9508 {
9509         if (is_simple_const(RHS(ins, 1))) {
9510                 ulong_t right;
9511                 right = read_const(state, ins, RHS(ins, 1));
9512                 if (right >= (size_of(state, ins->type))) {
9513                         warning(state, ins, "right shift count >= width of type");
9514                 }
9515         }
9516         if (is_simple_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9517                 long_t left, right;
9518                 left  = read_sconst(state, ins, RHS(ins, 0));
9519                 right = read_sconst(state, ins, RHS(ins, 1));
9520                 mkconst(state, ins, left >> right);
9521         }
9522 }
9523
9524 static void simplify_and(struct compile_state *state, struct triple *ins)
9525 {
9526         struct triple *left, *right;
9527         left = RHS(ins, 0);
9528         right = RHS(ins, 1);
9529
9530         if (is_simple_const(left) && is_simple_const(right)) {
9531                 ulong_t lval, rval;
9532                 lval = read_const(state, ins, left);
9533                 rval = read_const(state, ins, right);
9534                 mkconst(state, ins, lval & rval);
9535         }
9536         else if (is_zero(right) || is_zero(left)) {
9537                 mkconst(state, ins, 0);
9538         }
9539 }
9540
9541 static void simplify_or(struct compile_state *state, struct triple *ins)
9542 {
9543         struct triple *left, *right;
9544         left = RHS(ins, 0);
9545         right = RHS(ins, 1);
9546
9547         if (is_simple_const(left) && is_simple_const(right)) {
9548                 ulong_t lval, rval;
9549                 lval = read_const(state, ins, left);
9550                 rval = read_const(state, ins, right);
9551                 mkconst(state, ins, lval | rval);
9552         }
9553 #if 0 /* I need to handle type mismatches here... */
9554         else if (is_zero(right)) {
9555                 mkcopy(state, ins, left);
9556         }
9557         else if (is_zero(left)) {
9558                 mkcopy(state, ins, right);
9559         }
9560 #endif
9561 }
9562
9563 static void simplify_xor(struct compile_state *state, struct triple *ins)
9564 {
9565         if (is_simple_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9566                 ulong_t left, right;
9567                 left  = read_const(state, ins, RHS(ins, 0));
9568                 right = read_const(state, ins, RHS(ins, 1));
9569                 mkconst(state, ins, left ^ right);
9570         }
9571 }
9572
9573 static void simplify_pos(struct compile_state *state, struct triple *ins)
9574 {
9575         if (is_const(RHS(ins, 0))) {
9576                 mkconst(state, ins, RHS(ins, 0)->u.cval);
9577         }
9578         else {
9579                 mkcopy(state, ins, RHS(ins, 0));
9580         }
9581 }
9582
9583 static void simplify_neg(struct compile_state *state, struct triple *ins)
9584 {
9585         if (is_simple_const(RHS(ins, 0))) {
9586                 ulong_t left;
9587                 left = read_const(state, ins, RHS(ins, 0));
9588                 mkconst(state, ins, -left);
9589         }
9590         else if (RHS(ins, 0)->op == OP_NEG) {
9591                 mkcopy(state, ins, RHS(RHS(ins, 0), 0));
9592         }
9593 }
9594
9595 static void simplify_invert(struct compile_state *state, struct triple *ins)
9596 {
9597         if (is_simple_const(RHS(ins, 0))) {
9598                 ulong_t left;
9599                 left = read_const(state, ins, RHS(ins, 0));
9600                 mkconst(state, ins, ~left);
9601         }
9602 }
9603
9604 static void simplify_eq(struct compile_state *state, struct triple *ins)
9605 {
9606         struct triple *left, *right;
9607         left = RHS(ins, 0);
9608         right = RHS(ins, 1);
9609
9610         if (is_const(left) && is_const(right)) {
9611                 int val;
9612                 val = const_eq(state, ins, left, right);
9613                 if (val >= 0) {
9614                         mkconst(state, ins, val == 1);
9615                 }
9616         }
9617         else if (left == right) {
9618                 mkconst(state, ins, 1);
9619         }
9620 }
9621
9622 static void simplify_noteq(struct compile_state *state, struct triple *ins)
9623 {
9624         struct triple *left, *right;
9625         left = RHS(ins, 0);
9626         right = RHS(ins, 1);
9627
9628         if (is_const(left) && is_const(right)) {
9629                 int val;
9630                 val = const_eq(state, ins, left, right);
9631                 if (val >= 0) {
9632                         mkconst(state, ins, val != 1);
9633                 }
9634         }
9635         if (left == right) {
9636                 mkconst(state, ins, 0);
9637         }
9638 }
9639
9640 static void simplify_sless(struct compile_state *state, struct triple *ins)
9641 {
9642         struct triple *left, *right;
9643         left = RHS(ins, 0);
9644         right = RHS(ins, 1);
9645
9646         if (is_const(left) && is_const(right)) {
9647                 int val;
9648                 val = const_scmp(state, ins, left, right);
9649                 if ((val >= -1) && (val <= 1)) {
9650                         mkconst(state, ins, val < 0);
9651                 }
9652         }
9653         else if (left == right) {
9654                 mkconst(state, ins, 0);
9655         }
9656 }
9657
9658 static void simplify_uless(struct compile_state *state, struct triple *ins)
9659 {
9660         struct triple *left, *right;
9661         left = RHS(ins, 0);
9662         right = RHS(ins, 1);
9663
9664         if (is_const(left) && is_const(right)) {
9665                 int val;
9666                 val = const_ucmp(state, ins, left, right);
9667                 if ((val >= -1) && (val <= 1)) {
9668                         mkconst(state, ins, val < 0);
9669                 }
9670         }
9671         else if (is_zero(right)) {
9672                 mkconst(state, ins, 0);
9673         }
9674         else if (left == right) {
9675                 mkconst(state, ins, 0);
9676         }
9677 }
9678
9679 static void simplify_smore(struct compile_state *state, struct triple *ins)
9680 {
9681         struct triple *left, *right;
9682         left = RHS(ins, 0);
9683         right = RHS(ins, 1);
9684
9685         if (is_const(left) && is_const(right)) {
9686                 int val;
9687                 val = const_scmp(state, ins, left, right);
9688                 if ((val >= -1) && (val <= 1)) {
9689                         mkconst(state, ins, val > 0);
9690                 }
9691         }
9692         else if (left == right) {
9693                 mkconst(state, ins, 0);
9694         }
9695 }
9696
9697 static void simplify_umore(struct compile_state *state, struct triple *ins)
9698 {
9699         struct triple *left, *right;
9700         left = RHS(ins, 0);
9701         right = RHS(ins, 1);
9702
9703         if (is_const(left) && is_const(right)) {
9704                 int val;
9705                 val = const_ucmp(state, ins, left, right);
9706                 if ((val >= -1) && (val <= 1)) {
9707                         mkconst(state, ins, val > 0);
9708                 }
9709         }
9710         else if (is_zero(left)) {
9711                 mkconst(state, ins, 0);
9712         }
9713         else if (left == right) {
9714                 mkconst(state, ins, 0);
9715         }
9716 }
9717
9718
9719 static void simplify_slesseq(struct compile_state *state, struct triple *ins)
9720 {
9721         struct triple *left, *right;
9722         left = RHS(ins, 0);
9723         right = RHS(ins, 1);
9724
9725         if (is_const(left) && is_const(right)) {
9726                 int val;
9727                 val = const_scmp(state, ins, left, right);
9728                 if ((val >= -1) && (val <= 1)) {
9729                         mkconst(state, ins, val <= 0);
9730                 }
9731         }
9732         else if (left == right) {
9733                 mkconst(state, ins, 1);
9734         }
9735 }
9736
9737 static void simplify_ulesseq(struct compile_state *state, struct triple *ins)
9738 {
9739         struct triple *left, *right;
9740         left = RHS(ins, 0);
9741         right = RHS(ins, 1);
9742
9743         if (is_const(left) && is_const(right)) {
9744                 int val;
9745                 val = const_ucmp(state, ins, left, right);
9746                 if ((val >= -1) && (val <= 1)) {
9747                         mkconst(state, ins, val <= 0);
9748                 }
9749         }
9750         else if (is_zero(left)) {
9751                 mkconst(state, ins, 1);
9752         }
9753         else if (left == right) {
9754                 mkconst(state, ins, 1);
9755         }
9756 }
9757
9758 static void simplify_smoreeq(struct compile_state *state, struct triple *ins)
9759 {
9760         struct triple *left, *right;
9761         left = RHS(ins, 0);
9762         right = RHS(ins, 1);
9763
9764         if (is_const(left) && is_const(right)) {
9765                 int val;
9766                 val = const_scmp(state, ins, left, right);
9767                 if ((val >= -1) && (val <= 1)) {
9768                         mkconst(state, ins, val >= 0);
9769                 }
9770         }
9771         else if (left == right) {
9772                 mkconst(state, ins, 1);
9773         }
9774 }
9775
9776 static void simplify_umoreeq(struct compile_state *state, struct triple *ins)
9777 {
9778         struct triple *left, *right;
9779         left = RHS(ins, 0);
9780         right = RHS(ins, 1);
9781
9782         if (is_const(left) && is_const(right)) {
9783                 int val;
9784                 val = const_ucmp(state, ins, left, right);
9785                 if ((val >= -1) && (val <= 1)) {
9786                         mkconst(state, ins, val >= 0);
9787                 }
9788         }
9789         else if (is_zero(right)) {
9790                 mkconst(state, ins, 1);
9791         }
9792         else if (left == right) {
9793                 mkconst(state, ins, 1);
9794         }
9795 }
9796
9797 static void simplify_lfalse(struct compile_state *state, struct triple *ins)
9798 {
9799         struct triple *rhs;
9800         rhs = RHS(ins, 0);
9801
9802         if (is_const(rhs)) {
9803                 mkconst(state, ins, !const_ltrue(state, ins, rhs));
9804         }
9805         /* Otherwise if I am the only user... */
9806         else if ((rhs->use) &&
9807                 (rhs->use->member == ins) && (rhs->use->next == 0)) {
9808                 int need_copy = 1;
9809                 /* Invert a boolean operation */
9810                 switch(rhs->op) {
9811                 case OP_LTRUE:   rhs->op = OP_LFALSE;  break;
9812                 case OP_LFALSE:  rhs->op = OP_LTRUE;   break;
9813                 case OP_EQ:      rhs->op = OP_NOTEQ;   break;
9814                 case OP_NOTEQ:   rhs->op = OP_EQ;      break;
9815                 case OP_SLESS:   rhs->op = OP_SMOREEQ; break;
9816                 case OP_ULESS:   rhs->op = OP_UMOREEQ; break;
9817                 case OP_SMORE:   rhs->op = OP_SLESSEQ; break;
9818                 case OP_UMORE:   rhs->op = OP_ULESSEQ; break;
9819                 case OP_SLESSEQ: rhs->op = OP_SMORE;   break;
9820                 case OP_ULESSEQ: rhs->op = OP_UMORE;   break;
9821                 case OP_SMOREEQ: rhs->op = OP_SLESS;   break;
9822                 case OP_UMOREEQ: rhs->op = OP_ULESS;   break;
9823                 default:
9824                         need_copy = 0;
9825                         break;
9826                 }
9827                 if (need_copy) {
9828                         mkcopy(state, ins, rhs);
9829                 }
9830         }
9831 }
9832
9833 static void simplify_ltrue (struct compile_state *state, struct triple *ins)
9834 {
9835         struct triple *rhs;
9836         rhs = RHS(ins, 0);
9837
9838         if (is_const(rhs)) {
9839                 mkconst(state, ins, const_ltrue(state, ins, rhs));
9840         }
9841         else switch(rhs->op) {
9842         case OP_LTRUE:   case OP_LFALSE:  case OP_EQ:      case OP_NOTEQ:
9843         case OP_SLESS:   case OP_ULESS:   case OP_SMORE:   case OP_UMORE:
9844         case OP_SLESSEQ: case OP_ULESSEQ: case OP_SMOREEQ: case OP_UMOREEQ:
9845                 mkcopy(state, ins, rhs);
9846         }
9847
9848 }
9849
9850 static void simplify_load(struct compile_state *state, struct triple *ins)
9851 {
9852         struct triple *addr, *sdecl, *blob;
9853
9854         /* If I am doing a load with a constant pointer from a constant
9855          * table get the value.
9856          */
9857         addr = RHS(ins, 0);
9858         if ((addr->op == OP_ADDRCONST) && (sdecl = MISC(addr, 0)) &&
9859                 (sdecl->op == OP_SDECL) && (blob = MISC(sdecl, 0)) &&
9860                 (blob->op == OP_BLOBCONST)) {
9861                 unsigned char buffer[SIZEOF_WORD];
9862                 size_t reg_size, mem_size;
9863                 const char *src, *end;
9864                 ulong_t val;
9865                 reg_size = reg_size_of(state, ins->type);
9866                 if (reg_size > REG_SIZEOF_REG) {
9867                         internal_error(state, ins, "load size greater than register");
9868                 }
9869                 mem_size = size_of(state, ins->type);
9870                 end = blob->u.blob;
9871                 end += bits_to_bytes(size_of(state, sdecl->type));
9872                 src = blob->u.blob;
9873                 src += addr->u.cval;
9874
9875                 if (src > end) {
9876                         error(state, ins, "Load address out of bounds");
9877                 }
9878
9879                 memset(buffer, 0, sizeof(buffer));
9880                 memcpy(buffer, src, bits_to_bytes(mem_size));
9881
9882                 switch(mem_size) {
9883                 case SIZEOF_I8:  val = *((uint8_t *) buffer); break;
9884                 case SIZEOF_I16: val = *((uint16_t *)buffer); break;
9885                 case SIZEOF_I32: val = *((uint32_t *)buffer); break;
9886                 case SIZEOF_I64: val = *((uint64_t *)buffer); break;
9887                 default:
9888                         internal_error(state, ins, "mem_size: %d not handled",
9889                                 mem_size);
9890                         val = 0;
9891                         break;
9892                 }
9893                 mkconst(state, ins, val);
9894         }
9895 }
9896
9897 static void simplify_uextract(struct compile_state *state, struct triple *ins)
9898 {
9899         if (is_simple_const(RHS(ins, 0))) {
9900                 ulong_t val;
9901                 ulong_t mask;
9902                 val = read_const(state, ins, RHS(ins, 0));
9903                 mask = 1;
9904                 mask <<= ins->u.bitfield.size;
9905                 mask -= 1;
9906                 val >>= ins->u.bitfield.offset;
9907                 val &= mask;
9908                 mkconst(state, ins, val);
9909         }
9910 }
9911
9912 static void simplify_sextract(struct compile_state *state, struct triple *ins)
9913 {
9914         if (is_simple_const(RHS(ins, 0))) {
9915                 ulong_t val;
9916                 ulong_t mask;
9917                 long_t sval;
9918                 val = read_const(state, ins, RHS(ins, 0));
9919                 mask = 1;
9920                 mask <<= ins->u.bitfield.size;
9921                 mask -= 1;
9922                 val >>= ins->u.bitfield.offset;
9923                 val &= mask;
9924                 val <<= (SIZEOF_LONG - ins->u.bitfield.size);
9925                 sval = val;
9926                 sval >>= (SIZEOF_LONG - ins->u.bitfield.size); 
9927                 mkconst(state, ins, sval);
9928         }
9929 }
9930
9931 static void simplify_deposit(struct compile_state *state, struct triple *ins)
9932 {
9933         if (is_simple_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9934                 ulong_t targ, val;
9935                 ulong_t mask;
9936                 targ = read_const(state, ins, RHS(ins, 0));
9937                 val  = read_const(state, ins, RHS(ins, 1));
9938                 mask = 1;
9939                 mask <<= ins->u.bitfield.size;
9940                 mask -= 1;
9941                 mask <<= ins->u.bitfield.offset;
9942                 targ &= ~mask;
9943                 val <<= ins->u.bitfield.offset;
9944                 val &= mask;
9945                 targ |= val;
9946                 mkconst(state, ins, targ);
9947         }
9948 }
9949
9950 static void simplify_copy(struct compile_state *state, struct triple *ins)
9951 {
9952         struct triple *right;
9953         right = RHS(ins, 0);
9954         if (is_subset_type(ins->type, right->type)) {
9955                 ins->type = right->type;
9956         }
9957         if (equiv_types(ins->type, right->type)) {
9958                 ins->op = OP_COPY;/* I don't need to convert if the types match */
9959         } else {
9960                 if (ins->op == OP_COPY) {
9961                         internal_error(state, ins, "type mismatch on copy");
9962                 }
9963         }
9964         if (is_const(right) && (right->op == OP_ADDRCONST) && is_pointer(ins)) {
9965                 struct triple *sdecl;
9966                 ulong_t offset;
9967                 sdecl  = MISC(right, 0);
9968                 offset = right->u.cval;
9969                 mkaddr_const(state, ins, sdecl, offset);
9970         }
9971         else if (is_const(right) && is_write_compatible(state, ins->type, right->type)) {
9972                 switch(right->op) {
9973                 case OP_INTCONST:
9974                 {
9975                         ulong_t left;
9976                         left = read_const(state, ins, right);
9977                         /* Ensure I have not overflowed the destination. */
9978                         if (size_of(state, right->type) > size_of(state, ins->type)) {
9979                                 ulong_t mask;
9980                                 mask = 1;
9981                                 mask <<= size_of(state, ins->type);
9982                                 mask -= 1;
9983                                 left &= mask;
9984                         }
9985                         /* Ensure I am properly sign extended */
9986                         if (size_of(state, right->type) < size_of(state, ins->type) &&
9987                                 is_signed(right->type)) {
9988                                 long_t val;
9989                                 int shift;
9990                                 shift = SIZEOF_LONG - size_of(state, right->type);
9991                                 val = left;
9992                                 val <<= shift;
9993                                 val >>= shift;
9994                                 left = val;
9995                         }
9996                         mkconst(state, ins, left);
9997                         break;
9998                 }
9999                 default:
10000                         internal_error(state, ins, "uknown constant");
10001                         break;
10002                 }
10003         }
10004 }
10005
10006 static int phi_present(struct block *block)
10007 {
10008         struct triple *ptr;
10009         if (!block) {
10010                 return 0;
10011         }
10012         ptr = block->first;
10013         do {
10014                 if (ptr->op == OP_PHI) {
10015                         return 1;
10016                 }
10017                 ptr = ptr->next;
10018         } while(ptr != block->last);
10019         return 0;
10020 }
10021
10022 static int phi_dependency(struct block *block)
10023 {
10024         /* A block has a phi dependency if a phi function
10025          * depends on that block to exist, and makes a block
10026          * that is otherwise useless unsafe to remove.
10027          */
10028         if (block) {
10029                 struct block_set *edge;
10030                 for(edge = block->edges; edge; edge = edge->next) {
10031                         if (phi_present(edge->member)) {
10032                                 return 1;
10033                         }
10034                 }
10035         }
10036         return 0;
10037 }
10038
10039 static struct triple *branch_target(struct compile_state *state, struct triple *ins)
10040 {
10041         struct triple *targ;
10042         targ = TARG(ins, 0);
10043         /* During scc_transform temporary triples are allocated that
10044          * loop back onto themselves. If I see one don't advance the
10045          * target.
10046          */
10047         while(triple_is_structural(state, targ) && 
10048                 (targ->next != targ) && (targ->next != state->first)) {
10049                 targ = targ->next;
10050         }
10051         return targ;
10052 }
10053
10054
10055 static void simplify_branch(struct compile_state *state, struct triple *ins)
10056 {
10057         int simplified, loops;
10058         if ((ins->op != OP_BRANCH) && (ins->op != OP_CBRANCH)) {
10059                 internal_error(state, ins, "not branch");
10060         }
10061         if (ins->use != 0) {
10062                 internal_error(state, ins, "branch use");
10063         }
10064         /* The challenge here with simplify branch is that I need to 
10065          * make modifications to the control flow graph as well
10066          * as to the branch instruction itself.  That is handled
10067          * by rebuilding the basic blocks after simplify all is called.
10068          */
10069
10070         /* If we have a branch to an unconditional branch update
10071          * our target.  But watch out for dependencies from phi
10072          * functions.
10073          * Also only do this a limited number of times so
10074          * we don't get into an infinite loop.
10075          */
10076         loops = 0;
10077         do {
10078                 struct triple *targ;
10079                 simplified = 0;
10080                 targ = branch_target(state, ins);
10081                 if ((targ != ins) && (targ->op == OP_BRANCH) && 
10082                         !phi_dependency(targ->u.block))
10083                 {
10084                         unuse_triple(TARG(ins, 0), ins);
10085                         TARG(ins, 0) = TARG(targ, 0);
10086                         use_triple(TARG(ins, 0), ins);
10087                         simplified = 1;
10088                 }
10089         } while(simplified && (++loops < 20));
10090
10091         /* If we have a conditional branch with a constant condition
10092          * make it an unconditional branch.
10093          */
10094         if ((ins->op == OP_CBRANCH) && is_simple_const(RHS(ins, 0))) {
10095                 struct triple *targ;
10096                 ulong_t value;
10097                 value = read_const(state, ins, RHS(ins, 0));
10098                 unuse_triple(RHS(ins, 0), ins);
10099                 targ = TARG(ins, 0);
10100                 ins->rhs  = 0;
10101                 ins->targ = 1;
10102                 ins->op = OP_BRANCH;
10103                 if (value) {
10104                         unuse_triple(ins->next, ins);
10105                         TARG(ins, 0) = targ;
10106                 }
10107                 else {
10108                         unuse_triple(targ, ins);
10109                         TARG(ins, 0) = ins->next;
10110                 }
10111         }
10112
10113         /* If we have a branch to the next instruction,
10114          * make it a noop.
10115          */
10116         if (TARG(ins, 0) == ins->next) {
10117                 unuse_triple(TARG(ins, 0), ins);
10118                 if (ins->op == OP_CBRANCH) {
10119                         unuse_triple(RHS(ins, 0), ins);
10120                         unuse_triple(ins->next, ins);
10121                 }
10122                 ins->lhs = 0;
10123                 ins->rhs = 0;
10124                 ins->misc = 0;
10125                 ins->targ = 0;
10126                 ins->op = OP_NOOP;
10127                 if (ins->use) {
10128                         internal_error(state, ins, "noop use != 0");
10129                 }
10130         }
10131 }
10132
10133 static void simplify_label(struct compile_state *state, struct triple *ins)
10134 {
10135         /* Ignore volatile labels */
10136         if (!triple_is_pure(state, ins, ins->id)) {
10137                 return;
10138         }
10139         if (ins->use == 0) {
10140                 ins->op = OP_NOOP;
10141         }
10142         else if (ins->prev->op == OP_LABEL) {
10143                 /* In general it is not safe to merge one label that
10144                  * imediately follows another.  The problem is that the empty
10145                  * looking block may have phi functions that depend on it.
10146                  */
10147                 if (!phi_dependency(ins->prev->u.block)) {
10148                         struct triple_set *user, *next;
10149                         ins->op = OP_NOOP;
10150                         for(user = ins->use; user; user = next) {
10151                                 struct triple *use, **expr;
10152                                 next = user->next;
10153                                 use = user->member;
10154                                 expr = triple_targ(state, use, 0);
10155                                 for(;expr; expr = triple_targ(state, use, expr)) {
10156                                         if (*expr == ins) {
10157                                                 *expr = ins->prev;
10158                                                 unuse_triple(ins, use);
10159                                                 use_triple(ins->prev, use);
10160                                         }
10161                                         
10162                                 }
10163                         }
10164                         if (ins->use) {
10165                                 internal_error(state, ins, "noop use != 0");
10166                         }
10167                 }
10168         }
10169 }
10170
10171 static void simplify_phi(struct compile_state *state, struct triple *ins)
10172 {
10173         struct triple **slot;
10174         struct triple *value;
10175         int zrhs, i;
10176         ulong_t cvalue;
10177         slot = &RHS(ins, 0);
10178         zrhs = ins->rhs;
10179         if (zrhs == 0) {
10180                 return;
10181         }
10182         /* See if all of the rhs members of a phi have the same value */
10183         if (slot[0] && is_simple_const(slot[0])) {
10184                 cvalue = read_const(state, ins, slot[0]);
10185                 for(i = 1; i < zrhs; i++) {
10186                         if (    !slot[i] ||
10187                                 !is_simple_const(slot[i]) ||
10188                                 !equiv_types(slot[0]->type, slot[i]->type) ||
10189                                 (cvalue != read_const(state, ins, slot[i]))) {
10190                                 break;
10191                         }
10192                 }
10193                 if (i == zrhs) {
10194                         mkconst(state, ins, cvalue);
10195                         return;
10196                 }
10197         }
10198         
10199         /* See if all of rhs members of a phi are the same */
10200         value = slot[0];
10201         for(i = 1; i < zrhs; i++) {
10202                 if (slot[i] != value) {
10203                         break;
10204                 }
10205         }
10206         if (i == zrhs) {
10207                 /* If the phi has a single value just copy it */
10208                 if (!is_subset_type(ins->type, value->type)) {
10209                         internal_error(state, ins, "bad input type to phi");
10210                 }
10211                 /* Make the types match */
10212                 if (!equiv_types(ins->type, value->type)) {
10213                         ins->type = value->type;
10214                 }
10215                 /* Now make the actual copy */
10216                 mkcopy(state, ins, value);
10217                 return;
10218         }
10219 }
10220
10221
10222 static void simplify_bsf(struct compile_state *state, struct triple *ins)
10223 {
10224         if (is_simple_const(RHS(ins, 0))) {
10225                 ulong_t left;
10226                 left = read_const(state, ins, RHS(ins, 0));
10227                 mkconst(state, ins, bsf(left));
10228         }
10229 }
10230
10231 static void simplify_bsr(struct compile_state *state, struct triple *ins)
10232 {
10233         if (is_simple_const(RHS(ins, 0))) {
10234                 ulong_t left;
10235                 left = read_const(state, ins, RHS(ins, 0));
10236                 mkconst(state, ins, bsr(left));
10237         }
10238 }
10239
10240
10241 typedef void (*simplify_t)(struct compile_state *state, struct triple *ins);
10242 static const struct simplify_table {
10243         simplify_t func;
10244         unsigned long flag;
10245 } table_simplify[] = {
10246 #define simplify_sdivt    simplify_noop
10247 #define simplify_udivt    simplify_noop
10248 #define simplify_piece    simplify_noop
10249
10250 [OP_SDIVT      ] = { simplify_sdivt,    COMPILER_SIMPLIFY_ARITH },
10251 [OP_UDIVT      ] = { simplify_udivt,    COMPILER_SIMPLIFY_ARITH },
10252 [OP_SMUL       ] = { simplify_smul,     COMPILER_SIMPLIFY_ARITH },
10253 [OP_UMUL       ] = { simplify_umul,     COMPILER_SIMPLIFY_ARITH },
10254 [OP_SDIV       ] = { simplify_sdiv,     COMPILER_SIMPLIFY_ARITH },
10255 [OP_UDIV       ] = { simplify_udiv,     COMPILER_SIMPLIFY_ARITH },
10256 [OP_SMOD       ] = { simplify_smod,     COMPILER_SIMPLIFY_ARITH },
10257 [OP_UMOD       ] = { simplify_umod,     COMPILER_SIMPLIFY_ARITH },
10258 [OP_ADD        ] = { simplify_add,      COMPILER_SIMPLIFY_ARITH },
10259 [OP_SUB        ] = { simplify_sub,      COMPILER_SIMPLIFY_ARITH },
10260 [OP_SL         ] = { simplify_sl,       COMPILER_SIMPLIFY_SHIFT },
10261 [OP_USR        ] = { simplify_usr,      COMPILER_SIMPLIFY_SHIFT },
10262 [OP_SSR        ] = { simplify_ssr,      COMPILER_SIMPLIFY_SHIFT },
10263 [OP_AND        ] = { simplify_and,      COMPILER_SIMPLIFY_BITWISE },
10264 [OP_XOR        ] = { simplify_xor,      COMPILER_SIMPLIFY_BITWISE },
10265 [OP_OR         ] = { simplify_or,       COMPILER_SIMPLIFY_BITWISE },
10266 [OP_POS        ] = { simplify_pos,      COMPILER_SIMPLIFY_ARITH },
10267 [OP_NEG        ] = { simplify_neg,      COMPILER_SIMPLIFY_ARITH },
10268 [OP_INVERT     ] = { simplify_invert,   COMPILER_SIMPLIFY_BITWISE },
10269
10270 [OP_EQ         ] = { simplify_eq,       COMPILER_SIMPLIFY_LOGICAL },
10271 [OP_NOTEQ      ] = { simplify_noteq,    COMPILER_SIMPLIFY_LOGICAL },
10272 [OP_SLESS      ] = { simplify_sless,    COMPILER_SIMPLIFY_LOGICAL },
10273 [OP_ULESS      ] = { simplify_uless,    COMPILER_SIMPLIFY_LOGICAL },
10274 [OP_SMORE      ] = { simplify_smore,    COMPILER_SIMPLIFY_LOGICAL },
10275 [OP_UMORE      ] = { simplify_umore,    COMPILER_SIMPLIFY_LOGICAL },
10276 [OP_SLESSEQ    ] = { simplify_slesseq,  COMPILER_SIMPLIFY_LOGICAL },
10277 [OP_ULESSEQ    ] = { simplify_ulesseq,  COMPILER_SIMPLIFY_LOGICAL },
10278 [OP_SMOREEQ    ] = { simplify_smoreeq,  COMPILER_SIMPLIFY_LOGICAL },
10279 [OP_UMOREEQ    ] = { simplify_umoreeq,  COMPILER_SIMPLIFY_LOGICAL },
10280 [OP_LFALSE     ] = { simplify_lfalse,   COMPILER_SIMPLIFY_LOGICAL },
10281 [OP_LTRUE      ] = { simplify_ltrue,    COMPILER_SIMPLIFY_LOGICAL },
10282
10283 [OP_LOAD       ] = { simplify_load,     COMPILER_SIMPLIFY_OP },
10284 [OP_STORE      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10285
10286 [OP_UEXTRACT   ] = { simplify_uextract, COMPILER_SIMPLIFY_BITFIELD },
10287 [OP_SEXTRACT   ] = { simplify_sextract, COMPILER_SIMPLIFY_BITFIELD },
10288 [OP_DEPOSIT    ] = { simplify_deposit,  COMPILER_SIMPLIFY_BITFIELD },
10289
10290 [OP_NOOP       ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10291
10292 [OP_INTCONST   ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10293 [OP_BLOBCONST  ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10294 [OP_ADDRCONST  ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10295 [OP_UNKNOWNVAL ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10296
10297 [OP_WRITE      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10298 [OP_READ       ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10299 [OP_COPY       ] = { simplify_copy,     COMPILER_SIMPLIFY_COPY },
10300 [OP_CONVERT    ] = { simplify_copy,     COMPILER_SIMPLIFY_COPY },
10301 [OP_PIECE      ] = { simplify_piece,    COMPILER_SIMPLIFY_OP },
10302 [OP_ASM        ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10303
10304 [OP_DOT        ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10305 [OP_INDEX      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10306
10307 [OP_LIST       ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10308 [OP_BRANCH     ] = { simplify_branch,   COMPILER_SIMPLIFY_BRANCH },
10309 [OP_CBRANCH    ] = { simplify_branch,   COMPILER_SIMPLIFY_BRANCH },
10310 [OP_CALL       ] = { simplify_noop,     COMPILER_SIMPLIFY_BRANCH },
10311 [OP_RET        ] = { simplify_noop,     COMPILER_SIMPLIFY_BRANCH },
10312 [OP_LABEL      ] = { simplify_label,    COMPILER_SIMPLIFY_LABEL },
10313 [OP_ADECL      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10314 [OP_SDECL      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10315 [OP_PHI        ] = { simplify_phi,      COMPILER_SIMPLIFY_PHI },
10316
10317 [OP_INB        ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10318 [OP_INW        ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10319 [OP_INL        ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10320 [OP_OUTB       ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10321 [OP_OUTW       ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10322 [OP_OUTL       ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10323 [OP_BSF        ] = { simplify_bsf,      COMPILER_SIMPLIFY_OP },
10324 [OP_BSR        ] = { simplify_bsr,      COMPILER_SIMPLIFY_OP },
10325 [OP_RDMSR      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10326 [OP_WRMSR      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },               
10327 [OP_HLT        ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10328 };
10329
10330 static inline void debug_simplify(struct compile_state *state, 
10331         simplify_t do_simplify, struct triple *ins)
10332 {
10333 #if DEBUG_SIMPLIFY_HIRES
10334                 if (state->functions_joined && (do_simplify != simplify_noop)) {
10335                         /* High resolution debugging mode */
10336                         fprintf(state->dbgout, "simplifing: ");
10337                         display_triple(state->dbgout, ins);
10338                 }
10339 #endif
10340                 do_simplify(state, ins);
10341 #if DEBUG_SIMPLIFY_HIRES
10342                 if (state->functions_joined && (do_simplify != simplify_noop)) {
10343                         /* High resolution debugging mode */
10344                         fprintf(state->dbgout, "simplified: ");
10345                         display_triple(state->dbgout, ins);
10346                 }
10347 #endif
10348 }
10349 static void simplify(struct compile_state *state, struct triple *ins)
10350 {
10351         int op;
10352         simplify_t do_simplify;
10353         if (ins == &unknown_triple) {
10354                 internal_error(state, ins, "simplifying the unknown triple?");
10355         }
10356         do {
10357                 op = ins->op;
10358                 do_simplify = 0;
10359                 if ((op < 0) || (op > sizeof(table_simplify)/sizeof(table_simplify[0]))) {
10360                         do_simplify = 0;
10361                 }
10362                 else {
10363                         do_simplify = table_simplify[op].func;
10364                 }
10365                 if (do_simplify && 
10366                         !(state->compiler->flags & table_simplify[op].flag)) {
10367                         do_simplify = simplify_noop;
10368                 }
10369                 if (do_simplify && (ins->id & TRIPLE_FLAG_VOLATILE)) {
10370                         do_simplify = simplify_noop;
10371                 }
10372         
10373                 if (!do_simplify) {
10374                         internal_error(state, ins, "cannot simplify op: %d %s",
10375                                 op, tops(op));
10376                         return;
10377                 }
10378                 debug_simplify(state, do_simplify, ins);
10379         } while(ins->op != op);
10380 }
10381
10382 static void rebuild_ssa_form(struct compile_state *state);
10383
10384 static void simplify_all(struct compile_state *state)
10385 {
10386         struct triple *ins, *first;
10387         if (!(state->compiler->flags & COMPILER_SIMPLIFY)) {
10388                 return;
10389         }
10390         first = state->first;
10391         ins = first->prev;
10392         do {
10393                 simplify(state, ins);
10394                 ins = ins->prev;
10395         } while(ins != first->prev);
10396         ins = first;
10397         do {
10398                 simplify(state, ins);
10399                 ins = ins->next;
10400         }while(ins != first);
10401         rebuild_ssa_form(state);
10402
10403         print_blocks(state, __func__, state->dbgout);
10404 }
10405
10406 /*
10407  * Builtins....
10408  * ============================
10409  */
10410
10411 static void register_builtin_function(struct compile_state *state,
10412         const char *name, int op, struct type *rtype, ...)
10413 {
10414         struct type *ftype, *atype, *ctype, *crtype, *param, **next;
10415         struct triple *def, *arg, *result, *work, *last, *first, *retvar, *ret;
10416         struct hash_entry *ident;
10417         struct file_state file;
10418         int parameters;
10419         int name_len;
10420         va_list args;
10421         int i;
10422
10423         /* Dummy file state to get debug handling right */
10424         memset(&file, 0, sizeof(file));
10425         file.basename = "<built-in>";
10426         file.line = 1;
10427         file.report_line = 1;
10428         file.report_name = file.basename;
10429         file.prev = state->file;
10430         state->file = &file;
10431         state->function = name;
10432
10433         /* Find the Parameter count */
10434         valid_op(state, op);
10435         parameters = table_ops[op].rhs;
10436         if (parameters < 0 ) {
10437                 internal_error(state, 0, "Invalid builtin parameter count");
10438         }
10439
10440         /* Find the function type */
10441         ftype = new_type(TYPE_FUNCTION | STOR_INLINE | STOR_STATIC, rtype, 0);
10442         ftype->elements = parameters;
10443         next = &ftype->right;
10444         va_start(args, rtype);
10445         for(i = 0; i < parameters; i++) {
10446                 atype = va_arg(args, struct type *);
10447                 if (!*next) {
10448                         *next = atype;
10449                 } else {
10450                         *next = new_type(TYPE_PRODUCT, *next, atype);
10451                         next = &((*next)->right);
10452                 }
10453         }
10454         if (!*next) {
10455                 *next = &void_type;
10456         }
10457         va_end(args);
10458
10459         /* Get the initial closure type */
10460         ctype = new_type(TYPE_JOIN, &void_type, 0);
10461         ctype->elements = 1;
10462
10463         /* Get the return type */
10464         crtype = new_type(TYPE_TUPLE, new_type(TYPE_PRODUCT, ctype, rtype), 0);
10465         crtype->elements = 2;
10466
10467         /* Generate the needed triples */
10468         def = triple(state, OP_LIST, ftype, 0, 0);
10469         first = label(state);
10470         RHS(def, 0) = first;
10471         result = flatten(state, first, variable(state, crtype));
10472         retvar = flatten(state, first, variable(state, &void_ptr_type));
10473         ret = triple(state, OP_RET, &void_type, read_expr(state, retvar), 0);
10474
10475         /* Now string them together */
10476         param = ftype->right;
10477         for(i = 0; i < parameters; i++) {
10478                 if ((param->type & TYPE_MASK) == TYPE_PRODUCT) {
10479                         atype = param->left;
10480                 } else {
10481                         atype = param;
10482                 }
10483                 arg = flatten(state, first, variable(state, atype));
10484                 param = param->right;
10485         }
10486         work = new_triple(state, op, rtype, -1, parameters);
10487         generate_lhs_pieces(state, work);
10488         for(i = 0; i < parameters; i++) {
10489                 RHS(work, i) = read_expr(state, farg(state, def, i));
10490         }
10491         if ((rtype->type & TYPE_MASK) != TYPE_VOID) {
10492                 work = write_expr(state, deref_index(state, result, 1), work);
10493         }
10494         work = flatten(state, first, work);
10495         last = flatten(state, first, label(state));
10496         ret  = flatten(state, first, ret);
10497         name_len = strlen(name);
10498         ident = lookup(state, name, name_len);
10499         ftype->type_ident = ident;
10500         symbol(state, ident, &ident->sym_ident, def, ftype);
10501         
10502         state->file = file.prev;
10503         state->function = 0;
10504         state->main_function = 0;
10505
10506         if (!state->functions) {
10507                 state->functions = def;
10508         } else {
10509                 insert_triple(state, state->functions, def);
10510         }
10511         if (state->compiler->debug & DEBUG_INLINE) {
10512                 FILE *fp = state->dbgout;
10513                 fprintf(fp, "\n");
10514                 loc(fp, state, 0);
10515                 fprintf(fp, "\n__________ %s _________\n", __FUNCTION__);
10516                 display_func(state, fp, def);
10517                 fprintf(fp, "__________ %s _________ done\n\n", __FUNCTION__);
10518         }
10519 }
10520
10521 static struct type *partial_struct(struct compile_state *state,
10522         const char *field_name, struct type *type, struct type *rest)
10523 {
10524         struct hash_entry *field_ident;
10525         struct type *result;
10526         int field_name_len;
10527
10528         field_name_len = strlen(field_name);
10529         field_ident = lookup(state, field_name, field_name_len);
10530
10531         result = clone_type(0, type);
10532         result->field_ident = field_ident;
10533
10534         if (rest) {
10535                 result = new_type(TYPE_PRODUCT, result, rest);
10536         }
10537         return result;
10538 }
10539
10540 static struct type *register_builtin_type(struct compile_state *state,
10541         const char *name, struct type *type)
10542 {
10543         struct hash_entry *ident;
10544         int name_len;
10545
10546         name_len = strlen(name);
10547         ident = lookup(state, name, name_len);
10548         
10549         if ((type->type & TYPE_MASK) == TYPE_PRODUCT) {
10550                 ulong_t elements = 0;
10551                 struct type *field;
10552                 type = new_type(TYPE_STRUCT, type, 0);
10553                 field = type->left;
10554                 while((field->type & TYPE_MASK) == TYPE_PRODUCT) {
10555                         elements++;
10556                         field = field->right;
10557                 }
10558                 elements++;
10559                 symbol(state, ident, &ident->sym_tag, 0, type);
10560                 type->type_ident = ident;
10561                 type->elements = elements;
10562         }
10563         symbol(state, ident, &ident->sym_ident, 0, type);
10564         ident->tok = TOK_TYPE_NAME;
10565         return type;
10566 }
10567
10568
10569 static void register_builtins(struct compile_state *state)
10570 {
10571         struct type *div_type, *ldiv_type;
10572         struct type *udiv_type, *uldiv_type;
10573         struct type *msr_type;
10574
10575         div_type = register_builtin_type(state, "__builtin_div_t",
10576                 partial_struct(state, "quot", &int_type,
10577                 partial_struct(state, "rem",  &int_type, 0)));
10578         ldiv_type = register_builtin_type(state, "__builtin_ldiv_t",
10579                 partial_struct(state, "quot", &long_type,
10580                 partial_struct(state, "rem",  &long_type, 0)));
10581         udiv_type = register_builtin_type(state, "__builtin_udiv_t",
10582                 partial_struct(state, "quot", &uint_type,
10583                 partial_struct(state, "rem",  &uint_type, 0)));
10584         uldiv_type = register_builtin_type(state, "__builtin_uldiv_t",
10585                 partial_struct(state, "quot", &ulong_type,
10586                 partial_struct(state, "rem",  &ulong_type, 0)));
10587
10588         register_builtin_function(state, "__builtin_div",   OP_SDIVT, div_type,
10589                 &int_type, &int_type);
10590         register_builtin_function(state, "__builtin_ldiv",  OP_SDIVT, ldiv_type,
10591                 &long_type, &long_type);
10592         register_builtin_function(state, "__builtin_udiv",  OP_UDIVT, udiv_type,
10593                 &uint_type, &uint_type);
10594         register_builtin_function(state, "__builtin_uldiv", OP_UDIVT, uldiv_type,
10595                 &ulong_type, &ulong_type);
10596
10597         register_builtin_function(state, "__builtin_inb", OP_INB, &uchar_type, 
10598                 &ushort_type);
10599         register_builtin_function(state, "__builtin_inw", OP_INW, &ushort_type,
10600                 &ushort_type);
10601         register_builtin_function(state, "__builtin_inl", OP_INL, &uint_type,   
10602                 &ushort_type);
10603
10604         register_builtin_function(state, "__builtin_outb", OP_OUTB, &void_type, 
10605                 &uchar_type, &ushort_type);
10606         register_builtin_function(state, "__builtin_outw", OP_OUTW, &void_type, 
10607                 &ushort_type, &ushort_type);
10608         register_builtin_function(state, "__builtin_outl", OP_OUTL, &void_type, 
10609                 &uint_type, &ushort_type);
10610         
10611         register_builtin_function(state, "__builtin_bsf", OP_BSF, &int_type, 
10612                 &int_type);
10613         register_builtin_function(state, "__builtin_bsr", OP_BSR, &int_type, 
10614                 &int_type);
10615
10616         msr_type = register_builtin_type(state, "__builtin_msr_t",
10617                 partial_struct(state, "lo", &ulong_type,
10618                 partial_struct(state, "hi", &ulong_type, 0)));
10619
10620         register_builtin_function(state, "__builtin_rdmsr", OP_RDMSR, msr_type,
10621                 &ulong_type);
10622         register_builtin_function(state, "__builtin_wrmsr", OP_WRMSR, &void_type,
10623                 &ulong_type, &ulong_type, &ulong_type);
10624         
10625         register_builtin_function(state, "__builtin_hlt", OP_HLT, &void_type, 
10626                 &void_type);
10627 }
10628
10629 static struct type *declarator(
10630         struct compile_state *state, struct type *type, 
10631         struct hash_entry **ident, int need_ident);
10632 static void decl(struct compile_state *state, struct triple *first);
10633 static struct type *specifier_qualifier_list(struct compile_state *state);
10634 static int isdecl_specifier(int tok);
10635 static struct type *decl_specifiers(struct compile_state *state);
10636 static int istype(int tok);
10637 static struct triple *expr(struct compile_state *state);
10638 static struct triple *assignment_expr(struct compile_state *state);
10639 static struct type *type_name(struct compile_state *state);
10640 static void statement(struct compile_state *state, struct triple *first);
10641
10642 static struct triple *call_expr(
10643         struct compile_state *state, struct triple *func)
10644 {
10645         struct triple *def;
10646         struct type *param, *type;
10647         ulong_t pvals, index;
10648
10649         if ((func->type->type & TYPE_MASK) != TYPE_FUNCTION) {
10650                 error(state, 0, "Called object is not a function");
10651         }
10652         if (func->op != OP_LIST) {
10653                 internal_error(state, 0, "improper function");
10654         }
10655         eat(state, TOK_LPAREN);
10656         /* Find the return type without any specifiers */
10657         type = clone_type(0, func->type->left);
10658         /* Count the number of rhs entries for OP_FCALL */
10659         param = func->type->right;
10660         pvals = 0;
10661         while((param->type & TYPE_MASK) == TYPE_PRODUCT) {
10662                 pvals++;
10663                 param = param->right;
10664         }
10665         if ((param->type & TYPE_MASK) != TYPE_VOID) {
10666                 pvals++;
10667         }
10668         def = new_triple(state, OP_FCALL, type, -1, pvals);
10669         MISC(def, 0) = func;
10670
10671         param = func->type->right;
10672         for(index = 0; index < pvals; index++) {
10673                 struct triple *val;
10674                 struct type *arg_type;
10675                 val = read_expr(state, assignment_expr(state));
10676                 arg_type = param;
10677                 if ((param->type & TYPE_MASK) == TYPE_PRODUCT) {
10678                         arg_type = param->left;
10679                 }
10680                 write_compatible(state, arg_type, val->type);
10681                 RHS(def, index) = val;
10682                 if (index != (pvals - 1)) {
10683                         eat(state, TOK_COMMA);
10684                         param = param->right;
10685                 }
10686         }
10687         eat(state, TOK_RPAREN);
10688         return def;
10689 }
10690
10691
10692 static struct triple *character_constant(struct compile_state *state)
10693 {
10694         struct triple *def;
10695         struct token *tk;
10696         const signed char *str, *end;
10697         int c;
10698         int str_len;
10699         tk = eat(state, TOK_LIT_CHAR);
10700         str = tk->val.str + 1;
10701         str_len = tk->str_len - 2;
10702         if (str_len <= 0) {
10703                 error(state, 0, "empty character constant");
10704         }
10705         end = str + str_len;
10706         c = char_value(state, &str, end);
10707         if (str != end) {
10708                 error(state, 0, "multibyte character constant not supported");
10709         }
10710         def = int_const(state, &char_type, (ulong_t)((long_t)c));
10711         return def;
10712 }
10713
10714 static struct triple *string_constant(struct compile_state *state)
10715 {
10716         struct triple *def;
10717         struct token *tk;
10718         struct type *type;
10719         const signed char *str, *end;
10720         signed char *buf, *ptr;
10721         int str_len;
10722
10723         buf = 0;
10724         type = new_type(TYPE_ARRAY, &char_type, 0);
10725         type->elements = 0;
10726         /* The while loop handles string concatenation */
10727         do {
10728                 tk = eat(state, TOK_LIT_STRING);
10729                 str = tk->val.str + 1;
10730                 str_len = tk->str_len - 2;
10731                 if (str_len < 0) {
10732                         error(state, 0, "negative string constant length");
10733                 }
10734                 end = str + str_len;
10735                 ptr = buf;
10736                 buf = xmalloc(type->elements + str_len + 1, "string_constant");
10737                 memcpy(buf, ptr, type->elements);
10738                 ptr = buf + type->elements;
10739                 do {
10740                         *ptr++ = char_value(state, &str, end);
10741                 } while(str < end);
10742                 type->elements = ptr - buf;
10743         } while(peek(state) == TOK_LIT_STRING);
10744         *ptr = '\0';
10745         type->elements += 1;
10746         def = triple(state, OP_BLOBCONST, type, 0, 0);
10747         def->u.blob = buf;
10748
10749         return def;
10750 }
10751
10752
10753 static struct triple *integer_constant(struct compile_state *state)
10754 {
10755         struct triple *def;
10756         unsigned long val;
10757         struct token *tk;
10758         char *end;
10759         int u, l, decimal;
10760         struct type *type;
10761
10762         tk = eat(state, TOK_LIT_INT);
10763         errno = 0;
10764         decimal = (tk->val.str[0] != '0');
10765         val = strtoul(tk->val.str, &end, 0);
10766         if ((val > ULONG_T_MAX) || ((val == ULONG_MAX) && (errno == ERANGE))) {
10767                 error(state, 0, "Integer constant to large");
10768         }
10769         u = l = 0;
10770         if ((*end == 'u') || (*end == 'U')) {
10771                 u = 1;
10772                         end++;
10773         }
10774         if ((*end == 'l') || (*end == 'L')) {
10775                 l = 1;
10776                 end++;
10777         }
10778         if ((*end == 'u') || (*end == 'U')) {
10779                 u = 1;
10780                 end++;
10781         }
10782         if (*end) {
10783                 error(state, 0, "Junk at end of integer constant");
10784         }
10785         if (u && l)  {
10786                 type = &ulong_type;
10787         }
10788         else if (l) {
10789                 type = &long_type;
10790                 if (!decimal && (val > LONG_T_MAX)) {
10791                         type = &ulong_type;
10792                 }
10793         }
10794         else if (u) {
10795                 type = &uint_type;
10796                 if (val > UINT_T_MAX) {
10797                         type = &ulong_type;
10798                 }
10799         }
10800         else {
10801                 type = &int_type;
10802                 if (!decimal && (val > INT_T_MAX) && (val <= UINT_T_MAX)) {
10803                         type = &uint_type;
10804                 }
10805                 else if (!decimal && (val > LONG_T_MAX)) {
10806                         type = &ulong_type;
10807                 }
10808                 else if (val > INT_T_MAX) {
10809                         type = &long_type;
10810                 }
10811         }
10812         def = int_const(state, type, val);
10813         return def;
10814 }
10815
10816 static struct triple *primary_expr(struct compile_state *state)
10817 {
10818         struct triple *def;
10819         int tok;
10820         tok = peek(state);
10821         switch(tok) {
10822         case TOK_IDENT:
10823         {
10824                 struct hash_entry *ident;
10825                 /* Here ident is either:
10826                  * a varable name
10827                  * a function name
10828                  */
10829                 ident = eat(state, TOK_IDENT)->ident;
10830                 if (!ident->sym_ident) {
10831                         error(state, 0, "%s undeclared", ident->name);
10832                 }
10833                 def = ident->sym_ident->def;
10834                 break;
10835         }
10836         case TOK_ENUM_CONST:
10837         {
10838                 struct hash_entry *ident;
10839                 /* Here ident is an enumeration constant */
10840                 ident = eat(state, TOK_ENUM_CONST)->ident;
10841                 if (!ident->sym_ident) {
10842                         error(state, 0, "%s undeclared", ident->name);
10843                 }
10844                 def = ident->sym_ident->def;
10845                 break;
10846         }
10847         case TOK_MIDENT:
10848         {
10849                 struct hash_entry *ident;
10850                 ident = eat(state, TOK_MIDENT)->ident;
10851                 warning(state, 0, "Replacing undefined macro: %s with 0",
10852                         ident->name);
10853                 def = int_const(state, &int_type, 0);
10854                 break;
10855         }
10856         case TOK_LPAREN:
10857                 eat(state, TOK_LPAREN);
10858                 def = expr(state);
10859                 eat(state, TOK_RPAREN);
10860                 break;
10861         case TOK_LIT_INT:
10862                 def = integer_constant(state);
10863                 break;
10864         case TOK_LIT_FLOAT:
10865                 eat(state, TOK_LIT_FLOAT);
10866                 error(state, 0, "Floating point constants not supported");
10867                 def = 0;
10868                 FINISHME();
10869                 break;
10870         case TOK_LIT_CHAR:
10871                 def = character_constant(state);
10872                 break;
10873         case TOK_LIT_STRING:
10874                 def = string_constant(state);
10875                 break;
10876         default:
10877                 def = 0;
10878                 error(state, 0, "Unexpected token: %s\n", tokens[tok]);
10879         }
10880         return def;
10881 }
10882
10883 static struct triple *postfix_expr(struct compile_state *state)
10884 {
10885         struct triple *def;
10886         int postfix;
10887         def = primary_expr(state);
10888         do {
10889                 struct triple *left;
10890                 int tok;
10891                 postfix = 1;
10892                 left = def;
10893                 switch((tok = peek(state))) {
10894                 case TOK_LBRACKET:
10895                         eat(state, TOK_LBRACKET);
10896                         def = mk_subscript_expr(state, left, expr(state));
10897                         eat(state, TOK_RBRACKET);
10898                         break;
10899                 case TOK_LPAREN:
10900                         def = call_expr(state, def);
10901                         break;
10902                 case TOK_DOT:
10903                 {
10904                         struct hash_entry *field;
10905                         eat(state, TOK_DOT);
10906                         field = eat(state, TOK_IDENT)->ident;
10907                         def = deref_field(state, def, field);
10908                         break;
10909                 }
10910                 case TOK_ARROW:
10911                 {
10912                         struct hash_entry *field;
10913                         eat(state, TOK_ARROW);
10914                         field = eat(state, TOK_IDENT)->ident;
10915                         def = mk_deref_expr(state, read_expr(state, def));
10916                         def = deref_field(state, def, field);
10917                         break;
10918                 }
10919                 case TOK_PLUSPLUS:
10920                         eat(state, TOK_PLUSPLUS);
10921                         def = mk_post_inc_expr(state, left);
10922                         break;
10923                 case TOK_MINUSMINUS:
10924                         eat(state, TOK_MINUSMINUS);
10925                         def = mk_post_dec_expr(state, left);
10926                         break;
10927                 default:
10928                         postfix = 0;
10929                         break;
10930                 }
10931         } while(postfix);
10932         return def;
10933 }
10934
10935 static struct triple *cast_expr(struct compile_state *state);
10936
10937 static struct triple *unary_expr(struct compile_state *state)
10938 {
10939         struct triple *def, *right;
10940         int tok;
10941         switch((tok = peek(state))) {
10942         case TOK_PLUSPLUS:
10943                 eat(state, TOK_PLUSPLUS);
10944                 def = mk_pre_inc_expr(state, unary_expr(state));
10945                 break;
10946         case TOK_MINUSMINUS:
10947                 eat(state, TOK_MINUSMINUS);
10948                 def = mk_pre_dec_expr(state, unary_expr(state));
10949                 break;
10950         case TOK_AND:
10951                 eat(state, TOK_AND);
10952                 def = mk_addr_expr(state, cast_expr(state), 0);
10953                 break;
10954         case TOK_STAR:
10955                 eat(state, TOK_STAR);
10956                 def = mk_deref_expr(state, read_expr(state, cast_expr(state)));
10957                 break;
10958         case TOK_PLUS:
10959                 eat(state, TOK_PLUS);
10960                 right = read_expr(state, cast_expr(state));
10961                 arithmetic(state, right);
10962                 def = integral_promotion(state, right);
10963                 break;
10964         case TOK_MINUS:
10965                 eat(state, TOK_MINUS);
10966                 right = read_expr(state, cast_expr(state));
10967                 arithmetic(state, right);
10968                 def = integral_promotion(state, right);
10969                 def = triple(state, OP_NEG, def->type, def, 0);
10970                 break;
10971         case TOK_TILDE:
10972                 eat(state, TOK_TILDE);
10973                 right = read_expr(state, cast_expr(state));
10974                 integral(state, right);
10975                 def = integral_promotion(state, right);
10976                 def = triple(state, OP_INVERT, def->type, def, 0);
10977                 break;
10978         case TOK_BANG:
10979                 eat(state, TOK_BANG);
10980                 right = read_expr(state, cast_expr(state));
10981                 bool(state, right);
10982                 def = lfalse_expr(state, right);
10983                 break;
10984         case TOK_SIZEOF:
10985         {
10986                 struct type *type;
10987                 int tok1, tok2;
10988                 eat(state, TOK_SIZEOF);
10989                 tok1 = peek(state);
10990                 tok2 = peek2(state);
10991                 if ((tok1 == TOK_LPAREN) && istype(tok2)) {
10992                         eat(state, TOK_LPAREN);
10993                         type = type_name(state);
10994                         eat(state, TOK_RPAREN);
10995                 }
10996                 else {
10997                         struct triple *expr;
10998                         expr = unary_expr(state);
10999                         type = expr->type;
11000                         release_expr(state, expr);
11001                 }
11002                 def = int_const(state, &ulong_type, size_of_in_bytes(state, type));
11003                 break;
11004         }
11005         case TOK_ALIGNOF:
11006         {
11007                 struct type *type;
11008                 int tok1, tok2;
11009                 eat(state, TOK_ALIGNOF);
11010                 tok1 = peek(state);
11011                 tok2 = peek2(state);
11012                 if ((tok1 == TOK_LPAREN) && istype(tok2)) {
11013                         eat(state, TOK_LPAREN);
11014                         type = type_name(state);
11015                         eat(state, TOK_RPAREN);
11016                 }
11017                 else {
11018                         struct triple *expr;
11019                         expr = unary_expr(state);
11020                         type = expr->type;
11021                         release_expr(state, expr);
11022                 }
11023                 def = int_const(state, &ulong_type, align_of_in_bytes(state, type));
11024                 break;
11025         }
11026         case TOK_MDEFINED:
11027         {
11028                 /* We only come here if we are called from the preprocessor */
11029                 struct hash_entry *ident;
11030                 int parens;
11031                 eat(state, TOK_MDEFINED);
11032                 parens = 0;
11033                 if (pp_peek(state) == TOK_LPAREN) {
11034                         pp_eat(state, TOK_LPAREN);
11035                         parens = 1;
11036                 }
11037                 ident = pp_eat(state, TOK_MIDENT)->ident;
11038                 if (parens) {
11039                         eat(state, TOK_RPAREN);
11040                 }
11041                 def = int_const(state, &int_type, ident->sym_define != 0);
11042                 break;
11043         }
11044         default:
11045                 def = postfix_expr(state);
11046                 break;
11047         }
11048         return def;
11049 }
11050
11051 static struct triple *cast_expr(struct compile_state *state)
11052 {
11053         struct triple *def;
11054         int tok1, tok2;
11055         tok1 = peek(state);
11056         tok2 = peek2(state);
11057         if ((tok1 == TOK_LPAREN) && istype(tok2)) {
11058                 struct type *type;
11059                 eat(state, TOK_LPAREN);
11060                 type = type_name(state);
11061                 eat(state, TOK_RPAREN);
11062                 def = mk_cast_expr(state, type, cast_expr(state));
11063         }
11064         else {
11065                 def = unary_expr(state);
11066         }
11067         return def;
11068 }
11069
11070 static struct triple *mult_expr(struct compile_state *state)
11071 {
11072         struct triple *def;
11073         int done;
11074         def = cast_expr(state);
11075         do {
11076                 struct triple *left, *right;
11077                 struct type *result_type;
11078                 int tok, op, sign;
11079                 done = 0;
11080                 tok = peek(state);
11081                 switch(tok) {
11082                 case TOK_STAR:
11083                 case TOK_DIV:
11084                 case TOK_MOD:
11085                         left = read_expr(state, def);
11086                         arithmetic(state, left);
11087
11088                         eat(state, tok);
11089
11090                         right = read_expr(state, cast_expr(state));
11091                         arithmetic(state, right);
11092
11093                         result_type = arithmetic_result(state, left, right);
11094                         sign = is_signed(result_type);
11095                         op = -1;
11096                         switch(tok) {
11097                         case TOK_STAR: op = sign? OP_SMUL : OP_UMUL; break;
11098                         case TOK_DIV:  op = sign? OP_SDIV : OP_UDIV; break;
11099                         case TOK_MOD:  op = sign? OP_SMOD : OP_UMOD; break;
11100                         }
11101                         def = triple(state, op, result_type, left, right);
11102                         break;
11103                 default:
11104                         done = 1;
11105                         break;
11106                 }
11107         } while(!done);
11108         return def;
11109 }
11110
11111 static struct triple *add_expr(struct compile_state *state)
11112 {
11113         struct triple *def;
11114         int done;
11115         def = mult_expr(state);
11116         do {
11117                 done = 0;
11118                 switch( peek(state)) {
11119                 case TOK_PLUS:
11120                         eat(state, TOK_PLUS);
11121                         def = mk_add_expr(state, def, mult_expr(state));
11122                         break;
11123                 case TOK_MINUS:
11124                         eat(state, TOK_MINUS);
11125                         def = mk_sub_expr(state, def, mult_expr(state));
11126                         break;
11127                 default:
11128                         done = 1;
11129                         break;
11130                 }
11131         } while(!done);
11132         return def;
11133 }
11134
11135 static struct triple *shift_expr(struct compile_state *state)
11136 {
11137         struct triple *def;
11138         int done;
11139         def = add_expr(state);
11140         do {
11141                 struct triple *left, *right;
11142                 int tok, op;
11143                 done = 0;
11144                 switch((tok = peek(state))) {
11145                 case TOK_SL:
11146                 case TOK_SR:
11147                         left = read_expr(state, def);
11148                         integral(state, left);
11149                         left = integral_promotion(state, left);
11150
11151                         eat(state, tok);
11152
11153                         right = read_expr(state, add_expr(state));
11154                         integral(state, right);
11155                         right = integral_promotion(state, right);
11156                         
11157                         op = (tok == TOK_SL)? OP_SL : 
11158                                 is_signed(left->type)? OP_SSR: OP_USR;
11159
11160                         def = triple(state, op, left->type, left, right);
11161                         break;
11162                 default:
11163                         done = 1;
11164                         break;
11165                 }
11166         } while(!done);
11167         return def;
11168 }
11169
11170 static struct triple *relational_expr(struct compile_state *state)
11171 {
11172 #warning "Extend relational exprs to work on more than arithmetic types"
11173         struct triple *def;
11174         int done;
11175         def = shift_expr(state);
11176         do {
11177                 struct triple *left, *right;
11178                 struct type *arg_type;
11179                 int tok, op, sign;
11180                 done = 0;
11181                 switch((tok = peek(state))) {
11182                 case TOK_LESS:
11183                 case TOK_MORE:
11184                 case TOK_LESSEQ:
11185                 case TOK_MOREEQ:
11186                         left = read_expr(state, def);
11187                         arithmetic(state, left);
11188
11189                         eat(state, tok);
11190
11191                         right = read_expr(state, shift_expr(state));
11192                         arithmetic(state, right);
11193
11194                         arg_type = arithmetic_result(state, left, right);
11195                         sign = is_signed(arg_type);
11196                         op = -1;
11197                         switch(tok) {
11198                         case TOK_LESS:   op = sign? OP_SLESS : OP_ULESS; break;
11199                         case TOK_MORE:   op = sign? OP_SMORE : OP_UMORE; break;
11200                         case TOK_LESSEQ: op = sign? OP_SLESSEQ : OP_ULESSEQ; break;
11201                         case TOK_MOREEQ: op = sign? OP_SMOREEQ : OP_UMOREEQ; break;
11202                         }
11203                         def = triple(state, op, &int_type, left, right);
11204                         break;
11205                 default:
11206                         done = 1;
11207                         break;
11208                 }
11209         } while(!done);
11210         return def;
11211 }
11212
11213 static struct triple *equality_expr(struct compile_state *state)
11214 {
11215 #warning "Extend equality exprs to work on more than arithmetic types"
11216         struct triple *def;
11217         int done;
11218         def = relational_expr(state);
11219         do {
11220                 struct triple *left, *right;
11221                 int tok, op;
11222                 done = 0;
11223                 switch((tok = peek(state))) {
11224                 case TOK_EQEQ:
11225                 case TOK_NOTEQ:
11226                         left = read_expr(state, def);
11227                         arithmetic(state, left);
11228                         eat(state, tok);
11229                         right = read_expr(state, relational_expr(state));
11230                         arithmetic(state, right);
11231                         op = (tok == TOK_EQEQ) ? OP_EQ: OP_NOTEQ;
11232                         def = triple(state, op, &int_type, left, right);
11233                         break;
11234                 default:
11235                         done = 1;
11236                         break;
11237                 }
11238         } while(!done);
11239         return def;
11240 }
11241
11242 static struct triple *and_expr(struct compile_state *state)
11243 {
11244         struct triple *def;
11245         def = equality_expr(state);
11246         while(peek(state) == TOK_AND) {
11247                 struct triple *left, *right;
11248                 struct type *result_type;
11249                 left = read_expr(state, def);
11250                 integral(state, left);
11251                 eat(state, TOK_AND);
11252                 right = read_expr(state, equality_expr(state));
11253                 integral(state, right);
11254                 result_type = arithmetic_result(state, left, right);
11255                 def = triple(state, OP_AND, result_type, left, right);
11256         }
11257         return def;
11258 }
11259
11260 static struct triple *xor_expr(struct compile_state *state)
11261 {
11262         struct triple *def;
11263         def = and_expr(state);
11264         while(peek(state) == TOK_XOR) {
11265                 struct triple *left, *right;
11266                 struct type *result_type;
11267                 left = read_expr(state, def);
11268                 integral(state, left);
11269                 eat(state, TOK_XOR);
11270                 right = read_expr(state, and_expr(state));
11271                 integral(state, right);
11272                 result_type = arithmetic_result(state, left, right);
11273                 def = triple(state, OP_XOR, result_type, left, right);
11274         }
11275         return def;
11276 }
11277
11278 static struct triple *or_expr(struct compile_state *state)
11279 {
11280         struct triple *def;
11281         def = xor_expr(state);
11282         while(peek(state) == TOK_OR) {
11283                 struct triple *left, *right;
11284                 struct type *result_type;
11285                 left = read_expr(state, def);
11286                 integral(state, left);
11287                 eat(state, TOK_OR);
11288                 right = read_expr(state, xor_expr(state));
11289                 integral(state, right);
11290                 result_type = arithmetic_result(state, left, right);
11291                 def = triple(state, OP_OR, result_type, left, right);
11292         }
11293         return def;
11294 }
11295
11296 static struct triple *land_expr(struct compile_state *state)
11297 {
11298         struct triple *def;
11299         def = or_expr(state);
11300         while(peek(state) == TOK_LOGAND) {
11301                 struct triple *left, *right;
11302                 left = read_expr(state, def);
11303                 bool(state, left);
11304                 eat(state, TOK_LOGAND);
11305                 right = read_expr(state, or_expr(state));
11306                 bool(state, right);
11307
11308                 def = mkland_expr(state,
11309                         ltrue_expr(state, left),
11310                         ltrue_expr(state, right));
11311         }
11312         return def;
11313 }
11314
11315 static struct triple *lor_expr(struct compile_state *state)
11316 {
11317         struct triple *def;
11318         def = land_expr(state);
11319         while(peek(state) == TOK_LOGOR) {
11320                 struct triple *left, *right;
11321                 left = read_expr(state, def);
11322                 bool(state, left);
11323                 eat(state, TOK_LOGOR);
11324                 right = read_expr(state, land_expr(state));
11325                 bool(state, right);
11326
11327                 def = mklor_expr(state, 
11328                         ltrue_expr(state, left),
11329                         ltrue_expr(state, right));
11330         }
11331         return def;
11332 }
11333
11334 static struct triple *conditional_expr(struct compile_state *state)
11335 {
11336         struct triple *def;
11337         def = lor_expr(state);
11338         if (peek(state) == TOK_QUEST) {
11339                 struct triple *test, *left, *right;
11340                 bool(state, def);
11341                 test = ltrue_expr(state, read_expr(state, def));
11342                 eat(state, TOK_QUEST);
11343                 left = read_expr(state, expr(state));
11344                 eat(state, TOK_COLON);
11345                 right = read_expr(state, conditional_expr(state));
11346
11347                 def = mkcond_expr(state, test, left, right);
11348         }
11349         return def;
11350 }
11351
11352 struct cv_triple {
11353         struct triple *val;
11354         int id;
11355 };
11356
11357 static void set_cv(struct compile_state *state, struct cv_triple *cv,
11358         struct triple *dest, struct triple *val)
11359 {
11360         if (cv[dest->id].val) {
11361                 free_triple(state, cv[dest->id].val);
11362         }
11363         cv[dest->id].val = val;
11364 }
11365 static struct triple *get_cv(struct compile_state *state, struct cv_triple *cv,
11366         struct triple *src)
11367 {
11368         return cv[src->id].val;
11369 }
11370
11371 static struct triple *eval_const_expr(
11372         struct compile_state *state, struct triple *expr)
11373 {
11374         struct triple *def;
11375         if (is_const(expr)) {
11376                 def = expr;
11377         }
11378         else {
11379                 /* If we don't start out as a constant simplify into one */
11380                 struct triple *head, *ptr;
11381                 struct cv_triple *cv;
11382                 int i, count;
11383                 head = label(state); /* dummy initial triple */
11384                 flatten(state, head, expr);
11385                 count = 1;
11386                 for(ptr = head->next; ptr != head; ptr = ptr->next) {
11387                         count++;
11388                 }
11389                 cv = xcmalloc(sizeof(struct cv_triple)*count, "const value vector");
11390                 i = 1;
11391                 for(ptr = head->next; ptr != head; ptr = ptr->next) {
11392                         cv[i].val = 0;
11393                         cv[i].id  = ptr->id;
11394                         ptr->id   = i;
11395                         i++;
11396                 }
11397                 ptr = head->next;
11398                 do {
11399                         valid_ins(state, ptr);
11400                         if ((ptr->op == OP_PHI) || (ptr->op == OP_LIST)) {
11401                                 internal_error(state, ptr, 
11402                                         "unexpected %s in constant expression",
11403                                         tops(ptr->op));
11404                         }
11405                         else if (ptr->op == OP_LIST) {
11406                         }
11407                         else if (triple_is_structural(state, ptr)) {
11408                                 ptr = ptr->next;
11409                         }
11410                         else if (triple_is_ubranch(state, ptr)) {
11411                                 ptr = TARG(ptr, 0);
11412                         }
11413                         else if (triple_is_cbranch(state, ptr)) {
11414                                 struct triple *cond_val;
11415                                 cond_val = get_cv(state, cv, RHS(ptr, 0));
11416                                 if (!cond_val || !is_const(cond_val) || 
11417                                         (cond_val->op != OP_INTCONST)) 
11418                                 {
11419                                         internal_error(state, ptr, "bad branch condition");
11420                                 }
11421                                 if (cond_val->u.cval == 0) {
11422                                         ptr = ptr->next;
11423                                 } else {
11424                                         ptr = TARG(ptr, 0);
11425                                 }
11426                         }
11427                         else if (triple_is_branch(state, ptr)) {
11428                                 error(state, ptr, "bad branch type in constant expression");
11429                         }
11430                         else if (ptr->op == OP_WRITE) {
11431                                 struct triple *val;
11432                                 val = get_cv(state, cv, RHS(ptr, 0));
11433                                 
11434                                 set_cv(state, cv, MISC(ptr, 0), 
11435                                         copy_triple(state, val));
11436                                 set_cv(state, cv, ptr, 
11437                                         copy_triple(state, val));
11438                                 ptr = ptr->next;
11439                         }
11440                         else if (ptr->op == OP_READ) {
11441                                 set_cv(state, cv, ptr, 
11442                                         copy_triple(state, 
11443                                                 get_cv(state, cv, RHS(ptr, 0))));
11444                                 ptr = ptr->next;
11445                         }
11446                         else if (triple_is_pure(state, ptr, cv[ptr->id].id)) {
11447                                 struct triple *val, **rhs;
11448                                 val = copy_triple(state, ptr);
11449                                 rhs = triple_rhs(state, val, 0);
11450                                 for(; rhs; rhs = triple_rhs(state, val, rhs)) {
11451                                         if (!*rhs) {
11452                                                 internal_error(state, ptr, "Missing rhs");
11453                                         }
11454                                         *rhs = get_cv(state, cv, *rhs);
11455                                 }
11456                                 simplify(state, val);
11457                                 set_cv(state, cv, ptr, val);
11458                                 ptr = ptr->next;
11459                         }
11460                         else {
11461                                 error(state, ptr, "impure operation in constant expression");
11462                         }
11463                         
11464                 } while(ptr != head);
11465
11466                 /* Get the result value */
11467                 def = get_cv(state, cv, head->prev);
11468                 cv[head->prev->id].val = 0;
11469
11470                 /* Free the temporary values */
11471                 for(i = 0; i < count; i++) {
11472                         if (cv[i].val) {
11473                                 free_triple(state, cv[i].val);
11474                                 cv[i].val = 0;
11475                         }
11476                 }
11477                 xfree(cv);
11478                 /* Free the intermediate expressions */
11479                 while(head->next != head) {
11480                         release_triple(state, head->next);
11481                 }
11482                 free_triple(state, head);
11483         }
11484         if (!is_const(def)) {
11485                 error(state, expr, "Not a constant expression");
11486         }
11487         return def;
11488 }
11489
11490 static struct triple *constant_expr(struct compile_state *state)
11491 {
11492         return eval_const_expr(state, conditional_expr(state));
11493 }
11494
11495 static struct triple *assignment_expr(struct compile_state *state)
11496 {
11497         struct triple *def, *left, *right;
11498         int tok, op, sign;
11499         /* The C grammer in K&R shows assignment expressions
11500          * only taking unary expressions as input on their
11501          * left hand side.  But specifies the precedence of
11502          * assignemnt as the lowest operator except for comma.
11503          *
11504          * Allowing conditional expressions on the left hand side
11505          * of an assignement results in a grammar that accepts
11506          * a larger set of statements than standard C.   As long
11507          * as the subset of the grammar that is standard C behaves
11508          * correctly this should cause no problems.
11509          * 
11510          * For the extra token strings accepted by the grammar
11511          * none of them should produce a valid lvalue, so they
11512          * should not produce functioning programs.
11513          *
11514          * GCC has this bug as well, so surprises should be minimal.
11515          */
11516         def = conditional_expr(state);
11517         left = def;
11518         switch((tok = peek(state))) {
11519         case TOK_EQ:
11520                 lvalue(state, left);
11521                 eat(state, TOK_EQ);
11522                 def = write_expr(state, left, 
11523                         read_expr(state, assignment_expr(state)));
11524                 break;
11525         case TOK_TIMESEQ:
11526         case TOK_DIVEQ:
11527         case TOK_MODEQ:
11528                 lvalue(state, left);
11529                 arithmetic(state, left);
11530                 eat(state, tok);
11531                 right = read_expr(state, assignment_expr(state));
11532                 arithmetic(state, right);
11533
11534                 sign = is_signed(left->type);
11535                 op = -1;
11536                 switch(tok) {
11537                 case TOK_TIMESEQ: op = sign? OP_SMUL : OP_UMUL; break;
11538                 case TOK_DIVEQ:   op = sign? OP_SDIV : OP_UDIV; break;
11539                 case TOK_MODEQ:   op = sign? OP_SMOD : OP_UMOD; break;
11540                 }
11541                 def = write_expr(state, left,
11542                         triple(state, op, left->type, 
11543                                 read_expr(state, left), right));
11544                 break;
11545         case TOK_PLUSEQ:
11546                 lvalue(state, left);
11547                 eat(state, TOK_PLUSEQ);
11548                 def = write_expr(state, left,
11549                         mk_add_expr(state, left, assignment_expr(state)));
11550                 break;
11551         case TOK_MINUSEQ:
11552                 lvalue(state, left);
11553                 eat(state, TOK_MINUSEQ);
11554                 def = write_expr(state, left,
11555                         mk_sub_expr(state, left, assignment_expr(state)));
11556                 break;
11557         case TOK_SLEQ:
11558         case TOK_SREQ:
11559         case TOK_ANDEQ:
11560         case TOK_XOREQ:
11561         case TOK_OREQ:
11562                 lvalue(state, left);
11563                 integral(state, left);
11564                 eat(state, tok);
11565                 right = read_expr(state, assignment_expr(state));
11566                 integral(state, right);
11567                 right = integral_promotion(state, right);
11568                 sign = is_signed(left->type);
11569                 op = -1;
11570                 switch(tok) {
11571                 case TOK_SLEQ:  op = OP_SL; break;
11572                 case TOK_SREQ:  op = sign? OP_SSR: OP_USR; break;
11573                 case TOK_ANDEQ: op = OP_AND; break;
11574                 case TOK_XOREQ: op = OP_XOR; break;
11575                 case TOK_OREQ:  op = OP_OR; break;
11576                 }
11577                 def = write_expr(state, left,
11578                         triple(state, op, left->type, 
11579                                 read_expr(state, left), right));
11580                 break;
11581         }
11582         return def;
11583 }
11584
11585 static struct triple *expr(struct compile_state *state)
11586 {
11587         struct triple *def;
11588         def = assignment_expr(state);
11589         while(peek(state) == TOK_COMMA) {
11590                 eat(state, TOK_COMMA);
11591                 def = mkprog(state, def, assignment_expr(state), 0);
11592         }
11593         return def;
11594 }
11595
11596 static void expr_statement(struct compile_state *state, struct triple *first)
11597 {
11598         if (peek(state) != TOK_SEMI) {
11599                 /* lvalue conversions always apply except when certian operators
11600                  * are applied.  I apply the lvalue conversions here
11601                  * as I know no more operators will be applied.
11602                  */
11603                 flatten(state, first, lvalue_conversion(state, expr(state)));
11604         }
11605         eat(state, TOK_SEMI);
11606 }
11607
11608 static void if_statement(struct compile_state *state, struct triple *first)
11609 {
11610         struct triple *test, *jmp1, *jmp2, *middle, *end;
11611
11612         jmp1 = jmp2 = middle = 0;
11613         eat(state, TOK_IF);
11614         eat(state, TOK_LPAREN);
11615         test = expr(state);
11616         bool(state, test);
11617         /* Cleanup and invert the test */
11618         test = lfalse_expr(state, read_expr(state, test));
11619         eat(state, TOK_RPAREN);
11620         /* Generate the needed pieces */
11621         middle = label(state);
11622         jmp1 = branch(state, middle, test);
11623         /* Thread the pieces together */
11624         flatten(state, first, test);
11625         flatten(state, first, jmp1);
11626         flatten(state, first, label(state));
11627         statement(state, first);
11628         if (peek(state) == TOK_ELSE) {
11629                 eat(state, TOK_ELSE);
11630                 /* Generate the rest of the pieces */
11631                 end = label(state);
11632                 jmp2 = branch(state, end, 0);
11633                 /* Thread them together */
11634                 flatten(state, first, jmp2);
11635                 flatten(state, first, middle);
11636                 statement(state, first);
11637                 flatten(state, first, end);
11638         }
11639         else {
11640                 flatten(state, first, middle);
11641         }
11642 }
11643
11644 static void for_statement(struct compile_state *state, struct triple *first)
11645 {
11646         struct triple *head, *test, *tail, *jmp1, *jmp2, *end;
11647         struct triple *label1, *label2, *label3;
11648         struct hash_entry *ident;
11649
11650         eat(state, TOK_FOR);
11651         eat(state, TOK_LPAREN);
11652         head = test = tail = jmp1 = jmp2 = 0;
11653         if (peek(state) != TOK_SEMI) {
11654                 head = expr(state);
11655         } 
11656         eat(state, TOK_SEMI);
11657         if (peek(state) != TOK_SEMI) {
11658                 test = expr(state);
11659                 bool(state, test);
11660                 test = ltrue_expr(state, read_expr(state, test));
11661         }
11662         eat(state, TOK_SEMI);
11663         if (peek(state) != TOK_RPAREN) {
11664                 tail = expr(state);
11665         }
11666         eat(state, TOK_RPAREN);
11667         /* Generate the needed pieces */
11668         label1 = label(state);
11669         label2 = label(state);
11670         label3 = label(state);
11671         if (test) {
11672                 jmp1 = branch(state, label3, 0);
11673                 jmp2 = branch(state, label1, test);
11674         }
11675         else {
11676                 jmp2 = branch(state, label1, 0);
11677         }
11678         end = label(state);
11679         /* Remember where break and continue go */
11680         start_scope(state);
11681         ident = state->i_break;
11682         symbol(state, ident, &ident->sym_ident, end, end->type);
11683         ident = state->i_continue;
11684         symbol(state, ident, &ident->sym_ident, label2, label2->type);
11685         /* Now include the body */
11686         flatten(state, first, head);
11687         flatten(state, first, jmp1);
11688         flatten(state, first, label1);
11689         statement(state, first);
11690         flatten(state, first, label2);
11691         flatten(state, first, tail);
11692         flatten(state, first, label3);
11693         flatten(state, first, test);
11694         flatten(state, first, jmp2);
11695         flatten(state, first, end);
11696         /* Cleanup the break/continue scope */
11697         end_scope(state);
11698 }
11699
11700 static void while_statement(struct compile_state *state, struct triple *first)
11701 {
11702         struct triple *label1, *test, *label2, *jmp1, *jmp2, *end;
11703         struct hash_entry *ident;
11704         eat(state, TOK_WHILE);
11705         eat(state, TOK_LPAREN);
11706         test = expr(state);
11707         bool(state, test);
11708         test = ltrue_expr(state, read_expr(state, test));
11709         eat(state, TOK_RPAREN);
11710         /* Generate the needed pieces */
11711         label1 = label(state);
11712         label2 = label(state);
11713         jmp1 = branch(state, label2, 0);
11714         jmp2 = branch(state, label1, test);
11715         end = label(state);
11716         /* Remember where break and continue go */
11717         start_scope(state);
11718         ident = state->i_break;
11719         symbol(state, ident, &ident->sym_ident, end, end->type);
11720         ident = state->i_continue;
11721         symbol(state, ident, &ident->sym_ident, label2, label2->type);
11722         /* Thread them together */
11723         flatten(state, first, jmp1);
11724         flatten(state, first, label1);
11725         statement(state, first);
11726         flatten(state, first, label2);
11727         flatten(state, first, test);
11728         flatten(state, first, jmp2);
11729         flatten(state, first, end);
11730         /* Cleanup the break/continue scope */
11731         end_scope(state);
11732 }
11733
11734 static void do_statement(struct compile_state *state, struct triple *first)
11735 {
11736         struct triple *label1, *label2, *test, *end;
11737         struct hash_entry *ident;
11738         eat(state, TOK_DO);
11739         /* Generate the needed pieces */
11740         label1 = label(state);
11741         label2 = label(state);
11742         end = label(state);
11743         /* Remember where break and continue go */
11744         start_scope(state);
11745         ident = state->i_break;
11746         symbol(state, ident, &ident->sym_ident, end, end->type);
11747         ident = state->i_continue;
11748         symbol(state, ident, &ident->sym_ident, label2, label2->type);
11749         /* Now include the body */
11750         flatten(state, first, label1);
11751         statement(state, first);
11752         /* Cleanup the break/continue scope */
11753         end_scope(state);
11754         /* Eat the rest of the loop */
11755         eat(state, TOK_WHILE);
11756         eat(state, TOK_LPAREN);
11757         test = read_expr(state, expr(state));
11758         bool(state, test);
11759         eat(state, TOK_RPAREN);
11760         eat(state, TOK_SEMI);
11761         /* Thread the pieces together */
11762         test = ltrue_expr(state, test);
11763         flatten(state, first, label2);
11764         flatten(state, first, test);
11765         flatten(state, first, branch(state, label1, test));
11766         flatten(state, first, end);
11767 }
11768
11769
11770 static void return_statement(struct compile_state *state, struct triple *first)
11771 {
11772         struct triple *jmp, *mv, *dest, *var, *val;
11773         int last;
11774         eat(state, TOK_RETURN);
11775
11776 #warning "FIXME implement a more general excess branch elimination"
11777         val = 0;
11778         /* If we have a return value do some more work */
11779         if (peek(state) != TOK_SEMI) {
11780                 val = read_expr(state, expr(state));
11781         }
11782         eat(state, TOK_SEMI);
11783
11784         /* See if this last statement in a function */
11785         last = ((peek(state) == TOK_RBRACE) && 
11786                 (state->scope_depth == GLOBAL_SCOPE_DEPTH +2));
11787
11788         /* Find the return variable */
11789         var = fresult(state, state->main_function);
11790
11791         /* Find the return destination */
11792         dest = state->i_return->sym_ident->def;
11793         mv = jmp = 0;
11794         /* If needed generate a jump instruction */
11795         if (!last) {
11796                 jmp = branch(state, dest, 0);
11797         }
11798         /* If needed generate an assignment instruction */
11799         if (val) {
11800                 mv = write_expr(state, deref_index(state, var, 1), val);
11801         }
11802         /* Now put the code together */
11803         if (mv) {
11804                 flatten(state, first, mv);
11805                 flatten(state, first, jmp);
11806         }
11807         else if (jmp) {
11808                 flatten(state, first, jmp);
11809         }
11810 }
11811
11812 static void break_statement(struct compile_state *state, struct triple *first)
11813 {
11814         struct triple *dest;
11815         eat(state, TOK_BREAK);
11816         eat(state, TOK_SEMI);
11817         if (!state->i_break->sym_ident) {
11818                 error(state, 0, "break statement not within loop or switch");
11819         }
11820         dest = state->i_break->sym_ident->def;
11821         flatten(state, first, branch(state, dest, 0));
11822 }
11823
11824 static void continue_statement(struct compile_state *state, struct triple *first)
11825 {
11826         struct triple *dest;
11827         eat(state, TOK_CONTINUE);
11828         eat(state, TOK_SEMI);
11829         if (!state->i_continue->sym_ident) {
11830                 error(state, 0, "continue statement outside of a loop");
11831         }
11832         dest = state->i_continue->sym_ident->def;
11833         flatten(state, first, branch(state, dest, 0));
11834 }
11835
11836 static void goto_statement(struct compile_state *state, struct triple *first)
11837 {
11838         struct hash_entry *ident;
11839         eat(state, TOK_GOTO);
11840         ident = eat(state, TOK_IDENT)->ident;
11841         if (!ident->sym_label) {
11842                 /* If this is a forward branch allocate the label now,
11843                  * it will be flattend in the appropriate location later.
11844                  */
11845                 struct triple *ins;
11846                 ins = label(state);
11847                 label_symbol(state, ident, ins, FUNCTION_SCOPE_DEPTH);
11848         }
11849         eat(state, TOK_SEMI);
11850
11851         flatten(state, first, branch(state, ident->sym_label->def, 0));
11852 }
11853
11854 static void labeled_statement(struct compile_state *state, struct triple *first)
11855 {
11856         struct triple *ins;
11857         struct hash_entry *ident;
11858
11859         ident = eat(state, TOK_IDENT)->ident;
11860         if (ident->sym_label && ident->sym_label->def) {
11861                 ins = ident->sym_label->def;
11862                 put_occurance(ins->occurance);
11863                 ins->occurance = new_occurance(state);
11864         }
11865         else {
11866                 ins = label(state);
11867                 label_symbol(state, ident, ins, FUNCTION_SCOPE_DEPTH);
11868         }
11869         if (ins->id & TRIPLE_FLAG_FLATTENED) {
11870                 error(state, 0, "label %s already defined", ident->name);
11871         }
11872         flatten(state, first, ins);
11873
11874         eat(state, TOK_COLON);
11875         statement(state, first);
11876 }
11877
11878 static void switch_statement(struct compile_state *state, struct triple *first)
11879 {
11880         struct triple *value, *top, *end, *dbranch;
11881         struct hash_entry *ident;
11882
11883         /* See if we have a valid switch statement */
11884         eat(state, TOK_SWITCH);
11885         eat(state, TOK_LPAREN);
11886         value = expr(state);
11887         integral(state, value);
11888         value = read_expr(state, value);
11889         eat(state, TOK_RPAREN);
11890         /* Generate the needed pieces */
11891         top = label(state);
11892         end = label(state);
11893         dbranch = branch(state, end, 0);
11894         /* Remember where case branches and break goes */
11895         start_scope(state);
11896         ident = state->i_switch;
11897         symbol(state, ident, &ident->sym_ident, value, value->type);
11898         ident = state->i_case;
11899         symbol(state, ident, &ident->sym_ident, top, top->type);
11900         ident = state->i_break;
11901         symbol(state, ident, &ident->sym_ident, end, end->type);
11902         ident = state->i_default;
11903         symbol(state, ident, &ident->sym_ident, dbranch, dbranch->type);
11904         /* Thread them together */
11905         flatten(state, first, value);
11906         flatten(state, first, top);
11907         flatten(state, first, dbranch);
11908         statement(state, first);
11909         flatten(state, first, end);
11910         /* Cleanup the switch scope */
11911         end_scope(state);
11912 }
11913
11914 static void case_statement(struct compile_state *state, struct triple *first)
11915 {
11916         struct triple *cvalue, *dest, *test, *jmp;
11917         struct triple *ptr, *value, *top, *dbranch;
11918
11919         /* See if w have a valid case statement */
11920         eat(state, TOK_CASE);
11921         cvalue = constant_expr(state);
11922         integral(state, cvalue);
11923         if (cvalue->op != OP_INTCONST) {
11924                 error(state, 0, "integer constant expected");
11925         }
11926         eat(state, TOK_COLON);
11927         if (!state->i_case->sym_ident) {
11928                 error(state, 0, "case statement not within a switch");
11929         }
11930
11931         /* Lookup the interesting pieces */
11932         top = state->i_case->sym_ident->def;
11933         value = state->i_switch->sym_ident->def;
11934         dbranch = state->i_default->sym_ident->def;
11935
11936         /* See if this case label has already been used */
11937         for(ptr = top; ptr != dbranch; ptr = ptr->next) {
11938                 if (ptr->op != OP_EQ) {
11939                         continue;
11940                 }
11941                 if (RHS(ptr, 1)->u.cval == cvalue->u.cval) {
11942                         error(state, 0, "duplicate case %d statement",
11943                                 cvalue->u.cval);
11944                 }
11945         }
11946         /* Generate the needed pieces */
11947         dest = label(state);
11948         test = triple(state, OP_EQ, &int_type, value, cvalue);
11949         jmp = branch(state, dest, test);
11950         /* Thread the pieces together */
11951         flatten(state, dbranch, test);
11952         flatten(state, dbranch, jmp);
11953         flatten(state, dbranch, label(state));
11954         flatten(state, first, dest);
11955         statement(state, first);
11956 }
11957
11958 static void default_statement(struct compile_state *state, struct triple *first)
11959 {
11960         struct triple *dest;
11961         struct triple *dbranch, *end;
11962
11963         /* See if we have a valid default statement */
11964         eat(state, TOK_DEFAULT);
11965         eat(state, TOK_COLON);
11966
11967         if (!state->i_case->sym_ident) {
11968                 error(state, 0, "default statement not within a switch");
11969         }
11970
11971         /* Lookup the interesting pieces */
11972         dbranch = state->i_default->sym_ident->def;
11973         end = state->i_break->sym_ident->def;
11974
11975         /* See if a default statement has already happened */
11976         if (TARG(dbranch, 0) != end) {
11977                 error(state, 0, "duplicate default statement");
11978         }
11979
11980         /* Generate the needed pieces */
11981         dest = label(state);
11982
11983         /* Blame the branch on the default statement */
11984         put_occurance(dbranch->occurance);
11985         dbranch->occurance = new_occurance(state);
11986
11987         /* Thread the pieces together */
11988         TARG(dbranch, 0) = dest;
11989         use_triple(dest, dbranch);
11990         flatten(state, first, dest);
11991         statement(state, first);
11992 }
11993
11994 static void asm_statement(struct compile_state *state, struct triple *first)
11995 {
11996         struct asm_info *info;
11997         struct {
11998                 struct triple *constraint;
11999                 struct triple *expr;
12000         } out_param[MAX_LHS], in_param[MAX_RHS], clob_param[MAX_LHS];
12001         struct triple *def, *asm_str;
12002         int out, in, clobbers, more, colons, i;
12003         int flags;
12004
12005         flags = 0;
12006         eat(state, TOK_ASM);
12007         /* For now ignore the qualifiers */
12008         switch(peek(state)) {
12009         case TOK_CONST:
12010                 eat(state, TOK_CONST);
12011                 break;
12012         case TOK_VOLATILE:
12013                 eat(state, TOK_VOLATILE);
12014                 flags |= TRIPLE_FLAG_VOLATILE;
12015                 break;
12016         }
12017         eat(state, TOK_LPAREN);
12018         asm_str = string_constant(state);
12019
12020         colons = 0;
12021         out = in = clobbers = 0;
12022         /* Outputs */
12023         if ((colons == 0) && (peek(state) == TOK_COLON)) {
12024                 eat(state, TOK_COLON);
12025                 colons++;
12026                 more = (peek(state) == TOK_LIT_STRING);
12027                 while(more) {
12028                         struct triple *var;
12029                         struct triple *constraint;
12030                         char *str;
12031                         more = 0;
12032                         if (out > MAX_LHS) {
12033                                 error(state, 0, "Maximum output count exceeded.");
12034                         }
12035                         constraint = string_constant(state);
12036                         str = constraint->u.blob;
12037                         if (str[0] != '=') {
12038                                 error(state, 0, "Output constraint does not start with =");
12039                         }
12040                         constraint->u.blob = str + 1;
12041                         eat(state, TOK_LPAREN);
12042                         var = conditional_expr(state);
12043                         eat(state, TOK_RPAREN);
12044
12045                         lvalue(state, var);
12046                         out_param[out].constraint = constraint;
12047                         out_param[out].expr       = var;
12048                         if (peek(state) == TOK_COMMA) {
12049                                 eat(state, TOK_COMMA);
12050                                 more = 1;
12051                         }
12052                         out++;
12053                 }
12054         }
12055         /* Inputs */
12056         if ((colons == 1) && (peek(state) == TOK_COLON)) {
12057                 eat(state, TOK_COLON);
12058                 colons++;
12059                 more = (peek(state) == TOK_LIT_STRING);
12060                 while(more) {
12061                         struct triple *val;
12062                         struct triple *constraint;
12063                         char *str;
12064                         more = 0;
12065                         if (in > MAX_RHS) {
12066                                 error(state, 0, "Maximum input count exceeded.");
12067                         }
12068                         constraint = string_constant(state);
12069                         str = constraint->u.blob;
12070                         if (digitp(str[0] && str[1] == '\0')) {
12071                                 int val;
12072                                 val = digval(str[0]);
12073                                 if ((val < 0) || (val >= out)) {
12074                                         error(state, 0, "Invalid input constraint %d", val);
12075                                 }
12076                         }
12077                         eat(state, TOK_LPAREN);
12078                         val = conditional_expr(state);
12079                         eat(state, TOK_RPAREN);
12080
12081                         in_param[in].constraint = constraint;
12082                         in_param[in].expr       = val;
12083                         if (peek(state) == TOK_COMMA) {
12084                                 eat(state, TOK_COMMA);
12085                                 more = 1;
12086                         }
12087                         in++;
12088                 }
12089         }
12090
12091         /* Clobber */
12092         if ((colons == 2) && (peek(state) == TOK_COLON)) {
12093                 eat(state, TOK_COLON);
12094                 colons++;
12095                 more = (peek(state) == TOK_LIT_STRING);
12096                 while(more) {
12097                         struct triple *clobber;
12098                         more = 0;
12099                         if ((clobbers + out) > MAX_LHS) {
12100                                 error(state, 0, "Maximum clobber limit exceeded.");
12101                         }
12102                         clobber = string_constant(state);
12103
12104                         clob_param[clobbers].constraint = clobber;
12105                         if (peek(state) == TOK_COMMA) {
12106                                 eat(state, TOK_COMMA);
12107                                 more = 1;
12108                         }
12109                         clobbers++;
12110                 }
12111         }
12112         eat(state, TOK_RPAREN);
12113         eat(state, TOK_SEMI);
12114
12115
12116         info = xcmalloc(sizeof(*info), "asm_info");
12117         info->str = asm_str->u.blob;
12118         free_triple(state, asm_str);
12119
12120         def = new_triple(state, OP_ASM, &void_type, clobbers + out, in);
12121         def->u.ainfo = info;
12122         def->id |= flags;
12123
12124         /* Find the register constraints */
12125         for(i = 0; i < out; i++) {
12126                 struct triple *constraint;
12127                 constraint = out_param[i].constraint;
12128                 info->tmpl.lhs[i] = arch_reg_constraint(state, 
12129                         out_param[i].expr->type, constraint->u.blob);
12130                 free_triple(state, constraint);
12131         }
12132         for(; i - out < clobbers; i++) {
12133                 struct triple *constraint;
12134                 constraint = clob_param[i - out].constraint;
12135                 info->tmpl.lhs[i] = arch_reg_clobber(state, constraint->u.blob);
12136                 free_triple(state, constraint);
12137         }
12138         for(i = 0; i < in; i++) {
12139                 struct triple *constraint;
12140                 const char *str;
12141                 constraint = in_param[i].constraint;
12142                 str = constraint->u.blob;
12143                 if (digitp(str[0]) && str[1] == '\0') {
12144                         struct reg_info cinfo;
12145                         int val;
12146                         val = digval(str[0]);
12147                         cinfo.reg = info->tmpl.lhs[val].reg;
12148                         cinfo.regcm = arch_type_to_regcm(state, in_param[i].expr->type);
12149                         cinfo.regcm &= info->tmpl.lhs[val].regcm;
12150                         if (cinfo.reg == REG_UNSET) {
12151                                 cinfo.reg = REG_VIRT0 + val;
12152                         }
12153                         if (cinfo.regcm == 0) {
12154                                 error(state, 0, "No registers for %d", val);
12155                         }
12156                         info->tmpl.lhs[val] = cinfo;
12157                         info->tmpl.rhs[i]   = cinfo;
12158                                 
12159                 } else {
12160                         info->tmpl.rhs[i] = arch_reg_constraint(state, 
12161                                 in_param[i].expr->type, str);
12162                 }
12163                 free_triple(state, constraint);
12164         }
12165
12166         /* Now build the helper expressions */
12167         for(i = 0; i < in; i++) {
12168                 RHS(def, i) = read_expr(state, in_param[i].expr);
12169         }
12170         flatten(state, first, def);
12171         for(i = 0; i < (out + clobbers); i++) {
12172                 struct type *type;
12173                 struct triple *piece;
12174                 if (i < out) {
12175                         type = out_param[i].expr->type;
12176                 } else {
12177                         size_t size = arch_reg_size(info->tmpl.lhs[i].reg);
12178                         if (size >= SIZEOF_LONG) {
12179                                 type = &ulong_type;
12180                         } 
12181                         else if (size >= SIZEOF_INT) {
12182                                 type = &uint_type;
12183                         }
12184                         else if (size >= SIZEOF_SHORT) {
12185                                 type = &ushort_type;
12186                         }
12187                         else {
12188                                 type = &uchar_type;
12189                         }
12190                 }
12191                 piece = triple(state, OP_PIECE, type, def, 0);
12192                 piece->u.cval = i;
12193                 LHS(def, i) = piece;
12194                 flatten(state, first, piece);
12195         }
12196         /* And write the helpers to their destinations */
12197         for(i = 0; i < out; i++) {
12198                 struct triple *piece;
12199                 piece = LHS(def, i);
12200                 flatten(state, first,
12201                         write_expr(state, out_param[i].expr, piece));
12202         }
12203 }
12204
12205
12206 static int isdecl(int tok)
12207 {
12208         switch(tok) {
12209         case TOK_AUTO:
12210         case TOK_REGISTER:
12211         case TOK_STATIC:
12212         case TOK_EXTERN:
12213         case TOK_TYPEDEF:
12214         case TOK_CONST:
12215         case TOK_RESTRICT:
12216         case TOK_VOLATILE:
12217         case TOK_VOID:
12218         case TOK_CHAR:
12219         case TOK_SHORT:
12220         case TOK_INT:
12221         case TOK_LONG:
12222         case TOK_FLOAT:
12223         case TOK_DOUBLE:
12224         case TOK_SIGNED:
12225         case TOK_UNSIGNED:
12226         case TOK_STRUCT:
12227         case TOK_UNION:
12228         case TOK_ENUM:
12229         case TOK_TYPE_NAME: /* typedef name */
12230                 return 1;
12231         default:
12232                 return 0;
12233         }
12234 }
12235
12236 static void compound_statement(struct compile_state *state, struct triple *first)
12237 {
12238         eat(state, TOK_LBRACE);
12239         start_scope(state);
12240
12241         /* statement-list opt */
12242         while (peek(state) != TOK_RBRACE) {
12243                 statement(state, first);
12244         }
12245         end_scope(state);
12246         eat(state, TOK_RBRACE);
12247 }
12248
12249 static void statement(struct compile_state *state, struct triple *first)
12250 {
12251         int tok;
12252         tok = peek(state);
12253         if (tok == TOK_LBRACE) {
12254                 compound_statement(state, first);
12255         }
12256         else if (tok == TOK_IF) {
12257                 if_statement(state, first); 
12258         }
12259         else if (tok == TOK_FOR) {
12260                 for_statement(state, first);
12261         }
12262         else if (tok == TOK_WHILE) {
12263                 while_statement(state, first);
12264         }
12265         else if (tok == TOK_DO) {
12266                 do_statement(state, first);
12267         }
12268         else if (tok == TOK_RETURN) {
12269                 return_statement(state, first);
12270         }
12271         else if (tok == TOK_BREAK) {
12272                 break_statement(state, first);
12273         }
12274         else if (tok == TOK_CONTINUE) {
12275                 continue_statement(state, first);
12276         }
12277         else if (tok == TOK_GOTO) {
12278                 goto_statement(state, first);
12279         }
12280         else if (tok == TOK_SWITCH) {
12281                 switch_statement(state, first);
12282         }
12283         else if (tok == TOK_ASM) {
12284                 asm_statement(state, first);
12285         }
12286         else if ((tok == TOK_IDENT) && (peek2(state) == TOK_COLON)) {
12287                 labeled_statement(state, first); 
12288         }
12289         else if (tok == TOK_CASE) {
12290                 case_statement(state, first);
12291         }
12292         else if (tok == TOK_DEFAULT) {
12293                 default_statement(state, first);
12294         }
12295         else if (isdecl(tok)) {
12296                 /* This handles C99 intermixing of statements and decls */
12297                 decl(state, first);
12298         }
12299         else {
12300                 expr_statement(state, first);
12301         }
12302 }
12303
12304 static struct type *param_decl(struct compile_state *state)
12305 {
12306         struct type *type;
12307         struct hash_entry *ident;
12308         /* Cheat so the declarator will know we are not global */
12309         start_scope(state); 
12310         ident = 0;
12311         type = decl_specifiers(state);
12312         type = declarator(state, type, &ident, 0);
12313         type->field_ident = ident;
12314         end_scope(state);
12315         return type;
12316 }
12317
12318 static struct type *param_type_list(struct compile_state *state, struct type *type)
12319 {
12320         struct type *ftype, **next;
12321         ftype = new_type(TYPE_FUNCTION | (type->type & STOR_MASK), type, param_decl(state));
12322         next = &ftype->right;
12323         ftype->elements = 1;
12324         while(peek(state) == TOK_COMMA) {
12325                 eat(state, TOK_COMMA);
12326                 if (peek(state) == TOK_DOTS) {
12327                         eat(state, TOK_DOTS);
12328                         error(state, 0, "variadic functions not supported");
12329                 }
12330                 else {
12331                         *next = new_type(TYPE_PRODUCT, *next, param_decl(state));
12332                         next = &((*next)->right);
12333                         ftype->elements++;
12334                 }
12335         }
12336         return ftype;
12337 }
12338
12339 static struct type *type_name(struct compile_state *state)
12340 {
12341         struct type *type;
12342         type = specifier_qualifier_list(state);
12343         /* abstract-declarator (may consume no tokens) */
12344         type = declarator(state, type, 0, 0);
12345         return type;
12346 }
12347
12348 static struct type *direct_declarator(
12349         struct compile_state *state, struct type *type, 
12350         struct hash_entry **pident, int need_ident)
12351 {
12352         struct hash_entry *ident;
12353         struct type *outer;
12354         int op;
12355         outer = 0;
12356         arrays_complete(state, type);
12357         switch(peek(state)) {
12358         case TOK_IDENT:
12359                 ident = eat(state, TOK_IDENT)->ident;
12360                 if (!ident) {
12361                         error(state, 0, "Unexpected identifier found");
12362                 }
12363                 /* The name of what we are declaring */
12364                 *pident = ident;
12365                 break;
12366         case TOK_LPAREN:
12367                 eat(state, TOK_LPAREN);
12368                 outer = declarator(state, type, pident, need_ident);
12369                 eat(state, TOK_RPAREN);
12370                 break;
12371         default:
12372                 if (need_ident) {
12373                         error(state, 0, "Identifier expected");
12374                 }
12375                 break;
12376         }
12377         do {
12378                 op = 1;
12379                 arrays_complete(state, type);
12380                 switch(peek(state)) {
12381                 case TOK_LPAREN:
12382                         eat(state, TOK_LPAREN);
12383                         type = param_type_list(state, type);
12384                         eat(state, TOK_RPAREN);
12385                         break;
12386                 case TOK_LBRACKET:
12387                 {
12388                         unsigned int qualifiers;
12389                         struct triple *value;
12390                         value = 0;
12391                         eat(state, TOK_LBRACKET);
12392                         if (peek(state) != TOK_RBRACKET) {
12393                                 value = constant_expr(state);
12394                                 integral(state, value);
12395                         }
12396                         eat(state, TOK_RBRACKET);
12397
12398                         qualifiers = type->type & (QUAL_MASK | STOR_MASK);
12399                         type = new_type(TYPE_ARRAY | qualifiers, type, 0);
12400                         if (value) {
12401                                 type->elements = value->u.cval;
12402                                 free_triple(state, value);
12403                         } else {
12404                                 type->elements = ELEMENT_COUNT_UNSPECIFIED;
12405                                 op = 0;
12406                         }
12407                 }
12408                         break;
12409                 default:
12410                         op = 0;
12411                         break;
12412                 }
12413         } while(op);
12414         if (outer) {
12415                 struct type *inner;
12416                 arrays_complete(state, type);
12417                 FINISHME();
12418                 for(inner = outer; inner->left; inner = inner->left)
12419                         ;
12420                 inner->left = type;
12421                 type = outer;
12422         }
12423         return type;
12424 }
12425
12426 static struct type *declarator(
12427         struct compile_state *state, struct type *type, 
12428         struct hash_entry **pident, int need_ident)
12429 {
12430         while(peek(state) == TOK_STAR) {
12431                 eat(state, TOK_STAR);
12432                 type = new_type(TYPE_POINTER | (type->type & STOR_MASK), type, 0);
12433         }
12434         type = direct_declarator(state, type, pident, need_ident);
12435         return type;
12436 }
12437
12438 static struct type *typedef_name(
12439         struct compile_state *state, unsigned int specifiers)
12440 {
12441         struct hash_entry *ident;
12442         struct type *type;
12443         ident = eat(state, TOK_TYPE_NAME)->ident;
12444         type = ident->sym_ident->type;
12445         specifiers |= type->type & QUAL_MASK;
12446         if ((specifiers & (STOR_MASK | QUAL_MASK)) != 
12447                 (type->type & (STOR_MASK | QUAL_MASK))) {
12448                 type = clone_type(specifiers, type);
12449         }
12450         return type;
12451 }
12452
12453 static struct type *enum_specifier(
12454         struct compile_state *state, unsigned int spec)
12455 {
12456         struct hash_entry *ident;
12457         ulong_t base;
12458         int tok;
12459         struct type *enum_type;
12460         enum_type = 0;
12461         ident = 0;
12462         eat(state, TOK_ENUM);
12463         tok = peek(state);
12464         if ((tok == TOK_IDENT) || (tok == TOK_ENUM_CONST) || (tok == TOK_TYPE_NAME)) {
12465                 ident = eat(state, tok)->ident;
12466         }
12467         base = 0;
12468         if (!ident || (peek(state) == TOK_LBRACE)) {
12469                 struct type **next;
12470                 eat(state, TOK_LBRACE);
12471                 enum_type = new_type(TYPE_ENUM | spec, 0, 0);
12472                 enum_type->type_ident = ident;
12473                 next = &enum_type->right;
12474                 do {
12475                         struct hash_entry *eident;
12476                         struct triple *value;
12477                         struct type *entry;
12478                         eident = eat(state, TOK_IDENT)->ident;
12479                         if (eident->sym_ident) {
12480                                 error(state, 0, "%s already declared", 
12481                                         eident->name);
12482                         }
12483                         eident->tok = TOK_ENUM_CONST;
12484                         if (peek(state) == TOK_EQ) {
12485                                 struct triple *val;
12486                                 eat(state, TOK_EQ);
12487                                 val = constant_expr(state);
12488                                 integral(state, val);
12489                                 base = val->u.cval;
12490                         }
12491                         value = int_const(state, &int_type, base);
12492                         symbol(state, eident, &eident->sym_ident, value, &int_type);
12493                         entry = new_type(TYPE_LIST, 0, 0);
12494                         entry->field_ident = eident;
12495                         *next = entry;
12496                         next = &entry->right;
12497                         base += 1;
12498                         if (peek(state) == TOK_COMMA) {
12499                                 eat(state, TOK_COMMA);
12500                         }
12501                 } while(peek(state) != TOK_RBRACE);
12502                 eat(state, TOK_RBRACE);
12503                 if (ident) {
12504                         symbol(state, ident, &ident->sym_tag, 0, enum_type);
12505                 }
12506         }
12507         if (ident && ident->sym_tag &&
12508                 ident->sym_tag->type &&
12509                 ((ident->sym_tag->type->type & TYPE_MASK) == TYPE_ENUM)) {
12510                 enum_type = clone_type(spec, ident->sym_tag->type);
12511         }
12512         else if (ident && !enum_type) {
12513                 error(state, 0, "enum %s undeclared", ident->name);
12514         }
12515         return enum_type;
12516 }
12517
12518 static struct type *struct_declarator(
12519         struct compile_state *state, struct type *type, struct hash_entry **ident)
12520 {
12521         if (peek(state) != TOK_COLON) {
12522                 type = declarator(state, type, ident, 1);
12523         }
12524         if (peek(state) == TOK_COLON) {
12525                 struct triple *value;
12526                 eat(state, TOK_COLON);
12527                 value = constant_expr(state);
12528                 if (value->op != OP_INTCONST) {
12529                         error(state, 0, "Invalid constant expression");
12530                 }
12531                 if (value->u.cval > size_of(state, type)) {
12532                         error(state, 0, "bitfield larger than base type");
12533                 }
12534                 if (!TYPE_INTEGER(type->type) || ((type->type & TYPE_MASK) == TYPE_BITFIELD)) {
12535                         error(state, 0, "bitfield base not an integer type");
12536                 }
12537                 type = new_type(TYPE_BITFIELD, type, 0);
12538                 type->elements = value->u.cval;
12539         }
12540         return type;
12541 }
12542
12543 static struct type *struct_or_union_specifier(
12544         struct compile_state *state, unsigned int spec)
12545 {
12546         struct type *struct_type;
12547         struct hash_entry *ident;
12548         unsigned int type_main;
12549         unsigned int type_join;
12550         int tok;
12551         struct_type = 0;
12552         ident = 0;
12553         switch(peek(state)) {
12554         case TOK_STRUCT:
12555                 eat(state, TOK_STRUCT);
12556                 type_main = TYPE_STRUCT;
12557                 type_join = TYPE_PRODUCT;
12558                 break;
12559         case TOK_UNION:
12560                 eat(state, TOK_UNION);
12561                 type_main = TYPE_UNION;
12562                 type_join = TYPE_OVERLAP;
12563                 break;
12564         default:
12565                 eat(state, TOK_STRUCT);
12566                 type_main = TYPE_STRUCT;
12567                 type_join = TYPE_PRODUCT;
12568                 break;
12569         }
12570         tok = peek(state);
12571         if ((tok == TOK_IDENT) || (tok == TOK_ENUM_CONST) || (tok == TOK_TYPE_NAME)) {
12572                 ident = eat(state, tok)->ident;
12573         }
12574         if (!ident || (peek(state) == TOK_LBRACE)) {
12575                 ulong_t elements;
12576                 struct type **next;
12577                 elements = 0;
12578                 eat(state, TOK_LBRACE);
12579                 next = &struct_type;
12580                 do {
12581                         struct type *base_type;
12582                         int done;
12583                         base_type = specifier_qualifier_list(state);
12584                         do {
12585                                 struct type *type;
12586                                 struct hash_entry *fident;
12587                                 done = 1;
12588                                 type = struct_declarator(state, base_type, &fident);
12589                                 elements++;
12590                                 if (peek(state) == TOK_COMMA) {
12591                                         done = 0;
12592                                         eat(state, TOK_COMMA);
12593                                 }
12594                                 type = clone_type(0, type);
12595                                 type->field_ident = fident;
12596                                 if (*next) {
12597                                         *next = new_type(type_join, *next, type);
12598                                         next = &((*next)->right);
12599                                 } else {
12600                                         *next = type;
12601                                 }
12602                         } while(!done);
12603                         eat(state, TOK_SEMI);
12604                 } while(peek(state) != TOK_RBRACE);
12605                 eat(state, TOK_RBRACE);
12606                 struct_type = new_type(type_main | spec, struct_type, 0);
12607                 struct_type->type_ident = ident;
12608                 struct_type->elements = elements;
12609                 if (ident) {
12610                         symbol(state, ident, &ident->sym_tag, 0, struct_type);
12611                 }
12612         }
12613         if (ident && ident->sym_tag && 
12614                 ident->sym_tag->type && 
12615                 ((ident->sym_tag->type->type & TYPE_MASK) == type_main)) {
12616                 struct_type = clone_type(spec, ident->sym_tag->type);
12617         }
12618         else if (ident && !struct_type) {
12619                 error(state, 0, "%s %s undeclared", 
12620                         (type_main == TYPE_STRUCT)?"struct" : "union",
12621                         ident->name);
12622         }
12623         return struct_type;
12624 }
12625
12626 static unsigned int storage_class_specifier_opt(struct compile_state *state)
12627 {
12628         unsigned int specifiers;
12629         switch(peek(state)) {
12630         case TOK_AUTO:
12631                 eat(state, TOK_AUTO);
12632                 specifiers = STOR_AUTO;
12633                 break;
12634         case TOK_REGISTER:
12635                 eat(state, TOK_REGISTER);
12636                 specifiers = STOR_REGISTER;
12637                 break;
12638         case TOK_STATIC:
12639                 eat(state, TOK_STATIC);
12640                 specifiers = STOR_STATIC;
12641                 break;
12642         case TOK_EXTERN:
12643                 eat(state, TOK_EXTERN);
12644                 specifiers = STOR_EXTERN;
12645                 break;
12646         case TOK_TYPEDEF:
12647                 eat(state, TOK_TYPEDEF);
12648                 specifiers = STOR_TYPEDEF;
12649                 break;
12650         default:
12651                 if (state->scope_depth <= GLOBAL_SCOPE_DEPTH) {
12652                         specifiers = STOR_LOCAL;
12653                 }
12654                 else {
12655                         specifiers = STOR_AUTO;
12656                 }
12657         }
12658         return specifiers;
12659 }
12660
12661 static unsigned int function_specifier_opt(struct compile_state *state)
12662 {
12663         /* Ignore the inline keyword */
12664         unsigned int specifiers;
12665         specifiers = 0;
12666         switch(peek(state)) {
12667         case TOK_INLINE:
12668                 eat(state, TOK_INLINE);
12669                 specifiers = STOR_INLINE;
12670         }
12671         return specifiers;
12672 }
12673
12674 static unsigned int attrib(struct compile_state *state, unsigned int attributes)
12675 {
12676         int tok = peek(state);
12677         switch(tok) {
12678         case TOK_COMMA:
12679         case TOK_LPAREN:
12680                 /* The empty attribute ignore it */
12681                 break;
12682         case TOK_IDENT:
12683         case TOK_ENUM_CONST:
12684         case TOK_TYPE_NAME:
12685         {
12686                 struct hash_entry *ident;
12687                 ident = eat(state, TOK_IDENT)->ident;
12688
12689                 if (ident == state->i_noinline) {
12690                         if (attributes & ATTRIB_ALWAYS_INLINE) {
12691                                 error(state, 0, "both always_inline and noinline attribtes");
12692                         }
12693                         attributes |= ATTRIB_NOINLINE;
12694                 }
12695                 else if (ident == state->i_always_inline) {
12696                         if (attributes & ATTRIB_NOINLINE) {
12697                                 error(state, 0, "both noinline and always_inline attribtes");
12698                         }
12699                         attributes |= ATTRIB_ALWAYS_INLINE;
12700                 }
12701                 else {
12702                         error(state, 0, "Unknown attribute:%s", ident->name);
12703                 }
12704                 break;
12705         }
12706         default:
12707                 error(state, 0, "Unexpected token: %s\n", tokens[tok]);
12708                 break;
12709         }
12710         return attributes;
12711 }
12712
12713 static unsigned int attribute_list(struct compile_state *state, unsigned type)
12714 {
12715         type = attrib(state, type);
12716         while(peek(state) == TOK_COMMA) {
12717                 eat(state, TOK_COMMA);
12718                 type = attrib(state, type);
12719         }
12720         return type;
12721 }
12722
12723 static unsigned int attributes_opt(struct compile_state *state, unsigned type)
12724 {
12725         if (peek(state) == TOK_ATTRIBUTE) {
12726                 eat(state, TOK_ATTRIBUTE);
12727                 eat(state, TOK_LPAREN);
12728                 eat(state, TOK_LPAREN);
12729                 type = attribute_list(state, type);
12730                 eat(state, TOK_RPAREN);
12731                 eat(state, TOK_RPAREN);
12732         }
12733         return type;
12734 }
12735
12736 static unsigned int type_qualifiers(struct compile_state *state)
12737 {
12738         unsigned int specifiers;
12739         int done;
12740         done = 0;
12741         specifiers = QUAL_NONE;
12742         do {
12743                 switch(peek(state)) {
12744                 case TOK_CONST:
12745                         eat(state, TOK_CONST);
12746                         specifiers |= QUAL_CONST;
12747                         break;
12748                 case TOK_VOLATILE:
12749                         eat(state, TOK_VOLATILE);
12750                         specifiers |= QUAL_VOLATILE;
12751                         break;
12752                 case TOK_RESTRICT:
12753                         eat(state, TOK_RESTRICT);
12754                         specifiers |= QUAL_RESTRICT;
12755                         break;
12756                 default:
12757                         done = 1;
12758                         break;
12759                 }
12760         } while(!done);
12761         return specifiers;
12762 }
12763
12764 static struct type *type_specifier(
12765         struct compile_state *state, unsigned int spec)
12766 {
12767         struct type *type;
12768         int tok;
12769         type = 0;
12770         switch((tok = peek(state))) {
12771         case TOK_VOID:
12772                 eat(state, TOK_VOID);
12773                 type = new_type(TYPE_VOID | spec, 0, 0);
12774                 break;
12775         case TOK_CHAR:
12776                 eat(state, TOK_CHAR);
12777                 type = new_type(TYPE_CHAR | spec, 0, 0);
12778                 break;
12779         case TOK_SHORT:
12780                 eat(state, TOK_SHORT);
12781                 if (peek(state) == TOK_INT) {
12782                         eat(state, TOK_INT);
12783                 }
12784                 type = new_type(TYPE_SHORT | spec, 0, 0);
12785                 break;
12786         case TOK_INT:
12787                 eat(state, TOK_INT);
12788                 type = new_type(TYPE_INT | spec, 0, 0);
12789                 break;
12790         case TOK_LONG:
12791                 eat(state, TOK_LONG);
12792                 switch(peek(state)) {
12793                 case TOK_LONG:
12794                         eat(state, TOK_LONG);
12795                         error(state, 0, "long long not supported");
12796                         break;
12797                 case TOK_DOUBLE:
12798                         eat(state, TOK_DOUBLE);
12799                         error(state, 0, "long double not supported");
12800                         break;
12801                 case TOK_INT:
12802                         eat(state, TOK_INT);
12803                         type = new_type(TYPE_LONG | spec, 0, 0);
12804                         break;
12805                 default:
12806                         type = new_type(TYPE_LONG | spec, 0, 0);
12807                         break;
12808                 }
12809                 break;
12810         case TOK_FLOAT:
12811                 eat(state, TOK_FLOAT);
12812                 error(state, 0, "type float not supported");
12813                 break;
12814         case TOK_DOUBLE:
12815                 eat(state, TOK_DOUBLE);
12816                 error(state, 0, "type double not supported");
12817                 break;
12818         case TOK_SIGNED:
12819                 eat(state, TOK_SIGNED);
12820                 switch(peek(state)) {
12821                 case TOK_LONG:
12822                         eat(state, TOK_LONG);
12823                         switch(peek(state)) {
12824                         case TOK_LONG:
12825                                 eat(state, TOK_LONG);
12826                                 error(state, 0, "type long long not supported");
12827                                 break;
12828                         case TOK_INT:
12829                                 eat(state, TOK_INT);
12830                                 type = new_type(TYPE_LONG | spec, 0, 0);
12831                                 break;
12832                         default:
12833                                 type = new_type(TYPE_LONG | spec, 0, 0);
12834                                 break;
12835                         }
12836                         break;
12837                 case TOK_INT:
12838                         eat(state, TOK_INT);
12839                         type = new_type(TYPE_INT | spec, 0, 0);
12840                         break;
12841                 case TOK_SHORT:
12842                         eat(state, TOK_SHORT);
12843                         type = new_type(TYPE_SHORT | spec, 0, 0);
12844                         break;
12845                 case TOK_CHAR:
12846                         eat(state, TOK_CHAR);
12847                         type = new_type(TYPE_CHAR | spec, 0, 0);
12848                         break;
12849                 default:
12850                         type = new_type(TYPE_INT | spec, 0, 0);
12851                         break;
12852                 }
12853                 break;
12854         case TOK_UNSIGNED:
12855                 eat(state, TOK_UNSIGNED);
12856                 switch(peek(state)) {
12857                 case TOK_LONG:
12858                         eat(state, TOK_LONG);
12859                         switch(peek(state)) {
12860                         case TOK_LONG:
12861                                 eat(state, TOK_LONG);
12862                                 error(state, 0, "unsigned long long not supported");
12863                                 break;
12864                         case TOK_INT:
12865                                 eat(state, TOK_INT);
12866                                 type = new_type(TYPE_ULONG | spec, 0, 0);
12867                                 break;
12868                         default:
12869                                 type = new_type(TYPE_ULONG | spec, 0, 0);
12870                                 break;
12871                         }
12872                         break;
12873                 case TOK_INT:
12874                         eat(state, TOK_INT);
12875                         type = new_type(TYPE_UINT | spec, 0, 0);
12876                         break;
12877                 case TOK_SHORT:
12878                         eat(state, TOK_SHORT);
12879                         type = new_type(TYPE_USHORT | spec, 0, 0);
12880                         break;
12881                 case TOK_CHAR:
12882                         eat(state, TOK_CHAR);
12883                         type = new_type(TYPE_UCHAR | spec, 0, 0);
12884                         break;
12885                 default:
12886                         type = new_type(TYPE_UINT | spec, 0, 0);
12887                         break;
12888                 }
12889                 break;
12890                 /* struct or union specifier */
12891         case TOK_STRUCT:
12892         case TOK_UNION:
12893                 type = struct_or_union_specifier(state, spec);
12894                 break;
12895                 /* enum-spefifier */
12896         case TOK_ENUM:
12897                 type = enum_specifier(state, spec);
12898                 break;
12899                 /* typedef name */
12900         case TOK_TYPE_NAME:
12901                 type = typedef_name(state, spec);
12902                 break;
12903         default:
12904                 error(state, 0, "bad type specifier %s", 
12905                         tokens[tok]);
12906                 break;
12907         }
12908         return type;
12909 }
12910
12911 static int istype(int tok)
12912 {
12913         switch(tok) {
12914         case TOK_CONST:
12915         case TOK_RESTRICT:
12916         case TOK_VOLATILE:
12917         case TOK_VOID:
12918         case TOK_CHAR:
12919         case TOK_SHORT:
12920         case TOK_INT:
12921         case TOK_LONG:
12922         case TOK_FLOAT:
12923         case TOK_DOUBLE:
12924         case TOK_SIGNED:
12925         case TOK_UNSIGNED:
12926         case TOK_STRUCT:
12927         case TOK_UNION:
12928         case TOK_ENUM:
12929         case TOK_TYPE_NAME:
12930                 return 1;
12931         default:
12932                 return 0;
12933         }
12934 }
12935
12936
12937 static struct type *specifier_qualifier_list(struct compile_state *state)
12938 {
12939         struct type *type;
12940         unsigned int specifiers = 0;
12941
12942         /* type qualifiers */
12943         specifiers |= type_qualifiers(state);
12944
12945         /* type specifier */
12946         type = type_specifier(state, specifiers);
12947
12948         return type;
12949 }
12950
12951 static int isdecl_specifier(int tok)
12952 {
12953         switch(tok) {
12954                 /* storage class specifier */
12955         case TOK_AUTO:
12956         case TOK_REGISTER:
12957         case TOK_STATIC:
12958         case TOK_EXTERN:
12959         case TOK_TYPEDEF:
12960                 /* type qualifier */
12961         case TOK_CONST:
12962         case TOK_RESTRICT:
12963         case TOK_VOLATILE:
12964                 /* type specifiers */
12965         case TOK_VOID:
12966         case TOK_CHAR:
12967         case TOK_SHORT:
12968         case TOK_INT:
12969         case TOK_LONG:
12970         case TOK_FLOAT:
12971         case TOK_DOUBLE:
12972         case TOK_SIGNED:
12973         case TOK_UNSIGNED:
12974                 /* struct or union specifier */
12975         case TOK_STRUCT:
12976         case TOK_UNION:
12977                 /* enum-spefifier */
12978         case TOK_ENUM:
12979                 /* typedef name */
12980         case TOK_TYPE_NAME:
12981                 /* function specifiers */
12982         case TOK_INLINE:
12983                 return 1;
12984         default:
12985                 return 0;
12986         }
12987 }
12988
12989 static struct type *decl_specifiers(struct compile_state *state)
12990 {
12991         struct type *type;
12992         unsigned int specifiers;
12993         /* I am overly restrictive in the arragement of specifiers supported.
12994          * C is overly flexible in this department it makes interpreting
12995          * the parse tree difficult.
12996          */
12997         specifiers = 0;
12998
12999         /* storage class specifier */
13000         specifiers |= storage_class_specifier_opt(state);
13001
13002         /* function-specifier */
13003         specifiers |= function_specifier_opt(state);
13004
13005         /* attributes */
13006         specifiers |= attributes_opt(state, 0);
13007
13008         /* type qualifier */
13009         specifiers |= type_qualifiers(state);
13010
13011         /* type specifier */
13012         type = type_specifier(state, specifiers);
13013         return type;
13014 }
13015
13016 struct field_info {
13017         struct type *type;
13018         size_t offset;
13019 };
13020
13021 static struct field_info designator(struct compile_state *state, struct type *type)
13022 {
13023         int tok;
13024         struct field_info info;
13025         info.offset = ~0U;
13026         info.type = 0;
13027         do {
13028                 switch(peek(state)) {
13029                 case TOK_LBRACKET:
13030                 {
13031                         struct triple *value;
13032                         if ((type->type & TYPE_MASK) != TYPE_ARRAY) {
13033                                 error(state, 0, "Array designator not in array initializer");
13034                         }
13035                         eat(state, TOK_LBRACKET);
13036                         value = constant_expr(state);
13037                         eat(state, TOK_RBRACKET);
13038
13039                         info.type = type->left;
13040                         info.offset = value->u.cval * size_of(state, info.type);
13041                         break;
13042                 }
13043                 case TOK_DOT:
13044                 {
13045                         struct hash_entry *field;
13046                         if (((type->type & TYPE_MASK) != TYPE_STRUCT) &&
13047                                 ((type->type & TYPE_MASK) != TYPE_UNION))
13048                         {
13049                                 error(state, 0, "Struct designator not in struct initializer");
13050                         }
13051                         eat(state, TOK_DOT);
13052                         field = eat(state, TOK_IDENT)->ident;
13053                         info.offset = field_offset(state, type, field);
13054                         info.type   = field_type(state, type, field);
13055                         break;
13056                 }
13057                 default:
13058                         error(state, 0, "Invalid designator");
13059                 }
13060                 tok = peek(state);
13061         } while((tok == TOK_LBRACKET) || (tok == TOK_DOT));
13062         eat(state, TOK_EQ);
13063         return info;
13064 }
13065
13066 static struct triple *initializer(
13067         struct compile_state *state, struct type *type)
13068 {
13069         struct triple *result;
13070 #warning "FIXME more consistent initializer handling (where should eval_const_expr go?"
13071         if (peek(state) != TOK_LBRACE) {
13072                 result = assignment_expr(state);
13073                 if (((type->type & TYPE_MASK) == TYPE_ARRAY) &&
13074                         (type->elements == ELEMENT_COUNT_UNSPECIFIED) &&
13075                         ((result->type->type & TYPE_MASK) == TYPE_ARRAY) &&
13076                         (result->type->elements != ELEMENT_COUNT_UNSPECIFIED) &&
13077                         (equiv_types(type->left, result->type->left))) {
13078                         type->elements = result->type->elements;
13079                 }
13080                 if (is_lvalue(state, result) && 
13081                         ((result->type->type & TYPE_MASK) == TYPE_ARRAY) &&
13082                         (type->type & TYPE_MASK) != TYPE_ARRAY)
13083                 {
13084                         result = lvalue_conversion(state, result);
13085                 }
13086                 if (!is_init_compatible(state, type, result->type)) {
13087                         error(state, 0, "Incompatible types in initializer");
13088                 }
13089                 if (!equiv_types(type, result->type)) {
13090                         result = mk_cast_expr(state, type, result);
13091                 }
13092         }
13093         else {
13094                 int comma;
13095                 size_t max_offset;
13096                 struct field_info info;
13097                 void *buf;
13098                 if (((type->type & TYPE_MASK) != TYPE_ARRAY) &&
13099                         ((type->type & TYPE_MASK) != TYPE_STRUCT)) {
13100                         internal_error(state, 0, "unknown initializer type");
13101                 }
13102                 info.offset = 0;
13103                 info.type = type->left;
13104                 if ((type->type & TYPE_MASK) == TYPE_STRUCT) {
13105                         info.type = next_field(state, type, 0);
13106                 }
13107                 if (type->elements == ELEMENT_COUNT_UNSPECIFIED) {
13108                         max_offset = 0;
13109                 } else {
13110                         max_offset = size_of(state, type);
13111                 }
13112                 buf = xcmalloc(bits_to_bytes(max_offset), "initializer");
13113                 eat(state, TOK_LBRACE);
13114                 do {
13115                         struct triple *value;
13116                         struct type *value_type;
13117                         size_t value_size;
13118                         void *dest;
13119                         int tok;
13120                         comma = 0;
13121                         tok = peek(state);
13122                         if ((tok == TOK_LBRACKET) || (tok == TOK_DOT)) {
13123                                 info = designator(state, type);
13124                         }
13125                         if ((type->elements != ELEMENT_COUNT_UNSPECIFIED) &&
13126                                 (info.offset >= max_offset)) {
13127                                 error(state, 0, "element beyond bounds");
13128                         }
13129                         value_type = info.type;
13130                         value = eval_const_expr(state, initializer(state, value_type));
13131                         value_size = size_of(state, value_type);
13132                         if (((type->type & TYPE_MASK) == TYPE_ARRAY) &&
13133                                 (type->elements == ELEMENT_COUNT_UNSPECIFIED) &&
13134                                 (max_offset <= info.offset)) {
13135                                 void *old_buf;
13136                                 size_t old_size;
13137                                 old_buf = buf;
13138                                 old_size = max_offset;
13139                                 max_offset = info.offset + value_size;
13140                                 buf = xmalloc(bits_to_bytes(max_offset), "initializer");
13141                                 memcpy(buf, old_buf, bits_to_bytes(old_size));
13142                                 xfree(old_buf);
13143                         }
13144                         dest = ((char *)buf) + bits_to_bytes(info.offset);
13145 #if DEBUG_INITIALIZER
13146                         fprintf(state->errout, "dest = buf + %d max_offset: %d value_size: %d op: %d\n", 
13147                                 dest - buf,
13148                                 bits_to_bytes(max_offset),
13149                                 bits_to_bytes(value_size),
13150                                 value->op);
13151 #endif
13152                         if (value->op == OP_BLOBCONST) {
13153                                 memcpy(dest, value->u.blob, bits_to_bytes(value_size));
13154                         }
13155                         else if ((value->op == OP_INTCONST) && (value_size == SIZEOF_I8)) {
13156 #if DEBUG_INITIALIZER
13157                                 fprintf(state->errout, "byte: %02x\n", value->u.cval & 0xff);
13158 #endif
13159                                 *((uint8_t *)dest) = value->u.cval & 0xff;
13160                         }
13161                         else if ((value->op == OP_INTCONST) && (value_size == SIZEOF_I16)) {
13162                                 *((uint16_t *)dest) = value->u.cval & 0xffff;
13163                         }
13164                         else if ((value->op == OP_INTCONST) && (value_size == SIZEOF_I32)) {
13165                                 *((uint32_t *)dest) = value->u.cval & 0xffffffff;
13166                         }
13167                         else {
13168                                 internal_error(state, 0, "unhandled constant initializer");
13169                         }
13170                         free_triple(state, value);
13171                         if (peek(state) == TOK_COMMA) {
13172                                 eat(state, TOK_COMMA);
13173                                 comma = 1;
13174                         }
13175                         info.offset += value_size;
13176                         if ((type->type & TYPE_MASK) == TYPE_STRUCT) {
13177                                 info.type = next_field(state, type, info.type);
13178                                 info.offset = field_offset(state, type, 
13179                                         info.type->field_ident);
13180                         }
13181                 } while(comma && (peek(state) != TOK_RBRACE));
13182                 if ((type->elements == ELEMENT_COUNT_UNSPECIFIED) &&
13183                         ((type->type & TYPE_MASK) == TYPE_ARRAY)) {
13184                         type->elements = max_offset / size_of(state, type->left);
13185                 }
13186                 eat(state, TOK_RBRACE);
13187                 result = triple(state, OP_BLOBCONST, type, 0, 0);
13188                 result->u.blob = buf;
13189         }
13190         return result;
13191 }
13192
13193 static void resolve_branches(struct compile_state *state, struct triple *first)
13194 {
13195         /* Make a second pass and finish anything outstanding
13196          * with respect to branches.  The only outstanding item
13197          * is to see if there are goto to labels that have not
13198          * been defined and to error about them.
13199          */
13200         int i;
13201         struct triple *ins;
13202         /* Also error on branches that do not use their targets */
13203         ins = first;
13204         do {
13205                 if (!triple_is_ret(state, ins)) {
13206                         struct triple **expr ;
13207                         struct triple_set *set;
13208                         expr = triple_targ(state, ins, 0);
13209                         for(; expr; expr = triple_targ(state, ins, expr)) {
13210                                 struct triple *targ;
13211                                 targ = *expr;
13212                                 for(set = targ?targ->use:0; set; set = set->next) {
13213                                         if (set->member == ins) {
13214                                                 break;
13215                                         }
13216                                 }
13217                                 if (!set) {
13218                                         internal_error(state, ins, "targ not used");
13219                                 }
13220                         }
13221                 }
13222                 ins = ins->next;
13223         } while(ins != first);
13224         /* See if there are goto to labels that have not been defined */
13225         for(i = 0; i < HASH_TABLE_SIZE; i++) {
13226                 struct hash_entry *entry;
13227                 for(entry = state->hash_table[i]; entry; entry = entry->next) {
13228                         struct triple *ins;
13229                         if (!entry->sym_label) {
13230                                 continue;
13231                         }
13232                         ins = entry->sym_label->def;
13233                         if (!(ins->id & TRIPLE_FLAG_FLATTENED)) {
13234                                 error(state, ins, "label `%s' used but not defined",
13235                                         entry->name);
13236                         }
13237                 }
13238         }
13239 }
13240
13241 static struct triple *function_definition(
13242         struct compile_state *state, struct type *type)
13243 {
13244         struct triple *def, *tmp, *first, *end, *retvar, *result, *ret;
13245         struct triple *fname;
13246         struct type *fname_type;
13247         struct hash_entry *ident;
13248         struct type *param, *crtype, *ctype;
13249         int i;
13250         if ((type->type &TYPE_MASK) != TYPE_FUNCTION) {
13251                 error(state, 0, "Invalid function header");
13252         }
13253
13254         /* Verify the function type */
13255         if (((type->right->type & TYPE_MASK) != TYPE_VOID)  &&
13256                 ((type->right->type & TYPE_MASK) != TYPE_PRODUCT) &&
13257                 (type->right->field_ident == 0)) {
13258                 error(state, 0, "Invalid function parameters");
13259         }
13260         param = type->right;
13261         i = 0;
13262         while((param->type & TYPE_MASK) == TYPE_PRODUCT) {
13263                 i++;
13264                 if (!param->left->field_ident) {
13265                         error(state, 0, "No identifier for parameter %d\n", i);
13266                 }
13267                 param = param->right;
13268         }
13269         i++;
13270         if (((param->type & TYPE_MASK) != TYPE_VOID) && !param->field_ident) {
13271                 error(state, 0, "No identifier for paramter %d\n", i);
13272         }
13273         
13274         /* Get a list of statements for this function. */
13275         def = triple(state, OP_LIST, type, 0, 0);
13276
13277         /* Start a new scope for the passed parameters */
13278         start_scope(state);
13279
13280         /* Put a label at the very start of a function */
13281         first = label(state);
13282         RHS(def, 0) = first;
13283
13284         /* Put a label at the very end of a function */
13285         end = label(state);
13286         flatten(state, first, end);
13287         /* Remember where return goes */
13288         ident = state->i_return;
13289         symbol(state, ident, &ident->sym_ident, end, end->type);
13290
13291         /* Get the initial closure type */
13292         ctype = new_type(TYPE_JOIN, &void_type, 0);
13293         ctype->elements = 1;
13294
13295         /* Add a variable for the return value */
13296         crtype = new_type(TYPE_TUPLE, 
13297                 /* Remove all type qualifiers from the return type */
13298                 new_type(TYPE_PRODUCT, ctype, clone_type(0, type->left)), 0);
13299         crtype->elements = 2;
13300         result = flatten(state, end, variable(state, crtype));
13301
13302         /* Allocate a variable for the return address */
13303         retvar = flatten(state, end, variable(state, &void_ptr_type));
13304
13305         /* Add in the return instruction */
13306         ret = triple(state, OP_RET, &void_type, read_expr(state, retvar), 0);
13307         ret = flatten(state, first, ret);
13308
13309         /* Walk through the parameters and create symbol table entries
13310          * for them.
13311          */
13312         param = type->right;
13313         while((param->type & TYPE_MASK) == TYPE_PRODUCT) {
13314                 ident = param->left->field_ident;
13315                 tmp = variable(state, param->left);
13316                 var_symbol(state, ident, tmp);
13317                 flatten(state, end, tmp);
13318                 param = param->right;
13319         }
13320         if ((param->type & TYPE_MASK) != TYPE_VOID) {
13321                 /* And don't forget the last parameter */
13322                 ident = param->field_ident;
13323                 tmp = variable(state, param);
13324                 symbol(state, ident, &ident->sym_ident, tmp, tmp->type);
13325                 flatten(state, end, tmp);
13326         }
13327
13328         /* Add the declaration static const char __func__ [] = "func-name"  */
13329         fname_type = new_type(TYPE_ARRAY, 
13330                 clone_type(QUAL_CONST | STOR_STATIC, &char_type), 0);
13331         fname_type->type |= QUAL_CONST | STOR_STATIC;
13332         fname_type->elements = strlen(state->function) + 1;
13333
13334         fname = triple(state, OP_BLOBCONST, fname_type, 0, 0);
13335         fname->u.blob = (void *)state->function;
13336         fname = flatten(state, end, fname);
13337
13338         ident = state->i___func__;
13339         symbol(state, ident, &ident->sym_ident, fname, fname_type);
13340
13341         /* Remember which function I am compiling.
13342          * Also assume the last defined function is the main function.
13343          */
13344         state->main_function = def;
13345
13346         /* Now get the actual function definition */
13347         compound_statement(state, end);
13348
13349         /* Finish anything unfinished with branches */
13350         resolve_branches(state, first);
13351
13352         /* Remove the parameter scope */
13353         end_scope(state);
13354
13355
13356         /* Remember I have defined a function */
13357         if (!state->functions) {
13358                 state->functions = def;
13359         } else {
13360                 insert_triple(state, state->functions, def);
13361         }
13362         if (state->compiler->debug & DEBUG_INLINE) {
13363                 FILE *fp = state->dbgout;
13364                 fprintf(fp, "\n");
13365                 loc(fp, state, 0);
13366                 fprintf(fp, "\n__________ %s _________\n", __FUNCTION__);
13367                 display_func(state, fp, def);
13368                 fprintf(fp, "__________ %s _________ done\n\n", __FUNCTION__);
13369         }
13370
13371         return def;
13372 }
13373
13374 static struct triple *do_decl(struct compile_state *state, 
13375         struct type *type, struct hash_entry *ident)
13376 {
13377         struct triple *def;
13378         def = 0;
13379         /* Clean up the storage types used */
13380         switch (type->type & STOR_MASK) {
13381         case STOR_AUTO:
13382         case STOR_STATIC:
13383                 /* These are the good types I am aiming for */
13384                 break;
13385         case STOR_REGISTER:
13386                 type->type &= ~STOR_MASK;
13387                 type->type |= STOR_AUTO;
13388                 break;
13389         case STOR_LOCAL:
13390         case STOR_EXTERN:
13391                 type->type &= ~STOR_MASK;
13392                 type->type |= STOR_STATIC;
13393                 break;
13394         case STOR_TYPEDEF:
13395                 if (!ident) {
13396                         error(state, 0, "typedef without name");
13397                 }
13398                 symbol(state, ident, &ident->sym_ident, 0, type);
13399                 ident->tok = TOK_TYPE_NAME;
13400                 return 0;
13401                 break;
13402         default:
13403                 internal_error(state, 0, "Undefined storage class");
13404         }
13405         if ((type->type & TYPE_MASK) == TYPE_FUNCTION) {
13406                 error(state, 0, "Function prototypes not supported");
13407         }
13408         if (ident && 
13409                 ((type->type & STOR_MASK) == STOR_STATIC) &&
13410                 ((type->type & QUAL_CONST) == 0)) {
13411                 error(state, 0, "non const static variables not supported");
13412         }
13413         if (ident) {
13414                 def = variable(state, type);
13415                 var_symbol(state, ident, def);
13416         }
13417         return def;
13418 }
13419
13420 static void decl(struct compile_state *state, struct triple *first)
13421 {
13422         struct type *base_type, *type;
13423         struct hash_entry *ident;
13424         struct triple *def;
13425         int global;
13426         global = (state->scope_depth <= GLOBAL_SCOPE_DEPTH);
13427         base_type = decl_specifiers(state);
13428         ident = 0;
13429         type = declarator(state, base_type, &ident, 0);
13430         type->type = attributes_opt(state, type->type);
13431         if (global && ident && (peek(state) == TOK_LBRACE)) {
13432                 /* function */
13433                 type->type_ident = ident;
13434                 state->function = ident->name;
13435                 def = function_definition(state, type);
13436                 symbol(state, ident, &ident->sym_ident, def, type);
13437                 state->function = 0;
13438         }
13439         else {
13440                 int done;
13441                 flatten(state, first, do_decl(state, type, ident));
13442                 /* type or variable definition */
13443                 do {
13444                         done = 1;
13445                         if (peek(state) == TOK_EQ) {
13446                                 if (!ident) {
13447                                         error(state, 0, "cannot assign to a type");
13448                                 }
13449                                 eat(state, TOK_EQ);
13450                                 flatten(state, first,
13451                                         init_expr(state, 
13452                                                 ident->sym_ident->def, 
13453                                                 initializer(state, type)));
13454                         }
13455                         arrays_complete(state, type);
13456                         if (peek(state) == TOK_COMMA) {
13457                                 eat(state, TOK_COMMA);
13458                                 ident = 0;
13459                                 type = declarator(state, base_type, &ident, 0);
13460                                 flatten(state, first, do_decl(state, type, ident));
13461                                 done = 0;
13462                         }
13463                 } while(!done);
13464                 eat(state, TOK_SEMI);
13465         }
13466 }
13467
13468 static void decls(struct compile_state *state)
13469 {
13470         struct triple *list;
13471         int tok;
13472         list = label(state);
13473         while(1) {
13474                 tok = peek(state);
13475                 if (tok == TOK_EOF) {
13476                         return;
13477                 }
13478                 if (tok == TOK_SPACE) {
13479                         eat(state, TOK_SPACE);
13480                 }
13481                 decl(state, list);
13482                 if (list->next != list) {
13483                         error(state, 0, "global variables not supported");
13484                 }
13485         }
13486 }
13487
13488 /* 
13489  * Function inlining
13490  */
13491 struct triple_reg_set {
13492         struct triple_reg_set *next;
13493         struct triple *member;
13494         struct triple *new;
13495 };
13496 struct reg_block {
13497         struct block *block;
13498         struct triple_reg_set *in;
13499         struct triple_reg_set *out;
13500         int vertex;
13501 };
13502 static void setup_basic_blocks(struct compile_state *, struct basic_blocks *bb);
13503 static void analyze_basic_blocks(struct compile_state *state, struct basic_blocks *bb);
13504 static void free_basic_blocks(struct compile_state *, struct basic_blocks *bb);
13505 static int tdominates(struct compile_state *state, struct triple *dom, struct triple *sub);
13506 static void walk_blocks(struct compile_state *state, struct basic_blocks *bb,
13507         void (*cb)(struct compile_state *state, struct block *block, void *arg),
13508         void *arg);
13509 static void print_block(
13510         struct compile_state *state, struct block *block, void *arg);
13511 static int do_triple_set(struct triple_reg_set **head, 
13512         struct triple *member, struct triple *new_member);
13513 static void do_triple_unset(struct triple_reg_set **head, struct triple *member);
13514 static struct reg_block *compute_variable_lifetimes(
13515         struct compile_state *state, struct basic_blocks *bb);
13516 static void free_variable_lifetimes(struct compile_state *state, 
13517         struct basic_blocks *bb, struct reg_block *blocks);
13518 static void print_live_variables(struct compile_state *state, 
13519         struct basic_blocks *bb, struct reg_block *rb, FILE *fp);
13520
13521
13522 static struct triple *call(struct compile_state *state,
13523         struct triple *retvar, struct triple *ret_addr, 
13524         struct triple *targ, struct triple *ret)
13525 {
13526         struct triple *call;
13527
13528         if (!retvar || !is_lvalue(state, retvar)) {
13529                 internal_error(state, 0, "writing to a non lvalue?");
13530         }
13531         write_compatible(state, retvar->type, &void_ptr_type);
13532
13533         call = new_triple(state, OP_CALL, &void_type, 1, 0);
13534         TARG(call, 0) = targ;
13535         MISC(call, 0) = ret;
13536         if (!targ || (targ->op != OP_LABEL)) {
13537                 internal_error(state, 0, "call not to a label");
13538         }
13539         if (!ret || (ret->op != OP_RET)) {
13540                 internal_error(state, 0, "call not matched with return");
13541         }
13542         return call;
13543 }
13544
13545 static void walk_functions(struct compile_state *state,
13546         void (*cb)(struct compile_state *state, struct triple *func, void *arg),
13547         void *arg)
13548 {
13549         struct triple *func, *first;
13550         func = first = state->functions;
13551         do {
13552                 cb(state, func, arg);
13553                 func = func->next;
13554         } while(func != first);
13555 }
13556
13557 static void reverse_walk_functions(struct compile_state *state,
13558         void (*cb)(struct compile_state *state, struct triple *func, void *arg),
13559         void *arg)
13560 {
13561         struct triple *func, *first;
13562         func = first = state->functions;
13563         do {
13564                 func = func->prev;
13565                 cb(state, func, arg);
13566         } while(func != first);
13567 }
13568
13569
13570 static void mark_live(struct compile_state *state, struct triple *func, void *arg)
13571 {
13572         struct triple *ptr, *first;
13573         if (func->u.cval == 0) {
13574                 return;
13575         }
13576         ptr = first = RHS(func, 0);
13577         do {
13578                 if (ptr->op == OP_FCALL) {
13579                         struct triple *called_func;
13580                         called_func = MISC(ptr, 0);
13581                         /* Mark the called function as used */
13582                         if (!(func->id & TRIPLE_FLAG_FLATTENED)) {
13583                                 called_func->u.cval++;
13584                         }
13585                         /* Remove the called function from the list */
13586                         called_func->prev->next = called_func->next;
13587                         called_func->next->prev = called_func->prev;
13588
13589                         /* Place the called function before me on the list */
13590                         called_func->next       = func;
13591                         called_func->prev       = func->prev;
13592                         called_func->prev->next = called_func;
13593                         called_func->next->prev = called_func;
13594                 }
13595                 ptr = ptr->next;
13596         } while(ptr != first);
13597         func->id |= TRIPLE_FLAG_FLATTENED;
13598 }
13599
13600 static void mark_live_functions(struct compile_state *state)
13601 {
13602         /* Ensure state->main_function is the last function in 
13603          * the list of functions.
13604          */
13605         if ((state->main_function->next != state->functions) ||
13606                 (state->functions->prev != state->main_function)) {
13607                 internal_error(state, 0, 
13608                         "state->main_function is not at the end of the function list ");
13609         }
13610         state->main_function->u.cval = 1;
13611         reverse_walk_functions(state, mark_live, 0);
13612 }
13613
13614 static int local_triple(struct compile_state *state, 
13615         struct triple *func, struct triple *ins)
13616 {
13617         int local = (ins->id & TRIPLE_FLAG_LOCAL);
13618 #if 0
13619         if (!local) {
13620                 FILE *fp = state->errout;
13621                 fprintf(fp, "global: ");
13622                 display_triple(fp, ins);
13623         }
13624 #endif
13625         return local;
13626 }
13627
13628 struct triple *copy_func(struct compile_state *state, struct triple *ofunc, 
13629         struct occurance *base_occurance)
13630 {
13631         struct triple *nfunc;
13632         struct triple *nfirst, *ofirst;
13633         struct triple *new, *old;
13634
13635         if (state->compiler->debug & DEBUG_INLINE) {
13636                 FILE *fp = state->dbgout;
13637                 fprintf(fp, "\n");
13638                 loc(fp, state, 0);
13639                 fprintf(fp, "\n__________ %s _________\n", __FUNCTION__);
13640                 display_func(state, fp, ofunc);
13641                 fprintf(fp, "__________ %s _________ done\n\n", __FUNCTION__);
13642         }
13643
13644         /* Make a new copy of the old function */
13645         nfunc = triple(state, OP_LIST, ofunc->type, 0, 0);
13646         nfirst = 0;
13647         ofirst = old = RHS(ofunc, 0);
13648         do {
13649                 struct triple *new;
13650                 struct occurance *occurance;
13651                 int old_lhs, old_rhs;
13652                 old_lhs = old->lhs;
13653                 old_rhs = old->rhs;
13654                 occurance = inline_occurance(state, base_occurance, old->occurance);
13655                 if (ofunc->u.cval && (old->op == OP_FCALL)) {
13656                         MISC(old, 0)->u.cval += 1;
13657                 }
13658                 new = alloc_triple(state, old->op, old->type, old_lhs, old_rhs,
13659                         occurance);
13660                 if (!triple_stores_block(state, new)) {
13661                         memcpy(&new->u, &old->u, sizeof(new->u));
13662                 }
13663                 if (!nfirst) {
13664                         RHS(nfunc, 0) = nfirst = new;
13665                 }
13666                 else {
13667                         insert_triple(state, nfirst, new);
13668                 }
13669                 new->id |= TRIPLE_FLAG_FLATTENED;
13670                 new->id |= old->id & TRIPLE_FLAG_COPY;
13671                 
13672                 /* During the copy remember new as user of old */
13673                 use_triple(old, new);
13674
13675                 /* Remember which instructions are local */
13676                 old->id |= TRIPLE_FLAG_LOCAL;
13677                 old = old->next;
13678         } while(old != ofirst);
13679
13680         /* Make a second pass to fix up any unresolved references */
13681         old = ofirst;
13682         new = nfirst;
13683         do {
13684                 struct triple **oexpr, **nexpr;
13685                 int count, i;
13686                 /* Lookup where the copy is, to join pointers */
13687                 count = TRIPLE_SIZE(old);
13688                 for(i = 0; i < count; i++) {
13689                         oexpr = &old->param[i];
13690                         nexpr = &new->param[i];
13691                         if (*oexpr && !*nexpr) {
13692                                 if (!local_triple(state, ofunc, *oexpr)) {
13693                                         *nexpr = *oexpr;
13694                                 }
13695                                 else if ((*oexpr)->use) {
13696                                         *nexpr = (*oexpr)->use->member;
13697                                 }
13698                                 if (*nexpr == old) {
13699                                         internal_error(state, 0, "new == old?");
13700                                 }
13701                                 use_triple(*nexpr, new);
13702                         }
13703                         if (!*nexpr && *oexpr) {
13704                                 internal_error(state, 0, "Could not copy %d", i);
13705                         }
13706                 }
13707                 old = old->next;
13708                 new = new->next;
13709         } while((old != ofirst) && (new != nfirst));
13710         
13711         /* Make a third pass to cleanup the extra useses */
13712         old = ofirst;
13713         new = nfirst;
13714         do {
13715                 unuse_triple(old, new);
13716                 /* Forget which instructions are local */
13717                 old->id &= ~TRIPLE_FLAG_LOCAL;
13718                 old = old->next;
13719                 new = new->next;
13720         } while ((old != ofirst) && (new != nfirst));
13721         return nfunc;
13722 }
13723
13724 static void expand_inline_call(
13725         struct compile_state *state, struct triple *me, struct triple *fcall)
13726 {
13727         /* Inline the function call */
13728         struct type *ptype;
13729         struct triple *ofunc, *nfunc, *nfirst, *result, *retvar, *ins;
13730         struct triple *end, *nend;
13731         int pvals, i;
13732
13733         /* Find the triples */
13734         ofunc = MISC(fcall, 0);
13735         if (ofunc->op != OP_LIST) {
13736                 internal_error(state, 0, "improper function");
13737         }
13738         nfunc = copy_func(state, ofunc, fcall->occurance);
13739         /* Prepend the parameter reading into the new function list */
13740         ptype = nfunc->type->right;
13741         pvals = fcall->rhs;
13742         for(i = 0; i < pvals; i++) {
13743                 struct type *atype;
13744                 struct triple *arg, *param;
13745                 atype = ptype;
13746                 if ((ptype->type & TYPE_MASK) == TYPE_PRODUCT) {
13747                         atype = ptype->left;
13748                 }
13749                 param = farg(state, nfunc, i);
13750                 if ((param->type->type & TYPE_MASK) != (atype->type & TYPE_MASK)) {
13751                         internal_error(state, fcall, "param %d type mismatch", i);
13752                 }
13753                 arg = RHS(fcall, i);
13754                 flatten(state, fcall, write_expr(state, param, arg));
13755                 ptype = ptype->right;
13756         }
13757         result = 0;
13758         if ((nfunc->type->left->type & TYPE_MASK) != TYPE_VOID) {
13759                 result = read_expr(state, 
13760                         deref_index(state, fresult(state, nfunc), 1));
13761         }
13762         if (state->compiler->debug & DEBUG_INLINE) {
13763                 FILE *fp = state->dbgout;
13764                 fprintf(fp, "\n");
13765                 loc(fp, state, 0);
13766                 fprintf(fp, "\n__________ %s _________\n", __FUNCTION__);
13767                 display_func(state, fp, nfunc);
13768                 fprintf(fp, "__________ %s _________ done\n\n", __FUNCTION__);
13769         }
13770
13771         /* 
13772          * Get rid of the extra triples 
13773          */
13774         /* Remove the read of the return address */
13775         ins = RHS(nfunc, 0)->prev->prev;
13776         if ((ins->op != OP_READ) || (RHS(ins, 0) != fretaddr(state, nfunc))) {
13777                 internal_error(state, ins, "Not return addres read?");
13778         }
13779         release_triple(state, ins);
13780         /* Remove the return instruction */
13781         ins = RHS(nfunc, 0)->prev;
13782         if (ins->op != OP_RET) {
13783                 internal_error(state, ins, "Not return?");
13784         }
13785         release_triple(state, ins);
13786         /* Remove the retaddres variable */
13787         retvar = fretaddr(state, nfunc);
13788         if ((retvar->lhs != 1) || 
13789                 (retvar->op != OP_ADECL) ||
13790                 (retvar->next->op != OP_PIECE) ||
13791                 (MISC(retvar->next, 0) != retvar)) {
13792                 internal_error(state, retvar, "Not the return address?");
13793         }
13794         release_triple(state, retvar->next);
13795         release_triple(state, retvar);
13796
13797         /* Remove the label at the start of the function */
13798         ins = RHS(nfunc, 0);
13799         if (ins->op != OP_LABEL) {
13800                 internal_error(state, ins, "Not label?");
13801         }
13802         nfirst = ins->next;
13803         free_triple(state, ins);
13804         /* Release the new function header */
13805         RHS(nfunc, 0) = 0;
13806         free_triple(state, nfunc);
13807
13808         /* Append the new function list onto the return list */
13809         end = fcall->prev;
13810         nend = nfirst->prev;
13811         end->next    = nfirst;
13812         nfirst->prev = end;
13813         nend->next   = fcall;
13814         fcall->prev  = nend;
13815
13816         /* Now the result reading code */
13817         if (result) {
13818                 result = flatten(state, fcall, result);
13819                 propogate_use(state, fcall, result);
13820         }
13821
13822         /* Release the original fcall instruction */
13823         release_triple(state, fcall);
13824
13825         return;
13826 }
13827
13828 /*
13829  *
13830  * Type of the result variable.
13831  * 
13832  *                                     result
13833  *                                        |
13834  *                             +----------+------------+
13835  *                             |                       |
13836  *                     union of closures         result_type
13837  *                             |
13838  *          +------------------+---------------+
13839  *          |                                  |
13840  *       closure1                    ...   closuerN
13841  *          |                                  | 
13842  *  +----+--+-+--------+-----+       +----+----+---+-----+
13843  *  |    |    |        |     |       |    |        |     |
13844  * var1 var2 var3 ... varN result   var1 var2 ... varN result
13845  *                           |
13846  *                  +--------+---------+
13847  *                  |                  |
13848  *          union of closures     result_type
13849  *                  |
13850  *            +-----+-------------------+
13851  *            |                         |
13852  *         closure1            ...  closureN
13853  *            |                         |
13854  *  +-----+---+----+----+      +----+---+----+-----+
13855  *  |     |        |    |      |    |        |     |
13856  * var1 var2 ... varN result  var1 var2 ... varN result
13857  */
13858
13859 static int add_closure_type(struct compile_state *state, 
13860         struct triple *func, struct type *closure_type)
13861 {
13862         struct type *type, *ctype, **next;
13863         struct triple *var, *new_var;
13864         int i;
13865
13866 #if 0
13867         FILE *fp = state->errout;
13868         fprintf(fp, "original_type: ");
13869         name_of(fp, fresult(state, func)->type);
13870         fprintf(fp, "\n");
13871 #endif
13872         /* find the original type */
13873         var = fresult(state, func);
13874         type = var->type;
13875         if (type->elements != 2) {
13876                 internal_error(state, var, "bad return type");
13877         }
13878
13879         /* Find the complete closure type and update it */
13880         ctype = type->left->left;
13881         next = &ctype->left;
13882         while(((*next)->type & TYPE_MASK) == TYPE_OVERLAP) {
13883                 next = &(*next)->right;
13884         }
13885         *next = new_type(TYPE_OVERLAP, *next, dup_type(state, closure_type));
13886         ctype->elements += 1;
13887
13888 #if 0
13889         fprintf(fp, "new_type: ");
13890         name_of(fp, type);
13891         fprintf(fp, "\n");
13892         fprintf(fp, "ctype: %p %d bits: %d ", 
13893                 ctype, ctype->elements, reg_size_of(state, ctype));
13894         name_of(fp, ctype);
13895         fprintf(fp, "\n");
13896 #endif
13897         
13898         /* Regenerate the variable with the new type definition */
13899         new_var = pre_triple(state, var, OP_ADECL, type, 0, 0);
13900         new_var->id |= TRIPLE_FLAG_FLATTENED;
13901         for(i = 0; i < new_var->lhs; i++) {
13902                 LHS(new_var, i)->id |= TRIPLE_FLAG_FLATTENED;
13903         }
13904         
13905         /* Point everyone at the new variable */
13906         propogate_use(state, var, new_var);
13907
13908         /* Release the original variable */
13909         for(i = 0; i < var->lhs; i++) {
13910                 release_triple(state, LHS(var, i));
13911         }
13912         release_triple(state, var);
13913         
13914         /* Return the index of the added closure type */
13915         return ctype->elements - 1;
13916 }
13917
13918 static struct triple *closure_expr(struct compile_state *state,
13919         struct triple *func, int closure_idx, int var_idx)
13920 {
13921         return deref_index(state,
13922                 deref_index(state,
13923                         deref_index(state, fresult(state, func), 0),
13924                         closure_idx),
13925                 var_idx);
13926 }
13927
13928
13929 static void insert_triple_set(
13930         struct triple_reg_set **head, struct triple *member)
13931 {
13932         struct triple_reg_set *new;
13933         new = xcmalloc(sizeof(*new), "triple_set");
13934         new->member = member;
13935         new->new    = 0;
13936         new->next   = *head;
13937         *head       = new;
13938 }
13939
13940 static int ordered_triple_set(
13941         struct triple_reg_set **head, struct triple *member)
13942 {
13943         struct triple_reg_set **ptr;
13944         if (!member)
13945                 return 0;
13946         ptr = head;
13947         while(*ptr) {
13948                 if (member == (*ptr)->member) {
13949                         return 0;
13950                 }
13951                 /* keep the list ordered */
13952                 if (member->id < (*ptr)->member->id) {
13953                         break;
13954                 }
13955                 ptr = &(*ptr)->next;
13956         }
13957         insert_triple_set(ptr, member);
13958         return 1;
13959 }
13960
13961
13962 static void free_closure_variables(struct compile_state *state,
13963         struct triple_reg_set **enclose)
13964 {
13965         struct triple_reg_set *entry, *next;
13966         for(entry = *enclose; entry; entry = next) {
13967                 next = entry->next;
13968                 do_triple_unset(enclose, entry->member);
13969         }
13970 }
13971
13972 static int lookup_closure_index(struct compile_state *state,
13973         struct triple *me, struct triple *val)
13974 {
13975         struct triple *first, *ins, *next;
13976         first = RHS(me, 0);
13977         ins = next = first;
13978         do {
13979                 struct triple *result;
13980                 struct triple *index0, *index1, *index2, *read, *write;
13981                 ins = next;
13982                 next = ins->next;
13983                 if (ins->op != OP_CALL) {
13984                         continue;
13985                 }
13986                 /* I am at a previous call point examine it closely */
13987                 if (ins->next->op != OP_LABEL) {
13988                         internal_error(state, ins, "call not followed by label");
13989                 }
13990                 /* Does this call does not enclose any variables? */
13991                 if ((ins->next->next->op != OP_INDEX) ||
13992                         (ins->next->next->u.cval != 0) ||
13993                         (result = MISC(ins->next->next, 0)) ||
13994                         (result->id & TRIPLE_FLAG_LOCAL)) {
13995                         continue;
13996                 }
13997                 index0 = ins->next->next;
13998                 /* The pattern is:
13999                  * 0 index result < 0 >
14000                  * 1 index 0 < ? >
14001                  * 2 index 1 < ? >
14002                  * 3 read  2
14003                  * 4 write 3 var
14004                  */
14005                 for(index0 = ins->next->next;
14006                         (index0->op == OP_INDEX) &&
14007                                 (MISC(index0, 0) == result) &&
14008                                 (index0->u.cval == 0) ; 
14009                         index0 = write->next)
14010                 {
14011                         index1 = index0->next;
14012                         index2 = index1->next;
14013                         read   = index2->next;
14014                         write  = read->next;
14015                         if ((index0->op != OP_INDEX) ||
14016                                 (index1->op != OP_INDEX) ||
14017                                 (index2->op != OP_INDEX) ||
14018                                 (read->op != OP_READ) ||
14019                                 (write->op != OP_WRITE) ||
14020                                 (MISC(index1, 0) != index0) ||
14021                                 (MISC(index2, 0) != index1) ||
14022                                 (RHS(read, 0) != index2) ||
14023                                 (RHS(write, 0) != read)) {
14024                                 internal_error(state, index0, "bad var read");
14025                         }
14026                         if (MISC(write, 0) == val) {
14027                                 return index2->u.cval;
14028                         }
14029                 }
14030         } while(next != first);
14031         return -1;
14032 }
14033
14034 static inline int enclose_triple(struct triple *ins)
14035 {
14036         return (ins && ((ins->type->type & TYPE_MASK) != TYPE_VOID));
14037 }
14038
14039 static void compute_closure_variables(struct compile_state *state,
14040         struct triple *me, struct triple *fcall, struct triple_reg_set **enclose)
14041 {
14042         struct triple_reg_set *set, *vars, **last_var;
14043         struct basic_blocks bb;
14044         struct reg_block *rb;
14045         struct block *block;
14046         struct triple *old_result, *first, *ins;
14047         size_t count, idx;
14048         unsigned long used_indicies;
14049         int i, max_index;
14050 #define MAX_INDICIES (sizeof(used_indicies)*CHAR_BIT)
14051 #define ID_BITS(X) ((X) & (TRIPLE_FLAG_LOCAL -1))
14052         struct { 
14053                 unsigned id;
14054                 int index;
14055         } *info;
14056
14057         
14058         /* Find the basic blocks of this function */
14059         bb.func = me;
14060         bb.first = RHS(me, 0);
14061         old_result = 0;
14062         if (!triple_is_ret(state, bb.first->prev)) {
14063                 bb.func = 0;
14064         } else {
14065                 old_result = fresult(state, me);
14066         }
14067         analyze_basic_blocks(state, &bb);
14068
14069         /* Find which variables are currently alive in a given block */
14070         rb = compute_variable_lifetimes(state, &bb);
14071
14072         /* Find the variables that are currently alive */
14073         block = block_of_triple(state, fcall);
14074         if (!block || (block->vertex <= 0) || (block->vertex > bb.last_vertex)) {
14075                 internal_error(state, fcall, "No reg block? block: %p", block);
14076         }
14077
14078 #if DEBUG_EXPLICIT_CLOSURES
14079         print_live_variables(state, &bb, rb, state->dbgout);
14080         fflush(state->dbgout);
14081 #endif
14082
14083         /* Count the number of triples in the function */
14084         first = RHS(me, 0);
14085         ins = first;
14086         count = 0;
14087         do {
14088                 count++;
14089                 ins = ins->next;
14090         } while(ins != first);
14091
14092         /* Allocate some memory to temorary hold the id info */
14093         info = xcmalloc(sizeof(*info) * (count +1), "info");
14094
14095         /* Mark the local function */
14096         first = RHS(me, 0);
14097         ins = first;
14098         idx = 1;
14099         do {
14100                 info[idx].id = ins->id;
14101                 ins->id = TRIPLE_FLAG_LOCAL | idx;
14102                 idx++;
14103                 ins = ins->next;
14104         } while(ins != first);
14105
14106         /* 
14107          * Build the list of variables to enclose.
14108          *
14109          * A target it to put the same variable in the
14110          * same slot for ever call of a given function.
14111          * After coloring this removes all of the variable
14112          * manipulation code.
14113          *
14114          * The list of variables to enclose is built ordered
14115          * program order because except in corner cases this
14116          * gives me the stability of assignment I need.
14117          *
14118          * To gurantee that stability I lookup the variables
14119          * to see where they have been used before and
14120          * I build my final list with the assigned indicies.
14121          */
14122         vars = 0;
14123         if (enclose_triple(old_result)) {
14124                 ordered_triple_set(&vars, old_result);
14125         }
14126         for(set = rb[block->vertex].out; set; set = set->next) {
14127                 if (!enclose_triple(set->member)) {
14128                         continue;
14129                 }
14130                 if ((set->member == fcall) || (set->member == old_result)) {
14131                         continue;
14132                 }
14133                 if (!local_triple(state, me, set->member)) {
14134                         internal_error(state, set->member, "not local?");
14135                 }
14136                 ordered_triple_set(&vars, set->member);
14137         }
14138
14139         /* Lookup the current indicies of the live varialbe */
14140         used_indicies = 0;
14141         max_index = -1;
14142         for(set = vars; set ; set = set->next) {
14143                 struct triple *ins;
14144                 int index;
14145                 ins = set->member;
14146                 index  = lookup_closure_index(state, me, ins);
14147                 info[ID_BITS(ins->id)].index = index;
14148                 if (index < 0) {
14149                         continue;
14150                 }
14151                 if (index >= MAX_INDICIES) {
14152                         internal_error(state, ins, "index unexpectedly large");
14153                 }
14154                 if (used_indicies & (1 << index)) {
14155                         internal_error(state, ins, "index previously used?");
14156                 }
14157                 /* Remember which indicies have been used */
14158                 used_indicies |= (1 << index);
14159                 if (index > max_index) {
14160                         max_index = index;
14161                 }
14162         }
14163
14164         /* Walk through the live variables and make certain
14165          * everything is assigned an index.
14166          */
14167         for(set = vars; set; set = set->next) {
14168                 struct triple *ins;
14169                 int index;
14170                 ins = set->member;
14171                 index = info[ID_BITS(ins->id)].index;
14172                 if (index >= 0) {
14173                         continue;
14174                 }
14175                 /* Find the lowest unused index value */
14176                 for(index = 0; index < MAX_INDICIES; index++) {
14177                         if (!(used_indicies & (1 << index))) {
14178                                 break;
14179                         }
14180                 }
14181                 if (index == MAX_INDICIES) {
14182                         internal_error(state, ins, "no free indicies?");
14183                 }
14184                 info[ID_BITS(ins->id)].index = index;
14185                 /* Remember which indicies have been used */
14186                 used_indicies |= (1 << index);
14187                 if (index > max_index) {
14188                         max_index = index;
14189                 }
14190         }
14191
14192         /* Build the return list of variables with positions matching
14193          * their indicies.
14194          */
14195         *enclose = 0;
14196         last_var = enclose;
14197         for(i = 0; i <= max_index; i++) {
14198                 struct triple *var;
14199                 var = 0;
14200                 if (used_indicies & (1 << i)) {
14201                         for(set = vars; set; set = set->next) {
14202                                 int index;
14203                                 index = info[ID_BITS(set->member->id)].index;
14204                                 if (index == i) {
14205                                         var = set->member;
14206                                         break;
14207                                 }
14208                         }
14209                         if (!var) {
14210                                 internal_error(state, me, "missing variable");
14211                         }
14212                 }
14213                 insert_triple_set(last_var, var);
14214                 last_var = &(*last_var)->next;
14215         }
14216
14217 #if DEBUG_EXPLICIT_CLOSURES
14218         /* Print out the variables to be enclosed */
14219         loc(state->dbgout, state, fcall);
14220         fprintf(state->dbgout, "Alive: \n");
14221         for(set = *enclose; set; set = set->next) {
14222                 display_triple(state->dbgout, set->member);
14223         }
14224         fflush(state->dbgout);
14225 #endif
14226
14227         /* Clear the marks */
14228         ins = first;
14229         do {
14230                 ins->id = info[ID_BITS(ins->id)].id;
14231                 ins = ins->next;
14232         } while(ins != first);
14233
14234         /* Release the ordered list of live variables */
14235         free_closure_variables(state, &vars);
14236
14237         /* Release the storage of the old ids */
14238         xfree(info);
14239
14240         /* Release the variable lifetime information */
14241         free_variable_lifetimes(state, &bb, rb);
14242
14243         /* Release the basic blocks of this function */
14244         free_basic_blocks(state, &bb);
14245 }
14246
14247 static void expand_function_call(
14248         struct compile_state *state, struct triple *me, struct triple *fcall)
14249 {
14250         /* Generate an ordinary function call */
14251         struct type *closure_type, **closure_next;
14252         struct triple *func, *func_first, *func_last, *retvar;
14253         struct triple *first;
14254         struct type *ptype, *rtype;
14255         struct triple *jmp;
14256         struct triple *ret_addr, *ret_loc, *ret_set;
14257         struct triple_reg_set *enclose, *set;
14258         int closure_idx, pvals, i;
14259
14260 #if DEBUG_EXPLICIT_CLOSURES
14261         FILE *fp = state->dbgout;
14262         fprintf(fp, "\ndisplay_func(me) ptr: %p\n", fcall);
14263         display_func(state, fp, MISC(fcall, 0));
14264         display_func(state, fp, me);
14265         fprintf(fp, "__________ %s _________ done\n\n", __FUNCTION__);
14266 #endif
14267
14268         /* Find the triples */
14269         func = MISC(fcall, 0);
14270         func_first = RHS(func, 0);
14271         retvar = fretaddr(state, func);
14272         func_last  = func_first->prev;
14273         first = fcall->next;
14274
14275         /* Find what I need to enclose */
14276         compute_closure_variables(state, me, fcall, &enclose);
14277
14278         /* Compute the closure type */
14279         closure_type = new_type(TYPE_TUPLE, 0, 0);
14280         closure_type->elements = 0;
14281         closure_next = &closure_type->left;
14282         for(set = enclose; set ; set = set->next) {
14283                 struct type *type;
14284                 type = &void_type;
14285                 if (set->member) {
14286                         type = set->member->type;
14287                 }
14288                 if (!*closure_next) {
14289                         *closure_next = type;
14290                 } else {
14291                         *closure_next = new_type(TYPE_PRODUCT, *closure_next, 
14292                                 type);
14293                         closure_next = &(*closure_next)->right;
14294                 }
14295                 closure_type->elements += 1;
14296         }
14297         if (closure_type->elements == 0) {
14298                 closure_type->type = TYPE_VOID;
14299         }
14300
14301
14302 #if DEBUG_EXPLICIT_CLOSURES
14303         fprintf(state->dbgout, "closure type: ");
14304         name_of(state->dbgout, closure_type);
14305         fprintf(state->dbgout, "\n");
14306 #endif
14307
14308         /* Update the called functions closure variable */
14309         closure_idx = add_closure_type(state, func, closure_type);
14310
14311         /* Generate some needed triples */
14312         ret_loc = label(state);
14313         ret_addr = triple(state, OP_ADDRCONST, &void_ptr_type, ret_loc, 0);
14314
14315         /* Pass the parameters to the new function */
14316         ptype = func->type->right;
14317         pvals = fcall->rhs;
14318         for(i = 0; i < pvals; i++) {
14319                 struct type *atype;
14320                 struct triple *arg, *param;
14321                 atype = ptype;
14322                 if ((ptype->type & TYPE_MASK) == TYPE_PRODUCT) {
14323                         atype = ptype->left;
14324                 }
14325                 param = farg(state, func, i);
14326                 if ((param->type->type & TYPE_MASK) != (atype->type & TYPE_MASK)) {
14327                         internal_error(state, fcall, "param type mismatch");
14328                 }
14329                 arg = RHS(fcall, i);
14330                 flatten(state, first, write_expr(state, param, arg));
14331                 ptype = ptype->right;
14332         }
14333         rtype = func->type->left;
14334
14335         /* Thread the triples together */
14336         ret_loc       = flatten(state, first, ret_loc);
14337
14338         /* Save the active variables in the result variable */
14339         for(i = 0, set = enclose; set ; set = set->next, i++) {
14340                 if (!set->member) {
14341                         continue;
14342                 }
14343                 flatten(state, ret_loc,
14344                         write_expr(state,
14345                                 closure_expr(state, func, closure_idx, i),
14346                                 read_expr(state, set->member)));
14347         }
14348
14349         /* Initialize the return value */
14350         if ((rtype->type & TYPE_MASK) != TYPE_VOID) {
14351                 flatten(state, ret_loc, 
14352                         write_expr(state, 
14353                                 deref_index(state, fresult(state, func), 1),
14354                                 new_triple(state, OP_UNKNOWNVAL, rtype,  0, 0)));
14355         }
14356
14357         ret_addr      = flatten(state, ret_loc, ret_addr);
14358         ret_set       = flatten(state, ret_loc, write_expr(state, retvar, ret_addr));
14359         jmp           = flatten(state, ret_loc, 
14360                 call(state, retvar, ret_addr, func_first, func_last));
14361
14362         /* Find the result */
14363         if ((rtype->type & TYPE_MASK) != TYPE_VOID) {
14364                 struct triple * result;
14365                 result = flatten(state, first, 
14366                         read_expr(state, 
14367                                 deref_index(state, fresult(state, func), 1)));
14368
14369                 propogate_use(state, fcall, result);
14370         }
14371
14372         /* Release the original fcall instruction */
14373         release_triple(state, fcall);
14374
14375         /* Restore the active variables from the result variable */
14376         for(i = 0, set = enclose; set ; set = set->next, i++) {
14377                 struct triple_set *use, *next;
14378                 struct triple *new;
14379                 struct basic_blocks bb;
14380                 if (!set->member || (set->member == fcall)) {
14381                         continue;
14382                 }
14383                 /* Generate an expression for the value */
14384                 new = flatten(state, first,
14385                         read_expr(state, 
14386                                 closure_expr(state, func, closure_idx, i)));
14387
14388
14389                 /* If the original is an lvalue restore the preserved value */
14390                 if (is_lvalue(state, set->member)) {
14391                         flatten(state, first,
14392                                 write_expr(state, set->member, new));
14393                         continue;
14394                 }
14395                 /*
14396                  * If the original is a value update the dominated uses.
14397                  */
14398                 
14399                 /* Analyze the basic blocks so I can see who dominates whom */
14400                 bb.func = me;
14401                 bb.first = RHS(me, 0);
14402                 if (!triple_is_ret(state, bb.first->prev)) {
14403                         bb.func = 0;
14404                 }
14405                 analyze_basic_blocks(state, &bb);
14406                 
14407
14408 #if DEBUG_EXPLICIT_CLOSURES
14409                 fprintf(state->errout, "Updating domindated uses: %p -> %p\n",
14410                         set->member, new);
14411 #endif
14412                 /* If fcall dominates the use update the expression */
14413                 for(use = set->member->use; use; use = next) {
14414                         /* Replace use modifies the use chain and 
14415                          * removes use, so I must take a copy of the
14416                          * next entry early.
14417                          */
14418                         next = use->next;
14419                         if (!tdominates(state, fcall, use->member)) {
14420                                 continue;
14421                         }
14422                         replace_use(state, set->member, new, use->member);
14423                 }
14424
14425                 /* Release the basic blocks, the instructions will be
14426                  * different next time, and flatten/insert_triple does
14427                  * not update the block values so I can't cache the analysis.
14428                  */
14429                 free_basic_blocks(state, &bb);
14430         }
14431
14432         /* Release the closure variable list */
14433         free_closure_variables(state, &enclose);
14434
14435         if (state->compiler->debug & DEBUG_INLINE) {
14436                 FILE *fp = state->dbgout;
14437                 fprintf(fp, "\n");
14438                 loc(fp, state, 0);
14439                 fprintf(fp, "\n__________ %s _________\n", __FUNCTION__);
14440                 display_func(state, fp, func);
14441                 display_func(state, fp, me);
14442                 fprintf(fp, "__________ %s _________ done\n\n", __FUNCTION__);
14443         }
14444
14445         return;
14446 }
14447
14448 static int do_inline(struct compile_state *state, struct triple *func)
14449 {
14450         int do_inline;
14451         int policy;
14452
14453         policy = state->compiler->flags & COMPILER_INLINE_MASK;
14454         switch(policy) {
14455         case COMPILER_INLINE_ALWAYS:
14456                 do_inline = 1;
14457                 if (func->type->type & ATTRIB_NOINLINE) {
14458                         error(state, func, "noinline with always_inline compiler option");
14459                 }
14460                 break;
14461         case COMPILER_INLINE_NEVER:
14462                 do_inline = 0;
14463                 if (func->type->type & ATTRIB_ALWAYS_INLINE) {
14464                         error(state, func, "always_inline with noinline compiler option");
14465                 }
14466                 break;
14467         case COMPILER_INLINE_DEFAULTON:
14468                 switch(func->type->type & STOR_MASK) {
14469                 case STOR_STATIC | STOR_INLINE:
14470                 case STOR_LOCAL  | STOR_INLINE:
14471                 case STOR_EXTERN | STOR_INLINE:
14472                         do_inline = 1;
14473                         break;
14474                 default:
14475                         do_inline = 1;
14476                         break;
14477                 }
14478                 break;
14479         case COMPILER_INLINE_DEFAULTOFF:
14480                 switch(func->type->type & STOR_MASK) {
14481                 case STOR_STATIC | STOR_INLINE:
14482                 case STOR_LOCAL  | STOR_INLINE:
14483                 case STOR_EXTERN | STOR_INLINE:
14484                         do_inline = 1;
14485                         break;
14486                 default:
14487                         do_inline = 0;
14488                         break;
14489                 }
14490                 break;
14491         case COMPILER_INLINE_NOPENALTY:
14492                 switch(func->type->type & STOR_MASK) {
14493                 case STOR_STATIC | STOR_INLINE:
14494                 case STOR_LOCAL  | STOR_INLINE:
14495                 case STOR_EXTERN | STOR_INLINE:
14496                         do_inline = 1;
14497                         break;
14498                 default:
14499                         do_inline = (func->u.cval == 1);
14500                         break;
14501                 }
14502                 break;
14503         default:
14504                 do_inline = 0;
14505                 internal_error(state, 0, "Unimplemented inline policy");
14506                 break;
14507         }
14508         /* Force inlining */
14509         if (func->type->type & ATTRIB_NOINLINE) {
14510                 do_inline = 0;
14511         }
14512         if (func->type->type & ATTRIB_ALWAYS_INLINE) {
14513                 do_inline = 1;
14514         }
14515         return do_inline;
14516 }
14517
14518 static void inline_function(struct compile_state *state, struct triple *me, void *arg)
14519 {
14520         struct triple *first, *ptr, *next;
14521         /* If the function is not used don't bother */
14522         if (me->u.cval <= 0) {
14523                 return;
14524         }
14525         if (state->compiler->debug & DEBUG_CALLS2) {
14526                 FILE *fp = state->dbgout;
14527                 fprintf(fp, "in: %s\n",
14528                         me->type->type_ident->name);
14529         }
14530
14531         first = RHS(me, 0);
14532         ptr = next = first;
14533         do {
14534                 struct triple *func, *prev;
14535                 ptr = next;
14536                 prev = ptr->prev;
14537                 next = ptr->next;
14538                 if (ptr->op != OP_FCALL) {
14539                         continue;
14540                 }
14541                 func = MISC(ptr, 0);
14542                 /* See if the function should be inlined */
14543                 if (!do_inline(state, func)) {
14544                         /* Put a label after the fcall */
14545                         post_triple(state, ptr, OP_LABEL, &void_type, 0, 0);
14546                         continue;
14547                 }
14548                 if (state->compiler->debug & DEBUG_CALLS) {
14549                         FILE *fp = state->dbgout;
14550                         if (state->compiler->debug & DEBUG_CALLS2) {
14551                                 loc(fp, state, ptr);
14552                         }
14553                         fprintf(fp, "inlining %s\n",
14554                                 func->type->type_ident->name);
14555                         fflush(fp);
14556                 }
14557
14558                 /* Update the function use counts */
14559                 func->u.cval -= 1;
14560
14561                 /* Replace the fcall with the called function */
14562                 expand_inline_call(state, me, ptr);
14563
14564                 next = prev->next;
14565         } while (next != first);
14566
14567         ptr = next = first;
14568         do {
14569                 struct triple *prev, *func;
14570                 ptr = next;
14571                 prev = ptr->prev;
14572                 next = ptr->next;
14573                 if (ptr->op != OP_FCALL) {
14574                         continue;
14575                 }
14576                 func = MISC(ptr, 0);
14577                 if (state->compiler->debug & DEBUG_CALLS) {
14578                         FILE *fp = state->dbgout;
14579                         if (state->compiler->debug & DEBUG_CALLS2) {
14580                                 loc(fp, state, ptr);
14581                         }
14582                         fprintf(fp, "calling %s\n",
14583                                 func->type->type_ident->name);
14584                         fflush(fp);
14585                 }
14586                 /* Replace the fcall with the instruction sequence
14587                  * needed to make the call.
14588                  */
14589                 expand_function_call(state, me, ptr);
14590                 next = prev->next;
14591         } while(next != first);
14592 }
14593
14594 static void inline_functions(struct compile_state *state, struct triple *func)
14595 {
14596         inline_function(state, func, 0);
14597         reverse_walk_functions(state, inline_function, 0);
14598 }
14599
14600 static void insert_function(struct compile_state *state,
14601         struct triple *func, void *arg)
14602 {
14603         struct triple *first, *end, *ffirst, *fend;
14604
14605         if (state->compiler->debug & DEBUG_INLINE) {
14606                 FILE *fp = state->errout;
14607                 fprintf(fp, "%s func count: %d\n", 
14608                         func->type->type_ident->name, func->u.cval);
14609         }
14610         if (func->u.cval == 0) {
14611                 return;
14612         }
14613
14614         /* Find the end points of the lists */
14615         first  = arg;
14616         end    = first->prev;
14617         ffirst = RHS(func, 0);
14618         fend   = ffirst->prev;
14619
14620         /* splice the lists together */
14621         end->next    = ffirst;
14622         ffirst->prev = end;
14623         fend->next   = first;
14624         first->prev  = fend;
14625 }
14626
14627 struct triple *input_asm(struct compile_state *state)
14628 {
14629         struct asm_info *info;
14630         struct triple *def;
14631         int i, out;
14632         
14633         info = xcmalloc(sizeof(*info), "asm_info");
14634         info->str = "";
14635
14636         out = sizeof(arch_input_regs)/sizeof(arch_input_regs[0]);
14637         memcpy(&info->tmpl.lhs, arch_input_regs, sizeof(arch_input_regs));
14638
14639         def = new_triple(state, OP_ASM, &void_type, out, 0);
14640         def->u.ainfo = info;
14641         def->id |= TRIPLE_FLAG_VOLATILE;
14642         
14643         for(i = 0; i < out; i++) {
14644                 struct triple *piece;
14645                 piece = triple(state, OP_PIECE, &int_type, def, 0);
14646                 piece->u.cval = i;
14647                 LHS(def, i) = piece;
14648         }
14649
14650         return def;
14651 }
14652
14653 struct triple *output_asm(struct compile_state *state)
14654 {
14655         struct asm_info *info;
14656         struct triple *def;
14657         int in;
14658         
14659         info = xcmalloc(sizeof(*info), "asm_info");
14660         info->str = "";
14661
14662         in = sizeof(arch_output_regs)/sizeof(arch_output_regs[0]);
14663         memcpy(&info->tmpl.rhs, arch_output_regs, sizeof(arch_output_regs));
14664
14665         def = new_triple(state, OP_ASM, &void_type, 0, in);
14666         def->u.ainfo = info;
14667         def->id |= TRIPLE_FLAG_VOLATILE;
14668         
14669         return def;
14670 }
14671
14672 static void join_functions(struct compile_state *state)
14673 {
14674         struct triple *jmp, *start, *end, *call, *in, *out, *func;
14675         struct file_state file;
14676         struct type *pnext, *param;
14677         struct type *result_type, *args_type;
14678         int idx;
14679
14680         /* Be clear the functions have not been joined yet */
14681         state->functions_joined = 0;
14682
14683         /* Dummy file state to get debug handing right */
14684         memset(&file, 0, sizeof(file));
14685         file.basename = "";
14686         file.line = 0;
14687         file.report_line = 0;
14688         file.report_name = file.basename;
14689         file.prev = state->file;
14690         state->file = &file;
14691         state->function = "";
14692
14693         if (!state->main_function) {
14694                 error(state, 0, "No functions to compile\n");
14695         }
14696
14697         /* The type of arguments */
14698         args_type   = state->main_function->type->right;
14699         /* The return type without any specifiers */
14700         result_type = clone_type(0, state->main_function->type->left);
14701
14702
14703         /* Verify the external arguments */
14704         if (registers_of(state, args_type) > ARCH_INPUT_REGS) {
14705                 error(state, state->main_function, 
14706                         "Too many external input arguments");
14707         }
14708         if (registers_of(state, result_type) > ARCH_OUTPUT_REGS) {
14709                 error(state, state->main_function, 
14710                         "Too many external output arguments");
14711         }
14712
14713         /* Lay down the basic program structure */
14714         end           = label(state);
14715         start         = label(state);
14716         start         = flatten(state, state->first, start);
14717         end           = flatten(state, state->first, end);
14718         in            = input_asm(state);
14719         out           = output_asm(state);
14720         call          = new_triple(state, OP_FCALL, result_type, -1, registers_of(state, args_type));
14721         MISC(call, 0) = state->main_function;
14722         in            = flatten(state, state->first, in);
14723         call          = flatten(state, state->first, call);
14724         out           = flatten(state, state->first, out);
14725
14726
14727         /* Read the external input arguments */
14728         pnext = args_type;
14729         idx = 0;
14730         while(pnext && ((pnext->type & TYPE_MASK) != TYPE_VOID)) {
14731                 struct triple *expr;
14732                 param = pnext;
14733                 pnext = 0;
14734                 if ((param->type & TYPE_MASK) == TYPE_PRODUCT) {
14735                         pnext = param->right;
14736                         param = param->left;
14737                 }
14738                 if (registers_of(state, param) != 1) {
14739                         error(state, state->main_function, 
14740                                 "Arg: %d %s requires multiple registers", 
14741                                 idx + 1, param->field_ident->name);
14742                 }
14743                 expr = read_expr(state, LHS(in, idx));
14744                 RHS(call, idx) = expr;
14745                 expr = flatten(state, call, expr);
14746                 use_triple(expr, call);
14747
14748                 idx++;  
14749         }
14750
14751
14752         /* Write the external output arguments */
14753         pnext = result_type;
14754         if ((pnext->type & TYPE_MASK) == TYPE_STRUCT) {
14755                 pnext = result_type->left;
14756         }
14757         for(idx = 0; idx < out->rhs; idx++) {
14758                 struct triple *expr;
14759                 param = pnext;
14760                 pnext = 0;
14761                 if (param && ((param->type & TYPE_MASK) == TYPE_PRODUCT)) {
14762                         pnext = param->right;
14763                         param = param->left;
14764                 }
14765                 if (param && ((param->type & TYPE_MASK) == TYPE_VOID)) {
14766                         param = 0;
14767                 }
14768                 if (param) {
14769                         if (registers_of(state, param) != 1) {
14770                                 error(state, state->main_function,
14771                                         "Result: %d %s requires multiple registers",
14772                                         idx, param->field_ident->name);
14773                         }
14774                         expr = read_expr(state, call);
14775                         if ((result_type->type & TYPE_MASK) == TYPE_STRUCT) {
14776                                 expr = deref_field(state, expr, param->field_ident);
14777                         }
14778                 } else {
14779                         expr = triple(state, OP_UNKNOWNVAL, &int_type, 0, 0);
14780                 }
14781                 flatten(state, out, expr);
14782                 RHS(out, idx) = expr;
14783                 use_triple(expr, out);
14784         }
14785
14786         /* Allocate a dummy containing function */
14787         func = triple(state, OP_LIST, 
14788                 new_type(TYPE_FUNCTION, &void_type, &void_type), 0, 0);
14789         func->type->type_ident = lookup(state, "", 0);
14790         RHS(func, 0) = state->first;
14791         func->u.cval = 1;
14792
14793         /* See which functions are called, and how often */
14794         mark_live_functions(state);
14795         inline_functions(state, func);
14796         walk_functions(state, insert_function, end);
14797
14798         if (start->next != end) {
14799                 jmp = flatten(state, start, branch(state, end, 0));
14800         }
14801
14802         /* OK now the functions have been joined. */
14803         state->functions_joined = 1;
14804
14805         /* Done now cleanup */
14806         state->file = file.prev;
14807         state->function = 0;
14808 }
14809
14810 /*
14811  * Data structurs for optimation.
14812  */
14813
14814
14815 static int do_use_block(
14816         struct block *used, struct block_set **head, struct block *user, 
14817         int front)
14818 {
14819         struct block_set **ptr, *new;
14820         if (!used)
14821                 return 0;
14822         if (!user)
14823                 return 0;
14824         ptr = head;
14825         while(*ptr) {
14826                 if ((*ptr)->member == user) {
14827                         return 0;
14828                 }
14829                 ptr = &(*ptr)->next;
14830         }
14831         new = xcmalloc(sizeof(*new), "block_set");
14832         new->member = user;
14833         if (front) {
14834                 new->next = *head;
14835                 *head = new;
14836         }
14837         else {
14838                 new->next = 0;
14839                 *ptr = new;
14840         }
14841         return 1;
14842 }
14843 static int do_unuse_block(
14844         struct block *used, struct block_set **head, struct block *unuser)
14845 {
14846         struct block_set *use, **ptr;
14847         int count;
14848         count = 0;
14849         ptr = head;
14850         while(*ptr) {
14851                 use = *ptr;
14852                 if (use->member == unuser) {
14853                         *ptr = use->next;
14854                         memset(use, -1, sizeof(*use));
14855                         xfree(use);
14856                         count += 1;
14857                 }
14858                 else {
14859                         ptr = &use->next;
14860                 }
14861         }
14862         return count;
14863 }
14864
14865 static void use_block(struct block *used, struct block *user)
14866 {
14867         int count;
14868         /* Append new to the head of the list, print_block
14869          * depends on this.
14870          */
14871         count = do_use_block(used, &used->use, user, 1); 
14872         used->users += count;
14873 }
14874 static void unuse_block(struct block *used, struct block *unuser)
14875 {
14876         int count;
14877         count = do_unuse_block(used, &used->use, unuser); 
14878         used->users -= count;
14879 }
14880
14881 static void add_block_edge(struct block *block, struct block *edge, int front)
14882 {
14883         int count;
14884         count = do_use_block(block, &block->edges, edge, front);
14885         block->edge_count += count;
14886 }
14887
14888 static void remove_block_edge(struct block *block, struct block *edge)
14889 {
14890         int count;
14891         count = do_unuse_block(block, &block->edges, edge);
14892         block->edge_count -= count;
14893 }
14894
14895 static void idom_block(struct block *idom, struct block *user)
14896 {
14897         do_use_block(idom, &idom->idominates, user, 0);
14898 }
14899
14900 static void unidom_block(struct block *idom, struct block *unuser)
14901 {
14902         do_unuse_block(idom, &idom->idominates, unuser);
14903 }
14904
14905 static void domf_block(struct block *block, struct block *domf)
14906 {
14907         do_use_block(block, &block->domfrontier, domf, 0);
14908 }
14909
14910 static void undomf_block(struct block *block, struct block *undomf)
14911 {
14912         do_unuse_block(block, &block->domfrontier, undomf);
14913 }
14914
14915 static void ipdom_block(struct block *ipdom, struct block *user)
14916 {
14917         do_use_block(ipdom, &ipdom->ipdominates, user, 0);
14918 }
14919
14920 static void unipdom_block(struct block *ipdom, struct block *unuser)
14921 {
14922         do_unuse_block(ipdom, &ipdom->ipdominates, unuser);
14923 }
14924
14925 static void ipdomf_block(struct block *block, struct block *ipdomf)
14926 {
14927         do_use_block(block, &block->ipdomfrontier, ipdomf, 0);
14928 }
14929
14930 static void unipdomf_block(struct block *block, struct block *unipdomf)
14931 {
14932         do_unuse_block(block, &block->ipdomfrontier, unipdomf);
14933 }
14934
14935 static int walk_triples(
14936         struct compile_state *state, 
14937         int (*cb)(struct compile_state *state, struct triple *ptr, void *arg),
14938         void *arg)
14939 {
14940         struct triple *ptr;
14941         int result;
14942         ptr = state->first;
14943         do {
14944                 result = cb(state, ptr, arg);
14945                 if (ptr->next->prev != ptr) {
14946                         internal_error(state, ptr->next, "bad prev");
14947                 }
14948                 ptr = ptr->next;
14949         } while((result == 0) && (ptr != state->first));
14950         return result;
14951 }
14952
14953 #define PRINT_LIST 1
14954 static int do_print_triple(struct compile_state *state, struct triple *ins, void *arg)
14955 {
14956         FILE *fp = arg;
14957         int op;
14958         op = ins->op;
14959         if (op == OP_LIST) {
14960 #if !PRINT_LIST
14961                 return 0;
14962 #endif
14963         }
14964         if ((op == OP_LABEL) && (ins->use)) {
14965                 fprintf(fp, "\n%p:\n", ins);
14966         }
14967         display_triple(fp, ins);
14968
14969         if (triple_is_branch(state, ins) && ins->use && 
14970                 (ins->op != OP_RET) && (ins->op != OP_FCALL)) {
14971                 internal_error(state, ins, "branch used?");
14972         }
14973         if (triple_is_branch(state, ins)) {
14974                 fprintf(fp, "\n");
14975         }
14976         return 0;
14977 }
14978
14979 static void print_triples(struct compile_state *state)
14980 {
14981         if (state->compiler->debug & DEBUG_TRIPLES) {
14982                 FILE *fp = state->dbgout;
14983                 fprintf(fp, "--------------- triples ---------------\n");
14984                 walk_triples(state, do_print_triple, fp);
14985                 fprintf(fp, "\n");
14986         }
14987 }
14988
14989 struct cf_block {
14990         struct block *block;
14991 };
14992 static void find_cf_blocks(struct cf_block *cf, struct block *block)
14993 {
14994         struct block_set *edge;
14995         if (!block || (cf[block->vertex].block == block)) {
14996                 return;
14997         }
14998         cf[block->vertex].block = block;
14999         for(edge = block->edges; edge; edge = edge->next) {
15000                 find_cf_blocks(cf, edge->member);
15001         }
15002 }
15003
15004 static void print_control_flow(struct compile_state *state,
15005         FILE *fp, struct basic_blocks *bb)
15006 {
15007         struct cf_block *cf;
15008         int i;
15009         fprintf(fp, "\ncontrol flow\n");
15010         cf = xcmalloc(sizeof(*cf) * (bb->last_vertex + 1), "cf_block");
15011         find_cf_blocks(cf, bb->first_block);
15012
15013         for(i = 1; i <= bb->last_vertex; i++) {
15014                 struct block *block;
15015                 struct block_set *edge;
15016                 block = cf[i].block;
15017                 if (!block)
15018                         continue;
15019                 fprintf(fp, "(%p) %d:", block, block->vertex);
15020                 for(edge = block->edges; edge; edge = edge->next) {
15021                         fprintf(fp, " %d", edge->member->vertex);
15022                 }
15023                 fprintf(fp, "\n");
15024         }
15025
15026         xfree(cf);
15027 }
15028
15029 static void free_basic_block(struct compile_state *state, struct block *block)
15030 {
15031         struct block_set *edge, *entry;
15032         struct block *child;
15033         if (!block) {
15034                 return;
15035         }
15036         if (block->vertex == -1) {
15037                 return;
15038         }
15039         block->vertex = -1;
15040         for(edge = block->edges; edge; edge = edge->next) {
15041                 if (edge->member) {
15042                         unuse_block(edge->member, block);
15043                 }
15044         }
15045         if (block->idom) {
15046                 unidom_block(block->idom, block);
15047         }
15048         block->idom = 0;
15049         if (block->ipdom) {
15050                 unipdom_block(block->ipdom, block);
15051         }
15052         block->ipdom = 0;
15053         while((entry = block->use)) {
15054                 child = entry->member;
15055                 unuse_block(block, child);
15056                 if (child && (child->vertex != -1)) {
15057                         for(edge = child->edges; edge; edge = edge->next) {
15058                                 edge->member = 0;
15059                         }
15060                 }
15061         }
15062         while((entry = block->idominates)) {
15063                 child = entry->member;
15064                 unidom_block(block, child);
15065                 if (child && (child->vertex != -1)) {
15066                         child->idom = 0;
15067                 }
15068         }
15069         while((entry = block->domfrontier)) {
15070                 child = entry->member;
15071                 undomf_block(block, child);
15072         }
15073         while((entry = block->ipdominates)) {
15074                 child = entry->member;
15075                 unipdom_block(block, child);
15076                 if (child && (child->vertex != -1)) {
15077                         child->ipdom = 0;
15078                 }
15079         }
15080         while((entry = block->ipdomfrontier)) {
15081                 child = entry->member;
15082                 unipdomf_block(block, child);
15083         }
15084         if (block->users != 0) {
15085                 internal_error(state, 0, "block still has users");
15086         }
15087         while((edge = block->edges)) {
15088                 child = edge->member;
15089                 remove_block_edge(block, child);
15090                 
15091                 if (child && (child->vertex != -1)) {
15092                         free_basic_block(state, child);
15093                 }
15094         }
15095         memset(block, -1, sizeof(*block));
15096         xfree(block);
15097 }
15098
15099 static void free_basic_blocks(struct compile_state *state, 
15100         struct basic_blocks *bb)
15101 {
15102         struct triple *first, *ins;
15103         free_basic_block(state, bb->first_block);
15104         bb->last_vertex = 0;
15105         bb->first_block = bb->last_block = 0;
15106         first = bb->first;
15107         ins = first;
15108         do {
15109                 if (triple_stores_block(state, ins)) {
15110                         ins->u.block = 0;
15111                 }
15112                 ins = ins->next;
15113         } while(ins != first);
15114         
15115 }
15116
15117 static struct block *basic_block(struct compile_state *state, 
15118         struct basic_blocks *bb, struct triple *first)
15119 {
15120         struct block *block;
15121         struct triple *ptr;
15122         if (!triple_is_label(state, first)) {
15123                 internal_error(state, first, "block does not start with a label");
15124         }
15125         /* See if this basic block has already been setup */
15126         if (first->u.block != 0) {
15127                 return first->u.block;
15128         }
15129         /* Allocate another basic block structure */
15130         bb->last_vertex += 1;
15131         block = xcmalloc(sizeof(*block), "block");
15132         block->first = block->last = first;
15133         block->vertex = bb->last_vertex;
15134         ptr = first;
15135         do {
15136                 if ((ptr != first) && triple_is_label(state, ptr) && (ptr->use)) { 
15137                         break;
15138                 }
15139                 block->last = ptr;
15140                 /* If ptr->u is not used remember where the baic block is */
15141                 if (triple_stores_block(state, ptr)) {
15142                         ptr->u.block = block;
15143                 }
15144                 if (triple_is_branch(state, ptr)) {
15145                         break;
15146                 }
15147                 ptr = ptr->next;
15148         } while (ptr != bb->first);
15149         if ((ptr == bb->first) ||
15150                 ((ptr->next == bb->first) && (
15151                         triple_is_end(state, ptr) || 
15152                         triple_is_ret(state, ptr))))
15153         {
15154                 /* The block has no outflowing edges */
15155         }
15156         else if (triple_is_label(state, ptr)) {
15157                 struct block *next;
15158                 next = basic_block(state, bb, ptr);
15159                 add_block_edge(block, next, 0);
15160                 use_block(next, block);
15161         }
15162         else if (triple_is_branch(state, ptr)) {
15163                 struct triple **expr, *first;
15164                 struct block *child;
15165                 /* Find the branch targets.
15166                  * I special case the first branch as that magically
15167                  * avoids some difficult cases for the register allocator.
15168                  */
15169                 expr = triple_edge_targ(state, ptr, 0);
15170                 if (!expr) {
15171                         internal_error(state, ptr, "branch without targets");
15172                 }
15173                 first = *expr;
15174                 expr = triple_edge_targ(state, ptr, expr);
15175                 for(; expr; expr = triple_edge_targ(state, ptr, expr)) {
15176                         if (!*expr) continue;
15177                         child = basic_block(state, bb, *expr);
15178                         use_block(child, block);
15179                         add_block_edge(block, child, 0);
15180                 }
15181                 if (first) {
15182                         child = basic_block(state, bb, first);
15183                         use_block(child, block);
15184                         add_block_edge(block, child, 1);
15185
15186                         /* Be certain the return block of a call is
15187                          * in a basic block.  When it is not find
15188                          * start of the block, insert a label if
15189                          * necessary and build the basic block.
15190                          * Then add a fake edge from the start block
15191                          * to the return block of the function.
15192                          */
15193                         if (state->functions_joined && triple_is_call(state, ptr)
15194                                 && !block_of_triple(state, MISC(ptr, 0))) {
15195                                 struct block *tail;
15196                                 struct triple *start;
15197                                 start = triple_to_block_start(state, MISC(ptr, 0));
15198                                 if (!triple_is_label(state, start)) {
15199                                         start = pre_triple(state,
15200                                                 start, OP_LABEL, &void_type, 0, 0);
15201                                 }
15202                                 tail = basic_block(state, bb, start);
15203                                 add_block_edge(child, tail, 0);
15204                                 use_block(tail, child);
15205                         }
15206                 }
15207         }
15208         else {
15209                 internal_error(state, 0, "Bad basic block split");
15210         }
15211 #if 0
15212 {
15213         struct block_set *edge;
15214         FILE *fp = state->errout;
15215         fprintf(fp, "basic_block: %10p [%2d] ( %10p - %10p )",
15216                 block, block->vertex, 
15217                 block->first, block->last);
15218         for(edge = block->edges; edge; edge = edge->next) {
15219                 fprintf(fp, " %10p [%2d]",
15220                         edge->member ? edge->member->first : 0,
15221                         edge->member ? edge->member->vertex : -1);
15222         }
15223         fprintf(fp, "\n");
15224 }
15225 #endif
15226         return block;
15227 }
15228
15229
15230 static void walk_blocks(struct compile_state *state, struct basic_blocks *bb,
15231         void (*cb)(struct compile_state *state, struct block *block, void *arg),
15232         void *arg)
15233 {
15234         struct triple *ptr, *first;
15235         struct block *last_block;
15236         last_block = 0;
15237         first = bb->first;
15238         ptr = first;
15239         do {
15240                 if (triple_stores_block(state, ptr)) {
15241                         struct block *block;
15242                         block = ptr->u.block;
15243                         if (block && (block != last_block)) {
15244                                 cb(state, block, arg);
15245                         }
15246                         last_block = block;
15247                 }
15248                 ptr = ptr->next;
15249         } while(ptr != first);
15250 }
15251
15252 static void print_block(
15253         struct compile_state *state, struct block *block, void *arg)
15254 {
15255         struct block_set *user, *edge;
15256         struct triple *ptr;
15257         FILE *fp = arg;
15258
15259         fprintf(fp, "\nblock: %p (%d) ",
15260                 block, 
15261                 block->vertex);
15262
15263         for(edge = block->edges; edge; edge = edge->next) {
15264                 fprintf(fp, " %p<-%p",
15265                         edge->member,
15266                         (edge->member && edge->member->use)?
15267                         edge->member->use->member : 0);
15268         }
15269         fprintf(fp, "\n");
15270         if (block->first->op == OP_LABEL) {
15271                 fprintf(fp, "%p:\n", block->first);
15272         }
15273         for(ptr = block->first; ; ) {
15274                 display_triple(fp, ptr);
15275                 if (ptr == block->last)
15276                         break;
15277                 ptr = ptr->next;
15278                 if (ptr == block->first) {
15279                         internal_error(state, 0, "missing block last?");
15280                 }
15281         }
15282         fprintf(fp, "users %d: ", block->users);
15283         for(user = block->use; user; user = user->next) {
15284                 fprintf(fp, "%p (%d) ", 
15285                         user->member,
15286                         user->member->vertex);
15287         }
15288         fprintf(fp,"\n\n");
15289 }
15290
15291
15292 static void romcc_print_blocks(struct compile_state *state, FILE *fp)
15293 {
15294         fprintf(fp, "--------------- blocks ---------------\n");
15295         walk_blocks(state, &state->bb, print_block, fp);
15296 }
15297 static void print_blocks(struct compile_state *state, const char *func, FILE *fp)
15298 {
15299         if (state->compiler->debug & DEBUG_BASIC_BLOCKS) {
15300                 fprintf(fp, "After %s\n", func);
15301                 romcc_print_blocks(state, fp);
15302                 if (state->compiler->debug & DEBUG_FDOMINATORS) {
15303                         print_dominators(state, fp, &state->bb);
15304                         print_dominance_frontiers(state, fp, &state->bb);
15305                 }
15306                 print_control_flow(state, fp, &state->bb);
15307         }
15308 }
15309
15310 static void prune_nonblock_triples(struct compile_state *state, 
15311         struct basic_blocks *bb)
15312 {
15313         struct block *block;
15314         struct triple *first, *ins, *next;
15315         /* Delete the triples not in a basic block */
15316         block = 0;
15317         first = bb->first;
15318         ins = first;
15319         do {
15320                 next = ins->next;
15321                 if (ins->op == OP_LABEL) {
15322                         block = ins->u.block;
15323                 }
15324                 if (!block) {
15325                         struct triple_set *use;
15326                         for(use = ins->use; use; use = use->next) {
15327                                 struct block *block;
15328                                 block = block_of_triple(state, use->member);
15329                                 if (block != 0) {
15330                                         internal_error(state, ins, "pruning used ins?");
15331                                 }
15332                         }
15333                         release_triple(state, ins);
15334                 }
15335                 if (block && block->last == ins) {
15336                         block = 0;
15337                 }
15338                 ins = next;
15339         } while(ins != first);
15340 }
15341
15342 static void setup_basic_blocks(struct compile_state *state, 
15343         struct basic_blocks *bb)
15344 {
15345         if (!triple_stores_block(state, bb->first)) {
15346                 internal_error(state, 0, "ins will not store block?");
15347         }
15348         /* Initialize the state */
15349         bb->first_block = bb->last_block = 0;
15350         bb->last_vertex = 0;
15351         free_basic_blocks(state, bb);
15352
15353         /* Find the basic blocks */
15354         bb->first_block = basic_block(state, bb, bb->first);
15355
15356         /* Be certain the last instruction of a function, or the
15357          * entire program is in a basic block.  When it is not find 
15358          * the start of the block, insert a label if necessary and build 
15359          * basic block.  Then add a fake edge from the start block
15360          * to the final block.
15361          */
15362         if (!block_of_triple(state, bb->first->prev)) {
15363                 struct triple *start;
15364                 struct block *tail;
15365                 start = triple_to_block_start(state, bb->first->prev);
15366                 if (!triple_is_label(state, start)) {
15367                         start = pre_triple(state,
15368                                 start, OP_LABEL, &void_type, 0, 0);
15369                 }
15370                 tail = basic_block(state, bb, start);
15371                 add_block_edge(bb->first_block, tail, 0);
15372                 use_block(tail, bb->first_block);
15373         }
15374         
15375         /* Find the last basic block.
15376          */
15377         bb->last_block = block_of_triple(state, bb->first->prev);
15378
15379         /* Delete the triples not in a basic block */
15380         prune_nonblock_triples(state, bb);
15381
15382 #if 0
15383         /* If we are debugging print what I have just done */
15384         if (state->compiler->debug & DEBUG_BASIC_BLOCKS) {
15385                 print_blocks(state, state->dbgout);
15386                 print_control_flow(state, bb);
15387         }
15388 #endif
15389 }
15390
15391
15392 struct sdom_block {
15393         struct block *block;
15394         struct sdom_block *sdominates;
15395         struct sdom_block *sdom_next;
15396         struct sdom_block *sdom;
15397         struct sdom_block *label;
15398         struct sdom_block *parent;
15399         struct sdom_block *ancestor;
15400         int vertex;
15401 };
15402
15403
15404 static void unsdom_block(struct sdom_block *block)
15405 {
15406         struct sdom_block **ptr;
15407         if (!block->sdom_next) {
15408                 return;
15409         }
15410         ptr = &block->sdom->sdominates;
15411         while(*ptr) {
15412                 if ((*ptr) == block) {
15413                         *ptr = block->sdom_next;
15414                         return;
15415                 }
15416                 ptr = &(*ptr)->sdom_next;
15417         }
15418 }
15419
15420 static void sdom_block(struct sdom_block *sdom, struct sdom_block *block)
15421 {
15422         unsdom_block(block);
15423         block->sdom = sdom;
15424         block->sdom_next = sdom->sdominates;
15425         sdom->sdominates = block;
15426 }
15427
15428
15429
15430 static int initialize_sdblock(struct sdom_block *sd,
15431         struct block *parent, struct block *block, int vertex)
15432 {
15433         struct block_set *edge;
15434         if (!block || (sd[block->vertex].block == block)) {
15435                 return vertex;
15436         }
15437         vertex += 1;
15438         /* Renumber the blocks in a convinient fashion */
15439         block->vertex = vertex;
15440         sd[vertex].block    = block;
15441         sd[vertex].sdom     = &sd[vertex];
15442         sd[vertex].label    = &sd[vertex];
15443         sd[vertex].parent   = parent? &sd[parent->vertex] : 0;
15444         sd[vertex].ancestor = 0;
15445         sd[vertex].vertex   = vertex;
15446         for(edge = block->edges; edge; edge = edge->next) {
15447                 vertex = initialize_sdblock(sd, block, edge->member, vertex);
15448         }
15449         return vertex;
15450 }
15451
15452 static int initialize_spdblock(
15453         struct compile_state *state, struct sdom_block *sd,
15454         struct block *parent, struct block *block, int vertex)
15455 {
15456         struct block_set *user;
15457         if (!block || (sd[block->vertex].block == block)) {
15458                 return vertex;
15459         }
15460         vertex += 1;
15461         /* Renumber the blocks in a convinient fashion */
15462         block->vertex = vertex;
15463         sd[vertex].block    = block;
15464         sd[vertex].sdom     = &sd[vertex];
15465         sd[vertex].label    = &sd[vertex];
15466         sd[vertex].parent   = parent? &sd[parent->vertex] : 0;
15467         sd[vertex].ancestor = 0;
15468         sd[vertex].vertex   = vertex;
15469         for(user = block->use; user; user = user->next) {
15470                 vertex = initialize_spdblock(state, sd, block, user->member, vertex);
15471         }
15472         return vertex;
15473 }
15474
15475 static int setup_spdblocks(struct compile_state *state, 
15476         struct basic_blocks *bb, struct sdom_block *sd)
15477 {
15478         struct block *block;
15479         int vertex;
15480         /* Setup as many sdpblocks as possible without using fake edges */
15481         vertex = initialize_spdblock(state, sd, 0, bb->last_block, 0);
15482
15483         /* Walk through the graph and find unconnected blocks.  Add a
15484          * fake edge from the unconnected blocks to the end of the
15485          * graph. 
15486          */
15487         block = bb->first_block->last->next->u.block;
15488         for(; block && block != bb->first_block; block = block->last->next->u.block) {
15489                 if (sd[block->vertex].block == block) {
15490                         continue;
15491                 }
15492 #if DEBUG_SDP_BLOCKS
15493                 {
15494                         FILE *fp = state->errout;
15495                         fprintf(fp, "Adding %d\n", vertex +1);
15496                 }
15497 #endif
15498                 add_block_edge(block, bb->last_block, 0);
15499                 use_block(bb->last_block, block);
15500
15501                 vertex = initialize_spdblock(state, sd, bb->last_block, block, vertex);
15502         }
15503         return vertex;
15504 }
15505
15506 static void compress_ancestors(struct sdom_block *v)
15507 {
15508         /* This procedure assumes ancestor(v) != 0 */
15509         /* if (ancestor(ancestor(v)) != 0) {
15510          *      compress(ancestor(ancestor(v)));
15511          *      if (semi(label(ancestor(v))) < semi(label(v))) {
15512          *              label(v) = label(ancestor(v));
15513          *      }
15514          *      ancestor(v) = ancestor(ancestor(v));
15515          * }
15516          */
15517         if (!v->ancestor) {
15518                 return;
15519         }
15520         if (v->ancestor->ancestor) {
15521                 compress_ancestors(v->ancestor->ancestor);
15522                 if (v->ancestor->label->sdom->vertex < v->label->sdom->vertex) {
15523                         v->label = v->ancestor->label;
15524                 }
15525                 v->ancestor = v->ancestor->ancestor;
15526         }
15527 }
15528
15529 static void compute_sdom(struct compile_state *state, 
15530         struct basic_blocks *bb, struct sdom_block *sd)
15531 {
15532         int i;
15533         /* // step 2 
15534          *  for each v <= pred(w) {
15535          *      u = EVAL(v);
15536          *      if (semi[u] < semi[w] { 
15537          *              semi[w] = semi[u]; 
15538          *      } 
15539          * }
15540          * add w to bucket(vertex(semi[w]));
15541          * LINK(parent(w), w);
15542          *
15543          * // step 3
15544          * for each v <= bucket(parent(w)) {
15545          *      delete v from bucket(parent(w));
15546          *      u = EVAL(v);
15547          *      dom(v) = (semi[u] < semi[v]) ? u : parent(w);
15548          * }
15549          */
15550         for(i = bb->last_vertex; i >= 2; i--) {
15551                 struct sdom_block *v, *parent, *next;
15552                 struct block_set *user;
15553                 struct block *block;
15554                 block = sd[i].block;
15555                 parent = sd[i].parent;
15556                 /* Step 2 */
15557                 for(user = block->use; user; user = user->next) {
15558                         struct sdom_block *v, *u;
15559                         v = &sd[user->member->vertex];
15560                         u = !(v->ancestor)? v : (compress_ancestors(v), v->label);
15561                         if (u->sdom->vertex < sd[i].sdom->vertex) {
15562                                 sd[i].sdom = u->sdom;
15563                         }
15564                 }
15565                 sdom_block(sd[i].sdom, &sd[i]);
15566                 sd[i].ancestor = parent;
15567                 /* Step 3 */
15568                 for(v = parent->sdominates; v; v = next) {
15569                         struct sdom_block *u;
15570                         next = v->sdom_next;
15571                         unsdom_block(v);
15572                         u = (!v->ancestor) ? v : (compress_ancestors(v), v->label);
15573                         v->block->idom = (u->sdom->vertex < v->sdom->vertex)? 
15574                                 u->block : parent->block;
15575                 }
15576         }
15577 }
15578
15579 static void compute_spdom(struct compile_state *state, 
15580         struct basic_blocks *bb, struct sdom_block *sd)
15581 {
15582         int i;
15583         /* // step 2 
15584          *  for each v <= pred(w) {
15585          *      u = EVAL(v);
15586          *      if (semi[u] < semi[w] { 
15587          *              semi[w] = semi[u]; 
15588          *      } 
15589          * }
15590          * add w to bucket(vertex(semi[w]));
15591          * LINK(parent(w), w);
15592          *
15593          * // step 3
15594          * for each v <= bucket(parent(w)) {
15595          *      delete v from bucket(parent(w));
15596          *      u = EVAL(v);
15597          *      dom(v) = (semi[u] < semi[v]) ? u : parent(w);
15598          * }
15599          */
15600         for(i = bb->last_vertex; i >= 2; i--) {
15601                 struct sdom_block *u, *v, *parent, *next;
15602                 struct block_set *edge;
15603                 struct block *block;
15604                 block = sd[i].block;
15605                 parent = sd[i].parent;
15606                 /* Step 2 */
15607                 for(edge = block->edges; edge; edge = edge->next) {
15608                         v = &sd[edge->member->vertex];
15609                         u = !(v->ancestor)? v : (compress_ancestors(v), v->label);
15610                         if (u->sdom->vertex < sd[i].sdom->vertex) {
15611                                 sd[i].sdom = u->sdom;
15612                         }
15613                 }
15614                 sdom_block(sd[i].sdom, &sd[i]);
15615                 sd[i].ancestor = parent;
15616                 /* Step 3 */
15617                 for(v = parent->sdominates; v; v = next) {
15618                         struct sdom_block *u;
15619                         next = v->sdom_next;
15620                         unsdom_block(v);
15621                         u = (!v->ancestor) ? v : (compress_ancestors(v), v->label);
15622                         v->block->ipdom = (u->sdom->vertex < v->sdom->vertex)? 
15623                                 u->block : parent->block;
15624                 }
15625         }
15626 }
15627
15628 static void compute_idom(struct compile_state *state, 
15629         struct basic_blocks *bb, struct sdom_block *sd)
15630 {
15631         int i;
15632         for(i = 2; i <= bb->last_vertex; i++) {
15633                 struct block *block;
15634                 block = sd[i].block;
15635                 if (block->idom->vertex != sd[i].sdom->vertex) {
15636                         block->idom = block->idom->idom;
15637                 }
15638                 idom_block(block->idom, block);
15639         }
15640         sd[1].block->idom = 0;
15641 }
15642
15643 static void compute_ipdom(struct compile_state *state, 
15644         struct basic_blocks *bb, struct sdom_block *sd)
15645 {
15646         int i;
15647         for(i = 2; i <= bb->last_vertex; i++) {
15648                 struct block *block;
15649                 block = sd[i].block;
15650                 if (block->ipdom->vertex != sd[i].sdom->vertex) {
15651                         block->ipdom = block->ipdom->ipdom;
15652                 }
15653                 ipdom_block(block->ipdom, block);
15654         }
15655         sd[1].block->ipdom = 0;
15656 }
15657
15658         /* Theorem 1:
15659          *   Every vertex of a flowgraph G = (V, E, r) except r has
15660          *   a unique immediate dominator.  
15661          *   The edges {(idom(w), w) |w <= V - {r}} form a directed tree
15662          *   rooted at r, called the dominator tree of G, such that 
15663          *   v dominates w if and only if v is a proper ancestor of w in
15664          *   the dominator tree.
15665          */
15666         /* Lemma 1:  
15667          *   If v and w are vertices of G such that v <= w,
15668          *   than any path from v to w must contain a common ancestor
15669          *   of v and w in T.
15670          */
15671         /* Lemma 2:  For any vertex w != r, idom(w) -> w */
15672         /* Lemma 3:  For any vertex w != r, sdom(w) -> w */
15673         /* Lemma 4:  For any vertex w != r, idom(w) -> sdom(w) */
15674         /* Theorem 2:
15675          *   Let w != r.  Suppose every u for which sdom(w) -> u -> w satisfies
15676          *   sdom(u) >= sdom(w).  Then idom(w) = sdom(w).
15677          */
15678         /* Theorem 3:
15679          *   Let w != r and let u be a vertex for which sdom(u) is 
15680          *   minimum amoung vertices u satisfying sdom(w) -> u -> w.
15681          *   Then sdom(u) <= sdom(w) and idom(u) = idom(w).
15682          */
15683         /* Lemma 5:  Let vertices v,w satisfy v -> w.
15684          *           Then v -> idom(w) or idom(w) -> idom(v)
15685          */
15686
15687 static void find_immediate_dominators(struct compile_state *state,
15688         struct basic_blocks *bb)
15689 {
15690         struct sdom_block *sd;
15691         /* w->sdom = min{v| there is a path v = v0,v1,...,vk = w such that:
15692          *           vi > w for (1 <= i <= k - 1}
15693          */
15694         /* Theorem 4:
15695          *   For any vertex w != r.
15696          *   sdom(w) = min(
15697          *                 {v|(v,w) <= E  and v < w } U 
15698          *                 {sdom(u) | u > w and there is an edge (v, w) such that u -> v})
15699          */
15700         /* Corollary 1:
15701          *   Let w != r and let u be a vertex for which sdom(u) is 
15702          *   minimum amoung vertices u satisfying sdom(w) -> u -> w.
15703          *   Then:
15704          *                   { sdom(w) if sdom(w) = sdom(u),
15705          *        idom(w) = {
15706          *                   { idom(u) otherwise
15707          */
15708         /* The algorithm consists of the following 4 steps.
15709          * Step 1.  Carry out a depth-first search of the problem graph.  
15710          *    Number the vertices from 1 to N as they are reached during
15711          *    the search.  Initialize the variables used in succeeding steps.
15712          * Step 2.  Compute the semidominators of all vertices by applying
15713          *    theorem 4.   Carry out the computation vertex by vertex in
15714          *    decreasing order by number.
15715          * Step 3.  Implicitly define the immediate dominator of each vertex
15716          *    by applying Corollary 1.
15717          * Step 4.  Explicitly define the immediate dominator of each vertex,
15718          *    carrying out the computation vertex by vertex in increasing order
15719          *    by number.
15720          */
15721         /* Step 1 initialize the basic block information */
15722         sd = xcmalloc(sizeof(*sd) * (bb->last_vertex + 1), "sdom_state");
15723         initialize_sdblock(sd, 0, bb->first_block, 0);
15724 #if 0
15725         sd[1].size  = 0;
15726         sd[1].label = 0;
15727         sd[1].sdom  = 0;
15728 #endif
15729         /* Step 2 compute the semidominators */
15730         /* Step 3 implicitly define the immediate dominator of each vertex */
15731         compute_sdom(state, bb, sd);
15732         /* Step 4 explicitly define the immediate dominator of each vertex */
15733         compute_idom(state, bb, sd);
15734         xfree(sd);
15735 }
15736
15737 static void find_post_dominators(struct compile_state *state,
15738         struct basic_blocks *bb)
15739 {
15740         struct sdom_block *sd;
15741         int vertex;
15742         /* Step 1 initialize the basic block information */
15743         sd = xcmalloc(sizeof(*sd) * (bb->last_vertex + 1), "sdom_state");
15744
15745         vertex = setup_spdblocks(state, bb, sd);
15746         if (vertex != bb->last_vertex) {
15747                 internal_error(state, 0, "missing %d blocks",
15748                         bb->last_vertex - vertex);
15749         }
15750
15751         /* Step 2 compute the semidominators */
15752         /* Step 3 implicitly define the immediate dominator of each vertex */
15753         compute_spdom(state, bb, sd);
15754         /* Step 4 explicitly define the immediate dominator of each vertex */
15755         compute_ipdom(state, bb, sd);
15756         xfree(sd);
15757 }
15758
15759
15760
15761 static void find_block_domf(struct compile_state *state, struct block *block)
15762 {
15763         struct block *child;
15764         struct block_set *user, *edge;
15765         if (block->domfrontier != 0) {
15766                 internal_error(state, block->first, "domfrontier present?");
15767         }
15768         for(user = block->idominates; user; user = user->next) {
15769                 child = user->member;
15770                 if (child->idom != block) {
15771                         internal_error(state, block->first, "bad idom");
15772                 }
15773                 find_block_domf(state, child);
15774         }
15775         for(edge = block->edges; edge; edge = edge->next) {
15776                 if (edge->member->idom != block) {
15777                         domf_block(block, edge->member);
15778                 }
15779         }
15780         for(user = block->idominates; user; user = user->next) {
15781                 struct block_set *frontier;
15782                 child = user->member;
15783                 for(frontier = child->domfrontier; frontier; frontier = frontier->next) {
15784                         if (frontier->member->idom != block) {
15785                                 domf_block(block, frontier->member);
15786                         }
15787                 }
15788         }
15789 }
15790
15791 static void find_block_ipdomf(struct compile_state *state, struct block *block)
15792 {
15793         struct block *child;
15794         struct block_set *user;
15795         if (block->ipdomfrontier != 0) {
15796                 internal_error(state, block->first, "ipdomfrontier present?");
15797         }
15798         for(user = block->ipdominates; user; user = user->next) {
15799                 child = user->member;
15800                 if (child->ipdom != block) {
15801                         internal_error(state, block->first, "bad ipdom");
15802                 }
15803                 find_block_ipdomf(state, child);
15804         }
15805         for(user = block->use; user; user = user->next) {
15806                 if (user->member->ipdom != block) {
15807                         ipdomf_block(block, user->member);
15808                 }
15809         }
15810         for(user = block->ipdominates; user; user = user->next) {
15811                 struct block_set *frontier;
15812                 child = user->member;
15813                 for(frontier = child->ipdomfrontier; frontier; frontier = frontier->next) {
15814                         if (frontier->member->ipdom != block) {
15815                                 ipdomf_block(block, frontier->member);
15816                         }
15817                 }
15818         }
15819 }
15820
15821 static void print_dominated(
15822         struct compile_state *state, struct block *block, void *arg)
15823 {
15824         struct block_set *user;
15825         FILE *fp = arg;
15826
15827         fprintf(fp, "%d:", block->vertex);
15828         for(user = block->idominates; user; user = user->next) {
15829                 fprintf(fp, " %d", user->member->vertex);
15830                 if (user->member->idom != block) {
15831                         internal_error(state, user->member->first, "bad idom");
15832                 }
15833         }
15834         fprintf(fp,"\n");
15835 }
15836
15837 static void print_dominated2(
15838         struct compile_state *state, FILE *fp, int depth, struct block *block)
15839 {
15840         struct block_set *user;
15841         struct triple *ins;
15842         struct occurance *ptr, *ptr2;
15843         const char *filename1, *filename2;
15844         int equal_filenames;
15845         int i;
15846         for(i = 0; i < depth; i++) {
15847                 fprintf(fp, "   ");
15848         }
15849         fprintf(fp, "%3d: %p (%p - %p) @", 
15850                 block->vertex, block, block->first, block->last);
15851         ins = block->first;
15852         while(ins != block->last && (ins->occurance->line == 0)) {
15853                 ins = ins->next;
15854         }
15855         ptr = ins->occurance;
15856         ptr2 = block->last->occurance;
15857         filename1 = ptr->filename? ptr->filename : "";
15858         filename2 = ptr2->filename? ptr2->filename : "";
15859         equal_filenames = (strcmp(filename1, filename2) == 0);
15860         if ((ptr == ptr2) || (equal_filenames && ptr->line == ptr2->line)) {
15861                 fprintf(fp, " %s:%d", ptr->filename, ptr->line);
15862         } else if (equal_filenames) {
15863                 fprintf(fp, " %s:(%d - %d)",
15864                         ptr->filename, ptr->line, ptr2->line);
15865         } else {
15866                 fprintf(fp, " (%s:%d - %s:%d)",
15867                         ptr->filename, ptr->line,
15868                         ptr2->filename, ptr2->line);
15869         }
15870         fprintf(fp, "\n");
15871         for(user = block->idominates; user; user = user->next) {
15872                 print_dominated2(state, fp, depth + 1, user->member);
15873         }
15874 }
15875
15876 static void print_dominators(struct compile_state *state, FILE *fp, struct basic_blocks *bb)
15877 {
15878         fprintf(fp, "\ndominates\n");
15879         walk_blocks(state, bb, print_dominated, fp);
15880         fprintf(fp, "dominates\n");
15881         print_dominated2(state, fp, 0, bb->first_block);
15882 }
15883
15884
15885 static int print_frontiers(
15886         struct compile_state *state, FILE *fp, struct block *block, int vertex)
15887 {
15888         struct block_set *user, *edge;
15889
15890         if (!block || (block->vertex != vertex + 1)) {
15891                 return vertex;
15892         }
15893         vertex += 1;
15894
15895         fprintf(fp, "%d:", block->vertex);
15896         for(user = block->domfrontier; user; user = user->next) {
15897                 fprintf(fp, " %d", user->member->vertex);
15898         }
15899         fprintf(fp, "\n");
15900         
15901         for(edge = block->edges; edge; edge = edge->next) {
15902                 vertex = print_frontiers(state, fp, edge->member, vertex);
15903         }
15904         return vertex;
15905 }
15906 static void print_dominance_frontiers(struct compile_state *state,
15907         FILE *fp, struct basic_blocks *bb)
15908 {
15909         fprintf(fp, "\ndominance frontiers\n");
15910         print_frontiers(state, fp, bb->first_block, 0);
15911         
15912 }
15913
15914 static void analyze_idominators(struct compile_state *state, struct basic_blocks *bb)
15915 {
15916         /* Find the immediate dominators */
15917         find_immediate_dominators(state, bb);
15918         /* Find the dominance frontiers */
15919         find_block_domf(state, bb->first_block);
15920         /* If debuging print the print what I have just found */
15921         if (state->compiler->debug & DEBUG_FDOMINATORS) {
15922                 print_dominators(state, state->dbgout, bb);
15923                 print_dominance_frontiers(state, state->dbgout, bb);
15924                 print_control_flow(state, state->dbgout, bb);
15925         }
15926 }
15927
15928
15929 static void print_ipdominated(
15930         struct compile_state *state, struct block *block, void *arg)
15931 {
15932         struct block_set *user;
15933         FILE *fp = arg;
15934
15935         fprintf(fp, "%d:", block->vertex);
15936         for(user = block->ipdominates; user; user = user->next) {
15937                 fprintf(fp, " %d", user->member->vertex);
15938                 if (user->member->ipdom != block) {
15939                         internal_error(state, user->member->first, "bad ipdom");
15940                 }
15941         }
15942         fprintf(fp, "\n");
15943 }
15944
15945 static void print_ipdominators(struct compile_state *state, FILE *fp,
15946         struct basic_blocks *bb)
15947 {
15948         fprintf(fp, "\nipdominates\n");
15949         walk_blocks(state, bb, print_ipdominated, fp);
15950 }
15951
15952 static int print_pfrontiers(
15953         struct compile_state *state, FILE *fp, struct block *block, int vertex)
15954 {
15955         struct block_set *user;
15956
15957         if (!block || (block->vertex != vertex + 1)) {
15958                 return vertex;
15959         }
15960         vertex += 1;
15961
15962         fprintf(fp, "%d:", block->vertex);
15963         for(user = block->ipdomfrontier; user; user = user->next) {
15964                 fprintf(fp, " %d", user->member->vertex);
15965         }
15966         fprintf(fp, "\n");
15967         for(user = block->use; user; user = user->next) {
15968                 vertex = print_pfrontiers(state, fp, user->member, vertex);
15969         }
15970         return vertex;
15971 }
15972 static void print_ipdominance_frontiers(struct compile_state *state,
15973         FILE *fp, struct basic_blocks *bb)
15974 {
15975         fprintf(fp, "\nipdominance frontiers\n");
15976         print_pfrontiers(state, fp, bb->last_block, 0);
15977         
15978 }
15979
15980 static void analyze_ipdominators(struct compile_state *state,
15981         struct basic_blocks *bb)
15982 {
15983         /* Find the post dominators */
15984         find_post_dominators(state, bb);
15985         /* Find the control dependencies (post dominance frontiers) */
15986         find_block_ipdomf(state, bb->last_block);
15987         /* If debuging print the print what I have just found */
15988         if (state->compiler->debug & DEBUG_RDOMINATORS) {
15989                 print_ipdominators(state, state->dbgout, bb);
15990                 print_ipdominance_frontiers(state, state->dbgout, bb);
15991                 print_control_flow(state, state->dbgout, bb);
15992         }
15993 }
15994
15995 static int bdominates(struct compile_state *state,
15996         struct block *dom, struct block *sub)
15997 {
15998         while(sub && (sub != dom)) {
15999                 sub = sub->idom;
16000         }
16001         return sub == dom;
16002 }
16003
16004 static int tdominates(struct compile_state *state,
16005         struct triple *dom, struct triple *sub)
16006 {
16007         struct block *bdom, *bsub;
16008         int result;
16009         bdom = block_of_triple(state, dom);
16010         bsub = block_of_triple(state, sub);
16011         if (bdom != bsub) {
16012                 result = bdominates(state, bdom, bsub);
16013         } 
16014         else {
16015                 struct triple *ins;
16016                 if (!bdom || !bsub) {
16017                         internal_error(state, dom, "huh?");
16018                 }
16019                 ins = sub;
16020                 while((ins != bsub->first) && (ins != dom)) {
16021                         ins = ins->prev;
16022                 }
16023                 result = (ins == dom);
16024         }
16025         return result;
16026 }
16027
16028 static void analyze_basic_blocks(
16029         struct compile_state *state, struct basic_blocks *bb)
16030 {
16031         setup_basic_blocks(state, bb);
16032         analyze_idominators(state, bb);
16033         analyze_ipdominators(state, bb);
16034 }
16035
16036 static void insert_phi_operations(struct compile_state *state)
16037 {
16038         size_t size;
16039         struct triple *first;
16040         int *has_already, *work;
16041         struct block *work_list, **work_list_tail;
16042         int iter;
16043         struct triple *var, *vnext;
16044
16045         size = sizeof(int) * (state->bb.last_vertex + 1);
16046         has_already = xcmalloc(size, "has_already");
16047         work =        xcmalloc(size, "work");
16048         iter = 0;
16049
16050         first = state->first;
16051         for(var = first->next; var != first ; var = vnext) {
16052                 struct block *block;
16053                 struct triple_set *user, *unext;
16054                 vnext = var->next;
16055
16056                 if (!triple_is_auto_var(state, var) || !var->use) {
16057                         continue;
16058                 }
16059                         
16060                 iter += 1;
16061                 work_list = 0;
16062                 work_list_tail = &work_list;
16063                 for(user = var->use; user; user = unext) {
16064                         unext = user->next;
16065                         if (MISC(var, 0) == user->member) {
16066                                 continue;
16067                         }
16068                         if (user->member->op == OP_READ) {
16069                                 continue;
16070                         }
16071                         if (user->member->op != OP_WRITE) {
16072                                 internal_error(state, user->member, 
16073                                         "bad variable access");
16074                         }
16075                         block = user->member->u.block;
16076                         if (!block) {
16077                                 warning(state, user->member, "dead code");
16078                                 release_triple(state, user->member);
16079                                 continue;
16080                         }
16081                         if (work[block->vertex] >= iter) {
16082                                 continue;
16083                         }
16084                         work[block->vertex] = iter;
16085                         *work_list_tail = block;
16086                         block->work_next = 0;
16087                         work_list_tail = &block->work_next;
16088                 }
16089                 for(block = work_list; block; block = block->work_next) {
16090                         struct block_set *df;
16091                         for(df = block->domfrontier; df; df = df->next) {
16092                                 struct triple *phi;
16093                                 struct block *front;
16094                                 int in_edges;
16095                                 front = df->member;
16096
16097                                 if (has_already[front->vertex] >= iter) {
16098                                         continue;
16099                                 }
16100                                 /* Count how many edges flow into this block */
16101                                 in_edges = front->users;
16102                                 /* Insert a phi function for this variable */
16103                                 get_occurance(var->occurance);
16104                                 phi = alloc_triple(
16105                                         state, OP_PHI, var->type, -1, in_edges, 
16106                                         var->occurance);
16107                                 phi->u.block = front;
16108                                 MISC(phi, 0) = var;
16109                                 use_triple(var, phi);
16110 #if 1
16111                                 if (phi->rhs != in_edges) {
16112                                         internal_error(state, phi, "phi->rhs: %d != in_edges: %d",
16113                                                 phi->rhs, in_edges);
16114                                 }
16115 #endif
16116                                 /* Insert the phi functions immediately after the label */
16117                                 insert_triple(state, front->first->next, phi);
16118                                 if (front->first == front->last) {
16119                                         front->last = front->first->next;
16120                                 }
16121                                 has_already[front->vertex] = iter;
16122                                 transform_to_arch_instruction(state, phi);
16123
16124                                 /* If necessary plan to visit the basic block */
16125                                 if (work[front->vertex] >= iter) {
16126                                         continue;
16127                                 }
16128                                 work[front->vertex] = iter;
16129                                 *work_list_tail = front;
16130                                 front->work_next = 0;
16131                                 work_list_tail = &front->work_next;
16132                         }
16133                 }
16134         }
16135         xfree(has_already);
16136         xfree(work);
16137 }
16138
16139
16140 struct stack {
16141         struct triple_set *top;
16142         unsigned orig_id;
16143 };
16144
16145 static int count_auto_vars(struct compile_state *state)
16146 {
16147         struct triple *first, *ins;
16148         int auto_vars = 0;
16149         first = state->first;
16150         ins = first;
16151         do {
16152                 if (triple_is_auto_var(state, ins)) {
16153                         auto_vars += 1;
16154                 }
16155                 ins = ins->next;
16156         } while(ins != first);
16157         return auto_vars;
16158 }
16159
16160 static void number_auto_vars(struct compile_state *state, struct stack *stacks)
16161 {
16162         struct triple *first, *ins;
16163         int auto_vars = 0;
16164         first = state->first;
16165         ins = first;
16166         do {
16167                 if (triple_is_auto_var(state, ins)) {
16168                         auto_vars += 1;
16169                         stacks[auto_vars].orig_id = ins->id;
16170                         ins->id = auto_vars;
16171                 }
16172                 ins = ins->next;
16173         } while(ins != first);
16174 }
16175
16176 static void restore_auto_vars(struct compile_state *state, struct stack *stacks)
16177 {
16178         struct triple *first, *ins;
16179         first = state->first;
16180         ins = first;
16181         do {
16182                 if (triple_is_auto_var(state, ins)) {
16183                         ins->id = stacks[ins->id].orig_id;
16184                 }
16185                 ins = ins->next;
16186         } while(ins != first);
16187 }
16188
16189 static struct triple *peek_triple(struct stack *stacks, struct triple *var)
16190 {
16191         struct triple_set *head;
16192         struct triple *top_val;
16193         top_val = 0;
16194         head = stacks[var->id].top;
16195         if (head) {
16196                 top_val = head->member;
16197         }
16198         return top_val;
16199 }
16200
16201 static void push_triple(struct stack *stacks, struct triple *var, struct triple *val)
16202 {
16203         struct triple_set *new;
16204         /* Append new to the head of the list,
16205          * it's the only sensible behavoir for a stack.
16206          */
16207         new = xcmalloc(sizeof(*new), "triple_set");
16208         new->member = val;
16209         new->next   = stacks[var->id].top;
16210         stacks[var->id].top = new;
16211 }
16212
16213 static void pop_triple(struct stack *stacks, struct triple *var, struct triple *oldval)
16214 {
16215         struct triple_set *set, **ptr;
16216         ptr = &stacks[var->id].top;
16217         while(*ptr) {
16218                 set = *ptr;
16219                 if (set->member == oldval) {
16220                         *ptr = set->next;
16221                         xfree(set);
16222                         /* Only free one occurance from the stack */
16223                         return;
16224                 }
16225                 else {
16226                         ptr = &set->next;
16227                 }
16228         }
16229 }
16230
16231 /*
16232  * C(V)
16233  * S(V)
16234  */
16235 static void fixup_block_phi_variables(
16236         struct compile_state *state, struct stack *stacks, struct block *parent, struct block *block)
16237 {
16238         struct block_set *set;
16239         struct triple *ptr;
16240         int edge;
16241         if (!parent || !block)
16242                 return;
16243         /* Find the edge I am coming in on */
16244         edge = 0;
16245         for(set = block->use; set; set = set->next, edge++) {
16246                 if (set->member == parent) {
16247                         break;
16248                 }
16249         }
16250         if (!set) {
16251                 internal_error(state, 0, "phi input is not on a control predecessor");
16252         }
16253         for(ptr = block->first; ; ptr = ptr->next) {
16254                 if (ptr->op == OP_PHI) {
16255                         struct triple *var, *val, **slot;
16256                         var = MISC(ptr, 0);
16257                         if (!var) {
16258                                 internal_error(state, ptr, "no var???");
16259                         }
16260                         /* Find the current value of the variable */
16261                         val = peek_triple(stacks, var);
16262                         if (val && ((val->op == OP_WRITE) || (val->op == OP_READ))) {
16263                                 internal_error(state, val, "bad value in phi");
16264                         }
16265                         if (edge >= ptr->rhs) {
16266                                 internal_error(state, ptr, "edges > phi rhs");
16267                         }
16268                         slot = &RHS(ptr, edge);
16269                         if ((*slot != 0) && (*slot != val)) {
16270                                 internal_error(state, ptr, "phi already bound on this edge");
16271                         }
16272                         *slot = val;
16273                         use_triple(val, ptr);
16274                 }
16275                 if (ptr == block->last) {
16276                         break;
16277                 }
16278         }
16279 }
16280
16281
16282 static void rename_block_variables(
16283         struct compile_state *state, struct stack *stacks, struct block *block)
16284 {
16285         struct block_set *user, *edge;
16286         struct triple *ptr, *next, *last;
16287         int done;
16288         if (!block)
16289                 return;
16290         last = block->first;
16291         done = 0;
16292         for(ptr = block->first; !done; ptr = next) {
16293                 next = ptr->next;
16294                 if (ptr == block->last) {
16295                         done = 1;
16296                 }
16297                 /* RHS(A) */
16298                 if (ptr->op == OP_READ) {
16299                         struct triple *var, *val;
16300                         var = RHS(ptr, 0);
16301                         if (!triple_is_auto_var(state, var)) {
16302                                 internal_error(state, ptr, "read of non auto var!");
16303                         }
16304                         unuse_triple(var, ptr);
16305                         /* Find the current value of the variable */
16306                         val = peek_triple(stacks, var);
16307                         if (!val) {
16308                                 /* Let the optimizer at variables that are not initially
16309                                  * set.  But give it a bogus value so things seem to
16310                                  * work by accident.  This is useful for bitfields because
16311                                  * setting them always involves a read-modify-write.
16312                                  */
16313                                 if (TYPE_ARITHMETIC(ptr->type->type)) {
16314                                         val = pre_triple(state, ptr, OP_INTCONST, ptr->type, 0, 0);
16315                                         val->u.cval = 0xdeadbeaf;
16316                                 } else {
16317                                         val = pre_triple(state, ptr, OP_UNKNOWNVAL, ptr->type, 0, 0);
16318                                 }
16319                         }
16320                         if (!val) {
16321                                 error(state, ptr, "variable used without being set");
16322                         }
16323                         if ((val->op == OP_WRITE) || (val->op == OP_READ)) {
16324                                 internal_error(state, val, "bad value in read");
16325                         }
16326                         propogate_use(state, ptr, val);
16327                         release_triple(state, ptr);
16328                         continue;
16329                 }
16330                 /* LHS(A) */
16331                 if (ptr->op == OP_WRITE) {
16332                         struct triple *var, *val, *tval;
16333                         var = MISC(ptr, 0);
16334                         if (!triple_is_auto_var(state, var)) {
16335                                 internal_error(state, ptr, "write to non auto var!");
16336                         }
16337                         tval = val = RHS(ptr, 0);
16338                         if ((val->op == OP_WRITE) || (val->op == OP_READ) ||
16339                                 triple_is_auto_var(state, val)) {
16340                                 internal_error(state, ptr, "bad value in write");
16341                         }
16342                         /* Insert a cast if the types differ */
16343                         if (!is_subset_type(ptr->type, val->type)) {
16344                                 if (val->op == OP_INTCONST) {
16345                                         tval = pre_triple(state, ptr, OP_INTCONST, ptr->type, 0, 0);
16346                                         tval->u.cval = val->u.cval;
16347                                 }
16348                                 else {
16349                                         tval = pre_triple(state, ptr, OP_CONVERT, ptr->type, val, 0);
16350                                         use_triple(val, tval);
16351                                 }
16352                                 transform_to_arch_instruction(state, tval);
16353                                 unuse_triple(val, ptr);
16354                                 RHS(ptr, 0) = tval;
16355                                 use_triple(tval, ptr);
16356                         }
16357                         propogate_use(state, ptr, tval);
16358                         unuse_triple(var, ptr);
16359                         /* Push OP_WRITE ptr->right onto a stack of variable uses */
16360                         push_triple(stacks, var, tval);
16361                 }
16362                 if (ptr->op == OP_PHI) {
16363                         struct triple *var;
16364                         var = MISC(ptr, 0);
16365                         if (!triple_is_auto_var(state, var)) {
16366                                 internal_error(state, ptr, "phi references non auto var!");
16367                         }
16368                         /* Push OP_PHI onto a stack of variable uses */
16369                         push_triple(stacks, var, ptr);
16370                 }
16371                 last = ptr;
16372         }
16373         block->last = last;
16374
16375         /* Fixup PHI functions in the cf successors */
16376         for(edge = block->edges; edge; edge = edge->next) {
16377                 fixup_block_phi_variables(state, stacks, block, edge->member);
16378         }
16379         /* rename variables in the dominated nodes */
16380         for(user = block->idominates; user; user = user->next) {
16381                 rename_block_variables(state, stacks, user->member);
16382         }
16383         /* pop the renamed variable stack */
16384         last = block->first;
16385         done = 0;
16386         for(ptr = block->first; !done ; ptr = next) {
16387                 next = ptr->next;
16388                 if (ptr == block->last) {
16389                         done = 1;
16390                 }
16391                 if (ptr->op == OP_WRITE) {
16392                         struct triple *var;
16393                         var = MISC(ptr, 0);
16394                         /* Pop OP_WRITE ptr->right from the stack of variable uses */
16395                         pop_triple(stacks, var, RHS(ptr, 0));
16396                         release_triple(state, ptr);
16397                         continue;
16398                 }
16399                 if (ptr->op == OP_PHI) {
16400                         struct triple *var;
16401                         var = MISC(ptr, 0);
16402                         /* Pop OP_WRITE ptr->right from the stack of variable uses */
16403                         pop_triple(stacks, var, ptr);
16404                 }
16405                 last = ptr;
16406         }
16407         block->last = last;
16408 }
16409
16410 static void rename_variables(struct compile_state *state)
16411 {
16412         struct stack *stacks;
16413         int auto_vars;
16414
16415         /* Allocate stacks for the Variables */
16416         auto_vars = count_auto_vars(state);
16417         stacks = xcmalloc(sizeof(stacks[0])*(auto_vars + 1), "auto var stacks");
16418
16419         /* Give each auto_var a stack */
16420         number_auto_vars(state, stacks);
16421
16422         /* Rename the variables */
16423         rename_block_variables(state, stacks, state->bb.first_block);
16424
16425         /* Remove the stacks from the auto_vars */
16426         restore_auto_vars(state, stacks);
16427         xfree(stacks);
16428 }
16429
16430 static void prune_block_variables(struct compile_state *state,
16431         struct block *block)
16432 {
16433         struct block_set *user;
16434         struct triple *next, *ptr;
16435         int done;
16436
16437         done = 0;
16438         for(ptr = block->first; !done; ptr = next) {
16439                 /* Be extremely careful I am deleting the list
16440                  * as I walk trhough it.
16441                  */
16442                 next = ptr->next;
16443                 if (ptr == block->last) {
16444                         done = 1;
16445                 }
16446                 if (triple_is_auto_var(state, ptr)) {
16447                         struct triple_set *user, *next;
16448                         for(user = ptr->use; user; user = next) {
16449                                 struct triple *use;
16450                                 next = user->next;
16451                                 use = user->member;
16452                                 if (MISC(ptr, 0) == user->member) {
16453                                         continue;
16454                                 }
16455                                 if (use->op != OP_PHI) {
16456                                         internal_error(state, use, "decl still used");
16457                                 }
16458                                 if (MISC(use, 0) != ptr) {
16459                                         internal_error(state, use, "bad phi use of decl");
16460                                 }
16461                                 unuse_triple(ptr, use);
16462                                 MISC(use, 0) = 0;
16463                         }
16464                         if ((ptr->u.cval == 0) && (MISC(ptr, 0)->lhs == 1)) {
16465                                 /* Delete the adecl */
16466                                 release_triple(state, MISC(ptr, 0));
16467                                 /* And the piece */
16468                                 release_triple(state, ptr);
16469                         }
16470                         continue;
16471                 }
16472         }
16473         for(user = block->idominates; user; user = user->next) {
16474                 prune_block_variables(state, user->member);
16475         }
16476 }
16477
16478 struct phi_triple {
16479         struct triple *phi;
16480         unsigned orig_id;
16481         int alive;
16482 };
16483
16484 static void keep_phi(struct compile_state *state, struct phi_triple *live, struct triple *phi)
16485 {
16486         struct triple **slot;
16487         int zrhs, i;
16488         if (live[phi->id].alive) {
16489                 return;
16490         }
16491         live[phi->id].alive = 1;
16492         zrhs = phi->rhs;
16493         slot = &RHS(phi, 0);
16494         for(i = 0; i < zrhs; i++) {
16495                 struct triple *used;
16496                 used = slot[i];
16497                 if (used && (used->op == OP_PHI)) {
16498                         keep_phi(state, live, used);
16499                 }
16500         }
16501 }
16502
16503 static void prune_unused_phis(struct compile_state *state)
16504 {
16505         struct triple *first, *phi;
16506         struct phi_triple *live;
16507         int phis, i;
16508         
16509         /* Find the first instruction */
16510         first = state->first;
16511
16512         /* Count how many phi functions I need to process */
16513         phis = 0;
16514         for(phi = first->next; phi != first; phi = phi->next) {
16515                 if (phi->op == OP_PHI) {
16516                         phis += 1;
16517                 }
16518         }
16519         
16520         /* Mark them all dead */
16521         live = xcmalloc(sizeof(*live) * (phis + 1), "phi_triple");
16522         phis = 0;
16523         for(phi = first->next; phi != first; phi = phi->next) {
16524                 if (phi->op != OP_PHI) {
16525                         continue;
16526                 }
16527                 live[phis].alive   = 0;
16528                 live[phis].orig_id = phi->id;
16529                 live[phis].phi     = phi;
16530                 phi->id = phis;
16531                 phis += 1;
16532         }
16533         
16534         /* Mark phis alive that are used by non phis */
16535         for(i = 0; i < phis; i++) {
16536                 struct triple_set *set;
16537                 for(set = live[i].phi->use; !live[i].alive && set; set = set->next) {
16538                         if (set->member->op != OP_PHI) {
16539                                 keep_phi(state, live, live[i].phi);
16540                                 break;
16541                         }
16542                 }
16543         }
16544
16545         /* Delete the extraneous phis */
16546         for(i = 0; i < phis; i++) {
16547                 struct triple **slot;
16548                 int zrhs, j;
16549                 if (!live[i].alive) {
16550                         release_triple(state, live[i].phi);
16551                         continue;
16552                 }
16553                 phi = live[i].phi;
16554                 slot = &RHS(phi, 0);
16555                 zrhs = phi->rhs;
16556                 for(j = 0; j < zrhs; j++) {
16557                         if(!slot[j]) {
16558                                 struct triple *unknown;
16559                                 get_occurance(phi->occurance);
16560                                 unknown = flatten(state, state->global_pool,
16561                                         alloc_triple(state, OP_UNKNOWNVAL,
16562                                                 phi->type, 0, 0, phi->occurance));
16563                                 slot[j] = unknown;
16564                                 use_triple(unknown, phi);
16565                                 transform_to_arch_instruction(state, unknown);
16566 #if 0                           
16567                                 warning(state, phi, "variable not set at index %d on all paths to use", j);
16568 #endif
16569                         }
16570                 }
16571         }
16572         xfree(live);
16573 }
16574
16575 static void transform_to_ssa_form(struct compile_state *state)
16576 {
16577         insert_phi_operations(state);
16578         rename_variables(state);
16579
16580         prune_block_variables(state, state->bb.first_block);
16581         prune_unused_phis(state);
16582
16583         print_blocks(state, __func__, state->dbgout);
16584 }
16585
16586
16587 static void clear_vertex(
16588         struct compile_state *state, struct block *block, void *arg)
16589 {
16590         /* Clear the current blocks vertex and the vertex of all
16591          * of the current blocks neighbors in case there are malformed
16592          * blocks with now instructions at this point.
16593          */
16594         struct block_set *user, *edge;
16595         block->vertex = 0;
16596         for(edge = block->edges; edge; edge = edge->next) {
16597                 edge->member->vertex = 0;
16598         }
16599         for(user = block->use; user; user = user->next) {
16600                 user->member->vertex = 0;
16601         }
16602 }
16603
16604 static void mark_live_block(
16605         struct compile_state *state, struct block *block, int *next_vertex)
16606 {
16607         /* See if this is a block that has not been marked */
16608         if (block->vertex != 0) {
16609                 return;
16610         }
16611         block->vertex = *next_vertex;
16612         *next_vertex += 1;
16613         if (triple_is_branch(state, block->last)) {
16614                 struct triple **targ;
16615                 targ = triple_edge_targ(state, block->last, 0);
16616                 for(; targ; targ = triple_edge_targ(state, block->last, targ)) {
16617                         if (!*targ) {
16618                                 continue;
16619                         }
16620                         if (!triple_stores_block(state, *targ)) {
16621                                 internal_error(state, 0, "bad targ");
16622                         }
16623                         mark_live_block(state, (*targ)->u.block, next_vertex);
16624                 }
16625                 /* Ensure the last block of a function remains alive */
16626                 if (triple_is_call(state, block->last)) {
16627                         mark_live_block(state, MISC(block->last, 0)->u.block, next_vertex);
16628                 }
16629         }
16630         else if (block->last->next != state->first) {
16631                 struct triple *ins;
16632                 ins = block->last->next;
16633                 if (!triple_stores_block(state, ins)) {
16634                         internal_error(state, 0, "bad block start");
16635                 }
16636                 mark_live_block(state, ins->u.block, next_vertex);
16637         }
16638 }
16639
16640 static void transform_from_ssa_form(struct compile_state *state)
16641 {
16642         /* To get out of ssa form we insert moves on the incoming
16643          * edges to blocks containting phi functions.
16644          */
16645         struct triple *first;
16646         struct triple *phi, *var, *next;
16647         int next_vertex;
16648
16649         /* Walk the control flow to see which blocks remain alive */
16650         walk_blocks(state, &state->bb, clear_vertex, 0);
16651         next_vertex = 1;
16652         mark_live_block(state, state->bb.first_block, &next_vertex);
16653
16654         /* Walk all of the operations to find the phi functions */
16655         first = state->first;
16656         for(phi = first->next; phi != first ; phi = next) {
16657                 struct block_set *set;
16658                 struct block *block;
16659                 struct triple **slot;
16660                 struct triple *var;
16661                 struct triple_set *use, *use_next;
16662                 int edge, writers, readers;
16663                 next = phi->next;
16664                 if (phi->op != OP_PHI) {
16665                         continue;
16666                 }
16667
16668                 block = phi->u.block;
16669                 slot  = &RHS(phi, 0);
16670
16671                 /* If this phi is in a dead block just forget it */
16672                 if (block->vertex == 0) {
16673                         release_triple(state, phi);
16674                         continue;
16675                 }
16676
16677                 /* Forget uses from code in dead blocks */
16678                 for(use = phi->use; use; use = use_next) {
16679                         struct block *ublock;
16680                         struct triple **expr;
16681                         use_next = use->next;
16682                         ublock = block_of_triple(state, use->member);
16683                         if ((use->member == phi) || (ublock->vertex != 0)) {
16684                                 continue;
16685                         }
16686                         expr = triple_rhs(state, use->member, 0);
16687                         for(; expr; expr = triple_rhs(state, use->member, expr)) {
16688                                 if (*expr == phi) {
16689                                         *expr = 0;
16690                                 }
16691                         }
16692                         unuse_triple(phi, use->member);
16693                 }
16694                 /* A variable to replace the phi function */
16695                 if (registers_of(state, phi->type) != 1) {
16696                         internal_error(state, phi, "phi->type does not fit in a single register!");
16697                 }
16698                 var = post_triple(state, phi, OP_ADECL, phi->type, 0, 0);
16699                 var = var->next; /* point at the var */
16700                         
16701                 /* Replaces use of phi with var */
16702                 propogate_use(state, phi, var);
16703
16704                 /* Count the readers */
16705                 readers = 0;
16706                 for(use = var->use; use; use = use->next) {
16707                         if (use->member != MISC(var, 0)) {
16708                                 readers++;
16709                         }
16710                 }
16711
16712                 /* Walk all of the incoming edges/blocks and insert moves.
16713                  */
16714                 writers = 0;
16715                 for(edge = 0, set = block->use; set; set = set->next, edge++) {
16716                         struct block *eblock, *vblock;
16717                         struct triple *move;
16718                         struct triple *val, *base;
16719                         eblock = set->member;
16720                         val = slot[edge];
16721                         slot[edge] = 0;
16722                         unuse_triple(val, phi);
16723                         vblock = block_of_triple(state, val);
16724
16725                         /* If we don't have a value that belongs in an OP_WRITE
16726                          * continue on.
16727                          */
16728                         if (!val || (val == &unknown_triple) || (val == phi)
16729                                 || (vblock && (vblock->vertex == 0))) {
16730                                 continue;
16731                         }
16732                         /* If the value should never occur error */
16733                         if (!vblock) {
16734                                 internal_error(state, val, "no vblock?");
16735                                 continue;
16736                         }
16737
16738                         /* If the value occurs in a dead block see if a replacement
16739                          * block can be found.
16740                          */
16741                         while(eblock && (eblock->vertex == 0)) {
16742                                 eblock = eblock->idom;
16743                         }
16744                         /* If not continue on with the next value. */
16745                         if (!eblock || (eblock->vertex == 0)) {
16746                                 continue;
16747                         }
16748
16749                         /* If we have an empty incoming block ignore it. */
16750                         if (!eblock->first) {
16751                                 internal_error(state, 0, "empty block?");
16752                         }
16753                         
16754                         /* Make certain the write is placed in the edge block... */
16755                         /* Walk through the edge block backwards to find an
16756                          * appropriate location for the OP_WRITE.
16757                          */
16758                         for(base = eblock->last; base != eblock->first; base = base->prev) {
16759                                 struct triple **expr;
16760                                 if (base->op == OP_PIECE) {
16761                                         base = MISC(base, 0);
16762                                 }
16763                                 if ((base == var) || (base == val)) {
16764                                         goto out;
16765                                 }
16766                                 expr = triple_lhs(state, base, 0);
16767                                 for(; expr; expr = triple_lhs(state, base, expr)) {
16768                                         if ((*expr) == val) {
16769                                                 goto out;
16770                                         }
16771                                 }
16772                                 expr = triple_rhs(state, base, 0);
16773                                 for(; expr; expr = triple_rhs(state, base, expr)) {
16774                                         if ((*expr) == var) {
16775                                                 goto out;
16776                                         }
16777                                 }
16778                         }
16779                 out:
16780                         if (triple_is_branch(state, base)) {
16781                                 internal_error(state, base,
16782                                         "Could not insert write to phi");
16783                         }
16784                         move = post_triple(state, base, OP_WRITE, var->type, val, var);
16785                         use_triple(val, move);
16786                         use_triple(var, move);
16787                         writers++;
16788                 }
16789                 if (!writers && readers) {
16790                         internal_error(state, var, "no value written to in use phi?");
16791                 }
16792                 /* If var is not used free it */
16793                 if (!writers) {
16794                         release_triple(state, MISC(var, 0));
16795                         release_triple(state, var);
16796                 }
16797                 /* Release the phi function */
16798                 release_triple(state, phi);
16799         }
16800         
16801         /* Walk all of the operations to find the adecls */
16802         for(var = first->next; var != first ; var = var->next) {
16803                 struct triple_set *use, *use_next;
16804                 if (!triple_is_auto_var(state, var)) {
16805                         continue;
16806                 }
16807
16808                 /* Walk through all of the rhs uses of var and
16809                  * replace them with read of var.
16810                  */
16811                 for(use = var->use; use; use = use_next) {
16812                         struct triple *read, *user;
16813                         struct triple **slot;
16814                         int zrhs, i, used;
16815                         use_next = use->next;
16816                         user = use->member;
16817                         
16818                         /* Generate a read of var */
16819                         read = pre_triple(state, user, OP_READ, var->type, var, 0);
16820                         use_triple(var, read);
16821
16822                         /* Find the rhs uses and see if they need to be replaced */
16823                         used = 0;
16824                         zrhs = user->rhs;
16825                         slot = &RHS(user, 0);
16826                         for(i = 0; i < zrhs; i++) {
16827                                 if (slot[i] == var) {
16828                                         slot[i] = read;
16829                                         used = 1;
16830                                 }
16831                         }
16832                         /* If we did use it cleanup the uses */
16833                         if (used) {
16834                                 unuse_triple(var, user);
16835                                 use_triple(read, user);
16836                         } 
16837                         /* If we didn't use it release the extra triple */
16838                         else {
16839                                 release_triple(state, read);
16840                         }
16841                 }
16842         }
16843 }
16844
16845 #define HI() if (state->compiler->debug & DEBUG_REBUILD_SSA_FORM) { \
16846         FILE *fp = state->dbgout; \
16847         fprintf(fp, "@ %s:%d\n", __FILE__, __LINE__); romcc_print_blocks(state, fp); \
16848         } 
16849
16850 static void rebuild_ssa_form(struct compile_state *state)
16851 {
16852 HI();
16853         transform_from_ssa_form(state);
16854 HI();
16855         state->bb.first = state->first;
16856         free_basic_blocks(state, &state->bb);
16857         analyze_basic_blocks(state, &state->bb);
16858 HI();
16859         insert_phi_operations(state);
16860 HI();
16861         rename_variables(state);
16862 HI();
16863         
16864         prune_block_variables(state, state->bb.first_block);
16865 HI();
16866         prune_unused_phis(state);
16867 HI();
16868 }
16869 #undef HI
16870
16871 /* 
16872  * Register conflict resolution
16873  * =========================================================
16874  */
16875
16876 static struct reg_info find_def_color(
16877         struct compile_state *state, struct triple *def)
16878 {
16879         struct triple_set *set;
16880         struct reg_info info;
16881         info.reg = REG_UNSET;
16882         info.regcm = 0;
16883         if (!triple_is_def(state, def)) {
16884                 return info;
16885         }
16886         info = arch_reg_lhs(state, def, 0);
16887         if (info.reg >= MAX_REGISTERS) {
16888                 info.reg = REG_UNSET;
16889         }
16890         for(set = def->use; set; set = set->next) {
16891                 struct reg_info tinfo;
16892                 int i;
16893                 i = find_rhs_use(state, set->member, def);
16894                 if (i < 0) {
16895                         continue;
16896                 }
16897                 tinfo = arch_reg_rhs(state, set->member, i);
16898                 if (tinfo.reg >= MAX_REGISTERS) {
16899                         tinfo.reg = REG_UNSET;
16900                 }
16901                 if ((tinfo.reg != REG_UNSET) && 
16902                         (info.reg != REG_UNSET) &&
16903                         (tinfo.reg != info.reg)) {
16904                         internal_error(state, def, "register conflict");
16905                 }
16906                 if ((info.regcm & tinfo.regcm) == 0) {
16907                         internal_error(state, def, "regcm conflict %x & %x == 0",
16908                                 info.regcm, tinfo.regcm);
16909                 }
16910                 if (info.reg == REG_UNSET) {
16911                         info.reg = tinfo.reg;
16912                 }
16913                 info.regcm &= tinfo.regcm;
16914         }
16915         if (info.reg >= MAX_REGISTERS) {
16916                 internal_error(state, def, "register out of range");
16917         }
16918         return info;
16919 }
16920
16921 static struct reg_info find_lhs_pre_color(
16922         struct compile_state *state, struct triple *ins, int index)
16923 {
16924         struct reg_info info;
16925         int zlhs, zrhs, i;
16926         zrhs = ins->rhs;
16927         zlhs = ins->lhs;
16928         if (!zlhs && triple_is_def(state, ins)) {
16929                 zlhs = 1;
16930         }
16931         if (index >= zlhs) {
16932                 internal_error(state, ins, "Bad lhs %d", index);
16933         }
16934         info = arch_reg_lhs(state, ins, index);
16935         for(i = 0; i < zrhs; i++) {
16936                 struct reg_info rinfo;
16937                 rinfo = arch_reg_rhs(state, ins, i);
16938                 if ((info.reg == rinfo.reg) &&
16939                         (rinfo.reg >= MAX_REGISTERS)) {
16940                         struct reg_info tinfo;
16941                         tinfo = find_lhs_pre_color(state, RHS(ins, index), 0);
16942                         info.reg = tinfo.reg;
16943                         info.regcm &= tinfo.regcm;
16944                         break;
16945                 }
16946         }
16947         if (info.reg >= MAX_REGISTERS) {
16948                 info.reg = REG_UNSET;
16949         }
16950         return info;
16951 }
16952
16953 static struct reg_info find_rhs_post_color(
16954         struct compile_state *state, struct triple *ins, int index);
16955
16956 static struct reg_info find_lhs_post_color(
16957         struct compile_state *state, struct triple *ins, int index)
16958 {
16959         struct triple_set *set;
16960         struct reg_info info;
16961         struct triple *lhs;
16962 #if DEBUG_TRIPLE_COLOR
16963         fprintf(state->errout, "find_lhs_post_color(%p, %d)\n",
16964                 ins, index);
16965 #endif
16966         if ((index == 0) && triple_is_def(state, ins)) {
16967                 lhs = ins;
16968         }
16969         else if (index < ins->lhs) {
16970                 lhs = LHS(ins, index);
16971         }
16972         else {
16973                 internal_error(state, ins, "Bad lhs %d", index);
16974                 lhs = 0;
16975         }
16976         info = arch_reg_lhs(state, ins, index);
16977         if (info.reg >= MAX_REGISTERS) {
16978                 info.reg = REG_UNSET;
16979         }
16980         for(set = lhs->use; set; set = set->next) {
16981                 struct reg_info rinfo;
16982                 struct triple *user;
16983                 int zrhs, i;
16984                 user = set->member;
16985                 zrhs = user->rhs;
16986                 for(i = 0; i < zrhs; i++) {
16987                         if (RHS(user, i) != lhs) {
16988                                 continue;
16989                         }
16990                         rinfo = find_rhs_post_color(state, user, i);
16991                         if ((info.reg != REG_UNSET) &&
16992                                 (rinfo.reg != REG_UNSET) &&
16993                                 (info.reg != rinfo.reg)) {
16994                                 internal_error(state, ins, "register conflict");
16995                         }
16996                         if ((info.regcm & rinfo.regcm) == 0) {
16997                                 internal_error(state, ins, "regcm conflict %x & %x == 0",
16998                                         info.regcm, rinfo.regcm);
16999                         }
17000                         if (info.reg == REG_UNSET) {
17001                                 info.reg = rinfo.reg;
17002                         }
17003                         info.regcm &= rinfo.regcm;
17004                 }
17005         }
17006 #if DEBUG_TRIPLE_COLOR
17007         fprintf(state->errout, "find_lhs_post_color(%p, %d) -> ( %d, %x)\n",
17008                 ins, index, info.reg, info.regcm);
17009 #endif
17010         return info;
17011 }
17012
17013 static struct reg_info find_rhs_post_color(
17014         struct compile_state *state, struct triple *ins, int index)
17015 {
17016         struct reg_info info, rinfo;
17017         int zlhs, i;
17018 #if DEBUG_TRIPLE_COLOR
17019         fprintf(state->errout, "find_rhs_post_color(%p, %d)\n",
17020                 ins, index);
17021 #endif
17022         rinfo = arch_reg_rhs(state, ins, index);
17023         zlhs = ins->lhs;
17024         if (!zlhs && triple_is_def(state, ins)) {
17025                 zlhs = 1;
17026         }
17027         info = rinfo;
17028         if (info.reg >= MAX_REGISTERS) {
17029                 info.reg = REG_UNSET;
17030         }
17031         for(i = 0; i < zlhs; i++) {
17032                 struct reg_info linfo;
17033                 linfo = arch_reg_lhs(state, ins, i);
17034                 if ((linfo.reg == rinfo.reg) &&
17035                         (linfo.reg >= MAX_REGISTERS)) {
17036                         struct reg_info tinfo;
17037                         tinfo = find_lhs_post_color(state, ins, i);
17038                         if (tinfo.reg >= MAX_REGISTERS) {
17039                                 tinfo.reg = REG_UNSET;
17040                         }
17041                         info.regcm &= linfo.regcm;
17042                         info.regcm &= tinfo.regcm;
17043                         if (info.reg != REG_UNSET) {
17044                                 internal_error(state, ins, "register conflict");
17045                         }
17046                         if (info.regcm == 0) {
17047                                 internal_error(state, ins, "regcm conflict");
17048                         }
17049                         info.reg = tinfo.reg;
17050                 }
17051         }
17052 #if DEBUG_TRIPLE_COLOR
17053         fprintf(state->errout, "find_rhs_post_color(%p, %d) -> ( %d, %x)\n",
17054                 ins, index, info.reg, info.regcm);
17055 #endif
17056         return info;
17057 }
17058
17059 static struct reg_info find_lhs_color(
17060         struct compile_state *state, struct triple *ins, int index)
17061 {
17062         struct reg_info pre, post, info;
17063 #if DEBUG_TRIPLE_COLOR
17064         fprintf(state->errout, "find_lhs_color(%p, %d)\n",
17065                 ins, index);
17066 #endif
17067         pre = find_lhs_pre_color(state, ins, index);
17068         post = find_lhs_post_color(state, ins, index);
17069         if ((pre.reg != post.reg) &&
17070                 (pre.reg != REG_UNSET) &&
17071                 (post.reg != REG_UNSET)) {
17072                 internal_error(state, ins, "register conflict");
17073         }
17074         info.regcm = pre.regcm & post.regcm;
17075         info.reg = pre.reg;
17076         if (info.reg == REG_UNSET) {
17077                 info.reg = post.reg;
17078         }
17079 #if DEBUG_TRIPLE_COLOR
17080         fprintf(state->errout, "find_lhs_color(%p, %d) -> ( %d, %x) ... (%d, %x) (%d, %x)\n",
17081                 ins, index, info.reg, info.regcm,
17082                 pre.reg, pre.regcm, post.reg, post.regcm);
17083 #endif
17084         return info;
17085 }
17086
17087 static struct triple *post_copy(struct compile_state *state, struct triple *ins)
17088 {
17089         struct triple_set *entry, *next;
17090         struct triple *out;
17091         struct reg_info info, rinfo;
17092
17093         info = arch_reg_lhs(state, ins, 0);
17094         out = post_triple(state, ins, OP_COPY, ins->type, ins, 0);
17095         use_triple(RHS(out, 0), out);
17096         /* Get the users of ins to use out instead */
17097         for(entry = ins->use; entry; entry = next) {
17098                 int i;
17099                 next = entry->next;
17100                 if (entry->member == out) {
17101                         continue;
17102                 }
17103                 i = find_rhs_use(state, entry->member, ins);
17104                 if (i < 0) {
17105                         continue;
17106                 }
17107                 rinfo = arch_reg_rhs(state, entry->member, i);
17108                 if ((info.reg == REG_UNNEEDED) && (rinfo.reg == REG_UNNEEDED)) {
17109                         continue;
17110                 }
17111                 replace_rhs_use(state, ins, out, entry->member);
17112         }
17113         transform_to_arch_instruction(state, out);
17114         return out;
17115 }
17116
17117 static struct triple *typed_pre_copy(
17118         struct compile_state *state, struct type *type, struct triple *ins, int index)
17119 {
17120         /* Carefully insert enough operations so that I can
17121          * enter any operation with a GPR32.
17122          */
17123         struct triple *in;
17124         struct triple **expr;
17125         unsigned classes;
17126         struct reg_info info;
17127         int op;
17128         if (ins->op == OP_PHI) {
17129                 internal_error(state, ins, "pre_copy on a phi?");
17130         }
17131         classes = arch_type_to_regcm(state, type);
17132         info = arch_reg_rhs(state, ins, index);
17133         expr = &RHS(ins, index);
17134         if ((info.regcm & classes) == 0) {
17135                 FILE *fp = state->errout;
17136                 fprintf(fp, "src_type: ");
17137                 name_of(fp, ins->type);
17138                 fprintf(fp, "\ndst_type: ");
17139                 name_of(fp, type);
17140                 fprintf(fp, "\n");
17141                 internal_error(state, ins, "pre_copy with no register classes");
17142         }
17143         op = OP_COPY;
17144         if (!equiv_types(type, (*expr)->type)) {
17145                 op = OP_CONVERT;
17146         }
17147         in = pre_triple(state, ins, op, type, *expr, 0);
17148         unuse_triple(*expr, ins);
17149         *expr = in;
17150         use_triple(RHS(in, 0), in);
17151         use_triple(in, ins);
17152         transform_to_arch_instruction(state, in);
17153         return in;
17154         
17155 }
17156 static struct triple *pre_copy(
17157         struct compile_state *state, struct triple *ins, int index)
17158 {
17159         return typed_pre_copy(state, RHS(ins, index)->type, ins, index);
17160 }
17161
17162
17163 static void insert_copies_to_phi(struct compile_state *state)
17164 {
17165         /* To get out of ssa form we insert moves on the incoming
17166          * edges to blocks containting phi functions.
17167          */
17168         struct triple *first;
17169         struct triple *phi;
17170
17171         /* Walk all of the operations to find the phi functions */
17172         first = state->first;
17173         for(phi = first->next; phi != first ; phi = phi->next) {
17174                 struct block_set *set;
17175                 struct block *block;
17176                 struct triple **slot, *copy;
17177                 int edge;
17178                 if (phi->op != OP_PHI) {
17179                         continue;
17180                 }
17181                 phi->id |= TRIPLE_FLAG_POST_SPLIT;
17182                 block = phi->u.block;
17183                 slot  = &RHS(phi, 0);
17184                 /* Phi's that feed into mandatory live range joins
17185                  * cause nasty complications.  Insert a copy of
17186                  * the phi value so I never have to deal with
17187                  * that in the rest of the code.
17188                  */
17189                 copy = post_copy(state, phi);
17190                 copy->id |= TRIPLE_FLAG_PRE_SPLIT;
17191                 /* Walk all of the incoming edges/blocks and insert moves.
17192                  */
17193                 for(edge = 0, set = block->use; set; set = set->next, edge++) {
17194                         struct block *eblock;
17195                         struct triple *move;
17196                         struct triple *val;
17197                         struct triple *ptr;
17198                         eblock = set->member;
17199                         val = slot[edge];
17200
17201                         if (val == phi) {
17202                                 continue;
17203                         }
17204
17205                         get_occurance(val->occurance);
17206                         move = build_triple(state, OP_COPY, val->type, val, 0,
17207                                 val->occurance);
17208                         move->u.block = eblock;
17209                         move->id |= TRIPLE_FLAG_PRE_SPLIT;
17210                         use_triple(val, move);
17211                         
17212                         slot[edge] = move;
17213                         unuse_triple(val, phi);
17214                         use_triple(move, phi);
17215
17216                         /* Walk up the dominator tree until I have found the appropriate block */
17217                         while(eblock && !tdominates(state, val, eblock->last)) {
17218                                 eblock = eblock->idom;
17219                         }
17220                         if (!eblock) {
17221                                 internal_error(state, phi, "Cannot find block dominated by %p",
17222                                         val);
17223                         }
17224
17225                         /* Walk through the block backwards to find
17226                          * an appropriate location for the OP_COPY.
17227                          */
17228                         for(ptr = eblock->last; ptr != eblock->first; ptr = ptr->prev) {
17229                                 struct triple **expr;
17230                                 if (ptr->op == OP_PIECE) {
17231                                         ptr = MISC(ptr, 0);
17232                                 }
17233                                 if ((ptr == phi) || (ptr == val)) {
17234                                         goto out;
17235                                 }
17236                                 expr = triple_lhs(state, ptr, 0);
17237                                 for(;expr; expr = triple_lhs(state, ptr, expr)) {
17238                                         if ((*expr) == val) {
17239                                                 goto out;
17240                                         }
17241                                 }
17242                                 expr = triple_rhs(state, ptr, 0);
17243                                 for(;expr; expr = triple_rhs(state, ptr, expr)) {
17244                                         if ((*expr) == phi) {
17245                                                 goto out;
17246                                         }
17247                                 }
17248                         }
17249                 out:
17250                         if (triple_is_branch(state, ptr)) {
17251                                 internal_error(state, ptr,
17252                                         "Could not insert write to phi");
17253                         }
17254                         insert_triple(state, after_lhs(state, ptr), move);
17255                         if (eblock->last == after_lhs(state, ptr)->prev) {
17256                                 eblock->last = move;
17257                         }
17258                         transform_to_arch_instruction(state, move);
17259                 }
17260         }
17261         print_blocks(state, __func__, state->dbgout);
17262 }
17263
17264 struct triple_reg_set;
17265 struct reg_block;
17266
17267
17268 static int do_triple_set(struct triple_reg_set **head, 
17269         struct triple *member, struct triple *new_member)
17270 {
17271         struct triple_reg_set **ptr, *new;
17272         if (!member)
17273                 return 0;
17274         ptr = head;
17275         while(*ptr) {
17276                 if ((*ptr)->member == member) {
17277                         return 0;
17278                 }
17279                 ptr = &(*ptr)->next;
17280         }
17281         new = xcmalloc(sizeof(*new), "triple_set");
17282         new->member = member;
17283         new->new    = new_member;
17284         new->next   = *head;
17285         *head       = new;
17286         return 1;
17287 }
17288
17289 static void do_triple_unset(struct triple_reg_set **head, struct triple *member)
17290 {
17291         struct triple_reg_set *entry, **ptr;
17292         ptr = head;
17293         while(*ptr) {
17294                 entry = *ptr;
17295                 if (entry->member == member) {
17296                         *ptr = entry->next;
17297                         xfree(entry);
17298                         return;
17299                 }
17300                 else {
17301                         ptr = &entry->next;
17302                 }
17303         }
17304 }
17305
17306 static int in_triple(struct reg_block *rb, struct triple *in)
17307 {
17308         return do_triple_set(&rb->in, in, 0);
17309 }
17310 static void unin_triple(struct reg_block *rb, struct triple *unin)
17311 {
17312         do_triple_unset(&rb->in, unin);
17313 }
17314
17315 static int out_triple(struct reg_block *rb, struct triple *out)
17316 {
17317         return do_triple_set(&rb->out, out, 0);
17318 }
17319 static void unout_triple(struct reg_block *rb, struct triple *unout)
17320 {
17321         do_triple_unset(&rb->out, unout);
17322 }
17323
17324 static int initialize_regblock(struct reg_block *blocks,
17325         struct block *block, int vertex)
17326 {
17327         struct block_set *user;
17328         if (!block || (blocks[block->vertex].block == block)) {
17329                 return vertex;
17330         }
17331         vertex += 1;
17332         /* Renumber the blocks in a convinient fashion */
17333         block->vertex = vertex;
17334         blocks[vertex].block    = block;
17335         blocks[vertex].vertex   = vertex;
17336         for(user = block->use; user; user = user->next) {
17337                 vertex = initialize_regblock(blocks, user->member, vertex);
17338         }
17339         return vertex;
17340 }
17341
17342 static struct triple *part_to_piece(struct compile_state *state, struct triple *ins)
17343 {
17344 /* Part to piece is a best attempt and it cannot be correct all by
17345  * itself.  If various values are read as different sizes in different
17346  * parts of the code this function cannot work.  Or rather it cannot
17347  * work in conjunction with compute_variable_liftimes.  As the
17348  * analysis will get confused.
17349  */
17350         struct triple *base;
17351         unsigned reg;
17352         if (!is_lvalue(state, ins)) {
17353                 return ins;
17354         }
17355         base = 0;
17356         reg = 0;
17357         while(ins && triple_is_part(state, ins) && (ins->op != OP_PIECE)) {
17358                 base = MISC(ins, 0);
17359                 switch(ins->op) {
17360                 case OP_INDEX:
17361                         reg += index_reg_offset(state, base->type, ins->u.cval)/REG_SIZEOF_REG;
17362                         break;
17363                 case OP_DOT:
17364                         reg += field_reg_offset(state, base->type, ins->u.field)/REG_SIZEOF_REG;
17365                         break;
17366                 default:
17367                         internal_error(state, ins, "unhandled part");
17368                         break;
17369                 }
17370                 ins = base;
17371         }
17372         if (base) {
17373                 if (reg > base->lhs) {
17374                         internal_error(state, base, "part out of range?");
17375                 }
17376                 ins = LHS(base, reg);
17377         }
17378         return ins;
17379 }
17380
17381 static int this_def(struct compile_state *state, 
17382         struct triple *ins, struct triple *other)
17383 {
17384         if (ins == other) {
17385                 return 1;
17386         }
17387         if (ins->op == OP_WRITE) {
17388                 ins = part_to_piece(state, MISC(ins, 0));
17389         }
17390         return ins == other;
17391 }
17392
17393 static int phi_in(struct compile_state *state, struct reg_block *blocks,
17394         struct reg_block *rb, struct block *suc)
17395 {
17396         /* Read the conditional input set of a successor block
17397          * (i.e. the input to the phi nodes) and place it in the
17398          * current blocks output set.
17399          */
17400         struct block_set *set;
17401         struct triple *ptr;
17402         int edge;
17403         int done, change;
17404         change = 0;
17405         /* Find the edge I am coming in on */
17406         for(edge = 0, set = suc->use; set; set = set->next, edge++) {
17407                 if (set->member == rb->block) {
17408                         break;
17409                 }
17410         }
17411         if (!set) {
17412                 internal_error(state, 0, "Not coming on a control edge?");
17413         }
17414         for(done = 0, ptr = suc->first; !done; ptr = ptr->next) {
17415                 struct triple **slot, *expr, *ptr2;
17416                 int out_change, done2;
17417                 done = (ptr == suc->last);
17418                 if (ptr->op != OP_PHI) {
17419                         continue;
17420                 }
17421                 slot = &RHS(ptr, 0);
17422                 expr = slot[edge];
17423                 out_change = out_triple(rb, expr);
17424                 if (!out_change) {
17425                         continue;
17426                 }
17427                 /* If we don't define the variable also plast it
17428                  * in the current blocks input set.
17429                  */
17430                 ptr2 = rb->block->first;
17431                 for(done2 = 0; !done2; ptr2 = ptr2->next) {
17432                         if (this_def(state, ptr2, expr)) {
17433                                 break;
17434                         }
17435                         done2 = (ptr2 == rb->block->last);
17436                 }
17437                 if (!done2) {
17438                         continue;
17439                 }
17440                 change |= in_triple(rb, expr);
17441         }
17442         return change;
17443 }
17444
17445 static int reg_in(struct compile_state *state, struct reg_block *blocks,
17446         struct reg_block *rb, struct block *suc)
17447 {
17448         struct triple_reg_set *in_set;
17449         int change;
17450         change = 0;
17451         /* Read the input set of a successor block
17452          * and place it in the current blocks output set.
17453          */
17454         in_set = blocks[suc->vertex].in;
17455         for(; in_set; in_set = in_set->next) {
17456                 int out_change, done;
17457                 struct triple *first, *last, *ptr;
17458                 out_change = out_triple(rb, in_set->member);
17459                 if (!out_change) {
17460                         continue;
17461                 }
17462                 /* If we don't define the variable also place it
17463                  * in the current blocks input set.
17464                  */
17465                 first = rb->block->first;
17466                 last = rb->block->last;
17467                 done = 0;
17468                 for(ptr = first; !done; ptr = ptr->next) {
17469                         if (this_def(state, ptr, in_set->member)) {
17470                                 break;
17471                         }
17472                         done = (ptr == last);
17473                 }
17474                 if (!done) {
17475                         continue;
17476                 }
17477                 change |= in_triple(rb, in_set->member);
17478         }
17479         change |= phi_in(state, blocks, rb, suc);
17480         return change;
17481 }
17482
17483 static int use_in(struct compile_state *state, struct reg_block *rb)
17484 {
17485         /* Find the variables we use but don't define and add
17486          * it to the current blocks input set.
17487          */
17488 #warning "FIXME is this O(N^2) algorithm bad?"
17489         struct block *block;
17490         struct triple *ptr;
17491         int done;
17492         int change;
17493         block = rb->block;
17494         change = 0;
17495         for(done = 0, ptr = block->last; !done; ptr = ptr->prev) {
17496                 struct triple **expr;
17497                 done = (ptr == block->first);
17498                 /* The variable a phi function uses depends on the
17499                  * control flow, and is handled in phi_in, not
17500                  * here.
17501                  */
17502                 if (ptr->op == OP_PHI) {
17503                         continue;
17504                 }
17505                 expr = triple_rhs(state, ptr, 0);
17506                 for(;expr; expr = triple_rhs(state, ptr, expr)) {
17507                         struct triple *rhs, *test;
17508                         int tdone;
17509                         rhs = part_to_piece(state, *expr);
17510                         if (!rhs) {
17511                                 continue;
17512                         }
17513
17514                         /* See if rhs is defined in this block.
17515                          * A write counts as a definition.
17516                          */
17517                         for(tdone = 0, test = ptr; !tdone; test = test->prev) {
17518                                 tdone = (test == block->first);
17519                                 if (this_def(state, test, rhs)) {
17520                                         rhs = 0;
17521                                         break;
17522                                 }
17523                         }
17524                         /* If I still have a valid rhs add it to in */
17525                         change |= in_triple(rb, rhs);
17526                 }
17527         }
17528         return change;
17529 }
17530
17531 static struct reg_block *compute_variable_lifetimes(
17532         struct compile_state *state, struct basic_blocks *bb)
17533 {
17534         struct reg_block *blocks;
17535         int change;
17536         blocks = xcmalloc(
17537                 sizeof(*blocks)*(bb->last_vertex + 1), "reg_block");
17538         initialize_regblock(blocks, bb->last_block, 0);
17539         do {
17540                 int i;
17541                 change = 0;
17542                 for(i = 1; i <= bb->last_vertex; i++) {
17543                         struct block_set *edge;
17544                         struct reg_block *rb;
17545                         rb = &blocks[i];
17546                         /* Add the all successor's input set to in */
17547                         for(edge = rb->block->edges; edge; edge = edge->next) {
17548                                 change |= reg_in(state, blocks, rb, edge->member);
17549                         }
17550                         /* Add use to in... */
17551                         change |= use_in(state, rb);
17552                 }
17553         } while(change);
17554         return blocks;
17555 }
17556
17557 static void free_variable_lifetimes(struct compile_state *state, 
17558         struct basic_blocks *bb, struct reg_block *blocks)
17559 {
17560         int i;
17561         /* free in_set && out_set on each block */
17562         for(i = 1; i <= bb->last_vertex; i++) {
17563                 struct triple_reg_set *entry, *next;
17564                 struct reg_block *rb;
17565                 rb = &blocks[i];
17566                 for(entry = rb->in; entry ; entry = next) {
17567                         next = entry->next;
17568                         do_triple_unset(&rb->in, entry->member);
17569                 }
17570                 for(entry = rb->out; entry; entry = next) {
17571                         next = entry->next;
17572                         do_triple_unset(&rb->out, entry->member);
17573                 }
17574         }
17575         xfree(blocks);
17576
17577 }
17578
17579 typedef void (*wvl_cb_t)(
17580         struct compile_state *state, 
17581         struct reg_block *blocks, struct triple_reg_set *live, 
17582         struct reg_block *rb, struct triple *ins, void *arg);
17583
17584 static void walk_variable_lifetimes(struct compile_state *state,
17585         struct basic_blocks *bb, struct reg_block *blocks, 
17586         wvl_cb_t cb, void *arg)
17587 {
17588         int i;
17589         
17590         for(i = 1; i <= state->bb.last_vertex; i++) {
17591                 struct triple_reg_set *live;
17592                 struct triple_reg_set *entry, *next;
17593                 struct triple *ptr, *prev;
17594                 struct reg_block *rb;
17595                 struct block *block;
17596                 int done;
17597
17598                 /* Get the blocks */
17599                 rb = &blocks[i];
17600                 block = rb->block;
17601
17602                 /* Copy out into live */
17603                 live = 0;
17604                 for(entry = rb->out; entry; entry = next) {
17605                         next = entry->next;
17606                         do_triple_set(&live, entry->member, entry->new);
17607                 }
17608                 /* Walk through the basic block calculating live */
17609                 for(done = 0, ptr = block->last; !done; ptr = prev) {
17610                         struct triple **expr;
17611
17612                         prev = ptr->prev;
17613                         done = (ptr == block->first);
17614
17615                         /* Ensure the current definition is in live */
17616                         if (triple_is_def(state, ptr)) {
17617                                 do_triple_set(&live, ptr, 0);
17618                         }
17619
17620                         /* Inform the callback function of what is
17621                          * going on.
17622                          */
17623                          cb(state, blocks, live, rb, ptr, arg);
17624                         
17625                         /* Remove the current definition from live */
17626                         do_triple_unset(&live, ptr);
17627
17628                         /* Add the current uses to live.
17629                          *
17630                          * It is safe to skip phi functions because they do
17631                          * not have any block local uses, and the block
17632                          * output sets already properly account for what
17633                          * control flow depedent uses phi functions do have.
17634                          */
17635                         if (ptr->op == OP_PHI) {
17636                                 continue;
17637                         }
17638                         expr = triple_rhs(state, ptr, 0);
17639                         for(;expr; expr = triple_rhs(state, ptr, expr)) {
17640                                 /* If the triple is not a definition skip it. */
17641                                 if (!*expr || !triple_is_def(state, *expr)) {
17642                                         continue;
17643                                 }
17644                                 do_triple_set(&live, *expr, 0);
17645                         }
17646                 }
17647                 /* Free live */
17648                 for(entry = live; entry; entry = next) {
17649                         next = entry->next;
17650                         do_triple_unset(&live, entry->member);
17651                 }
17652         }
17653 }
17654
17655 struct print_live_variable_info {
17656         struct reg_block *rb;
17657         FILE *fp;
17658 };
17659 static void print_live_variables_block(
17660         struct compile_state *state, struct block *block, void *arg)
17661
17662 {
17663         struct print_live_variable_info *info = arg;
17664         struct block_set *edge;
17665         FILE *fp = info->fp;
17666         struct reg_block *rb;
17667         struct triple *ptr;
17668         int phi_present;
17669         int done;
17670         rb = &info->rb[block->vertex];
17671
17672         fprintf(fp, "\nblock: %p (%d),",
17673                 block,  block->vertex);
17674         for(edge = block->edges; edge; edge = edge->next) {
17675                 fprintf(fp, " %p<-%p",
17676                         edge->member, 
17677                         edge->member && edge->member->use?edge->member->use->member : 0);
17678         }
17679         fprintf(fp, "\n");
17680         if (rb->in) {
17681                 struct triple_reg_set *in_set;
17682                 fprintf(fp, "        in:");
17683                 for(in_set = rb->in; in_set; in_set = in_set->next) {
17684                         fprintf(fp, " %-10p", in_set->member);
17685                 }
17686                 fprintf(fp, "\n");
17687         }
17688         phi_present = 0;
17689         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
17690                 done = (ptr == block->last);
17691                 if (ptr->op == OP_PHI) {
17692                         phi_present = 1;
17693                         break;
17694                 }
17695         }
17696         if (phi_present) {
17697                 int edge;
17698                 for(edge = 0; edge < block->users; edge++) {
17699                         fprintf(fp, "     in(%d):", edge);
17700                         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
17701                                 struct triple **slot;
17702                                 done = (ptr == block->last);
17703                                 if (ptr->op != OP_PHI) {
17704                                         continue;
17705                                 }
17706                                 slot = &RHS(ptr, 0);
17707                                 fprintf(fp, " %-10p", slot[edge]);
17708                         }
17709                         fprintf(fp, "\n");
17710                 }
17711         }
17712         if (block->first->op == OP_LABEL) {
17713                 fprintf(fp, "%p:\n", block->first);
17714         }
17715         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
17716                 done = (ptr == block->last);
17717                 display_triple(fp, ptr);
17718         }
17719         if (rb->out) {
17720                 struct triple_reg_set *out_set;
17721                 fprintf(fp, "       out:");
17722                 for(out_set = rb->out; out_set; out_set = out_set->next) {
17723                         fprintf(fp, " %-10p", out_set->member);
17724                 }
17725                 fprintf(fp, "\n");
17726         }
17727         fprintf(fp, "\n");
17728 }
17729
17730 static void print_live_variables(struct compile_state *state, 
17731         struct basic_blocks *bb, struct reg_block *rb, FILE *fp)
17732 {
17733         struct print_live_variable_info info;
17734         info.rb = rb;
17735         info.fp = fp;
17736         fprintf(fp, "\nlive variables by block\n");
17737         walk_blocks(state, bb, print_live_variables_block, &info);
17738
17739 }
17740
17741
17742 static int count_triples(struct compile_state *state)
17743 {
17744         struct triple *first, *ins;
17745         int triples = 0;
17746         first = state->first;
17747         ins = first;
17748         do {
17749                 triples++;
17750                 ins = ins->next;
17751         } while (ins != first);
17752         return triples;
17753 }
17754
17755
17756 struct dead_triple {
17757         struct triple *triple;
17758         struct dead_triple *work_next;
17759         struct block *block;
17760         int old_id;
17761         int flags;
17762 #define TRIPLE_FLAG_ALIVE 1
17763 #define TRIPLE_FLAG_FREE  1
17764 };
17765
17766 static void print_dead_triples(struct compile_state *state, 
17767         struct dead_triple *dtriple)
17768 {
17769         struct triple *first, *ins;
17770         struct dead_triple *dt;
17771         FILE *fp;
17772         if (!(state->compiler->debug & DEBUG_TRIPLES)) {
17773                 return;
17774         }
17775         fp = state->dbgout;
17776         fprintf(fp, "--------------- dtriples ---------------\n");
17777         first = state->first;
17778         ins = first;
17779         do {
17780                 dt = &dtriple[ins->id];
17781                 if ((ins->op == OP_LABEL) && (ins->use)) {
17782                         fprintf(fp, "\n%p:\n", ins);
17783                 }
17784                 fprintf(fp, "%c", 
17785                         (dt->flags & TRIPLE_FLAG_ALIVE)?' ': '-');
17786                 display_triple(fp, ins);
17787                 if (triple_is_branch(state, ins)) {
17788                         fprintf(fp, "\n");
17789                 }
17790                 ins = ins->next;
17791         } while(ins != first);
17792         fprintf(fp, "\n");
17793 }
17794
17795
17796 static void awaken(
17797         struct compile_state *state,
17798         struct dead_triple *dtriple, struct triple **expr,
17799         struct dead_triple ***work_list_tail)
17800 {
17801         struct triple *triple;
17802         struct dead_triple *dt;
17803         if (!expr) {
17804                 return;
17805         }
17806         triple = *expr;
17807         if (!triple) {
17808                 return;
17809         }
17810         if (triple->id <= 0)  {
17811                 internal_error(state, triple, "bad triple id: %d",
17812                         triple->id);
17813         }
17814         if (triple->op == OP_NOOP) {
17815                 internal_error(state, triple, "awakening noop?");
17816                 return;
17817         }
17818         dt = &dtriple[triple->id];
17819         if (!(dt->flags & TRIPLE_FLAG_ALIVE)) {
17820                 dt->flags |= TRIPLE_FLAG_ALIVE;
17821                 if (!dt->work_next) {
17822                         **work_list_tail = dt;
17823                         *work_list_tail = &dt->work_next;
17824                 }
17825         }
17826 }
17827
17828 static void eliminate_inefectual_code(struct compile_state *state)
17829 {
17830         struct block *block;
17831         struct dead_triple *dtriple, *work_list, **work_list_tail, *dt;
17832         int triples, i;
17833         struct triple *first, *final, *ins;
17834
17835         if (!(state->compiler->flags & COMPILER_ELIMINATE_INEFECTUAL_CODE)) {
17836                 return;
17837         }
17838
17839         /* Setup the work list */
17840         work_list = 0;
17841         work_list_tail = &work_list;
17842
17843         first = state->first;
17844         final = state->first->prev;
17845
17846         /* Count how many triples I have */
17847         triples = count_triples(state);
17848
17849         /* Now put then in an array and mark all of the triples dead */
17850         dtriple = xcmalloc(sizeof(*dtriple) * (triples + 1), "dtriples");
17851         
17852         ins = first;
17853         i = 1;
17854         block = 0;
17855         do {
17856                 dtriple[i].triple = ins;
17857                 dtriple[i].block  = block_of_triple(state, ins);
17858                 dtriple[i].flags  = 0;
17859                 dtriple[i].old_id = ins->id;
17860                 ins->id = i;
17861                 /* See if it is an operation we always keep */
17862                 if (!triple_is_pure(state, ins, dtriple[i].old_id)) {
17863                         awaken(state, dtriple, &ins, &work_list_tail);
17864                 }
17865                 i++;
17866                 ins = ins->next;
17867         } while(ins != first);
17868         while(work_list) {
17869                 struct block *block;
17870                 struct dead_triple *dt;
17871                 struct block_set *user;
17872                 struct triple **expr;
17873                 dt = work_list;
17874                 work_list = dt->work_next;
17875                 if (!work_list) {
17876                         work_list_tail = &work_list;
17877                 }
17878                 /* Make certain the block the current instruction is in lives */
17879                 block = block_of_triple(state, dt->triple);
17880                 awaken(state, dtriple, &block->first, &work_list_tail);
17881                 if (triple_is_branch(state, block->last)) {
17882                         awaken(state, dtriple, &block->last, &work_list_tail);
17883                 } else {
17884                         awaken(state, dtriple, &block->last->next, &work_list_tail);
17885                 }
17886
17887                 /* Wake up the data depencencies of this triple */
17888                 expr = 0;
17889                 do {
17890                         expr = triple_rhs(state, dt->triple, expr);
17891                         awaken(state, dtriple, expr, &work_list_tail);
17892                 } while(expr);
17893                 do {
17894                         expr = triple_lhs(state, dt->triple, expr);
17895                         awaken(state, dtriple, expr, &work_list_tail);
17896                 } while(expr);
17897                 do {
17898                         expr = triple_misc(state, dt->triple, expr);
17899                         awaken(state, dtriple, expr, &work_list_tail);
17900                 } while(expr);
17901                 /* Wake up the forward control dependencies */
17902                 do {
17903                         expr = triple_targ(state, dt->triple, expr);
17904                         awaken(state, dtriple, expr, &work_list_tail);
17905                 } while(expr);
17906                 /* Wake up the reverse control dependencies of this triple */
17907                 for(user = dt->block->ipdomfrontier; user; user = user->next) {
17908                         struct triple *last;
17909                         last = user->member->last;
17910                         while((last->op == OP_NOOP) && (last != user->member->first)) {
17911                                 internal_warning(state, last, "awakening noop?");
17912                                 last = last->prev;
17913                         }
17914                         awaken(state, dtriple, &last, &work_list_tail);
17915                 }
17916         }
17917         print_dead_triples(state, dtriple);
17918         for(dt = &dtriple[1]; dt <= &dtriple[triples]; dt++) {
17919                 if ((dt->triple->op == OP_NOOP) && 
17920                         (dt->flags & TRIPLE_FLAG_ALIVE)) {
17921                         internal_error(state, dt->triple, "noop effective?");
17922                 }
17923                 dt->triple->id = dt->old_id;    /* Restore the color */
17924                 if (!(dt->flags & TRIPLE_FLAG_ALIVE)) {
17925                         release_triple(state, dt->triple);
17926                 }
17927         }
17928         xfree(dtriple);
17929
17930         rebuild_ssa_form(state);
17931
17932         print_blocks(state, __func__, state->dbgout);
17933 }
17934
17935
17936 static void insert_mandatory_copies(struct compile_state *state)
17937 {
17938         struct triple *ins, *first;
17939
17940         /* The object is with a minimum of inserted copies,
17941          * to resolve in fundamental register conflicts between
17942          * register value producers and consumers.
17943          * Theoretically we may be greater than minimal when we
17944          * are inserting copies before instructions but that
17945          * case should be rare.
17946          */
17947         first = state->first;
17948         ins = first;
17949         do {
17950                 struct triple_set *entry, *next;
17951                 struct triple *tmp;
17952                 struct reg_info info;
17953                 unsigned reg, regcm;
17954                 int do_post_copy, do_pre_copy;
17955                 tmp = 0;
17956                 if (!triple_is_def(state, ins)) {
17957                         goto next;
17958                 }
17959                 /* Find the architecture specific color information */
17960                 info = find_lhs_pre_color(state, ins, 0);
17961                 if (info.reg >= MAX_REGISTERS) {
17962                         info.reg = REG_UNSET;
17963                 }
17964
17965                 reg = REG_UNSET;
17966                 regcm = arch_type_to_regcm(state, ins->type);
17967                 do_post_copy = do_pre_copy = 0;
17968
17969                 /* Walk through the uses of ins and check for conflicts */
17970                 for(entry = ins->use; entry; entry = next) {
17971                         struct reg_info rinfo;
17972                         int i;
17973                         next = entry->next;
17974                         i = find_rhs_use(state, entry->member, ins);
17975                         if (i < 0) {
17976                                 continue;
17977                         }
17978                         
17979                         /* Find the users color requirements */
17980                         rinfo = arch_reg_rhs(state, entry->member, i);
17981                         if (rinfo.reg >= MAX_REGISTERS) {
17982                                 rinfo.reg = REG_UNSET;
17983                         }
17984                         
17985                         /* See if I need a pre_copy */
17986                         if (rinfo.reg != REG_UNSET) {
17987                                 if ((reg != REG_UNSET) && (reg != rinfo.reg)) {
17988                                         do_pre_copy = 1;
17989                                 }
17990                                 reg = rinfo.reg;
17991                         }
17992                         regcm &= rinfo.regcm;
17993                         regcm = arch_regcm_normalize(state, regcm);
17994                         if (regcm == 0) {
17995                                 do_pre_copy = 1;
17996                         }
17997                         /* Always use pre_copies for constants.
17998                          * They do not take up any registers until a
17999                          * copy places them in one.
18000                          */
18001                         if ((info.reg == REG_UNNEEDED) && 
18002                                 (rinfo.reg != REG_UNNEEDED)) {
18003                                 do_pre_copy = 1;
18004                         }
18005                 }
18006                 do_post_copy =
18007                         !do_pre_copy &&
18008                         (((info.reg != REG_UNSET) && 
18009                                 (reg != REG_UNSET) &&
18010                                 (info.reg != reg)) ||
18011                         ((info.regcm & regcm) == 0));
18012
18013                 reg = info.reg;
18014                 regcm = info.regcm;
18015                 /* Walk through the uses of ins and do a pre_copy or see if a post_copy is warranted */
18016                 for(entry = ins->use; entry; entry = next) {
18017                         struct reg_info rinfo;
18018                         int i;
18019                         next = entry->next;
18020                         i = find_rhs_use(state, entry->member, ins);
18021                         if (i < 0) {
18022                                 continue;
18023                         }
18024                         
18025                         /* Find the users color requirements */
18026                         rinfo = arch_reg_rhs(state, entry->member, i);
18027                         if (rinfo.reg >= MAX_REGISTERS) {
18028                                 rinfo.reg = REG_UNSET;
18029                         }
18030
18031                         /* Now see if it is time to do the pre_copy */
18032                         if (rinfo.reg != REG_UNSET) {
18033                                 if (((reg != REG_UNSET) && (reg != rinfo.reg)) ||
18034                                         ((regcm & rinfo.regcm) == 0) ||
18035                                         /* Don't let a mandatory coalesce sneak
18036                                          * into a operation that is marked to prevent
18037                                          * coalescing.
18038                                          */
18039                                         ((reg != REG_UNNEEDED) &&
18040                                         ((ins->id & TRIPLE_FLAG_POST_SPLIT) ||
18041                                         (entry->member->id & TRIPLE_FLAG_PRE_SPLIT)))
18042                                         ) {
18043                                         if (do_pre_copy) {
18044                                                 struct triple *user;
18045                                                 user = entry->member;
18046                                                 if (RHS(user, i) != ins) {
18047                                                         internal_error(state, user, "bad rhs");
18048                                                 }
18049                                                 tmp = pre_copy(state, user, i);
18050                                                 tmp->id |= TRIPLE_FLAG_PRE_SPLIT;
18051                                                 continue;
18052                                         } else {
18053                                                 do_post_copy = 1;
18054                                         }
18055                                 }
18056                                 reg = rinfo.reg;
18057                         }
18058                         if ((regcm & rinfo.regcm) == 0) {
18059                                 if (do_pre_copy) {
18060                                         struct triple *user;
18061                                         user = entry->member;
18062                                         if (RHS(user, i) != ins) {
18063                                                 internal_error(state, user, "bad rhs");
18064                                         }
18065                                         tmp = pre_copy(state, user, i);
18066                                         tmp->id |= TRIPLE_FLAG_PRE_SPLIT;
18067                                         continue;
18068                                 } else {
18069                                         do_post_copy = 1;
18070                                 }
18071                         }
18072                         regcm &= rinfo.regcm;
18073                         
18074                 }
18075                 if (do_post_copy) {
18076                         struct reg_info pre, post;
18077                         tmp = post_copy(state, ins);
18078                         tmp->id |= TRIPLE_FLAG_PRE_SPLIT;
18079                         pre = arch_reg_lhs(state, ins, 0);
18080                         post = arch_reg_lhs(state, tmp, 0);
18081                         if ((pre.reg == post.reg) && (pre.regcm == post.regcm)) {
18082                                 internal_error(state, tmp, "useless copy");
18083                         }
18084                 }
18085         next:
18086                 ins = ins->next;
18087         } while(ins != first);
18088
18089         print_blocks(state, __func__, state->dbgout);
18090 }
18091
18092
18093 struct live_range_edge;
18094 struct live_range_def;
18095 struct live_range {
18096         struct live_range_edge *edges;
18097         struct live_range_def *defs;
18098 /* Note. The list pointed to by defs is kept in order.
18099  * That is baring splits in the flow control
18100  * defs dominates defs->next wich dominates defs->next->next
18101  * etc.
18102  */
18103         unsigned color;
18104         unsigned classes;
18105         unsigned degree;
18106         unsigned length;
18107         struct live_range *group_next, **group_prev;
18108 };
18109
18110 struct live_range_edge {
18111         struct live_range_edge *next;
18112         struct live_range *node;
18113 };
18114
18115 struct live_range_def {
18116         struct live_range_def *next;
18117         struct live_range_def *prev;
18118         struct live_range *lr;
18119         struct triple *def;
18120         unsigned orig_id;
18121 };
18122
18123 #define LRE_HASH_SIZE 2048
18124 struct lre_hash {
18125         struct lre_hash *next;
18126         struct live_range *left;
18127         struct live_range *right;
18128 };
18129
18130
18131 struct reg_state {
18132         struct lre_hash *hash[LRE_HASH_SIZE];
18133         struct reg_block *blocks;
18134         struct live_range_def *lrd;
18135         struct live_range *lr;
18136         struct live_range *low, **low_tail;
18137         struct live_range *high, **high_tail;
18138         unsigned defs;
18139         unsigned ranges;
18140         int passes, max_passes;
18141 };
18142
18143
18144 struct print_interference_block_info {
18145         struct reg_state *rstate;
18146         FILE *fp;
18147         int need_edges;
18148 };
18149 static void print_interference_block(
18150         struct compile_state *state, struct block *block, void *arg)
18151
18152 {
18153         struct print_interference_block_info *info = arg;
18154         struct reg_state *rstate = info->rstate;
18155         struct block_set *edge;
18156         FILE *fp = info->fp;
18157         struct reg_block *rb;
18158         struct triple *ptr;
18159         int phi_present;
18160         int done;
18161         rb = &rstate->blocks[block->vertex];
18162
18163         fprintf(fp, "\nblock: %p (%d),",
18164                 block,  block->vertex);
18165         for(edge = block->edges; edge; edge = edge->next) {
18166                 fprintf(fp, " %p<-%p",
18167                         edge->member, 
18168                         edge->member && edge->member->use?edge->member->use->member : 0);
18169         }
18170         fprintf(fp, "\n");
18171         if (rb->in) {
18172                 struct triple_reg_set *in_set;
18173                 fprintf(fp, "        in:");
18174                 for(in_set = rb->in; in_set; in_set = in_set->next) {
18175                         fprintf(fp, " %-10p", in_set->member);
18176                 }
18177                 fprintf(fp, "\n");
18178         }
18179         phi_present = 0;
18180         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
18181                 done = (ptr == block->last);
18182                 if (ptr->op == OP_PHI) {
18183                         phi_present = 1;
18184                         break;
18185                 }
18186         }
18187         if (phi_present) {
18188                 int edge;
18189                 for(edge = 0; edge < block->users; edge++) {
18190                         fprintf(fp, "     in(%d):", edge);
18191                         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
18192                                 struct triple **slot;
18193                                 done = (ptr == block->last);
18194                                 if (ptr->op != OP_PHI) {
18195                                         continue;
18196                                 }
18197                                 slot = &RHS(ptr, 0);
18198                                 fprintf(fp, " %-10p", slot[edge]);
18199                         }
18200                         fprintf(fp, "\n");
18201                 }
18202         }
18203         if (block->first->op == OP_LABEL) {
18204                 fprintf(fp, "%p:\n", block->first);
18205         }
18206         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
18207                 struct live_range *lr;
18208                 unsigned id;
18209                 int op;
18210                 op = ptr->op;
18211                 done = (ptr == block->last);
18212                 lr = rstate->lrd[ptr->id].lr;
18213                 
18214                 id = ptr->id;
18215                 ptr->id = rstate->lrd[id].orig_id;
18216                 SET_REG(ptr->id, lr->color);
18217                 display_triple(fp, ptr);
18218                 ptr->id = id;
18219
18220                 if (triple_is_def(state, ptr) && (lr->defs == 0)) {
18221                         internal_error(state, ptr, "lr has no defs!");
18222                 }
18223                 if (info->need_edges) {
18224                         if (lr->defs) {
18225                                 struct live_range_def *lrd;
18226                                 fprintf(fp, "       range:");
18227                                 lrd = lr->defs;
18228                                 do {
18229                                         fprintf(fp, " %-10p", lrd->def);
18230                                         lrd = lrd->next;
18231                                 } while(lrd != lr->defs);
18232                                 fprintf(fp, "\n");
18233                         }
18234                         if (lr->edges > 0) {
18235                                 struct live_range_edge *edge;
18236                                 fprintf(fp, "       edges:");
18237                                 for(edge = lr->edges; edge; edge = edge->next) {
18238                                         struct live_range_def *lrd;
18239                                         lrd = edge->node->defs;
18240                                         do {
18241                                                 fprintf(fp, " %-10p", lrd->def);
18242                                                 lrd = lrd->next;
18243                                         } while(lrd != edge->node->defs);
18244                                         fprintf(fp, "|");
18245                                 }
18246                                 fprintf(fp, "\n");
18247                         }
18248                 }
18249                 /* Do a bunch of sanity checks */
18250                 valid_ins(state, ptr);
18251                 if ((ptr->id < 0) || (ptr->id > rstate->defs)) {
18252                         internal_error(state, ptr, "Invalid triple id: %d",
18253                                 ptr->id);
18254                 }
18255         }
18256         if (rb->out) {
18257                 struct triple_reg_set *out_set;
18258                 fprintf(fp, "       out:");
18259                 for(out_set = rb->out; out_set; out_set = out_set->next) {
18260                         fprintf(fp, " %-10p", out_set->member);
18261                 }
18262                 fprintf(fp, "\n");
18263         }
18264         fprintf(fp, "\n");
18265 }
18266
18267 static void print_interference_blocks(
18268         struct compile_state *state, struct reg_state *rstate, FILE *fp, int need_edges)
18269 {
18270         struct print_interference_block_info info;
18271         info.rstate = rstate;
18272         info.fp = fp;
18273         info.need_edges = need_edges;
18274         fprintf(fp, "\nlive variables by block\n");
18275         walk_blocks(state, &state->bb, print_interference_block, &info);
18276
18277 }
18278
18279 static unsigned regc_max_size(struct compile_state *state, int classes)
18280 {
18281         unsigned max_size;
18282         int i;
18283         max_size = 0;
18284         for(i = 0; i < MAX_REGC; i++) {
18285                 if (classes & (1 << i)) {
18286                         unsigned size;
18287                         size = arch_regc_size(state, i);
18288                         if (size > max_size) {
18289                                 max_size = size;
18290                         }
18291                 }
18292         }
18293         return max_size;
18294 }
18295
18296 static int reg_is_reg(struct compile_state *state, int reg1, int reg2)
18297 {
18298         unsigned equivs[MAX_REG_EQUIVS];
18299         int i;
18300         if ((reg1 < 0) || (reg1 >= MAX_REGISTERS)) {
18301                 internal_error(state, 0, "invalid register");
18302         }
18303         if ((reg2 < 0) || (reg2 >= MAX_REGISTERS)) {
18304                 internal_error(state, 0, "invalid register");
18305         }
18306         arch_reg_equivs(state, equivs, reg1);
18307         for(i = 0; (i < MAX_REG_EQUIVS) && equivs[i] != REG_UNSET; i++) {
18308                 if (equivs[i] == reg2) {
18309                         return 1;
18310                 }
18311         }
18312         return 0;
18313 }
18314
18315 static void reg_fill_used(struct compile_state *state, char *used, int reg)
18316 {
18317         unsigned equivs[MAX_REG_EQUIVS];
18318         int i;
18319         if (reg == REG_UNNEEDED) {
18320                 return;
18321         }
18322         arch_reg_equivs(state, equivs, reg);
18323         for(i = 0; (i < MAX_REG_EQUIVS) && equivs[i] != REG_UNSET; i++) {
18324                 used[equivs[i]] = 1;
18325         }
18326         return;
18327 }
18328
18329 static void reg_inc_used(struct compile_state *state, char *used, int reg)
18330 {
18331         unsigned equivs[MAX_REG_EQUIVS];
18332         int i;
18333         if (reg == REG_UNNEEDED) {
18334                 return;
18335         }
18336         arch_reg_equivs(state, equivs, reg);
18337         for(i = 0; (i < MAX_REG_EQUIVS) && equivs[i] != REG_UNSET; i++) {
18338                 used[equivs[i]] += 1;
18339         }
18340         return;
18341 }
18342
18343 static unsigned int hash_live_edge(
18344         struct live_range *left, struct live_range *right)
18345 {
18346         unsigned int hash, val;
18347         unsigned long lval, rval;
18348         lval = ((unsigned long)left)/sizeof(struct live_range);
18349         rval = ((unsigned long)right)/sizeof(struct live_range);
18350         hash = 0;
18351         while(lval) {
18352                 val = lval & 0xff;
18353                 lval >>= 8;
18354                 hash = (hash *263) + val;
18355         }
18356         while(rval) {
18357                 val = rval & 0xff;
18358                 rval >>= 8;
18359                 hash = (hash *263) + val;
18360         }
18361         hash = hash & (LRE_HASH_SIZE - 1);
18362         return hash;
18363 }
18364
18365 static struct lre_hash **lre_probe(struct reg_state *rstate,
18366         struct live_range *left, struct live_range *right)
18367 {
18368         struct lre_hash **ptr;
18369         unsigned int index;
18370         /* Ensure left <= right */
18371         if (left > right) {
18372                 struct live_range *tmp;
18373                 tmp = left;
18374                 left = right;
18375                 right = tmp;
18376         }
18377         index = hash_live_edge(left, right);
18378         
18379         ptr = &rstate->hash[index];
18380         while(*ptr) {
18381                 if (((*ptr)->left == left) && ((*ptr)->right == right)) {
18382                         break;
18383                 }
18384                 ptr = &(*ptr)->next;
18385         }
18386         return ptr;
18387 }
18388
18389 static int interfere(struct reg_state *rstate,
18390         struct live_range *left, struct live_range *right)
18391 {
18392         struct lre_hash **ptr;
18393         ptr = lre_probe(rstate, left, right);
18394         return ptr && *ptr;
18395 }
18396
18397 static void add_live_edge(struct reg_state *rstate, 
18398         struct live_range *left, struct live_range *right)
18399 {
18400         /* FIXME the memory allocation overhead is noticeable here... */
18401         struct lre_hash **ptr, *new_hash;
18402         struct live_range_edge *edge;
18403
18404         if (left == right) {
18405                 return;
18406         }
18407         if ((left == &rstate->lr[0]) || (right == &rstate->lr[0])) {
18408                 return;
18409         }
18410         /* Ensure left <= right */
18411         if (left > right) {
18412                 struct live_range *tmp;
18413                 tmp = left;
18414                 left = right;
18415                 right = tmp;
18416         }
18417         ptr = lre_probe(rstate, left, right);
18418         if (*ptr) {
18419                 return;
18420         }
18421 #if 0
18422         fprintf(state->errout, "new_live_edge(%p, %p)\n",
18423                 left, right);
18424 #endif
18425         new_hash = xmalloc(sizeof(*new_hash), "lre_hash");
18426         new_hash->next  = *ptr;
18427         new_hash->left  = left;
18428         new_hash->right = right;
18429         *ptr = new_hash;
18430
18431         edge = xmalloc(sizeof(*edge), "live_range_edge");
18432         edge->next   = left->edges;
18433         edge->node   = right;
18434         left->edges  = edge;
18435         left->degree += 1;
18436         
18437         edge = xmalloc(sizeof(*edge), "live_range_edge");
18438         edge->next    = right->edges;
18439         edge->node    = left;
18440         right->edges  = edge;
18441         right->degree += 1;
18442 }
18443
18444 static void remove_live_edge(struct reg_state *rstate,
18445         struct live_range *left, struct live_range *right)
18446 {
18447         struct live_range_edge *edge, **ptr;
18448         struct lre_hash **hptr, *entry;
18449         hptr = lre_probe(rstate, left, right);
18450         if (!hptr || !*hptr) {
18451                 return;
18452         }
18453         entry = *hptr;
18454         *hptr = entry->next;
18455         xfree(entry);
18456
18457         for(ptr = &left->edges; *ptr; ptr = &(*ptr)->next) {
18458                 edge = *ptr;
18459                 if (edge->node == right) {
18460                         *ptr = edge->next;
18461                         memset(edge, 0, sizeof(*edge));
18462                         xfree(edge);
18463                         right->degree--;
18464                         break;
18465                 }
18466         }
18467         for(ptr = &right->edges; *ptr; ptr = &(*ptr)->next) {
18468                 edge = *ptr;
18469                 if (edge->node == left) {
18470                         *ptr = edge->next;
18471                         memset(edge, 0, sizeof(*edge));
18472                         xfree(edge);
18473                         left->degree--;
18474                         break;
18475                 }
18476         }
18477 }
18478
18479 static void remove_live_edges(struct reg_state *rstate, struct live_range *range)
18480 {
18481         struct live_range_edge *edge, *next;
18482         for(edge = range->edges; edge; edge = next) {
18483                 next = edge->next;
18484                 remove_live_edge(rstate, range, edge->node);
18485         }
18486 }
18487
18488 static void transfer_live_edges(struct reg_state *rstate, 
18489         struct live_range *dest, struct live_range *src)
18490 {
18491         struct live_range_edge *edge, *next;
18492         for(edge = src->edges; edge; edge = next) {
18493                 struct live_range *other;
18494                 next = edge->next;
18495                 other = edge->node;
18496                 remove_live_edge(rstate, src, other);
18497                 add_live_edge(rstate, dest, other);
18498         }
18499 }
18500
18501
18502 /* Interference graph...
18503  * 
18504  * new(n) --- Return a graph with n nodes but no edges.
18505  * add(g,x,y) --- Return a graph including g with an between x and y
18506  * interfere(g, x, y) --- Return true if there exists an edge between the nodes
18507  *                x and y in the graph g
18508  * degree(g, x) --- Return the degree of the node x in the graph g
18509  * neighbors(g, x, f) --- Apply function f to each neighbor of node x in the graph g
18510  *
18511  * Implement with a hash table && a set of adjcency vectors.
18512  * The hash table supports constant time implementations of add and interfere.
18513  * The adjacency vectors support an efficient implementation of neighbors.
18514  */
18515
18516 /* 
18517  *     +---------------------------------------------------+
18518  *     |         +--------------+                          |
18519  *     v         v              |                          |
18520  * renumber -> build graph -> colalesce -> spill_costs -> simplify -> select 
18521  *
18522  * -- In simplify implment optimistic coloring... (No backtracking)
18523  * -- Implement Rematerialization it is the only form of spilling we can perform
18524  *    Essentially this means dropping a constant from a register because
18525  *    we can regenerate it later.
18526  *
18527  * --- Very conservative colalescing (don't colalesce just mark the opportunities)
18528  *     coalesce at phi points...
18529  * --- Bias coloring if at all possible do the coalesing a compile time.
18530  *
18531  *
18532  */
18533
18534 static void different_colored(
18535         struct compile_state *state, struct reg_state *rstate, 
18536         struct triple *parent, struct triple *ins)
18537 {
18538         struct live_range *lr;
18539         struct triple **expr;
18540         lr = rstate->lrd[ins->id].lr;
18541         expr = triple_rhs(state, ins, 0);
18542         for(;expr; expr = triple_rhs(state, ins, expr)) {
18543                 struct live_range *lr2;
18544                 if (!*expr || (*expr == parent) || (*expr == ins)) {
18545                         continue;
18546                 }
18547                 lr2 = rstate->lrd[(*expr)->id].lr;
18548                 if (lr->color == lr2->color) {
18549                         internal_error(state, ins, "live range too big");
18550                 }
18551         }
18552 }
18553
18554
18555 static struct live_range *coalesce_ranges(
18556         struct compile_state *state, struct reg_state *rstate,
18557         struct live_range *lr1, struct live_range *lr2)
18558 {
18559         struct live_range_def *head, *mid1, *mid2, *end, *lrd;
18560         unsigned color;
18561         unsigned classes;
18562         if (lr1 == lr2) {
18563                 return lr1;
18564         }
18565         if (!lr1->defs || !lr2->defs) {
18566                 internal_error(state, 0,
18567                         "cannot coalese dead live ranges");
18568         }
18569         if ((lr1->color == REG_UNNEEDED) ||
18570                 (lr2->color == REG_UNNEEDED)) {
18571                 internal_error(state, 0, 
18572                         "cannot coalesce live ranges without a possible color");
18573         }
18574         if ((lr1->color != lr2->color) &&
18575                 (lr1->color != REG_UNSET) &&
18576                 (lr2->color != REG_UNSET)) {
18577                 internal_error(state, lr1->defs->def, 
18578                         "cannot coalesce live ranges of different colors");
18579         }
18580         color = lr1->color;
18581         if (color == REG_UNSET) {
18582                 color = lr2->color;
18583         }
18584         classes = lr1->classes & lr2->classes;
18585         if (!classes) {
18586                 internal_error(state, lr1->defs->def,
18587                         "cannot coalesce live ranges with dissimilar register classes");
18588         }
18589         if (state->compiler->debug & DEBUG_COALESCING) {
18590                 FILE *fp = state->errout;
18591                 fprintf(fp, "coalescing:");
18592                 lrd = lr1->defs;
18593                 do {
18594                         fprintf(fp, " %p", lrd->def);
18595                         lrd = lrd->next;
18596                 } while(lrd != lr1->defs);
18597                 fprintf(fp, " |");
18598                 lrd = lr2->defs;
18599                 do {
18600                         fprintf(fp, " %p", lrd->def);
18601                         lrd = lrd->next;
18602                 } while(lrd != lr2->defs);
18603                 fprintf(fp, "\n");
18604         }
18605         /* If there is a clear dominate live range put it in lr1,
18606          * For purposes of this test phi functions are
18607          * considered dominated by the definitions that feed into
18608          * them. 
18609          */
18610         if ((lr1->defs->prev->def->op == OP_PHI) ||
18611                 ((lr2->defs->prev->def->op != OP_PHI) &&
18612                 tdominates(state, lr2->defs->def, lr1->defs->def))) {
18613                 struct live_range *tmp;
18614                 tmp = lr1;
18615                 lr1 = lr2;
18616                 lr2 = tmp;
18617         }
18618 #if 0
18619         if (lr1->defs->orig_id  & TRIPLE_FLAG_POST_SPLIT) {
18620                 fprintf(state->errout, "lr1 post\n");
18621         }
18622         if (lr1->defs->orig_id & TRIPLE_FLAG_PRE_SPLIT) {
18623                 fprintf(state->errout, "lr1 pre\n");
18624         }
18625         if (lr2->defs->orig_id  & TRIPLE_FLAG_POST_SPLIT) {
18626                 fprintf(state->errout, "lr2 post\n");
18627         }
18628         if (lr2->defs->orig_id & TRIPLE_FLAG_PRE_SPLIT) {
18629                 fprintf(state->errout, "lr2 pre\n");
18630         }
18631 #endif
18632 #if 0
18633         fprintf(state->errout, "coalesce color1(%p): %3d color2(%p) %3d\n",
18634                 lr1->defs->def,
18635                 lr1->color,
18636                 lr2->defs->def,
18637                 lr2->color);
18638 #endif
18639         
18640         /* Append lr2 onto lr1 */
18641 #warning "FIXME should this be a merge instead of a splice?"
18642         /* This FIXME item applies to the correctness of live_range_end 
18643          * and to the necessity of making multiple passes of coalesce_live_ranges.
18644          * A failure to find some coalesce opportunities in coaleace_live_ranges
18645          * does not impact the correct of the compiler just the efficiency with
18646          * which registers are allocated.
18647          */
18648         head = lr1->defs;
18649         mid1 = lr1->defs->prev;
18650         mid2 = lr2->defs;
18651         end  = lr2->defs->prev;
18652         
18653         head->prev = end;
18654         end->next  = head;
18655
18656         mid1->next = mid2;
18657         mid2->prev = mid1;
18658
18659         /* Fixup the live range in the added live range defs */
18660         lrd = head;
18661         do {
18662                 lrd->lr = lr1;
18663                 lrd = lrd->next;
18664         } while(lrd != head);
18665
18666         /* Mark lr2 as free. */
18667         lr2->defs = 0;
18668         lr2->color = REG_UNNEEDED;
18669         lr2->classes = 0;
18670
18671         if (!lr1->defs) {
18672                 internal_error(state, 0, "lr1->defs == 0 ?");
18673         }
18674
18675         lr1->color   = color;
18676         lr1->classes = classes;
18677
18678         /* Keep the graph in sync by transfering the edges from lr2 to lr1 */
18679         transfer_live_edges(rstate, lr1, lr2);
18680
18681         return lr1;
18682 }
18683
18684 static struct live_range_def *live_range_head(
18685         struct compile_state *state, struct live_range *lr,
18686         struct live_range_def *last)
18687 {
18688         struct live_range_def *result;
18689         result = 0;
18690         if (last == 0) {
18691                 result = lr->defs;
18692         }
18693         else if (!tdominates(state, lr->defs->def, last->next->def)) {
18694                 result = last->next;
18695         }
18696         return result;
18697 }
18698
18699 static struct live_range_def *live_range_end(
18700         struct compile_state *state, struct live_range *lr,
18701         struct live_range_def *last)
18702 {
18703         struct live_range_def *result;
18704         result = 0;
18705         if (last == 0) {
18706                 result = lr->defs->prev;
18707         }
18708         else if (!tdominates(state, last->prev->def, lr->defs->prev->def)) {
18709                 result = last->prev;
18710         }
18711         return result;
18712 }
18713
18714
18715 static void initialize_live_ranges(
18716         struct compile_state *state, struct reg_state *rstate)
18717 {
18718         struct triple *ins, *first;
18719         size_t count, size;
18720         int i, j;
18721
18722         first = state->first;
18723         /* First count how many instructions I have.
18724          */
18725         count = count_triples(state);
18726         /* Potentially I need one live range definitions for each
18727          * instruction.
18728          */
18729         rstate->defs = count;
18730         /* Potentially I need one live range for each instruction
18731          * plus an extra for the dummy live range.
18732          */
18733         rstate->ranges = count + 1;
18734         size = sizeof(rstate->lrd[0]) * rstate->defs;
18735         rstate->lrd = xcmalloc(size, "live_range_def");
18736         size = sizeof(rstate->lr[0]) * rstate->ranges;
18737         rstate->lr  = xcmalloc(size, "live_range");
18738
18739         /* Setup the dummy live range */
18740         rstate->lr[0].classes = 0;
18741         rstate->lr[0].color = REG_UNSET;
18742         rstate->lr[0].defs = 0;
18743         i = j = 0;
18744         ins = first;
18745         do {
18746                 /* If the triple is a variable give it a live range */
18747                 if (triple_is_def(state, ins)) {
18748                         struct reg_info info;
18749                         /* Find the architecture specific color information */
18750                         info = find_def_color(state, ins);
18751                         i++;
18752                         rstate->lr[i].defs    = &rstate->lrd[j];
18753                         rstate->lr[i].color   = info.reg;
18754                         rstate->lr[i].classes = info.regcm;
18755                         rstate->lr[i].degree  = 0;
18756                         rstate->lrd[j].lr = &rstate->lr[i];
18757                 } 
18758                 /* Otherwise give the triple the dummy live range. */
18759                 else {
18760                         rstate->lrd[j].lr = &rstate->lr[0];
18761                 }
18762
18763                 /* Initalize the live_range_def */
18764                 rstate->lrd[j].next    = &rstate->lrd[j];
18765                 rstate->lrd[j].prev    = &rstate->lrd[j];
18766                 rstate->lrd[j].def     = ins;
18767                 rstate->lrd[j].orig_id = ins->id;
18768                 ins->id = j;
18769
18770                 j++;
18771                 ins = ins->next;
18772         } while(ins != first);
18773         rstate->ranges = i;
18774
18775         /* Make a second pass to handle achitecture specific register
18776          * constraints.
18777          */
18778         ins = first;
18779         do {
18780                 int zlhs, zrhs, i, j;
18781                 if (ins->id > rstate->defs) {
18782                         internal_error(state, ins, "bad id");
18783                 }
18784                 
18785                 /* Walk through the template of ins and coalesce live ranges */
18786                 zlhs = ins->lhs;
18787                 if ((zlhs == 0) && triple_is_def(state, ins)) {
18788                         zlhs = 1;
18789                 }
18790                 zrhs = ins->rhs;
18791
18792                 if (state->compiler->debug & DEBUG_COALESCING2) {
18793                         fprintf(state->errout, "mandatory coalesce: %p %d %d\n",
18794                                 ins, zlhs, zrhs);
18795                 }
18796
18797                 for(i = 0; i < zlhs; i++) {
18798                         struct reg_info linfo;
18799                         struct live_range_def *lhs;
18800                         linfo = arch_reg_lhs(state, ins, i);
18801                         if (linfo.reg < MAX_REGISTERS) {
18802                                 continue;
18803                         }
18804                         if (triple_is_def(state, ins)) {
18805                                 lhs = &rstate->lrd[ins->id];
18806                         } else {
18807                                 lhs = &rstate->lrd[LHS(ins, i)->id];
18808                         }
18809
18810                         if (state->compiler->debug & DEBUG_COALESCING2) {
18811                                 fprintf(state->errout, "coalesce lhs(%d): %p %d\n",
18812                                         i, lhs, linfo.reg);
18813                         }
18814
18815                         for(j = 0; j < zrhs; j++) {
18816                                 struct reg_info rinfo;
18817                                 struct live_range_def *rhs;
18818                                 rinfo = arch_reg_rhs(state, ins, j);
18819                                 if (rinfo.reg < MAX_REGISTERS) {
18820                                         continue;
18821                                 }
18822                                 rhs = &rstate->lrd[RHS(ins, j)->id];
18823
18824                                 if (state->compiler->debug & DEBUG_COALESCING2) {
18825                                         fprintf(state->errout, "coalesce rhs(%d): %p %d\n",
18826                                                 j, rhs, rinfo.reg);
18827                                 }
18828
18829                                 if (rinfo.reg == linfo.reg) {
18830                                         coalesce_ranges(state, rstate, 
18831                                                 lhs->lr, rhs->lr);
18832                                 }
18833                         }
18834                 }
18835                 ins = ins->next;
18836         } while(ins != first);
18837 }
18838
18839 static void graph_ins(
18840         struct compile_state *state, 
18841         struct reg_block *blocks, struct triple_reg_set *live, 
18842         struct reg_block *rb, struct triple *ins, void *arg)
18843 {
18844         struct reg_state *rstate = arg;
18845         struct live_range *def;
18846         struct triple_reg_set *entry;
18847
18848         /* If the triple is not a definition
18849          * we do not have a definition to add to
18850          * the interference graph.
18851          */
18852         if (!triple_is_def(state, ins)) {
18853                 return;
18854         }
18855         def = rstate->lrd[ins->id].lr;
18856         
18857         /* Create an edge between ins and everything that is
18858          * alive, unless the live_range cannot share
18859          * a physical register with ins.
18860          */
18861         for(entry = live; entry; entry = entry->next) {
18862                 struct live_range *lr;
18863                 if ((entry->member->id < 0) || (entry->member->id > rstate->defs)) {
18864                         internal_error(state, 0, "bad entry?");
18865                 }
18866                 lr = rstate->lrd[entry->member->id].lr;
18867                 if (def == lr) {
18868                         continue;
18869                 }
18870                 if (!arch_regcm_intersect(def->classes, lr->classes)) {
18871                         continue;
18872                 }
18873                 add_live_edge(rstate, def, lr);
18874         }
18875         return;
18876 }
18877
18878 static struct live_range *get_verify_live_range(
18879         struct compile_state *state, struct reg_state *rstate, struct triple *ins)
18880 {
18881         struct live_range *lr;
18882         struct live_range_def *lrd;
18883         int ins_found;
18884         if ((ins->id < 0) || (ins->id > rstate->defs)) {
18885                 internal_error(state, ins, "bad ins?");
18886         }
18887         lr = rstate->lrd[ins->id].lr;
18888         ins_found = 0;
18889         lrd = lr->defs;
18890         do {
18891                 if (lrd->def == ins) {
18892                         ins_found = 1;
18893                 }
18894                 lrd = lrd->next;
18895         } while(lrd != lr->defs);
18896         if (!ins_found) {
18897                 internal_error(state, ins, "ins not in live range");
18898         }
18899         return lr;
18900 }
18901
18902 static void verify_graph_ins(
18903         struct compile_state *state, 
18904         struct reg_block *blocks, struct triple_reg_set *live, 
18905         struct reg_block *rb, struct triple *ins, void *arg)
18906 {
18907         struct reg_state *rstate = arg;
18908         struct triple_reg_set *entry1, *entry2;
18909
18910
18911         /* Compare live against edges and make certain the code is working */
18912         for(entry1 = live; entry1; entry1 = entry1->next) {
18913                 struct live_range *lr1;
18914                 lr1 = get_verify_live_range(state, rstate, entry1->member);
18915                 for(entry2 = live; entry2; entry2 = entry2->next) {
18916                         struct live_range *lr2;
18917                         struct live_range_edge *edge2;
18918                         int lr1_found;
18919                         int lr2_degree;
18920                         if (entry2 == entry1) {
18921                                 continue;
18922                         }
18923                         lr2 = get_verify_live_range(state, rstate, entry2->member);
18924                         if (lr1 == lr2) {
18925                                 internal_error(state, entry2->member, 
18926                                         "live range with 2 values simultaneously alive");
18927                         }
18928                         if (!arch_regcm_intersect(lr1->classes, lr2->classes)) {
18929                                 continue;
18930                         }
18931                         if (!interfere(rstate, lr1, lr2)) {
18932                                 internal_error(state, entry2->member, 
18933                                         "edges don't interfere?");
18934                         }
18935                                 
18936                         lr1_found = 0;
18937                         lr2_degree = 0;
18938                         for(edge2 = lr2->edges; edge2; edge2 = edge2->next) {
18939                                 lr2_degree++;
18940                                 if (edge2->node == lr1) {
18941                                         lr1_found = 1;
18942                                 }
18943                         }
18944                         if (lr2_degree != lr2->degree) {
18945                                 internal_error(state, entry2->member,
18946                                         "computed degree: %d does not match reported degree: %d\n",
18947                                         lr2_degree, lr2->degree);
18948                         }
18949                         if (!lr1_found) {
18950                                 internal_error(state, entry2->member, "missing edge");
18951                         }
18952                 }
18953         }
18954         return;
18955 }
18956
18957
18958 static void print_interference_ins(
18959         struct compile_state *state, 
18960         struct reg_block *blocks, struct triple_reg_set *live, 
18961         struct reg_block *rb, struct triple *ins, void *arg)
18962 {
18963         struct reg_state *rstate = arg;
18964         struct live_range *lr;
18965         unsigned id;
18966         FILE *fp = state->dbgout;
18967
18968         lr = rstate->lrd[ins->id].lr;
18969         id = ins->id;
18970         ins->id = rstate->lrd[id].orig_id;
18971         SET_REG(ins->id, lr->color);
18972         display_triple(state->dbgout, ins);
18973         ins->id = id;
18974
18975         if (lr->defs) {
18976                 struct live_range_def *lrd;
18977                 fprintf(fp, "       range:");
18978                 lrd = lr->defs;
18979                 do {
18980                         fprintf(fp, " %-10p", lrd->def);
18981                         lrd = lrd->next;
18982                 } while(lrd != lr->defs);
18983                 fprintf(fp, "\n");
18984         }
18985         if (live) {
18986                 struct triple_reg_set *entry;
18987                 fprintf(fp, "        live:");
18988                 for(entry = live; entry; entry = entry->next) {
18989                         fprintf(fp, " %-10p", entry->member);
18990                 }
18991                 fprintf(fp, "\n");
18992         }
18993         if (lr->edges) {
18994                 struct live_range_edge *entry;
18995                 fprintf(fp, "       edges:");
18996                 for(entry = lr->edges; entry; entry = entry->next) {
18997                         struct live_range_def *lrd;
18998                         lrd = entry->node->defs;
18999                         do {
19000                                 fprintf(fp, " %-10p", lrd->def);
19001                                 lrd = lrd->next;
19002                         } while(lrd != entry->node->defs);
19003                         fprintf(fp, "|");
19004                 }
19005                 fprintf(fp, "\n");
19006         }
19007         if (triple_is_branch(state, ins)) {
19008                 fprintf(fp, "\n");
19009         }
19010         return;
19011 }
19012
19013 static int coalesce_live_ranges(
19014         struct compile_state *state, struct reg_state *rstate)
19015 {
19016         /* At the point where a value is moved from one
19017          * register to another that value requires two
19018          * registers, thus increasing register pressure.
19019          * Live range coaleescing reduces the register
19020          * pressure by keeping a value in one register
19021          * longer.
19022          *
19023          * In the case of a phi function all paths leading
19024          * into it must be allocated to the same register
19025          * otherwise the phi function may not be removed.
19026          *
19027          * Forcing a value to stay in a single register
19028          * for an extended period of time does have
19029          * limitations when applied to non homogenous
19030          * register pool.  
19031          *
19032          * The two cases I have identified are:
19033          * 1) Two forced register assignments may
19034          *    collide.
19035          * 2) Registers may go unused because they
19036          *    are only good for storing the value
19037          *    and not manipulating it.
19038          *
19039          * Because of this I need to split live ranges,
19040          * even outside of the context of coalesced live
19041          * ranges.  The need to split live ranges does
19042          * impose some constraints on live range coalescing.
19043          *
19044          * - Live ranges may not be coalesced across phi
19045          *   functions.  This creates a 2 headed live
19046          *   range that cannot be sanely split.
19047          *
19048          * - phi functions (coalesced in initialize_live_ranges) 
19049          *   are handled as pre split live ranges so we will
19050          *   never attempt to split them.
19051          */
19052         int coalesced;
19053         int i;
19054
19055         coalesced = 0;
19056         for(i = 0; i <= rstate->ranges; i++) {
19057                 struct live_range *lr1;
19058                 struct live_range_def *lrd1;
19059                 lr1 = &rstate->lr[i];
19060                 if (!lr1->defs) {
19061                         continue;
19062                 }
19063                 lrd1 = live_range_end(state, lr1, 0);
19064                 for(; lrd1; lrd1 = live_range_end(state, lr1, lrd1)) {
19065                         struct triple_set *set;
19066                         if (lrd1->def->op != OP_COPY) {
19067                                 continue;
19068                         }
19069                         /* Skip copies that are the result of a live range split. */
19070                         if (lrd1->orig_id & TRIPLE_FLAG_POST_SPLIT) {
19071                                 continue;
19072                         }
19073                         for(set = lrd1->def->use; set; set = set->next) {
19074                                 struct live_range_def *lrd2;
19075                                 struct live_range *lr2, *res;
19076
19077                                 lrd2 = &rstate->lrd[set->member->id];
19078
19079                                 /* Don't coalesce with instructions
19080                                  * that are the result of a live range
19081                                  * split.
19082                                  */
19083                                 if (lrd2->orig_id & TRIPLE_FLAG_PRE_SPLIT) {
19084                                         continue;
19085                                 }
19086                                 lr2 = rstate->lrd[set->member->id].lr;
19087                                 if (lr1 == lr2) {
19088                                         continue;
19089                                 }
19090                                 if ((lr1->color != lr2->color) &&
19091                                         (lr1->color != REG_UNSET) &&
19092                                         (lr2->color != REG_UNSET)) {
19093                                         continue;
19094                                 }
19095                                 if ((lr1->classes & lr2->classes) == 0) {
19096                                         continue;
19097                                 }
19098                                 
19099                                 if (interfere(rstate, lr1, lr2)) {
19100                                         continue;
19101                                 }
19102
19103                                 res = coalesce_ranges(state, rstate, lr1, lr2);
19104                                 coalesced += 1;
19105                                 if (res != lr1) {
19106                                         goto next;
19107                                 }
19108                         }
19109                 }
19110         next:
19111                 ;
19112         }
19113         return coalesced;
19114 }
19115
19116
19117 static void fix_coalesce_conflicts(struct compile_state *state,
19118         struct reg_block *blocks, struct triple_reg_set *live,
19119         struct reg_block *rb, struct triple *ins, void *arg)
19120 {
19121         int *conflicts = arg;
19122         int zlhs, zrhs, i, j;
19123
19124         /* See if we have a mandatory coalesce operation between
19125          * a lhs and a rhs value.  If so and the rhs value is also
19126          * alive then this triple needs to be pre copied.  Otherwise
19127          * we would have two definitions in the same live range simultaneously
19128          * alive.
19129          */
19130         zlhs = ins->lhs;
19131         if ((zlhs == 0) && triple_is_def(state, ins)) {
19132                 zlhs = 1;
19133         }
19134         zrhs = ins->rhs;
19135         for(i = 0; i < zlhs; i++) {
19136                 struct reg_info linfo;
19137                 linfo = arch_reg_lhs(state, ins, i);
19138                 if (linfo.reg < MAX_REGISTERS) {
19139                         continue;
19140                 }
19141                 for(j = 0; j < zrhs; j++) {
19142                         struct reg_info rinfo;
19143                         struct triple *rhs;
19144                         struct triple_reg_set *set;
19145                         int found;
19146                         found = 0;
19147                         rinfo = arch_reg_rhs(state, ins, j);
19148                         if (rinfo.reg != linfo.reg) {
19149                                 continue;
19150                         }
19151                         rhs = RHS(ins, j);
19152                         for(set = live; set && !found; set = set->next) {
19153                                 if (set->member == rhs) {
19154                                         found = 1;
19155                                 }
19156                         }
19157                         if (found) {
19158                                 struct triple *copy;
19159                                 copy = pre_copy(state, ins, j);
19160                                 copy->id |= TRIPLE_FLAG_PRE_SPLIT;
19161                                 (*conflicts)++;
19162                         }
19163                 }
19164         }
19165         return;
19166 }
19167
19168 static int correct_coalesce_conflicts(
19169         struct compile_state *state, struct reg_block *blocks)
19170 {
19171         int conflicts;
19172         conflicts = 0;
19173         walk_variable_lifetimes(state, &state->bb, blocks, 
19174                 fix_coalesce_conflicts, &conflicts);
19175         return conflicts;
19176 }
19177
19178 static void replace_set_use(struct compile_state *state,
19179         struct triple_reg_set *head, struct triple *orig, struct triple *new)
19180 {
19181         struct triple_reg_set *set;
19182         for(set = head; set; set = set->next) {
19183                 if (set->member == orig) {
19184                         set->member = new;
19185                 }
19186         }
19187 }
19188
19189 static void replace_block_use(struct compile_state *state, 
19190         struct reg_block *blocks, struct triple *orig, struct triple *new)
19191 {
19192         int i;
19193 #warning "WISHLIST visit just those blocks that need it *"
19194         for(i = 1; i <= state->bb.last_vertex; i++) {
19195                 struct reg_block *rb;
19196                 rb = &blocks[i];
19197                 replace_set_use(state, rb->in, orig, new);
19198                 replace_set_use(state, rb->out, orig, new);
19199         }
19200 }
19201
19202 static void color_instructions(struct compile_state *state)
19203 {
19204         struct triple *ins, *first;
19205         first = state->first;
19206         ins = first;
19207         do {
19208                 if (triple_is_def(state, ins)) {
19209                         struct reg_info info;
19210                         info = find_lhs_color(state, ins, 0);
19211                         if (info.reg >= MAX_REGISTERS) {
19212                                 info.reg = REG_UNSET;
19213                         }
19214                         SET_INFO(ins->id, info);
19215                 }
19216                 ins = ins->next;
19217         } while(ins != first);
19218 }
19219
19220 static struct reg_info read_lhs_color(
19221         struct compile_state *state, struct triple *ins, int index)
19222 {
19223         struct reg_info info;
19224         if ((index == 0) && triple_is_def(state, ins)) {
19225                 info.reg   = ID_REG(ins->id);
19226                 info.regcm = ID_REGCM(ins->id);
19227         }
19228         else if (index < ins->lhs) {
19229                 info = read_lhs_color(state, LHS(ins, index), 0);
19230         }
19231         else {
19232                 internal_error(state, ins, "Bad lhs %d", index);
19233                 info.reg = REG_UNSET;
19234                 info.regcm = 0;
19235         }
19236         return info;
19237 }
19238
19239 static struct triple *resolve_tangle(
19240         struct compile_state *state, struct triple *tangle)
19241 {
19242         struct reg_info info, uinfo;
19243         struct triple_set *set, *next;
19244         struct triple *copy;
19245
19246 #warning "WISHLIST recalculate all affected instructions colors"
19247         info = find_lhs_color(state, tangle, 0);
19248         for(set = tangle->use; set; set = next) {
19249                 struct triple *user;
19250                 int i, zrhs;
19251                 next = set->next;
19252                 user = set->member;
19253                 zrhs = user->rhs;
19254                 for(i = 0; i < zrhs; i++) {
19255                         if (RHS(user, i) != tangle) {
19256                                 continue;
19257                         }
19258                         uinfo = find_rhs_post_color(state, user, i);
19259                         if (uinfo.reg == info.reg) {
19260                                 copy = pre_copy(state, user, i);
19261                                 copy->id |= TRIPLE_FLAG_PRE_SPLIT;
19262                                 SET_INFO(copy->id, uinfo);
19263                         }
19264                 }
19265         }
19266         copy = 0;
19267         uinfo = find_lhs_pre_color(state, tangle, 0);
19268         if (uinfo.reg == info.reg) {
19269                 struct reg_info linfo;
19270                 copy = post_copy(state, tangle);
19271                 copy->id |= TRIPLE_FLAG_PRE_SPLIT;
19272                 linfo = find_lhs_color(state, copy, 0);
19273                 SET_INFO(copy->id, linfo);
19274         }
19275         info = find_lhs_color(state, tangle, 0);
19276         SET_INFO(tangle->id, info);
19277         
19278         return copy;
19279 }
19280
19281
19282 static void fix_tangles(struct compile_state *state,
19283         struct reg_block *blocks, struct triple_reg_set *live,
19284         struct reg_block *rb, struct triple *ins, void *arg)
19285 {
19286         int *tangles = arg;
19287         struct triple *tangle;
19288         do {
19289                 char used[MAX_REGISTERS];
19290                 struct triple_reg_set *set;
19291                 tangle = 0;
19292
19293                 /* Find out which registers have multiple uses at this point */
19294                 memset(used, 0, sizeof(used));
19295                 for(set = live; set; set = set->next) {
19296                         struct reg_info info;
19297                         info = read_lhs_color(state, set->member, 0);
19298                         if (info.reg == REG_UNSET) {
19299                                 continue;
19300                         }
19301                         reg_inc_used(state, used, info.reg);
19302                 }
19303                 
19304                 /* Now find the least dominated definition of a register in
19305                  * conflict I have seen so far.
19306                  */
19307                 for(set = live; set; set = set->next) {
19308                         struct reg_info info;
19309                         info = read_lhs_color(state, set->member, 0);
19310                         if (used[info.reg] < 2) {
19311                                 continue;
19312                         }
19313                         /* Changing copies that feed into phi functions
19314                          * is incorrect.
19315                          */
19316                         if (set->member->use && 
19317                                 (set->member->use->member->op == OP_PHI)) {
19318                                 continue;
19319                         }
19320                         if (!tangle || tdominates(state, set->member, tangle)) {
19321                                 tangle = set->member;
19322                         }
19323                 }
19324                 /* If I have found a tangle resolve it */
19325                 if (tangle) {
19326                         struct triple *post_copy;
19327                         (*tangles)++;
19328                         post_copy = resolve_tangle(state, tangle);
19329                         if (post_copy) {
19330                                 replace_block_use(state, blocks, tangle, post_copy);
19331                         }
19332                         if (post_copy && (tangle != ins)) {
19333                                 replace_set_use(state, live, tangle, post_copy);
19334                         }
19335                 }
19336         } while(tangle);
19337         return;
19338 }
19339
19340 static int correct_tangles(
19341         struct compile_state *state, struct reg_block *blocks)
19342 {
19343         int tangles;
19344         tangles = 0;
19345         color_instructions(state);
19346         walk_variable_lifetimes(state, &state->bb, blocks, 
19347                 fix_tangles, &tangles);
19348         return tangles;
19349 }
19350
19351
19352 static void ids_from_rstate(struct compile_state *state, struct reg_state *rstate);
19353 static void cleanup_rstate(struct compile_state *state, struct reg_state *rstate);
19354
19355 struct triple *find_constrained_def(
19356         struct compile_state *state, struct live_range *range, struct triple *constrained)
19357 {
19358         struct live_range_def *lrd, *lrd_next;
19359         lrd_next = range->defs;
19360         do {
19361                 struct reg_info info;
19362                 unsigned regcm;
19363
19364                 lrd = lrd_next;
19365                 lrd_next = lrd->next;
19366
19367                 regcm = arch_type_to_regcm(state, lrd->def->type);
19368                 info = find_lhs_color(state, lrd->def, 0);
19369                 regcm      = arch_regcm_reg_normalize(state, regcm);
19370                 info.regcm = arch_regcm_reg_normalize(state, info.regcm);
19371                 /* If the 2 register class masks are equal then
19372                  * the current register class is not constrained.
19373                  */
19374                 if (regcm == info.regcm) {
19375                         continue;
19376                 }
19377                 
19378                 /* If there is just one use.
19379                  * That use cannot accept a larger register class.
19380                  * There are no intervening definitions except
19381                  * definitions that feed into that use.
19382                  * Then a triple is not constrained.
19383                  * FIXME handle this case!
19384                  */
19385 #warning "FIXME ignore cases that cannot be fixed (a definition followed by a use)"
19386                 
19387
19388                 /* Of the constrained live ranges deal with the
19389                  * least dominated one first.
19390                  */
19391                 if (state->compiler->debug & DEBUG_RANGE_CONFLICTS) {
19392                         fprintf(state->errout, "canidate: %p %-8s regcm: %x %x\n",
19393                                 lrd->def, tops(lrd->def->op), regcm, info.regcm);
19394                 }
19395                 if (!constrained || 
19396                         tdominates(state, lrd->def, constrained))
19397                 {
19398                         constrained = lrd->def;
19399                 }
19400         } while(lrd_next != range->defs);
19401         return constrained;
19402 }
19403
19404 static int split_constrained_ranges(
19405         struct compile_state *state, struct reg_state *rstate, 
19406         struct live_range *range)
19407 {
19408         /* Walk through the edges in conflict and our current live
19409          * range, and find definitions that are more severly constrained
19410          * than they type of data they contain require.
19411          * 
19412          * Then pick one of those ranges and relax the constraints.
19413          */
19414         struct live_range_edge *edge;
19415         struct triple *constrained;
19416
19417         constrained = 0;
19418         for(edge = range->edges; edge; edge = edge->next) {
19419                 constrained = find_constrained_def(state, edge->node, constrained);
19420         }
19421 #warning "FIXME should I call find_constrained_def here only if no previous constrained def was found?"
19422         if (!constrained) {
19423                 constrained = find_constrained_def(state, range, constrained);
19424         }
19425
19426         if (state->compiler->debug & DEBUG_RANGE_CONFLICTS) {
19427                 fprintf(state->errout, "constrained: ");
19428                 display_triple(state->errout, constrained);
19429         }
19430         if (constrained) {
19431                 ids_from_rstate(state, rstate);
19432                 cleanup_rstate(state, rstate);
19433                 resolve_tangle(state, constrained);
19434         }
19435         return !!constrained;
19436 }
19437         
19438 static int split_ranges(
19439         struct compile_state *state, struct reg_state *rstate,
19440         char *used, struct live_range *range)
19441 {
19442         int split;
19443         if (state->compiler->debug & DEBUG_RANGE_CONFLICTS) {
19444                 fprintf(state->errout, "split_ranges %d %s %p\n", 
19445                         rstate->passes, tops(range->defs->def->op), range->defs->def);
19446         }
19447         if ((range->color == REG_UNNEEDED) ||
19448                 (rstate->passes >= rstate->max_passes)) {
19449                 return 0;
19450         }
19451         split = split_constrained_ranges(state, rstate, range);
19452
19453         /* Ideally I would split the live range that will not be used
19454          * for the longest period of time in hopes that this will 
19455          * (a) allow me to spill a register or
19456          * (b) allow me to place a value in another register.
19457          *
19458          * So far I don't have a test case for this, the resolving
19459          * of mandatory constraints has solved all of my
19460          * know issues.  So I have choosen not to write any
19461          * code until I cat get a better feel for cases where
19462          * it would be useful to have.
19463          *
19464          */
19465 #warning "WISHLIST implement live range splitting..."
19466         
19467         if (!split && (state->compiler->debug & DEBUG_RANGE_CONFLICTS2)) {
19468                 FILE *fp = state->errout;
19469                 print_interference_blocks(state, rstate, fp, 0);
19470                 print_dominators(state, fp, &state->bb);
19471         }
19472         return split;
19473 }
19474
19475 static FILE *cgdebug_fp(struct compile_state *state)
19476 {
19477         FILE *fp;
19478         fp = 0;
19479         if (!fp && (state->compiler->debug & DEBUG_COLOR_GRAPH2)) {
19480                 fp = state->errout;
19481         }
19482         if (!fp && (state->compiler->debug & DEBUG_COLOR_GRAPH)) {
19483                 fp = state->dbgout;
19484         }
19485         return fp;
19486 }
19487
19488 static void cgdebug_printf(struct compile_state *state, const char *fmt, ...)
19489 {
19490         FILE *fp;
19491         fp = cgdebug_fp(state);
19492         if (fp) {
19493                 va_list args;
19494                 va_start(args, fmt);
19495                 vfprintf(fp, fmt, args);
19496                 va_end(args);
19497         }
19498 }
19499
19500 static void cgdebug_flush(struct compile_state *state)
19501 {
19502         FILE *fp;
19503         fp = cgdebug_fp(state);
19504         if (fp) {
19505                 fflush(fp);
19506         }
19507 }
19508
19509 static void cgdebug_loc(struct compile_state *state, struct triple *ins)
19510 {
19511         FILE *fp;
19512         fp = cgdebug_fp(state);
19513         if (fp) {
19514                 loc(fp, state, ins);
19515         }
19516 }
19517
19518 static int select_free_color(struct compile_state *state, 
19519         struct reg_state *rstate, struct live_range *range)
19520 {
19521         struct triple_set *entry;
19522         struct live_range_def *lrd;
19523         struct live_range_def *phi;
19524         struct live_range_edge *edge;
19525         char used[MAX_REGISTERS];
19526         struct triple **expr;
19527
19528         /* Instead of doing just the trivial color select here I try
19529          * a few extra things because a good color selection will help reduce
19530          * copies.
19531          */
19532
19533         /* Find the registers currently in use */
19534         memset(used, 0, sizeof(used));
19535         for(edge = range->edges; edge; edge = edge->next) {
19536                 if (edge->node->color == REG_UNSET) {
19537                         continue;
19538                 }
19539                 reg_fill_used(state, used, edge->node->color);
19540         }
19541
19542         if (state->compiler->debug & DEBUG_COLOR_GRAPH2) {
19543                 int i;
19544                 i = 0;
19545                 for(edge = range->edges; edge; edge = edge->next) {
19546                         i++;
19547                 }
19548                 cgdebug_printf(state, "\n%s edges: %d", 
19549                         tops(range->defs->def->op), i);
19550                 cgdebug_loc(state, range->defs->def);
19551                 cgdebug_printf(state, "\n");
19552                 for(i = 0; i < MAX_REGISTERS; i++) {
19553                         if (used[i]) {
19554                                 cgdebug_printf(state, "used: %s\n",
19555                                         arch_reg_str(i));
19556                         }
19557                 }
19558         }       
19559
19560         /* If a color is already assigned see if it will work */
19561         if (range->color != REG_UNSET) {
19562                 struct live_range_def *lrd;
19563                 if (!used[range->color]) {
19564                         return 1;
19565                 }
19566                 for(edge = range->edges; edge; edge = edge->next) {
19567                         if (edge->node->color != range->color) {
19568                                 continue;
19569                         }
19570                         warning(state, edge->node->defs->def, "edge: ");
19571                         lrd = edge->node->defs;
19572                         do {
19573                                 warning(state, lrd->def, " %p %s",
19574                                         lrd->def, tops(lrd->def->op));
19575                                 lrd = lrd->next;
19576                         } while(lrd != edge->node->defs);
19577                 }
19578                 lrd = range->defs;
19579                 warning(state, range->defs->def, "def: ");
19580                 do {
19581                         warning(state, lrd->def, " %p %s",
19582                                 lrd->def, tops(lrd->def->op));
19583                         lrd = lrd->next;
19584                 } while(lrd != range->defs);
19585                 internal_error(state, range->defs->def,
19586                         "live range with already used color %s",
19587                         arch_reg_str(range->color));
19588         }
19589
19590         /* If I feed into an expression reuse it's color.
19591          * This should help remove copies in the case of 2 register instructions
19592          * and phi functions.
19593          */
19594         phi = 0;
19595         lrd = live_range_end(state, range, 0);
19596         for(; (range->color == REG_UNSET) && lrd ; lrd = live_range_end(state, range, lrd)) {
19597                 entry = lrd->def->use;
19598                 for(;(range->color == REG_UNSET) && entry; entry = entry->next) {
19599                         struct live_range_def *insd;
19600                         unsigned regcm;
19601                         insd = &rstate->lrd[entry->member->id];
19602                         if (insd->lr->defs == 0) {
19603                                 continue;
19604                         }
19605                         if (!phi && (insd->def->op == OP_PHI) &&
19606                                 !interfere(rstate, range, insd->lr)) {
19607                                 phi = insd;
19608                         }
19609                         if (insd->lr->color == REG_UNSET) {
19610                                 continue;
19611                         }
19612                         regcm = insd->lr->classes;
19613                         if (((regcm & range->classes) == 0) ||
19614                                 (used[insd->lr->color])) {
19615                                 continue;
19616                         }
19617                         if (interfere(rstate, range, insd->lr)) {
19618                                 continue;
19619                         }
19620                         range->color = insd->lr->color;
19621                 }
19622         }
19623         /* If I feed into a phi function reuse it's color or the color
19624          * of something else that feeds into the phi function.
19625          */
19626         if (phi) {
19627                 if (phi->lr->color != REG_UNSET) {
19628                         if (used[phi->lr->color]) {
19629                                 range->color = phi->lr->color;
19630                         }
19631                 }
19632                 else {
19633                         expr = triple_rhs(state, phi->def, 0);
19634                         for(; expr; expr = triple_rhs(state, phi->def, expr)) {
19635                                 struct live_range *lr;
19636                                 unsigned regcm;
19637                                 if (!*expr) {
19638                                         continue;
19639                                 }
19640                                 lr = rstate->lrd[(*expr)->id].lr;
19641                                 if (lr->color == REG_UNSET) {
19642                                         continue;
19643                                 }
19644                                 regcm = lr->classes;
19645                                 if (((regcm & range->classes) == 0) ||
19646                                         (used[lr->color])) {
19647                                         continue;
19648                                 }
19649                                 if (interfere(rstate, range, lr)) {
19650                                         continue;
19651                                 }
19652                                 range->color = lr->color;
19653                         }
19654                 }
19655         }
19656         /* If I don't interfere with a rhs node reuse it's color */
19657         lrd = live_range_head(state, range, 0);
19658         for(; (range->color == REG_UNSET) && lrd ; lrd = live_range_head(state, range, lrd)) {
19659                 expr = triple_rhs(state, lrd->def, 0);
19660                 for(; expr; expr = triple_rhs(state, lrd->def, expr)) {
19661                         struct live_range *lr;
19662                         unsigned regcm;
19663                         if (!*expr) {
19664                                 continue;
19665                         }
19666                         lr = rstate->lrd[(*expr)->id].lr;
19667                         if (lr->color == REG_UNSET) {
19668                                 continue;
19669                         }
19670                         regcm = lr->classes;
19671                         if (((regcm & range->classes) == 0) ||
19672                                 (used[lr->color])) {
19673                                 continue;
19674                         }
19675                         if (interfere(rstate, range, lr)) {
19676                                 continue;
19677                         }
19678                         range->color = lr->color;
19679                         break;
19680                 }
19681         }
19682         /* If I have not opportunitically picked a useful color
19683          * pick the first color that is free.
19684          */
19685         if (range->color == REG_UNSET) {
19686                 range->color = 
19687                         arch_select_free_register(state, used, range->classes);
19688         }
19689         if (range->color == REG_UNSET) {
19690                 struct live_range_def *lrd;
19691                 int i;
19692                 if (split_ranges(state, rstate, used, range)) {
19693                         return 0;
19694                 }
19695                 for(edge = range->edges; edge; edge = edge->next) {
19696                         warning(state, edge->node->defs->def, "edge reg %s",
19697                                 arch_reg_str(edge->node->color));
19698                         lrd = edge->node->defs;
19699                         do {
19700                                 warning(state, lrd->def, " %s %p",
19701                                         tops(lrd->def->op), lrd->def);
19702                                 lrd = lrd->next;
19703                         } while(lrd != edge->node->defs);
19704                 }
19705                 warning(state, range->defs->def, "range: ");
19706                 lrd = range->defs;
19707                 do {
19708                         warning(state, lrd->def, " %s %p",
19709                                 tops(lrd->def->op), lrd->def);
19710                         lrd = lrd->next;
19711                 } while(lrd != range->defs);
19712                         
19713                 warning(state, range->defs->def, "classes: %x",
19714                         range->classes);
19715                 for(i = 0; i < MAX_REGISTERS; i++) {
19716                         if (used[i]) {
19717                                 warning(state, range->defs->def, "used: %s",
19718                                         arch_reg_str(i));
19719                         }
19720                 }
19721                 error(state, range->defs->def, "too few registers");
19722         }
19723         range->classes &= arch_reg_regcm(state, range->color);
19724         if ((range->color == REG_UNSET) || (range->classes == 0)) {
19725                 internal_error(state, range->defs->def, "select_free_color did not?");
19726         }
19727         return 1;
19728 }
19729
19730 static int color_graph(struct compile_state *state, struct reg_state *rstate)
19731 {
19732         int colored;
19733         struct live_range_edge *edge;
19734         struct live_range *range;
19735         if (rstate->low) {
19736                 cgdebug_printf(state, "Lo: ");
19737                 range = rstate->low;
19738                 if (*range->group_prev != range) {
19739                         internal_error(state, 0, "lo: *prev != range?");
19740                 }
19741                 *range->group_prev = range->group_next;
19742                 if (range->group_next) {
19743                         range->group_next->group_prev = range->group_prev;
19744                 }
19745                 if (&range->group_next == rstate->low_tail) {
19746                         rstate->low_tail = range->group_prev;
19747                 }
19748                 if (rstate->low == range) {
19749                         internal_error(state, 0, "low: next != prev?");
19750                 }
19751         }
19752         else if (rstate->high) {
19753                 cgdebug_printf(state, "Hi: ");
19754                 range = rstate->high;
19755                 if (*range->group_prev != range) {
19756                         internal_error(state, 0, "hi: *prev != range?");
19757                 }
19758                 *range->group_prev = range->group_next;
19759                 if (range->group_next) {
19760                         range->group_next->group_prev = range->group_prev;
19761                 }
19762                 if (&range->group_next == rstate->high_tail) {
19763                         rstate->high_tail = range->group_prev;
19764                 }
19765                 if (rstate->high == range) {
19766                         internal_error(state, 0, "high: next != prev?");
19767                 }
19768         }
19769         else {
19770                 return 1;
19771         }
19772         cgdebug_printf(state, " %d\n", range - rstate->lr);
19773         range->group_prev = 0;
19774         for(edge = range->edges; edge; edge = edge->next) {
19775                 struct live_range *node;
19776                 node = edge->node;
19777                 /* Move nodes from the high to the low list */
19778                 if (node->group_prev && (node->color == REG_UNSET) &&
19779                         (node->degree == regc_max_size(state, node->classes))) {
19780                         if (*node->group_prev != node) {
19781                                 internal_error(state, 0, "move: *prev != node?");
19782                         }
19783                         *node->group_prev = node->group_next;
19784                         if (node->group_next) {
19785                                 node->group_next->group_prev = node->group_prev;
19786                         }
19787                         if (&node->group_next == rstate->high_tail) {
19788                                 rstate->high_tail = node->group_prev;
19789                         }
19790                         cgdebug_printf(state, "Moving...%d to low\n", node - rstate->lr);
19791                         node->group_prev  = rstate->low_tail;
19792                         node->group_next  = 0;
19793                         *rstate->low_tail = node;
19794                         rstate->low_tail  = &node->group_next;
19795                         if (*node->group_prev != node) {
19796                                 internal_error(state, 0, "move2: *prev != node?");
19797                         }
19798                 }
19799                 node->degree -= 1;
19800         }
19801         colored = color_graph(state, rstate);
19802         if (colored) {
19803                 cgdebug_printf(state, "Coloring %d @", range - rstate->lr);
19804                 cgdebug_loc(state, range->defs->def);
19805                 cgdebug_flush(state);
19806                 colored = select_free_color(state, rstate, range);
19807                 if (colored) {
19808                         cgdebug_printf(state, " %s\n", arch_reg_str(range->color));
19809                 }
19810         }
19811         return colored;
19812 }
19813
19814 static void verify_colors(struct compile_state *state, struct reg_state *rstate)
19815 {
19816         struct live_range *lr;
19817         struct live_range_edge *edge;
19818         struct triple *ins, *first;
19819         char used[MAX_REGISTERS];
19820         first = state->first;
19821         ins = first;
19822         do {
19823                 if (triple_is_def(state, ins)) {
19824                         if ((ins->id < 0) || (ins->id > rstate->defs)) {
19825                                 internal_error(state, ins, 
19826                                         "triple without a live range def");
19827                         }
19828                         lr = rstate->lrd[ins->id].lr;
19829                         if (lr->color == REG_UNSET) {
19830                                 internal_error(state, ins,
19831                                         "triple without a color");
19832                         }
19833                         /* Find the registers used by the edges */
19834                         memset(used, 0, sizeof(used));
19835                         for(edge = lr->edges; edge; edge = edge->next) {
19836                                 if (edge->node->color == REG_UNSET) {
19837                                         internal_error(state, 0,
19838                                                 "live range without a color");
19839                         }
19840                                 reg_fill_used(state, used, edge->node->color);
19841                         }
19842                         if (used[lr->color]) {
19843                                 internal_error(state, ins,
19844                                         "triple with already used color");
19845                         }
19846                 }
19847                 ins = ins->next;
19848         } while(ins != first);
19849 }
19850
19851 static void color_triples(struct compile_state *state, struct reg_state *rstate)
19852 {
19853         struct live_range_def *lrd;
19854         struct live_range *lr;
19855         struct triple *first, *ins;
19856         first = state->first;
19857         ins = first;
19858         do {
19859                 if ((ins->id < 0) || (ins->id > rstate->defs)) {
19860                         internal_error(state, ins, 
19861                                 "triple without a live range");
19862                 }
19863                 lrd = &rstate->lrd[ins->id];
19864                 lr = lrd->lr;
19865                 ins->id = lrd->orig_id;
19866                 SET_REG(ins->id, lr->color);
19867                 ins = ins->next;
19868         } while (ins != first);
19869 }
19870
19871 static struct live_range *merge_sort_lr(
19872         struct live_range *first, struct live_range *last)
19873 {
19874         struct live_range *mid, *join, **join_tail, *pick;
19875         size_t size;
19876         size = (last - first) + 1;
19877         if (size >= 2) {
19878                 mid = first + size/2;
19879                 first = merge_sort_lr(first, mid -1);
19880                 mid   = merge_sort_lr(mid, last);
19881                 
19882                 join = 0;
19883                 join_tail = &join;
19884                 /* merge the two lists */
19885                 while(first && mid) {
19886                         if ((first->degree < mid->degree) ||
19887                                 ((first->degree == mid->degree) &&
19888                                         (first->length < mid->length))) {
19889                                 pick = first;
19890                                 first = first->group_next;
19891                                 if (first) {
19892                                         first->group_prev = 0;
19893                                 }
19894                         }
19895                         else {
19896                                 pick = mid;
19897                                 mid = mid->group_next;
19898                                 if (mid) {
19899                                         mid->group_prev = 0;
19900                                 }
19901                         }
19902                         pick->group_next = 0;
19903                         pick->group_prev = join_tail;
19904                         *join_tail = pick;
19905                         join_tail = &pick->group_next;
19906                 }
19907                 /* Splice the remaining list */
19908                 pick = (first)? first : mid;
19909                 *join_tail = pick;
19910                 if (pick) { 
19911                         pick->group_prev = join_tail;
19912                 }
19913         }
19914         else {
19915                 if (!first->defs) {
19916                         first = 0;
19917                 }
19918                 join = first;
19919         }
19920         return join;
19921 }
19922
19923 static void ids_from_rstate(struct compile_state *state, 
19924         struct reg_state *rstate)
19925 {
19926         struct triple *ins, *first;
19927         if (!rstate->defs) {
19928                 return;
19929         }
19930         /* Display the graph if desired */
19931         if (state->compiler->debug & DEBUG_INTERFERENCE) {
19932                 FILE *fp = state->dbgout;
19933                 print_interference_blocks(state, rstate, fp, 0);
19934                 print_control_flow(state, fp, &state->bb);
19935                 fflush(fp);
19936         }
19937         first = state->first;
19938         ins = first;
19939         do {
19940                 if (ins->id) {
19941                         struct live_range_def *lrd;
19942                         lrd = &rstate->lrd[ins->id];
19943                         ins->id = lrd->orig_id;
19944                 }
19945                 ins = ins->next;
19946         } while(ins != first);
19947 }
19948
19949 static void cleanup_live_edges(struct reg_state *rstate)
19950 {
19951         int i;
19952         /* Free the edges on each node */
19953         for(i = 1; i <= rstate->ranges; i++) {
19954                 remove_live_edges(rstate, &rstate->lr[i]);
19955         }
19956 }
19957
19958 static void cleanup_rstate(struct compile_state *state, struct reg_state *rstate)
19959 {
19960         cleanup_live_edges(rstate);
19961         xfree(rstate->lrd);
19962         xfree(rstate->lr);
19963
19964         /* Free the variable lifetime information */
19965         if (rstate->blocks) {
19966                 free_variable_lifetimes(state, &state->bb, rstate->blocks);
19967         }
19968         rstate->defs = 0;
19969         rstate->ranges = 0;
19970         rstate->lrd = 0;
19971         rstate->lr = 0;
19972         rstate->blocks = 0;
19973 }
19974
19975 static void verify_consistency(struct compile_state *state);
19976 static void allocate_registers(struct compile_state *state)
19977 {
19978         struct reg_state rstate;
19979         int colored;
19980
19981         /* Clear out the reg_state */
19982         memset(&rstate, 0, sizeof(rstate));
19983         rstate.max_passes = state->compiler->max_allocation_passes;
19984
19985         do {
19986                 struct live_range **point, **next;
19987                 int conflicts;
19988                 int tangles;
19989                 int coalesced;
19990
19991                 if (state->compiler->debug & DEBUG_RANGE_CONFLICTS) {
19992                         FILE *fp = state->errout;
19993                         fprintf(fp, "pass: %d\n", rstate.passes);
19994                         fflush(fp);
19995                 }
19996
19997                 /* Restore ids */
19998                 ids_from_rstate(state, &rstate);
19999
20000                 /* Cleanup the temporary data structures */
20001                 cleanup_rstate(state, &rstate);
20002
20003                 /* Compute the variable lifetimes */
20004                 rstate.blocks = compute_variable_lifetimes(state, &state->bb);
20005
20006                 /* Fix invalid mandatory live range coalesce conflicts */
20007                 conflicts = correct_coalesce_conflicts(state, rstate.blocks);
20008
20009                 /* Fix two simultaneous uses of the same register.
20010                  * In a few pathlogical cases a partial untangle moves
20011                  * the tangle to a part of the graph we won't revisit.
20012                  * So we keep looping until we have no more tangle fixes
20013                  * to apply.
20014                  */
20015                 do {
20016                         tangles = correct_tangles(state, rstate.blocks);
20017                 } while(tangles);
20018
20019                 
20020                 print_blocks(state, "resolve_tangles", state->dbgout);
20021                 verify_consistency(state);
20022                 
20023                 /* Allocate and initialize the live ranges */
20024                 initialize_live_ranges(state, &rstate);
20025
20026                 /* Note currently doing coalescing in a loop appears to 
20027                  * buys me nothing.  The code is left this way in case
20028                  * there is some value in it.  Or if a future bugfix
20029                  * yields some benefit.
20030                  */
20031                 do {
20032                         if (state->compiler->debug & DEBUG_COALESCING) {
20033                                 fprintf(state->errout, "coalescing\n");
20034                         }
20035
20036                         /* Remove any previous live edge calculations */
20037                         cleanup_live_edges(&rstate);
20038
20039                         /* Compute the interference graph */
20040                         walk_variable_lifetimes(
20041                                 state, &state->bb, rstate.blocks, 
20042                                 graph_ins, &rstate);
20043                         
20044                         /* Display the interference graph if desired */
20045                         if (state->compiler->debug & DEBUG_INTERFERENCE) {
20046                                 print_interference_blocks(state, &rstate, state->dbgout, 1);
20047                                 fprintf(state->dbgout, "\nlive variables by instruction\n");
20048                                 walk_variable_lifetimes(
20049                                         state, &state->bb, rstate.blocks, 
20050                                         print_interference_ins, &rstate);
20051                         }
20052                         
20053                         coalesced = coalesce_live_ranges(state, &rstate);
20054
20055                         if (state->compiler->debug & DEBUG_COALESCING) {
20056                                 fprintf(state->errout, "coalesced: %d\n", coalesced);
20057                         }
20058                 } while(coalesced);
20059
20060 #if DEBUG_CONSISTENCY > 1
20061 # if 0
20062                 fprintf(state->errout, "verify_graph_ins...\n");
20063 # endif
20064                 /* Verify the interference graph */
20065                 walk_variable_lifetimes(
20066                         state, &state->bb, rstate.blocks, 
20067                         verify_graph_ins, &rstate);
20068 # if 0
20069                 fprintf(state->errout, "verify_graph_ins done\n");
20070 #endif
20071 #endif
20072                         
20073                 /* Build the groups low and high.  But with the nodes
20074                  * first sorted by degree order.
20075                  */
20076                 rstate.low_tail  = &rstate.low;
20077                 rstate.high_tail = &rstate.high;
20078                 rstate.high = merge_sort_lr(&rstate.lr[1], &rstate.lr[rstate.ranges]);
20079                 if (rstate.high) {
20080                         rstate.high->group_prev = &rstate.high;
20081                 }
20082                 for(point = &rstate.high; *point; point = &(*point)->group_next)
20083                         ;
20084                 rstate.high_tail = point;
20085                 /* Walk through the high list and move everything that needs
20086                  * to be onto low.
20087                  */
20088                 for(point = &rstate.high; *point; point = next) {
20089                         struct live_range *range;
20090                         next = &(*point)->group_next;
20091                         range = *point;
20092                         
20093                         /* If it has a low degree or it already has a color
20094                          * place the node in low.
20095                          */
20096                         if ((range->degree < regc_max_size(state, range->classes)) ||
20097                                 (range->color != REG_UNSET)) {
20098                                 cgdebug_printf(state, "Lo: %5d degree %5d%s\n", 
20099                                         range - rstate.lr, range->degree,
20100                                         (range->color != REG_UNSET) ? " (colored)": "");
20101                                 *range->group_prev = range->group_next;
20102                                 if (range->group_next) {
20103                                         range->group_next->group_prev = range->group_prev;
20104                                 }
20105                                 if (&range->group_next == rstate.high_tail) {
20106                                         rstate.high_tail = range->group_prev;
20107                                 }
20108                                 range->group_prev  = rstate.low_tail;
20109                                 range->group_next  = 0;
20110                                 *rstate.low_tail   = range;
20111                                 rstate.low_tail    = &range->group_next;
20112                                 next = point;
20113                         }
20114                         else {
20115                                 cgdebug_printf(state, "hi: %5d degree %5d%s\n", 
20116                                         range - rstate.lr, range->degree,
20117                                         (range->color != REG_UNSET) ? " (colored)": "");
20118                         }
20119                 }
20120                 /* Color the live_ranges */
20121                 colored = color_graph(state, &rstate);
20122                 rstate.passes++;
20123         } while (!colored);
20124
20125         /* Verify the graph was properly colored */
20126         verify_colors(state, &rstate);
20127
20128         /* Move the colors from the graph to the triples */
20129         color_triples(state, &rstate);
20130
20131         /* Cleanup the temporary data structures */
20132         cleanup_rstate(state, &rstate);
20133
20134         /* Display the new graph */
20135         print_blocks(state, __func__, state->dbgout);
20136 }
20137
20138 /* Sparce Conditional Constant Propogation
20139  * =========================================
20140  */
20141 struct ssa_edge;
20142 struct flow_block;
20143 struct lattice_node {
20144         unsigned old_id;
20145         struct triple *def;
20146         struct ssa_edge *out;
20147         struct flow_block *fblock;
20148         struct triple *val;
20149         /* lattice high   val == def
20150          * lattice const  is_const(val)
20151          * lattice low    other
20152          */
20153 };
20154 struct ssa_edge {
20155         struct lattice_node *src;
20156         struct lattice_node *dst;
20157         struct ssa_edge *work_next;
20158         struct ssa_edge *work_prev;
20159         struct ssa_edge *out_next;
20160 };
20161 struct flow_edge {
20162         struct flow_block *src;
20163         struct flow_block *dst;
20164         struct flow_edge *work_next;
20165         struct flow_edge *work_prev;
20166         struct flow_edge *in_next;
20167         struct flow_edge *out_next;
20168         int executable;
20169 };
20170 #define MAX_FLOW_BLOCK_EDGES 3
20171 struct flow_block {
20172         struct block *block;
20173         struct flow_edge *in;
20174         struct flow_edge *out;
20175         struct flow_edge *edges;
20176 };
20177
20178 struct scc_state {
20179         int ins_count;
20180         struct lattice_node *lattice;
20181         struct ssa_edge     *ssa_edges;
20182         struct flow_block   *flow_blocks;
20183         struct flow_edge    *flow_work_list;
20184         struct ssa_edge     *ssa_work_list;
20185 };
20186
20187
20188 static int is_scc_const(struct compile_state *state, struct triple *ins)
20189 {
20190         return ins && (triple_is_ubranch(state, ins) || is_const(ins));
20191 }
20192
20193 static int is_lattice_hi(struct compile_state *state, struct lattice_node *lnode)
20194 {
20195         return !is_scc_const(state, lnode->val) && (lnode->val == lnode->def);
20196 }
20197
20198 static int is_lattice_const(struct compile_state *state, struct lattice_node *lnode)
20199 {
20200         return is_scc_const(state, lnode->val);
20201 }
20202
20203 static int is_lattice_lo(struct compile_state *state, struct lattice_node *lnode)
20204 {
20205         return (lnode->val != lnode->def) && !is_scc_const(state, lnode->val);
20206 }
20207
20208 static void scc_add_fedge(struct compile_state *state, struct scc_state *scc, 
20209         struct flow_edge *fedge)
20210 {
20211         if (state->compiler->debug & DEBUG_SCC_TRANSFORM2) {
20212                 fprintf(state->errout, "adding fedge: %p (%4d -> %5d)\n",
20213                         fedge,
20214                         fedge->src->block?fedge->src->block->last->id: 0,
20215                         fedge->dst->block?fedge->dst->block->first->id: 0);
20216         }
20217         if ((fedge == scc->flow_work_list) ||
20218                 (fedge->work_next != fedge) ||
20219                 (fedge->work_prev != fedge)) {
20220
20221                 if (state->compiler->debug & DEBUG_SCC_TRANSFORM2) {
20222                         fprintf(state->errout, "dupped fedge: %p\n",
20223                                 fedge);
20224                 }
20225                 return;
20226         }
20227         if (!scc->flow_work_list) {
20228                 scc->flow_work_list = fedge;
20229                 fedge->work_next = fedge->work_prev = fedge;
20230         }
20231         else {
20232                 struct flow_edge *ftail;
20233                 ftail = scc->flow_work_list->work_prev;
20234                 fedge->work_next = ftail->work_next;
20235                 fedge->work_prev = ftail;
20236                 fedge->work_next->work_prev = fedge;
20237                 fedge->work_prev->work_next = fedge;
20238         }
20239 }
20240
20241 static struct flow_edge *scc_next_fedge(
20242         struct compile_state *state, struct scc_state *scc)
20243 {
20244         struct flow_edge *fedge;
20245         fedge = scc->flow_work_list;
20246         if (fedge) {
20247                 fedge->work_next->work_prev = fedge->work_prev;
20248                 fedge->work_prev->work_next = fedge->work_next;
20249                 if (fedge->work_next != fedge) {
20250                         scc->flow_work_list = fedge->work_next;
20251                 } else {
20252                         scc->flow_work_list = 0;
20253                 }
20254                 fedge->work_next = fedge->work_prev = fedge;
20255         }
20256         return fedge;
20257 }
20258
20259 static void scc_add_sedge(struct compile_state *state, struct scc_state *scc,
20260         struct ssa_edge *sedge)
20261 {
20262         if (state->compiler->debug & DEBUG_SCC_TRANSFORM2) {
20263                 fprintf(state->errout, "adding sedge: %5d (%4d -> %5d)\n",
20264                         sedge - scc->ssa_edges,
20265                         sedge->src->def->id,
20266                         sedge->dst->def->id);
20267         }
20268         if ((sedge == scc->ssa_work_list) ||
20269                 (sedge->work_next != sedge) ||
20270                 (sedge->work_prev != sedge)) {
20271
20272                 if (state->compiler->debug & DEBUG_SCC_TRANSFORM2) {
20273                         fprintf(state->errout, "dupped sedge: %5d\n",
20274                                 sedge - scc->ssa_edges);
20275                 }
20276                 return;
20277         }
20278         if (!scc->ssa_work_list) {
20279                 scc->ssa_work_list = sedge;
20280                 sedge->work_next = sedge->work_prev = sedge;
20281         }
20282         else {
20283                 struct ssa_edge *stail;
20284                 stail = scc->ssa_work_list->work_prev;
20285                 sedge->work_next = stail->work_next;
20286                 sedge->work_prev = stail;
20287                 sedge->work_next->work_prev = sedge;
20288                 sedge->work_prev->work_next = sedge;
20289         }
20290 }
20291
20292 static struct ssa_edge *scc_next_sedge(
20293         struct compile_state *state, struct scc_state *scc)
20294 {
20295         struct ssa_edge *sedge;
20296         sedge = scc->ssa_work_list;
20297         if (sedge) {
20298                 sedge->work_next->work_prev = sedge->work_prev;
20299                 sedge->work_prev->work_next = sedge->work_next;
20300                 if (sedge->work_next != sedge) {
20301                         scc->ssa_work_list = sedge->work_next;
20302                 } else {
20303                         scc->ssa_work_list = 0;
20304                 }
20305                 sedge->work_next = sedge->work_prev = sedge;
20306         }
20307         return sedge;
20308 }
20309
20310 static void initialize_scc_state(
20311         struct compile_state *state, struct scc_state *scc)
20312 {
20313         int ins_count, ssa_edge_count;
20314         int ins_index, ssa_edge_index, fblock_index;
20315         struct triple *first, *ins;
20316         struct block *block;
20317         struct flow_block *fblock;
20318
20319         memset(scc, 0, sizeof(*scc));
20320
20321         /* Inialize pass zero find out how much memory we need */
20322         first = state->first;
20323         ins = first;
20324         ins_count = ssa_edge_count = 0;
20325         do {
20326                 struct triple_set *edge;
20327                 ins_count += 1;
20328                 for(edge = ins->use; edge; edge = edge->next) {
20329                         ssa_edge_count++;
20330                 }
20331                 ins = ins->next;
20332         } while(ins != first);
20333         if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
20334                 fprintf(state->errout, "ins_count: %d ssa_edge_count: %d vertex_count: %d\n",
20335                         ins_count, ssa_edge_count, state->bb.last_vertex);
20336         }
20337         scc->ins_count   = ins_count;
20338         scc->lattice     = 
20339                 xcmalloc(sizeof(*scc->lattice)*(ins_count + 1), "lattice");
20340         scc->ssa_edges   = 
20341                 xcmalloc(sizeof(*scc->ssa_edges)*(ssa_edge_count + 1), "ssa_edges");
20342         scc->flow_blocks = 
20343                 xcmalloc(sizeof(*scc->flow_blocks)*(state->bb.last_vertex + 1), 
20344                         "flow_blocks");
20345
20346         /* Initialize pass one collect up the nodes */
20347         fblock = 0;
20348         block = 0;
20349         ins_index = ssa_edge_index = fblock_index = 0;
20350         ins = first;
20351         do {
20352                 if ((ins->op == OP_LABEL) && (block != ins->u.block)) {
20353                         block = ins->u.block;
20354                         if (!block) {
20355                                 internal_error(state, ins, "label without block");
20356                         }
20357                         fblock_index += 1;
20358                         block->vertex = fblock_index;
20359                         fblock = &scc->flow_blocks[fblock_index];
20360                         fblock->block = block;
20361                         fblock->edges = xcmalloc(sizeof(*fblock->edges)*block->edge_count,
20362                                 "flow_edges");
20363                 }
20364                 {
20365                         struct lattice_node *lnode;
20366                         ins_index += 1;
20367                         lnode = &scc->lattice[ins_index];
20368                         lnode->def = ins;
20369                         lnode->out = 0;
20370                         lnode->fblock = fblock;
20371                         lnode->val = ins; /* LATTICE HIGH */
20372                         if (lnode->val->op == OP_UNKNOWNVAL) {
20373                                 lnode->val = 0; /* LATTICE LOW by definition */
20374                         }
20375                         lnode->old_id = ins->id;
20376                         ins->id = ins_index;
20377                 }
20378                 ins = ins->next;
20379         } while(ins != first);
20380         /* Initialize pass two collect up the edges */
20381         block = 0;
20382         fblock = 0;
20383         ins = first;
20384         do {
20385                 {
20386                         struct triple_set *edge;
20387                         struct ssa_edge **stail;
20388                         struct lattice_node *lnode;
20389                         lnode = &scc->lattice[ins->id];
20390                         lnode->out = 0;
20391                         stail = &lnode->out;
20392                         for(edge = ins->use; edge; edge = edge->next) {
20393                                 struct ssa_edge *sedge;
20394                                 ssa_edge_index += 1;
20395                                 sedge = &scc->ssa_edges[ssa_edge_index];
20396                                 *stail = sedge;
20397                                 stail = &sedge->out_next;
20398                                 sedge->src = lnode;
20399                                 sedge->dst = &scc->lattice[edge->member->id];
20400                                 sedge->work_next = sedge->work_prev = sedge;
20401                                 sedge->out_next = 0;
20402                         }
20403                 }
20404                 if ((ins->op == OP_LABEL) && (block != ins->u.block)) {
20405                         struct flow_edge *fedge, **ftail;
20406                         struct block_set *bedge;
20407                         block = ins->u.block;
20408                         fblock = &scc->flow_blocks[block->vertex];
20409                         fblock->in = 0;
20410                         fblock->out = 0;
20411                         ftail = &fblock->out;
20412
20413                         fedge = fblock->edges;
20414                         bedge = block->edges;
20415                         for(; bedge; bedge = bedge->next, fedge++) {
20416                                 fedge->dst = &scc->flow_blocks[bedge->member->vertex];
20417                                 if (fedge->dst->block != bedge->member) {
20418                                         internal_error(state, 0, "block mismatch");
20419                                 }
20420                                 *ftail = fedge;
20421                                 ftail = &fedge->out_next;
20422                                 fedge->out_next = 0;
20423                         }
20424                         for(fedge = fblock->out; fedge; fedge = fedge->out_next) {
20425                                 fedge->src = fblock;
20426                                 fedge->work_next = fedge->work_prev = fedge;
20427                                 fedge->executable = 0;
20428                         }
20429                 }
20430                 ins = ins->next;
20431         } while (ins != first);
20432         block = 0;
20433         fblock = 0;
20434         ins = first;
20435         do {
20436                 if ((ins->op  == OP_LABEL) && (block != ins->u.block)) {
20437                         struct flow_edge **ftail;
20438                         struct block_set *bedge;
20439                         block = ins->u.block;
20440                         fblock = &scc->flow_blocks[block->vertex];
20441                         ftail = &fblock->in;
20442                         for(bedge = block->use; bedge; bedge = bedge->next) {
20443                                 struct block *src_block;
20444                                 struct flow_block *sfblock;
20445                                 struct flow_edge *sfedge;
20446                                 src_block = bedge->member;
20447                                 sfblock = &scc->flow_blocks[src_block->vertex];
20448                                 for(sfedge = sfblock->out; sfedge; sfedge = sfedge->out_next) {
20449                                         if (sfedge->dst == fblock) {
20450                                                 break;
20451                                         }
20452                                 }
20453                                 if (!sfedge) {
20454                                         internal_error(state, 0, "edge mismatch");
20455                                 }
20456                                 *ftail = sfedge;
20457                                 ftail = &sfedge->in_next;
20458                                 sfedge->in_next = 0;
20459                         }
20460                 }
20461                 ins = ins->next;
20462         } while(ins != first);
20463         /* Setup a dummy block 0 as a node above the start node */
20464         {
20465                 struct flow_block *fblock, *dst;
20466                 struct flow_edge *fedge;
20467                 fblock = &scc->flow_blocks[0];
20468                 fblock->block = 0;
20469                 fblock->edges = xcmalloc(sizeof(*fblock->edges)*1, "flow_edges");
20470                 fblock->in = 0;
20471                 fblock->out = fblock->edges;
20472                 dst = &scc->flow_blocks[state->bb.first_block->vertex];
20473                 fedge = fblock->edges;
20474                 fedge->src        = fblock;
20475                 fedge->dst        = dst;
20476                 fedge->work_next  = fedge;
20477                 fedge->work_prev  = fedge;
20478                 fedge->in_next    = fedge->dst->in;
20479                 fedge->out_next   = 0;
20480                 fedge->executable = 0;
20481                 fedge->dst->in = fedge;
20482                 
20483                 /* Initialize the work lists */
20484                 scc->flow_work_list = 0;
20485                 scc->ssa_work_list  = 0;
20486                 scc_add_fedge(state, scc, fedge);
20487         }
20488         if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
20489                 fprintf(state->errout, "ins_index: %d ssa_edge_index: %d fblock_index: %d\n",
20490                         ins_index, ssa_edge_index, fblock_index);
20491         }
20492 }
20493
20494         
20495 static void free_scc_state(
20496         struct compile_state *state, struct scc_state *scc)
20497 {
20498         int i;
20499         for(i = 0; i < state->bb.last_vertex + 1; i++) {
20500                 struct flow_block *fblock;
20501                 fblock = &scc->flow_blocks[i];
20502                 if (fblock->edges) {
20503                         xfree(fblock->edges);
20504                         fblock->edges = 0;
20505                 }
20506         }
20507         xfree(scc->flow_blocks);
20508         xfree(scc->ssa_edges);
20509         xfree(scc->lattice);
20510         
20511 }
20512
20513 static struct lattice_node *triple_to_lattice(
20514         struct compile_state *state, struct scc_state *scc, struct triple *ins)
20515 {
20516         if (ins->id <= 0) {
20517                 internal_error(state, ins, "bad id");
20518         }
20519         return &scc->lattice[ins->id];
20520 }
20521
20522 static struct triple *preserve_lval(
20523         struct compile_state *state, struct lattice_node *lnode)
20524 {
20525         struct triple *old;
20526         /* Preserve the original value */
20527         if (lnode->val) {
20528                 old = dup_triple(state, lnode->val);
20529                 if (lnode->val != lnode->def) {
20530                         xfree(lnode->val);
20531                 }
20532                 lnode->val = 0;
20533         } else {
20534                 old = 0;
20535         }
20536         return old;
20537 }
20538
20539 static int lval_changed(struct compile_state *state, 
20540         struct triple *old, struct lattice_node *lnode)
20541 {
20542         int changed;
20543         /* See if the lattice value has changed */
20544         changed = 1;
20545         if (!old && !lnode->val) {
20546                 changed = 0;
20547         }
20548         if (changed &&
20549                 lnode->val && old &&
20550                 (memcmp(lnode->val->param, old->param,
20551                         TRIPLE_SIZE(lnode->val) * sizeof(lnode->val->param[0])) == 0) &&
20552                 (memcmp(&lnode->val->u, &old->u, sizeof(old->u)) == 0)) {
20553                 changed = 0;
20554         }
20555         if (old) {
20556                 xfree(old);
20557         }
20558         return changed;
20559
20560 }
20561
20562 static void scc_debug_lnode(
20563         struct compile_state *state, struct scc_state *scc,
20564         struct lattice_node *lnode, int changed)
20565 {
20566         if ((state->compiler->debug & DEBUG_SCC_TRANSFORM2) && lnode->val) {
20567                 display_triple_changes(state->errout, lnode->val, lnode->def);
20568         }
20569         if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
20570                 FILE *fp = state->errout;
20571                 struct triple *val, **expr;
20572                 val = lnode->val? lnode->val : lnode->def;
20573                 fprintf(fp, "%p %s %3d %10s (",
20574                         lnode->def, 
20575                         ((lnode->def->op == OP_PHI)? "phi: ": "expr:"),
20576                         lnode->def->id,
20577                         tops(lnode->def->op));
20578                 expr = triple_rhs(state, lnode->def, 0);
20579                 for(;expr;expr = triple_rhs(state, lnode->def, expr)) {
20580                         if (*expr) {
20581                                 fprintf(fp, " %d", (*expr)->id);
20582                         }
20583                 }
20584                 if (val->op == OP_INTCONST) {
20585                         fprintf(fp, " <0x%08lx>", (unsigned long)(val->u.cval));
20586                 }
20587                 fprintf(fp, " ) -> %s %s\n",
20588                         (is_lattice_hi(state, lnode)? "hi":
20589                                 is_lattice_const(state, lnode)? "const" : "lo"),
20590                         changed? "changed" : ""
20591                         );
20592         }
20593 }
20594
20595 static int compute_lnode_val(struct compile_state *state, struct scc_state *scc,
20596         struct lattice_node *lnode)
20597 {
20598         int changed;
20599         struct triple *old, *scratch;
20600         struct triple **dexpr, **vexpr;
20601         int count, i;
20602         
20603         /* Store the original value */
20604         old = preserve_lval(state, lnode);
20605
20606         /* Reinitialize the value */
20607         lnode->val = scratch = dup_triple(state, lnode->def);
20608         scratch->id = lnode->old_id;
20609         scratch->next     = scratch;
20610         scratch->prev     = scratch;
20611         scratch->use      = 0;
20612
20613         count = TRIPLE_SIZE(scratch);
20614         for(i = 0; i < count; i++) {
20615                 dexpr = &lnode->def->param[i];
20616                 vexpr = &scratch->param[i];
20617                 *vexpr = *dexpr;
20618                 if (((i < TRIPLE_MISC_OFF(scratch)) ||
20619                         (i >= TRIPLE_TARG_OFF(scratch))) &&
20620                         *dexpr) {
20621                         struct lattice_node *tmp;
20622                         tmp = triple_to_lattice(state, scc, *dexpr);
20623                         *vexpr = (tmp->val)? tmp->val : tmp->def;
20624                 }
20625         }
20626         if (triple_is_branch(state, scratch)) {
20627                 scratch->next = lnode->def->next;
20628         }
20629         /* Recompute the value */
20630 #warning "FIXME see if simplify does anything bad"
20631         /* So far it looks like only the strength reduction
20632          * optimization are things I need to worry about.
20633          */
20634         simplify(state, scratch);
20635         /* Cleanup my value */
20636         if (scratch->use) {
20637                 internal_error(state, lnode->def, "scratch used?");
20638         }
20639         if ((scratch->prev != scratch) ||
20640                 ((scratch->next != scratch) &&
20641                         (!triple_is_branch(state, lnode->def) ||
20642                                 (scratch->next != lnode->def->next)))) {
20643                 internal_error(state, lnode->def, "scratch in list?");
20644         }
20645         /* undo any uses... */
20646         count = TRIPLE_SIZE(scratch);
20647         for(i = 0; i < count; i++) {
20648                 vexpr = &scratch->param[i];
20649                 if (*vexpr) {
20650                         unuse_triple(*vexpr, scratch);
20651                 }
20652         }
20653         if (lnode->val->op == OP_UNKNOWNVAL) {
20654                 lnode->val = 0; /* Lattice low by definition */
20655         }
20656         /* Find the case when I am lattice high */
20657         if (lnode->val && 
20658                 (lnode->val->op == lnode->def->op) &&
20659                 (memcmp(lnode->val->param, lnode->def->param, 
20660                         count * sizeof(lnode->val->param[0])) == 0) &&
20661                 (memcmp(&lnode->val->u, &lnode->def->u, sizeof(lnode->def->u)) == 0)) {
20662                 lnode->val = lnode->def;
20663         }
20664         /* Only allow lattice high when all of my inputs
20665          * are also lattice high.  Occassionally I can
20666          * have constants with a lattice low input, so
20667          * I do not need to check that case.
20668          */
20669         if (is_lattice_hi(state, lnode)) {
20670                 struct lattice_node *tmp;
20671                 int rhs;
20672                 rhs = lnode->val->rhs;
20673                 for(i = 0; i < rhs; i++) {
20674                         tmp = triple_to_lattice(state, scc, RHS(lnode->val, i));
20675                         if (!is_lattice_hi(state, tmp)) {
20676                                 lnode->val = 0;
20677                                 break;
20678                         }
20679                 }
20680         }
20681         /* Find the cases that are always lattice lo */
20682         if (lnode->val && 
20683                 triple_is_def(state, lnode->val) &&
20684                 !triple_is_pure(state, lnode->val, lnode->old_id)) {
20685                 lnode->val = 0;
20686         }
20687         /* See if the lattice value has changed */
20688         changed = lval_changed(state, old, lnode);
20689         /* See if this value should not change */
20690         if ((lnode->val != lnode->def) && 
20691                 ((      !triple_is_def(state, lnode->def)  &&
20692                         !triple_is_cbranch(state, lnode->def)) ||
20693                         (lnode->def->op == OP_PIECE))) {
20694 #warning "FIXME constant propogate through expressions with multiple left hand sides"
20695                 if (changed) {
20696                         internal_warning(state, lnode->def, "non def changes value?");
20697                 }
20698                 lnode->val = 0;
20699         }
20700
20701         /* See if we need to free the scratch value */
20702         if (lnode->val != scratch) {
20703                 xfree(scratch);
20704         }
20705         
20706         return changed;
20707 }
20708
20709
20710 static void scc_visit_cbranch(struct compile_state *state, struct scc_state *scc,
20711         struct lattice_node *lnode)
20712 {
20713         struct lattice_node *cond;
20714         struct flow_edge *left, *right;
20715         int changed;
20716
20717         /* Update the branch value */
20718         changed = compute_lnode_val(state, scc, lnode);
20719         scc_debug_lnode(state, scc, lnode, changed);
20720
20721         /* This only applies to conditional branches */
20722         if (!triple_is_cbranch(state, lnode->def)) {
20723                 internal_error(state, lnode->def, "not a conditional branch");
20724         }
20725
20726         if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
20727                 struct flow_edge *fedge;
20728                 FILE *fp = state->errout;
20729                 fprintf(fp, "%s: %d (",
20730                         tops(lnode->def->op),
20731                         lnode->def->id);
20732                 
20733                 for(fedge = lnode->fblock->out; fedge; fedge = fedge->out_next) {
20734                         fprintf(fp, " %d", fedge->dst->block->vertex);
20735                 }
20736                 fprintf(fp, " )");
20737                 if (lnode->def->rhs > 0) {
20738                         fprintf(fp, " <- %d",
20739                                 RHS(lnode->def, 0)->id);
20740                 }
20741                 fprintf(fp, "\n");
20742         }
20743         cond = triple_to_lattice(state, scc, RHS(lnode->def,0));
20744         for(left = cond->fblock->out; left; left = left->out_next) {
20745                 if (left->dst->block->first == lnode->def->next) {
20746                         break;
20747                 }
20748         }
20749         if (!left) {
20750                 internal_error(state, lnode->def, "Cannot find left branch edge");
20751         }
20752         for(right = cond->fblock->out; right; right = right->out_next) {
20753                 if (right->dst->block->first == TARG(lnode->def, 0)) {
20754                         break;
20755                 }
20756         }
20757         if (!right) {
20758                 internal_error(state, lnode->def, "Cannot find right branch edge");
20759         }
20760         /* I should only come here if the controlling expressions value
20761          * has changed, which means it must be either a constant or lo.
20762          */
20763         if (is_lattice_hi(state, cond)) {
20764                 internal_error(state, cond->def, "condition high?");
20765                 return;
20766         }
20767         if (is_lattice_lo(state, cond)) {
20768                 scc_add_fedge(state, scc, left);
20769                 scc_add_fedge(state, scc, right);
20770         }
20771         else if (cond->val->u.cval) {
20772                 scc_add_fedge(state, scc, right);
20773         } else {
20774                 scc_add_fedge(state, scc, left);
20775         }
20776
20777 }
20778
20779
20780 static void scc_add_sedge_dst(struct compile_state *state, 
20781         struct scc_state *scc, struct ssa_edge *sedge)
20782 {
20783         if (triple_is_cbranch(state, sedge->dst->def)) {
20784                 scc_visit_cbranch(state, scc, sedge->dst);
20785         }
20786         else if (triple_is_def(state, sedge->dst->def)) {
20787                 scc_add_sedge(state, scc, sedge);
20788         }
20789 }
20790
20791 static void scc_visit_phi(struct compile_state *state, struct scc_state *scc, 
20792         struct lattice_node *lnode)
20793 {
20794         struct lattice_node *tmp;
20795         struct triple **slot, *old;
20796         struct flow_edge *fedge;
20797         int changed;
20798         int index;
20799         if (lnode->def->op != OP_PHI) {
20800                 internal_error(state, lnode->def, "not phi");
20801         }
20802         /* Store the original value */
20803         old = preserve_lval(state, lnode);
20804
20805         /* default to lattice high */
20806         lnode->val = lnode->def;
20807         slot = &RHS(lnode->def, 0);
20808         index = 0;
20809         for(fedge = lnode->fblock->in; fedge; index++, fedge = fedge->in_next) {
20810                 if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
20811                         fprintf(state->errout, "Examining edge: %d vertex: %d executable: %d\n", 
20812                                 index,
20813                                 fedge->dst->block->vertex,
20814                                 fedge->executable
20815                                 );
20816                 }
20817                 if (!fedge->executable) {
20818                         continue;
20819                 }
20820                 if (!slot[index]) {
20821                         internal_error(state, lnode->def, "no phi value");
20822                 }
20823                 tmp = triple_to_lattice(state, scc, slot[index]);
20824                 /* meet(X, lattice low) = lattice low */
20825                 if (is_lattice_lo(state, tmp)) {
20826                         lnode->val = 0;
20827                 }
20828                 /* meet(X, lattice high) = X */
20829                 else if (is_lattice_hi(state, tmp)) {
20830                         lnode->val = lnode->val;
20831                 }
20832                 /* meet(lattice high, X) = X */
20833                 else if (is_lattice_hi(state, lnode)) {
20834                         lnode->val = dup_triple(state, tmp->val);
20835                         /* Only change the type if necessary */
20836                         if (!is_subset_type(lnode->def->type, tmp->val->type)) {
20837                                 lnode->val->type = lnode->def->type;
20838                         }
20839                 }
20840                 /* meet(const, const) = const or lattice low */
20841                 else if (!constants_equal(state, lnode->val, tmp->val)) {
20842                         lnode->val = 0;
20843                 }
20844
20845                 /* meet(lattice low, X) = lattice low */
20846                 if (is_lattice_lo(state, lnode)) {
20847                         lnode->val = 0;
20848                         break;
20849                 }
20850         }
20851         changed = lval_changed(state, old, lnode);
20852         scc_debug_lnode(state, scc, lnode, changed);
20853
20854         /* If the lattice value has changed update the work lists. */
20855         if (changed) {
20856                 struct ssa_edge *sedge;
20857                 for(sedge = lnode->out; sedge; sedge = sedge->out_next) {
20858                         scc_add_sedge_dst(state, scc, sedge);
20859                 }
20860         }
20861 }
20862
20863
20864 static void scc_visit_expr(struct compile_state *state, struct scc_state *scc,
20865         struct lattice_node *lnode)
20866 {
20867         int changed;
20868
20869         if (!triple_is_def(state, lnode->def)) {
20870                 internal_warning(state, lnode->def, "not visiting an expression?");
20871         }
20872         changed = compute_lnode_val(state, scc, lnode);
20873         scc_debug_lnode(state, scc, lnode, changed);
20874
20875         if (changed) {
20876                 struct ssa_edge *sedge;
20877                 for(sedge = lnode->out; sedge; sedge = sedge->out_next) {
20878                         scc_add_sedge_dst(state, scc, sedge);
20879                 }
20880         }
20881 }
20882
20883 static void scc_writeback_values(
20884         struct compile_state *state, struct scc_state *scc)
20885 {
20886         struct triple *first, *ins;
20887         first = state->first;
20888         ins = first;
20889         do {
20890                 struct lattice_node *lnode;
20891                 lnode = triple_to_lattice(state, scc, ins);
20892                 if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
20893                         if (is_lattice_hi(state, lnode) &&
20894                                 (lnode->val->op != OP_NOOP))
20895                         {
20896                                 struct flow_edge *fedge;
20897                                 int executable;
20898                                 executable = 0;
20899                                 for(fedge = lnode->fblock->in; 
20900                                     !executable && fedge; fedge = fedge->in_next) {
20901                                         executable |= fedge->executable;
20902                                 }
20903                                 if (executable) {
20904                                         internal_warning(state, lnode->def,
20905                                                 "lattice node %d %s->%s still high?",
20906                                                 ins->id, 
20907                                                 tops(lnode->def->op),
20908                                                 tops(lnode->val->op));
20909                                 }
20910                         }
20911                 }
20912
20913                 /* Restore id */
20914                 ins->id = lnode->old_id;
20915                 if (lnode->val && (lnode->val != ins)) {
20916                         /* See if it something I know how to write back */
20917                         switch(lnode->val->op) {
20918                         case OP_INTCONST:
20919                                 mkconst(state, ins, lnode->val->u.cval);
20920                                 break;
20921                         case OP_ADDRCONST:
20922                                 mkaddr_const(state, ins, 
20923                                         MISC(lnode->val, 0), lnode->val->u.cval);
20924                                 break;
20925                         default:
20926                                 /* By default don't copy the changes,
20927                                  * recompute them in place instead.
20928                                  */
20929                                 simplify(state, ins);
20930                                 break;
20931                         }
20932                         if (is_const(lnode->val) &&
20933                                 !constants_equal(state, lnode->val, ins)) {
20934                                 internal_error(state, 0, "constants not equal");
20935                         }
20936                         /* Free the lattice nodes */
20937                         xfree(lnode->val);
20938                         lnode->val = 0;
20939                 }
20940                 ins = ins->next;
20941         } while(ins != first);
20942 }
20943
20944 static void scc_transform(struct compile_state *state)
20945 {
20946         struct scc_state scc;
20947         if (!(state->compiler->flags & COMPILER_SCC_TRANSFORM)) {
20948                 return;
20949         }
20950
20951         initialize_scc_state(state, &scc);
20952
20953         while(scc.flow_work_list || scc.ssa_work_list) {
20954                 struct flow_edge *fedge;
20955                 struct ssa_edge *sedge;
20956                 struct flow_edge *fptr;
20957                 while((fedge = scc_next_fedge(state, &scc))) {
20958                         struct block *block;
20959                         struct triple *ptr;
20960                         struct flow_block *fblock;
20961                         int reps;
20962                         int done;
20963                         if (fedge->executable) {
20964                                 continue;
20965                         }
20966                         if (!fedge->dst) {
20967                                 internal_error(state, 0, "fedge without dst");
20968                         }
20969                         if (!fedge->src) {
20970                                 internal_error(state, 0, "fedge without src");
20971                         }
20972                         fedge->executable = 1;
20973                         fblock = fedge->dst;
20974                         block = fblock->block;
20975                         reps = 0;
20976                         for(fptr = fblock->in; fptr; fptr = fptr->in_next) {
20977                                 if (fptr->executable) {
20978                                         reps++;
20979                                 }
20980                         }
20981                         
20982                         if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
20983                                 fprintf(state->errout, "vertex: %d reps: %d\n", 
20984                                         block->vertex, reps);
20985                         }
20986
20987                         done = 0;
20988                         for(ptr = block->first; !done; ptr = ptr->next) {
20989                                 struct lattice_node *lnode;
20990                                 done = (ptr == block->last);
20991                                 lnode = &scc.lattice[ptr->id];
20992                                 if (ptr->op == OP_PHI) {
20993                                         scc_visit_phi(state, &scc, lnode);
20994                                 }
20995                                 else if ((reps == 1) && triple_is_def(state, ptr))
20996                                 {
20997                                         scc_visit_expr(state, &scc, lnode);
20998                                 }
20999                         }
21000                         /* Add unconditional branch edges */
21001                         if (!triple_is_cbranch(state, fblock->block->last)) {
21002                                 struct flow_edge *out;
21003                                 for(out = fblock->out; out; out = out->out_next) {
21004                                         scc_add_fedge(state, &scc, out);
21005                                 }
21006                         }
21007                 }
21008                 while((sedge = scc_next_sedge(state, &scc))) {
21009                         struct lattice_node *lnode;
21010                         struct flow_block *fblock;
21011                         lnode = sedge->dst;
21012                         fblock = lnode->fblock;
21013
21014                         if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
21015                                 fprintf(state->errout, "sedge: %5d (%5d -> %5d)\n",
21016                                         sedge - scc.ssa_edges,
21017                                         sedge->src->def->id,
21018                                         sedge->dst->def->id);
21019                         }
21020
21021                         if (lnode->def->op == OP_PHI) {
21022                                 scc_visit_phi(state, &scc, lnode);
21023                         }
21024                         else {
21025                                 for(fptr = fblock->in; fptr; fptr = fptr->in_next) {
21026                                         if (fptr->executable) {
21027                                                 break;
21028                                         }
21029                                 }
21030                                 if (fptr) {
21031                                         scc_visit_expr(state, &scc, lnode);
21032                                 }
21033                         }
21034                 }
21035         }
21036         
21037         scc_writeback_values(state, &scc);
21038         free_scc_state(state, &scc);
21039         rebuild_ssa_form(state);
21040         
21041         print_blocks(state, __func__, state->dbgout);
21042 }
21043
21044
21045 static void transform_to_arch_instructions(struct compile_state *state)
21046 {
21047         struct triple *ins, *first;
21048         first = state->first;
21049         ins = first;
21050         do {
21051                 ins = transform_to_arch_instruction(state, ins);
21052         } while(ins != first);
21053         
21054         print_blocks(state, __func__, state->dbgout);
21055 }
21056
21057 #if DEBUG_CONSISTENCY
21058 static void verify_uses(struct compile_state *state)
21059 {
21060         struct triple *first, *ins;
21061         struct triple_set *set;
21062         first = state->first;
21063         ins = first;
21064         do {
21065                 struct triple **expr;
21066                 expr = triple_rhs(state, ins, 0);
21067                 for(; expr; expr = triple_rhs(state, ins, expr)) {
21068                         struct triple *rhs;
21069                         rhs = *expr;
21070                         for(set = rhs?rhs->use:0; set; set = set->next) {
21071                                 if (set->member == ins) {
21072                                         break;
21073                                 }
21074                         }
21075                         if (!set) {
21076                                 internal_error(state, ins, "rhs not used");
21077                         }
21078                 }
21079                 expr = triple_lhs(state, ins, 0);
21080                 for(; expr; expr = triple_lhs(state, ins, expr)) {
21081                         struct triple *lhs;
21082                         lhs = *expr;
21083                         for(set =  lhs?lhs->use:0; set; set = set->next) {
21084                                 if (set->member == ins) {
21085                                         break;
21086                                 }
21087                         }
21088                         if (!set) {
21089                                 internal_error(state, ins, "lhs not used");
21090                         }
21091                 }
21092                 expr = triple_misc(state, ins, 0);
21093                 if (ins->op != OP_PHI) {
21094                         for(; expr; expr = triple_targ(state, ins, expr)) {
21095                                 struct triple *misc;
21096                                 misc = *expr;
21097                                 for(set = misc?misc->use:0; set; set = set->next) {
21098                                         if (set->member == ins) {
21099                                                 break;
21100                                         }
21101                                 }
21102                                 if (!set) {
21103                                         internal_error(state, ins, "misc not used");
21104                                 }
21105                         }
21106                 }
21107                 if (!triple_is_ret(state, ins)) {
21108                         expr = triple_targ(state, ins, 0);
21109                         for(; expr; expr = triple_targ(state, ins, expr)) {
21110                                 struct triple *targ;
21111                                 targ = *expr;
21112                                 for(set = targ?targ->use:0; set; set = set->next) {
21113                                         if (set->member == ins) {
21114                                                 break;
21115                                         }
21116                                 }
21117                                 if (!set) {
21118                                         internal_error(state, ins, "targ not used");
21119                                 }
21120                         }
21121                 }
21122                 ins = ins->next;
21123         } while(ins != first);
21124         
21125 }
21126 static void verify_blocks_present(struct compile_state *state)
21127 {
21128         struct triple *first, *ins;
21129         if (!state->bb.first_block) {
21130                 return;
21131         }
21132         first = state->first;
21133         ins = first;
21134         do {
21135                 valid_ins(state, ins);
21136                 if (triple_stores_block(state, ins)) {
21137                         if (!ins->u.block) {
21138                                 internal_error(state, ins, 
21139                                         "%p not in a block?", ins);
21140                         }
21141                 }
21142                 ins = ins->next;
21143         } while(ins != first);
21144         
21145         
21146 }
21147
21148 static int edge_present(struct compile_state *state, struct block *block, struct triple *edge)
21149 {
21150         struct block_set *bedge;
21151         struct block *targ;
21152         targ = block_of_triple(state, edge);
21153         for(bedge = block->edges; bedge; bedge = bedge->next) {
21154                 if (bedge->member == targ) {
21155                         return 1;
21156                 }
21157         }
21158         return 0;
21159 }
21160
21161 static void verify_blocks(struct compile_state *state)
21162 {
21163         struct triple *ins;
21164         struct block *block;
21165         int blocks;
21166         block = state->bb.first_block;
21167         if (!block) {
21168                 return;
21169         }
21170         blocks = 0;
21171         do {
21172                 int users;
21173                 struct block_set *user, *edge;
21174                 blocks++;
21175                 for(ins = block->first; ins != block->last->next; ins = ins->next) {
21176                         if (triple_stores_block(state, ins) && (ins->u.block != block)) {
21177                                 internal_error(state, ins, "inconsitent block specified");
21178                         }
21179                         valid_ins(state, ins);
21180                 }
21181                 users = 0;
21182                 for(user = block->use; user; user = user->next) {
21183                         users++;
21184                         if (!user->member->first) {
21185                                 internal_error(state, block->first, "user is empty");
21186                         }
21187                         if ((block == state->bb.last_block) &&
21188                                 (user->member == state->bb.first_block)) {
21189                                 continue;
21190                         }
21191                         for(edge = user->member->edges; edge; edge = edge->next) {
21192                                 if (edge->member == block) {
21193                                         break;
21194                                 }
21195                         }
21196                         if (!edge) {
21197                                 internal_error(state, user->member->first,
21198                                         "user does not use block");
21199                         }
21200                 }
21201                 if (triple_is_branch(state, block->last)) {
21202                         struct triple **expr;
21203                         expr = triple_edge_targ(state, block->last, 0);
21204                         for(;expr; expr = triple_edge_targ(state, block->last, expr)) {
21205                                 if (*expr && !edge_present(state, block, *expr)) {
21206                                         internal_error(state, block->last, "no edge to targ");
21207                                 }
21208                         }
21209                 }
21210                 if (!triple_is_ubranch(state, block->last) &&
21211                         (block != state->bb.last_block) &&
21212                         !edge_present(state, block, block->last->next)) {
21213                         internal_error(state, block->last, "no edge to block->last->next");
21214                 }
21215                 for(edge = block->edges; edge; edge = edge->next) {
21216                         for(user = edge->member->use; user; user = user->next) {
21217                                 if (user->member == block) {
21218                                         break;
21219                                 }
21220                         }
21221                         if (!user || user->member != block) {
21222                                 internal_error(state, block->first,
21223                                         "block does not use edge");
21224                         }
21225                         if (!edge->member->first) {
21226                                 internal_error(state, block->first, "edge block is empty");
21227                         }
21228                 }
21229                 if (block->users != users) {
21230                         internal_error(state, block->first, 
21231                                 "computed users %d != stored users %d",
21232                                 users, block->users);
21233                 }
21234                 if (!triple_stores_block(state, block->last->next)) {
21235                         internal_error(state, block->last->next, 
21236                                 "cannot find next block");
21237                 }
21238                 block = block->last->next->u.block;
21239                 if (!block) {
21240                         internal_error(state, block->last->next,
21241                                 "bad next block");
21242                 }
21243         } while(block != state->bb.first_block);
21244         if (blocks != state->bb.last_vertex) {
21245                 internal_error(state, 0, "computed blocks: %d != stored blocks %d",
21246                         blocks, state->bb.last_vertex);
21247         }
21248 }
21249
21250 static void verify_domination(struct compile_state *state)
21251 {
21252         struct triple *first, *ins;
21253         struct triple_set *set;
21254         if (!state->bb.first_block) {
21255                 return;
21256         }
21257         
21258         first = state->first;
21259         ins = first;
21260         do {
21261                 for(set = ins->use; set; set = set->next) {
21262                         struct triple **slot;
21263                         struct triple *use_point;
21264                         int i, zrhs;
21265                         use_point = 0;
21266                         zrhs = set->member->rhs;
21267                         slot = &RHS(set->member, 0);
21268                         /* See if the use is on the right hand side */
21269                         for(i = 0; i < zrhs; i++) {
21270                                 if (slot[i] == ins) {
21271                                         break;
21272                                 }
21273                         }
21274                         if (i < zrhs) {
21275                                 use_point = set->member;
21276                                 if (set->member->op == OP_PHI) {
21277                                         struct block_set *bset;
21278                                         int edge;
21279                                         bset = set->member->u.block->use;
21280                                         for(edge = 0; bset && (edge < i); edge++) {
21281                                                 bset = bset->next;
21282                                         }
21283                                         if (!bset) {
21284                                                 internal_error(state, set->member, 
21285                                                         "no edge for phi rhs %d", i);
21286                                         }
21287                                         use_point = bset->member->last;
21288                                 }
21289                         }
21290                         if (use_point &&
21291                                 !tdominates(state, ins, use_point)) {
21292                                 if (is_const(ins)) {
21293                                         internal_warning(state, ins, 
21294                                         "non dominated rhs use point %p?", use_point);
21295                                 }
21296                                 else {
21297                                         internal_error(state, ins, 
21298                                                 "non dominated rhs use point %p?", use_point);
21299                                 }
21300                         }
21301                 }
21302                 ins = ins->next;
21303         } while(ins != first);
21304 }
21305
21306 static void verify_rhs(struct compile_state *state)
21307 {
21308         struct triple *first, *ins;
21309         first = state->first;
21310         ins = first;
21311         do {
21312                 struct triple **slot;
21313                 int zrhs, i;
21314                 zrhs = ins->rhs;
21315                 slot = &RHS(ins, 0);
21316                 for(i = 0; i < zrhs; i++) {
21317                         if (slot[i] == 0) {
21318                                 internal_error(state, ins,
21319                                         "missing rhs %d on %s",
21320                                         i, tops(ins->op));
21321                         }
21322                         if ((ins->op != OP_PHI) && (slot[i] == ins)) {
21323                                 internal_error(state, ins,
21324                                         "ins == rhs[%d] on %s",
21325                                         i, tops(ins->op));
21326                         }
21327                 }
21328                 ins = ins->next;
21329         } while(ins != first);
21330 }
21331
21332 static void verify_piece(struct compile_state *state)
21333 {
21334         struct triple *first, *ins;
21335         first = state->first;
21336         ins = first;
21337         do {
21338                 struct triple *ptr;
21339                 int lhs, i;
21340                 lhs = ins->lhs;
21341                 for(ptr = ins->next, i = 0; i < lhs; i++, ptr = ptr->next) {
21342                         if (ptr != LHS(ins, i)) {
21343                                 internal_error(state, ins, "malformed lhs on %s",
21344                                         tops(ins->op));
21345                         }
21346                         if (ptr->op != OP_PIECE) {
21347                                 internal_error(state, ins, "bad lhs op %s at %d on %s",
21348                                         tops(ptr->op), i, tops(ins->op));
21349                         }
21350                         if (ptr->u.cval != i) {
21351                                 internal_error(state, ins, "bad u.cval of %d %d expected",
21352                                         ptr->u.cval, i);
21353                         }
21354                 }
21355                 ins = ins->next;
21356         } while(ins != first);
21357 }
21358
21359 static void verify_ins_colors(struct compile_state *state)
21360 {
21361         struct triple *first, *ins;
21362         
21363         first = state->first;
21364         ins = first;
21365         do {
21366                 ins = ins->next;
21367         } while(ins != first);
21368 }
21369
21370 static void verify_unknown(struct compile_state *state)
21371 {
21372         struct triple *first, *ins;
21373         if (    (unknown_triple.next != &unknown_triple) ||
21374                 (unknown_triple.prev != &unknown_triple) ||
21375 #if 0
21376                 (unknown_triple.use != 0) ||
21377 #endif
21378                 (unknown_triple.op != OP_UNKNOWNVAL) ||
21379                 (unknown_triple.lhs != 0) ||
21380                 (unknown_triple.rhs != 0) ||
21381                 (unknown_triple.misc != 0) ||
21382                 (unknown_triple.targ != 0) ||
21383                 (unknown_triple.template_id != 0) ||
21384                 (unknown_triple.id != -1) ||
21385                 (unknown_triple.type != &unknown_type) ||
21386                 (unknown_triple.occurance != &dummy_occurance) ||
21387                 (unknown_triple.param[0] != 0) ||
21388                 (unknown_triple.param[1] != 0)) {
21389                 internal_error(state, &unknown_triple, "unknown_triple corrupted!");
21390         }
21391         if (    (dummy_occurance.count != 2) ||
21392                 (strcmp(dummy_occurance.filename, __FILE__) != 0) ||
21393                 (strcmp(dummy_occurance.function, "") != 0) ||
21394                 (dummy_occurance.col != 0) ||
21395                 (dummy_occurance.parent != 0)) {
21396                 internal_error(state, &unknown_triple, "dummy_occurance corrupted!");
21397         }
21398         if (    (unknown_type.type != TYPE_UNKNOWN)) {
21399                 internal_error(state, &unknown_triple, "unknown_type corrupted!");
21400         }
21401         first = state->first;
21402         ins = first;
21403         do {
21404                 int params, i;
21405                 if (ins == &unknown_triple) {
21406                         internal_error(state, ins, "unknown triple in list");
21407                 }
21408                 params = TRIPLE_SIZE(ins);
21409                 for(i = 0; i < params; i++) {
21410                         if (ins->param[i] == &unknown_triple) {
21411                                 internal_error(state, ins, "unknown triple used!");
21412                         }
21413                 }
21414                 ins = ins->next;
21415         } while(ins != first);
21416 }
21417
21418 static void verify_types(struct compile_state *state)
21419 {
21420         struct triple *first, *ins;
21421         first = state->first;
21422         ins = first;
21423         do {
21424                 struct type *invalid;
21425                 invalid = invalid_type(state, ins->type);
21426                 if (invalid) {
21427                         FILE *fp = state->errout;
21428                         fprintf(fp, "type: ");
21429                         name_of(fp, ins->type);
21430                         fprintf(fp, "\n");
21431                         fprintf(fp, "invalid type: ");
21432                         name_of(fp, invalid);
21433                         fprintf(fp, "\n");
21434                         internal_error(state, ins, "invalid ins type");
21435                 }
21436         } while(ins != first);
21437 }
21438
21439 static void verify_copy(struct compile_state *state)
21440 {
21441         struct triple *first, *ins, *next;
21442         first = state->first;
21443         next = ins = first;
21444         do {
21445                 ins = next;
21446                 next = ins->next;
21447                 if (ins->op != OP_COPY) {
21448                         continue;
21449                 }
21450                 if (!equiv_types(ins->type, RHS(ins, 0)->type)) {
21451                         FILE *fp = state->errout;
21452                         fprintf(fp, "src type: ");
21453                         name_of(fp, RHS(ins, 0)->type);
21454                         fprintf(fp, "\n");
21455                         fprintf(fp, "dst type: ");
21456                         name_of(fp, ins->type);
21457                         fprintf(fp, "\n");
21458                         internal_error(state, ins, "type mismatch in copy");
21459                 }
21460         } while(next != first);
21461 }
21462
21463 static void verify_consistency(struct compile_state *state)
21464 {
21465         verify_unknown(state);
21466         verify_uses(state);
21467         verify_blocks_present(state);
21468         verify_blocks(state);
21469         verify_domination(state);
21470         verify_rhs(state);
21471         verify_piece(state);
21472         verify_ins_colors(state);
21473         verify_types(state);
21474         verify_copy(state);
21475         if (state->compiler->debug & DEBUG_VERIFICATION) {
21476                 fprintf(state->dbgout, "consistency verified\n");
21477         }
21478 }
21479 #else 
21480 static void verify_consistency(struct compile_state *state) {}
21481 #endif /* DEBUG_CONSISTENCY */
21482
21483 static void optimize(struct compile_state *state)
21484 {
21485         /* Join all of the functions into one giant function */
21486         join_functions(state);
21487
21488         /* Dump what the instruction graph intially looks like */
21489         print_triples(state);
21490
21491         /* Replace structures with simpler data types */
21492         decompose_compound_types(state);
21493         print_triples(state);
21494
21495         verify_consistency(state);
21496         /* Analyze the intermediate code */
21497         state->bb.first = state->first;
21498         analyze_basic_blocks(state, &state->bb);
21499
21500         /* Transform the code to ssa form. */
21501         /*
21502          * The transformation to ssa form puts a phi function
21503          * on each of edge of a dominance frontier where that
21504          * phi function might be needed.  At -O2 if we don't
21505          * eleminate the excess phi functions we can get an
21506          * exponential code size growth.  So I kill the extra
21507          * phi functions early and I kill them often.
21508          */
21509         transform_to_ssa_form(state);
21510         verify_consistency(state);
21511
21512         /* Remove dead code */
21513         eliminate_inefectual_code(state);
21514         verify_consistency(state);
21515
21516         /* Do strength reduction and simple constant optimizations */
21517         simplify_all(state);
21518         verify_consistency(state);
21519         /* Propogate constants throughout the code */
21520         scc_transform(state);
21521         verify_consistency(state);
21522 #warning "WISHLIST implement single use constants (least possible register pressure)"
21523 #warning "WISHLIST implement induction variable elimination"
21524         /* Select architecture instructions and an initial partial
21525          * coloring based on architecture constraints.
21526          */
21527         transform_to_arch_instructions(state);
21528         verify_consistency(state);
21529
21530         /* Remove dead code */
21531         eliminate_inefectual_code(state);
21532         verify_consistency(state);
21533
21534         /* Color all of the variables to see if they will fit in registers */
21535         insert_copies_to_phi(state);
21536         verify_consistency(state);
21537
21538         insert_mandatory_copies(state);
21539         verify_consistency(state);
21540
21541         allocate_registers(state);
21542         verify_consistency(state);
21543
21544         /* Remove the optimization information.
21545          * This is more to check for memory consistency than to free memory.
21546          */
21547         free_basic_blocks(state, &state->bb);
21548 }
21549
21550 static void print_op_asm(struct compile_state *state,
21551         struct triple *ins, FILE *fp)
21552 {
21553         struct asm_info *info;
21554         const char *ptr;
21555         unsigned lhs, rhs, i;
21556         info = ins->u.ainfo;
21557         lhs = ins->lhs;
21558         rhs = ins->rhs;
21559         /* Don't count the clobbers in lhs */
21560         for(i = 0; i < lhs; i++) {
21561                 if (LHS(ins, i)->type == &void_type) {
21562                         break;
21563                 }
21564         }
21565         lhs = i;
21566         fprintf(fp, "#ASM\n");
21567         fputc('\t', fp);
21568         for(ptr = info->str; *ptr; ptr++) {
21569                 char *next;
21570                 unsigned long param;
21571                 struct triple *piece;
21572                 if (*ptr != '%') {
21573                         fputc(*ptr, fp);
21574                         continue;
21575                 }
21576                 ptr++;
21577                 if (*ptr == '%') {
21578                         fputc('%', fp);
21579                         continue;
21580                 }
21581                 param = strtoul(ptr, &next, 10);
21582                 if (ptr == next) {
21583                         error(state, ins, "Invalid asm template");
21584                 }
21585                 if (param >= (lhs + rhs)) {
21586                         error(state, ins, "Invalid param %%%u in asm template",
21587                                 param);
21588                 }
21589                 piece = (param < lhs)? LHS(ins, param) : RHS(ins, param - lhs);
21590                 fprintf(fp, "%s", 
21591                         arch_reg_str(ID_REG(piece->id)));
21592                 ptr = next -1;
21593         }
21594         fprintf(fp, "\n#NOT ASM\n");
21595 }
21596
21597
21598 /* Only use the low x86 byte registers.  This allows me
21599  * allocate the entire register when a byte register is used.
21600  */
21601 #define X86_4_8BIT_GPRS 1
21602
21603 /* x86 featrues */
21604 #define X86_MMX_REGS  (1<<0)
21605 #define X86_XMM_REGS  (1<<1)
21606 #define X86_NOOP_COPY (1<<2)
21607
21608 /* The x86 register classes */
21609 #define REGC_FLAGS       0
21610 #define REGC_GPR8        1
21611 #define REGC_GPR16       2
21612 #define REGC_GPR32       3
21613 #define REGC_DIVIDEND64  4
21614 #define REGC_DIVIDEND32  5
21615 #define REGC_MMX         6
21616 #define REGC_XMM         7
21617 #define REGC_GPR32_8     8
21618 #define REGC_GPR16_8     9
21619 #define REGC_GPR8_LO    10
21620 #define REGC_IMM32      11
21621 #define REGC_IMM16      12
21622 #define REGC_IMM8       13
21623 #define LAST_REGC  REGC_IMM8
21624 #if LAST_REGC >= MAX_REGC
21625 #error "MAX_REGC is to low"
21626 #endif
21627
21628 /* Register class masks */
21629 #define REGCM_FLAGS      (1 << REGC_FLAGS)
21630 #define REGCM_GPR8       (1 << REGC_GPR8)
21631 #define REGCM_GPR16      (1 << REGC_GPR16)
21632 #define REGCM_GPR32      (1 << REGC_GPR32)
21633 #define REGCM_DIVIDEND64 (1 << REGC_DIVIDEND64)
21634 #define REGCM_DIVIDEND32 (1 << REGC_DIVIDEND32)
21635 #define REGCM_MMX        (1 << REGC_MMX)
21636 #define REGCM_XMM        (1 << REGC_XMM)
21637 #define REGCM_GPR32_8    (1 << REGC_GPR32_8)
21638 #define REGCM_GPR16_8    (1 << REGC_GPR16_8)
21639 #define REGCM_GPR8_LO    (1 << REGC_GPR8_LO)
21640 #define REGCM_IMM32      (1 << REGC_IMM32)
21641 #define REGCM_IMM16      (1 << REGC_IMM16)
21642 #define REGCM_IMM8       (1 << REGC_IMM8)
21643 #define REGCM_ALL        ((1 << (LAST_REGC + 1)) - 1)
21644 #define REGCM_IMMALL    (REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8)
21645
21646 /* The x86 registers */
21647 #define REG_EFLAGS  2
21648 #define REGC_FLAGS_FIRST REG_EFLAGS
21649 #define REGC_FLAGS_LAST  REG_EFLAGS
21650 #define REG_AL      3
21651 #define REG_BL      4
21652 #define REG_CL      5
21653 #define REG_DL      6
21654 #define REG_AH      7
21655 #define REG_BH      8
21656 #define REG_CH      9
21657 #define REG_DH      10
21658 #define REGC_GPR8_LO_FIRST REG_AL
21659 #define REGC_GPR8_LO_LAST  REG_DL
21660 #define REGC_GPR8_FIRST  REG_AL
21661 #define REGC_GPR8_LAST   REG_DH
21662 #define REG_AX     11
21663 #define REG_BX     12
21664 #define REG_CX     13
21665 #define REG_DX     14
21666 #define REG_SI     15
21667 #define REG_DI     16
21668 #define REG_BP     17
21669 #define REG_SP     18
21670 #define REGC_GPR16_FIRST REG_AX
21671 #define REGC_GPR16_LAST  REG_SP
21672 #define REG_EAX    19
21673 #define REG_EBX    20
21674 #define REG_ECX    21
21675 #define REG_EDX    22
21676 #define REG_ESI    23
21677 #define REG_EDI    24
21678 #define REG_EBP    25
21679 #define REG_ESP    26
21680 #define REGC_GPR32_FIRST REG_EAX
21681 #define REGC_GPR32_LAST  REG_ESP
21682 #define REG_EDXEAX 27
21683 #define REGC_DIVIDEND64_FIRST REG_EDXEAX
21684 #define REGC_DIVIDEND64_LAST  REG_EDXEAX
21685 #define REG_DXAX   28
21686 #define REGC_DIVIDEND32_FIRST REG_DXAX
21687 #define REGC_DIVIDEND32_LAST  REG_DXAX
21688 #define REG_MMX0   29
21689 #define REG_MMX1   30
21690 #define REG_MMX2   31
21691 #define REG_MMX3   32
21692 #define REG_MMX4   33
21693 #define REG_MMX5   34
21694 #define REG_MMX6   35
21695 #define REG_MMX7   36
21696 #define REGC_MMX_FIRST REG_MMX0
21697 #define REGC_MMX_LAST  REG_MMX7
21698 #define REG_XMM0   37
21699 #define REG_XMM1   38
21700 #define REG_XMM2   39
21701 #define REG_XMM3   40
21702 #define REG_XMM4   41
21703 #define REG_XMM5   42
21704 #define REG_XMM6   43
21705 #define REG_XMM7   44
21706 #define REGC_XMM_FIRST REG_XMM0
21707 #define REGC_XMM_LAST  REG_XMM7
21708 #warning "WISHLIST figure out how to use pinsrw and pextrw to better use extended regs"
21709 #define LAST_REG   REG_XMM7
21710
21711 #define REGC_GPR32_8_FIRST REG_EAX
21712 #define REGC_GPR32_8_LAST  REG_EDX
21713 #define REGC_GPR16_8_FIRST REG_AX
21714 #define REGC_GPR16_8_LAST  REG_DX
21715
21716 #define REGC_IMM8_FIRST    -1
21717 #define REGC_IMM8_LAST     -1
21718 #define REGC_IMM16_FIRST   -2
21719 #define REGC_IMM16_LAST    -1
21720 #define REGC_IMM32_FIRST   -4
21721 #define REGC_IMM32_LAST    -1
21722
21723 #if LAST_REG >= MAX_REGISTERS
21724 #error "MAX_REGISTERS to low"
21725 #endif
21726
21727
21728 static unsigned regc_size[LAST_REGC +1] = {
21729         [REGC_FLAGS]      = REGC_FLAGS_LAST      - REGC_FLAGS_FIRST + 1,
21730         [REGC_GPR8]       = REGC_GPR8_LAST       - REGC_GPR8_FIRST + 1,
21731         [REGC_GPR16]      = REGC_GPR16_LAST      - REGC_GPR16_FIRST + 1,
21732         [REGC_GPR32]      = REGC_GPR32_LAST      - REGC_GPR32_FIRST + 1,
21733         [REGC_DIVIDEND64] = REGC_DIVIDEND64_LAST - REGC_DIVIDEND64_FIRST + 1,
21734         [REGC_DIVIDEND32] = REGC_DIVIDEND32_LAST - REGC_DIVIDEND32_FIRST + 1,
21735         [REGC_MMX]        = REGC_MMX_LAST        - REGC_MMX_FIRST + 1,
21736         [REGC_XMM]        = REGC_XMM_LAST        - REGC_XMM_FIRST + 1,
21737         [REGC_GPR32_8]    = REGC_GPR32_8_LAST    - REGC_GPR32_8_FIRST + 1,
21738         [REGC_GPR16_8]    = REGC_GPR16_8_LAST    - REGC_GPR16_8_FIRST + 1,
21739         [REGC_GPR8_LO]    = REGC_GPR8_LO_LAST    - REGC_GPR8_LO_FIRST + 1,
21740         [REGC_IMM32]      = 0,
21741         [REGC_IMM16]      = 0,
21742         [REGC_IMM8]       = 0,
21743 };
21744
21745 static const struct {
21746         int first, last;
21747 } regcm_bound[LAST_REGC + 1] = {
21748         [REGC_FLAGS]      = { REGC_FLAGS_FIRST,      REGC_FLAGS_LAST },
21749         [REGC_GPR8]       = { REGC_GPR8_FIRST,       REGC_GPR8_LAST },
21750         [REGC_GPR16]      = { REGC_GPR16_FIRST,      REGC_GPR16_LAST },
21751         [REGC_GPR32]      = { REGC_GPR32_FIRST,      REGC_GPR32_LAST },
21752         [REGC_DIVIDEND64] = { REGC_DIVIDEND64_FIRST, REGC_DIVIDEND64_LAST },
21753         [REGC_DIVIDEND32] = { REGC_DIVIDEND32_FIRST, REGC_DIVIDEND32_LAST },
21754         [REGC_MMX]        = { REGC_MMX_FIRST,        REGC_MMX_LAST },
21755         [REGC_XMM]        = { REGC_XMM_FIRST,        REGC_XMM_LAST },
21756         [REGC_GPR32_8]    = { REGC_GPR32_8_FIRST,    REGC_GPR32_8_LAST },
21757         [REGC_GPR16_8]    = { REGC_GPR16_8_FIRST,    REGC_GPR16_8_LAST },
21758         [REGC_GPR8_LO]    = { REGC_GPR8_LO_FIRST,    REGC_GPR8_LO_LAST },
21759         [REGC_IMM32]      = { REGC_IMM32_FIRST,      REGC_IMM32_LAST },
21760         [REGC_IMM16]      = { REGC_IMM16_FIRST,      REGC_IMM16_LAST },
21761         [REGC_IMM8]       = { REGC_IMM8_FIRST,       REGC_IMM8_LAST },
21762 };
21763
21764 #if ARCH_INPUT_REGS != 4
21765 #error ARCH_INPUT_REGS size mismatch
21766 #endif
21767 static const struct reg_info arch_input_regs[ARCH_INPUT_REGS] = {
21768         { .reg = REG_EAX, .regcm = REGCM_GPR32 },
21769         { .reg = REG_EBX, .regcm = REGCM_GPR32 },
21770         { .reg = REG_ECX, .regcm = REGCM_GPR32 },
21771         { .reg = REG_EDX, .regcm = REGCM_GPR32 },
21772 };
21773
21774 #if ARCH_OUTPUT_REGS != 4
21775 #error ARCH_INPUT_REGS size mismatch
21776 #endif
21777 static const struct reg_info arch_output_regs[ARCH_OUTPUT_REGS] = {
21778         { .reg = REG_EAX, .regcm = REGCM_GPR32 },
21779         { .reg = REG_EBX, .regcm = REGCM_GPR32 },
21780         { .reg = REG_ECX, .regcm = REGCM_GPR32 },
21781         { .reg = REG_EDX, .regcm = REGCM_GPR32 },
21782 };
21783
21784 static void init_arch_state(struct arch_state *arch)
21785 {
21786         memset(arch, 0, sizeof(*arch));
21787         arch->features = 0;
21788 }
21789
21790 static const struct compiler_flag arch_flags[] = {
21791         { "mmx",       X86_MMX_REGS },
21792         { "sse",       X86_XMM_REGS },
21793         { "noop-copy", X86_NOOP_COPY },
21794         { 0,     0 },
21795 };
21796 static const struct compiler_flag arch_cpus[] = {
21797         { "i386", 0 },
21798         { "p2",   X86_MMX_REGS },
21799         { "p3",   X86_MMX_REGS | X86_XMM_REGS },
21800         { "p4",   X86_MMX_REGS | X86_XMM_REGS },
21801         { "k7",   X86_MMX_REGS },
21802         { "k8",   X86_MMX_REGS | X86_XMM_REGS },
21803         { "c3",   X86_MMX_REGS },
21804         { "c3-2", X86_MMX_REGS | X86_XMM_REGS }, /* Nehemiah */
21805         {  0,     0 }
21806 };
21807 static int arch_encode_flag(struct arch_state *arch, const char *flag)
21808 {
21809         int result;
21810         int act;
21811
21812         act = 1;
21813         result = -1;
21814         if (strncmp(flag, "no-", 3) == 0) {
21815                 flag += 3;
21816                 act = 0;
21817         }
21818         if (act && strncmp(flag, "cpu=", 4) == 0) {
21819                 flag += 4;
21820                 result = set_flag(arch_cpus, &arch->features, 1, flag);
21821         }
21822         else {
21823                 result = set_flag(arch_flags, &arch->features, act, flag);
21824         }
21825         return result;
21826 }
21827
21828 static void arch_usage(FILE *fp)
21829 {
21830         flag_usage(fp, arch_flags, "-m", "-mno-");
21831         flag_usage(fp, arch_cpus, "-mcpu=", 0);
21832 }
21833
21834 static unsigned arch_regc_size(struct compile_state *state, int class)
21835 {
21836         if ((class < 0) || (class > LAST_REGC)) {
21837                 return 0;
21838         }
21839         return regc_size[class];
21840 }
21841
21842 static int arch_regcm_intersect(unsigned regcm1, unsigned regcm2)
21843 {
21844         /* See if two register classes may have overlapping registers */
21845         unsigned gpr_mask = REGCM_GPR8 | REGCM_GPR8_LO | REGCM_GPR16_8 | REGCM_GPR16 |
21846                 REGCM_GPR32_8 | REGCM_GPR32 | 
21847                 REGCM_DIVIDEND32 | REGCM_DIVIDEND64;
21848
21849         /* Special case for the immediates */
21850         if ((regcm1 & (REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8)) &&
21851                 ((regcm1 & ~(REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8)) == 0) &&
21852                 (regcm2 & (REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8)) &&
21853                 ((regcm2 & ~(REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8)) == 0)) { 
21854                 return 0;
21855         }
21856         return (regcm1 & regcm2) ||
21857                 ((regcm1 & gpr_mask) && (regcm2 & gpr_mask));
21858 }
21859
21860 static void arch_reg_equivs(
21861         struct compile_state *state, unsigned *equiv, int reg)
21862 {
21863         if ((reg < 0) || (reg > LAST_REG)) {
21864                 internal_error(state, 0, "invalid register");
21865         }
21866         *equiv++ = reg;
21867         switch(reg) {
21868         case REG_AL:
21869 #if X86_4_8BIT_GPRS
21870                 *equiv++ = REG_AH;
21871 #endif
21872                 *equiv++ = REG_AX;
21873                 *equiv++ = REG_EAX;
21874                 *equiv++ = REG_DXAX;
21875                 *equiv++ = REG_EDXEAX;
21876                 break;
21877         case REG_AH:
21878 #if X86_4_8BIT_GPRS
21879                 *equiv++ = REG_AL;
21880 #endif
21881                 *equiv++ = REG_AX;
21882                 *equiv++ = REG_EAX;
21883                 *equiv++ = REG_DXAX;
21884                 *equiv++ = REG_EDXEAX;
21885                 break;
21886         case REG_BL:  
21887 #if X86_4_8BIT_GPRS
21888                 *equiv++ = REG_BH;
21889 #endif
21890                 *equiv++ = REG_BX;
21891                 *equiv++ = REG_EBX;
21892                 break;
21893
21894         case REG_BH:
21895 #if X86_4_8BIT_GPRS
21896                 *equiv++ = REG_BL;
21897 #endif
21898                 *equiv++ = REG_BX;
21899                 *equiv++ = REG_EBX;
21900                 break;
21901         case REG_CL:
21902 #if X86_4_8BIT_GPRS
21903                 *equiv++ = REG_CH;
21904 #endif
21905                 *equiv++ = REG_CX;
21906                 *equiv++ = REG_ECX;
21907                 break;
21908
21909         case REG_CH:
21910 #if X86_4_8BIT_GPRS
21911                 *equiv++ = REG_CL;
21912 #endif
21913                 *equiv++ = REG_CX;
21914                 *equiv++ = REG_ECX;
21915                 break;
21916         case REG_DL:
21917 #if X86_4_8BIT_GPRS
21918                 *equiv++ = REG_DH;
21919 #endif
21920                 *equiv++ = REG_DX;
21921                 *equiv++ = REG_EDX;
21922                 *equiv++ = REG_DXAX;
21923                 *equiv++ = REG_EDXEAX;
21924                 break;
21925         case REG_DH:
21926 #if X86_4_8BIT_GPRS
21927                 *equiv++ = REG_DL;
21928 #endif
21929                 *equiv++ = REG_DX;
21930                 *equiv++ = REG_EDX;
21931                 *equiv++ = REG_DXAX;
21932                 *equiv++ = REG_EDXEAX;
21933                 break;
21934         case REG_AX:
21935                 *equiv++ = REG_AL;
21936                 *equiv++ = REG_AH;
21937                 *equiv++ = REG_EAX;
21938                 *equiv++ = REG_DXAX;
21939                 *equiv++ = REG_EDXEAX;
21940                 break;
21941         case REG_BX:
21942                 *equiv++ = REG_BL;
21943                 *equiv++ = REG_BH;
21944                 *equiv++ = REG_EBX;
21945                 break;
21946         case REG_CX:  
21947                 *equiv++ = REG_CL;
21948                 *equiv++ = REG_CH;
21949                 *equiv++ = REG_ECX;
21950                 break;
21951         case REG_DX:  
21952                 *equiv++ = REG_DL;
21953                 *equiv++ = REG_DH;
21954                 *equiv++ = REG_EDX;
21955                 *equiv++ = REG_DXAX;
21956                 *equiv++ = REG_EDXEAX;
21957                 break;
21958         case REG_SI:  
21959                 *equiv++ = REG_ESI;
21960                 break;
21961         case REG_DI:
21962                 *equiv++ = REG_EDI;
21963                 break;
21964         case REG_BP:
21965                 *equiv++ = REG_EBP;
21966                 break;
21967         case REG_SP:
21968                 *equiv++ = REG_ESP;
21969                 break;
21970         case REG_EAX:
21971                 *equiv++ = REG_AL;
21972                 *equiv++ = REG_AH;
21973                 *equiv++ = REG_AX;
21974                 *equiv++ = REG_DXAX;
21975                 *equiv++ = REG_EDXEAX;
21976                 break;
21977         case REG_EBX:
21978                 *equiv++ = REG_BL;
21979                 *equiv++ = REG_BH;
21980                 *equiv++ = REG_BX;
21981                 break;
21982         case REG_ECX:
21983                 *equiv++ = REG_CL;
21984                 *equiv++ = REG_CH;
21985                 *equiv++ = REG_CX;
21986                 break;
21987         case REG_EDX:
21988                 *equiv++ = REG_DL;
21989                 *equiv++ = REG_DH;
21990                 *equiv++ = REG_DX;
21991                 *equiv++ = REG_DXAX;
21992                 *equiv++ = REG_EDXEAX;
21993                 break;
21994         case REG_ESI: 
21995                 *equiv++ = REG_SI;
21996                 break;
21997         case REG_EDI: 
21998                 *equiv++ = REG_DI;
21999                 break;
22000         case REG_EBP: 
22001                 *equiv++ = REG_BP;
22002                 break;
22003         case REG_ESP: 
22004                 *equiv++ = REG_SP;
22005                 break;
22006         case REG_DXAX: 
22007                 *equiv++ = REG_AL;
22008                 *equiv++ = REG_AH;
22009                 *equiv++ = REG_DL;
22010                 *equiv++ = REG_DH;
22011                 *equiv++ = REG_AX;
22012                 *equiv++ = REG_DX;
22013                 *equiv++ = REG_EAX;
22014                 *equiv++ = REG_EDX;
22015                 *equiv++ = REG_EDXEAX;
22016                 break;
22017         case REG_EDXEAX: 
22018                 *equiv++ = REG_AL;
22019                 *equiv++ = REG_AH;
22020                 *equiv++ = REG_DL;
22021                 *equiv++ = REG_DH;
22022                 *equiv++ = REG_AX;
22023                 *equiv++ = REG_DX;
22024                 *equiv++ = REG_EAX;
22025                 *equiv++ = REG_EDX;
22026                 *equiv++ = REG_DXAX;
22027                 break;
22028         }
22029         *equiv++ = REG_UNSET; 
22030 }
22031
22032 static unsigned arch_avail_mask(struct compile_state *state)
22033 {
22034         unsigned avail_mask;
22035         /* REGCM_GPR8 is not available */
22036         avail_mask = REGCM_GPR8_LO | REGCM_GPR16_8 | REGCM_GPR16 | 
22037                 REGCM_GPR32 | REGCM_GPR32_8 | 
22038                 REGCM_DIVIDEND32 | REGCM_DIVIDEND64 |
22039                 REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8 | REGCM_FLAGS;
22040         if (state->arch->features & X86_MMX_REGS) {
22041                 avail_mask |= REGCM_MMX;
22042         }
22043         if (state->arch->features & X86_XMM_REGS) {
22044                 avail_mask |= REGCM_XMM;
22045         }
22046         return avail_mask;
22047 }
22048
22049 static unsigned arch_regcm_normalize(struct compile_state *state, unsigned regcm)
22050 {
22051         unsigned mask, result;
22052         int class, class2;
22053         result = regcm;
22054
22055         for(class = 0, mask = 1; mask; mask <<= 1, class++) {
22056                 if ((result & mask) == 0) {
22057                         continue;
22058                 }
22059                 if (class > LAST_REGC) {
22060                         result &= ~mask;
22061                 }
22062                 for(class2 = 0; class2 <= LAST_REGC; class2++) {
22063                         if ((regcm_bound[class2].first >= regcm_bound[class].first) &&
22064                                 (regcm_bound[class2].last <= regcm_bound[class].last)) {
22065                                 result |= (1 << class2);
22066                         }
22067                 }
22068         }
22069         result &= arch_avail_mask(state);
22070         return result;
22071 }
22072
22073 static unsigned arch_regcm_reg_normalize(struct compile_state *state, unsigned regcm)
22074 {
22075         /* Like arch_regcm_normalize except immediate register classes are excluded */
22076         regcm = arch_regcm_normalize(state, regcm);
22077         /* Remove the immediate register classes */
22078         regcm &= ~(REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8);
22079         return regcm;
22080         
22081 }
22082
22083 static unsigned arch_reg_regcm(struct compile_state *state, int reg)
22084 {
22085         unsigned mask;
22086         int class;
22087         mask = 0;
22088         for(class = 0; class <= LAST_REGC; class++) {
22089                 if ((reg >= regcm_bound[class].first) &&
22090                         (reg <= regcm_bound[class].last)) {
22091                         mask |= (1 << class);
22092                 }
22093         }
22094         if (!mask) {
22095                 internal_error(state, 0, "reg %d not in any class", reg);
22096         }
22097         return mask;
22098 }
22099
22100 static struct reg_info arch_reg_constraint(
22101         struct compile_state *state, struct type *type, const char *constraint)
22102 {
22103         static const struct {
22104                 char class;
22105                 unsigned int mask;
22106                 unsigned int reg;
22107         } constraints[] = {
22108                 { 'r', REGCM_GPR32,   REG_UNSET },
22109                 { 'g', REGCM_GPR32,   REG_UNSET },
22110                 { 'p', REGCM_GPR32,   REG_UNSET },
22111                 { 'q', REGCM_GPR8_LO, REG_UNSET },
22112                 { 'Q', REGCM_GPR32_8, REG_UNSET },
22113                 { 'x', REGCM_XMM,     REG_UNSET },
22114                 { 'y', REGCM_MMX,     REG_UNSET },
22115                 { 'a', REGCM_GPR32,   REG_EAX },
22116                 { 'b', REGCM_GPR32,   REG_EBX },
22117                 { 'c', REGCM_GPR32,   REG_ECX },
22118                 { 'd', REGCM_GPR32,   REG_EDX },
22119                 { 'D', REGCM_GPR32,   REG_EDI },
22120                 { 'S', REGCM_GPR32,   REG_ESI },
22121                 { '\0', 0, REG_UNSET },
22122         };
22123         unsigned int regcm;
22124         unsigned int mask, reg;
22125         struct reg_info result;
22126         const char *ptr;
22127         regcm = arch_type_to_regcm(state, type);
22128         reg = REG_UNSET;
22129         mask = 0;
22130         for(ptr = constraint; *ptr; ptr++) {
22131                 int i;
22132                 if (*ptr ==  ' ') {
22133                         continue;
22134                 }
22135                 for(i = 0; constraints[i].class != '\0'; i++) {
22136                         if (constraints[i].class == *ptr) {
22137                                 break;
22138                         }
22139                 }
22140                 if (constraints[i].class == '\0') {
22141                         error(state, 0, "invalid register constraint ``%c''", *ptr);
22142                         break;
22143                 }
22144                 if ((constraints[i].mask & regcm) == 0) {
22145                         error(state, 0, "invalid register class %c specified",
22146                                 *ptr);
22147                 }
22148                 mask |= constraints[i].mask;
22149                 if (constraints[i].reg != REG_UNSET) {
22150                         if ((reg != REG_UNSET) && (reg != constraints[i].reg)) {
22151                                 error(state, 0, "Only one register may be specified");
22152                         }
22153                         reg = constraints[i].reg;
22154                 }
22155         }
22156         result.reg = reg;
22157         result.regcm = mask;
22158         return result;
22159 }
22160
22161 static struct reg_info arch_reg_clobber(
22162         struct compile_state *state, const char *clobber)
22163 {
22164         struct reg_info result;
22165         if (strcmp(clobber, "memory") == 0) {
22166                 result.reg = REG_UNSET;
22167                 result.regcm = 0;
22168         }
22169         else if (strcmp(clobber, "eax") == 0) {
22170                 result.reg = REG_EAX;
22171                 result.regcm = REGCM_GPR32;
22172         }
22173         else if (strcmp(clobber, "ebx") == 0) {
22174                 result.reg = REG_EBX;
22175                 result.regcm = REGCM_GPR32;
22176         }
22177         else if (strcmp(clobber, "ecx") == 0) {
22178                 result.reg = REG_ECX;
22179                 result.regcm = REGCM_GPR32;
22180         }
22181         else if (strcmp(clobber, "edx") == 0) {
22182                 result.reg = REG_EDX;
22183                 result.regcm = REGCM_GPR32;
22184         }
22185         else if (strcmp(clobber, "esi") == 0) {
22186                 result.reg = REG_ESI;
22187                 result.regcm = REGCM_GPR32;
22188         }
22189         else if (strcmp(clobber, "edi") == 0) {
22190                 result.reg = REG_EDI;
22191                 result.regcm = REGCM_GPR32;
22192         }
22193         else if (strcmp(clobber, "ebp") == 0) {
22194                 result.reg = REG_EBP;
22195                 result.regcm = REGCM_GPR32;
22196         }
22197         else if (strcmp(clobber, "esp") == 0) {
22198                 result.reg = REG_ESP;
22199                 result.regcm = REGCM_GPR32;
22200         }
22201         else if (strcmp(clobber, "cc") == 0) {
22202                 result.reg = REG_EFLAGS;
22203                 result.regcm = REGCM_FLAGS;
22204         }
22205         else if ((strncmp(clobber, "xmm", 3) == 0)  &&
22206                 octdigitp(clobber[3]) && (clobber[4] == '\0')) {
22207                 result.reg = REG_XMM0 + octdigval(clobber[3]);
22208                 result.regcm = REGCM_XMM;
22209         }
22210         else if ((strncmp(clobber, "mm", 2) == 0) &&
22211                 octdigitp(clobber[3]) && (clobber[4] == '\0')) {
22212                 result.reg = REG_MMX0 + octdigval(clobber[3]);
22213                 result.regcm = REGCM_MMX;
22214         }
22215         else {
22216                 error(state, 0, "unknown register name `%s' in asm",
22217                         clobber);
22218                 result.reg = REG_UNSET;
22219                 result.regcm = 0;
22220         }
22221         return result;
22222 }
22223
22224 static int do_select_reg(struct compile_state *state, 
22225         char *used, int reg, unsigned classes)
22226 {
22227         unsigned mask;
22228         if (used[reg]) {
22229                 return REG_UNSET;
22230         }
22231         mask = arch_reg_regcm(state, reg);
22232         return (classes & mask) ? reg : REG_UNSET;
22233 }
22234
22235 static int arch_select_free_register(
22236         struct compile_state *state, char *used, int classes)
22237 {
22238         /* Live ranges with the most neighbors are colored first.
22239          *
22240          * Generally it does not matter which colors are given
22241          * as the register allocator attempts to color live ranges
22242          * in an order where you are guaranteed not to run out of colors.
22243          *
22244          * Occasionally the register allocator cannot find an order
22245          * of register selection that will find a free color.  To
22246          * increase the odds the register allocator will work when
22247          * it guesses first give out registers from register classes
22248          * least likely to run out of registers.
22249          * 
22250          */
22251         int i, reg;
22252         reg = REG_UNSET;
22253         for(i = REGC_XMM_FIRST; (reg == REG_UNSET) && (i <= REGC_XMM_LAST); i++) {
22254                 reg = do_select_reg(state, used, i, classes);
22255         }
22256         for(i = REGC_MMX_FIRST; (reg == REG_UNSET) && (i <= REGC_MMX_LAST); i++) {
22257                 reg = do_select_reg(state, used, i, classes);
22258         }
22259         for(i = REGC_GPR32_LAST; (reg == REG_UNSET) && (i >= REGC_GPR32_FIRST); i--) {
22260                 reg = do_select_reg(state, used, i, classes);
22261         }
22262         for(i = REGC_GPR16_FIRST; (reg == REG_UNSET) && (i <= REGC_GPR16_LAST); i++) {
22263                 reg = do_select_reg(state, used, i, classes);
22264         }
22265         for(i = REGC_GPR8_FIRST; (reg == REG_UNSET) && (i <= REGC_GPR8_LAST); i++) {
22266                 reg = do_select_reg(state, used, i, classes);
22267         }
22268         for(i = REGC_GPR8_LO_FIRST; (reg == REG_UNSET) && (i <= REGC_GPR8_LO_LAST); i++) {
22269                 reg = do_select_reg(state, used, i, classes);
22270         }
22271         for(i = REGC_DIVIDEND32_FIRST; (reg == REG_UNSET) && (i <= REGC_DIVIDEND32_LAST); i++) {
22272                 reg = do_select_reg(state, used, i, classes);
22273         }
22274         for(i = REGC_DIVIDEND64_FIRST; (reg == REG_UNSET) && (i <= REGC_DIVIDEND64_LAST); i++) {
22275                 reg = do_select_reg(state, used, i, classes);
22276         }
22277         for(i = REGC_FLAGS_FIRST; (reg == REG_UNSET) && (i <= REGC_FLAGS_LAST); i++) {
22278                 reg = do_select_reg(state, used, i, classes);
22279         }
22280         return reg;
22281 }
22282
22283
22284 static unsigned arch_type_to_regcm(struct compile_state *state, struct type *type) 
22285 {
22286 #warning "FIXME force types smaller (if legal) before I get here"
22287         unsigned mask;
22288         mask = 0;
22289         switch(type->type & TYPE_MASK) {
22290         case TYPE_ARRAY:
22291         case TYPE_VOID: 
22292                 mask = 0; 
22293                 break;
22294         case TYPE_CHAR:
22295         case TYPE_UCHAR:
22296                 mask = REGCM_GPR8 | REGCM_GPR8_LO |
22297                         REGCM_GPR16 | REGCM_GPR16_8 | 
22298                         REGCM_GPR32 | REGCM_GPR32_8 |
22299                         REGCM_DIVIDEND32 | REGCM_DIVIDEND64 |
22300                         REGCM_MMX | REGCM_XMM |
22301                         REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8;
22302                 break;
22303         case TYPE_SHORT:
22304         case TYPE_USHORT:
22305                 mask =  REGCM_GPR16 | REGCM_GPR16_8 |
22306                         REGCM_GPR32 | REGCM_GPR32_8 |
22307                         REGCM_DIVIDEND32 | REGCM_DIVIDEND64 |
22308                         REGCM_MMX | REGCM_XMM |
22309                         REGCM_IMM32 | REGCM_IMM16;
22310                 break;
22311         case TYPE_ENUM:
22312         case TYPE_INT:
22313         case TYPE_UINT:
22314         case TYPE_LONG:
22315         case TYPE_ULONG:
22316         case TYPE_POINTER:
22317                 mask =  REGCM_GPR32 | REGCM_GPR32_8 |
22318                         REGCM_DIVIDEND32 | REGCM_DIVIDEND64 |
22319                         REGCM_MMX | REGCM_XMM |
22320                         REGCM_IMM32;
22321                 break;
22322         case TYPE_JOIN:
22323         case TYPE_UNION:
22324                 mask = arch_type_to_regcm(state, type->left);
22325                 break;
22326         case TYPE_OVERLAP:
22327                 mask = arch_type_to_regcm(state, type->left) &
22328                         arch_type_to_regcm(state, type->right);
22329                 break;
22330         case TYPE_BITFIELD:
22331                 mask = arch_type_to_regcm(state, type->left);
22332                 break;
22333         default:
22334                 fprintf(state->errout, "type: ");
22335                 name_of(state->errout, type);
22336                 fprintf(state->errout, "\n");
22337                 internal_error(state, 0, "no register class for type");
22338                 break;
22339         }
22340         mask = arch_regcm_normalize(state, mask);
22341         return mask;
22342 }
22343
22344 static int is_imm32(struct triple *imm)
22345 {
22346         return ((imm->op == OP_INTCONST) && (imm->u.cval <= 0xffffffffUL)) ||
22347                 (imm->op == OP_ADDRCONST);
22348         
22349 }
22350 static int is_imm16(struct triple *imm)
22351 {
22352         return ((imm->op == OP_INTCONST) && (imm->u.cval <= 0xffff));
22353 }
22354 static int is_imm8(struct triple *imm)
22355 {
22356         return ((imm->op == OP_INTCONST) && (imm->u.cval <= 0xff));
22357 }
22358
22359 static int get_imm32(struct triple *ins, struct triple **expr)
22360 {
22361         struct triple *imm;
22362         imm = *expr;
22363         while(imm->op == OP_COPY) {
22364                 imm = RHS(imm, 0);
22365         }
22366         if (!is_imm32(imm)) {
22367                 return 0;
22368         }
22369         unuse_triple(*expr, ins);
22370         use_triple(imm, ins);
22371         *expr = imm;
22372         return 1;
22373 }
22374
22375 static int get_imm8(struct triple *ins, struct triple **expr)
22376 {
22377         struct triple *imm;
22378         imm = *expr;
22379         while(imm->op == OP_COPY) {
22380                 imm = RHS(imm, 0);
22381         }
22382         if (!is_imm8(imm)) {
22383                 return 0;
22384         }
22385         unuse_triple(*expr, ins);
22386         use_triple(imm, ins);
22387         *expr = imm;
22388         return 1;
22389 }
22390
22391 #define TEMPLATE_NOP           0
22392 #define TEMPLATE_INTCONST8     1
22393 #define TEMPLATE_INTCONST32    2
22394 #define TEMPLATE_UNKNOWNVAL    3
22395 #define TEMPLATE_COPY8_REG     5
22396 #define TEMPLATE_COPY16_REG    6
22397 #define TEMPLATE_COPY32_REG    7
22398 #define TEMPLATE_COPY_IMM8     8
22399 #define TEMPLATE_COPY_IMM16    9
22400 #define TEMPLATE_COPY_IMM32   10
22401 #define TEMPLATE_PHI8         11
22402 #define TEMPLATE_PHI16        12
22403 #define TEMPLATE_PHI32        13
22404 #define TEMPLATE_STORE8       14
22405 #define TEMPLATE_STORE16      15
22406 #define TEMPLATE_STORE32      16
22407 #define TEMPLATE_LOAD8        17
22408 #define TEMPLATE_LOAD16       18
22409 #define TEMPLATE_LOAD32       19
22410 #define TEMPLATE_BINARY8_REG  20
22411 #define TEMPLATE_BINARY16_REG 21
22412 #define TEMPLATE_BINARY32_REG 22
22413 #define TEMPLATE_BINARY8_IMM  23
22414 #define TEMPLATE_BINARY16_IMM 24
22415 #define TEMPLATE_BINARY32_IMM 25
22416 #define TEMPLATE_SL8_CL       26
22417 #define TEMPLATE_SL16_CL      27
22418 #define TEMPLATE_SL32_CL      28
22419 #define TEMPLATE_SL8_IMM      29
22420 #define TEMPLATE_SL16_IMM     30
22421 #define TEMPLATE_SL32_IMM     31
22422 #define TEMPLATE_UNARY8       32
22423 #define TEMPLATE_UNARY16      33
22424 #define TEMPLATE_UNARY32      34
22425 #define TEMPLATE_CMP8_REG     35
22426 #define TEMPLATE_CMP16_REG    36
22427 #define TEMPLATE_CMP32_REG    37
22428 #define TEMPLATE_CMP8_IMM     38
22429 #define TEMPLATE_CMP16_IMM    39
22430 #define TEMPLATE_CMP32_IMM    40
22431 #define TEMPLATE_TEST8        41
22432 #define TEMPLATE_TEST16       42
22433 #define TEMPLATE_TEST32       43
22434 #define TEMPLATE_SET          44
22435 #define TEMPLATE_JMP          45
22436 #define TEMPLATE_RET          46
22437 #define TEMPLATE_INB_DX       47
22438 #define TEMPLATE_INB_IMM      48
22439 #define TEMPLATE_INW_DX       49
22440 #define TEMPLATE_INW_IMM      50
22441 #define TEMPLATE_INL_DX       51
22442 #define TEMPLATE_INL_IMM      52
22443 #define TEMPLATE_OUTB_DX      53
22444 #define TEMPLATE_OUTB_IMM     54
22445 #define TEMPLATE_OUTW_DX      55
22446 #define TEMPLATE_OUTW_IMM     56
22447 #define TEMPLATE_OUTL_DX      57
22448 #define TEMPLATE_OUTL_IMM     58
22449 #define TEMPLATE_BSF          59
22450 #define TEMPLATE_RDMSR        60
22451 #define TEMPLATE_WRMSR        61
22452 #define TEMPLATE_UMUL8        62
22453 #define TEMPLATE_UMUL16       63
22454 #define TEMPLATE_UMUL32       64
22455 #define TEMPLATE_DIV8         65
22456 #define TEMPLATE_DIV16        66
22457 #define TEMPLATE_DIV32        67
22458 #define LAST_TEMPLATE       TEMPLATE_DIV32
22459 #if LAST_TEMPLATE >= MAX_TEMPLATES
22460 #error "MAX_TEMPLATES to low"
22461 #endif
22462
22463 #define COPY8_REGCM     (REGCM_DIVIDEND64 | REGCM_DIVIDEND32 | REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO | REGCM_MMX | REGCM_XMM)
22464 #define COPY16_REGCM    (REGCM_DIVIDEND64 | REGCM_DIVIDEND32 | REGCM_GPR32 | REGCM_GPR16 | REGCM_MMX | REGCM_XMM)  
22465 #define COPY32_REGCM    (REGCM_DIVIDEND64 | REGCM_DIVIDEND32 | REGCM_GPR32 | REGCM_MMX | REGCM_XMM)
22466
22467
22468 static struct ins_template templates[] = {
22469         [TEMPLATE_NOP]      = {
22470                 .lhs = { 
22471                         [ 0] = { REG_UNNEEDED, REGCM_IMMALL },
22472                         [ 1] = { REG_UNNEEDED, REGCM_IMMALL },
22473                         [ 2] = { REG_UNNEEDED, REGCM_IMMALL },
22474                         [ 3] = { REG_UNNEEDED, REGCM_IMMALL },
22475                         [ 4] = { REG_UNNEEDED, REGCM_IMMALL },
22476                         [ 5] = { REG_UNNEEDED, REGCM_IMMALL },
22477                         [ 6] = { REG_UNNEEDED, REGCM_IMMALL },
22478                         [ 7] = { REG_UNNEEDED, REGCM_IMMALL },
22479                         [ 8] = { REG_UNNEEDED, REGCM_IMMALL },
22480                         [ 9] = { REG_UNNEEDED, REGCM_IMMALL },
22481                         [10] = { REG_UNNEEDED, REGCM_IMMALL },
22482                         [11] = { REG_UNNEEDED, REGCM_IMMALL },
22483                         [12] = { REG_UNNEEDED, REGCM_IMMALL },
22484                         [13] = { REG_UNNEEDED, REGCM_IMMALL },
22485                         [14] = { REG_UNNEEDED, REGCM_IMMALL },
22486                         [15] = { REG_UNNEEDED, REGCM_IMMALL },
22487                         [16] = { REG_UNNEEDED, REGCM_IMMALL },
22488                         [17] = { REG_UNNEEDED, REGCM_IMMALL },
22489                         [18] = { REG_UNNEEDED, REGCM_IMMALL },
22490                         [19] = { REG_UNNEEDED, REGCM_IMMALL },
22491                         [20] = { REG_UNNEEDED, REGCM_IMMALL },
22492                         [21] = { REG_UNNEEDED, REGCM_IMMALL },
22493                         [22] = { REG_UNNEEDED, REGCM_IMMALL },
22494                         [23] = { REG_UNNEEDED, REGCM_IMMALL },
22495                         [24] = { REG_UNNEEDED, REGCM_IMMALL },
22496                         [25] = { REG_UNNEEDED, REGCM_IMMALL },
22497                         [26] = { REG_UNNEEDED, REGCM_IMMALL },
22498                         [27] = { REG_UNNEEDED, REGCM_IMMALL },
22499                         [28] = { REG_UNNEEDED, REGCM_IMMALL },
22500                         [29] = { REG_UNNEEDED, REGCM_IMMALL },
22501                         [30] = { REG_UNNEEDED, REGCM_IMMALL },
22502                         [31] = { REG_UNNEEDED, REGCM_IMMALL },
22503                         [32] = { REG_UNNEEDED, REGCM_IMMALL },
22504                         [33] = { REG_UNNEEDED, REGCM_IMMALL },
22505                         [34] = { REG_UNNEEDED, REGCM_IMMALL },
22506                         [35] = { REG_UNNEEDED, REGCM_IMMALL },
22507                         [36] = { REG_UNNEEDED, REGCM_IMMALL },
22508                         [37] = { REG_UNNEEDED, REGCM_IMMALL },
22509                         [38] = { REG_UNNEEDED, REGCM_IMMALL },
22510                         [39] = { REG_UNNEEDED, REGCM_IMMALL },
22511                         [40] = { REG_UNNEEDED, REGCM_IMMALL },
22512                         [41] = { REG_UNNEEDED, REGCM_IMMALL },
22513                         [42] = { REG_UNNEEDED, REGCM_IMMALL },
22514                         [43] = { REG_UNNEEDED, REGCM_IMMALL },
22515                         [44] = { REG_UNNEEDED, REGCM_IMMALL },
22516                         [45] = { REG_UNNEEDED, REGCM_IMMALL },
22517                         [46] = { REG_UNNEEDED, REGCM_IMMALL },
22518                         [47] = { REG_UNNEEDED, REGCM_IMMALL },
22519                         [48] = { REG_UNNEEDED, REGCM_IMMALL },
22520                         [49] = { REG_UNNEEDED, REGCM_IMMALL },
22521                         [50] = { REG_UNNEEDED, REGCM_IMMALL },
22522                         [51] = { REG_UNNEEDED, REGCM_IMMALL },
22523                         [52] = { REG_UNNEEDED, REGCM_IMMALL },
22524                         [53] = { REG_UNNEEDED, REGCM_IMMALL },
22525                         [54] = { REG_UNNEEDED, REGCM_IMMALL },
22526                         [55] = { REG_UNNEEDED, REGCM_IMMALL },
22527                         [56] = { REG_UNNEEDED, REGCM_IMMALL },
22528                         [57] = { REG_UNNEEDED, REGCM_IMMALL },
22529                         [58] = { REG_UNNEEDED, REGCM_IMMALL },
22530                         [59] = { REG_UNNEEDED, REGCM_IMMALL },
22531                         [60] = { REG_UNNEEDED, REGCM_IMMALL },
22532                         [61] = { REG_UNNEEDED, REGCM_IMMALL },
22533                         [62] = { REG_UNNEEDED, REGCM_IMMALL },
22534                         [63] = { REG_UNNEEDED, REGCM_IMMALL },
22535                 },
22536         },
22537         [TEMPLATE_INTCONST8] = { 
22538                 .lhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
22539         },
22540         [TEMPLATE_INTCONST32] = { 
22541                 .lhs = { [0] = { REG_UNNEEDED, REGCM_IMM32 } },
22542         },
22543         [TEMPLATE_UNKNOWNVAL] = {
22544                 .lhs = { [0] = { REG_UNSET, COPY32_REGCM } },
22545         },
22546         [TEMPLATE_COPY8_REG] = {
22547                 .lhs = { [0] = { REG_UNSET, COPY8_REGCM } },
22548                 .rhs = { [0] = { REG_UNSET, COPY8_REGCM }  },
22549         },
22550         [TEMPLATE_COPY16_REG] = {
22551                 .lhs = { [0] = { REG_UNSET, COPY16_REGCM } },
22552                 .rhs = { [0] = { REG_UNSET, COPY16_REGCM }  },
22553         },
22554         [TEMPLATE_COPY32_REG] = {
22555                 .lhs = { [0] = { REG_UNSET, COPY32_REGCM } },
22556                 .rhs = { [0] = { REG_UNSET, COPY32_REGCM }  },
22557         },
22558         [TEMPLATE_COPY_IMM8] = {
22559                 .lhs = { [0] = { REG_UNSET, COPY8_REGCM } },
22560                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
22561         },
22562         [TEMPLATE_COPY_IMM16] = {
22563                 .lhs = { [0] = { REG_UNSET, COPY16_REGCM } },
22564                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM16 | REGCM_IMM8 } },
22565         },
22566         [TEMPLATE_COPY_IMM32] = {
22567                 .lhs = { [0] = { REG_UNSET, COPY32_REGCM } },
22568                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8 } },
22569         },
22570         [TEMPLATE_PHI8] = { 
22571                 .lhs = { [0] = { REG_VIRT0, COPY8_REGCM } },
22572                 .rhs = { [0] = { REG_VIRT0, COPY8_REGCM } },
22573         },
22574         [TEMPLATE_PHI16] = { 
22575                 .lhs = { [0] = { REG_VIRT0, COPY16_REGCM } },
22576                 .rhs = { [0] = { REG_VIRT0, COPY16_REGCM } }, 
22577         },
22578         [TEMPLATE_PHI32] = { 
22579                 .lhs = { [0] = { REG_VIRT0, COPY32_REGCM } },
22580                 .rhs = { [0] = { REG_VIRT0, COPY32_REGCM } }, 
22581         },
22582         [TEMPLATE_STORE8] = {
22583                 .rhs = { 
22584                         [0] = { REG_UNSET, REGCM_GPR32 },
22585                         [1] = { REG_UNSET, REGCM_GPR8_LO },
22586                 },
22587         },
22588         [TEMPLATE_STORE16] = {
22589                 .rhs = { 
22590                         [0] = { REG_UNSET, REGCM_GPR32 },
22591                         [1] = { REG_UNSET, REGCM_GPR16 },
22592                 },
22593         },
22594         [TEMPLATE_STORE32] = {
22595                 .rhs = { 
22596                         [0] = { REG_UNSET, REGCM_GPR32 },
22597                         [1] = { REG_UNSET, REGCM_GPR32 },
22598                 },
22599         },
22600         [TEMPLATE_LOAD8] = {
22601                 .lhs = { [0] = { REG_UNSET, REGCM_GPR8_LO } },
22602                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
22603         },
22604         [TEMPLATE_LOAD16] = {
22605                 .lhs = { [0] = { REG_UNSET, REGCM_GPR16 } },
22606                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
22607         },
22608         [TEMPLATE_LOAD32] = {
22609                 .lhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
22610                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
22611         },
22612         [TEMPLATE_BINARY8_REG] = {
22613                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
22614                 .rhs = { 
22615                         [0] = { REG_VIRT0, REGCM_GPR8_LO },
22616                         [1] = { REG_UNSET, REGCM_GPR8_LO },
22617                 },
22618         },
22619         [TEMPLATE_BINARY16_REG] = {
22620                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
22621                 .rhs = { 
22622                         [0] = { REG_VIRT0, REGCM_GPR16 },
22623                         [1] = { REG_UNSET, REGCM_GPR16 },
22624                 },
22625         },
22626         [TEMPLATE_BINARY32_REG] = {
22627                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
22628                 .rhs = { 
22629                         [0] = { REG_VIRT0, REGCM_GPR32 },
22630                         [1] = { REG_UNSET, REGCM_GPR32 },
22631                 },
22632         },
22633         [TEMPLATE_BINARY8_IMM] = {
22634                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
22635                 .rhs = { 
22636                         [0] = { REG_VIRT0,    REGCM_GPR8_LO },
22637                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
22638                 },
22639         },
22640         [TEMPLATE_BINARY16_IMM] = {
22641                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
22642                 .rhs = { 
22643                         [0] = { REG_VIRT0,    REGCM_GPR16 },
22644                         [1] = { REG_UNNEEDED, REGCM_IMM16 },
22645                 },
22646         },
22647         [TEMPLATE_BINARY32_IMM] = {
22648                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
22649                 .rhs = { 
22650                         [0] = { REG_VIRT0,    REGCM_GPR32 },
22651                         [1] = { REG_UNNEEDED, REGCM_IMM32 },
22652                 },
22653         },
22654         [TEMPLATE_SL8_CL] = {
22655                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
22656                 .rhs = { 
22657                         [0] = { REG_VIRT0, REGCM_GPR8_LO },
22658                         [1] = { REG_CL, REGCM_GPR8_LO },
22659                 },
22660         },
22661         [TEMPLATE_SL16_CL] = {
22662                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
22663                 .rhs = { 
22664                         [0] = { REG_VIRT0, REGCM_GPR16 },
22665                         [1] = { REG_CL, REGCM_GPR8_LO },
22666                 },
22667         },
22668         [TEMPLATE_SL32_CL] = {
22669                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
22670                 .rhs = { 
22671                         [0] = { REG_VIRT0, REGCM_GPR32 },
22672                         [1] = { REG_CL, REGCM_GPR8_LO },
22673                 },
22674         },
22675         [TEMPLATE_SL8_IMM] = {
22676                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
22677                 .rhs = { 
22678                         [0] = { REG_VIRT0,    REGCM_GPR8_LO },
22679                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
22680                 },
22681         },
22682         [TEMPLATE_SL16_IMM] = {
22683                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
22684                 .rhs = { 
22685                         [0] = { REG_VIRT0,    REGCM_GPR16 },
22686                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
22687                 },
22688         },
22689         [TEMPLATE_SL32_IMM] = {
22690                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
22691                 .rhs = { 
22692                         [0] = { REG_VIRT0,    REGCM_GPR32 },
22693                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
22694                 },
22695         },
22696         [TEMPLATE_UNARY8] = {
22697                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
22698                 .rhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
22699         },
22700         [TEMPLATE_UNARY16] = {
22701                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
22702                 .rhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
22703         },
22704         [TEMPLATE_UNARY32] = {
22705                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
22706                 .rhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
22707         },
22708         [TEMPLATE_CMP8_REG] = {
22709                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22710                 .rhs = {
22711                         [0] = { REG_UNSET, REGCM_GPR8_LO },
22712                         [1] = { REG_UNSET, REGCM_GPR8_LO },
22713                 },
22714         },
22715         [TEMPLATE_CMP16_REG] = {
22716                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22717                 .rhs = {
22718                         [0] = { REG_UNSET, REGCM_GPR16 },
22719                         [1] = { REG_UNSET, REGCM_GPR16 },
22720                 },
22721         },
22722         [TEMPLATE_CMP32_REG] = {
22723                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22724                 .rhs = {
22725                         [0] = { REG_UNSET, REGCM_GPR32 },
22726                         [1] = { REG_UNSET, REGCM_GPR32 },
22727                 },
22728         },
22729         [TEMPLATE_CMP8_IMM] = {
22730                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22731                 .rhs = {
22732                         [0] = { REG_UNSET, REGCM_GPR8_LO },
22733                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
22734                 },
22735         },
22736         [TEMPLATE_CMP16_IMM] = {
22737                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22738                 .rhs = {
22739                         [0] = { REG_UNSET, REGCM_GPR16 },
22740                         [1] = { REG_UNNEEDED, REGCM_IMM16 },
22741                 },
22742         },
22743         [TEMPLATE_CMP32_IMM] = {
22744                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22745                 .rhs = {
22746                         [0] = { REG_UNSET, REGCM_GPR32 },
22747                         [1] = { REG_UNNEEDED, REGCM_IMM32 },
22748                 },
22749         },
22750         [TEMPLATE_TEST8] = {
22751                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22752                 .rhs = { [0] = { REG_UNSET, REGCM_GPR8_LO } },
22753         },
22754         [TEMPLATE_TEST16] = {
22755                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22756                 .rhs = { [0] = { REG_UNSET, REGCM_GPR16 } },
22757         },
22758         [TEMPLATE_TEST32] = {
22759                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22760                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
22761         },
22762         [TEMPLATE_SET] = {
22763                 .lhs = { [0] = { REG_UNSET, REGCM_GPR8_LO } },
22764                 .rhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22765         },
22766         [TEMPLATE_JMP] = {
22767                 .rhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22768         },
22769         [TEMPLATE_RET] = {
22770                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
22771         },
22772         [TEMPLATE_INB_DX] = {
22773                 .lhs = { [0] = { REG_AL,  REGCM_GPR8_LO } },  
22774                 .rhs = { [0] = { REG_DX, REGCM_GPR16 } },
22775         },
22776         [TEMPLATE_INB_IMM] = {
22777                 .lhs = { [0] = { REG_AL,  REGCM_GPR8_LO } },  
22778                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
22779         },
22780         [TEMPLATE_INW_DX]  = { 
22781                 .lhs = { [0] = { REG_AX,  REGCM_GPR16 } }, 
22782                 .rhs = { [0] = { REG_DX, REGCM_GPR16 } },
22783         },
22784         [TEMPLATE_INW_IMM] = { 
22785                 .lhs = { [0] = { REG_AX,  REGCM_GPR16 } }, 
22786                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
22787         },
22788         [TEMPLATE_INL_DX]  = {
22789                 .lhs = { [0] = { REG_EAX, REGCM_GPR32 } },
22790                 .rhs = { [0] = { REG_DX, REGCM_GPR16 } },
22791         },
22792         [TEMPLATE_INL_IMM] = {
22793                 .lhs = { [0] = { REG_EAX, REGCM_GPR32 } },
22794                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
22795         },
22796         [TEMPLATE_OUTB_DX] = { 
22797                 .rhs = {
22798                         [0] = { REG_AL,  REGCM_GPR8_LO },
22799                         [1] = { REG_DX, REGCM_GPR16 },
22800                 },
22801         },
22802         [TEMPLATE_OUTB_IMM] = { 
22803                 .rhs = {
22804                         [0] = { REG_AL,  REGCM_GPR8_LO },  
22805                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
22806                 },
22807         },
22808         [TEMPLATE_OUTW_DX] = { 
22809                 .rhs = {
22810                         [0] = { REG_AX,  REGCM_GPR16 },
22811                         [1] = { REG_DX, REGCM_GPR16 },
22812                 },
22813         },
22814         [TEMPLATE_OUTW_IMM] = {
22815                 .rhs = {
22816                         [0] = { REG_AX,  REGCM_GPR16 }, 
22817                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
22818                 },
22819         },
22820         [TEMPLATE_OUTL_DX] = { 
22821                 .rhs = {
22822                         [0] = { REG_EAX, REGCM_GPR32 },
22823                         [1] = { REG_DX, REGCM_GPR16 },
22824                 },
22825         },
22826         [TEMPLATE_OUTL_IMM] = { 
22827                 .rhs = {
22828                         [0] = { REG_EAX, REGCM_GPR32 }, 
22829                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
22830                 },
22831         },
22832         [TEMPLATE_BSF] = {
22833                 .lhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
22834                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
22835         },
22836         [TEMPLATE_RDMSR] = {
22837                 .lhs = { 
22838                         [0] = { REG_EAX, REGCM_GPR32 },
22839                         [1] = { REG_EDX, REGCM_GPR32 },
22840                 },
22841                 .rhs = { [0] = { REG_ECX, REGCM_GPR32 } },
22842         },
22843         [TEMPLATE_WRMSR] = {
22844                 .rhs = {
22845                         [0] = { REG_ECX, REGCM_GPR32 },
22846                         [1] = { REG_EAX, REGCM_GPR32 },
22847                         [2] = { REG_EDX, REGCM_GPR32 },
22848                 },
22849         },
22850         [TEMPLATE_UMUL8] = {
22851                 .lhs = { [0] = { REG_AX, REGCM_GPR16 } },
22852                 .rhs = { 
22853                         [0] = { REG_AL, REGCM_GPR8_LO },
22854                         [1] = { REG_UNSET, REGCM_GPR8_LO },
22855                 },
22856         },
22857         [TEMPLATE_UMUL16] = {
22858                 .lhs = { [0] = { REG_DXAX, REGCM_DIVIDEND32 } },
22859                 .rhs = { 
22860                         [0] = { REG_AX, REGCM_GPR16 },
22861                         [1] = { REG_UNSET, REGCM_GPR16 },
22862                 },
22863         },
22864         [TEMPLATE_UMUL32] = {
22865                 .lhs = { [0] = { REG_EDXEAX, REGCM_DIVIDEND64 } },
22866                 .rhs = { 
22867                         [0] = { REG_EAX, REGCM_GPR32 },
22868                         [1] = { REG_UNSET, REGCM_GPR32 },
22869                 },
22870         },
22871         [TEMPLATE_DIV8] = {
22872                 .lhs = { 
22873                         [0] = { REG_AL, REGCM_GPR8_LO },
22874                         [1] = { REG_AH, REGCM_GPR8 },
22875                 },
22876                 .rhs = {
22877                         [0] = { REG_AX, REGCM_GPR16 },
22878                         [1] = { REG_UNSET, REGCM_GPR8_LO },
22879                 },
22880         },
22881         [TEMPLATE_DIV16] = {
22882                 .lhs = { 
22883                         [0] = { REG_AX, REGCM_GPR16 },
22884                         [1] = { REG_DX, REGCM_GPR16 },
22885                 },
22886                 .rhs = {
22887                         [0] = { REG_DXAX, REGCM_DIVIDEND32 },
22888                         [1] = { REG_UNSET, REGCM_GPR16 },
22889                 },
22890         },
22891         [TEMPLATE_DIV32] = {
22892                 .lhs = { 
22893                         [0] = { REG_EAX, REGCM_GPR32 },
22894                         [1] = { REG_EDX, REGCM_GPR32 },
22895                 },
22896                 .rhs = {
22897                         [0] = { REG_EDXEAX, REGCM_DIVIDEND64 },
22898                         [1] = { REG_UNSET, REGCM_GPR32 },
22899                 },
22900         },
22901 };
22902
22903 static void fixup_branch(struct compile_state *state,
22904         struct triple *branch, int jmp_op, int cmp_op, struct type *cmp_type,
22905         struct triple *left, struct triple *right)
22906 {
22907         struct triple *test;
22908         if (!left) {
22909                 internal_error(state, branch, "no branch test?");
22910         }
22911         test = pre_triple(state, branch,
22912                 cmp_op, cmp_type, left, right);
22913         test->template_id = TEMPLATE_TEST32; 
22914         if (cmp_op == OP_CMP) {
22915                 test->template_id = TEMPLATE_CMP32_REG;
22916                 if (get_imm32(test, &RHS(test, 1))) {
22917                         test->template_id = TEMPLATE_CMP32_IMM;
22918                 }
22919         }
22920         use_triple(RHS(test, 0), test);
22921         use_triple(RHS(test, 1), test);
22922         unuse_triple(RHS(branch, 0), branch);
22923         RHS(branch, 0) = test;
22924         branch->op = jmp_op;
22925         branch->template_id = TEMPLATE_JMP;
22926         use_triple(RHS(branch, 0), branch);
22927 }
22928
22929 static void fixup_branches(struct compile_state *state,
22930         struct triple *cmp, struct triple *use, int jmp_op)
22931 {
22932         struct triple_set *entry, *next;
22933         for(entry = use->use; entry; entry = next) {
22934                 next = entry->next;
22935                 if (entry->member->op == OP_COPY) {
22936                         fixup_branches(state, cmp, entry->member, jmp_op);
22937                 }
22938                 else if (entry->member->op == OP_CBRANCH) {
22939                         struct triple *branch;
22940                         struct triple *left, *right;
22941                         left = right = 0;
22942                         left = RHS(cmp, 0);
22943                         if (cmp->rhs > 1) {
22944                                 right = RHS(cmp, 1);
22945                         }
22946                         branch = entry->member;
22947                         fixup_branch(state, branch, jmp_op, 
22948                                 cmp->op, cmp->type, left, right);
22949                 }
22950         }
22951 }
22952
22953 static void bool_cmp(struct compile_state *state, 
22954         struct triple *ins, int cmp_op, int jmp_op, int set_op)
22955 {
22956         struct triple_set *entry, *next;
22957         struct triple *set, *convert;
22958
22959         /* Put a barrier up before the cmp which preceeds the
22960          * copy instruction.  If a set actually occurs this gives
22961          * us a chance to move variables in registers out of the way.
22962          */
22963
22964         /* Modify the comparison operator */
22965         ins->op = cmp_op;
22966         ins->template_id = TEMPLATE_TEST32;
22967         if (cmp_op == OP_CMP) {
22968                 ins->template_id = TEMPLATE_CMP32_REG;
22969                 if (get_imm32(ins, &RHS(ins, 1))) {
22970                         ins->template_id =  TEMPLATE_CMP32_IMM;
22971                 }
22972         }
22973         /* Generate the instruction sequence that will transform the
22974          * result of the comparison into a logical value.
22975          */
22976         set = post_triple(state, ins, set_op, &uchar_type, ins, 0);
22977         use_triple(ins, set);
22978         set->template_id = TEMPLATE_SET;
22979
22980         convert = set;
22981         if (!equiv_types(ins->type, set->type)) {
22982                 convert = post_triple(state, set, OP_CONVERT, ins->type, set, 0);
22983                 use_triple(set, convert);
22984                 convert->template_id = TEMPLATE_COPY32_REG;
22985         }
22986
22987         for(entry = ins->use; entry; entry = next) {
22988                 next = entry->next;
22989                 if (entry->member == set) {
22990                         continue;
22991                 }
22992                 replace_rhs_use(state, ins, convert, entry->member);
22993         }
22994         fixup_branches(state, ins, convert, jmp_op);
22995 }
22996
22997 struct reg_info arch_reg_lhs(struct compile_state *state, struct triple *ins, int index)
22998 {
22999         struct ins_template *template;
23000         struct reg_info result;
23001         int zlhs;
23002         if (ins->op == OP_PIECE) {
23003                 index = ins->u.cval;
23004                 ins = MISC(ins, 0);
23005         }
23006         zlhs = ins->lhs;
23007         if (triple_is_def(state, ins)) {
23008                 zlhs = 1;
23009         }
23010         if (index >= zlhs) {
23011                 internal_error(state, ins, "index %d out of range for %s",
23012                         index, tops(ins->op));
23013         }
23014         switch(ins->op) {
23015         case OP_ASM:
23016                 template = &ins->u.ainfo->tmpl;
23017                 break;
23018         default:
23019                 if (ins->template_id > LAST_TEMPLATE) {
23020                         internal_error(state, ins, "bad template number %d", 
23021                                 ins->template_id);
23022                 }
23023                 template = &templates[ins->template_id];
23024                 break;
23025         }
23026         result = template->lhs[index];
23027         result.regcm = arch_regcm_normalize(state, result.regcm);
23028         if (result.reg != REG_UNNEEDED) {
23029                 result.regcm &= ~(REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8);
23030         }
23031         if (result.regcm == 0) {
23032                 internal_error(state, ins, "lhs %d regcm == 0", index);
23033         }
23034         return result;
23035 }
23036
23037 struct reg_info arch_reg_rhs(struct compile_state *state, struct triple *ins, int index)
23038 {
23039         struct reg_info result;
23040         struct ins_template *template;
23041         if ((index > ins->rhs) ||
23042                 (ins->op == OP_PIECE)) {
23043                 internal_error(state, ins, "index %d out of range for %s\n",
23044                         index, tops(ins->op));
23045         }
23046         switch(ins->op) {
23047         case OP_ASM:
23048                 template = &ins->u.ainfo->tmpl;
23049                 break;
23050         case OP_PHI:
23051                 index = 0;
23052                 /* Fall through */
23053         default:
23054                 if (ins->template_id > LAST_TEMPLATE) {
23055                         internal_error(state, ins, "bad template number %d", 
23056                                 ins->template_id);
23057                 }
23058                 template = &templates[ins->template_id];
23059                 break;
23060         }
23061         result = template->rhs[index];
23062         result.regcm = arch_regcm_normalize(state, result.regcm);
23063         if (result.regcm == 0) {
23064                 internal_error(state, ins, "rhs %d regcm == 0", index);
23065         }
23066         return result;
23067 }
23068
23069 static struct triple *mod_div(struct compile_state *state,
23070         struct triple *ins, int div_op, int index)
23071 {
23072         struct triple *div, *piece0, *piece1;
23073         
23074         /* Generate the appropriate division instruction */
23075         div = post_triple(state, ins, div_op, ins->type, 0, 0);
23076         RHS(div, 0) = RHS(ins, 0);
23077         RHS(div, 1) = RHS(ins, 1);
23078         piece0 = LHS(div, 0);
23079         piece1 = LHS(div, 1);
23080         div->template_id  = TEMPLATE_DIV32;
23081         use_triple(RHS(div, 0), div);
23082         use_triple(RHS(div, 1), div);
23083         use_triple(LHS(div, 0), div);
23084         use_triple(LHS(div, 1), div);
23085
23086         /* Replate uses of ins with the appropriate piece of the div */
23087         propogate_use(state, ins, LHS(div, index));
23088         release_triple(state, ins);
23089
23090         /* Return the address of the next instruction */
23091         return piece1->next;
23092 }
23093
23094 static int noop_adecl(struct triple *adecl)
23095 {
23096         struct triple_set *use;
23097         /* It's a noop if it doesn't specify stoorage */
23098         if (adecl->lhs == 0) {
23099                 return 1;
23100         }
23101         /* Is the adecl used? If not it's a noop */
23102         for(use = adecl->use; use ; use = use->next) {
23103                 if ((use->member->op != OP_PIECE) ||
23104                         (MISC(use->member, 0) != adecl)) {
23105                         return 0;
23106                 }
23107         }
23108         return 1;
23109 }
23110
23111 static struct triple *x86_deposit(struct compile_state *state, struct triple *ins)
23112 {
23113         struct triple *mask, *nmask, *shift;
23114         struct triple *val, *val_mask, *val_shift;
23115         struct triple *targ, *targ_mask;
23116         struct triple *new;
23117         ulong_t the_mask, the_nmask;
23118
23119         targ = RHS(ins, 0);
23120         val = RHS(ins, 1);
23121
23122         /* Get constant for the mask value */
23123         the_mask = 1;
23124         the_mask <<= ins->u.bitfield.size;
23125         the_mask -= 1;
23126         the_mask <<= ins->u.bitfield.offset;
23127         mask = pre_triple(state, ins, OP_INTCONST, &uint_type, 0, 0);
23128         mask->u.cval = the_mask;
23129
23130         /* Get the inverted mask value */
23131         the_nmask = ~the_mask;
23132         nmask = pre_triple(state, ins, OP_INTCONST, &uint_type, 0, 0);
23133         nmask->u.cval = the_nmask;
23134
23135         /* Get constant for the shift value */
23136         shift = pre_triple(state, ins, OP_INTCONST, &uint_type, 0, 0);
23137         shift->u.cval = ins->u.bitfield.offset;
23138
23139         /* Shift and mask the source value */
23140         val_shift = val;
23141         if (shift->u.cval != 0) {
23142                 val_shift = pre_triple(state, ins, OP_SL, val->type, val, shift);
23143                 use_triple(val, val_shift);
23144                 use_triple(shift, val_shift);
23145         }
23146         val_mask = val_shift;
23147         if (is_signed(val->type)) {
23148                 val_mask = pre_triple(state, ins, OP_AND, val->type, val_shift, mask);
23149                 use_triple(val_shift, val_mask);
23150                 use_triple(mask, val_mask);
23151         }
23152
23153         /* Mask the target value */
23154         targ_mask = pre_triple(state, ins, OP_AND, targ->type, targ, nmask);
23155         use_triple(targ, targ_mask);
23156         use_triple(nmask, targ_mask);
23157
23158         /* Now combined them together */
23159         new = pre_triple(state, ins, OP_OR, targ->type, targ_mask, val_mask);
23160         use_triple(targ_mask, new);
23161         use_triple(val_mask, new);
23162
23163         /* Move all of the users over to the new expression */
23164         propogate_use(state, ins, new);
23165
23166         /* Delete the original triple */
23167         release_triple(state, ins);
23168
23169         /* Restart the transformation at mask */
23170         return mask;
23171 }
23172
23173 static struct triple *x86_extract(struct compile_state *state, struct triple *ins)
23174 {
23175         struct triple *mask, *shift;
23176         struct triple *val, *val_mask, *val_shift;
23177         ulong_t the_mask;
23178
23179         val = RHS(ins, 0);
23180
23181         /* Get constant for the mask value */
23182         the_mask = 1;
23183         the_mask <<= ins->u.bitfield.size;
23184         the_mask -= 1;
23185         mask = pre_triple(state, ins, OP_INTCONST, &int_type, 0, 0);
23186         mask->u.cval = the_mask;
23187
23188         /* Get constant for the right shift value */
23189         shift = pre_triple(state, ins, OP_INTCONST, &int_type, 0, 0);
23190         shift->u.cval = ins->u.bitfield.offset;
23191
23192         /* Shift arithmetic right, to correct the sign */
23193         val_shift = val;
23194         if (shift->u.cval != 0) {
23195                 int op;
23196                 if (ins->op == OP_SEXTRACT) {
23197                         op = OP_SSR;
23198                 } else {
23199                         op = OP_USR;
23200                 }
23201                 val_shift = pre_triple(state, ins, op, val->type, val, shift);
23202                 use_triple(val, val_shift);
23203                 use_triple(shift, val_shift);
23204         }
23205
23206         /* Finally mask the value */
23207         val_mask = pre_triple(state, ins, OP_AND, ins->type, val_shift, mask);
23208         use_triple(val_shift, val_mask);
23209         use_triple(mask,      val_mask);
23210
23211         /* Move all of the users over to the new expression */
23212         propogate_use(state, ins, val_mask);
23213
23214         /* Release the original instruction */
23215         release_triple(state, ins);
23216
23217         return mask;
23218
23219 }
23220
23221 static struct triple *transform_to_arch_instruction(
23222         struct compile_state *state, struct triple *ins)
23223 {
23224         /* Transform from generic 3 address instructions
23225          * to archtecture specific instructions.
23226          * And apply architecture specific constraints to instructions.
23227          * Copies are inserted to preserve the register flexibility
23228          * of 3 address instructions.
23229          */
23230         struct triple *next, *value;
23231         size_t size;
23232         next = ins->next;
23233         switch(ins->op) {
23234         case OP_INTCONST:
23235                 ins->template_id = TEMPLATE_INTCONST32;
23236                 if (ins->u.cval < 256) {
23237                         ins->template_id = TEMPLATE_INTCONST8;
23238                 }
23239                 break;
23240         case OP_ADDRCONST:
23241                 ins->template_id = TEMPLATE_INTCONST32;
23242                 break;
23243         case OP_UNKNOWNVAL:
23244                 ins->template_id = TEMPLATE_UNKNOWNVAL;
23245                 break;
23246         case OP_NOOP:
23247         case OP_SDECL:
23248         case OP_BLOBCONST:
23249         case OP_LABEL:
23250                 ins->template_id = TEMPLATE_NOP;
23251                 break;
23252         case OP_COPY:
23253         case OP_CONVERT:
23254                 size = size_of(state, ins->type);
23255                 value = RHS(ins, 0);
23256                 if (is_imm8(value) && (size <= SIZEOF_I8)) {
23257                         ins->template_id = TEMPLATE_COPY_IMM8;
23258                 }
23259                 else if (is_imm16(value) && (size <= SIZEOF_I16)) {
23260                         ins->template_id = TEMPLATE_COPY_IMM16;
23261                 }
23262                 else if (is_imm32(value) && (size <= SIZEOF_I32)) {
23263                         ins->template_id = TEMPLATE_COPY_IMM32;
23264                 }
23265                 else if (is_const(value)) {
23266                         internal_error(state, ins, "bad constant passed to copy");
23267                 }
23268                 else if (size <= SIZEOF_I8) {
23269                         ins->template_id = TEMPLATE_COPY8_REG;
23270                 }
23271                 else if (size <= SIZEOF_I16) {
23272                         ins->template_id = TEMPLATE_COPY16_REG;
23273                 }
23274                 else if (size <= SIZEOF_I32) {
23275                         ins->template_id = TEMPLATE_COPY32_REG;
23276                 }
23277                 else {
23278                         internal_error(state, ins, "bad type passed to copy");
23279                 }
23280                 break;
23281         case OP_PHI:
23282                 size = size_of(state, ins->type);
23283                 if (size <= SIZEOF_I8) {
23284                         ins->template_id = TEMPLATE_PHI8;
23285                 }
23286                 else if (size <= SIZEOF_I16) {
23287                         ins->template_id = TEMPLATE_PHI16;
23288                 }
23289                 else if (size <= SIZEOF_I32) {
23290                         ins->template_id = TEMPLATE_PHI32;
23291                 }
23292                 else {
23293                         internal_error(state, ins, "bad type passed to phi");
23294                 }
23295                 break;
23296         case OP_ADECL:
23297                 /* Adecls should always be treated as dead code and
23298                  * removed.  If we are not optimizing they may linger.
23299                  */
23300                 if (!noop_adecl(ins)) {
23301                         internal_error(state, ins, "adecl remains?");
23302                 }
23303                 ins->template_id = TEMPLATE_NOP;
23304                 next = after_lhs(state, ins);
23305                 break;
23306         case OP_STORE:
23307                 switch(ins->type->type & TYPE_MASK) {
23308                 case TYPE_CHAR:    case TYPE_UCHAR:
23309                         ins->template_id = TEMPLATE_STORE8;
23310                         break;
23311                 case TYPE_SHORT:   case TYPE_USHORT:
23312                         ins->template_id = TEMPLATE_STORE16;
23313                         break;
23314                 case TYPE_INT:     case TYPE_UINT:
23315                 case TYPE_LONG:    case TYPE_ULONG:
23316                 case TYPE_POINTER:
23317                         ins->template_id = TEMPLATE_STORE32;
23318                         break;
23319                 default:
23320                         internal_error(state, ins, "unknown type in store");
23321                         break;
23322                 }
23323                 break;
23324         case OP_LOAD:
23325                 switch(ins->type->type & TYPE_MASK) {
23326                 case TYPE_CHAR:   case TYPE_UCHAR:
23327                 case TYPE_SHORT:  case TYPE_USHORT:
23328                 case TYPE_INT:    case TYPE_UINT:
23329                 case TYPE_LONG:   case TYPE_ULONG:
23330                 case TYPE_POINTER:
23331                         break;
23332                 default:
23333                         internal_error(state, ins, "unknown type in load");
23334                         break;
23335                 }
23336                 ins->template_id = TEMPLATE_LOAD32;
23337                 break;
23338         case OP_ADD:
23339         case OP_SUB:
23340         case OP_AND:
23341         case OP_XOR:
23342         case OP_OR:
23343         case OP_SMUL:
23344                 ins->template_id = TEMPLATE_BINARY32_REG;
23345                 if (get_imm32(ins, &RHS(ins, 1))) {
23346                         ins->template_id = TEMPLATE_BINARY32_IMM;
23347                 }
23348                 break;
23349         case OP_SDIVT:
23350         case OP_UDIVT:
23351                 ins->template_id = TEMPLATE_DIV32;
23352                 next = after_lhs(state, ins);
23353                 break;
23354         case OP_UMUL:
23355                 ins->template_id = TEMPLATE_UMUL32;
23356                 break;
23357         case OP_UDIV:
23358                 next = mod_div(state, ins, OP_UDIVT, 0);
23359                 break;
23360         case OP_SDIV:
23361                 next = mod_div(state, ins, OP_SDIVT, 0);
23362                 break;
23363         case OP_UMOD:
23364                 next = mod_div(state, ins, OP_UDIVT, 1);
23365                 break;
23366         case OP_SMOD:
23367                 next = mod_div(state, ins, OP_SDIVT, 1);
23368                 break;
23369         case OP_SL:
23370         case OP_SSR:
23371         case OP_USR:
23372                 ins->template_id = TEMPLATE_SL32_CL;
23373                 if (get_imm8(ins, &RHS(ins, 1))) {
23374                         ins->template_id = TEMPLATE_SL32_IMM;
23375                 } else if (size_of(state, RHS(ins, 1)->type) > SIZEOF_CHAR) {
23376                         typed_pre_copy(state, &uchar_type, ins, 1);
23377                 }
23378                 break;
23379         case OP_INVERT:
23380         case OP_NEG:
23381                 ins->template_id = TEMPLATE_UNARY32;
23382                 break;
23383         case OP_EQ: 
23384                 bool_cmp(state, ins, OP_CMP, OP_JMP_EQ, OP_SET_EQ); 
23385                 break;
23386         case OP_NOTEQ:
23387                 bool_cmp(state, ins, OP_CMP, OP_JMP_NOTEQ, OP_SET_NOTEQ);
23388                 break;
23389         case OP_SLESS:
23390                 bool_cmp(state, ins, OP_CMP, OP_JMP_SLESS, OP_SET_SLESS);
23391                 break;
23392         case OP_ULESS:
23393                 bool_cmp(state, ins, OP_CMP, OP_JMP_ULESS, OP_SET_ULESS);
23394                 break;
23395         case OP_SMORE:
23396                 bool_cmp(state, ins, OP_CMP, OP_JMP_SMORE, OP_SET_SMORE);
23397                 break;
23398         case OP_UMORE:
23399                 bool_cmp(state, ins, OP_CMP, OP_JMP_UMORE, OP_SET_UMORE);
23400                 break;
23401         case OP_SLESSEQ:
23402                 bool_cmp(state, ins, OP_CMP, OP_JMP_SLESSEQ, OP_SET_SLESSEQ);
23403                 break;
23404         case OP_ULESSEQ:
23405                 bool_cmp(state, ins, OP_CMP, OP_JMP_ULESSEQ, OP_SET_ULESSEQ);
23406                 break;
23407         case OP_SMOREEQ:
23408                 bool_cmp(state, ins, OP_CMP, OP_JMP_SMOREEQ, OP_SET_SMOREEQ);
23409                 break;
23410         case OP_UMOREEQ:
23411                 bool_cmp(state, ins, OP_CMP, OP_JMP_UMOREEQ, OP_SET_UMOREEQ);
23412                 break;
23413         case OP_LTRUE:
23414                 bool_cmp(state, ins, OP_TEST, OP_JMP_NOTEQ, OP_SET_NOTEQ);
23415                 break;
23416         case OP_LFALSE:
23417                 bool_cmp(state, ins, OP_TEST, OP_JMP_EQ, OP_SET_EQ);
23418                 break;
23419         case OP_BRANCH:
23420                 ins->op = OP_JMP;
23421                 ins->template_id = TEMPLATE_NOP;
23422                 break;
23423         case OP_CBRANCH:
23424                 fixup_branch(state, ins, OP_JMP_NOTEQ, OP_TEST, 
23425                         RHS(ins, 0)->type, RHS(ins, 0), 0);
23426                 break;
23427         case OP_CALL:
23428                 ins->template_id = TEMPLATE_NOP;
23429                 break;
23430         case OP_RET:
23431                 ins->template_id = TEMPLATE_RET;
23432                 break;
23433         case OP_INB:
23434         case OP_INW:
23435         case OP_INL:
23436                 switch(ins->op) {
23437                 case OP_INB: ins->template_id = TEMPLATE_INB_DX; break;
23438                 case OP_INW: ins->template_id = TEMPLATE_INW_DX; break;
23439                 case OP_INL: ins->template_id = TEMPLATE_INL_DX; break;
23440                 }
23441                 if (get_imm8(ins, &RHS(ins, 0))) {
23442                         ins->template_id += 1;
23443                 }
23444                 break;
23445         case OP_OUTB:
23446         case OP_OUTW:
23447         case OP_OUTL:
23448                 switch(ins->op) {
23449                 case OP_OUTB: ins->template_id = TEMPLATE_OUTB_DX; break;
23450                 case OP_OUTW: ins->template_id = TEMPLATE_OUTW_DX; break;
23451                 case OP_OUTL: ins->template_id = TEMPLATE_OUTL_DX; break;
23452                 }
23453                 if (get_imm8(ins, &RHS(ins, 1))) {
23454                         ins->template_id += 1;
23455                 }
23456                 break;
23457         case OP_BSF:
23458         case OP_BSR:
23459                 ins->template_id = TEMPLATE_BSF;
23460                 break;
23461         case OP_RDMSR:
23462                 ins->template_id = TEMPLATE_RDMSR;
23463                 next = after_lhs(state, ins);
23464                 break;
23465         case OP_WRMSR:
23466                 ins->template_id = TEMPLATE_WRMSR;
23467                 break;
23468         case OP_HLT:
23469                 ins->template_id = TEMPLATE_NOP;
23470                 break;
23471         case OP_ASM:
23472                 ins->template_id = TEMPLATE_NOP;
23473                 next = after_lhs(state, ins);
23474                 break;
23475                 /* Already transformed instructions */
23476         case OP_TEST:
23477                 ins->template_id = TEMPLATE_TEST32;
23478                 break;
23479         case OP_CMP:
23480                 ins->template_id = TEMPLATE_CMP32_REG;
23481                 if (get_imm32(ins, &RHS(ins, 1))) {
23482                         ins->template_id = TEMPLATE_CMP32_IMM;
23483                 }
23484                 break;
23485         case OP_JMP:
23486                 ins->template_id = TEMPLATE_NOP;
23487                 break;
23488         case OP_JMP_EQ:      case OP_JMP_NOTEQ:
23489         case OP_JMP_SLESS:   case OP_JMP_ULESS:
23490         case OP_JMP_SMORE:   case OP_JMP_UMORE:
23491         case OP_JMP_SLESSEQ: case OP_JMP_ULESSEQ:
23492         case OP_JMP_SMOREEQ: case OP_JMP_UMOREEQ:
23493                 ins->template_id = TEMPLATE_JMP;
23494                 break;
23495         case OP_SET_EQ:      case OP_SET_NOTEQ:
23496         case OP_SET_SLESS:   case OP_SET_ULESS:
23497         case OP_SET_SMORE:   case OP_SET_UMORE:
23498         case OP_SET_SLESSEQ: case OP_SET_ULESSEQ:
23499         case OP_SET_SMOREEQ: case OP_SET_UMOREEQ:
23500                 ins->template_id = TEMPLATE_SET;
23501                 break;
23502         case OP_DEPOSIT:
23503                 next = x86_deposit(state, ins);
23504                 break;
23505         case OP_SEXTRACT:
23506         case OP_UEXTRACT:
23507                 next = x86_extract(state, ins);
23508                 break;
23509                 /* Unhandled instructions */
23510         case OP_PIECE:
23511         default:
23512                 internal_error(state, ins, "unhandled ins: %d %s",
23513                         ins->op, tops(ins->op));
23514                 break;
23515         }
23516         return next;
23517 }
23518
23519 static long next_label(struct compile_state *state)
23520 {
23521         static long label_counter = 1000;
23522         return ++label_counter;
23523 }
23524 static void generate_local_labels(struct compile_state *state)
23525 {
23526         struct triple *first, *label;
23527         first = state->first;
23528         label = first;
23529         do {
23530                 if ((label->op == OP_LABEL) || 
23531                         (label->op == OP_SDECL)) {
23532                         if (label->use) {
23533                                 label->u.cval = next_label(state);
23534                         } else {
23535                                 label->u.cval = 0;
23536                         }
23537                         
23538                 }
23539                 label = label->next;
23540         } while(label != first);
23541 }
23542
23543 static int check_reg(struct compile_state *state, 
23544         struct triple *triple, int classes)
23545 {
23546         unsigned mask;
23547         int reg;
23548         reg = ID_REG(triple->id);
23549         if (reg == REG_UNSET) {
23550                 internal_error(state, triple, "register not set");
23551         }
23552         mask = arch_reg_regcm(state, reg);
23553         if (!(classes & mask)) {
23554                 internal_error(state, triple, "reg %d in wrong class",
23555                         reg);
23556         }
23557         return reg;
23558 }
23559
23560
23561 #if REG_XMM7 != 44
23562 #error "Registers have renumberd fix arch_reg_str"
23563 #endif
23564 static const char *arch_regs[] = {
23565         "%unset",
23566         "%unneeded",
23567         "%eflags",
23568         "%al", "%bl", "%cl", "%dl", "%ah", "%bh", "%ch", "%dh",
23569         "%ax", "%bx", "%cx", "%dx", "%si", "%di", "%bp", "%sp",
23570         "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi", "%ebp", "%esp",
23571         "%edx:%eax",
23572         "%dx:%ax",
23573         "%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7",
23574         "%xmm0", "%xmm1", "%xmm2", "%xmm3", 
23575         "%xmm4", "%xmm5", "%xmm6", "%xmm7",
23576 };
23577 static const char *arch_reg_str(int reg)
23578 {
23579         if (!((reg >= REG_EFLAGS) && (reg <= REG_XMM7))) {
23580                 reg = 0;
23581         }
23582         return arch_regs[reg];
23583 }
23584
23585 static const char *reg(struct compile_state *state, struct triple *triple,
23586         int classes)
23587 {
23588         int reg;
23589         reg = check_reg(state, triple, classes);
23590         return arch_reg_str(reg);
23591 }
23592
23593 static int arch_reg_size(int reg)
23594 {
23595         int size;
23596         size = 0;
23597         if (reg == REG_EFLAGS) {
23598                 size = 32;
23599         }
23600         else if ((reg >= REG_AL) && (reg <= REG_DH)) {
23601                 size = 8;
23602         }
23603         else if ((reg >= REG_AX) && (reg <= REG_SP)) {
23604                 size = 16;
23605         }
23606         else if ((reg >= REG_EAX) && (reg <= REG_ESP)) {
23607                 size = 32;
23608         }
23609         else if (reg == REG_EDXEAX) {
23610                 size = 64;
23611         }
23612         else if (reg == REG_DXAX) {
23613                 size = 32;
23614         }
23615         else if ((reg >= REG_MMX0) && (reg <= REG_MMX7)) {
23616                 size = 64;
23617         }
23618         else if ((reg >= REG_XMM0) && (reg <= REG_XMM7)) {
23619                 size = 128;
23620         }
23621         return size;
23622 }
23623
23624 static int reg_size(struct compile_state *state, struct triple *ins)
23625 {
23626         int reg;
23627         reg = ID_REG(ins->id);
23628         if (reg == REG_UNSET) {
23629                 internal_error(state, ins, "register not set");
23630         }
23631         return arch_reg_size(reg);
23632 }
23633         
23634
23635
23636 const char *type_suffix(struct compile_state *state, struct type *type)
23637 {
23638         const char *suffix;
23639         switch(size_of(state, type)) {
23640         case SIZEOF_I8:  suffix = "b"; break;
23641         case SIZEOF_I16: suffix = "w"; break;
23642         case SIZEOF_I32: suffix = "l"; break;
23643         default:
23644                 internal_error(state, 0, "unknown suffix");
23645                 suffix = 0;
23646                 break;
23647         }
23648         return suffix;
23649 }
23650
23651 static void print_const_val(
23652         struct compile_state *state, struct triple *ins, FILE *fp)
23653 {
23654         switch(ins->op) {
23655         case OP_INTCONST:
23656                 fprintf(fp, " $%ld ", 
23657                         (long)(ins->u.cval));
23658                 break;
23659         case OP_ADDRCONST:
23660                 if ((MISC(ins, 0)->op != OP_SDECL) &&
23661                         (MISC(ins, 0)->op != OP_LABEL))
23662                 {
23663                         internal_error(state, ins, "bad base for addrconst");
23664                 }
23665                 if (MISC(ins, 0)->u.cval <= 0) {
23666                         internal_error(state, ins, "unlabeled constant");
23667                 }
23668                 fprintf(fp, " $L%s%lu+%lu ",
23669                         state->compiler->label_prefix, 
23670                         (unsigned long)(MISC(ins, 0)->u.cval),
23671                         (unsigned long)(ins->u.cval));
23672                 break;
23673         default:
23674                 internal_error(state, ins, "unknown constant type");
23675                 break;
23676         }
23677 }
23678
23679 static void print_const(struct compile_state *state,
23680         struct triple *ins, FILE *fp)
23681 {
23682         switch(ins->op) {
23683         case OP_INTCONST:
23684                 switch(ins->type->type & TYPE_MASK) {
23685                 case TYPE_CHAR:
23686                 case TYPE_UCHAR:
23687                         fprintf(fp, ".byte 0x%02lx\n", 
23688                                 (unsigned long)(ins->u.cval));
23689                         break;
23690                 case TYPE_SHORT:
23691                 case TYPE_USHORT:
23692                         fprintf(fp, ".short 0x%04lx\n", 
23693                                 (unsigned long)(ins->u.cval));
23694                         break;
23695                 case TYPE_INT:
23696                 case TYPE_UINT:
23697                 case TYPE_LONG:
23698                 case TYPE_ULONG:
23699                 case TYPE_POINTER:
23700                         fprintf(fp, ".int %lu\n", 
23701                                 (unsigned long)(ins->u.cval));
23702                         break;
23703                 default:
23704                         fprintf(state->errout, "type: ");
23705                         name_of(state->errout, ins->type);
23706                         fprintf(state->errout, "\n");
23707                         internal_error(state, ins, "Unknown constant type. Val: %lu",
23708                                 (unsigned long)(ins->u.cval));
23709                 }
23710                 
23711                 break;
23712         case OP_ADDRCONST:
23713                 if ((MISC(ins, 0)->op != OP_SDECL) &&
23714                         (MISC(ins, 0)->op != OP_LABEL)) {
23715                         internal_error(state, ins, "bad base for addrconst");
23716                 }
23717                 if (MISC(ins, 0)->u.cval <= 0) {
23718                         internal_error(state, ins, "unlabeled constant");
23719                 }
23720                 fprintf(fp, ".int L%s%lu+%lu\n",
23721                         state->compiler->label_prefix,
23722                         (unsigned long)(MISC(ins, 0)->u.cval),
23723                         (unsigned long)(ins->u.cval));
23724                 break;
23725         case OP_BLOBCONST:
23726         {
23727                 unsigned char *blob;
23728                 size_t size, i;
23729                 size = size_of_in_bytes(state, ins->type);
23730                 blob = ins->u.blob;
23731                 for(i = 0; i < size; i++) {
23732                         fprintf(fp, ".byte 0x%02x\n",
23733                                 blob[i]);
23734                 }
23735                 break;
23736         }
23737         default:
23738                 internal_error(state, ins, "Unknown constant type");
23739                 break;
23740         }
23741 }
23742
23743 #define TEXT_SECTION ".rom.text"
23744 #define DATA_SECTION ".rom.data"
23745
23746 static long get_const_pool_ref(
23747         struct compile_state *state, struct triple *ins, size_t size, FILE *fp)
23748 {
23749         size_t fill_bytes;
23750         long ref;
23751         ref = next_label(state);
23752         fprintf(fp, ".section \"" DATA_SECTION "\"\n");
23753         fprintf(fp, ".balign %d\n", align_of_in_bytes(state, ins->type));
23754         fprintf(fp, "L%s%lu:\n", state->compiler->label_prefix, ref);
23755         print_const(state, ins, fp);
23756         fill_bytes = bits_to_bytes(size - size_of(state, ins->type));
23757         if (fill_bytes) {
23758                 fprintf(fp, ".fill %d, 1, 0\n", fill_bytes);
23759         }
23760         fprintf(fp, ".section \"" TEXT_SECTION "\"\n");
23761         return ref;
23762 }
23763
23764 static long get_mask_pool_ref(
23765         struct compile_state *state, struct triple *ins, unsigned long mask, FILE *fp)
23766 {
23767         long ref;
23768         if (mask == 0xff) {
23769                 ref = 1;
23770         }
23771         else if (mask == 0xffff) {
23772                 ref = 2;
23773         }
23774         else {
23775                 ref = 0;
23776                 internal_error(state, ins, "unhandled mask value");
23777         }
23778         return ref;
23779 }
23780
23781 static void print_binary_op(struct compile_state *state,
23782         const char *op, struct triple *ins, FILE *fp) 
23783 {
23784         unsigned mask;
23785         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO;
23786         if (ID_REG(RHS(ins, 0)->id) != ID_REG(ins->id)) {
23787                 internal_error(state, ins, "invalid register assignment");
23788         }
23789         if (is_const(RHS(ins, 1))) {
23790                 fprintf(fp, "\t%s ", op);
23791                 print_const_val(state, RHS(ins, 1), fp);
23792                 fprintf(fp, ", %s\n",
23793                         reg(state, RHS(ins, 0), mask));
23794         }
23795         else {
23796                 unsigned lmask, rmask;
23797                 int lreg, rreg;
23798                 lreg = check_reg(state, RHS(ins, 0), mask);
23799                 rreg = check_reg(state, RHS(ins, 1), mask);
23800                 lmask = arch_reg_regcm(state, lreg);
23801                 rmask = arch_reg_regcm(state, rreg);
23802                 mask = lmask & rmask;
23803                 fprintf(fp, "\t%s %s, %s\n",
23804                         op,
23805                         reg(state, RHS(ins, 1), mask),
23806                         reg(state, RHS(ins, 0), mask));
23807         }
23808 }
23809 static void print_unary_op(struct compile_state *state, 
23810         const char *op, struct triple *ins, FILE *fp)
23811 {
23812         unsigned mask;
23813         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO;
23814         fprintf(fp, "\t%s %s\n",
23815                 op,
23816                 reg(state, RHS(ins, 0), mask));
23817 }
23818
23819 static void print_op_shift(struct compile_state *state,
23820         const char *op, struct triple *ins, FILE *fp)
23821 {
23822         unsigned mask;
23823         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO;
23824         if (ID_REG(RHS(ins, 0)->id) != ID_REG(ins->id)) {
23825                 internal_error(state, ins, "invalid register assignment");
23826         }
23827         if (is_const(RHS(ins, 1))) {
23828                 fprintf(fp, "\t%s ", op);
23829                 print_const_val(state, RHS(ins, 1), fp);
23830                 fprintf(fp, ", %s\n",
23831                         reg(state, RHS(ins, 0), mask));
23832         }
23833         else {
23834                 fprintf(fp, "\t%s %s, %s\n",
23835                         op,
23836                         reg(state, RHS(ins, 1), REGCM_GPR8_LO),
23837                         reg(state, RHS(ins, 0), mask));
23838         }
23839 }
23840
23841 static void print_op_in(struct compile_state *state, struct triple *ins, FILE *fp)
23842 {
23843         const char *op;
23844         int mask;
23845         int dreg;
23846         mask = 0;
23847         switch(ins->op) {
23848         case OP_INB: op = "inb", mask = REGCM_GPR8_LO; break;
23849         case OP_INW: op = "inw", mask = REGCM_GPR16; break;
23850         case OP_INL: op = "inl", mask = REGCM_GPR32; break;
23851         default:
23852                 internal_error(state, ins, "not an in operation");
23853                 op = 0;
23854                 break;
23855         }
23856         dreg = check_reg(state, ins, mask);
23857         if (!reg_is_reg(state, dreg, REG_EAX)) {
23858                 internal_error(state, ins, "dst != %%eax");
23859         }
23860         if (is_const(RHS(ins, 0))) {
23861                 fprintf(fp, "\t%s ", op);
23862                 print_const_val(state, RHS(ins, 0), fp);
23863                 fprintf(fp, ", %s\n",
23864                         reg(state, ins, mask));
23865         }
23866         else {
23867                 int addr_reg;
23868                 addr_reg = check_reg(state, RHS(ins, 0), REGCM_GPR16);
23869                 if (!reg_is_reg(state, addr_reg, REG_DX)) {
23870                         internal_error(state, ins, "src != %%dx");
23871                 }
23872                 fprintf(fp, "\t%s %s, %s\n",
23873                         op, 
23874                         reg(state, RHS(ins, 0), REGCM_GPR16),
23875                         reg(state, ins, mask));
23876         }
23877 }
23878
23879 static void print_op_out(struct compile_state *state, struct triple *ins, FILE *fp)
23880 {
23881         const char *op;
23882         int mask;
23883         int lreg;
23884         mask = 0;
23885         switch(ins->op) {
23886         case OP_OUTB: op = "outb", mask = REGCM_GPR8_LO; break;
23887         case OP_OUTW: op = "outw", mask = REGCM_GPR16; break;
23888         case OP_OUTL: op = "outl", mask = REGCM_GPR32; break;
23889         default:
23890                 internal_error(state, ins, "not an out operation");
23891                 op = 0;
23892                 break;
23893         }
23894         lreg = check_reg(state, RHS(ins, 0), mask);
23895         if (!reg_is_reg(state, lreg, REG_EAX)) {
23896                 internal_error(state, ins, "src != %%eax");
23897         }
23898         if (is_const(RHS(ins, 1))) {
23899                 fprintf(fp, "\t%s %s,", 
23900                         op, reg(state, RHS(ins, 0), mask));
23901                 print_const_val(state, RHS(ins, 1), fp);
23902                 fprintf(fp, "\n");
23903         }
23904         else {
23905                 int addr_reg;
23906                 addr_reg = check_reg(state, RHS(ins, 1), REGCM_GPR16);
23907                 if (!reg_is_reg(state, addr_reg, REG_DX)) {
23908                         internal_error(state, ins, "dst != %%dx");
23909                 }
23910                 fprintf(fp, "\t%s %s, %s\n",
23911                         op, 
23912                         reg(state, RHS(ins, 0), mask),
23913                         reg(state, RHS(ins, 1), REGCM_GPR16));
23914         }
23915 }
23916
23917 static void print_op_move(struct compile_state *state,
23918         struct triple *ins, FILE *fp)
23919 {
23920         /* op_move is complex because there are many types
23921          * of registers we can move between.
23922          * Because OP_COPY will be introduced in arbitrary locations
23923          * OP_COPY must not affect flags.
23924          * OP_CONVERT can change the flags and it is the only operation
23925          * where it is expected the types in the registers can change.
23926          */
23927         int omit_copy = 1; /* Is it o.k. to omit a noop copy? */
23928         struct triple *dst, *src;
23929         if (state->arch->features & X86_NOOP_COPY) {
23930                 omit_copy = 0;
23931         }
23932         if ((ins->op == OP_COPY) || (ins->op == OP_CONVERT)) {
23933                 src = RHS(ins, 0);
23934                 dst = ins;
23935         }
23936         else {
23937                 internal_error(state, ins, "unknown move operation");
23938                 src = dst = 0;
23939         }
23940         if (reg_size(state, dst) < size_of(state, dst->type)) {
23941                 internal_error(state, ins, "Invalid destination register");
23942         }
23943         if (!equiv_types(src->type, dst->type) && (dst->op == OP_COPY)) {
23944                 fprintf(state->errout, "src type: ");
23945                 name_of(state->errout, src->type);
23946                 fprintf(state->errout, "\n");
23947                 fprintf(state->errout, "dst type: ");
23948                 name_of(state->errout, dst->type);
23949                 fprintf(state->errout, "\n");
23950                 internal_error(state, ins, "Type mismatch for OP_COPY");
23951         }
23952
23953         if (!is_const(src)) {
23954                 int src_reg, dst_reg;
23955                 int src_regcm, dst_regcm;
23956                 src_reg   = ID_REG(src->id);
23957                 dst_reg   = ID_REG(dst->id);
23958                 src_regcm = arch_reg_regcm(state, src_reg);
23959                 dst_regcm = arch_reg_regcm(state, dst_reg);
23960                 /* If the class is the same just move the register */
23961                 if (src_regcm & dst_regcm & 
23962                         (REGCM_GPR8_LO | REGCM_GPR16 | REGCM_GPR32)) {
23963                         if ((src_reg != dst_reg) || !omit_copy) {
23964                                 fprintf(fp, "\tmov %s, %s\n",
23965                                         reg(state, src, src_regcm),
23966                                         reg(state, dst, dst_regcm));
23967                         }
23968                 }
23969                 /* Move 32bit to 16bit */
23970                 else if ((src_regcm & REGCM_GPR32) &&
23971                         (dst_regcm & REGCM_GPR16)) {
23972                         src_reg = (src_reg - REGC_GPR32_FIRST) + REGC_GPR16_FIRST;
23973                         if ((src_reg != dst_reg) || !omit_copy) {
23974                                 fprintf(fp, "\tmovw %s, %s\n",
23975                                         arch_reg_str(src_reg), 
23976                                         arch_reg_str(dst_reg));
23977                         }
23978                 }
23979                 /* Move from 32bit gprs to 16bit gprs */
23980                 else if ((src_regcm & REGCM_GPR32) &&
23981                         (dst_regcm & REGCM_GPR16)) {
23982                         dst_reg = (dst_reg - REGC_GPR16_FIRST) + REGC_GPR32_FIRST;
23983                         if ((src_reg != dst_reg) || !omit_copy) {
23984                                 fprintf(fp, "\tmov %s, %s\n",
23985                                         arch_reg_str(src_reg),
23986                                         arch_reg_str(dst_reg));
23987                         }
23988                 }
23989                 /* Move 32bit to 8bit */
23990                 else if ((src_regcm & REGCM_GPR32_8) &&
23991                         (dst_regcm & REGCM_GPR8_LO))
23992                 {
23993                         src_reg = (src_reg - REGC_GPR32_8_FIRST) + REGC_GPR8_FIRST;
23994                         if ((src_reg != dst_reg) || !omit_copy) {
23995                                 fprintf(fp, "\tmovb %s, %s\n",
23996                                         arch_reg_str(src_reg),
23997                                         arch_reg_str(dst_reg));
23998                         }
23999                 }
24000                 /* Move 16bit to 8bit */
24001                 else if ((src_regcm & REGCM_GPR16_8) &&
24002                         (dst_regcm & REGCM_GPR8_LO))
24003                 {
24004                         src_reg = (src_reg - REGC_GPR16_8_FIRST) + REGC_GPR8_FIRST;
24005                         if ((src_reg != dst_reg) || !omit_copy) {
24006                                 fprintf(fp, "\tmovb %s, %s\n",
24007                                         arch_reg_str(src_reg),
24008                                         arch_reg_str(dst_reg));
24009                         }
24010                 }
24011                 /* Move 8/16bit to 16/32bit */
24012                 else if ((src_regcm & (REGCM_GPR8_LO | REGCM_GPR16)) && 
24013                         (dst_regcm & (REGCM_GPR16 | REGCM_GPR32))) {
24014                         const char *op;
24015                         op = is_signed(src->type)? "movsx": "movzx";
24016                         fprintf(fp, "\t%s %s, %s\n",
24017                                 op,
24018                                 reg(state, src, src_regcm),
24019                                 reg(state, dst, dst_regcm));
24020                 }
24021                 /* Move between sse registers */
24022                 else if ((src_regcm & dst_regcm & REGCM_XMM)) {
24023                         if ((src_reg != dst_reg) || !omit_copy) {
24024                                 fprintf(fp, "\tmovdqa %s, %s\n",
24025                                         reg(state, src, src_regcm),
24026                                         reg(state, dst, dst_regcm));
24027                         }
24028                 }
24029                 /* Move between mmx registers */
24030                 else if ((src_regcm & dst_regcm & REGCM_MMX)) {
24031                         if ((src_reg != dst_reg) || !omit_copy) {
24032                                 fprintf(fp, "\tmovq %s, %s\n",
24033                                         reg(state, src, src_regcm),
24034                                         reg(state, dst, dst_regcm));
24035                         }
24036                 }
24037                 /* Move from sse to mmx registers */
24038                 else if ((src_regcm & REGCM_XMM) && (dst_regcm & REGCM_MMX)) {
24039                         fprintf(fp, "\tmovdq2q %s, %s\n",
24040                                 reg(state, src, src_regcm),
24041                                 reg(state, dst, dst_regcm));
24042                 }
24043                 /* Move from mmx to sse registers */
24044                 else if ((src_regcm & REGCM_MMX) && (dst_regcm & REGCM_XMM)) {
24045                         fprintf(fp, "\tmovq2dq %s, %s\n",
24046                                 reg(state, src, src_regcm),
24047                                 reg(state, dst, dst_regcm));
24048                 }
24049                 /* Move between 32bit gprs & mmx/sse registers */
24050                 else if ((src_regcm & (REGCM_GPR32 | REGCM_MMX | REGCM_XMM)) &&
24051                         (dst_regcm & (REGCM_GPR32 | REGCM_MMX | REGCM_XMM))) {
24052                         fprintf(fp, "\tmovd %s, %s\n",
24053                                 reg(state, src, src_regcm),
24054                                 reg(state, dst, dst_regcm));
24055                 }
24056                 /* Move from 16bit gprs &  mmx/sse registers */
24057                 else if ((src_regcm & REGCM_GPR16) &&
24058                         (dst_regcm & (REGCM_MMX | REGCM_XMM))) {
24059                         const char *op;
24060                         int mid_reg;
24061                         op = is_signed(src->type)? "movsx":"movzx";
24062                         mid_reg = (src_reg - REGC_GPR16_FIRST) + REGC_GPR32_FIRST;
24063                         fprintf(fp, "\t%s %s, %s\n\tmovd %s, %s\n",
24064                                 op,
24065                                 arch_reg_str(src_reg),
24066                                 arch_reg_str(mid_reg),
24067                                 arch_reg_str(mid_reg),
24068                                 arch_reg_str(dst_reg));
24069                 }
24070                 /* Move from mmx/sse registers to 16bit gprs */
24071                 else if ((src_regcm & (REGCM_MMX | REGCM_XMM)) &&
24072                         (dst_regcm & REGCM_GPR16)) {
24073                         dst_reg = (dst_reg - REGC_GPR16_FIRST) + REGC_GPR32_FIRST;
24074                         fprintf(fp, "\tmovd %s, %s\n",
24075                                 arch_reg_str(src_reg),
24076                                 arch_reg_str(dst_reg));
24077                 }
24078                 /* Move from gpr to 64bit dividend */
24079                 else if ((src_regcm & (REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO))  &&
24080                         (dst_regcm & REGCM_DIVIDEND64)) {
24081                         const char *extend;
24082                         extend = is_signed(src->type)? "cltd":"movl $0, %edx";
24083                         fprintf(fp, "\tmov %s, %%eax\n\t%s\n",
24084                                 arch_reg_str(src_reg), 
24085                                 extend);
24086                 }
24087                 /* Move from 64bit gpr to gpr */
24088                 else if ((src_regcm & REGCM_DIVIDEND64) &&
24089                         (dst_regcm & (REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO))) {
24090                         if (dst_regcm & REGCM_GPR32) {
24091                                 src_reg = REG_EAX;
24092                         } 
24093                         else if (dst_regcm & REGCM_GPR16) {
24094                                 src_reg = REG_AX;
24095                         }
24096                         else if (dst_regcm & REGCM_GPR8_LO) {
24097                                 src_reg = REG_AL;
24098                         }
24099                         fprintf(fp, "\tmov %s, %s\n",
24100                                 arch_reg_str(src_reg),
24101                                 arch_reg_str(dst_reg));
24102                 }
24103                 /* Move from mmx/sse registers to 64bit gpr */
24104                 else if ((src_regcm & (REGCM_MMX | REGCM_XMM)) &&
24105                         (dst_regcm & REGCM_DIVIDEND64)) {
24106                         const char *extend;
24107                         extend = is_signed(src->type)? "cltd": "movl $0, %edx";
24108                         fprintf(fp, "\tmovd %s, %%eax\n\t%s\n",
24109                                 arch_reg_str(src_reg),
24110                                 extend);
24111                 }
24112                 /* Move from 64bit gpr to mmx/sse register */
24113                 else if ((src_regcm & REGCM_DIVIDEND64) &&
24114                         (dst_regcm & (REGCM_XMM | REGCM_MMX))) {
24115                         fprintf(fp, "\tmovd %%eax, %s\n",
24116                                 arch_reg_str(dst_reg));
24117                 }
24118 #if X86_4_8BIT_GPRS
24119                 /* Move from 8bit gprs to  mmx/sse registers */
24120                 else if ((src_regcm & REGCM_GPR8_LO) && (src_reg <= REG_DL) &&
24121                         (dst_regcm & (REGCM_MMX | REGCM_XMM))) {
24122                         const char *op;
24123                         int mid_reg;
24124                         op = is_signed(src->type)? "movsx":"movzx";
24125                         mid_reg = (src_reg - REGC_GPR8_FIRST) + REGC_GPR32_FIRST;
24126                         fprintf(fp, "\t%s %s, %s\n\tmovd %s, %s\n",
24127                                 op,
24128                                 reg(state, src, src_regcm),
24129                                 arch_reg_str(mid_reg),
24130                                 arch_reg_str(mid_reg),
24131                                 reg(state, dst, dst_regcm));
24132                 }
24133                 /* Move from mmx/sse registers and 8bit gprs */
24134                 else if ((src_regcm & (REGCM_MMX | REGCM_XMM)) &&
24135                         (dst_regcm & REGCM_GPR8_LO) && (dst_reg <= REG_DL)) {
24136                         int mid_reg;
24137                         mid_reg = (dst_reg - REGC_GPR8_FIRST) + REGC_GPR32_FIRST;
24138                         fprintf(fp, "\tmovd %s, %s\n",
24139                                 reg(state, src, src_regcm),
24140                                 arch_reg_str(mid_reg));
24141                 }
24142                 /* Move from 32bit gprs to 8bit gprs */
24143                 else if ((src_regcm & REGCM_GPR32) &&
24144                         (dst_regcm & REGCM_GPR8_LO)) {
24145                         dst_reg = (dst_reg - REGC_GPR8_FIRST) + REGC_GPR32_FIRST;
24146                         if ((src_reg != dst_reg) || !omit_copy) {
24147                                 fprintf(fp, "\tmov %s, %s\n",
24148                                         arch_reg_str(src_reg),
24149                                         arch_reg_str(dst_reg));
24150                         }
24151                 }
24152                 /* Move from 16bit gprs to 8bit gprs */
24153                 else if ((src_regcm & REGCM_GPR16) &&
24154                         (dst_regcm & REGCM_GPR8_LO)) {
24155                         dst_reg = (dst_reg - REGC_GPR8_FIRST) + REGC_GPR16_FIRST;
24156                         if ((src_reg != dst_reg) || !omit_copy) {
24157                                 fprintf(fp, "\tmov %s, %s\n",
24158                                         arch_reg_str(src_reg),
24159                                         arch_reg_str(dst_reg));
24160                         }
24161                 }
24162 #endif /* X86_4_8BIT_GPRS */
24163                 /* Move from %eax:%edx to %eax:%edx */
24164                 else if ((src_regcm & REGCM_DIVIDEND64) &&
24165                         (dst_regcm & REGCM_DIVIDEND64) &&
24166                         (src_reg == dst_reg)) {
24167                         if (!omit_copy) {
24168                                 fprintf(fp, "\t/*mov %s, %s*/\n",
24169                                         arch_reg_str(src_reg),
24170                                         arch_reg_str(dst_reg));
24171                         }
24172                 }
24173                 else {
24174                         if ((src_regcm & ~REGCM_FLAGS) == 0) {
24175                                 internal_error(state, ins, "attempt to copy from %%eflags!");
24176                         }
24177                         internal_error(state, ins, "unknown copy type");
24178                 }
24179         }
24180         else {
24181                 size_t dst_size;
24182                 int dst_reg;
24183                 int dst_regcm;
24184                 dst_size = size_of(state, dst->type);
24185                 dst_reg = ID_REG(dst->id);
24186                 dst_regcm = arch_reg_regcm(state, dst_reg);
24187                 if (dst_regcm & (REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO)) {
24188                         fprintf(fp, "\tmov ");
24189                         print_const_val(state, src, fp);
24190                         fprintf(fp, ", %s\n",
24191                                 reg(state, dst, REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO));
24192                 }
24193                 else if (dst_regcm & REGCM_DIVIDEND64) {
24194                         if (dst_size > SIZEOF_I32) {
24195                                 internal_error(state, ins, "%dbit constant...", dst_size);
24196                         }
24197                         fprintf(fp, "\tmov $0, %%edx\n");
24198                         fprintf(fp, "\tmov ");
24199                         print_const_val(state, src, fp);
24200                         fprintf(fp, ", %%eax\n");
24201                 }
24202                 else if (dst_regcm & REGCM_DIVIDEND32) {
24203                         if (dst_size > SIZEOF_I16) {
24204                                 internal_error(state, ins, "%dbit constant...", dst_size);
24205                         }
24206                         fprintf(fp, "\tmov $0, %%dx\n");
24207                         fprintf(fp, "\tmov ");
24208                         print_const_val(state, src, fp);
24209                         fprintf(fp, ", %%ax");
24210                 }
24211                 else if (dst_regcm & (REGCM_XMM | REGCM_MMX)) {
24212                         long ref;
24213                         if (dst_size > SIZEOF_I32) {
24214                                 internal_error(state, ins, "%d bit constant...", dst_size);
24215                         }
24216                         ref = get_const_pool_ref(state, src, SIZEOF_I32, fp);
24217                         fprintf(fp, "\tmovd L%s%lu, %s\n",
24218                                 state->compiler->label_prefix, ref,
24219                                 reg(state, dst, (REGCM_XMM | REGCM_MMX)));
24220                 }
24221                 else {
24222                         internal_error(state, ins, "unknown copy immediate type");
24223                 }
24224         }
24225         /* Leave now if this is not a type conversion */
24226         if (ins->op != OP_CONVERT) {
24227                 return;
24228         }
24229         /* Now make certain I have not logically overflowed the destination */
24230         if ((size_of(state, src->type) > size_of(state, dst->type)) &&
24231                 (size_of(state, dst->type) < reg_size(state, dst)))
24232         {
24233                 unsigned long mask;
24234                 int dst_reg;
24235                 int dst_regcm;
24236                 if (size_of(state, dst->type) >= 32) {
24237                         fprintf(state->errout, "dst type: ");
24238                         name_of(state->errout, dst->type);
24239                         fprintf(state->errout, "\n");
24240                         internal_error(state, dst, "unhandled dst type size");
24241                 }
24242                 mask = 1;
24243                 mask <<= size_of(state, dst->type);
24244                 mask -= 1;
24245
24246                 dst_reg = ID_REG(dst->id);
24247                 dst_regcm = arch_reg_regcm(state, dst_reg);
24248
24249                 if (dst_regcm & (REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO)) {
24250                         fprintf(fp, "\tand $0x%lx, %s\n",
24251                                 mask, reg(state, dst, REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO));
24252                 }
24253                 else if (dst_regcm & REGCM_MMX) {
24254                         long ref;
24255                         ref = get_mask_pool_ref(state, dst, mask, fp);
24256                         fprintf(fp, "\tpand L%s%lu, %s\n",
24257                                 state->compiler->label_prefix, ref,
24258                                 reg(state, dst, REGCM_MMX));
24259                 }
24260                 else if (dst_regcm & REGCM_XMM) {
24261                         long ref;
24262                         ref = get_mask_pool_ref(state, dst, mask, fp);
24263                         fprintf(fp, "\tpand L%s%lu, %s\n",
24264                                 state->compiler->label_prefix, ref,
24265                                 reg(state, dst, REGCM_XMM));
24266                 }
24267                 else {
24268                         fprintf(state->errout, "dst type: ");
24269                         name_of(state->errout, dst->type);
24270                         fprintf(state->errout, "\n");
24271                         fprintf(state->errout, "dst: %s\n", reg(state, dst, REGCM_ALL));
24272                         internal_error(state, dst, "failed to trunc value: mask %lx", mask);
24273                 }
24274         }
24275         /* Make certain I am properly sign extended */
24276         if ((size_of(state, src->type) < size_of(state, dst->type)) &&
24277                 (is_signed(src->type)))
24278         {
24279                 int bits, reg_bits, shift_bits;
24280                 int dst_reg;
24281                 int dst_regcm;
24282
24283                 bits = size_of(state, src->type);
24284                 reg_bits = reg_size(state, dst);
24285                 if (reg_bits > 32) {
24286                         reg_bits = 32;
24287                 }
24288                 shift_bits = reg_bits - size_of(state, src->type);
24289                 dst_reg = ID_REG(dst->id);
24290                 dst_regcm = arch_reg_regcm(state, dst_reg);
24291
24292                 if (shift_bits < 0) {
24293                         internal_error(state, dst, "negative shift?");
24294                 }
24295
24296                 if (dst_regcm & (REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO)) {
24297                         fprintf(fp, "\tshl $%d, %s\n", 
24298                                 shift_bits, 
24299                                 reg(state, dst, REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO));
24300                         fprintf(fp, "\tsar $%d, %s\n", 
24301                                 shift_bits, 
24302                                 reg(state, dst, REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO));
24303                 }
24304                 else if (dst_regcm & (REGCM_MMX | REGCM_XMM)) {
24305                         fprintf(fp, "\tpslld $%d, %s\n",
24306                                 shift_bits, 
24307                                 reg(state, dst, REGCM_MMX | REGCM_XMM));
24308                         fprintf(fp, "\tpsrad $%d, %s\n",
24309                                 shift_bits, 
24310                                 reg(state, dst, REGCM_MMX | REGCM_XMM));
24311                 }
24312                 else {
24313                         fprintf(state->errout, "dst type: ");
24314                         name_of(state->errout, dst->type);
24315                         fprintf(state->errout, "\n");
24316                         fprintf(state->errout, "dst: %s\n", reg(state, dst, REGCM_ALL));
24317                         internal_error(state, dst, "failed to signed extend value");
24318                 }
24319         }
24320 }
24321
24322 static void print_op_load(struct compile_state *state,
24323         struct triple *ins, FILE *fp)
24324 {
24325         struct triple *dst, *src;
24326         const char *op;
24327         dst = ins;
24328         src = RHS(ins, 0);
24329         if (is_const(src) || is_const(dst)) {
24330                 internal_error(state, ins, "unknown load operation");
24331         }
24332         switch(ins->type->type & TYPE_MASK) {
24333         case TYPE_CHAR:   op = "movsbl"; break;
24334         case TYPE_UCHAR:  op = "movzbl"; break;
24335         case TYPE_SHORT:  op = "movswl"; break;
24336         case TYPE_USHORT: op = "movzwl"; break;
24337         case TYPE_INT:    case TYPE_UINT:
24338         case TYPE_LONG:   case TYPE_ULONG:
24339         case TYPE_POINTER:
24340                 op = "movl"; 
24341                 break;
24342         default:
24343                 internal_error(state, ins, "unknown type in load");
24344                 op = "<invalid opcode>";
24345                 break;
24346         }
24347         fprintf(fp, "\t%s (%s), %s\n",
24348                 op, 
24349                 reg(state, src, REGCM_GPR32),
24350                 reg(state, dst, REGCM_GPR32));
24351 }
24352
24353
24354 static void print_op_store(struct compile_state *state,
24355         struct triple *ins, FILE *fp)
24356 {
24357         struct triple *dst, *src;
24358         dst = RHS(ins, 0);
24359         src = RHS(ins, 1);
24360         if (is_const(src) && (src->op == OP_INTCONST)) {
24361                 long_t value;
24362                 value = (long_t)(src->u.cval);
24363                 fprintf(fp, "\tmov%s $%ld, (%s)\n",
24364                         type_suffix(state, src->type),
24365                         (long)(value),
24366                         reg(state, dst, REGCM_GPR32));
24367         }
24368         else if (is_const(dst) && (dst->op == OP_INTCONST)) {
24369                 fprintf(fp, "\tmov%s %s, 0x%08lx\n",
24370                         type_suffix(state, src->type),
24371                         reg(state, src, REGCM_GPR8_LO | REGCM_GPR16 | REGCM_GPR32),
24372                         (unsigned long)(dst->u.cval));
24373         }
24374         else {
24375                 if (is_const(src) || is_const(dst)) {
24376                         internal_error(state, ins, "unknown store operation");
24377                 }
24378                 fprintf(fp, "\tmov%s %s, (%s)\n",
24379                         type_suffix(state, src->type),
24380                         reg(state, src, REGCM_GPR8_LO | REGCM_GPR16 | REGCM_GPR32),
24381                         reg(state, dst, REGCM_GPR32));
24382         }
24383         
24384         
24385 }
24386
24387 static void print_op_smul(struct compile_state *state,
24388         struct triple *ins, FILE *fp)
24389 {
24390         if (!is_const(RHS(ins, 1))) {
24391                 fprintf(fp, "\timul %s, %s\n",
24392                         reg(state, RHS(ins, 1), REGCM_GPR32),
24393                         reg(state, RHS(ins, 0), REGCM_GPR32));
24394         }
24395         else {
24396                 fprintf(fp, "\timul ");
24397                 print_const_val(state, RHS(ins, 1), fp);
24398                 fprintf(fp, ", %s\n", reg(state, RHS(ins, 0), REGCM_GPR32));
24399         }
24400 }
24401
24402 static void print_op_cmp(struct compile_state *state,
24403         struct triple *ins, FILE *fp)
24404 {
24405         unsigned mask;
24406         int dreg;
24407         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO;
24408         dreg = check_reg(state, ins, REGCM_FLAGS);
24409         if (!reg_is_reg(state, dreg, REG_EFLAGS)) {
24410                 internal_error(state, ins, "bad dest register for cmp");
24411         }
24412         if (is_const(RHS(ins, 1))) {
24413                 fprintf(fp, "\tcmp ");
24414                 print_const_val(state, RHS(ins, 1), fp);
24415                 fprintf(fp, ", %s\n", reg(state, RHS(ins, 0), mask));
24416         }
24417         else {
24418                 unsigned lmask, rmask;
24419                 int lreg, rreg;
24420                 lreg = check_reg(state, RHS(ins, 0), mask);
24421                 rreg = check_reg(state, RHS(ins, 1), mask);
24422                 lmask = arch_reg_regcm(state, lreg);
24423                 rmask = arch_reg_regcm(state, rreg);
24424                 mask = lmask & rmask;
24425                 fprintf(fp, "\tcmp %s, %s\n",
24426                         reg(state, RHS(ins, 1), mask),
24427                         reg(state, RHS(ins, 0), mask));
24428         }
24429 }
24430
24431 static void print_op_test(struct compile_state *state,
24432         struct triple *ins, FILE *fp)
24433 {
24434         unsigned mask;
24435         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO;
24436         fprintf(fp, "\ttest %s, %s\n",
24437                 reg(state, RHS(ins, 0), mask),
24438                 reg(state, RHS(ins, 0), mask));
24439 }
24440
24441 static void print_op_branch(struct compile_state *state,
24442         struct triple *branch, FILE *fp)
24443 {
24444         const char *bop = "j";
24445         if ((branch->op == OP_JMP) || (branch->op == OP_CALL)) {
24446                 if (branch->rhs != 0) {
24447                         internal_error(state, branch, "jmp with condition?");
24448                 }
24449                 bop = "jmp";
24450         }
24451         else {
24452                 struct triple *ptr;
24453                 if (branch->rhs != 1) {
24454                         internal_error(state, branch, "jmpcc without condition?");
24455                 }
24456                 check_reg(state, RHS(branch, 0), REGCM_FLAGS);
24457                 if ((RHS(branch, 0)->op != OP_CMP) &&
24458                         (RHS(branch, 0)->op != OP_TEST)) {
24459                         internal_error(state, branch, "bad branch test");
24460                 }
24461 #warning "FIXME I have observed instructions between the test and branch instructions"
24462                 ptr = RHS(branch, 0);
24463                 for(ptr = RHS(branch, 0)->next; ptr != branch; ptr = ptr->next) {
24464                         if (ptr->op != OP_COPY) {
24465                                 internal_error(state, branch, "branch does not follow test");
24466                         }
24467                 }
24468                 switch(branch->op) {
24469                 case OP_JMP_EQ:       bop = "jz";  break;
24470                 case OP_JMP_NOTEQ:    bop = "jnz"; break;
24471                 case OP_JMP_SLESS:    bop = "jl";  break;
24472                 case OP_JMP_ULESS:    bop = "jb";  break;
24473                 case OP_JMP_SMORE:    bop = "jg";  break;
24474                 case OP_JMP_UMORE:    bop = "ja";  break;
24475                 case OP_JMP_SLESSEQ:  bop = "jle"; break;
24476                 case OP_JMP_ULESSEQ:  bop = "jbe"; break;
24477                 case OP_JMP_SMOREEQ:  bop = "jge"; break;
24478                 case OP_JMP_UMOREEQ:  bop = "jae"; break;
24479                 default:
24480                         internal_error(state, branch, "Invalid branch op");
24481                         break;
24482                 }
24483                 
24484         }
24485 #if 1
24486         if (branch->op == OP_CALL) {
24487                 fprintf(fp, "\t/* call */\n");
24488         }
24489 #endif
24490         fprintf(fp, "\t%s L%s%lu\n",
24491                 bop, 
24492                 state->compiler->label_prefix,
24493                 (unsigned long)(TARG(branch, 0)->u.cval));
24494 }
24495
24496 static void print_op_ret(struct compile_state *state,
24497         struct triple *branch, FILE *fp)
24498 {
24499         fprintf(fp, "\tjmp *%s\n",
24500                 reg(state, RHS(branch, 0), REGCM_GPR32));
24501 }
24502
24503 static void print_op_set(struct compile_state *state,
24504         struct triple *set, FILE *fp)
24505 {
24506         const char *sop = "set";
24507         if (set->rhs != 1) {
24508                 internal_error(state, set, "setcc without condition?");
24509         }
24510         check_reg(state, RHS(set, 0), REGCM_FLAGS);
24511         if ((RHS(set, 0)->op != OP_CMP) &&
24512                 (RHS(set, 0)->op != OP_TEST)) {
24513                 internal_error(state, set, "bad set test");
24514         }
24515         if (RHS(set, 0)->next != set) {
24516                 internal_error(state, set, "set does not follow test");
24517         }
24518         switch(set->op) {
24519         case OP_SET_EQ:       sop = "setz";  break;
24520         case OP_SET_NOTEQ:    sop = "setnz"; break;
24521         case OP_SET_SLESS:    sop = "setl";  break;
24522         case OP_SET_ULESS:    sop = "setb";  break;
24523         case OP_SET_SMORE:    sop = "setg";  break;
24524         case OP_SET_UMORE:    sop = "seta";  break;
24525         case OP_SET_SLESSEQ:  sop = "setle"; break;
24526         case OP_SET_ULESSEQ:  sop = "setbe"; break;
24527         case OP_SET_SMOREEQ:  sop = "setge"; break;
24528         case OP_SET_UMOREEQ:  sop = "setae"; break;
24529         default:
24530                 internal_error(state, set, "Invalid set op");
24531                 break;
24532         }
24533         fprintf(fp, "\t%s %s\n",
24534                 sop, reg(state, set, REGCM_GPR8_LO));
24535 }
24536
24537 static void print_op_bit_scan(struct compile_state *state, 
24538         struct triple *ins, FILE *fp) 
24539 {
24540         const char *op;
24541         switch(ins->op) {
24542         case OP_BSF: op = "bsf"; break;
24543         case OP_BSR: op = "bsr"; break;
24544         default: 
24545                 internal_error(state, ins, "unknown bit scan");
24546                 op = 0;
24547                 break;
24548         }
24549         fprintf(fp, 
24550                 "\t%s %s, %s\n"
24551                 "\tjnz 1f\n"
24552                 "\tmovl $-1, %s\n"
24553                 "1:\n",
24554                 op,
24555                 reg(state, RHS(ins, 0), REGCM_GPR32),
24556                 reg(state, ins, REGCM_GPR32),
24557                 reg(state, ins, REGCM_GPR32));
24558 }
24559
24560
24561 static void print_sdecl(struct compile_state *state,
24562         struct triple *ins, FILE *fp)
24563 {
24564         fprintf(fp, ".section \"" DATA_SECTION "\"\n");
24565         fprintf(fp, ".balign %d\n", align_of_in_bytes(state, ins->type));
24566         fprintf(fp, "L%s%lu:\n", 
24567                 state->compiler->label_prefix, (unsigned long)(ins->u.cval));
24568         print_const(state, MISC(ins, 0), fp);
24569         fprintf(fp, ".section \"" TEXT_SECTION "\"\n");
24570                 
24571 }
24572
24573 static void print_instruction(struct compile_state *state,
24574         struct triple *ins, FILE *fp)
24575 {
24576         /* Assumption: after I have exted the register allocator
24577          * everything is in a valid register. 
24578          */
24579         switch(ins->op) {
24580         case OP_ASM:
24581                 print_op_asm(state, ins, fp);
24582                 break;
24583         case OP_ADD:    print_binary_op(state, "add", ins, fp); break;
24584         case OP_SUB:    print_binary_op(state, "sub", ins, fp); break;
24585         case OP_AND:    print_binary_op(state, "and", ins, fp); break;
24586         case OP_XOR:    print_binary_op(state, "xor", ins, fp); break;
24587         case OP_OR:     print_binary_op(state, "or",  ins, fp); break;
24588         case OP_SL:     print_op_shift(state, "shl", ins, fp); break;
24589         case OP_USR:    print_op_shift(state, "shr", ins, fp); break;
24590         case OP_SSR:    print_op_shift(state, "sar", ins, fp); break;
24591         case OP_POS:    break;
24592         case OP_NEG:    print_unary_op(state, "neg", ins, fp); break;
24593         case OP_INVERT: print_unary_op(state, "not", ins, fp); break;
24594         case OP_NOOP:
24595         case OP_INTCONST:
24596         case OP_ADDRCONST:
24597         case OP_BLOBCONST:
24598                 /* Don't generate anything here for constants */
24599         case OP_PHI:
24600                 /* Don't generate anything for variable declarations. */
24601                 break;
24602         case OP_UNKNOWNVAL:
24603                 fprintf(fp, " /* unknown %s */\n",
24604                         reg(state, ins, REGCM_ALL));
24605                 break;
24606         case OP_SDECL:
24607                 print_sdecl(state, ins, fp);
24608                 break;
24609         case OP_COPY:   
24610         case OP_CONVERT:
24611                 print_op_move(state, ins, fp);
24612                 break;
24613         case OP_LOAD:
24614                 print_op_load(state, ins, fp);
24615                 break;
24616         case OP_STORE:
24617                 print_op_store(state, ins, fp);
24618                 break;
24619         case OP_SMUL:
24620                 print_op_smul(state, ins, fp);
24621                 break;
24622         case OP_CMP:    print_op_cmp(state, ins, fp); break;
24623         case OP_TEST:   print_op_test(state, ins, fp); break;
24624         case OP_JMP:
24625         case OP_JMP_EQ:      case OP_JMP_NOTEQ:
24626         case OP_JMP_SLESS:   case OP_JMP_ULESS:
24627         case OP_JMP_SMORE:   case OP_JMP_UMORE:
24628         case OP_JMP_SLESSEQ: case OP_JMP_ULESSEQ:
24629         case OP_JMP_SMOREEQ: case OP_JMP_UMOREEQ:
24630         case OP_CALL:
24631                 print_op_branch(state, ins, fp);
24632                 break;
24633         case OP_RET:
24634                 print_op_ret(state, ins, fp);
24635                 break;
24636         case OP_SET_EQ:      case OP_SET_NOTEQ:
24637         case OP_SET_SLESS:   case OP_SET_ULESS:
24638         case OP_SET_SMORE:   case OP_SET_UMORE:
24639         case OP_SET_SLESSEQ: case OP_SET_ULESSEQ:
24640         case OP_SET_SMOREEQ: case OP_SET_UMOREEQ:
24641                 print_op_set(state, ins, fp);
24642                 break;
24643         case OP_INB:  case OP_INW:  case OP_INL:
24644                 print_op_in(state, ins, fp); 
24645                 break;
24646         case OP_OUTB: case OP_OUTW: case OP_OUTL:
24647                 print_op_out(state, ins, fp); 
24648                 break;
24649         case OP_BSF:
24650         case OP_BSR:
24651                 print_op_bit_scan(state, ins, fp);
24652                 break;
24653         case OP_RDMSR:
24654                 after_lhs(state, ins);
24655                 fprintf(fp, "\trdmsr\n");
24656                 break;
24657         case OP_WRMSR:
24658                 fprintf(fp, "\twrmsr\n");
24659                 break;
24660         case OP_HLT:
24661                 fprintf(fp, "\thlt\n");
24662                 break;
24663         case OP_SDIVT:
24664                 fprintf(fp, "\tidiv %s\n", reg(state, RHS(ins, 1), REGCM_GPR32));
24665                 break;
24666         case OP_UDIVT:
24667                 fprintf(fp, "\tdiv %s\n", reg(state, RHS(ins, 1), REGCM_GPR32));
24668                 break;
24669         case OP_UMUL:
24670                 fprintf(fp, "\tmul %s\n", reg(state, RHS(ins, 1), REGCM_GPR32));
24671                 break;
24672         case OP_LABEL:
24673                 if (!ins->use) {
24674                         return;
24675                 }
24676                 fprintf(fp, "L%s%lu:\n", 
24677                         state->compiler->label_prefix, (unsigned long)(ins->u.cval));
24678                 break;
24679         case OP_ADECL:
24680                 /* Ignore adecls with no registers error otherwise */
24681                 if (!noop_adecl(ins)) {
24682                         internal_error(state, ins, "adecl remains?");
24683                 }
24684                 break;
24685                 /* Ignore OP_PIECE */
24686         case OP_PIECE:
24687                 break;
24688                 /* Operations that should never get here */
24689         case OP_SDIV: case OP_UDIV:
24690         case OP_SMOD: case OP_UMOD:
24691         case OP_LTRUE:   case OP_LFALSE:  case OP_EQ:      case OP_NOTEQ:
24692         case OP_SLESS:   case OP_ULESS:   case OP_SMORE:   case OP_UMORE:
24693         case OP_SLESSEQ: case OP_ULESSEQ: case OP_SMOREEQ: case OP_UMOREEQ:
24694         default:
24695                 internal_error(state, ins, "unknown op: %d %s",
24696                         ins->op, tops(ins->op));
24697                 break;
24698         }
24699 }
24700
24701 static void print_instructions(struct compile_state *state)
24702 {
24703         struct triple *first, *ins;
24704         int print_location;
24705         struct occurance *last_occurance;
24706         FILE *fp;
24707         int max_inline_depth;
24708         max_inline_depth = 0;
24709         print_location = 1;
24710         last_occurance = 0;
24711         fp = state->output;
24712         /* Masks for common sizes */
24713         fprintf(fp, ".section \"" DATA_SECTION "\"\n");
24714         fprintf(fp, ".balign 16\n");
24715         fprintf(fp, "L%s1:\n", state->compiler->label_prefix);
24716         fprintf(fp, ".int 0xff, 0, 0, 0\n");
24717         fprintf(fp, "L%s2:\n", state->compiler->label_prefix);
24718         fprintf(fp, ".int 0xffff, 0, 0, 0\n");
24719         fprintf(fp, ".section \"" TEXT_SECTION "\"\n");
24720         first = state->first;
24721         ins = first;
24722         do {
24723                 if (print_location && 
24724                         last_occurance != ins->occurance) {
24725                         if (!ins->occurance->parent) {
24726                                 fprintf(fp, "\t/* %s,%s:%d.%d */\n",
24727                                         ins->occurance->function,
24728                                         ins->occurance->filename,
24729                                         ins->occurance->line,
24730                                         ins->occurance->col);
24731                         }
24732                         else {
24733                                 struct occurance *ptr;
24734                                 int inline_depth;
24735                                 fprintf(fp, "\t/*\n");
24736                                 inline_depth = 0;
24737                                 for(ptr = ins->occurance; ptr; ptr = ptr->parent) {
24738                                         inline_depth++;
24739                                         fprintf(fp, "\t * %s,%s:%d.%d\n",
24740                                                 ptr->function,
24741                                                 ptr->filename,
24742                                                 ptr->line,
24743                                                 ptr->col);
24744                                 }
24745                                 fprintf(fp, "\t */\n");
24746                                 if (inline_depth > max_inline_depth) {
24747                                         max_inline_depth = inline_depth;
24748                                 }
24749                         }
24750                         if (last_occurance) {
24751                                 put_occurance(last_occurance);
24752                         }
24753                         get_occurance(ins->occurance);
24754                         last_occurance = ins->occurance;
24755                 }
24756
24757                 print_instruction(state, ins, fp);
24758                 ins = ins->next;
24759         } while(ins != first);
24760         if (print_location) {
24761                 fprintf(fp, "/* max inline depth %d */\n",
24762                         max_inline_depth);
24763         }
24764 }
24765
24766 static void generate_code(struct compile_state *state)
24767 {
24768         generate_local_labels(state);
24769         print_instructions(state);
24770         
24771 }
24772
24773 static void print_preprocessed_tokens(struct compile_state *state)
24774 {
24775         int tok;
24776         FILE *fp;
24777         int line;
24778         const char *filename;
24779         fp = state->output;
24780         filename = 0;
24781         line = 0;
24782         for(;;) {
24783                 struct file_state *file;
24784                 struct token *tk;
24785                 const char *token_str;
24786                 tok = peek(state);
24787                 if (tok == TOK_EOF) {
24788                         break;
24789                 }
24790                 tk = eat(state, tok);
24791                 token_str = 
24792                         tk->ident ? tk->ident->name :
24793                         tk->str_len ? tk->val.str :
24794                         tokens[tk->tok];
24795
24796                 file = state->file;
24797                 while(file->macro && file->prev) {
24798                         file = file->prev;
24799                 }
24800                 if (!file->macro && 
24801                         ((file->line != line) || (file->basename != filename))) 
24802                 {
24803                         int i, col;
24804                         if ((file->basename == filename) &&
24805                                 (line < file->line)) {
24806                                 while(line < file->line) {
24807                                         fprintf(fp, "\n");
24808                                         line++;
24809                                 }
24810                         }
24811                         else {
24812                                 fprintf(fp, "\n#line %d \"%s\"\n",
24813                                         file->line, file->basename);
24814                         }
24815                         line = file->line;
24816                         filename = file->basename;
24817                         col = get_col(file) - strlen(token_str);
24818                         for(i = 0; i < col; i++) {
24819                                 fprintf(fp, " ");
24820                         }
24821                 }
24822                 
24823                 fprintf(fp, "%s ", token_str);
24824                 
24825                 if (state->compiler->debug & DEBUG_TOKENS) {
24826                         loc(state->dbgout, state, 0);
24827                         fprintf(state->dbgout, "%s <- `%s'\n",
24828                                 tokens[tok], token_str);
24829                 }
24830         }
24831 }
24832
24833 static void compile(const char *filename, 
24834         struct compiler_state *compiler, struct arch_state *arch)
24835 {
24836         int i;
24837         struct compile_state state;
24838         struct triple *ptr;
24839         memset(&state, 0, sizeof(state));
24840         state.compiler = compiler;
24841         state.arch     = arch;
24842         state.file = 0;
24843         for(i = 0; i < sizeof(state.token)/sizeof(state.token[0]); i++) {
24844                 memset(&state.token[i], 0, sizeof(state.token[i]));
24845                 state.token[i].tok = -1;
24846         }
24847         /* Remember the output descriptors */
24848         state.errout = stderr;
24849         state.dbgout = stdout;
24850         /* Remember the output filename */
24851         state.output    = fopen(state.compiler->ofilename, "w");
24852         if (!state.output) {
24853                 error(&state, 0, "Cannot open output file %s\n",
24854                         state.compiler->ofilename);
24855         }
24856         /* Make certain a good cleanup happens */
24857         exit_state = &state;
24858         atexit(exit_cleanup);
24859
24860         /* Prep the preprocessor */
24861         state.if_depth = 0;
24862         memset(state.if_bytes, 0, sizeof(state.if_bytes));
24863         /* register the C keywords */
24864         register_keywords(&state);
24865         /* register the keywords the macro preprocessor knows */
24866         register_macro_keywords(&state);
24867         /* generate some builtin macros */
24868         register_builtin_macros(&state);
24869         /* Memorize where some special keywords are. */
24870         state.i_switch        = lookup(&state, "switch", 6);
24871         state.i_case          = lookup(&state, "case", 4);
24872         state.i_continue      = lookup(&state, "continue", 8);
24873         state.i_break         = lookup(&state, "break", 5);
24874         state.i_default       = lookup(&state, "default", 7);
24875         state.i_return        = lookup(&state, "return", 6);
24876         /* Memorize where predefined macros are. */
24877         state.i___VA_ARGS__   = lookup(&state, "__VA_ARGS__", 11);
24878         state.i___FILE__      = lookup(&state, "__FILE__", 8);
24879         state.i___LINE__      = lookup(&state, "__LINE__", 8);
24880         /* Memorize where predefined identifiers are. */
24881         state.i___func__      = lookup(&state, "__func__", 8);
24882         /* Memorize where some attribute keywords are. */
24883         state.i_noinline      = lookup(&state, "noinline", 8);
24884         state.i_always_inline = lookup(&state, "always_inline", 13);
24885
24886         /* Process the command line macros */
24887         process_cmdline_macros(&state);
24888
24889         /* Allocate beginning bounding labels for the function list */
24890         state.first = label(&state);
24891         state.first->id |= TRIPLE_FLAG_VOLATILE;
24892         use_triple(state.first, state.first);
24893         ptr = label(&state);
24894         ptr->id |= TRIPLE_FLAG_VOLATILE;
24895         use_triple(ptr, ptr);
24896         flatten(&state, state.first, ptr);
24897
24898         /* Allocate a label for the pool of global variables */
24899         state.global_pool = label(&state);
24900         state.global_pool->id |= TRIPLE_FLAG_VOLATILE;
24901         flatten(&state, state.first, state.global_pool);
24902
24903         /* Enter the globl definition scope */
24904         start_scope(&state);
24905         register_builtins(&state);
24906         compile_file(&state, filename, 1);
24907
24908         /* Stop if all we want is preprocessor output */
24909         if (state.compiler->flags & COMPILER_PP_ONLY) {
24910                 print_preprocessed_tokens(&state);
24911                 return;
24912         }
24913
24914         decls(&state);
24915
24916         /* Exit the global definition scope */
24917         end_scope(&state);
24918
24919         /* Now that basic compilation has happened 
24920          * optimize the intermediate code 
24921          */
24922         optimize(&state);
24923
24924         generate_code(&state);
24925         if (state.compiler->debug) {
24926                 fprintf(state.errout, "done\n");
24927         }
24928         exit_state = 0;
24929 }
24930
24931 static void version(FILE *fp)
24932 {
24933         fprintf(fp, "romcc " VERSION " released " RELEASE_DATE "\n");
24934 }
24935
24936 static void usage(void)
24937 {
24938         FILE *fp = stdout;
24939         version(fp);
24940         fprintf(fp,
24941                 "\nUsage: romcc [options] <source>.c\n"
24942                 "Compile a C source file generating a binary that does not implicilty use RAM\n"
24943                 "Options: \n"
24944                 "-o <output file name>\n"
24945                 "-f<option>            Specify a generic compiler option\n"
24946                 "-m<option>            Specify a arch dependent option\n"
24947                 "--                    Specify this is the last option\n"
24948                 "\nGeneric compiler options:\n"
24949         );
24950         compiler_usage(fp);
24951         fprintf(fp,
24952                 "\nArchitecture compiler options:\n"
24953         );
24954         arch_usage(fp);
24955         fprintf(fp,
24956                 "\n"
24957         );
24958 }
24959
24960 static void arg_error(char *fmt, ...)
24961 {
24962         va_list args;
24963         va_start(args, fmt);
24964         vfprintf(stderr, fmt, args);
24965         va_end(args);
24966         usage();
24967         exit(1);
24968 }
24969
24970 int main(int argc, char **argv)
24971 {
24972         const char *filename;
24973         struct compiler_state compiler;
24974         struct arch_state arch;
24975         int all_opts;
24976         
24977         
24978         /* I don't want any surprises */
24979         setlocale(LC_ALL, "C");
24980
24981         init_compiler_state(&compiler);
24982         init_arch_state(&arch);
24983         filename = 0;
24984         all_opts = 0;
24985         while(argc > 1) {
24986                 if (!all_opts && (strcmp(argv[1], "-o") == 0) && (argc > 2)) {
24987                         compiler.ofilename = argv[2];
24988                         argv += 2;
24989                         argc -= 2;
24990                 }
24991                 else if (!all_opts && argv[1][0] == '-') {
24992                         int result;
24993                         result = -1;
24994                         if (strcmp(argv[1], "--") == 0) {
24995                                 result = 0;
24996                                 all_opts = 1;
24997                         }
24998                         else if (strncmp(argv[1], "-E", 2) == 0) {
24999                                 result = compiler_encode_flag(&compiler, argv[1]);
25000                         }
25001                         else if (strncmp(argv[1], "-O", 2) == 0) {
25002                                 result = compiler_encode_flag(&compiler, argv[1]);
25003                         }
25004                         else if (strncmp(argv[1], "-I", 2) == 0) {
25005                                 result = compiler_encode_flag(&compiler, argv[1]);
25006                         }
25007                         else if (strncmp(argv[1], "-D", 2) == 0) {
25008                                 result = compiler_encode_flag(&compiler, argv[1]);
25009                         }
25010                         else if (strncmp(argv[1], "-U", 2) == 0) {
25011                                 result = compiler_encode_flag(&compiler, argv[1]);
25012                         }
25013                         else if (strncmp(argv[1], "--label-prefix=", 15) == 0) {
25014                                 result = compiler_encode_flag(&compiler, argv[1]+2);
25015                         }
25016                         else if (strncmp(argv[1], "-f", 2) == 0) {
25017                                 result = compiler_encode_flag(&compiler, argv[1]+2);
25018                         }
25019                         else if (strncmp(argv[1], "-m", 2) == 0) {
25020                                 result = arch_encode_flag(&arch, argv[1]+2);
25021                         }
25022                         if (result < 0) {
25023                                 arg_error("Invalid option specified: %s\n",
25024                                         argv[1]);
25025                         }
25026                         argv++;
25027                         argc--;
25028                 }
25029                 else {
25030                         if (filename) {
25031                                 arg_error("Only one filename may be specified\n");
25032                         }
25033                         filename = argv[1];
25034                         argv++;
25035                         argc--;
25036                 }
25037         }
25038         if (!filename) {
25039                 arg_error("No filename specified\n");
25040         }
25041         compile(filename, &compiler, &arch);
25042
25043         return 0;
25044 }