- Merge from linuxbios-lnxi (Linux Networx repository) up to public tree.
[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
1305
1306
1307
1308 #define DEBUG_ABORT_ON_ERROR    0x00000001
1309 #define DEBUG_BASIC_BLOCKS      0x00000002
1310 #define DEBUG_FDOMINATORS       0x00000004
1311 #define DEBUG_RDOMINATORS       0x00000008
1312 #define DEBUG_TRIPLES           0x00000010
1313 #define DEBUG_INTERFERENCE      0x00000020
1314 #define DEBUG_SCC_TRANSFORM     0x00000040
1315 #define DEBUG_SCC_TRANSFORM2    0x00000080
1316 #define DEBUG_REBUILD_SSA_FORM  0x00000100
1317 #define DEBUG_INLINE            0x00000200
1318 #define DEBUG_RANGE_CONFLICTS   0x00000400
1319 #define DEBUG_RANGE_CONFLICTS2  0x00000800
1320 #define DEBUG_COLOR_GRAPH       0x00001000
1321 #define DEBUG_COLOR_GRAPH2      0x00002000
1322 #define DEBUG_COALESCING        0x00004000
1323 #define DEBUG_COALESCING2       0x00008000
1324 #define DEBUG_VERIFICATION      0x00010000
1325 #define DEBUG_CALLS             0x00020000
1326 #define DEBUG_CALLS2            0x00040000
1327 #define DEBUG_TOKENS            0x80000000
1328
1329 #define DEBUG_DEFAULT ( \
1330         DEBUG_ABORT_ON_ERROR | \
1331         DEBUG_BASIC_BLOCKS | \
1332         DEBUG_FDOMINATORS | \
1333         DEBUG_RDOMINATORS | \
1334         DEBUG_TRIPLES | \
1335         0 )
1336
1337 #define DEBUG_ALL ( \
1338         DEBUG_ABORT_ON_ERROR   | \
1339         DEBUG_BASIC_BLOCKS     | \
1340         DEBUG_FDOMINATORS      | \
1341         DEBUG_RDOMINATORS      | \
1342         DEBUG_TRIPLES          | \
1343         DEBUG_INTERFERENCE     | \
1344         DEBUG_SCC_TRANSFORM    | \
1345         DEBUG_SCC_TRANSFORM2   | \
1346         DEBUG_REBUILD_SSA_FORM | \
1347         DEBUG_INLINE           | \
1348         DEBUG_RANGE_CONFLICTS  | \
1349         DEBUG_RANGE_CONFLICTS2 | \
1350         DEBUG_COLOR_GRAPH      | \
1351         DEBUG_COLOR_GRAPH2     | \
1352         DEBUG_COALESCING       | \
1353         DEBUG_COALESCING2      | \
1354         DEBUG_VERIFICATION     | \
1355         DEBUG_CALLS            | \
1356         DEBUG_CALLS2           | \
1357         DEBUG_TOKENS           | \
1358         0 )
1359
1360 #define COMPILER_INLINE_MASK               0x00000007
1361 #define COMPILER_INLINE_ALWAYS             0x00000000
1362 #define COMPILER_INLINE_NEVER              0x00000001
1363 #define COMPILER_INLINE_DEFAULTON          0x00000002
1364 #define COMPILER_INLINE_DEFAULTOFF         0x00000003
1365 #define COMPILER_INLINE_NOPENALTY          0x00000004
1366 #define COMPILER_ELIMINATE_INEFECTUAL_CODE 0x00000008
1367 #define COMPILER_SIMPLIFY                  0x00000010
1368 #define COMPILER_SCC_TRANSFORM             0x00000020
1369 #define COMPILER_SIMPLIFY_OP               0x00000040
1370 #define COMPILER_SIMPLIFY_PHI              0x00000080
1371 #define COMPILER_SIMPLIFY_LABEL            0x00000100
1372 #define COMPILER_SIMPLIFY_BRANCH           0x00000200
1373 #define COMPILER_SIMPLIFY_COPY             0x00000400
1374 #define COMPILER_SIMPLIFY_ARITH            0x00000800
1375 #define COMPILER_SIMPLIFY_SHIFT            0x00001000
1376 #define COMPILER_SIMPLIFY_BITWISE          0x00002000
1377 #define COMPILER_SIMPLIFY_LOGICAL          0x00004000
1378 #define COMPILER_SIMPLIFY_BITFIELD         0x00008000
1379
1380 #define COMPILER_TRIGRAPHS                 0x40000000
1381 #define COMPILER_PP_ONLY                   0x80000000
1382
1383 #define COMPILER_DEFAULT_FLAGS ( \
1384         COMPILER_TRIGRAPHS | \
1385         COMPILER_ELIMINATE_INEFECTUAL_CODE | \
1386         COMPILER_INLINE_DEFAULTON | \
1387         COMPILER_SIMPLIFY_OP | \
1388         COMPILER_SIMPLIFY_PHI | \
1389         COMPILER_SIMPLIFY_LABEL | \
1390         COMPILER_SIMPLIFY_BRANCH | \
1391         COMPILER_SIMPLIFY_COPY | \
1392         COMPILER_SIMPLIFY_ARITH | \
1393         COMPILER_SIMPLIFY_SHIFT | \
1394         COMPILER_SIMPLIFY_BITWISE | \
1395         COMPILER_SIMPLIFY_LOGICAL | \
1396         COMPILER_SIMPLIFY_BITFIELD | \
1397         0 )
1398
1399 #define GLOBAL_SCOPE_DEPTH   1
1400 #define FUNCTION_SCOPE_DEPTH (GLOBAL_SCOPE_DEPTH + 1)
1401
1402 static void compile_file(struct compile_state *old_state, const char *filename, int local);
1403
1404
1405
1406 static void init_compiler_state(struct compiler_state *compiler)
1407 {
1408         memset(compiler, 0, sizeof(*compiler));
1409         compiler->label_prefix = "";
1410         compiler->ofilename = "auto.inc";
1411         compiler->flags = COMPILER_DEFAULT_FLAGS;
1412         compiler->debug = 0;
1413         compiler->max_allocation_passes = MAX_ALLOCATION_PASSES;
1414         compiler->include_path_count = 1;
1415         compiler->include_paths      = xcmalloc(sizeof(char *), "include_paths");
1416         compiler->define_count       = 1;
1417         compiler->defines            = xcmalloc(sizeof(char *), "defines");
1418         compiler->undef_count        = 1;
1419         compiler->undefs             = xcmalloc(sizeof(char *), "undefs");
1420 }
1421
1422 struct compiler_flag {
1423         const char *name;
1424         unsigned long flag;
1425 };
1426
1427 struct compiler_arg {
1428         const char *name;
1429         unsigned long mask;
1430         struct compiler_flag flags[16];
1431 };
1432
1433 static int set_flag(
1434         const struct compiler_flag *ptr, unsigned long *flags,
1435         int act, const char *flag)
1436 {
1437         int result = -1;
1438         for(; ptr->name; ptr++) {
1439                 if (strcmp(ptr->name, flag) == 0) {
1440                         break;
1441                 }
1442         }
1443         if (ptr->name) {
1444                 result = 0;
1445                 *flags &= ~(ptr->flag);
1446                 if (act) {
1447                         *flags |= ptr->flag;
1448                 }
1449         }
1450         return result;
1451 }
1452
1453 static int set_arg(
1454         const struct compiler_arg *ptr, unsigned long *flags, const char *arg)
1455 {
1456         const char *val;
1457         int result = -1;
1458         int len;
1459         val = strchr(arg, '=');
1460         if (val) {
1461                 len = val - arg;
1462                 val++;
1463                 for(; ptr->name; ptr++) {
1464                         if (strncmp(ptr->name, arg, len) == 0) {
1465                                 break;
1466                         }
1467                 }
1468                 if (ptr->name) {
1469                         *flags &= ~ptr->mask;
1470                         result = set_flag(&ptr->flags[0], flags, 1, val);
1471                 }
1472         }
1473         return result;
1474 }
1475         
1476
1477 static void flag_usage(FILE *fp, const struct compiler_flag *ptr, 
1478         const char *prefix, const char *invert_prefix)
1479 {
1480         for(;ptr->name; ptr++) {
1481                 fprintf(fp, "%s%s\n", prefix, ptr->name);
1482                 if (invert_prefix) {
1483                         fprintf(fp, "%s%s\n", invert_prefix, ptr->name);
1484                 }
1485         }
1486 }
1487
1488 static void arg_usage(FILE *fp, const struct compiler_arg *ptr,
1489         const char *prefix)
1490 {
1491         for(;ptr->name; ptr++) {
1492                 const struct compiler_flag *flag;
1493                 for(flag = &ptr->flags[0]; flag->name; flag++) {
1494                         fprintf(fp, "%s%s=%s\n", 
1495                                 prefix, ptr->name, flag->name);
1496                 }
1497         }
1498 }
1499
1500 static int append_string(size_t *max, const char ***vec, const char *str,
1501         const char *name)
1502 {
1503         size_t count;
1504         count = ++(*max);
1505         *vec = xrealloc(*vec, sizeof(char *)*count, "name");
1506         (*vec)[count -1] = 0;
1507         (*vec)[count -2] = str; 
1508         return 0;
1509 }
1510
1511 static void arg_error(char *fmt, ...);
1512 static const char *identifier(const char *str, const char *end);
1513
1514 static int append_include_path(struct compiler_state *compiler, const char *str)
1515 {
1516         int result;
1517         if (!exists(str, ".")) {
1518                 arg_error("Nonexistent include path: `%s'\n",
1519                         str);
1520         }
1521         result = append_string(&compiler->include_path_count,
1522                 &compiler->include_paths, str, "include_paths");
1523         return result;
1524 }
1525
1526 static int append_define(struct compiler_state *compiler, const char *str)
1527 {
1528         const char *end, *rest;
1529         int result;
1530
1531         end = strchr(str, '=');
1532         if (!end) {
1533                 end = str + strlen(str);
1534         }
1535         rest = identifier(str, end);
1536         if (rest != end) {
1537                 int len = end - str - 1;
1538                 arg_error("Invalid name cannot define macro: `%*.*s'\n", 
1539                         len, len, str);
1540         }
1541         result = append_string(&compiler->define_count,
1542                 &compiler->defines, str, "defines");
1543         return result;
1544 }
1545
1546 static int append_undef(struct compiler_state *compiler, const char *str)
1547 {
1548         const char *end, *rest;
1549         int result;
1550
1551         end = str + strlen(str);
1552         rest = identifier(str, end);
1553         if (rest != end) {
1554                 int len = end - str - 1;
1555                 arg_error("Invalid name cannot undefine macro: `%*.*s'\n", 
1556                         len, len, str);
1557         }
1558         result = append_string(&compiler->undef_count,
1559                 &compiler->undefs, str, "undefs");
1560         return result;
1561 }
1562
1563 static const struct compiler_flag romcc_flags[] = {
1564         { "trigraphs",                 COMPILER_TRIGRAPHS },
1565         { "pp-only",                   COMPILER_PP_ONLY },
1566         { "eliminate-inefectual-code", COMPILER_ELIMINATE_INEFECTUAL_CODE },
1567         { "simplify",                  COMPILER_SIMPLIFY },
1568         { "scc-transform",             COMPILER_SCC_TRANSFORM },
1569         { "simplify-op",               COMPILER_SIMPLIFY_OP },
1570         { "simplify-phi",              COMPILER_SIMPLIFY_PHI },
1571         { "simplify-label",            COMPILER_SIMPLIFY_LABEL },
1572         { "simplify-branch",           COMPILER_SIMPLIFY_BRANCH },
1573         { "simplify-copy",             COMPILER_SIMPLIFY_COPY },
1574         { "simplify-arith",            COMPILER_SIMPLIFY_ARITH },
1575         { "simplify-shift",            COMPILER_SIMPLIFY_SHIFT },
1576         { "simplify-bitwise",          COMPILER_SIMPLIFY_BITWISE },
1577         { "simplify-logical",          COMPILER_SIMPLIFY_LOGICAL },
1578         { "simplify-bitfield",         COMPILER_SIMPLIFY_BITFIELD },
1579         { 0, 0 },
1580 };
1581 static const struct compiler_arg romcc_args[] = {
1582         { "inline-policy",             COMPILER_INLINE_MASK,
1583                 {
1584                         { "always",      COMPILER_INLINE_ALWAYS, },
1585                         { "never",       COMPILER_INLINE_NEVER, },
1586                         { "defaulton",   COMPILER_INLINE_DEFAULTON, },
1587                         { "defaultoff",  COMPILER_INLINE_DEFAULTOFF, },
1588                         { "nopenalty",   COMPILER_INLINE_NOPENALTY, },
1589                         { 0, 0 },
1590                 },
1591         },
1592         { 0, 0 },
1593 };
1594 static const struct compiler_flag romcc_opt_flags[] = {
1595         { "-O",  COMPILER_SIMPLIFY },
1596         { "-O2", COMPILER_SIMPLIFY | COMPILER_SCC_TRANSFORM },
1597         { "-E",  COMPILER_PP_ONLY },
1598         { 0, 0, },
1599 };
1600 static const struct compiler_flag romcc_debug_flags[] = {
1601         { "all",                   DEBUG_ALL },
1602         { "abort-on-error",        DEBUG_ABORT_ON_ERROR },
1603         { "basic-blocks",          DEBUG_BASIC_BLOCKS },
1604         { "fdominators",           DEBUG_FDOMINATORS },
1605         { "rdominators",           DEBUG_RDOMINATORS },
1606         { "triples",               DEBUG_TRIPLES },
1607         { "interference",          DEBUG_INTERFERENCE },
1608         { "scc-transform",         DEBUG_SCC_TRANSFORM },
1609         { "scc-transform2",        DEBUG_SCC_TRANSFORM2 },
1610         { "rebuild-ssa-form",      DEBUG_REBUILD_SSA_FORM },
1611         { "inline",                DEBUG_INLINE },
1612         { "live-range-conflicts",  DEBUG_RANGE_CONFLICTS },
1613         { "live-range-conflicts2", DEBUG_RANGE_CONFLICTS2 },
1614         { "color-graph",           DEBUG_COLOR_GRAPH },
1615         { "color-graph2",          DEBUG_COLOR_GRAPH2 },
1616         { "coalescing",            DEBUG_COALESCING },
1617         { "coalescing2",           DEBUG_COALESCING2 },
1618         { "verification",          DEBUG_VERIFICATION },
1619         { "calls",                 DEBUG_CALLS },
1620         { "calls2",                DEBUG_CALLS2 },
1621         { "tokens",                DEBUG_TOKENS },
1622         { 0, 0 },
1623 };
1624
1625 static int compiler_encode_flag(
1626         struct compiler_state *compiler, const char *flag)
1627 {
1628         int act;
1629         int result;
1630
1631         act = 1;
1632         result = -1;
1633         if (strncmp(flag, "no-", 3) == 0) {
1634                 flag += 3;
1635                 act = 0;
1636         }
1637         if (strncmp(flag, "-O", 2) == 0) {
1638                 result = set_flag(romcc_opt_flags, &compiler->flags, act, flag);
1639         }
1640         else if (strncmp(flag, "-E", 2) == 0) {
1641                 result = set_flag(romcc_opt_flags, &compiler->flags, act, flag);
1642         }
1643         else if (strncmp(flag, "-I", 2) == 0) {
1644                 result = append_include_path(compiler, flag + 2);
1645         }
1646         else if (strncmp(flag, "-D", 2) == 0) {
1647                 result = append_define(compiler, flag + 2);
1648         }
1649         else if (strncmp(flag, "-U", 2) == 0) {
1650                 result = append_undef(compiler, flag + 2);
1651         }
1652         else if (act && strncmp(flag, "label-prefix=", 13) == 0) {
1653                 result = 0;
1654                 compiler->label_prefix = flag + 13;
1655         }
1656         else if (act && strncmp(flag, "max-allocation-passes=", 22) == 0) {
1657                 unsigned long max_passes;
1658                 char *end;
1659                 max_passes = strtoul(flag + 22, &end, 10);
1660                 if (end[0] == '\0') {
1661                         result = 0;
1662                         compiler->max_allocation_passes = max_passes;
1663                 }
1664         }
1665         else if (act && strcmp(flag, "debug") == 0) {
1666                 result = 0;
1667                 compiler->debug |= DEBUG_DEFAULT;
1668         }
1669         else if (strncmp(flag, "debug-", 6) == 0) {
1670                 flag += 6;
1671                 result = set_flag(romcc_debug_flags, &compiler->debug, act, flag);
1672         }
1673         else {
1674                 result = set_flag(romcc_flags, &compiler->flags, act, flag);
1675                 if (result < 0) {
1676                         result = set_arg(romcc_args, &compiler->flags, flag);
1677                 }
1678         }
1679         return result;
1680 }
1681
1682 static void compiler_usage(FILE *fp)
1683 {
1684         flag_usage(fp, romcc_opt_flags, "", 0);
1685         flag_usage(fp, romcc_flags, "-f", "-fno-");
1686         arg_usage(fp,  romcc_args, "-f");
1687         flag_usage(fp, romcc_debug_flags, "-fdebug-", "-fno-debug-");
1688         fprintf(fp, "-flabel-prefix=<prefix for assembly language labels>\n");
1689         fprintf(fp, "--label-prefix=<prefix for assembly language labels>\n");
1690         fprintf(fp, "-I<include path>\n");
1691         fprintf(fp, "-D<macro>[=defn]\n");
1692         fprintf(fp, "-U<macro>\n");
1693 }
1694
1695 static void do_cleanup(struct compile_state *state)
1696 {
1697         if (state->output) {
1698                 fclose(state->output);
1699                 unlink(state->compiler->ofilename);
1700                 state->output = 0;
1701         }
1702         if (state->dbgout) {
1703                 fflush(state->dbgout);
1704         }
1705         if (state->errout) {
1706                 fflush(state->errout);
1707         }
1708 }
1709
1710 static struct compile_state *exit_state;
1711 static void exit_cleanup(void)
1712 {
1713         if (exit_state) {
1714                 do_cleanup(exit_state);
1715         }
1716 }
1717
1718 static int get_col(struct file_state *file)
1719 {
1720         int col;
1721         const char *ptr, *end;
1722         ptr = file->line_start;
1723         end = file->pos;
1724         for(col = 0; ptr < end; ptr++) {
1725                 if (*ptr != '\t') {
1726                         col++;
1727                 } 
1728                 else {
1729                         col = (col & ~7) + 8;
1730                 }
1731         }
1732         return col;
1733 }
1734
1735 static void loc(FILE *fp, struct compile_state *state, struct triple *triple)
1736 {
1737         int col;
1738         if (triple && triple->occurance) {
1739                 struct occurance *spot;
1740                 for(spot = triple->occurance; spot; spot = spot->parent) {
1741                         fprintf(fp, "%s:%d.%d: ", 
1742                                 spot->filename, spot->line, spot->col);
1743                 }
1744                 return;
1745         }
1746         if (!state->file) {
1747                 return;
1748         }
1749         col = get_col(state->file);
1750         fprintf(fp, "%s:%d.%d: ", 
1751                 state->file->report_name, state->file->report_line, col);
1752 }
1753
1754 static void internal_error(struct compile_state *state, struct triple *ptr, 
1755         const char *fmt, ...)
1756 {
1757         FILE *fp = state->errout;
1758         va_list args;
1759         va_start(args, fmt);
1760         loc(fp, state, ptr);
1761         fputc('\n', fp);
1762         if (ptr) {
1763                 fprintf(fp, "%p %-10s ", ptr, tops(ptr->op));
1764         }
1765         fprintf(fp, "Internal compiler error: ");
1766         vfprintf(fp, fmt, args);
1767         fprintf(fp, "\n");
1768         va_end(args);
1769         do_cleanup(state);
1770         abort();
1771 }
1772
1773
1774 static void internal_warning(struct compile_state *state, struct triple *ptr, 
1775         const char *fmt, ...)
1776 {
1777         FILE *fp = state->errout;
1778         va_list args;
1779         va_start(args, fmt);
1780         loc(fp, state, ptr);
1781         if (ptr) {
1782                 fprintf(fp, "%p %-10s ", ptr, tops(ptr->op));
1783         }
1784         fprintf(fp, "Internal compiler warning: ");
1785         vfprintf(fp, fmt, args);
1786         fprintf(fp, "\n");
1787         va_end(args);
1788 }
1789
1790
1791
1792 static void error(struct compile_state *state, struct triple *ptr, 
1793         const char *fmt, ...)
1794 {
1795         FILE *fp = state->errout;
1796         va_list args;
1797         va_start(args, fmt);
1798         loc(fp, state, ptr);
1799         fputc('\n', fp);
1800         if (ptr && (state->compiler->debug & DEBUG_ABORT_ON_ERROR)) {
1801                 fprintf(fp, "%p %-10s ", ptr, tops(ptr->op));
1802         }
1803         vfprintf(fp, fmt, args);
1804         va_end(args);
1805         fprintf(fp, "\n");
1806         do_cleanup(state);
1807         if (state->compiler->debug & DEBUG_ABORT_ON_ERROR) {
1808                 abort();
1809         }
1810         exit(1);
1811 }
1812
1813 static void warning(struct compile_state *state, struct triple *ptr, 
1814         const char *fmt, ...)
1815 {
1816         FILE *fp = state->errout;
1817         va_list args;
1818         va_start(args, fmt);
1819         loc(fp, state, ptr);
1820         fprintf(fp, "warning: "); 
1821         if (ptr && (state->compiler->debug & DEBUG_ABORT_ON_ERROR)) {
1822                 fprintf(fp, "%p %-10s ", ptr, tops(ptr->op));
1823         }
1824         vfprintf(fp, fmt, args);
1825         fprintf(fp, "\n");
1826         va_end(args);
1827 }
1828
1829 #define FINISHME() warning(state, 0, "FINISHME @ %s.%s:%d", __FILE__, __func__, __LINE__)
1830
1831 static void valid_op(struct compile_state *state, int op)
1832 {
1833         char *fmt = "invalid op: %d";
1834         if (op >= OP_MAX) {
1835                 internal_error(state, 0, fmt, op);
1836         }
1837         if (op < 0) {
1838                 internal_error(state, 0, fmt, op);
1839         }
1840 }
1841
1842 static void valid_ins(struct compile_state *state, struct triple *ptr)
1843 {
1844         valid_op(state, ptr->op);
1845 }
1846
1847 static void valid_param_count(struct compile_state *state, struct triple *ins)
1848 {
1849         int lhs, rhs, misc, targ;
1850         valid_ins(state, ins);
1851         lhs  = table_ops[ins->op].lhs;
1852         rhs  = table_ops[ins->op].rhs;
1853         misc = table_ops[ins->op].misc;
1854         targ = table_ops[ins->op].targ;
1855
1856         if ((lhs >= 0) && (ins->lhs != lhs)) {
1857                 internal_error(state, ins, "Bad lhs count");
1858         }
1859         if ((rhs >= 0) && (ins->rhs != rhs)) {
1860                 internal_error(state, ins, "Bad rhs count");
1861         }
1862         if ((misc >= 0) && (ins->misc != misc)) {
1863                 internal_error(state, ins, "Bad misc count");
1864         }
1865         if ((targ >= 0) && (ins->targ != targ)) {
1866                 internal_error(state, ins, "Bad targ count");
1867         }
1868 }
1869
1870 static struct type void_type;
1871 static struct type unknown_type;
1872 static void use_triple(struct triple *used, struct triple *user)
1873 {
1874         struct triple_set **ptr, *new;
1875         if (!used)
1876                 return;
1877         if (!user)
1878                 return;
1879         ptr = &used->use;
1880         while(*ptr) {
1881                 if ((*ptr)->member == user) {
1882                         return;
1883                 }
1884                 ptr = &(*ptr)->next;
1885         }
1886         /* Append new to the head of the list, 
1887          * copy_func and rename_block_variables
1888          * depends on this.
1889          */
1890         new = xcmalloc(sizeof(*new), "triple_set");
1891         new->member = user;
1892         new->next   = used->use;
1893         used->use   = new;
1894 }
1895
1896 static void unuse_triple(struct triple *used, struct triple *unuser)
1897 {
1898         struct triple_set *use, **ptr;
1899         if (!used) {
1900                 return;
1901         }
1902         ptr = &used->use;
1903         while(*ptr) {
1904                 use = *ptr;
1905                 if (use->member == unuser) {
1906                         *ptr = use->next;
1907                         xfree(use);
1908                 }
1909                 else {
1910                         ptr = &use->next;
1911                 }
1912         }
1913 }
1914
1915 static void put_occurance(struct occurance *occurance)
1916 {
1917         if (occurance) {
1918                 occurance->count -= 1;
1919                 if (occurance->count <= 0) {
1920                         if (occurance->parent) {
1921                                 put_occurance(occurance->parent);
1922                         }
1923                         xfree(occurance);
1924                 }
1925         }
1926 }
1927
1928 static void get_occurance(struct occurance *occurance)
1929 {
1930         if (occurance) {
1931                 occurance->count += 1;
1932         }
1933 }
1934
1935
1936 static struct occurance *new_occurance(struct compile_state *state)
1937 {
1938         struct occurance *result, *last;
1939         const char *filename;
1940         const char *function;
1941         int line, col;
1942
1943         function = "";
1944         filename = 0;
1945         line = 0;
1946         col  = 0;
1947         if (state->file) {
1948                 filename = state->file->report_name;
1949                 line     = state->file->report_line;
1950                 col      = get_col(state->file);
1951         }
1952         if (state->function) {
1953                 function = state->function;
1954         }
1955         last = state->last_occurance;
1956         if (last &&
1957                 (last->col == col) &&
1958                 (last->line == line) &&
1959                 (last->function == function) &&
1960                 ((last->filename == filename) ||
1961                         (strcmp(last->filename, filename) == 0))) 
1962         {
1963                 get_occurance(last);
1964                 return last;
1965         }
1966         if (last) {
1967                 state->last_occurance = 0;
1968                 put_occurance(last);
1969         }
1970         result = xmalloc(sizeof(*result), "occurance");
1971         result->count    = 2;
1972         result->filename = filename;
1973         result->function = function;
1974         result->line     = line;
1975         result->col      = col;
1976         result->parent   = 0;
1977         state->last_occurance = result;
1978         return result;
1979 }
1980
1981 static struct occurance *inline_occurance(struct compile_state *state,
1982         struct occurance *base, struct occurance *top)
1983 {
1984         struct occurance *result, *last;
1985         if (top->parent) {
1986                 internal_error(state, 0, "inlining an already inlined function?");
1987         }
1988         /* If I have a null base treat it that way */
1989         if ((base->parent == 0) &&
1990                 (base->col == 0) &&
1991                 (base->line == 0) &&
1992                 (base->function[0] == '\0') &&
1993                 (base->filename[0] == '\0')) {
1994                 base = 0;
1995         }
1996         /* See if I can reuse the last occurance I had */
1997         last = state->last_occurance;
1998         if (last &&
1999                 (last->parent   == base) &&
2000                 (last->col      == top->col) &&
2001                 (last->line     == top->line) &&
2002                 (last->function == top->function) &&
2003                 (last->filename == top->filename)) {
2004                 get_occurance(last);
2005                 return last;
2006         }
2007         /* I can't reuse the last occurance so free it */
2008         if (last) {
2009                 state->last_occurance = 0;
2010                 put_occurance(last);
2011         }
2012         /* Generate a new occurance structure */
2013         get_occurance(base);
2014         result = xmalloc(sizeof(*result), "occurance");
2015         result->count    = 2;
2016         result->filename = top->filename;
2017         result->function = top->function;
2018         result->line     = top->line;
2019         result->col      = top->col;
2020         result->parent   = base;
2021         state->last_occurance = result;
2022         return result;
2023 }
2024
2025 static struct occurance dummy_occurance = {
2026         .count    = 2,
2027         .filename = __FILE__,
2028         .function = "",
2029         .line     = __LINE__,
2030         .col      = 0,
2031         .parent   = 0,
2032 };
2033
2034 /* The undef triple is used as a place holder when we are removing pointers
2035  * from a triple.  Having allows certain sanity checks to pass even
2036  * when the original triple that was pointed to is gone.
2037  */
2038 static struct triple unknown_triple = {
2039         .next      = &unknown_triple,
2040         .prev      = &unknown_triple,
2041         .use       = 0,
2042         .op        = OP_UNKNOWNVAL,
2043         .lhs       = 0,
2044         .rhs       = 0,
2045         .misc      = 0,
2046         .targ      = 0,
2047         .type      = &unknown_type,
2048         .id        = -1, /* An invalid id */
2049         .u = { .cval = 0, },
2050         .occurance = &dummy_occurance,
2051         .param = { [0] = 0, [1] = 0, },
2052 };
2053
2054
2055 static size_t registers_of(struct compile_state *state, struct type *type);
2056
2057 static struct triple *alloc_triple(struct compile_state *state, 
2058         int op, struct type *type, int lhs_wanted, int rhs_wanted,
2059         struct occurance *occurance)
2060 {
2061         size_t size, extra_count, min_count;
2062         int lhs, rhs, misc, targ;
2063         struct triple *ret, dummy;
2064         dummy.op = op;
2065         dummy.occurance = occurance;
2066         valid_op(state, op);
2067         lhs = table_ops[op].lhs;
2068         rhs = table_ops[op].rhs;
2069         misc = table_ops[op].misc;
2070         targ = table_ops[op].targ;
2071
2072         switch(op) {
2073         case OP_FCALL:
2074                 rhs = rhs_wanted;
2075                 break;
2076         case OP_PHI:
2077                 rhs = rhs_wanted;
2078                 break;
2079         case OP_ADECL:
2080                 lhs = registers_of(state, type);
2081                 break;
2082         case OP_TUPLE:
2083                 lhs = registers_of(state, type);
2084                 break;
2085         case OP_ASM:
2086                 rhs = rhs_wanted;
2087                 lhs = lhs_wanted;
2088                 break;
2089         }
2090         if ((rhs < 0) || (rhs > MAX_RHS)) {
2091                 internal_error(state, &dummy, "bad rhs count %d", rhs);
2092         }
2093         if ((lhs < 0) || (lhs > MAX_LHS)) {
2094                 internal_error(state, &dummy, "bad lhs count %d", lhs);
2095         }
2096         if ((misc < 0) || (misc > MAX_MISC)) {
2097                 internal_error(state, &dummy, "bad misc count %d", misc);
2098         }
2099         if ((targ < 0) || (targ > MAX_TARG)) {
2100                 internal_error(state, &dummy, "bad targs count %d", targ);
2101         }
2102
2103         min_count = sizeof(ret->param)/sizeof(ret->param[0]);
2104         extra_count = lhs + rhs + misc + targ;
2105         extra_count = (extra_count < min_count)? 0 : extra_count - min_count;
2106
2107         size = sizeof(*ret) + sizeof(ret->param[0]) * extra_count;
2108         ret = xcmalloc(size, "tripple");
2109         ret->op        = op;
2110         ret->lhs       = lhs;
2111         ret->rhs       = rhs;
2112         ret->misc      = misc;
2113         ret->targ      = targ;
2114         ret->type      = type;
2115         ret->next      = ret;
2116         ret->prev      = ret;
2117         ret->occurance = occurance;
2118         /* A simple sanity check */
2119         if ((ret->op != op) ||
2120                 (ret->lhs != lhs) ||
2121                 (ret->rhs != rhs) ||
2122                 (ret->misc != misc) ||
2123                 (ret->targ != targ) ||
2124                 (ret->type != type) ||
2125                 (ret->next != ret) ||
2126                 (ret->prev != ret) ||
2127                 (ret->occurance != occurance)) {
2128                 internal_error(state, ret, "huh?");
2129         }
2130         return ret;
2131 }
2132
2133 struct triple *dup_triple(struct compile_state *state, struct triple *src)
2134 {
2135         struct triple *dup;
2136         int src_lhs, src_rhs, src_size;
2137         src_lhs = src->lhs;
2138         src_rhs = src->rhs;
2139         src_size = TRIPLE_SIZE(src);
2140         get_occurance(src->occurance);
2141         dup = alloc_triple(state, src->op, src->type, src_lhs, src_rhs,
2142                 src->occurance);
2143         memcpy(dup, src, sizeof(*src));
2144         memcpy(dup->param, src->param, src_size * sizeof(src->param[0]));
2145         return dup;
2146 }
2147
2148 static struct triple *copy_triple(struct compile_state *state, struct triple *src)
2149 {
2150         struct triple *copy;
2151         copy = dup_triple(state, src);
2152         copy->use = 0;
2153         copy->next = copy->prev = copy;
2154         return copy;
2155 }
2156
2157 static struct triple *new_triple(struct compile_state *state, 
2158         int op, struct type *type, int lhs, int rhs)
2159 {
2160         struct triple *ret;
2161         struct occurance *occurance;
2162         occurance = new_occurance(state);
2163         ret = alloc_triple(state, op, type, lhs, rhs, occurance);
2164         return ret;
2165 }
2166
2167 static struct triple *build_triple(struct compile_state *state, 
2168         int op, struct type *type, struct triple *left, struct triple *right,
2169         struct occurance *occurance)
2170 {
2171         struct triple *ret;
2172         size_t count;
2173         ret = alloc_triple(state, op, type, -1, -1, occurance);
2174         count = TRIPLE_SIZE(ret);
2175         if (count > 0) {
2176                 ret->param[0] = left;
2177         }
2178         if (count > 1) {
2179                 ret->param[1] = right;
2180         }
2181         return ret;
2182 }
2183
2184 static struct triple *triple(struct compile_state *state, 
2185         int op, struct type *type, struct triple *left, struct triple *right)
2186 {
2187         struct triple *ret;
2188         size_t count;
2189         ret = new_triple(state, op, type, -1, -1);
2190         count = TRIPLE_SIZE(ret);
2191         if (count >= 1) {
2192                 ret->param[0] = left;
2193         }
2194         if (count >= 2) {
2195                 ret->param[1] = right;
2196         }
2197         return ret;
2198 }
2199
2200 static struct triple *branch(struct compile_state *state, 
2201         struct triple *targ, struct triple *test)
2202 {
2203         struct triple *ret;
2204         if (test) {
2205                 ret = new_triple(state, OP_CBRANCH, &void_type, -1, 1);
2206                 RHS(ret, 0) = test;
2207         } else {
2208                 ret = new_triple(state, OP_BRANCH, &void_type, -1, 0);
2209         }
2210         TARG(ret, 0) = targ;
2211         /* record the branch target was used */
2212         if (!targ || (targ->op != OP_LABEL)) {
2213                 internal_error(state, 0, "branch not to label");
2214         }
2215         return ret;
2216 }
2217
2218 static int triple_is_label(struct compile_state *state, struct triple *ins);
2219 static int triple_is_call(struct compile_state *state, struct triple *ins);
2220 static int triple_is_cbranch(struct compile_state *state, struct triple *ins);
2221 static void insert_triple(struct compile_state *state,
2222         struct triple *first, struct triple *ptr)
2223 {
2224         if (ptr) {
2225                 if ((ptr->id & TRIPLE_FLAG_FLATTENED) || (ptr->next != ptr)) {
2226                         internal_error(state, ptr, "expression already used");
2227                 }
2228                 ptr->next       = first;
2229                 ptr->prev       = first->prev;
2230                 ptr->prev->next = ptr;
2231                 ptr->next->prev = ptr;
2232
2233                 if (triple_is_cbranch(state, ptr->prev) ||
2234                         triple_is_call(state, ptr->prev)) {
2235                         unuse_triple(first, ptr->prev);
2236                         use_triple(ptr, ptr->prev);
2237                 }
2238         }
2239 }
2240
2241 static int triple_stores_block(struct compile_state *state, struct triple *ins)
2242 {
2243         /* This function is used to determine if u.block 
2244          * is utilized to store the current block number.
2245          */
2246         int stores_block;
2247         valid_ins(state, ins);
2248         stores_block = (table_ops[ins->op].flags & BLOCK) == BLOCK;
2249         return stores_block;
2250 }
2251
2252 static int triple_is_branch(struct compile_state *state, struct triple *ins);
2253 static struct block *block_of_triple(struct compile_state *state, 
2254         struct triple *ins)
2255 {
2256         struct triple *first;
2257         if (!ins || ins == &unknown_triple) {
2258                 return 0;
2259         }
2260         first = state->first;
2261         while(ins != first && !triple_is_branch(state, ins->prev) &&
2262                 !triple_stores_block(state, ins)) 
2263         { 
2264                 if (ins == ins->prev) {
2265                         internal_error(state, ins, "ins == ins->prev?");
2266                 }
2267                 ins = ins->prev;
2268         }
2269         return triple_stores_block(state, ins)? ins->u.block: 0;
2270 }
2271
2272 static void generate_lhs_pieces(struct compile_state *state, struct triple *ins);
2273 static struct triple *pre_triple(struct compile_state *state,
2274         struct triple *base,
2275         int op, struct type *type, struct triple *left, struct triple *right)
2276 {
2277         struct block *block;
2278         struct triple *ret;
2279         int i;
2280         /* If I am an OP_PIECE jump to the real instruction */
2281         if (base->op == OP_PIECE) {
2282                 base = MISC(base, 0);
2283         }
2284         block = block_of_triple(state, base);
2285         get_occurance(base->occurance);
2286         ret = build_triple(state, op, type, left, right, base->occurance);
2287         generate_lhs_pieces(state, ret);
2288         if (triple_stores_block(state, ret)) {
2289                 ret->u.block = block;
2290         }
2291         insert_triple(state, base, ret);
2292         for(i = 0; i < ret->lhs; i++) {
2293                 struct triple *piece;
2294                 piece = LHS(ret, i);
2295                 insert_triple(state, base, piece);
2296                 use_triple(ret, piece);
2297                 use_triple(piece, ret);
2298         }
2299         if (block && (block->first == base)) {
2300                 block->first = ret;
2301         }
2302         return ret;
2303 }
2304
2305 static struct triple *post_triple(struct compile_state *state,
2306         struct triple *base,
2307         int op, struct type *type, struct triple *left, struct triple *right)
2308 {
2309         struct block *block;
2310         struct triple *ret, *next;
2311         int zlhs, i;
2312         /* If I am an OP_PIECE jump to the real instruction */
2313         if (base->op == OP_PIECE) {
2314                 base = MISC(base, 0);
2315         }
2316         /* If I have a left hand side skip over it */
2317         zlhs = base->lhs;
2318         if (zlhs) {
2319                 base = LHS(base, zlhs - 1);
2320         }
2321
2322         block = block_of_triple(state, base);
2323         get_occurance(base->occurance);
2324         ret = build_triple(state, op, type, left, right, base->occurance);
2325         generate_lhs_pieces(state, ret);
2326         if (triple_stores_block(state, ret)) {
2327                 ret->u.block = block;
2328         }
2329         next = base->next;
2330         insert_triple(state, next, ret);
2331         zlhs = ret->lhs;
2332         for(i = 0; i < zlhs; i++) {
2333                 struct triple *piece;
2334                 piece = LHS(ret, i);
2335                 insert_triple(state, next, piece);
2336                 use_triple(ret, piece);
2337                 use_triple(piece, ret);
2338         }
2339         if (block && (block->last == base)) {
2340                 block->last = ret;
2341                 if (zlhs) {
2342                         block->last = LHS(ret, zlhs - 1);
2343                 }
2344         }
2345         return ret;
2346 }
2347
2348 static struct type *reg_type(
2349         struct compile_state *state, struct type *type, int reg);
2350
2351 static void generate_lhs_piece(
2352         struct compile_state *state, struct triple *ins, int index)
2353 {
2354         struct type *piece_type;
2355         struct triple *piece;
2356         get_occurance(ins->occurance);
2357         piece_type = reg_type(state, ins->type, index * REG_SIZEOF_REG);
2358
2359         if ((piece_type->type & TYPE_MASK) == TYPE_BITFIELD) {
2360                 piece_type = piece_type->left;
2361         }
2362 #if 0
2363 {
2364         static void name_of(FILE *fp, struct type *type);
2365         FILE * fp = state->errout;
2366         fprintf(fp, "piece_type(%d): ", index);
2367         name_of(fp, piece_type);
2368         fprintf(fp, "\n");
2369 }
2370 #endif
2371         piece = alloc_triple(state, OP_PIECE, piece_type, -1, -1, ins->occurance);
2372         piece->u.cval  = index;
2373         LHS(ins, piece->u.cval) = piece;
2374         MISC(piece, 0) = ins;
2375 }
2376
2377 static void generate_lhs_pieces(struct compile_state *state, struct triple *ins)
2378 {
2379         int i, zlhs;
2380         zlhs = ins->lhs;
2381         for(i = 0; i < zlhs; i++) {
2382                 generate_lhs_piece(state, ins, i);
2383         }
2384 }
2385
2386 static struct triple *label(struct compile_state *state)
2387 {
2388         /* Labels don't get a type */
2389         struct triple *result;
2390         result = triple(state, OP_LABEL, &void_type, 0, 0);
2391         return result;
2392 }
2393
2394 static struct triple *mkprog(struct compile_state *state, ...)
2395 {
2396         struct triple *prog, *head, *arg;
2397         va_list args;
2398         int i;
2399
2400         head = label(state);
2401         prog = new_triple(state, OP_PROG, &void_type, -1, -1);
2402         RHS(prog, 0) = head;
2403         va_start(args, state);
2404         i = 0;
2405         while((arg = va_arg(args, struct triple *)) != 0) {
2406                 if (++i >= 100) {
2407                         internal_error(state, 0, "too many arguments to mkprog");
2408                 }
2409                 flatten(state, head, arg);
2410         }
2411         va_end(args);
2412         prog->type = head->prev->type;
2413         return prog;
2414 }
2415 static void name_of(FILE *fp, struct type *type);
2416 static void display_triple(FILE *fp, struct triple *ins)
2417 {
2418         struct occurance *ptr;
2419         const char *reg;
2420         char pre, post, vol;
2421         pre = post = vol = ' ';
2422         if (ins) {
2423                 if (ins->id & TRIPLE_FLAG_PRE_SPLIT) {
2424                         pre = '^';
2425                 }
2426                 if (ins->id & TRIPLE_FLAG_POST_SPLIT) {
2427                         post = ',';
2428                 }
2429                 if (ins->id & TRIPLE_FLAG_VOLATILE) {
2430                         vol = 'v';
2431                 }
2432                 reg = arch_reg_str(ID_REG(ins->id));
2433         }
2434         if (ins == 0) {
2435                 fprintf(fp, "(%p) <nothing> ", ins);
2436         }
2437         else if (ins->op == OP_INTCONST) {
2438                 fprintf(fp, "(%p) %c%c%c %-7s %-2d %-10s <0x%08lx>         ",
2439                         ins, pre, post, vol, reg, ins->template_id, tops(ins->op), 
2440                         (unsigned long)(ins->u.cval));
2441         }
2442         else if (ins->op == OP_ADDRCONST) {
2443                 fprintf(fp, "(%p) %c%c%c %-7s %-2d %-10s %-10p <0x%08lx>",
2444                         ins, pre, post, vol, reg, ins->template_id, tops(ins->op), 
2445                         MISC(ins, 0), (unsigned long)(ins->u.cval));
2446         }
2447         else if (ins->op == OP_INDEX) {
2448                 fprintf(fp, "(%p) %c%c%c %-7s %-2d %-10s %-10p <0x%08lx>",
2449                         ins, pre, post, vol, reg, ins->template_id, tops(ins->op), 
2450                         RHS(ins, 0), (unsigned long)(ins->u.cval));
2451         }
2452         else if (ins->op == OP_PIECE) {
2453                 fprintf(fp, "(%p) %c%c%c %-7s %-2d %-10s %-10p <0x%08lx>",
2454                         ins, pre, post, vol, reg, ins->template_id, tops(ins->op), 
2455                         MISC(ins, 0), (unsigned long)(ins->u.cval));
2456         }
2457         else {
2458                 int i, count;
2459                 fprintf(fp, "(%p) %c%c%c %-7s %-2d %-10s", 
2460                         ins, pre, post, vol, reg, ins->template_id, tops(ins->op));
2461                 if (table_ops[ins->op].flags & BITFIELD) {
2462                         fprintf(fp, " <%2d-%2d:%2d>", 
2463                                 ins->u.bitfield.offset,
2464                                 ins->u.bitfield.offset + ins->u.bitfield.size,
2465                                 ins->u.bitfield.size);
2466                 }
2467                 count = TRIPLE_SIZE(ins);
2468                 for(i = 0; i < count; i++) {
2469                         fprintf(fp, " %-10p", ins->param[i]);
2470                 }
2471                 for(; i < 2; i++) {
2472                         fprintf(fp, "           ");
2473                 }
2474         }
2475         if (ins) {
2476                 struct triple_set *user;
2477 #if DEBUG_DISPLAY_TYPES
2478                 fprintf(fp, " <");
2479                 name_of(fp, ins->type);
2480                 fprintf(fp, "> ");
2481 #endif
2482 #if DEBUG_DISPLAY_USES
2483                 fprintf(fp, " [");
2484                 for(user = ins->use; user; user = user->next) {
2485                         fprintf(fp, " %-10p", user->member);
2486                 }
2487                 fprintf(fp, " ]");
2488 #endif
2489                 fprintf(fp, " @");
2490                 for(ptr = ins->occurance; ptr; ptr = ptr->parent) {
2491                         fprintf(fp, " %s,%s:%d.%d",
2492                                 ptr->function, 
2493                                 ptr->filename,
2494                                 ptr->line, 
2495                                 ptr->col);
2496                 }
2497                 if (ins->op == OP_ASM) {
2498                         fprintf(fp, "\n\t%s", ins->u.ainfo->str);
2499                 }
2500         }
2501         fprintf(fp, "\n");
2502         fflush(fp);
2503 }
2504
2505 static int equiv_types(struct type *left, struct type *right);
2506 static void display_triple_changes(
2507         FILE *fp, const struct triple *new, const struct triple *orig)
2508 {
2509
2510         int new_count, orig_count;
2511         new_count = TRIPLE_SIZE(new);
2512         orig_count = TRIPLE_SIZE(orig);
2513         if ((new->op != orig->op) ||
2514                 (new_count != orig_count) ||
2515                 (memcmp(orig->param, new->param,        
2516                         orig_count * sizeof(orig->param[0])) != 0) ||
2517                 (memcmp(&orig->u, &new->u, sizeof(orig->u)) != 0)) 
2518         {
2519                 struct occurance *ptr;
2520                 int i, min_count, indent;
2521                 fprintf(fp, "(%p %p)", new, orig);
2522                 if (orig->op == new->op) {
2523                         fprintf(fp, " %-11s", tops(orig->op));
2524                 } else {
2525                         fprintf(fp, " [%-10s %-10s]", 
2526                                 tops(new->op), tops(orig->op));
2527                 }
2528                 min_count = new_count;
2529                 if (min_count > orig_count) {
2530                         min_count = orig_count;
2531                 }
2532                 for(indent = i = 0; i < min_count; i++) {
2533                         if (orig->param[i] == new->param[i]) {
2534                                 fprintf(fp, " %-11p", 
2535                                         orig->param[i]);
2536                                 indent += 12;
2537                         } else {
2538                                 fprintf(fp, " [%-10p %-10p]",
2539                                         new->param[i], 
2540                                         orig->param[i]);
2541                                 indent += 24;
2542                         }
2543                 }
2544                 for(; i < orig_count; i++) {
2545                         fprintf(fp, " [%-9p]", orig->param[i]);
2546                         indent += 12;
2547                 }
2548                 for(; i < new_count; i++) {
2549                         fprintf(fp, " [%-9p]", new->param[i]);
2550                         indent += 12;
2551                 }
2552                 if ((new->op == OP_INTCONST)||
2553                         (new->op == OP_ADDRCONST)) {
2554                         fprintf(fp, " <0x%08lx>", 
2555                                 (unsigned long)(new->u.cval));
2556                         indent += 13;
2557                 }
2558                 for(;indent < 36; indent++) {
2559                         putc(' ', fp);
2560                 }
2561
2562 #if DEBUG_DISPLAY_TYPES
2563                 fprintf(fp, " <");
2564                 name_of(fp, new->type);
2565                 if (!equiv_types(new->type, orig->type)) {
2566                         fprintf(fp, " -- ");
2567                         name_of(fp, orig->type);
2568                 }
2569                 fprintf(fp, "> ");
2570 #endif
2571
2572                 fprintf(fp, " @");
2573                 for(ptr = orig->occurance; ptr; ptr = ptr->parent) {
2574                         fprintf(fp, " %s,%s:%d.%d",
2575                                 ptr->function, 
2576                                 ptr->filename,
2577                                 ptr->line, 
2578                                 ptr->col);
2579                         
2580                 }
2581                 fprintf(fp, "\n");
2582                 fflush(fp);
2583         }
2584 }
2585
2586 static int triple_is_pure(struct compile_state *state, struct triple *ins, unsigned id)
2587 {
2588         /* Does the triple have no side effects.
2589          * I.e. Rexecuting the triple with the same arguments 
2590          * gives the same value.
2591          */
2592         unsigned pure;
2593         valid_ins(state, ins);
2594         pure = PURE_BITS(table_ops[ins->op].flags);
2595         if ((pure != PURE) && (pure != IMPURE)) {
2596                 internal_error(state, 0, "Purity of %s not known",
2597                         tops(ins->op));
2598         }
2599         return (pure == PURE) && !(id & TRIPLE_FLAG_VOLATILE);
2600 }
2601
2602 static int triple_is_branch_type(struct compile_state *state, 
2603         struct triple *ins, unsigned type)
2604 {
2605         /* Is this one of the passed branch types? */
2606         valid_ins(state, ins);
2607         return (BRANCH_BITS(table_ops[ins->op].flags) == type);
2608 }
2609
2610 static int triple_is_branch(struct compile_state *state, struct triple *ins)
2611 {
2612         /* Is this triple a branch instruction? */
2613         valid_ins(state, ins);
2614         return (BRANCH_BITS(table_ops[ins->op].flags) != 0);
2615 }
2616
2617 static int triple_is_cbranch(struct compile_state *state, struct triple *ins)
2618 {
2619         /* Is this triple a conditional branch instruction? */
2620         return triple_is_branch_type(state, ins, CBRANCH);
2621 }
2622
2623 static int triple_is_ubranch(struct compile_state *state, struct triple *ins)
2624 {
2625         /* Is this triple a unconditional branch instruction? */
2626         unsigned type;
2627         valid_ins(state, ins);
2628         type = BRANCH_BITS(table_ops[ins->op].flags);
2629         return (type != 0) && (type != CBRANCH);
2630 }
2631
2632 static int triple_is_call(struct compile_state *state, struct triple *ins)
2633 {
2634         /* Is this triple a call instruction? */
2635         return triple_is_branch_type(state, ins, CALLBRANCH);
2636 }
2637
2638 static int triple_is_ret(struct compile_state *state, struct triple *ins)
2639 {
2640         /* Is this triple a return instruction? */
2641         return triple_is_branch_type(state, ins, RETBRANCH);
2642 }
2643
2644 static int triple_is_simple_ubranch(struct compile_state *state, struct triple *ins)
2645 {
2646         /* Is this triple an unconditional branch and not a call or a
2647          * return? */
2648         return triple_is_branch_type(state, ins, UBRANCH);
2649 }
2650
2651 static int triple_is_end(struct compile_state *state, struct triple *ins)
2652 {
2653         return triple_is_branch_type(state, ins, ENDBRANCH);
2654 }
2655
2656 static int triple_is_label(struct compile_state *state, struct triple *ins)
2657 {
2658         valid_ins(state, ins);
2659         return (ins->op == OP_LABEL);
2660 }
2661
2662 static struct triple *triple_to_block_start(
2663         struct compile_state *state, struct triple *start)
2664 {
2665         while(!triple_is_branch(state, start->prev) &&
2666                 (!triple_is_label(state, start) || !start->use)) {
2667                 start = start->prev;
2668         }
2669         return start;
2670 }
2671
2672 static int triple_is_def(struct compile_state *state, struct triple *ins)
2673 {
2674         /* This function is used to determine which triples need
2675          * a register.
2676          */
2677         int is_def;
2678         valid_ins(state, ins);
2679         is_def = (table_ops[ins->op].flags & DEF) == DEF;
2680         if (ins->lhs >= 1) {
2681                 is_def = 0;
2682         }
2683         return is_def;
2684 }
2685
2686 static int triple_is_structural(struct compile_state *state, struct triple *ins)
2687 {
2688         int is_structural;
2689         valid_ins(state, ins);
2690         is_structural = (table_ops[ins->op].flags & STRUCTURAL) == STRUCTURAL;
2691         return is_structural;
2692 }
2693
2694 static int triple_is_part(struct compile_state *state, struct triple *ins)
2695 {
2696         int is_part;
2697         valid_ins(state, ins);
2698         is_part = (table_ops[ins->op].flags & PART) == PART;
2699         return is_part;
2700 }
2701
2702 static int triple_is_auto_var(struct compile_state *state, struct triple *ins)
2703 {
2704         return (ins->op == OP_PIECE) && (MISC(ins, 0)->op == OP_ADECL);
2705 }
2706
2707 static struct triple **triple_iter(struct compile_state *state,
2708         size_t count, struct triple **vector,
2709         struct triple *ins, struct triple **last)
2710 {
2711         struct triple **ret;
2712         ret = 0;
2713         if (count) {
2714                 if (!last) {
2715                         ret = vector;
2716                 }
2717                 else if ((last >= vector) && (last < (vector + count - 1))) {
2718                         ret = last + 1;
2719                 }
2720         }
2721         return ret;
2722         
2723 }
2724
2725 static struct triple **triple_lhs(struct compile_state *state,
2726         struct triple *ins, struct triple **last)
2727 {
2728         return triple_iter(state, ins->lhs, &LHS(ins,0), 
2729                 ins, last);
2730 }
2731
2732 static struct triple **triple_rhs(struct compile_state *state,
2733         struct triple *ins, struct triple **last)
2734 {
2735         return triple_iter(state, ins->rhs, &RHS(ins,0), 
2736                 ins, last);
2737 }
2738
2739 static struct triple **triple_misc(struct compile_state *state,
2740         struct triple *ins, struct triple **last)
2741 {
2742         return triple_iter(state, ins->misc, &MISC(ins,0), 
2743                 ins, last);
2744 }
2745
2746 static struct triple **do_triple_targ(struct compile_state *state,
2747         struct triple *ins, struct triple **last, int call_edges, int next_edges)
2748 {
2749         size_t count;
2750         struct triple **ret, **vector;
2751         int next_is_targ;
2752         ret = 0;
2753         count = ins->targ;
2754         next_is_targ = 0;
2755         if (triple_is_cbranch(state, ins)) {
2756                 next_is_targ = 1;
2757         }
2758         if (!call_edges && triple_is_call(state, ins)) {
2759                 count = 0;
2760         }
2761         if (next_edges && triple_is_call(state, ins)) {
2762                 next_is_targ = 1;
2763         }
2764         vector = &TARG(ins, 0);
2765         if (!ret && next_is_targ) {
2766                 if (!last) {
2767                         ret = &ins->next;
2768                 } else if (last == &ins->next) {
2769                         last = 0;
2770                 }
2771         }
2772         if (!ret && count) {
2773                 if (!last) {
2774                         ret = vector;
2775                 }
2776                 else if ((last >= vector) && (last < (vector + count - 1))) {
2777                         ret = last + 1;
2778                 }
2779                 else if (last == vector + count - 1) {
2780                         last = 0;
2781                 }
2782         }
2783         if (!ret && triple_is_ret(state, ins) && call_edges) {
2784                 struct triple_set *use;
2785                 for(use = ins->use; use; use = use->next) {
2786                         if (!triple_is_call(state, use->member)) {
2787                                 continue;
2788                         }
2789                         if (!last) {
2790                                 ret = &use->member->next;
2791                                 break;
2792                         }
2793                         else if (last == &use->member->next) {
2794                                 last = 0;
2795                         }
2796                 }
2797         }
2798         return ret;
2799 }
2800
2801 static struct triple **triple_targ(struct compile_state *state,
2802         struct triple *ins, struct triple **last)
2803 {
2804         return do_triple_targ(state, ins, last, 1, 1);
2805 }
2806
2807 static struct triple **triple_edge_targ(struct compile_state *state,
2808         struct triple *ins, struct triple **last)
2809 {
2810         return do_triple_targ(state, ins, last, 
2811                 state->functions_joined, !state->functions_joined);
2812 }
2813
2814 static struct triple *after_lhs(struct compile_state *state, struct triple *ins)
2815 {
2816         struct triple *next;
2817         int lhs, i;
2818         lhs = ins->lhs;
2819         next = ins->next;
2820         for(i = 0; i < lhs; i++) {
2821                 struct triple *piece;
2822                 piece = LHS(ins, i);
2823                 if (next != piece) {
2824                         internal_error(state, ins, "malformed lhs on %s",
2825                                 tops(ins->op));
2826                 }
2827                 if (next->op != OP_PIECE) {
2828                         internal_error(state, ins, "bad lhs op %s at %d on %s",
2829                                 tops(next->op), i, tops(ins->op));
2830                 }
2831                 if (next->u.cval != i) {
2832                         internal_error(state, ins, "bad u.cval of %d %d expected",
2833                                 next->u.cval, i);
2834                 }
2835                 next = next->next;
2836         }
2837         return next;
2838 }
2839
2840 /* Function piece accessor functions */
2841 static struct triple *do_farg(struct compile_state *state, 
2842         struct triple *func, unsigned index)
2843 {
2844         struct type *ftype;
2845         struct triple *first, *arg;
2846         unsigned i;
2847
2848         ftype = func->type;
2849         if((index < 0) || (index >= (ftype->elements + 2))) {
2850                 internal_error(state, func, "bad argument index: %d", index);
2851         }
2852         first = RHS(func, 0);
2853         arg = first->next;
2854         for(i = 0; i < index; i++, arg = after_lhs(state, arg)) {
2855                 /* do nothing */
2856         }
2857         if (arg->op != OP_ADECL) {
2858                 internal_error(state, 0, "arg not adecl?");
2859         }
2860         return arg;
2861 }
2862 static struct triple *fresult(struct compile_state *state, struct triple *func)
2863 {
2864         return do_farg(state, func, 0);
2865 }
2866 static struct triple *fretaddr(struct compile_state *state, struct triple *func)
2867 {
2868         return do_farg(state, func, 1);
2869 }
2870 static struct triple *farg(struct compile_state *state, 
2871         struct triple *func, unsigned index)
2872 {
2873         return do_farg(state, func, index + 2);
2874 }
2875
2876
2877 static void display_func(struct compile_state *state, FILE *fp, struct triple *func)
2878 {
2879         struct triple *first, *ins;
2880         fprintf(fp, "display_func %s\n", func->type->type_ident->name);
2881         first = ins = RHS(func, 0);
2882         do {
2883                 if (triple_is_label(state, ins) && ins->use) {
2884                         fprintf(fp, "%p:\n", ins);
2885                 }
2886                 display_triple(fp, ins);
2887
2888                 if (triple_is_branch(state, ins)) {
2889                         fprintf(fp, "\n");
2890                 }
2891                 if (ins->next->prev != ins) {
2892                         internal_error(state, ins->next, "bad prev");
2893                 }
2894                 ins = ins->next;
2895         } while(ins != first);
2896 }
2897
2898 static void verify_use(struct compile_state *state,
2899         struct triple *user, struct triple *used)
2900 {
2901         int size, i;
2902         size = TRIPLE_SIZE(user);
2903         for(i = 0; i < size; i++) {
2904                 if (user->param[i] == used) {
2905                         break;
2906                 }
2907         }
2908         if (triple_is_branch(state, user)) {
2909                 if (user->next == used) {
2910                         i = -1;
2911                 }
2912         }
2913         if (i == size) {
2914                 internal_error(state, user, "%s(%p) does not use %s(%p)",
2915                         tops(user->op), user, tops(used->op), used);
2916         }
2917 }
2918
2919 static int find_rhs_use(struct compile_state *state, 
2920         struct triple *user, struct triple *used)
2921 {
2922         struct triple **param;
2923         int size, i;
2924         verify_use(state, user, used);
2925 #warning "AUDIT ME ->rhs"
2926         size = user->rhs;
2927         param = &RHS(user, 0);
2928         for(i = 0; i < size; i++) {
2929                 if (param[i] == used) {
2930                         return i;
2931                 }
2932         }
2933         return -1;
2934 }
2935
2936 static void free_triple(struct compile_state *state, struct triple *ptr)
2937 {
2938         size_t size;
2939         size = sizeof(*ptr) - sizeof(ptr->param) +
2940                 (sizeof(ptr->param[0])*TRIPLE_SIZE(ptr));
2941         ptr->prev->next = ptr->next;
2942         ptr->next->prev = ptr->prev;
2943         if (ptr->use) {
2944                 internal_error(state, ptr, "ptr->use != 0");
2945         }
2946         put_occurance(ptr->occurance);
2947         memset(ptr, -1, size);
2948         xfree(ptr);
2949 }
2950
2951 static void release_triple(struct compile_state *state, struct triple *ptr)
2952 {
2953         struct triple_set *set, *next;
2954         struct triple **expr;
2955         struct block *block;
2956         if (ptr == &unknown_triple) {
2957                 return;
2958         }
2959         valid_ins(state, ptr);
2960         /* Make certain the we are not the first or last element of a block */
2961         block = block_of_triple(state, ptr);
2962         if (block) {
2963                 if ((block->last == ptr) && (block->first == ptr)) {
2964                         block->last = block->first = 0;
2965                 }
2966                 else if (block->last == ptr) {
2967                         block->last = ptr->prev;
2968                 }
2969                 else if (block->first == ptr) {
2970                         block->first = ptr->next;
2971                 }
2972         }
2973         /* Remove ptr from use chains where it is the user */
2974         expr = triple_rhs(state, ptr, 0);
2975         for(; expr; expr = triple_rhs(state, ptr, expr)) {
2976                 if (*expr) {
2977                         unuse_triple(*expr, ptr);
2978                 }
2979         }
2980         expr = triple_lhs(state, ptr, 0);
2981         for(; expr; expr = triple_lhs(state, ptr, expr)) {
2982                 if (*expr) {
2983                         unuse_triple(*expr, ptr);
2984                 }
2985         }
2986         expr = triple_misc(state, ptr, 0);
2987         for(; expr; expr = triple_misc(state, ptr, expr)) {
2988                 if (*expr) {
2989                         unuse_triple(*expr, ptr);
2990                 }
2991         }
2992         expr = triple_targ(state, ptr, 0);
2993         for(; expr; expr = triple_targ(state, ptr, expr)) {
2994                 if (*expr){
2995                         unuse_triple(*expr, ptr);
2996                 }
2997         }
2998         /* Reomve ptr from use chains where it is used */
2999         for(set = ptr->use; set; set = next) {
3000                 next = set->next;
3001                 valid_ins(state, set->member);
3002                 expr = triple_rhs(state, set->member, 0);
3003                 for(; expr; expr = triple_rhs(state, set->member, expr)) {
3004                         if (*expr == ptr) {
3005                                 *expr = &unknown_triple;
3006                         }
3007                 }
3008                 expr = triple_lhs(state, set->member, 0);
3009                 for(; expr; expr = triple_lhs(state, set->member, expr)) {
3010                         if (*expr == ptr) {
3011                                 *expr = &unknown_triple;
3012                         }
3013                 }
3014                 expr = triple_misc(state, set->member, 0);
3015                 for(; expr; expr = triple_misc(state, set->member, expr)) {
3016                         if (*expr == ptr) {
3017                                 *expr = &unknown_triple;
3018                         }
3019                 }
3020                 expr = triple_targ(state, set->member, 0);
3021                 for(; expr; expr = triple_targ(state, set->member, expr)) {
3022                         if (*expr == ptr) {
3023                                 *expr = &unknown_triple;
3024                         }
3025                 }
3026                 unuse_triple(ptr, set->member);
3027         }
3028         free_triple(state, ptr);
3029 }
3030
3031 static void print_triples(struct compile_state *state);
3032 static void print_blocks(struct compile_state *state, const char *func, FILE *fp);
3033
3034 #define TOK_UNKNOWN     0
3035 #define TOK_SPACE       1
3036 #define TOK_SEMI        2
3037 #define TOK_LBRACE      3
3038 #define TOK_RBRACE      4
3039 #define TOK_COMMA       5
3040 #define TOK_EQ          6
3041 #define TOK_COLON       7
3042 #define TOK_LBRACKET    8
3043 #define TOK_RBRACKET    9
3044 #define TOK_LPAREN      10
3045 #define TOK_RPAREN      11
3046 #define TOK_STAR        12
3047 #define TOK_DOTS        13
3048 #define TOK_MORE        14
3049 #define TOK_LESS        15
3050 #define TOK_TIMESEQ     16
3051 #define TOK_DIVEQ       17
3052 #define TOK_MODEQ       18
3053 #define TOK_PLUSEQ      19
3054 #define TOK_MINUSEQ     20
3055 #define TOK_SLEQ        21
3056 #define TOK_SREQ        22
3057 #define TOK_ANDEQ       23
3058 #define TOK_XOREQ       24
3059 #define TOK_OREQ        25
3060 #define TOK_EQEQ        26
3061 #define TOK_NOTEQ       27
3062 #define TOK_QUEST       28
3063 #define TOK_LOGOR       29
3064 #define TOK_LOGAND      30
3065 #define TOK_OR          31
3066 #define TOK_AND         32
3067 #define TOK_XOR         33
3068 #define TOK_LESSEQ      34
3069 #define TOK_MOREEQ      35
3070 #define TOK_SL          36
3071 #define TOK_SR          37
3072 #define TOK_PLUS        38
3073 #define TOK_MINUS       39
3074 #define TOK_DIV         40
3075 #define TOK_MOD         41
3076 #define TOK_PLUSPLUS    42
3077 #define TOK_MINUSMINUS  43
3078 #define TOK_BANG        44
3079 #define TOK_ARROW       45
3080 #define TOK_DOT         46
3081 #define TOK_TILDE       47
3082 #define TOK_LIT_STRING  48
3083 #define TOK_LIT_CHAR    49
3084 #define TOK_LIT_INT     50
3085 #define TOK_LIT_FLOAT   51
3086 #define TOK_MACRO       52
3087 #define TOK_CONCATENATE 53
3088
3089 #define TOK_IDENT       54
3090 #define TOK_STRUCT_NAME 55
3091 #define TOK_ENUM_CONST  56
3092 #define TOK_TYPE_NAME   57
3093
3094 #define TOK_AUTO        58
3095 #define TOK_BREAK       59
3096 #define TOK_CASE        60
3097 #define TOK_CHAR        61
3098 #define TOK_CONST       62
3099 #define TOK_CONTINUE    63
3100 #define TOK_DEFAULT     64
3101 #define TOK_DO          65
3102 #define TOK_DOUBLE      66
3103 #define TOK_ELSE        67
3104 #define TOK_ENUM        68
3105 #define TOK_EXTERN      69
3106 #define TOK_FLOAT       70
3107 #define TOK_FOR         71
3108 #define TOK_GOTO        72
3109 #define TOK_IF          73
3110 #define TOK_INLINE      74
3111 #define TOK_INT         75
3112 #define TOK_LONG        76
3113 #define TOK_REGISTER    77
3114 #define TOK_RESTRICT    78
3115 #define TOK_RETURN      79
3116 #define TOK_SHORT       80
3117 #define TOK_SIGNED      81
3118 #define TOK_SIZEOF      82
3119 #define TOK_STATIC      83
3120 #define TOK_STRUCT      84
3121 #define TOK_SWITCH      85
3122 #define TOK_TYPEDEF     86
3123 #define TOK_UNION       87
3124 #define TOK_UNSIGNED    88
3125 #define TOK_VOID        89
3126 #define TOK_VOLATILE    90
3127 #define TOK_WHILE       91
3128 #define TOK_ASM         92
3129 #define TOK_ATTRIBUTE   93
3130 #define TOK_ALIGNOF     94
3131 #define TOK_FIRST_KEYWORD TOK_AUTO
3132 #define TOK_LAST_KEYWORD  TOK_ALIGNOF
3133
3134 #define TOK_MDEFINE       100
3135 #define TOK_MDEFINED      101
3136 #define TOK_MUNDEF        102
3137 #define TOK_MINCLUDE      103
3138 #define TOK_MLINE         104
3139 #define TOK_MERROR        105
3140 #define TOK_MWARNING      106
3141 #define TOK_MPRAGMA       107
3142 #define TOK_MIFDEF        108
3143 #define TOK_MIFNDEF       109
3144 #define TOK_MELIF         110
3145 #define TOK_MENDIF        111
3146
3147 #define TOK_FIRST_MACRO   TOK_MDEFINE
3148 #define TOK_LAST_MACRO    TOK_MENDIF
3149          
3150 #define TOK_MIF           112
3151 #define TOK_MELSE         113
3152 #define TOK_MIDENT        114
3153
3154 #define TOK_EOL           115
3155 #define TOK_EOF           116
3156
3157 static const char *tokens[] = {
3158 [TOK_UNKNOWN     ] = ":unknown:",
3159 [TOK_SPACE       ] = ":space:",
3160 [TOK_SEMI        ] = ";",
3161 [TOK_LBRACE      ] = "{",
3162 [TOK_RBRACE      ] = "}",
3163 [TOK_COMMA       ] = ",",
3164 [TOK_EQ          ] = "=",
3165 [TOK_COLON       ] = ":",
3166 [TOK_LBRACKET    ] = "[",
3167 [TOK_RBRACKET    ] = "]",
3168 [TOK_LPAREN      ] = "(",
3169 [TOK_RPAREN      ] = ")",
3170 [TOK_STAR        ] = "*",
3171 [TOK_DOTS        ] = "...",
3172 [TOK_MORE        ] = ">",
3173 [TOK_LESS        ] = "<",
3174 [TOK_TIMESEQ     ] = "*=",
3175 [TOK_DIVEQ       ] = "/=",
3176 [TOK_MODEQ       ] = "%=",
3177 [TOK_PLUSEQ      ] = "+=",
3178 [TOK_MINUSEQ     ] = "-=",
3179 [TOK_SLEQ        ] = "<<=",
3180 [TOK_SREQ        ] = ">>=",
3181 [TOK_ANDEQ       ] = "&=",
3182 [TOK_XOREQ       ] = "^=",
3183 [TOK_OREQ        ] = "|=",
3184 [TOK_EQEQ        ] = "==",
3185 [TOK_NOTEQ       ] = "!=",
3186 [TOK_QUEST       ] = "?",
3187 [TOK_LOGOR       ] = "||",
3188 [TOK_LOGAND      ] = "&&",
3189 [TOK_OR          ] = "|",
3190 [TOK_AND         ] = "&",
3191 [TOK_XOR         ] = "^",
3192 [TOK_LESSEQ      ] = "<=",
3193 [TOK_MOREEQ      ] = ">=",
3194 [TOK_SL          ] = "<<",
3195 [TOK_SR          ] = ">>",
3196 [TOK_PLUS        ] = "+",
3197 [TOK_MINUS       ] = "-",
3198 [TOK_DIV         ] = "/",
3199 [TOK_MOD         ] = "%",
3200 [TOK_PLUSPLUS    ] = "++",
3201 [TOK_MINUSMINUS  ] = "--",
3202 [TOK_BANG        ] = "!",
3203 [TOK_ARROW       ] = "->",
3204 [TOK_DOT         ] = ".",
3205 [TOK_TILDE       ] = "~",
3206 [TOK_LIT_STRING  ] = ":string:",
3207 [TOK_IDENT       ] = ":ident:",
3208 [TOK_TYPE_NAME   ] = ":typename:",
3209 [TOK_LIT_CHAR    ] = ":char:",
3210 [TOK_LIT_INT     ] = ":integer:",
3211 [TOK_LIT_FLOAT   ] = ":float:",
3212 [TOK_MACRO       ] = "#",
3213 [TOK_CONCATENATE ] = "##",
3214
3215 [TOK_AUTO        ] = "auto",
3216 [TOK_BREAK       ] = "break",
3217 [TOK_CASE        ] = "case",
3218 [TOK_CHAR        ] = "char",
3219 [TOK_CONST       ] = "const",
3220 [TOK_CONTINUE    ] = "continue",
3221 [TOK_DEFAULT     ] = "default",
3222 [TOK_DO          ] = "do",
3223 [TOK_DOUBLE      ] = "double",
3224 [TOK_ELSE        ] = "else",
3225 [TOK_ENUM        ] = "enum",
3226 [TOK_EXTERN      ] = "extern",
3227 [TOK_FLOAT       ] = "float",
3228 [TOK_FOR         ] = "for",
3229 [TOK_GOTO        ] = "goto",
3230 [TOK_IF          ] = "if",
3231 [TOK_INLINE      ] = "inline",
3232 [TOK_INT         ] = "int",
3233 [TOK_LONG        ] = "long",
3234 [TOK_REGISTER    ] = "register",
3235 [TOK_RESTRICT    ] = "restrict",
3236 [TOK_RETURN      ] = "return",
3237 [TOK_SHORT       ] = "short",
3238 [TOK_SIGNED      ] = "signed",
3239 [TOK_SIZEOF      ] = "sizeof",
3240 [TOK_STATIC      ] = "static",
3241 [TOK_STRUCT      ] = "struct",
3242 [TOK_SWITCH      ] = "switch",
3243 [TOK_TYPEDEF     ] = "typedef",
3244 [TOK_UNION       ] = "union",
3245 [TOK_UNSIGNED    ] = "unsigned",
3246 [TOK_VOID        ] = "void",
3247 [TOK_VOLATILE    ] = "volatile",
3248 [TOK_WHILE       ] = "while",
3249 [TOK_ASM         ] = "asm",
3250 [TOK_ATTRIBUTE   ] = "__attribute__",
3251 [TOK_ALIGNOF     ] = "__alignof__",
3252
3253 [TOK_MDEFINE     ] = "#define",
3254 [TOK_MDEFINED    ] = "#defined",
3255 [TOK_MUNDEF      ] = "#undef",
3256 [TOK_MINCLUDE    ] = "#include",
3257 [TOK_MLINE       ] = "#line",
3258 [TOK_MERROR      ] = "#error",
3259 [TOK_MWARNING    ] = "#warning",
3260 [TOK_MPRAGMA     ] = "#pragma",
3261 [TOK_MIFDEF      ] = "#ifdef",
3262 [TOK_MIFNDEF     ] = "#ifndef",
3263 [TOK_MELIF       ] = "#elif",
3264 [TOK_MENDIF      ] = "#endif",
3265
3266 [TOK_MIF         ] = "#if",
3267 [TOK_MELSE       ] = "#else",
3268 [TOK_MIDENT      ] = "#:ident:",
3269 [TOK_EOL         ] = "EOL", 
3270 [TOK_EOF         ] = "EOF",
3271 };
3272
3273 static unsigned int hash(const char *str, int str_len)
3274 {
3275         unsigned int hash;
3276         const char *end;
3277         end = str + str_len;
3278         hash = 0;
3279         for(; str < end; str++) {
3280                 hash = (hash *263) + *str;
3281         }
3282         hash = hash & (HASH_TABLE_SIZE -1);
3283         return hash;
3284 }
3285
3286 static struct hash_entry *lookup(
3287         struct compile_state *state, const char *name, int name_len)
3288 {
3289         struct hash_entry *entry;
3290         unsigned int index;
3291         index = hash(name, name_len);
3292         entry = state->hash_table[index];
3293         while(entry && 
3294                 ((entry->name_len != name_len) ||
3295                         (memcmp(entry->name, name, name_len) != 0))) {
3296                 entry = entry->next;
3297         }
3298         if (!entry) {
3299                 char *new_name;
3300                 /* Get a private copy of the name */
3301                 new_name = xmalloc(name_len + 1, "hash_name");
3302                 memcpy(new_name, name, name_len);
3303                 new_name[name_len] = '\0';
3304
3305                 /* Create a new hash entry */
3306                 entry = xcmalloc(sizeof(*entry), "hash_entry");
3307                 entry->next = state->hash_table[index];
3308                 entry->name = new_name;
3309                 entry->name_len = name_len;
3310
3311                 /* Place the new entry in the hash table */
3312                 state->hash_table[index] = entry;
3313         }
3314         return entry;
3315 }
3316
3317 static void ident_to_keyword(struct compile_state *state, struct token *tk)
3318 {
3319         struct hash_entry *entry;
3320         entry = tk->ident;
3321         if (entry && ((entry->tok == TOK_TYPE_NAME) ||
3322                 (entry->tok == TOK_ENUM_CONST) ||
3323                 ((entry->tok >= TOK_FIRST_KEYWORD) && 
3324                         (entry->tok <= TOK_LAST_KEYWORD)))) {
3325                 tk->tok = entry->tok;
3326         }
3327 }
3328
3329 static void ident_to_macro(struct compile_state *state, struct token *tk)
3330 {
3331         struct hash_entry *entry;
3332         entry = tk->ident;
3333         if (!entry)
3334                 return;
3335         if ((entry->tok >= TOK_FIRST_MACRO) && (entry->tok <= TOK_LAST_MACRO)) {
3336                 tk->tok = entry->tok;
3337         }
3338         else if (entry->tok == TOK_IF) {
3339                 tk->tok = TOK_MIF;
3340         }
3341         else if (entry->tok == TOK_ELSE) {
3342                 tk->tok = TOK_MELSE;
3343         }
3344         else {
3345                 tk->tok = TOK_MIDENT;
3346         }
3347 }
3348
3349 static void hash_keyword(
3350         struct compile_state *state, const char *keyword, int tok)
3351 {
3352         struct hash_entry *entry;
3353         entry = lookup(state, keyword, strlen(keyword));
3354         if (entry && entry->tok != TOK_UNKNOWN) {
3355                 die("keyword %s already hashed", keyword);
3356         }
3357         entry->tok  = tok;
3358 }
3359
3360 static void romcc_symbol(
3361         struct compile_state *state, struct hash_entry *ident,
3362         struct symbol **chain, struct triple *def, struct type *type, int depth)
3363 {
3364         struct symbol *sym;
3365         if (*chain && ((*chain)->scope_depth >= depth)) {
3366                 error(state, 0, "%s already defined", ident->name);
3367         }
3368         sym = xcmalloc(sizeof(*sym), "symbol");
3369         sym->ident = ident;
3370         sym->def   = def;
3371         sym->type  = type;
3372         sym->scope_depth = depth;
3373         sym->next = *chain;
3374         *chain    = sym;
3375 }
3376
3377 static void symbol(
3378         struct compile_state *state, struct hash_entry *ident,
3379         struct symbol **chain, struct triple *def, struct type *type)
3380 {
3381         romcc_symbol(state, ident, chain, def, type, state->scope_depth);
3382 }
3383
3384 static void var_symbol(struct compile_state *state, 
3385         struct hash_entry *ident, struct triple *def)
3386 {
3387         if ((def->type->type & TYPE_MASK) == TYPE_PRODUCT) {
3388                 internal_error(state, 0, "bad var type");
3389         }
3390         symbol(state, ident, &ident->sym_ident, def, def->type);
3391 }
3392
3393 static void label_symbol(struct compile_state *state, 
3394         struct hash_entry *ident, struct triple *label, int depth)
3395 {
3396         romcc_symbol(state, ident, &ident->sym_label, label, &void_type, depth);
3397 }
3398
3399 static void start_scope(struct compile_state *state)
3400 {
3401         state->scope_depth++;
3402 }
3403
3404 static void end_scope_syms(struct compile_state *state,
3405         struct symbol **chain, int depth)
3406 {
3407         struct symbol *sym, *next;
3408         sym = *chain;
3409         while(sym && (sym->scope_depth == depth)) {
3410                 next = sym->next;
3411                 xfree(sym);
3412                 sym = next;
3413         }
3414         *chain = sym;
3415 }
3416
3417 static void end_scope(struct compile_state *state)
3418 {
3419         int i;
3420         int depth;
3421         /* Walk through the hash table and remove all symbols
3422          * in the current scope. 
3423          */
3424         depth = state->scope_depth;
3425         for(i = 0; i < HASH_TABLE_SIZE; i++) {
3426                 struct hash_entry *entry;
3427                 entry = state->hash_table[i];
3428                 while(entry) {
3429                         end_scope_syms(state, &entry->sym_label, depth);
3430                         end_scope_syms(state, &entry->sym_tag,   depth);
3431                         end_scope_syms(state, &entry->sym_ident, depth);
3432                         entry = entry->next;
3433                 }
3434         }
3435         state->scope_depth = depth - 1;
3436 }
3437
3438 static void register_keywords(struct compile_state *state)
3439 {
3440         hash_keyword(state, "auto",          TOK_AUTO);
3441         hash_keyword(state, "break",         TOK_BREAK);
3442         hash_keyword(state, "case",          TOK_CASE);
3443         hash_keyword(state, "char",          TOK_CHAR);
3444         hash_keyword(state, "const",         TOK_CONST);
3445         hash_keyword(state, "continue",      TOK_CONTINUE);
3446         hash_keyword(state, "default",       TOK_DEFAULT);
3447         hash_keyword(state, "do",            TOK_DO);
3448         hash_keyword(state, "double",        TOK_DOUBLE);
3449         hash_keyword(state, "else",          TOK_ELSE);
3450         hash_keyword(state, "enum",          TOK_ENUM);
3451         hash_keyword(state, "extern",        TOK_EXTERN);
3452         hash_keyword(state, "float",         TOK_FLOAT);
3453         hash_keyword(state, "for",           TOK_FOR);
3454         hash_keyword(state, "goto",          TOK_GOTO);
3455         hash_keyword(state, "if",            TOK_IF);
3456         hash_keyword(state, "inline",        TOK_INLINE);
3457         hash_keyword(state, "int",           TOK_INT);
3458         hash_keyword(state, "long",          TOK_LONG);
3459         hash_keyword(state, "register",      TOK_REGISTER);
3460         hash_keyword(state, "restrict",      TOK_RESTRICT);
3461         hash_keyword(state, "return",        TOK_RETURN);
3462         hash_keyword(state, "short",         TOK_SHORT);
3463         hash_keyword(state, "signed",        TOK_SIGNED);
3464         hash_keyword(state, "sizeof",        TOK_SIZEOF);
3465         hash_keyword(state, "static",        TOK_STATIC);
3466         hash_keyword(state, "struct",        TOK_STRUCT);
3467         hash_keyword(state, "switch",        TOK_SWITCH);
3468         hash_keyword(state, "typedef",       TOK_TYPEDEF);
3469         hash_keyword(state, "union",         TOK_UNION);
3470         hash_keyword(state, "unsigned",      TOK_UNSIGNED);
3471         hash_keyword(state, "void",          TOK_VOID);
3472         hash_keyword(state, "volatile",      TOK_VOLATILE);
3473         hash_keyword(state, "__volatile__",  TOK_VOLATILE);
3474         hash_keyword(state, "while",         TOK_WHILE);
3475         hash_keyword(state, "asm",           TOK_ASM);
3476         hash_keyword(state, "__asm__",       TOK_ASM);
3477         hash_keyword(state, "__attribute__", TOK_ATTRIBUTE);
3478         hash_keyword(state, "__alignof__",   TOK_ALIGNOF);
3479 }
3480
3481 static void register_macro_keywords(struct compile_state *state)
3482 {
3483         hash_keyword(state, "define",        TOK_MDEFINE);
3484         hash_keyword(state, "defined",       TOK_MDEFINED);
3485         hash_keyword(state, "undef",         TOK_MUNDEF);
3486         hash_keyword(state, "include",       TOK_MINCLUDE);
3487         hash_keyword(state, "line",          TOK_MLINE);
3488         hash_keyword(state, "error",         TOK_MERROR);
3489         hash_keyword(state, "warning",       TOK_MWARNING);
3490         hash_keyword(state, "pragma",        TOK_MPRAGMA);
3491         hash_keyword(state, "ifdef",         TOK_MIFDEF);
3492         hash_keyword(state, "ifndef",        TOK_MIFNDEF);
3493         hash_keyword(state, "elif",          TOK_MELIF);
3494         hash_keyword(state, "endif",         TOK_MENDIF);
3495 }
3496
3497
3498 static void undef_macro(struct compile_state *state, struct hash_entry *ident)
3499 {
3500         if (ident->sym_define != 0) {
3501                 struct macro *macro;
3502                 struct macro_arg *arg, *anext;
3503                 macro = ident->sym_define;
3504                 ident->sym_define = 0;
3505                 
3506                 /* Free the macro arguments... */
3507                 anext = macro->args;
3508                 while(anext) {
3509                         arg = anext;
3510                         anext = arg->next;
3511                         xfree(arg);
3512                 }
3513
3514                 /* Free the macro buffer */
3515                 xfree(macro->buf);
3516
3517                 /* Now free the macro itself */
3518                 xfree(macro);
3519         }
3520 }
3521
3522 static void do_define_macro(struct compile_state *state, 
3523         struct hash_entry *ident, const char *body, 
3524         int argc, struct macro_arg *args)
3525 {
3526         struct macro *macro;
3527         struct macro_arg *arg;
3528         size_t body_len;
3529
3530         /* Find the length of the body */
3531         body_len = strlen(body);
3532         macro = ident->sym_define;
3533         if (macro != 0) {
3534                 int identical_bodies, identical_args;
3535                 struct macro_arg *oarg;
3536                 /* Explicitly allow identical redfinitions of the same macro */
3537                 identical_bodies = 
3538                         (macro->buf_len == body_len) &&
3539                         (memcmp(macro->buf, body, body_len) == 0);
3540                 identical_args = macro->argc == argc;
3541                 oarg = macro->args;
3542                 arg = args;
3543                 while(identical_args && arg) {
3544                         identical_args = oarg->ident == arg->ident;
3545                         arg = arg->next;
3546                         oarg = oarg->next;
3547                 }
3548                 if (identical_bodies && identical_args) {
3549                         xfree(body);
3550                         return;
3551                 }
3552                 error(state, 0, "macro %s already defined\n", ident->name);
3553         }
3554 #if 0
3555         fprintf(state->errout, "#define %s: `%*.*s'\n",
3556                 ident->name, body_len, body_len, body);
3557 #endif
3558         macro = xmalloc(sizeof(*macro), "macro");
3559         macro->ident   = ident;
3560         macro->buf     = body;
3561         macro->buf_len = body_len;
3562         macro->args    = args;
3563         macro->argc    = argc;
3564
3565         ident->sym_define = macro;
3566 }
3567         
3568 static void define_macro(
3569         struct compile_state *state,
3570         struct hash_entry *ident,
3571         const char *body, int body_len,
3572         int argc, struct macro_arg *args)
3573 {
3574         char *buf;
3575         buf = xmalloc(body_len + 1, "macro buf");
3576         memcpy(buf, body, body_len);
3577         buf[body_len] = '\0';
3578         do_define_macro(state, ident, buf, argc, args);
3579 }
3580
3581 static void register_builtin_macro(struct compile_state *state,
3582         const char *name, const char *value)
3583 {
3584         struct hash_entry *ident;
3585
3586         if (value[0] == '(') {
3587                 internal_error(state, 0, "Builtin macros with arguments not supported");
3588         }
3589         ident = lookup(state, name, strlen(name));
3590         define_macro(state, ident, value, strlen(value), -1, 0);
3591 }
3592
3593 static void register_builtin_macros(struct compile_state *state)
3594 {
3595         char buf[30];
3596         char scratch[30];
3597         time_t now;
3598         struct tm *tm;
3599         now = time(NULL);
3600         tm = localtime(&now);
3601
3602         register_builtin_macro(state, "__ROMCC__", VERSION_MAJOR);
3603         register_builtin_macro(state, "__ROMCC_MINOR__", VERSION_MINOR);
3604         register_builtin_macro(state, "__FILE__", "\"This should be the filename\"");
3605         register_builtin_macro(state, "__LINE__", "54321");
3606
3607         strftime(scratch, sizeof(scratch), "%b %e %Y", tm);
3608         sprintf(buf, "\"%s\"", scratch);
3609         register_builtin_macro(state, "__DATE__", buf);
3610
3611         strftime(scratch, sizeof(scratch), "%H:%M:%S", tm);
3612         sprintf(buf, "\"%s\"", scratch);
3613         register_builtin_macro(state, "__TIME__", buf);
3614
3615         /* I can't be a conforming implementation of C :( */
3616         register_builtin_macro(state, "__STDC__", "0");
3617         /* In particular I don't conform to C99 */
3618         register_builtin_macro(state, "__STDC_VERSION__", "199901L");
3619         
3620 }
3621
3622 static void process_cmdline_macros(struct compile_state *state)
3623 {
3624         const char **macro, *name;
3625         struct hash_entry *ident;
3626         for(macro = state->compiler->defines; (name = *macro); macro++) {
3627                 const char *body;
3628                 size_t name_len;
3629
3630                 name_len = strlen(name);
3631                 body = strchr(name, '=');
3632                 if (!body) {
3633                         body = "\0";
3634                 } else {
3635                         name_len = body - name;
3636                         body++;
3637                 }
3638                 ident = lookup(state, name, name_len);
3639                 define_macro(state, ident, body, strlen(body), -1, 0);
3640         }
3641         for(macro = state->compiler->undefs; (name = *macro); macro++) {
3642                 ident = lookup(state, name, strlen(name));
3643                 undef_macro(state, ident);
3644         }
3645 }
3646
3647 static int spacep(int c)
3648 {
3649         int ret = 0;
3650         switch(c) {
3651         case ' ':
3652         case '\t':
3653         case '\f':
3654         case '\v':
3655         case '\r':
3656                 ret = 1;
3657                 break;
3658         }
3659         return ret;
3660 }
3661
3662 static int digitp(int c)
3663 {
3664         int ret = 0;
3665         switch(c) {
3666         case '0': case '1': case '2': case '3': case '4': 
3667         case '5': case '6': case '7': case '8': case '9':
3668                 ret = 1;
3669                 break;
3670         }
3671         return ret;
3672 }
3673 static int digval(int c)
3674 {
3675         int val = -1;
3676         if ((c >= '0') && (c <= '9')) {
3677                 val = c - '0';
3678         }
3679         return val;
3680 }
3681
3682 static int hexdigitp(int c)
3683 {
3684         int ret = 0;
3685         switch(c) {
3686         case '0': case '1': case '2': case '3': case '4': 
3687         case '5': case '6': case '7': case '8': case '9':
3688         case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
3689         case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
3690                 ret = 1;
3691                 break;
3692         }
3693         return ret;
3694 }
3695 static int hexdigval(int c) 
3696 {
3697         int val = -1;
3698         if ((c >= '0') && (c <= '9')) {
3699                 val = c - '0';
3700         }
3701         else if ((c >= 'A') && (c <= 'F')) {
3702                 val = 10 + (c - 'A');
3703         }
3704         else if ((c >= 'a') && (c <= 'f')) {
3705                 val = 10 + (c - 'a');
3706         }
3707         return val;
3708 }
3709
3710 static int octdigitp(int c)
3711 {
3712         int ret = 0;
3713         switch(c) {
3714         case '0': case '1': case '2': case '3': 
3715         case '4': case '5': case '6': case '7':
3716                 ret = 1;
3717                 break;
3718         }
3719         return ret;
3720 }
3721 static int octdigval(int c)
3722 {
3723         int val = -1;
3724         if ((c >= '0') && (c <= '7')) {
3725                 val = c - '0';
3726         }
3727         return val;
3728 }
3729
3730 static int letterp(int c)
3731 {
3732         int ret = 0;
3733         switch(c) {
3734         case 'a': case 'b': case 'c': case 'd': case 'e':
3735         case 'f': case 'g': case 'h': case 'i': case 'j':
3736         case 'k': case 'l': case 'm': case 'n': case 'o':
3737         case 'p': case 'q': case 'r': case 's': case 't':
3738         case 'u': case 'v': case 'w': case 'x': case 'y':
3739         case 'z':
3740         case 'A': case 'B': case 'C': case 'D': case 'E':
3741         case 'F': case 'G': case 'H': case 'I': case 'J':
3742         case 'K': case 'L': case 'M': case 'N': case 'O':
3743         case 'P': case 'Q': case 'R': case 'S': case 'T':
3744         case 'U': case 'V': case 'W': case 'X': case 'Y':
3745         case 'Z':
3746         case '_':
3747                 ret = 1;
3748                 break;
3749         }
3750         return ret;
3751 }
3752
3753 static const char *identifier(const char *str, const char *end)
3754 {
3755         if (letterp(*str)) {
3756                 for(; str < end; str++) {
3757                         int c;
3758                         c = *str;
3759                         if (!letterp(c) && !digitp(c)) {
3760                                 break;
3761                         }
3762                 }
3763         }
3764         return str;
3765 }
3766
3767 static int char_value(struct compile_state *state,
3768         const signed char **strp, const signed char *end)
3769 {
3770         const signed char *str;
3771         int c;
3772         str = *strp;
3773         c = *str++;
3774         if ((c == '\\') && (str < end)) {
3775                 switch(*str) {
3776                 case 'n':  c = '\n'; str++; break;
3777                 case 't':  c = '\t'; str++; break;
3778                 case 'v':  c = '\v'; str++; break;
3779                 case 'b':  c = '\b'; str++; break;
3780                 case 'r':  c = '\r'; str++; break;
3781                 case 'f':  c = '\f'; str++; break;
3782                 case 'a':  c = '\a'; str++; break;
3783                 case '\\': c = '\\'; str++; break;
3784                 case '?':  c = '?';  str++; break;
3785                 case '\'': c = '\''; str++; break;
3786                 case '"':  c = '"';  str++; break;
3787                 case 'x': 
3788                         c = 0;
3789                         str++;
3790                         while((str < end) && hexdigitp(*str)) {
3791                                 c <<= 4;
3792                                 c += hexdigval(*str);
3793                                 str++;
3794                         }
3795                         break;
3796                 case '0': case '1': case '2': case '3': 
3797                 case '4': case '5': case '6': case '7':
3798                         c = 0;
3799                         while((str < end) && octdigitp(*str)) {
3800                                 c <<= 3;
3801                                 c += octdigval(*str);
3802                                 str++;
3803                         }
3804                         break;
3805                 default:
3806                         error(state, 0, "Invalid character constant");
3807                         break;
3808                 }
3809         }
3810         *strp = str;
3811         return c;
3812 }
3813
3814 static const char *next_char(struct file_state *file, const char *pos, int index)
3815 {
3816         const char *end = file->buf + file->size;
3817         while(pos < end) {
3818                 /* Lookup the character */
3819                 int size = 1;
3820                 int c = *pos;
3821                 /* Is this a trigraph? */
3822                 if (file->trigraphs &&
3823                         (c == '?') && ((end - pos) >= 3) && (pos[1] == '?')) 
3824                 {
3825                         switch(pos[2]) {
3826                         case '=': c = '#'; break;
3827                         case '/': c = '\\'; break;
3828                         case '\'': c = '^'; break;
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                         }
3836                         if (c != '?') {
3837                                 size = 3;
3838                         }
3839                 }
3840                 /* Is this an escaped newline? */
3841                 if (file->join_lines &&
3842                         (c == '\\') && (pos + size < end) && (pos[1] == '\n')) 
3843                 {
3844                         /* At the start of a line just eat it */
3845                         if (pos == file->pos) {
3846                                 file->line++;
3847                                 file->report_line++;
3848                                 file->line_start = pos + size + 1;
3849                         }
3850                         pos += size + 1;
3851                 }
3852                 /* Do I need to ga any farther? */
3853                 else if (index == 0) {
3854                         break;
3855                 }
3856                 /* Process a normal character */
3857                 else {
3858                         pos += size;
3859                         index -= 1;
3860                 }
3861         }
3862         return pos;
3863 }
3864
3865 static int get_char(struct file_state *file, const char *pos)
3866 {
3867         const char *end = file->buf + file->size;
3868         int c;
3869         c = -1;
3870         pos = next_char(file, pos, 0);
3871         if (pos < end) {
3872                 /* Lookup the character */
3873                 c = *pos;
3874                 /* If it is a trigraph get the trigraph value */
3875                 if (file->trigraphs &&
3876                         (c == '?') && ((end - pos) >= 3) && (pos[1] == '?')) 
3877                 {
3878                         switch(pos[2]) {
3879                         case '=': c = '#'; break;
3880                         case '/': c = '\\'; break;
3881                         case '\'': c = '^'; break;
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                         }
3889                 }
3890         }
3891         return c;
3892 }
3893
3894 static void eat_chars(struct file_state *file, const char *targ)
3895 {
3896         const char *pos = file->pos;
3897         while(pos < targ) {
3898                 /* Do we have a newline? */
3899                 if (pos[0] == '\n') {
3900                         file->line++;
3901                         file->report_line++;
3902                         file->line_start = pos + 1;
3903                 }
3904                 pos++;
3905         }
3906         file->pos = pos;
3907 }
3908
3909
3910 static size_t char_strlen(struct file_state *file, const char *src, const char *end)
3911 {
3912         size_t len;
3913         len = 0;
3914         while(src < end) {
3915                 src = next_char(file, src, 1);
3916                 len++;
3917         }
3918         return len;
3919 }
3920
3921 static void char_strcpy(char *dest, 
3922         struct file_state *file, const char *src, const char *end)
3923 {
3924         while(src < end) {
3925                 int c;
3926                 c = get_char(file, src);
3927                 src = next_char(file, src, 1);
3928                 *dest++ = c;
3929         }
3930 }
3931
3932 static char *char_strdup(struct file_state *file, 
3933         const char *start, const char *end, const char *id)
3934 {
3935         char *str;
3936         size_t str_len;
3937         str_len = char_strlen(file, start, end);
3938         str = xcmalloc(str_len + 1, id);
3939         char_strcpy(str, file, start, end);
3940         str[str_len] = '\0';
3941         return str;
3942 }
3943
3944 static const char *after_digits(struct file_state *file, const char *ptr)
3945 {
3946         while(digitp(get_char(file, ptr))) {
3947                 ptr = next_char(file, ptr, 1);
3948         }
3949         return ptr;
3950 }
3951
3952 static const char *after_octdigits(struct file_state *file, const char *ptr)
3953 {
3954         while(octdigitp(get_char(file, ptr))) {
3955                 ptr = next_char(file, ptr, 1);
3956         }
3957         return ptr;
3958 }
3959
3960 static const char *after_hexdigits(struct file_state *file, const char *ptr)
3961 {
3962         while(hexdigitp(get_char(file, ptr))) {
3963                 ptr = next_char(file, ptr, 1);
3964         }
3965         return ptr;
3966 }
3967
3968 static const char *after_alnums(struct file_state *file, const char *ptr)
3969 {
3970         int c;
3971         c = get_char(file, ptr);
3972         while(letterp(c) || digitp(c)) {
3973                 ptr = next_char(file, ptr, 1);
3974                 c = get_char(file, ptr);
3975         }
3976         return ptr;
3977 }
3978
3979 static void save_string(struct file_state *file,
3980         struct token *tk, const char *start, const char *end, const char *id)
3981 {
3982         char *str;
3983
3984         /* Create a private copy of the string */
3985         str = char_strdup(file, start, end, id);
3986
3987         /* Store the copy in the token */
3988         tk->val.str = str;
3989         tk->str_len = strlen(str);
3990 }
3991
3992 static void raw_next_token(struct compile_state *state, 
3993         struct file_state *file, struct token *tk)
3994 {
3995         const char *token;
3996         int c, c1, c2, c3;
3997         const char *tokp;
3998         int eat;
3999         int tok;
4000
4001         tk->str_len = 0;
4002         tk->ident = 0;
4003         token = tokp = next_char(file, file->pos, 0);
4004         tok = TOK_UNKNOWN;
4005         c  = get_char(file, tokp);
4006         tokp = next_char(file, tokp, 1);
4007         eat = 0;
4008         c1 = get_char(file, tokp);
4009         c2 = get_char(file, next_char(file, tokp, 1));
4010         c3 = get_char(file, next_char(file, tokp, 2));
4011
4012         /* The end of the file */
4013         if (c == -1) {
4014                 tok = TOK_EOF;
4015         }
4016         /* Whitespace */
4017         else if (spacep(c)) {
4018                 tok = TOK_SPACE;
4019                 while (spacep(get_char(file, tokp))) {
4020                         tokp = next_char(file, tokp, 1);
4021                 }
4022         }
4023         /* EOL Comments */
4024         else if ((c == '/') && (c1 == '/')) {
4025                 tok = TOK_SPACE;
4026                 tokp = next_char(file, tokp, 1);
4027                 while((c = get_char(file, tokp)) != -1) {
4028                         tokp = next_char(file, tokp, 1);
4029                         if (c == '\n') {
4030                                 break;
4031                         }
4032                 }
4033         }
4034         /* Comments */
4035         else if ((c == '/') && (c1 == '*')) {
4036                 tokp = next_char(file, tokp, 2);
4037                 c = c2;
4038                 while((c1 = get_char(file, tokp)) != -1) {
4039                         tokp = next_char(file, tokp, 1);
4040                         if ((c == '*') && (c1 == '/')) {
4041                                 tok = TOK_SPACE;
4042                                 break;
4043                         }
4044                         c = c1;
4045                 }
4046                 if (tok == TOK_UNKNOWN) {
4047                         error(state, 0, "unterminated comment");
4048                 }
4049         }
4050         /* string constants */
4051         else if ((c == '"') || ((c == 'L') && (c1 == '"'))) {
4052                 int wchar, multiline;
4053
4054                 wchar = 0;
4055                 multiline = 0;
4056                 if (c == 'L') {
4057                         wchar = 1;
4058                         tokp = next_char(file, tokp, 1);
4059                 }
4060                 while((c = get_char(file, tokp)) != -1) {
4061                         tokp = next_char(file, tokp, 1);
4062                         if (c == '\n') {
4063                                 multiline = 1;
4064                         }
4065                         else if (c == '\\') {
4066                                 tokp = next_char(file, tokp, 1);
4067                         }
4068                         else if (c == '"') {
4069                                 tok = TOK_LIT_STRING;
4070                                 break;
4071                         }
4072                 }
4073                 if (tok == TOK_UNKNOWN) {
4074                         error(state, 0, "unterminated string constant");
4075                 }
4076                 if (multiline) {
4077                         warning(state, 0, "multiline string constant");
4078                 }
4079
4080                 /* Save the string value */
4081                 save_string(file, tk, token, tokp, "literal string");
4082         }
4083         /* character constants */
4084         else if ((c == '\'') || ((c == 'L') && (c1 == '\''))) {
4085                 int wchar, multiline;
4086
4087                 wchar = 0;
4088                 multiline = 0;
4089                 if (c == 'L') {
4090                         wchar = 1;
4091                         tokp = next_char(file, tokp, 1);
4092                 }
4093                 while((c = get_char(file, tokp)) != -1) {
4094                         tokp = next_char(file, tokp, 1);
4095                         if (c == '\n') {
4096                                 multiline = 1;
4097                         }
4098                         else if (c == '\\') {
4099                                 tokp = next_char(file, tokp, 1);
4100                         }
4101                         else if (c == '\'') {
4102                                 tok = TOK_LIT_CHAR;
4103                                 break;
4104                         }
4105                 }
4106                 if (tok == TOK_UNKNOWN) {
4107                         error(state, 0, "unterminated character constant");
4108                 }
4109                 if (multiline) {
4110                         warning(state, 0, "multiline character constant");
4111                 }
4112
4113                 /* Save the character value */
4114                 save_string(file, tk, token, tokp, "literal character");
4115         }
4116         /* integer and floating constants 
4117          * Integer Constants
4118          * {digits}
4119          * 0[Xx]{hexdigits}
4120          * 0{octdigit}+
4121          * 
4122          * Floating constants
4123          * {digits}.{digits}[Ee][+-]?{digits}
4124          * {digits}.{digits}
4125          * {digits}[Ee][+-]?{digits}
4126          * .{digits}[Ee][+-]?{digits}
4127          * .{digits}
4128          */
4129         else if (digitp(c) || ((c == '.') && (digitp(c1)))) {
4130                 const char *next;
4131                 int is_float;
4132                 int cn;
4133                 is_float = 0;
4134                 if (c != '.') {
4135                         next = after_digits(file, tokp);
4136                 }
4137                 else {
4138                         next = token;
4139                 }
4140                 cn = get_char(file, next);
4141                 if (cn == '.') {
4142                         next = next_char(file, next, 1);
4143                         next = after_digits(file, next);
4144                         is_float = 1;
4145                 }
4146                 cn = get_char(file, next);
4147                 if ((cn == 'e') || (cn == 'E')) {
4148                         const char *new;
4149                         next = next_char(file, next, 1);
4150                         cn = get_char(file, next);
4151                         if ((cn == '+') || (cn == '-')) {
4152                                 next = next_char(file, next, 1);
4153                         }
4154                         new = after_digits(file, next);
4155                         is_float |= (new != next);
4156                         next = new;
4157                 }
4158                 if (is_float) {
4159                         tok = TOK_LIT_FLOAT;
4160                         cn = get_char(file, next);
4161                         if ((cn  == 'f') || (cn == 'F') || (cn == 'l') || (cn == 'L')) {
4162                                 next = next_char(file, next, 1);
4163                         }
4164                 }
4165                 if (!is_float && digitp(c)) {
4166                         tok = TOK_LIT_INT;
4167                         if ((c == '0') && ((c1 == 'x') || (c1 == 'X'))) {
4168                                 next = next_char(file, tokp, 1);
4169                                 next = after_hexdigits(file, next);
4170                         }
4171                         else if (c == '0') {
4172                                 next = after_octdigits(file, tokp);
4173                         }
4174                         else {
4175                                 next = after_digits(file, tokp);
4176                         }
4177                         /* crazy integer suffixes */
4178                         cn = get_char(file, next);
4179                         if ((cn == 'u') || (cn == 'U')) {
4180                                 next = next_char(file, next, 1);
4181                                 cn = get_char(file, next);
4182                                 if ((cn == 'l') || (cn == 'L')) {
4183                                         next = next_char(file, next, 1);
4184                                         cn = get_char(file, next);
4185                                 }
4186                                 if ((cn == 'l') || (cn == 'L')) {
4187                                         next = next_char(file, next, 1);
4188                                 }
4189                         }
4190                         else if ((cn == 'l') || (cn == 'L')) {
4191                                 next = next_char(file, next, 1);
4192                                 cn = get_char(file, next);
4193                                 if ((cn == 'l') || (cn == 'L')) {
4194                                         next = next_char(file, next, 1);
4195                                         cn = get_char(file, next);
4196                                 }
4197                                 if ((cn == 'u') || (cn == 'U')) {
4198                                         next = next_char(file, next, 1);
4199                                 }
4200                         }
4201                 }
4202                 tokp = next;
4203
4204                 /* Save the integer/floating point value */
4205                 save_string(file, tk, token, tokp, "literal number");
4206         }
4207         /* identifiers */
4208         else if (letterp(c)) {
4209                 tok = TOK_IDENT;
4210
4211                 /* Find and save the identifier string */
4212                 tokp = after_alnums(file, tokp);
4213                 save_string(file, tk, token, tokp, "identifier");
4214
4215                 /* Look up to see which identifier it is */
4216                 tk->ident = lookup(state, tk->val.str, tk->str_len);
4217
4218                 /* Free the identifier string */
4219                 tk->str_len = 0;
4220                 xfree(tk->val.str);
4221
4222                 /* See if this identifier can be macro expanded */
4223                 tk->val.notmacro = 0;
4224                 c = get_char(file, tokp);
4225                 if (c == '$') {
4226                         tokp = next_char(file, tokp, 1);
4227                         tk->val.notmacro = 1;
4228                 }
4229         }
4230         /* C99 alternate macro characters */
4231         else if ((c == '%') && (c1 == ':') && (c2 == '%') && (c3 == ':')) { 
4232                 eat += 3;
4233                 tok = TOK_CONCATENATE; 
4234         }
4235         else if ((c == '.') && (c1 == '.') && (c2 == '.')) { eat += 2; tok = TOK_DOTS; }
4236         else if ((c == '<') && (c1 == '<') && (c2 == '=')) { eat += 2; tok = TOK_SLEQ; }
4237         else if ((c == '>') && (c1 == '>') && (c2 == '=')) { eat += 2; tok = TOK_SREQ; }
4238         else if ((c == '*') && (c1 == '=')) { eat += 1; tok = TOK_TIMESEQ; }
4239         else if ((c == '/') && (c1 == '=')) { eat += 1; tok = TOK_DIVEQ; }
4240         else if ((c == '%') && (c1 == '=')) { eat += 1; tok = TOK_MODEQ; }
4241         else if ((c == '+') && (c1 == '=')) { eat += 1; tok = TOK_PLUSEQ; }
4242         else if ((c == '-') && (c1 == '=')) { eat += 1; tok = TOK_MINUSEQ; }
4243         else if ((c == '&') && (c1 == '=')) { eat += 1; tok = TOK_ANDEQ; }
4244         else if ((c == '^') && (c1 == '=')) { eat += 1; tok = TOK_XOREQ; }
4245         else if ((c == '|') && (c1 == '=')) { eat += 1; tok = TOK_OREQ; }
4246         else if ((c == '=') && (c1 == '=')) { eat += 1; tok = TOK_EQEQ; }
4247         else if ((c == '!') && (c1 == '=')) { eat += 1; tok = TOK_NOTEQ; }
4248         else if ((c == '|') && (c1 == '|')) { eat += 1; tok = TOK_LOGOR; }
4249         else if ((c == '&') && (c1 == '&')) { eat += 1; tok = TOK_LOGAND; }
4250         else if ((c == '<') && (c1 == '=')) { eat += 1; tok = TOK_LESSEQ; }
4251         else if ((c == '>') && (c1 == '=')) { eat += 1; tok = TOK_MOREEQ; }
4252         else if ((c == '<') && (c1 == '<')) { eat += 1; tok = TOK_SL; }
4253         else if ((c == '>') && (c1 == '>')) { eat += 1; tok = TOK_SR; }
4254         else if ((c == '+') && (c1 == '+')) { eat += 1; tok = TOK_PLUSPLUS; }
4255         else if ((c == '-') && (c1 == '-')) { eat += 1; tok = TOK_MINUSMINUS; }
4256         else if ((c == '-') && (c1 == '>')) { eat += 1; tok = TOK_ARROW; }
4257         else if ((c == '<') && (c1 == ':')) { eat += 1; tok = TOK_LBRACKET; }
4258         else if ((c == ':') && (c1 == '>')) { eat += 1; tok = TOK_RBRACKET; }
4259         else if ((c == '<') && (c1 == '%')) { eat += 1; tok = TOK_LBRACE; }
4260         else if ((c == '%') && (c1 == '>')) { eat += 1; tok = TOK_RBRACE; }
4261         else if ((c == '%') && (c1 == ':')) { eat += 1; tok = TOK_MACRO; }
4262         else if ((c == '#') && (c1 == '#')) { eat += 1; tok = TOK_CONCATENATE; }
4263         else if (c == ';') { tok = TOK_SEMI; }
4264         else if (c == '{') { tok = TOK_LBRACE; }
4265         else if (c == '}') { tok = TOK_RBRACE; }
4266         else if (c == ',') { tok = TOK_COMMA; }
4267         else if (c == '=') { tok = TOK_EQ; }
4268         else if (c == ':') { tok = TOK_COLON; }
4269         else if (c == '[') { tok = TOK_LBRACKET; }
4270         else if (c == ']') { tok = TOK_RBRACKET; }
4271         else if (c == '(') { tok = TOK_LPAREN; }
4272         else if (c == ')') { tok = TOK_RPAREN; }
4273         else if (c == '*') { tok = TOK_STAR; }
4274         else if (c == '>') { tok = TOK_MORE; }
4275         else if (c == '<') { tok = TOK_LESS; }
4276         else if (c == '?') { tok = TOK_QUEST; }
4277         else if (c == '|') { tok = TOK_OR; }
4278         else if (c == '&') { tok = TOK_AND; }
4279         else if (c == '^') { tok = TOK_XOR; }
4280         else if (c == '+') { tok = TOK_PLUS; }
4281         else if (c == '-') { tok = TOK_MINUS; }
4282         else if (c == '/') { tok = TOK_DIV; }
4283         else if (c == '%') { tok = TOK_MOD; }
4284         else if (c == '!') { tok = TOK_BANG; }
4285         else if (c == '.') { tok = TOK_DOT; }
4286         else if (c == '~') { tok = TOK_TILDE; }
4287         else if (c == '#') { tok = TOK_MACRO; }
4288         else if (c == '\n') { tok = TOK_EOL; }
4289
4290         tokp = next_char(file, tokp, eat);
4291         eat_chars(file, tokp);
4292         tk->tok = tok;
4293         tk->pos = token;
4294 }
4295
4296 static void check_tok(struct compile_state *state, struct token *tk, int tok)
4297 {
4298         if (tk->tok != tok) {
4299                 const char *name1, *name2;
4300                 name1 = tokens[tk->tok];
4301                 name2 = "";
4302                 if ((tk->tok == TOK_IDENT) || (tk->tok == TOK_MIDENT)) {
4303                         name2 = tk->ident->name;
4304                 }
4305                 error(state, 0, "\tfound %s %s expected %s",
4306                         name1, name2, tokens[tok]);
4307         }
4308 }
4309
4310 struct macro_arg_value {
4311         struct hash_entry *ident;
4312         unsigned char *value;
4313         size_t len;
4314 };
4315 static struct macro_arg_value *read_macro_args(
4316         struct compile_state *state, struct macro *macro, 
4317         struct file_state *file, struct token *tk)
4318 {
4319         struct macro_arg_value *argv;
4320         struct macro_arg *arg;
4321         int paren_depth;
4322         int i;
4323
4324         if (macro->argc == 0) {
4325                 do {
4326                         raw_next_token(state, file, tk);
4327                 } while(tk->tok == TOK_SPACE);
4328                 return NULL;
4329         }
4330         argv = xcmalloc(sizeof(*argv) * macro->argc, "macro args");
4331         for(i = 0, arg = macro->args; arg; arg = arg->next, i++) {
4332                 argv[i].value = 0;
4333                 argv[i].len   = 0;
4334                 argv[i].ident = arg->ident;
4335         }
4336         paren_depth = 0;
4337         i = 0;
4338         
4339         for(;;) {
4340                 const char *start;
4341                 size_t len;
4342                 start = file->pos;
4343                 raw_next_token(state, file, tk);
4344                 
4345                 if (!paren_depth && (tk->tok == TOK_COMMA) &&
4346                         (argv[i].ident != state->i___VA_ARGS__)) 
4347                 {
4348                         i++;
4349                         if (i >= macro->argc) {
4350                                 error(state, 0, "too many args to %s\n",
4351                                         macro->ident->name);
4352                         }
4353                         continue;
4354                 }
4355                 
4356                 if (tk->tok == TOK_LPAREN) {
4357                         paren_depth++;
4358                 }
4359                 
4360                 if (tk->tok == TOK_RPAREN) {
4361                         if (paren_depth == 0) {
4362                                 break;
4363                         }
4364                         paren_depth--;
4365                 }
4366                 if (tk->tok == TOK_EOF) {
4367                         error(state, 0, "End of file encountered while parsing macro arguments");
4368                 }
4369
4370                 len = char_strlen(file, start, file->pos);
4371                 argv[i].value = xrealloc(
4372                         argv[i].value, argv[i].len + len, "macro args");
4373                 char_strcpy(argv[i].value + argv[i].len, file, start, file->pos);
4374                 argv[i].len += len;
4375         }
4376         if (i != macro->argc -1) {
4377                 error(state, 0, "missing %s arg %d\n", 
4378                         macro->ident->name, i +2);
4379         }
4380         return argv;
4381 }
4382
4383
4384 static void free_macro_args(struct macro *macro, struct macro_arg_value *argv)
4385 {
4386         int i;
4387         for(i = 0; i < macro->argc; i++) {
4388                 xfree(argv[i].value);
4389         }
4390         xfree(argv);
4391 }
4392
4393 struct macro_buf {
4394         char *str;
4395         size_t len, pos;
4396 };
4397
4398 static void grow_macro_buf(struct compile_state *state,
4399         const char *id, struct macro_buf *buf,
4400         size_t grow)
4401 {
4402         if ((buf->pos + grow) >= buf->len) {
4403                 buf->str = xrealloc(buf->str, buf->len + grow, id);
4404                 buf->len += grow;
4405         }
4406 }
4407
4408 static void append_macro_text(struct compile_state *state,
4409         const char *id, struct macro_buf *buf,
4410         const char *fstart, size_t flen)
4411 {
4412         grow_macro_buf(state, id, buf, flen);
4413         memcpy(buf->str + buf->pos, fstart, flen);
4414 #if 0
4415         fprintf(state->errout, "append: `%*.*s' `%*.*s'\n",
4416                 buf->pos, buf->pos, buf->str,
4417                 flen, flen, buf->str + buf->pos);
4418 #endif
4419         buf->pos += flen;
4420 }
4421
4422
4423 static void append_macro_chars(struct compile_state *state,
4424         const char *id, struct macro_buf *buf,
4425         struct file_state *file, const char *start, const char *end)
4426 {
4427         size_t flen;
4428         flen = char_strlen(file, start, end);
4429         grow_macro_buf(state, id, buf, flen);
4430         char_strcpy(buf->str + buf->pos, file, start, end);
4431 #if 0
4432         fprintf(state->errout, "append: `%*.*s' `%*.*s'\n",
4433                 buf->pos, buf->pos, buf->str,
4434                 flen, flen, buf->str + buf->pos);
4435 #endif
4436         buf->pos += flen;
4437 }
4438
4439 static int compile_macro(struct compile_state *state, 
4440         struct file_state **filep, struct token *tk);
4441
4442 static void macro_expand_args(struct compile_state *state, 
4443         struct macro *macro, struct macro_arg_value *argv, struct token *tk)
4444 {
4445         int i;
4446         
4447         for(i = 0; i < macro->argc; i++) {
4448                 struct file_state fmacro, *file;
4449                 struct macro_buf buf;
4450
4451                 fmacro.prev        = 0;
4452                 fmacro.basename    = argv[i].ident->name;
4453                 fmacro.dirname     = "";
4454                 fmacro.buf         = argv[i].value;
4455                 fmacro.size        = argv[i].len;
4456                 fmacro.pos         = fmacro.buf;
4457                 fmacro.line        = 1;
4458                 fmacro.line_start  = fmacro.buf;
4459                 fmacro.report_line = 1;
4460                 fmacro.report_name = fmacro.basename;
4461                 fmacro.report_dir  = fmacro.dirname;
4462                 fmacro.macro       = 1;
4463                 fmacro.trigraphs   = 0;
4464                 fmacro.join_lines  = 0;
4465
4466                 buf.len = argv[i].len;
4467                 buf.str = xmalloc(buf.len, argv[i].ident->name);
4468                 buf.pos = 0;
4469
4470                 file = &fmacro;
4471                 for(;;) {
4472                         raw_next_token(state, file, tk);
4473                         
4474                         /* If we have recursed into another macro body
4475                          * get out of it.
4476                          */
4477                         if (tk->tok == TOK_EOF) {
4478                                 struct file_state *old;
4479                                 old = file;
4480                                 file = file->prev;
4481                                 if (!file) {
4482                                         break;
4483                                 }
4484                                 /* old->basename is used keep it */
4485                                 xfree(old->dirname);
4486                                 xfree(old->buf);
4487                                 xfree(old);
4488                                 continue;
4489                         }
4490                         else if (tk->ident && tk->ident->sym_define) {
4491                                 if (compile_macro(state, &file, tk)) {
4492                                         continue;
4493                                 }
4494                         }
4495
4496                         append_macro_chars(state, macro->ident->name, &buf,
4497                                 file, tk->pos, file->pos);
4498                 }
4499                         
4500                 xfree(argv[i].value);
4501                 argv[i].value = buf.str;
4502                 argv[i].len   = buf.pos;
4503         }
4504         return;
4505 }
4506
4507 static void expand_macro(struct compile_state *state,
4508         struct macro *macro, struct macro_buf *buf,
4509         struct macro_arg_value *argv, struct token *tk)
4510 {
4511         struct file_state fmacro;
4512         const char space[] = " ";
4513         const char *fstart;
4514         size_t flen;
4515         int i, j;
4516
4517         /* Place the macro body in a dummy file */
4518         fmacro.prev        = 0;
4519         fmacro.basename    = macro->ident->name;
4520         fmacro.dirname     = "";
4521         fmacro.buf         = macro->buf;
4522         fmacro.size        = macro->buf_len;
4523         fmacro.pos         = fmacro.buf;
4524         fmacro.line        = 1;
4525         fmacro.line_start  = fmacro.buf;
4526         fmacro.report_line = 1;
4527         fmacro.report_name = fmacro.basename;
4528         fmacro.report_dir  = fmacro.dirname;
4529         fmacro.macro       = 1;
4530         fmacro.trigraphs   = 0;
4531         fmacro.join_lines  = 0;
4532         
4533         /* Allocate a buffer to hold the macro expansion */
4534         buf->len = macro->buf_len + 3;
4535         buf->str = xmalloc(buf->len, macro->ident->name);
4536         buf->pos = 0;
4537         
4538         fstart = fmacro.pos;
4539         raw_next_token(state, &fmacro, tk);
4540         while(tk->tok != TOK_EOF) {
4541                 flen = fmacro.pos - fstart;
4542                 switch(tk->tok) {
4543                 case TOK_IDENT:
4544                         for(i = 0; i < macro->argc; i++) {
4545                                 if (argv[i].ident == tk->ident) {
4546                                         break;
4547                                 }
4548                         }
4549                         if (i >= macro->argc) {
4550                                 break;
4551                         }
4552                         /* Substitute macro parameter */
4553                         fstart = argv[i].value;
4554                         flen   = argv[i].len;
4555                         break;
4556                 case TOK_MACRO:
4557                         if (macro->argc < 0) {
4558                                 break;
4559                         }
4560                         do {
4561                                 raw_next_token(state, &fmacro, tk);
4562                         } while(tk->tok == TOK_SPACE);
4563                         check_tok(state, tk, TOK_IDENT);
4564                         for(i = 0; i < macro->argc; i++) {
4565                                 if (argv[i].ident == tk->ident) {
4566                                         break;
4567                                 }
4568                         }
4569                         if (i >= macro->argc) {
4570                                 error(state, 0, "parameter `%s' not found",
4571                                         tk->ident->name);
4572                         }
4573                         /* Stringize token */
4574                         append_macro_text(state, macro->ident->name, buf, "\"", 1);
4575                         for(j = 0; j < argv[i].len; j++) {
4576                                 char *str = argv[i].value + j;
4577                                 size_t len = 1;
4578                                 if (*str == '\\') {
4579                                         str = "\\";
4580                                         len = 2;
4581                                 } 
4582                                 else if (*str == '"') {
4583                                         str = "\\\"";
4584                                         len = 2;
4585                                 }
4586                                 append_macro_text(state, macro->ident->name, buf, str, len);
4587                         }
4588                         append_macro_text(state, macro->ident->name, buf, "\"", 1);
4589                         fstart = 0;
4590                         flen   = 0;
4591                         break;
4592                 case TOK_CONCATENATE:
4593                         /* Concatenate tokens */
4594                         /* Delete the previous whitespace token */
4595                         if (buf->str[buf->pos - 1] == ' ') {
4596                                 buf->pos -= 1;
4597                         }
4598                         /* Skip the next sequence of whitspace tokens */
4599                         do {
4600                                 fstart = fmacro.pos;
4601                                 raw_next_token(state, &fmacro, tk);
4602                         } while(tk->tok == TOK_SPACE);
4603                         /* Restart at the top of the loop.
4604                          * I need to process the non white space token.
4605                          */
4606                         continue;
4607                         break;
4608                 case TOK_SPACE:
4609                         /* Collapse multiple spaces into one */
4610                         if (buf->str[buf->pos - 1] != ' ') {
4611                                 fstart = space;
4612                                 flen   = 1;
4613                         } else {
4614                                 fstart = 0;
4615                                 flen   = 0;
4616                         }
4617                         break;
4618                 default:
4619                         break;
4620                 }
4621
4622                 append_macro_text(state, macro->ident->name, buf, fstart, flen);
4623                 
4624                 fstart = fmacro.pos;
4625                 raw_next_token(state, &fmacro, tk);
4626         }
4627 }
4628
4629 static void tag_macro_name(struct compile_state *state,
4630         struct macro *macro, struct macro_buf *buf,
4631         struct token *tk)
4632 {
4633         /* Guard all instances of the macro name in the replacement
4634          * text from further macro expansion.
4635          */
4636         struct file_state fmacro;
4637         const char *fstart;
4638         size_t flen;
4639
4640         /* Put the old macro expansion buffer in a file */
4641         fmacro.prev        = 0;
4642         fmacro.basename    = macro->ident->name;
4643         fmacro.dirname     = "";
4644         fmacro.buf         = buf->str;
4645         fmacro.size        = buf->pos;
4646         fmacro.pos         = fmacro.buf;
4647         fmacro.line        = 1;
4648         fmacro.line_start  = fmacro.buf;
4649         fmacro.report_line = 1;
4650         fmacro.report_name = fmacro.basename;
4651         fmacro.report_dir  = fmacro.dirname;
4652         fmacro.macro       = 1;
4653         fmacro.trigraphs   = 0;
4654         fmacro.join_lines  = 0;
4655         
4656         /* Allocate a new macro expansion buffer */
4657         buf->len = macro->buf_len + 3;
4658         buf->str = xmalloc(buf->len, macro->ident->name);
4659         buf->pos = 0;
4660         
4661         fstart = fmacro.pos;
4662         raw_next_token(state, &fmacro, tk);
4663         while(tk->tok != TOK_EOF) {
4664                 flen = fmacro.pos - fstart;
4665                 if ((tk->tok == TOK_IDENT) &&
4666                         (tk->ident == macro->ident) &&
4667                         (tk->val.notmacro == 0)) 
4668                 {
4669                         append_macro_text(state, macro->ident->name, buf, fstart, flen);
4670                         fstart = "$";
4671                         flen   = 1;
4672                 }
4673
4674                 append_macro_text(state, macro->ident->name, buf, fstart, flen);
4675                 
4676                 fstart = fmacro.pos;
4677                 raw_next_token(state, &fmacro, tk);
4678         }
4679         xfree(fmacro.buf);
4680 }
4681
4682 static int compile_macro(struct compile_state *state, 
4683         struct file_state **filep, struct token *tk)
4684 {
4685         struct file_state *file;
4686         struct hash_entry *ident;
4687         struct macro *macro;
4688         struct macro_arg_value *argv;
4689         struct macro_buf buf;
4690
4691 #if 0
4692         fprintf(state->errout, "macro: %s\n", tk->ident->name);
4693 #endif
4694         ident = tk->ident;
4695         macro = ident->sym_define;
4696
4697         /* If this token comes from a macro expansion ignore it */
4698         if (tk->val.notmacro) {
4699                 return 0;
4700         }
4701         /* If I am a function like macro and the identifier is not followed
4702          * by a left parenthesis, do nothing.
4703          */
4704         if ((macro->argc >= 0) && (get_char(*filep, (*filep)->pos) != '(')) {
4705                 return 0;
4706         }
4707
4708         /* Read in the macro arguments */
4709         argv = 0;
4710         if (macro->argc >= 0) {
4711                 raw_next_token(state, *filep, tk);
4712                 check_tok(state, tk, TOK_LPAREN);
4713
4714                 argv = read_macro_args(state, macro, *filep, tk);
4715
4716                 check_tok(state, tk, TOK_RPAREN);
4717         }
4718         /* Macro expand the macro arguments */
4719         macro_expand_args(state, macro, argv, tk);
4720
4721         buf.str = 0;
4722         buf.len = 0;
4723         buf.pos = 0;
4724         if (ident == state->i___FILE__) {
4725                 buf.len = strlen(state->file->basename) + 1 + 2 + 3;
4726                 buf.str = xmalloc(buf.len, ident->name);
4727                 sprintf(buf.str, "\"%s\"", state->file->basename);
4728                 buf.pos = strlen(buf.str);
4729         }
4730         else if (ident == state->i___LINE__) {
4731                 buf.len = 30;
4732                 buf.str = xmalloc(buf.len, ident->name);
4733                 sprintf(buf.str, "%d", state->file->line);
4734                 buf.pos = strlen(buf.str);
4735         }
4736         else {
4737                 expand_macro(state, macro, &buf, argv, tk);
4738         }
4739         /* Tag the macro name with a $ so it will no longer
4740          * be regonized as a canidate for macro expansion.
4741          */
4742         tag_macro_name(state, macro, &buf, tk);
4743
4744 #if 0
4745         fprintf(state->errout, "%s: %d -> `%*.*s'\n",
4746                 ident->name, buf.pos, buf.pos, (int)(buf.pos), buf.str);
4747 #endif
4748
4749         free_macro_args(macro, argv);
4750
4751         file = xmalloc(sizeof(*file), "file_state");
4752         file->prev        = *filep;
4753         file->basename    = xstrdup(ident->name);
4754         file->dirname     = xstrdup("");
4755         file->buf         = buf.str;
4756         file->size        = buf.pos;
4757         file->pos         = file->buf;
4758         file->line        = 1;
4759         file->line_start  = file->pos;
4760         file->report_line = 1;
4761         file->report_name = file->basename;
4762         file->report_dir  = file->dirname;
4763         file->macro       = 1;
4764         file->trigraphs   = 0;
4765         file->join_lines  = 0;
4766         *filep = file;
4767         return 1;
4768 }
4769
4770 static void eat_tokens(struct compile_state *state, int targ_tok)
4771 {
4772         if (state->eat_depth > 0) {
4773                 internal_error(state, 0, "Already eating...");
4774         }
4775         state->eat_depth = state->if_depth;
4776         state->eat_targ = targ_tok;
4777 }
4778 static int if_eat(struct compile_state *state)
4779 {
4780         return state->eat_depth > 0;
4781 }
4782 static int if_value(struct compile_state *state)
4783 {
4784         int index, offset;
4785         index = state->if_depth / CHAR_BIT;
4786         offset = state->if_depth % CHAR_BIT;
4787         return !!(state->if_bytes[index] & (1 << (offset)));
4788 }
4789 static void set_if_value(struct compile_state *state, int value) 
4790 {
4791         int index, offset;
4792         index = state->if_depth / CHAR_BIT;
4793         offset = state->if_depth % CHAR_BIT;
4794
4795         state->if_bytes[index] &= ~(1 << offset);
4796         if (value) {
4797                 state->if_bytes[index] |= (1 << offset);
4798         }
4799 }
4800 static void in_if(struct compile_state *state, const char *name)
4801 {
4802         if (state->if_depth <= 0) {
4803                 error(state, 0, "%s without #if", name);
4804         }
4805 }
4806 static void enter_if(struct compile_state *state)
4807 {
4808         state->if_depth += 1;
4809         if (state->if_depth > MAX_PP_IF_DEPTH) {
4810                 error(state, 0, "#if depth too great");
4811         }
4812 }
4813 static void reenter_if(struct compile_state *state, const char *name)
4814 {
4815         in_if(state, name);
4816         if ((state->eat_depth == state->if_depth) &&
4817                 (state->eat_targ == TOK_MELSE)) {
4818                 state->eat_depth = 0;
4819                 state->eat_targ = 0;
4820         }
4821 }
4822 static void enter_else(struct compile_state *state, const char *name)
4823 {
4824         in_if(state, name);
4825         if ((state->eat_depth == state->if_depth) &&
4826                 (state->eat_targ == TOK_MELSE)) {
4827                 state->eat_depth = 0;
4828                 state->eat_targ = 0;
4829         }
4830 }
4831 static void exit_if(struct compile_state *state, const char *name)
4832 {
4833         in_if(state, name);
4834         if (state->eat_depth == state->if_depth) {
4835                 state->eat_depth = 0;
4836                 state->eat_targ = 0;
4837         }
4838         state->if_depth -= 1;
4839 }
4840
4841 static void raw_token(struct compile_state *state, struct token *tk)
4842 {
4843         struct file_state *file;
4844         int rescan;
4845
4846         file = state->file;
4847         raw_next_token(state, file, tk);
4848         do {
4849                 rescan = 0;
4850                 file = state->file;
4851                 /* Exit out of an include directive or macro call */
4852                 if ((tk->tok == TOK_EOF) && 
4853                         (file != state->macro_file) && file->prev) 
4854                 {
4855                         state->file = file->prev;
4856                         /* file->basename is used keep it */
4857                         xfree(file->dirname);
4858                         xfree(file->buf);
4859                         xfree(file);
4860                         file = 0;
4861                         raw_next_token(state, state->file, tk);
4862                         rescan = 1;
4863                 }
4864         } while(rescan);
4865 }
4866
4867 static void pp_token(struct compile_state *state, struct token *tk)
4868 {
4869         struct file_state *file;
4870         int rescan;
4871
4872         raw_token(state, tk);
4873         do {
4874                 rescan = 0;
4875                 file = state->file;
4876                 if (tk->tok == TOK_SPACE) {
4877                         raw_token(state, tk);
4878                         rescan = 1;
4879                 }
4880                 else if (tk->tok == TOK_IDENT) {
4881                         if (state->token_base == 0) {
4882                                 ident_to_keyword(state, tk);
4883                         } else {
4884                                 ident_to_macro(state, tk);
4885                         }
4886                 }
4887         } while(rescan);
4888 }
4889
4890 static void preprocess(struct compile_state *state, struct token *tk);
4891
4892 static void token(struct compile_state *state, struct token *tk)
4893 {
4894         int rescan;
4895         pp_token(state, tk);
4896         do {
4897                 rescan = 0;
4898                 /* Process a macro directive */
4899                 if (tk->tok == TOK_MACRO) {
4900                         /* Only match preprocessor directives at the start of a line */
4901                         const char *ptr;
4902                         ptr = state->file->line_start;
4903                         while((ptr < tk->pos)
4904                                 && spacep(get_char(state->file, ptr)))
4905                         {
4906                                 ptr = next_char(state->file, ptr, 1);
4907                         }
4908                         if (ptr == tk->pos) {
4909                                 preprocess(state, tk);
4910                                 rescan = 1;
4911                         }
4912                 }
4913                 /* Expand a macro call */
4914                 else if (tk->ident && tk->ident->sym_define) {
4915                         rescan = compile_macro(state, &state->file, tk);
4916                         if (rescan) {
4917                                 pp_token(state, tk);
4918                         }
4919                 }
4920                 /* Eat tokens disabled by the preprocessor 
4921                  * (Unless we are parsing a preprocessor directive 
4922                  */
4923                 else if (if_eat(state) && (state->token_base == 0)) {
4924                         pp_token(state, tk);
4925                         rescan = 1;
4926                 }
4927                 /* Make certain EOL only shows up in preprocessor directives */
4928                 else if ((tk->tok == TOK_EOL) && (state->token_base == 0)) {
4929                         pp_token(state, tk);
4930                         rescan = 1;
4931                 }
4932                 /* Error on unknown tokens */
4933                 else if (tk->tok == TOK_UNKNOWN) {
4934                         error(state, 0, "unknown token");
4935                 }
4936         } while(rescan);
4937 }
4938
4939
4940 static inline struct token *get_token(struct compile_state *state, int offset)
4941 {
4942         int index;
4943         index = state->token_base + offset;
4944         if (index >= sizeof(state->token)/sizeof(state->token[0])) {
4945                 internal_error(state, 0, "token array to small");
4946         }
4947         return &state->token[index];
4948 }
4949
4950 static struct token *do_eat_token(struct compile_state *state, int tok)
4951 {
4952         struct token *tk;
4953         int i;
4954         check_tok(state, get_token(state, 1), tok);
4955         
4956         /* Free the old token value */
4957         tk = get_token(state, 0);
4958         if (tk->str_len) {
4959                 memset((void *)tk->val.str, -1, tk->str_len);
4960                 xfree(tk->val.str);
4961         }
4962         /* Overwrite the old token with newer tokens */
4963         for(i = state->token_base; i < sizeof(state->token)/sizeof(state->token[0]) - 1; i++) {
4964                 state->token[i] = state->token[i + 1];
4965         }
4966         /* Clear the last token */
4967         memset(&state->token[i], 0, sizeof(state->token[i]));
4968         state->token[i].tok = -1;
4969
4970         /* Return the token */
4971         return tk;
4972 }
4973
4974 static int raw_peek(struct compile_state *state)
4975 {
4976         struct token *tk1;
4977         tk1 = get_token(state, 1);
4978         if (tk1->tok == -1) {
4979                 raw_token(state, tk1);
4980         }
4981         return tk1->tok;
4982 }
4983
4984 static struct token *raw_eat(struct compile_state *state, int tok)
4985 {
4986         raw_peek(state);
4987         return do_eat_token(state, tok);
4988 }
4989
4990 static int pp_peek(struct compile_state *state)
4991 {
4992         struct token *tk1;
4993         tk1 = get_token(state, 1);
4994         if (tk1->tok == -1) {
4995                 pp_token(state, tk1);
4996         }
4997         return tk1->tok;
4998 }
4999
5000 static struct token *pp_eat(struct compile_state *state, int tok)
5001 {
5002         pp_peek(state);
5003         return do_eat_token(state, tok);
5004 }
5005
5006 static int peek(struct compile_state *state)
5007 {
5008         struct token *tk1;
5009         tk1 = get_token(state, 1);
5010         if (tk1->tok == -1) {
5011                 token(state, tk1);
5012         }
5013         return tk1->tok;
5014 }
5015
5016 static int peek2(struct compile_state *state)
5017 {
5018         struct token *tk1, *tk2;
5019         tk1 = get_token(state, 1);
5020         tk2 = get_token(state, 2);
5021         if (tk1->tok == -1) {
5022                 token(state, tk1);
5023         }
5024         if (tk2->tok == -1) {
5025                 token(state, tk2);
5026         }
5027         return tk2->tok;
5028 }
5029
5030 static struct token *eat(struct compile_state *state, int tok)
5031 {
5032         peek(state);
5033         return do_eat_token(state, tok);
5034 }
5035
5036 static void compile_file(struct compile_state *state, const char *filename, int local)
5037 {
5038         char cwd[MAX_CWD_SIZE];
5039         const char *subdir, *base;
5040         int subdir_len;
5041         struct file_state *file;
5042         char *basename;
5043         file = xmalloc(sizeof(*file), "file_state");
5044
5045         base = strrchr(filename, '/');
5046         subdir = filename;
5047         if (base != 0) {
5048                 subdir_len = base - filename;
5049                 base++;
5050         }
5051         else {
5052                 base = filename;
5053                 subdir_len = 0;
5054         }
5055         basename = xmalloc(strlen(base) +1, "basename");
5056         strcpy(basename, base);
5057         file->basename = basename;
5058
5059         if (getcwd(cwd, sizeof(cwd)) == 0) {
5060                 die("cwd buffer to small");
5061         }
5062         if (subdir[0] == '/') {
5063                 file->dirname = xmalloc(subdir_len + 1, "dirname");
5064                 memcpy(file->dirname, subdir, subdir_len);
5065                 file->dirname[subdir_len] = '\0';
5066         }
5067         else {
5068                 const char *dir;
5069                 int dirlen;
5070                 const char **path;
5071                 /* Find the appropriate directory... */
5072                 dir = 0;
5073                 if (!state->file && exists(cwd, filename)) {
5074                         dir = cwd;
5075                 }
5076                 if (local && state->file && exists(state->file->dirname, filename)) {
5077                         dir = state->file->dirname;
5078                 }
5079                 for(path = state->compiler->include_paths; !dir && *path; path++) {
5080                         if (exists(*path, filename)) {
5081                                 dir = *path;
5082                         }
5083                 }
5084                 if (!dir) {
5085                         error(state, 0, "Cannot open `%s'\n", filename);
5086                 }
5087                 dirlen = strlen(dir);
5088                 file->dirname = xmalloc(dirlen + 1 + subdir_len + 1, "dirname");
5089                 memcpy(file->dirname, dir, dirlen);
5090                 file->dirname[dirlen] = '/';
5091                 memcpy(file->dirname + dirlen + 1, subdir, subdir_len);
5092                 file->dirname[dirlen + 1 + subdir_len] = '\0';
5093         }
5094         file->buf = slurp_file(file->dirname, file->basename, &file->size);
5095
5096         file->pos = file->buf;
5097         file->line_start = file->pos;
5098         file->line = 1;
5099
5100         file->report_line = 1;
5101         file->report_name = file->basename;
5102         file->report_dir  = file->dirname;
5103         file->macro       = 0;
5104         file->trigraphs   = (state->compiler->flags & COMPILER_TRIGRAPHS)? 1: 0;
5105         file->join_lines  = 1;
5106
5107         file->prev = state->file;
5108         state->file = file;
5109 }
5110
5111 static struct triple *constant_expr(struct compile_state *state);
5112 static void integral(struct compile_state *state, struct triple *def);
5113
5114 static int mcexpr(struct compile_state *state)
5115 {
5116         struct triple *cvalue;
5117         cvalue = constant_expr(state);
5118         integral(state, cvalue);
5119         if (cvalue->op != OP_INTCONST) {
5120                 error(state, 0, "integer constant expected");
5121         }
5122         return cvalue->u.cval != 0;
5123 }
5124
5125 static void preprocess(struct compile_state *state, struct token *current_token)
5126 {
5127         /* Doing much more with the preprocessor would require
5128          * a parser and a major restructuring.
5129          * Postpone that for later.
5130          */
5131         int old_token_base;
5132         int tok;
5133         
5134         state->macro_file = state->file;
5135
5136         old_token_base = state->token_base;
5137         state->token_base = current_token - state->token;
5138
5139         tok = pp_peek(state);
5140         switch(tok) {
5141         case TOK_LIT_INT:
5142         {
5143                 struct token *tk;
5144                 int override_line;
5145                 tk = pp_eat(state, TOK_LIT_INT);
5146                 override_line = strtoul(tk->val.str, 0, 10);
5147                 /* I have a preprocessor  line marker parse it */
5148                 if (pp_peek(state) == TOK_LIT_STRING) {
5149                         const char *token, *base;
5150                         char *name, *dir;
5151                         int name_len, dir_len;
5152                         tk = pp_eat(state, TOK_LIT_STRING);
5153                         name = xmalloc(tk->str_len, "report_name");
5154                         token = tk->val.str + 1;
5155                         base = strrchr(token, '/');
5156                         name_len = tk->str_len -2;
5157                         if (base != 0) {
5158                                 dir_len = base - token;
5159                                 base++;
5160                                 name_len -= base - token;
5161                         } else {
5162                                 dir_len = 0;
5163                                 base = token;
5164                         }
5165                         memcpy(name, base, name_len);
5166                         name[name_len] = '\0';
5167                         dir = xmalloc(dir_len + 1, "report_dir");
5168                         memcpy(dir, token, dir_len);
5169                         dir[dir_len] = '\0';
5170                         state->file->report_line = override_line - 1;
5171                         state->file->report_name = name;
5172                         state->file->report_dir = dir;
5173                         state->file->macro      = 0;
5174                 }
5175                 break;
5176         }
5177         case TOK_MLINE:
5178         {
5179                 struct token *tk;
5180                 pp_eat(state, TOK_MLINE);
5181                 tk = eat(state, TOK_LIT_INT);
5182                 state->file->report_line = strtoul(tk->val.str, 0, 10) -1;
5183                 if (pp_peek(state) == TOK_LIT_STRING) {
5184                         const char *token, *base;
5185                         char *name, *dir;
5186                         int name_len, dir_len;
5187                         tk = pp_eat(state, TOK_LIT_STRING);
5188                         name = xmalloc(tk->str_len, "report_name");
5189                         token = tk->val.str + 1;
5190                         base = strrchr(token, '/');
5191                         name_len = tk->str_len - 2;
5192                         if (base != 0) {
5193                                 dir_len = base - token;
5194                                 base++;
5195                                 name_len -= base - token;
5196                         } else {
5197                                 dir_len = 0;
5198                                 base = token;
5199                         }
5200                         memcpy(name, base, name_len);
5201                         name[name_len] = '\0';
5202                         dir = xmalloc(dir_len + 1, "report_dir");
5203                         memcpy(dir, token, dir_len);
5204                         dir[dir_len] = '\0';
5205                         state->file->report_name = name;
5206                         state->file->report_dir = dir;
5207                         state->file->macro      = 0;
5208                 }
5209                 break;
5210         }
5211         case TOK_MUNDEF:
5212         {
5213                 struct hash_entry *ident;
5214                 pp_eat(state, TOK_MUNDEF);
5215                 if (if_eat(state))  /* quit early when #if'd out */
5216                         break;
5217                 
5218                 ident = pp_eat(state, TOK_MIDENT)->ident;
5219
5220                 undef_macro(state, ident);
5221                 break;
5222         }
5223         case TOK_MPRAGMA:
5224                 pp_eat(state, TOK_MPRAGMA);
5225                 if (if_eat(state))  /* quit early when #if'd out */
5226                         break;
5227                 warning(state, 0, "Ignoring pragma"); 
5228                 break;
5229         case TOK_MELIF:
5230                 pp_eat(state, TOK_MELIF);
5231                 reenter_if(state, "#elif");
5232                 if (if_eat(state))   /* quit early when #if'd out */
5233                         break;
5234                 /* If the #if was taken the #elif just disables the following code */
5235                 if (if_value(state)) {
5236                         eat_tokens(state, TOK_MENDIF);
5237                 }
5238                 /* If the previous #if was not taken see if the #elif enables the 
5239                  * trailing code.
5240                  */
5241                 else {
5242                         set_if_value(state, mcexpr(state));
5243                         if (!if_value(state)) {
5244                                 eat_tokens(state, TOK_MELSE);
5245                         }
5246                 }
5247                 break;
5248         case TOK_MIF:
5249                 pp_eat(state, TOK_MIF);
5250                 enter_if(state);
5251                 if (if_eat(state))  /* quit early when #if'd out */
5252                         break;
5253                 set_if_value(state, mcexpr(state));
5254                 if (!if_value(state)) {
5255                         eat_tokens(state, TOK_MELSE);
5256                 }
5257                 break;
5258         case TOK_MIFNDEF:
5259         {
5260                 struct hash_entry *ident;
5261
5262                 pp_eat(state, TOK_MIFNDEF);
5263                 enter_if(state);
5264                 if (if_eat(state))  /* quit early when #if'd out */
5265                         break;
5266                 ident = pp_eat(state, TOK_MIDENT)->ident;
5267                 set_if_value(state, ident->sym_define == 0);
5268                 if (!if_value(state)) {
5269                         eat_tokens(state, TOK_MELSE);
5270                 }
5271                 break;
5272         }
5273         case TOK_MIFDEF:
5274         {
5275                 struct hash_entry *ident;
5276                 pp_eat(state, TOK_MIFDEF);
5277                 enter_if(state);
5278                 if (if_eat(state))  /* quit early when #if'd out */
5279                         break;
5280                 ident = pp_eat(state, TOK_MIDENT)->ident;
5281                 set_if_value(state, ident->sym_define != 0);
5282                 if (!if_value(state)) {
5283                         eat_tokens(state, TOK_MELSE);
5284                 }
5285                 break;
5286         }
5287         case TOK_MELSE:
5288                 pp_eat(state, TOK_MELSE);
5289                 enter_else(state, "#else");
5290                 if (!if_eat(state) && if_value(state)) {
5291                         eat_tokens(state, TOK_MENDIF);
5292                 }
5293                 break;
5294         case TOK_MENDIF:
5295                 pp_eat(state, TOK_MENDIF);
5296                 exit_if(state, "#endif");
5297                 break;
5298         case TOK_MDEFINE:
5299         {
5300                 struct hash_entry *ident;
5301                 struct macro_arg *args, **larg;
5302                 const char *mstart, *mend;
5303                 int argc;
5304
5305                 pp_eat(state, TOK_MDEFINE);
5306                 if (if_eat(state))  /* quit early when #if'd out */
5307                         break;
5308                 ident = pp_eat(state, TOK_MIDENT)->ident;
5309                 argc = -1;
5310                 args = 0;
5311                 larg = &args;
5312
5313                 /* Parse macro parameters */
5314                 if (raw_peek(state) == TOK_LPAREN) {
5315                         raw_eat(state, TOK_LPAREN);
5316                         argc += 1;
5317
5318                         for(;;) {
5319                                 struct macro_arg *narg, *arg;
5320                                 struct hash_entry *aident;
5321                                 int tok;
5322
5323                                 tok = pp_peek(state);
5324                                 if (!args && (tok == TOK_RPAREN)) {
5325                                         break;
5326                                 }
5327                                 else if (tok == TOK_DOTS) {
5328                                         pp_eat(state, TOK_DOTS);
5329                                         aident = state->i___VA_ARGS__;
5330                                 } 
5331                                 else {
5332                                         aident = pp_eat(state, TOK_MIDENT)->ident;
5333                                 }
5334                                 
5335                                 narg = xcmalloc(sizeof(*arg), "macro arg");
5336                                 narg->ident = aident;
5337
5338                                 /* Verify I don't have a duplicate identifier */
5339                                 for(arg = args; arg; arg = arg->next) {
5340                                         if (arg->ident == narg->ident) {
5341                                                 error(state, 0, "Duplicate macro arg `%s'",
5342                                                         narg->ident->name);
5343                                         }
5344                                 }
5345                                 /* Add the new argument to the end of the list */
5346                                 *larg = narg;
5347                                 larg = &narg->next;
5348                                 argc += 1;
5349
5350                                 if ((aident == state->i___VA_ARGS__) ||
5351                                         (pp_peek(state) != TOK_COMMA)) {
5352                                         break;
5353                                 }
5354                                 pp_eat(state, TOK_COMMA);
5355                         }
5356                         pp_eat(state, TOK_RPAREN);
5357                 }
5358                 /* Remove leading whitespace */
5359                 while(raw_peek(state) == TOK_SPACE) {
5360                         raw_eat(state, TOK_SPACE);
5361                 }
5362
5363                 /* Remember the start of the macro body */
5364                 tok = raw_peek(state);
5365                 mend = mstart = get_token(state, 1)->pos;
5366
5367                 /* Find the end of the macro */
5368                 for(tok = raw_peek(state); tok != TOK_EOL; tok = raw_peek(state)) {
5369                         raw_eat(state, tok);
5370                         /* Remember the end of the last non space token */
5371                         raw_peek(state);
5372                         if (tok != TOK_SPACE) {
5373                                 mend = get_token(state, 1)->pos;
5374                         }
5375                 }
5376                 
5377                 /* Now that I have found the body defined the token */
5378                 do_define_macro(state, ident,
5379                         char_strdup(state->file, mstart, mend, "macro buf"),
5380                         argc, args);
5381                 break;
5382         }
5383         case TOK_MERROR:
5384         {
5385                 const char *start, *end;
5386                 int len;
5387                 
5388                 pp_eat(state, TOK_MERROR);
5389                 /* Find the start of the line */
5390                 raw_peek(state);
5391                 start = get_token(state, 1)->pos;
5392
5393                 /* Find the end of the line */
5394                 while((tok = raw_peek(state)) != TOK_EOL) {
5395                         raw_eat(state, tok);
5396                 }
5397                 end = get_token(state, 1)->pos;
5398                 len = end - start;
5399                 if (!if_eat(state)) {
5400                         error(state, 0, "%*.*s", len, len, start);
5401                 }
5402                 break;
5403         }
5404         case TOK_MWARNING:
5405         {
5406                 const char *start, *end;
5407                 int len;
5408                 
5409                 pp_eat(state, TOK_MWARNING);
5410
5411                 /* Find the start of the line */
5412                 raw_peek(state);
5413                 start = get_token(state, 1)->pos;
5414                  
5415                 /* Find the end of the line */
5416                 while((tok = raw_peek(state)) != TOK_EOL) {
5417                         raw_eat(state, tok);
5418                 }
5419                 end = get_token(state, 1)->pos;
5420                 len = end - start;
5421                 if (!if_eat(state)) {
5422                         warning(state, 0, "%*.*s", len, len, start);
5423                 }
5424                 break;
5425         }
5426         case TOK_MINCLUDE:
5427         {
5428                 char *name;
5429                 int local;
5430                 local = 0;
5431                 name = 0;
5432
5433                 pp_eat(state, TOK_MINCLUDE);
5434                 tok = peek(state);
5435                 if (tok == TOK_LIT_STRING) {
5436                         struct token *tk;
5437                         const char *token;
5438                         int name_len;
5439                         tk = eat(state, TOK_LIT_STRING);
5440                         name = xmalloc(tk->str_len, "include");
5441                         token = tk->val.str +1;
5442                         name_len = tk->str_len -2;
5443                         if (*token == '"') {
5444                                 token++;
5445                                 name_len--;
5446                         }
5447                         memcpy(name, token, name_len);
5448                         name[name_len] = '\0';
5449                         local = 1;
5450                 }
5451                 else if (tok == TOK_LESS) {
5452                         struct macro_buf buf;
5453                         eat(state, TOK_LESS);
5454
5455                         buf.len = 40;
5456                         buf.str = xmalloc(buf.len, "include");
5457                         buf.pos = 0;
5458
5459                         tok = peek(state);
5460                         while((tok != TOK_MORE) &&
5461                                 (tok != TOK_EOL) && (tok != TOK_EOF))
5462                         {
5463                                 struct token *tk;
5464                                 tk = eat(state, tok);
5465                                 append_macro_chars(state, "include", &buf,
5466                                         state->file, tk->pos, state->file->pos);
5467                                 tok = peek(state);
5468                         }
5469                         append_macro_text(state, "include", &buf, "\0", 1);
5470                         if (peek(state) != TOK_MORE) {
5471                                 error(state, 0, "Unterminated include directive");
5472                         }
5473                         eat(state, TOK_MORE);
5474                         local = 0;
5475                         name = buf.str;
5476                 }
5477                 else {
5478                         error(state, 0, "Invalid include directive");
5479                 }
5480                 /* Error if there are any tokens after the include */
5481                 if (pp_peek(state) != TOK_EOL) {
5482                         error(state, 0, "garbage after include directive");
5483                 }
5484                 if (!if_eat(state)) {
5485                         compile_file(state, name, local);
5486                 }
5487                 xfree(name);
5488                 break;
5489         }
5490         case TOK_EOL:
5491                 /* Ignore # without a follwing ident */
5492                 break;
5493         default:
5494         {
5495                 const char *name1, *name2;
5496                 name1 = tokens[tok];
5497                 name2 = "";
5498                 if (tok == TOK_MIDENT) {
5499                         name2 = get_token(state, 1)->ident->name;
5500                 }
5501                 error(state, 0, "Invalid preprocessor directive: %s %s", 
5502                         name1, name2);
5503                 break;
5504         }
5505         }
5506         /* Consume the rest of the macro line */
5507         do {
5508                 tok = pp_peek(state);
5509                 pp_eat(state, tok);
5510         } while((tok != TOK_EOF) && (tok != TOK_EOL));
5511         state->token_base = old_token_base;
5512         state->macro_file = NULL;
5513         return;
5514 }
5515
5516 /* Type helper functions */
5517
5518 static struct type *new_type(
5519         unsigned int type, struct type *left, struct type *right)
5520 {
5521         struct type *result;
5522         result = xmalloc(sizeof(*result), "type");
5523         result->type = type;
5524         result->left = left;
5525         result->right = right;
5526         result->field_ident = 0;
5527         result->type_ident = 0;
5528         result->elements = 0;
5529         return result;
5530 }
5531
5532 static struct type *clone_type(unsigned int specifiers, struct type *old)
5533 {
5534         struct type *result;
5535         result = xmalloc(sizeof(*result), "type");
5536         memcpy(result, old, sizeof(*result));
5537         result->type &= TYPE_MASK;
5538         result->type |= specifiers;
5539         return result;
5540 }
5541
5542 static struct type *dup_type(struct compile_state *state, struct type *orig)
5543 {
5544         struct type *new;
5545         new = xcmalloc(sizeof(*new), "type");
5546         new->type = orig->type;
5547         new->field_ident = orig->field_ident;
5548         new->type_ident  = orig->type_ident;
5549         new->elements    = orig->elements;
5550         if (orig->left) {
5551                 new->left = dup_type(state, orig->left);
5552         }
5553         if (orig->right) {
5554                 new->right = dup_type(state, orig->right);
5555         }
5556         return new;
5557 }
5558
5559
5560 static struct type *invalid_type(struct compile_state *state, struct type *type)
5561 {
5562         struct type *invalid, *member;
5563         invalid = 0;
5564         if (!type) {
5565                 internal_error(state, 0, "type missing?");
5566         }
5567         switch(type->type & TYPE_MASK) {
5568         case TYPE_VOID:
5569         case TYPE_CHAR:         case TYPE_UCHAR:
5570         case TYPE_SHORT:        case TYPE_USHORT:
5571         case TYPE_INT:          case TYPE_UINT:
5572         case TYPE_LONG:         case TYPE_ULONG:
5573         case TYPE_LLONG:        case TYPE_ULLONG:
5574         case TYPE_POINTER:
5575         case TYPE_ENUM:
5576                 break;
5577         case TYPE_BITFIELD:
5578                 invalid = invalid_type(state, type->left);
5579                 break;
5580         case TYPE_ARRAY:
5581                 invalid = invalid_type(state, type->left);
5582                 break;
5583         case TYPE_STRUCT:
5584         case TYPE_TUPLE:
5585                 member = type->left;
5586                 while(member && (invalid == 0) && 
5587                         ((member->type & TYPE_MASK) == TYPE_PRODUCT)) {
5588                         invalid = invalid_type(state, member->left);
5589                         member = member->right;
5590                 }
5591                 if (!invalid) {
5592                         invalid = invalid_type(state, member);
5593                 }
5594                 break;
5595         case TYPE_UNION:
5596         case TYPE_JOIN:
5597                 member = type->left;
5598                 while(member && (invalid == 0) &&
5599                         ((member->type & TYPE_MASK) == TYPE_OVERLAP)) {
5600                         invalid = invalid_type(state, member->left);
5601                         member = member->right;
5602                 }
5603                 if (!invalid) {
5604                         invalid = invalid_type(state, member);
5605                 }
5606                 break;
5607         default:
5608                 invalid = type;
5609                 break;
5610         }
5611         return invalid;
5612         
5613 }
5614
5615 #define MASK_UCHAR(X)    ((X) & ((ulong_t)0xff))
5616 #define MASK_USHORT(X)   ((X) & (((ulong_t)1 << (SIZEOF_SHORT)) - 1))
5617 static inline ulong_t mask_uint(ulong_t x)
5618 {
5619         if (SIZEOF_INT < SIZEOF_LONG) {
5620                 ulong_t mask = (((ulong_t)1) << ((ulong_t)(SIZEOF_INT))) -1;
5621                 x &= mask;
5622         }
5623         return x;
5624 }
5625 #define MASK_UINT(X)      (mask_uint(X))
5626 #define MASK_ULONG(X)    (X)
5627
5628 static struct type void_type    = { .type  = TYPE_VOID };
5629 static struct type char_type    = { .type  = TYPE_CHAR };
5630 static struct type uchar_type   = { .type  = TYPE_UCHAR };
5631 static struct type short_type   = { .type  = TYPE_SHORT };
5632 static struct type ushort_type  = { .type  = TYPE_USHORT };
5633 static struct type int_type     = { .type  = TYPE_INT };
5634 static struct type uint_type    = { .type  = TYPE_UINT };
5635 static struct type long_type    = { .type  = TYPE_LONG };
5636 static struct type ulong_type   = { .type  = TYPE_ULONG };
5637 static struct type unknown_type = { .type  = TYPE_UNKNOWN };
5638
5639 static struct type void_ptr_type  = {
5640         .type = TYPE_POINTER,
5641         .left = &void_type,
5642 };
5643
5644 static struct type void_func_type = { 
5645         .type  = TYPE_FUNCTION,
5646         .left  = &void_type,
5647         .right = &void_type,
5648 };
5649
5650 static size_t bits_to_bytes(size_t size)
5651 {
5652         return (size + SIZEOF_CHAR - 1)/SIZEOF_CHAR;
5653 }
5654
5655 static struct triple *variable(struct compile_state *state, struct type *type)
5656 {
5657         struct triple *result;
5658         if ((type->type & STOR_MASK) != STOR_PERM) {
5659                 result = triple(state, OP_ADECL, type, 0, 0);
5660                 generate_lhs_pieces(state, result);
5661         }
5662         else {
5663                 result = triple(state, OP_SDECL, type, 0, 0);
5664         }
5665         return result;
5666 }
5667
5668 static void stor_of(FILE *fp, struct type *type)
5669 {
5670         switch(type->type & STOR_MASK) {
5671         case STOR_AUTO:
5672                 fprintf(fp, "auto ");
5673                 break;
5674         case STOR_STATIC:
5675                 fprintf(fp, "static ");
5676                 break;
5677         case STOR_LOCAL:
5678                 fprintf(fp, "local ");
5679                 break;
5680         case STOR_EXTERN:
5681                 fprintf(fp, "extern ");
5682                 break;
5683         case STOR_REGISTER:
5684                 fprintf(fp, "register ");
5685                 break;
5686         case STOR_TYPEDEF:
5687                 fprintf(fp, "typedef ");
5688                 break;
5689         case STOR_INLINE | STOR_LOCAL:
5690                 fprintf(fp, "inline ");
5691                 break;
5692         case STOR_INLINE | STOR_STATIC:
5693                 fprintf(fp, "static inline");
5694                 break;
5695         case STOR_INLINE | STOR_EXTERN:
5696                 fprintf(fp, "extern inline");
5697                 break;
5698         default:
5699                 fprintf(fp, "stor:%x", type->type & STOR_MASK);
5700                 break;
5701         }
5702 }
5703 static void qual_of(FILE *fp, struct type *type)
5704 {
5705         if (type->type & QUAL_CONST) {
5706                 fprintf(fp, " const");
5707         }
5708         if (type->type & QUAL_VOLATILE) {
5709                 fprintf(fp, " volatile");
5710         }
5711         if (type->type & QUAL_RESTRICT) {
5712                 fprintf(fp, " restrict");
5713         }
5714 }
5715
5716 static void name_of(FILE *fp, struct type *type)
5717 {
5718         unsigned int base_type;
5719         base_type = type->type & TYPE_MASK;
5720         if ((base_type != TYPE_PRODUCT) && (base_type != TYPE_OVERLAP)) {
5721                 stor_of(fp, type);
5722         }
5723         switch(base_type) {
5724         case TYPE_VOID:
5725                 fprintf(fp, "void");
5726                 qual_of(fp, type);
5727                 break;
5728         case TYPE_CHAR:
5729                 fprintf(fp, "signed char");
5730                 qual_of(fp, type);
5731                 break;
5732         case TYPE_UCHAR:
5733                 fprintf(fp, "unsigned char");
5734                 qual_of(fp, type);
5735                 break;
5736         case TYPE_SHORT:
5737                 fprintf(fp, "signed short");
5738                 qual_of(fp, type);
5739                 break;
5740         case TYPE_USHORT:
5741                 fprintf(fp, "unsigned short");
5742                 qual_of(fp, type);
5743                 break;
5744         case TYPE_INT:
5745                 fprintf(fp, "signed int");
5746                 qual_of(fp, type);
5747                 break;
5748         case TYPE_UINT:
5749                 fprintf(fp, "unsigned int");
5750                 qual_of(fp, type);
5751                 break;
5752         case TYPE_LONG:
5753                 fprintf(fp, "signed long");
5754                 qual_of(fp, type);
5755                 break;
5756         case TYPE_ULONG:
5757                 fprintf(fp, "unsigned long");
5758                 qual_of(fp, type);
5759                 break;
5760         case TYPE_POINTER:
5761                 name_of(fp, type->left);
5762                 fprintf(fp, " * ");
5763                 qual_of(fp, type);
5764                 break;
5765         case TYPE_PRODUCT:
5766                 name_of(fp, type->left);
5767                 fprintf(fp, ", ");
5768                 name_of(fp, type->right);
5769                 break;
5770         case TYPE_OVERLAP:
5771                 name_of(fp, type->left);
5772                 fprintf(fp, ",| ");
5773                 name_of(fp, type->right);
5774                 break;
5775         case TYPE_ENUM:
5776                 fprintf(fp, "enum %s", 
5777                         (type->type_ident)? type->type_ident->name : "");
5778                 qual_of(fp, type);
5779                 break;
5780         case TYPE_STRUCT:
5781                 fprintf(fp, "struct %s { ", 
5782                         (type->type_ident)? type->type_ident->name : "");
5783                 name_of(fp, type->left);
5784                 fprintf(fp, " } ");
5785                 qual_of(fp, type);
5786                 break;
5787         case TYPE_UNION:
5788                 fprintf(fp, "union %s { ", 
5789                         (type->type_ident)? type->type_ident->name : "");
5790                 name_of(fp, type->left);
5791                 fprintf(fp, " } ");
5792                 qual_of(fp, type);
5793                 break;
5794         case TYPE_FUNCTION:
5795                 name_of(fp, type->left);
5796                 fprintf(fp, " (*)(");
5797                 name_of(fp, type->right);
5798                 fprintf(fp, ")");
5799                 break;
5800         case TYPE_ARRAY:
5801                 name_of(fp, type->left);
5802                 fprintf(fp, " [%ld]", (long)(type->elements));
5803                 break;
5804         case TYPE_TUPLE:
5805                 fprintf(fp, "tuple { "); 
5806                 name_of(fp, type->left);
5807                 fprintf(fp, " } ");
5808                 qual_of(fp, type);
5809                 break;
5810         case TYPE_JOIN:
5811                 fprintf(fp, "join { ");
5812                 name_of(fp, type->left);
5813                 fprintf(fp, " } ");
5814                 qual_of(fp, type);
5815                 break;
5816         case TYPE_BITFIELD:
5817                 name_of(fp, type->left);
5818                 fprintf(fp, " : %d ", type->elements);
5819                 qual_of(fp, type);
5820                 break;
5821         case TYPE_UNKNOWN:
5822                 fprintf(fp, "unknown_t");
5823                 break;
5824         default:
5825                 fprintf(fp, "????: %x", base_type);
5826                 break;
5827         }
5828         if (type->field_ident && type->field_ident->name) {
5829                 fprintf(fp, " .%s", type->field_ident->name);
5830         }
5831 }
5832
5833 static size_t align_of(struct compile_state *state, struct type *type)
5834 {
5835         size_t align;
5836         align = 0;
5837         switch(type->type & TYPE_MASK) {
5838         case TYPE_VOID:
5839                 align = 1;
5840                 break;
5841         case TYPE_BITFIELD:
5842                 align = 1;
5843                 break;
5844         case TYPE_CHAR:
5845         case TYPE_UCHAR:
5846                 align = ALIGNOF_CHAR;
5847                 break;
5848         case TYPE_SHORT:
5849         case TYPE_USHORT:
5850                 align = ALIGNOF_SHORT;
5851                 break;
5852         case TYPE_INT:
5853         case TYPE_UINT:
5854         case TYPE_ENUM:
5855                 align = ALIGNOF_INT;
5856                 break;
5857         case TYPE_LONG:
5858         case TYPE_ULONG:
5859                 align = ALIGNOF_LONG;
5860                 break;
5861         case TYPE_POINTER:
5862                 align = ALIGNOF_POINTER;
5863                 break;
5864         case TYPE_PRODUCT:
5865         case TYPE_OVERLAP:
5866         {
5867                 size_t left_align, right_align;
5868                 left_align  = align_of(state, type->left);
5869                 right_align = align_of(state, type->right);
5870                 align = (left_align >= right_align) ? left_align : right_align;
5871                 break;
5872         }
5873         case TYPE_ARRAY:
5874                 align = align_of(state, type->left);
5875                 break;
5876         case TYPE_STRUCT:
5877         case TYPE_TUPLE:
5878         case TYPE_UNION:
5879         case TYPE_JOIN:
5880                 align = align_of(state, type->left);
5881                 break;
5882         default:
5883                 error(state, 0, "alignof not yet defined for type\n");
5884                 break;
5885         }
5886         return align;
5887 }
5888
5889 static size_t reg_align_of(struct compile_state *state, struct type *type)
5890 {
5891         size_t align;
5892         align = 0;
5893         switch(type->type & TYPE_MASK) {
5894         case TYPE_VOID:
5895                 align = 1;
5896                 break;
5897         case TYPE_BITFIELD:
5898                 align = 1;
5899                 break;
5900         case TYPE_CHAR:
5901         case TYPE_UCHAR:
5902                 align = REG_ALIGNOF_CHAR;
5903                 break;
5904         case TYPE_SHORT:
5905         case TYPE_USHORT:
5906                 align = REG_ALIGNOF_SHORT;
5907                 break;
5908         case TYPE_INT:
5909         case TYPE_UINT:
5910         case TYPE_ENUM:
5911                 align = REG_ALIGNOF_INT;
5912                 break;
5913         case TYPE_LONG:
5914         case TYPE_ULONG:
5915                 align = REG_ALIGNOF_LONG;
5916                 break;
5917         case TYPE_POINTER:
5918                 align = REG_ALIGNOF_POINTER;
5919                 break;
5920         case TYPE_PRODUCT:
5921         case TYPE_OVERLAP:
5922         {
5923                 size_t left_align, right_align;
5924                 left_align  = reg_align_of(state, type->left);
5925                 right_align = reg_align_of(state, type->right);
5926                 align = (left_align >= right_align) ? left_align : right_align;
5927                 break;
5928         }
5929         case TYPE_ARRAY:
5930                 align = reg_align_of(state, type->left);
5931                 break;
5932         case TYPE_STRUCT:
5933         case TYPE_UNION:
5934         case TYPE_TUPLE:
5935         case TYPE_JOIN:
5936                 align = reg_align_of(state, type->left);
5937                 break;
5938         default:
5939                 error(state, 0, "alignof not yet defined for type\n");
5940                 break;
5941         }
5942         return align;
5943 }
5944
5945 static size_t align_of_in_bytes(struct compile_state *state, struct type *type)
5946 {
5947         return bits_to_bytes(align_of(state, type));
5948 }
5949 static size_t size_of(struct compile_state *state, struct type *type);
5950 static size_t reg_size_of(struct compile_state *state, struct type *type);
5951
5952 static size_t needed_padding(struct compile_state *state, 
5953         struct type *type, size_t offset)
5954 {
5955         size_t padding, align;
5956         align = align_of(state, type);
5957         /* Align to the next machine word if the bitfield does completely
5958          * fit into the current word.
5959          */
5960         if ((type->type & TYPE_MASK) == TYPE_BITFIELD) {
5961                 size_t size;
5962                 size = size_of(state, type);
5963                 if ((offset + type->elements)/size != offset/size) {
5964                         align = size;
5965                 }
5966         }
5967         padding = 0;
5968         if (offset % align) {
5969                 padding = align - (offset % align);
5970         }
5971         return padding;
5972 }
5973
5974 static size_t reg_needed_padding(struct compile_state *state, 
5975         struct type *type, size_t offset)
5976 {
5977         size_t padding, align;
5978         align = reg_align_of(state, type);
5979         /* Align to the next register word if the bitfield does completely
5980          * fit into the current register.
5981          */
5982         if (((type->type & TYPE_MASK) == TYPE_BITFIELD) &&
5983                 (((offset + type->elements)/REG_SIZEOF_REG) != (offset/REG_SIZEOF_REG))) 
5984         {
5985                 align = REG_SIZEOF_REG;
5986         }
5987         padding = 0;
5988         if (offset % align) {
5989                 padding = align - (offset % align);
5990         }
5991         return padding;
5992 }
5993
5994 static size_t size_of(struct compile_state *state, struct type *type)
5995 {
5996         size_t size;
5997         size = 0;
5998         switch(type->type & TYPE_MASK) {
5999         case TYPE_VOID:
6000                 size = 0;
6001                 break;
6002         case TYPE_BITFIELD:
6003                 size = type->elements;
6004                 break;
6005         case TYPE_CHAR:
6006         case TYPE_UCHAR:
6007                 size = SIZEOF_CHAR;
6008                 break;
6009         case TYPE_SHORT:
6010         case TYPE_USHORT:
6011                 size = SIZEOF_SHORT;
6012                 break;
6013         case TYPE_INT:
6014         case TYPE_UINT:
6015         case TYPE_ENUM:
6016                 size = SIZEOF_INT;
6017                 break;
6018         case TYPE_LONG:
6019         case TYPE_ULONG:
6020                 size = SIZEOF_LONG;
6021                 break;
6022         case TYPE_POINTER:
6023                 size = SIZEOF_POINTER;
6024                 break;
6025         case TYPE_PRODUCT:
6026         {
6027                 size_t pad;
6028                 size = 0;
6029                 while((type->type & TYPE_MASK) == TYPE_PRODUCT) {
6030                         pad = needed_padding(state, type->left, size);
6031                         size = size + pad + size_of(state, type->left);
6032                         type = type->right;
6033                 }
6034                 pad = needed_padding(state, type, size);
6035                 size = size + pad + size_of(state, type);
6036                 break;
6037         }
6038         case TYPE_OVERLAP:
6039         {
6040                 size_t size_left, size_right;
6041                 size_left = size_of(state, type->left);
6042                 size_right = size_of(state, type->right);
6043                 size = (size_left >= size_right)? size_left : size_right;
6044                 break;
6045         }
6046         case TYPE_ARRAY:
6047                 if (type->elements == ELEMENT_COUNT_UNSPECIFIED) {
6048                         internal_error(state, 0, "Invalid array type");
6049                 } else {
6050                         size = size_of(state, type->left) * type->elements;
6051                 }
6052                 break;
6053         case TYPE_STRUCT:
6054         case TYPE_TUPLE:
6055         {
6056                 size_t pad;
6057                 size = size_of(state, type->left);
6058                 /* Pad structures so their size is a multiples of their alignment */
6059                 pad = needed_padding(state, type, size);
6060                 size = size + pad;
6061                 break;
6062         }
6063         case TYPE_UNION:
6064         case TYPE_JOIN:
6065         {
6066                 size_t pad;
6067                 size = size_of(state, type->left);
6068                 /* Pad unions so their size is a multiple of their alignment */
6069                 pad = needed_padding(state, type, size);
6070                 size = size + pad;
6071                 break;
6072         }
6073         default:
6074                 internal_error(state, 0, "sizeof not yet defined for type");
6075                 break;
6076         }
6077         return size;
6078 }
6079
6080 static size_t reg_size_of(struct compile_state *state, struct type *type)
6081 {
6082         size_t size;
6083         size = 0;
6084         switch(type->type & TYPE_MASK) {
6085         case TYPE_VOID:
6086                 size = 0;
6087                 break;
6088         case TYPE_BITFIELD:
6089                 size = type->elements;
6090                 break;
6091         case TYPE_CHAR:
6092         case TYPE_UCHAR:
6093                 size = REG_SIZEOF_CHAR;
6094                 break;
6095         case TYPE_SHORT:
6096         case TYPE_USHORT:
6097                 size = REG_SIZEOF_SHORT;
6098                 break;
6099         case TYPE_INT:
6100         case TYPE_UINT:
6101         case TYPE_ENUM:
6102                 size = REG_SIZEOF_INT;
6103                 break;
6104         case TYPE_LONG:
6105         case TYPE_ULONG:
6106                 size = REG_SIZEOF_LONG;
6107                 break;
6108         case TYPE_POINTER:
6109                 size = REG_SIZEOF_POINTER;
6110                 break;
6111         case TYPE_PRODUCT:
6112         {
6113                 size_t pad;
6114                 size = 0;
6115                 while((type->type & TYPE_MASK) == TYPE_PRODUCT) {
6116                         pad = reg_needed_padding(state, type->left, size);
6117                         size = size + pad + reg_size_of(state, type->left);
6118                         type = type->right;
6119                 }
6120                 pad = reg_needed_padding(state, type, size);
6121                 size = size + pad + reg_size_of(state, type);
6122                 break;
6123         }
6124         case TYPE_OVERLAP:
6125         {
6126                 size_t size_left, size_right;
6127                 size_left  = reg_size_of(state, type->left);
6128                 size_right = reg_size_of(state, type->right);
6129                 size = (size_left >= size_right)? size_left : size_right;
6130                 break;
6131         }
6132         case TYPE_ARRAY:
6133                 if (type->elements == ELEMENT_COUNT_UNSPECIFIED) {
6134                         internal_error(state, 0, "Invalid array type");
6135                 } else {
6136                         size = reg_size_of(state, type->left) * type->elements;
6137                 }
6138                 break;
6139         case TYPE_STRUCT:
6140         case TYPE_TUPLE:
6141         {
6142                 size_t pad;
6143                 size = reg_size_of(state, type->left);
6144                 /* Pad structures so their size is a multiples of their alignment */
6145                 pad = reg_needed_padding(state, type, size);
6146                 size = size + pad;
6147                 break;
6148         }
6149         case TYPE_UNION:
6150         case TYPE_JOIN:
6151         {
6152                 size_t pad;
6153                 size = reg_size_of(state, type->left);
6154                 /* Pad unions so their size is a multiple of their alignment */
6155                 pad = reg_needed_padding(state, type, size);
6156                 size = size + pad;
6157                 break;
6158         }
6159         default:
6160                 internal_error(state, 0, "sizeof not yet defined for type");
6161                 break;
6162         }
6163         return size;
6164 }
6165
6166 static size_t registers_of(struct compile_state *state, struct type *type)
6167 {
6168         size_t registers;
6169         registers = reg_size_of(state, type);
6170         registers += REG_SIZEOF_REG - 1;
6171         registers /= REG_SIZEOF_REG;
6172         return registers;
6173 }
6174
6175 static size_t size_of_in_bytes(struct compile_state *state, struct type *type)
6176 {
6177         return bits_to_bytes(size_of(state, type));
6178 }
6179
6180 static size_t field_offset(struct compile_state *state, 
6181         struct type *type, struct hash_entry *field)
6182 {
6183         struct type *member;
6184         size_t size;
6185
6186         size = 0;
6187         member = 0;
6188         if ((type->type & TYPE_MASK) == TYPE_STRUCT) {
6189                 member = type->left;
6190                 while(member && ((member->type & TYPE_MASK) == TYPE_PRODUCT)) {
6191                         size += needed_padding(state, member->left, size);
6192                         if (member->left->field_ident == field) {
6193                                 member = member->left;
6194                                 break;
6195                         }
6196                         size += size_of(state, member->left);
6197                         member = member->right;
6198                 }
6199                 size += needed_padding(state, member, size);
6200         }
6201         else if ((type->type & TYPE_MASK) == TYPE_UNION) {
6202                 member = type->left;
6203                 while(member && ((member->type & TYPE_MASK) == TYPE_OVERLAP)) {
6204                         if (member->left->field_ident == field) {
6205                                 member = member->left;
6206                                 break;
6207                         }
6208                         member = member->right;
6209                 }
6210         }
6211         else {
6212                 internal_error(state, 0, "field_offset only works on structures and unions");
6213         }
6214
6215         if (!member || (member->field_ident != field)) {
6216                 error(state, 0, "member %s not present", field->name);
6217         }
6218         return size;
6219 }
6220
6221 static size_t field_reg_offset(struct compile_state *state, 
6222         struct type *type, struct hash_entry *field)
6223 {
6224         struct type *member;
6225         size_t size;
6226
6227         size = 0;
6228         member = 0;
6229         if ((type->type & TYPE_MASK) == TYPE_STRUCT) {
6230                 member = type->left;
6231                 while(member && ((member->type & TYPE_MASK) == TYPE_PRODUCT)) {
6232                         size += reg_needed_padding(state, member->left, size);
6233                         if (member->left->field_ident == field) {
6234                                 member = member->left;
6235                                 break;
6236                         }
6237                         size += reg_size_of(state, member->left);
6238                         member = member->right;
6239                 }
6240         }
6241         else if ((type->type & TYPE_MASK) == TYPE_UNION) {
6242                 member = type->left;
6243                 while(member && ((member->type & TYPE_MASK) == TYPE_OVERLAP)) {
6244                         if (member->left->field_ident == field) {
6245                                 member = member->left;
6246                                 break;
6247                         }
6248                         member = member->right;
6249                 }
6250         }
6251         else {
6252                 internal_error(state, 0, "field_reg_offset only works on structures and unions");
6253         }
6254
6255         size += reg_needed_padding(state, member, size);
6256         if (!member || (member->field_ident != field)) {
6257                 error(state, 0, "member %s not present", field->name);
6258         }
6259         return size;
6260 }
6261
6262 static struct type *field_type(struct compile_state *state, 
6263         struct type *type, struct hash_entry *field)
6264 {
6265         struct type *member;
6266
6267         member = 0;
6268         if ((type->type & TYPE_MASK) == TYPE_STRUCT) {
6269                 member = type->left;
6270                 while(member && ((member->type & TYPE_MASK) == TYPE_PRODUCT)) {
6271                         if (member->left->field_ident == field) {
6272                                 member = member->left;
6273                                 break;
6274                         }
6275                         member = member->right;
6276                 }
6277         }
6278         else if ((type->type & TYPE_MASK) == TYPE_UNION) {
6279                 member = type->left;
6280                 while(member && ((member->type & TYPE_MASK) == TYPE_OVERLAP)) {
6281                         if (member->left->field_ident == field) {
6282                                 member = member->left;
6283                                 break;
6284                         }
6285                         member = member->right;
6286                 }
6287         }
6288         else {
6289                 internal_error(state, 0, "field_type only works on structures and unions");
6290         }
6291         
6292         if (!member || (member->field_ident != field)) {
6293                 error(state, 0, "member %s not present", field->name);
6294         }
6295         return member;
6296 }
6297
6298 static size_t index_offset(struct compile_state *state, 
6299         struct type *type, ulong_t index)
6300 {
6301         struct type *member;
6302         size_t size;
6303         size = 0;
6304         if ((type->type & TYPE_MASK) == TYPE_ARRAY) {
6305                 size = size_of(state, type->left) * index;
6306         }
6307         else if ((type->type & TYPE_MASK) == TYPE_TUPLE) {
6308                 ulong_t i;
6309                 member = type->left;
6310                 i = 0;
6311                 while(member && ((member->type & TYPE_MASK) == TYPE_PRODUCT)) {
6312                         size += needed_padding(state, member->left, size);
6313                         if (i == index) {
6314                                 member = member->left;
6315                                 break;
6316                         }
6317                         size += size_of(state, member->left);
6318                         i++;
6319                         member = member->right;
6320                 }
6321                 size += needed_padding(state, member, size);
6322                 if (i != index) {
6323                         internal_error(state, 0, "Missing member index: %u", index);
6324                 }
6325         }
6326         else if ((type->type & TYPE_MASK) == TYPE_JOIN) {
6327                 ulong_t i;
6328                 size = 0;
6329                 member = type->left;
6330                 i = 0;
6331                 while(member && ((member->type & TYPE_MASK) == TYPE_OVERLAP)) {
6332                         if (i == index) {
6333                                 member = member->left;
6334                                 break;
6335                         }
6336                         i++;
6337                         member = member->right;
6338                 }
6339                 if (i != index) {
6340                         internal_error(state, 0, "Missing member index: %u", index);
6341                 }
6342         }
6343         else {
6344                 internal_error(state, 0, 
6345                         "request for index %u in something not an array, tuple or join",
6346                         index);
6347         }
6348         return size;
6349 }
6350
6351 static size_t index_reg_offset(struct compile_state *state, 
6352         struct type *type, ulong_t index)
6353 {
6354         struct type *member;
6355         size_t size;
6356         size = 0;
6357         if ((type->type & TYPE_MASK) == TYPE_ARRAY) {
6358                 size = reg_size_of(state, type->left) * index;
6359         }
6360         else if ((type->type & TYPE_MASK) == TYPE_TUPLE) {
6361                 ulong_t i;
6362                 member = type->left;
6363                 i = 0;
6364                 while(member && ((member->type & TYPE_MASK) == TYPE_PRODUCT)) {
6365                         size += reg_needed_padding(state, member->left, size);
6366                         if (i == index) {
6367                                 member = member->left;
6368                                 break;
6369                         }
6370                         size += reg_size_of(state, member->left);
6371                         i++;
6372                         member = member->right;
6373                 }
6374                 size += reg_needed_padding(state, member, size);
6375                 if (i != index) {
6376                         internal_error(state, 0, "Missing member index: %u", index);
6377                 }
6378                 
6379         }
6380         else if ((type->type & TYPE_MASK) == TYPE_JOIN) {
6381                 ulong_t i;
6382                 size = 0;
6383                 member = type->left;
6384                 i = 0;
6385                 while(member && ((member->type & TYPE_MASK) == TYPE_OVERLAP)) {
6386                         if (i == index) {
6387                                 member = member->left;
6388                                 break;
6389                         }
6390                         i++;
6391                         member = member->right;
6392                 }
6393                 if (i != index) {
6394                         internal_error(state, 0, "Missing member index: %u", index);
6395                 }
6396         }
6397         else {
6398                 internal_error(state, 0, 
6399                         "request for index %u in something not an array, tuple or join",
6400                         index);
6401         }
6402         return size;
6403 }
6404
6405 static struct type *index_type(struct compile_state *state,
6406         struct type *type, ulong_t index)
6407 {
6408         struct type *member;
6409         if (index >= type->elements) {
6410                 internal_error(state, 0, "Invalid element %u requested", index);
6411         }
6412         if ((type->type & TYPE_MASK) == TYPE_ARRAY) {
6413                 member = type->left;
6414         }
6415         else if ((type->type & TYPE_MASK) == TYPE_TUPLE) {
6416                 ulong_t i;
6417                 member = type->left;
6418                 i = 0;
6419                 while(member && ((member->type & TYPE_MASK) == TYPE_PRODUCT)) {
6420                         if (i == index) {
6421                                 member = member->left;
6422                                 break;
6423                         }
6424                         i++;
6425                         member = member->right;
6426                 }
6427                 if (i != index) {
6428                         internal_error(state, 0, "Missing member index: %u", index);
6429                 }
6430         }
6431         else if ((type->type & TYPE_MASK) == TYPE_JOIN) {
6432                 ulong_t i;
6433                 member = type->left;
6434                 i = 0;
6435                 while(member && ((member->type & TYPE_MASK) == TYPE_OVERLAP)) {
6436                         if (i == index) {
6437                                 member = member->left;
6438                                 break;
6439                         }
6440                         i++;
6441                         member = member->right;
6442                 }
6443                 if (i != index) {
6444                         internal_error(state, 0, "Missing member index: %u", index);
6445                 }
6446         }
6447         else {
6448                 member = 0;
6449                 internal_error(state, 0, 
6450                         "request for index %u in something not an array, tuple or join",
6451                         index);
6452         }
6453         return member;
6454 }
6455
6456 static struct type *unpack_type(struct compile_state *state, struct type *type)
6457 {
6458         /* If I have a single register compound type not a bit-field
6459          * find the real type.
6460          */
6461         struct type *start_type;
6462         size_t size;
6463         /* Get out early if I need multiple registers for this type */
6464         size = reg_size_of(state, type);
6465         if (size > REG_SIZEOF_REG) {
6466                 return type;
6467         }
6468         /* Get out early if I don't need any registers for this type */
6469         if (size == 0) {
6470                 return &void_type;
6471         }
6472         /* Loop until I have no more layers I can remove */
6473         do {
6474                 start_type = type;
6475                 switch(type->type & TYPE_MASK) {
6476                 case TYPE_ARRAY:
6477                         /* If I have a single element the unpacked type
6478                          * is that element.
6479                          */
6480                         if (type->elements == 1) {
6481                                 type = type->left;
6482                         }
6483                         break;
6484                 case TYPE_STRUCT:
6485                 case TYPE_TUPLE:
6486                         /* If I have a single element the unpacked type
6487                          * is that element.
6488                          */
6489                         if (type->elements == 1) {
6490                                 type = type->left;
6491                         }
6492                         /* If I have multiple elements the unpacked
6493                          * type is the non-void element.
6494                          */
6495                         else {
6496                                 struct type *next, *member;
6497                                 struct type *sub_type;
6498                                 sub_type = 0;
6499                                 next = type->left;
6500                                 while(next) {
6501                                         member = next;
6502                                         next = 0;
6503                                         if ((member->type & TYPE_MASK) == TYPE_PRODUCT) {
6504                                                 next = member->right;
6505                                                 member = member->left;
6506                                         }
6507                                         if (reg_size_of(state, member) > 0) {
6508                                                 if (sub_type) {
6509                                                         internal_error(state, 0, "true compound type in a register");
6510                                                 }
6511                                                 sub_type = member;
6512                                         }
6513                                 }
6514                                 if (sub_type) {
6515                                         type = sub_type;
6516                                 }
6517                         }
6518                         break;
6519
6520                 case TYPE_UNION:
6521                 case TYPE_JOIN:
6522                         /* If I have a single element the unpacked type
6523                          * is that element.
6524                          */
6525                         if (type->elements == 1) {
6526                                 type = type->left;
6527                         }
6528                         /* I can't in general unpack union types */
6529                         break;
6530                 default:
6531                         /* If I'm not a compound type I can't unpack it */
6532                         break;
6533                 }
6534         } while(start_type != type);
6535         switch(type->type & TYPE_MASK) {
6536         case TYPE_STRUCT:
6537         case TYPE_ARRAY:
6538         case TYPE_TUPLE:
6539                 internal_error(state, 0, "irredicible type?");
6540                 break;
6541         }
6542         return type;
6543 }
6544
6545 static int equiv_types(struct type *left, struct type *right);
6546 static int is_compound_type(struct type *type);
6547
6548 static struct type *reg_type(
6549         struct compile_state *state, struct type *type, int reg_offset)
6550 {
6551         struct type *member;
6552         size_t size;
6553 #if 1
6554         struct type *invalid;
6555         invalid = invalid_type(state, type);
6556         if (invalid) {
6557                 fprintf(state->errout, "type: ");
6558                 name_of(state->errout, type);
6559                 fprintf(state->errout, "\n");
6560                 fprintf(state->errout, "invalid: ");
6561                 name_of(state->errout, invalid);
6562                 fprintf(state->errout, "\n");
6563                 internal_error(state, 0, "bad input type?");
6564         }
6565 #endif
6566
6567         size = reg_size_of(state, type);
6568         if (reg_offset > size) {
6569                 member = 0;
6570                 fprintf(state->errout, "type: ");
6571                 name_of(state->errout, type);
6572                 fprintf(state->errout, "\n");
6573                 internal_error(state, 0, "offset outside of type");
6574         }
6575         else {
6576                 switch(type->type & TYPE_MASK) {
6577                         /* Don't do anything with the basic types */
6578                 case TYPE_VOID:
6579                 case TYPE_CHAR:         case TYPE_UCHAR:
6580                 case TYPE_SHORT:        case TYPE_USHORT:
6581                 case TYPE_INT:          case TYPE_UINT:
6582                 case TYPE_LONG:         case TYPE_ULONG:
6583                 case TYPE_LLONG:        case TYPE_ULLONG:
6584                 case TYPE_FLOAT:        case TYPE_DOUBLE:
6585                 case TYPE_LDOUBLE:
6586                 case TYPE_POINTER:
6587                 case TYPE_ENUM:
6588                 case TYPE_BITFIELD:
6589                         member = type;
6590                         break;
6591                 case TYPE_ARRAY:
6592                         member = type->left;
6593                         size = reg_size_of(state, member);
6594                         if (size > REG_SIZEOF_REG) {
6595                                 member = reg_type(state, member, reg_offset % size);
6596                         }
6597                         break;
6598                 case TYPE_STRUCT:
6599                 case TYPE_TUPLE:
6600                 {
6601                         size_t offset;
6602                         offset = 0;
6603                         member = type->left;
6604                         while(member && ((member->type & TYPE_MASK) == TYPE_PRODUCT)) {
6605                                 size = reg_size_of(state, member->left);
6606                                 offset += reg_needed_padding(state, member->left, offset);
6607                                 if ((offset + size) > reg_offset) {
6608                                         member = member->left;
6609                                         break;
6610                                 }
6611                                 offset += size;
6612                                 member = member->right;
6613                         }
6614                         offset += reg_needed_padding(state, member, offset);
6615                         member = reg_type(state, member, reg_offset - offset);
6616                         break;
6617                 }
6618                 case TYPE_UNION:
6619                 case TYPE_JOIN:
6620                 {
6621                         struct type *join, **jnext, *mnext;
6622                         join = new_type(TYPE_JOIN, 0, 0);
6623                         jnext = &join->left;
6624                         mnext = type->left;
6625                         while(mnext) {
6626                                 size_t size;
6627                                 member = mnext;
6628                                 mnext = 0;
6629                                 if ((member->type & TYPE_MASK) == TYPE_OVERLAP) {
6630                                         mnext = member->right;
6631                                         member = member->left;
6632                                 }
6633                                 size = reg_size_of(state, member);
6634                                 if (size > reg_offset) {
6635                                         struct type *part, *hunt;
6636                                         part = reg_type(state, member, reg_offset);
6637                                         /* See if this type is already in the union */
6638                                         hunt = join->left;
6639                                         while(hunt) {
6640                                                 struct type *test = hunt;
6641                                                 hunt = 0;
6642                                                 if ((test->type & TYPE_MASK) == TYPE_OVERLAP) {
6643                                                         hunt = test->right;
6644                                                         test = test->left;
6645                                                 }
6646                                                 if (equiv_types(part, test)) {
6647                                                         goto next;
6648                                                 }
6649                                         }
6650                                         /* Nope add it */
6651                                         if (!*jnext) {
6652                                                 *jnext = part;
6653                                         } else {
6654                                                 *jnext = new_type(TYPE_OVERLAP, *jnext, part);
6655                                                 jnext = &(*jnext)->right;
6656                                         }
6657                                         join->elements++;
6658                                 }
6659                         next:
6660                                 ;
6661                         }
6662                         if (join->elements == 0) {
6663                                 internal_error(state, 0, "No elements?");
6664                         }
6665                         member = join;
6666                         break;
6667                 }
6668                 default:
6669                         member = 0;
6670                         fprintf(state->errout, "type: ");
6671                         name_of(state->errout, type);
6672                         fprintf(state->errout, "\n");
6673                         internal_error(state, 0, "reg_type not yet defined for type");
6674                         
6675                 }
6676         }
6677         /* If I have a single register compound type not a bit-field
6678          * find the real type.
6679          */
6680         member = unpack_type(state, member);
6681                 ;
6682         size  = reg_size_of(state, member);
6683         if (size > REG_SIZEOF_REG) {
6684                 internal_error(state, 0, "Cannot find type of single register");
6685         }
6686 #if 1
6687         invalid = invalid_type(state, member);
6688         if (invalid) {
6689                 fprintf(state->errout, "type: ");
6690                 name_of(state->errout, member);
6691                 fprintf(state->errout, "\n");
6692                 fprintf(state->errout, "invalid: ");
6693                 name_of(state->errout, invalid);
6694                 fprintf(state->errout, "\n");
6695                 internal_error(state, 0, "returning bad type?");
6696         }
6697 #endif
6698         return member;
6699 }
6700
6701 static struct type *next_field(struct compile_state *state,
6702         struct type *type, struct type *prev_member) 
6703 {
6704         struct type *member;
6705         if ((type->type & TYPE_MASK) != TYPE_STRUCT) {
6706                 internal_error(state, 0, "next_field only works on structures");
6707         }
6708         member = type->left;
6709         while((member->type & TYPE_MASK) == TYPE_PRODUCT) {
6710                 if (!prev_member) {
6711                         member = member->left;
6712                         break;
6713                 }
6714                 if (member->left == prev_member) {
6715                         prev_member = 0;
6716                 }
6717                 member = member->right;
6718         }
6719         if (member == prev_member) {
6720                 prev_member = 0;
6721         }
6722         if (prev_member) {
6723                 internal_error(state, 0, "prev_member %s not present", 
6724                         prev_member->field_ident->name);
6725         }
6726         return member;
6727 }
6728
6729 typedef void (*walk_type_fields_cb_t)(struct compile_state *state, struct type *type, 
6730         size_t ret_offset, size_t mem_offset, void *arg);
6731
6732 static void walk_type_fields(struct compile_state *state,
6733         struct type *type, size_t reg_offset, size_t mem_offset,
6734         walk_type_fields_cb_t cb, void *arg);
6735
6736 static void walk_struct_fields(struct compile_state *state,
6737         struct type *type, size_t reg_offset, size_t mem_offset,
6738         walk_type_fields_cb_t cb, void *arg)
6739 {
6740         struct type *tptr;
6741         ulong_t i;
6742         if ((type->type & TYPE_MASK) != TYPE_STRUCT) {
6743                 internal_error(state, 0, "walk_struct_fields only works on structures");
6744         }
6745         tptr = type->left;
6746         for(i = 0; i < type->elements; i++) {
6747                 struct type *mtype;
6748                 mtype = tptr;
6749                 if ((mtype->type & TYPE_MASK) == TYPE_PRODUCT) {
6750                         mtype = mtype->left;
6751                 }
6752                 walk_type_fields(state, mtype, 
6753                         reg_offset + 
6754                         field_reg_offset(state, type, mtype->field_ident),
6755                         mem_offset + 
6756                         field_offset(state, type, mtype->field_ident),
6757                         cb, arg);
6758                 tptr = tptr->right;
6759         }
6760         
6761 }
6762
6763 static void walk_type_fields(struct compile_state *state,
6764         struct type *type, size_t reg_offset, size_t mem_offset,
6765         walk_type_fields_cb_t cb, void *arg)
6766 {
6767         switch(type->type & TYPE_MASK) {
6768         case TYPE_STRUCT:
6769                 walk_struct_fields(state, type, reg_offset, mem_offset, cb, arg);
6770                 break;
6771         case TYPE_CHAR:
6772         case TYPE_UCHAR:
6773         case TYPE_SHORT:
6774         case TYPE_USHORT:
6775         case TYPE_INT:
6776         case TYPE_UINT:
6777         case TYPE_LONG:
6778         case TYPE_ULONG:
6779                 cb(state, type, reg_offset, mem_offset, arg);
6780                 break;
6781         case TYPE_VOID:
6782                 break;
6783         default:
6784                 internal_error(state, 0, "walk_type_fields not yet implemented for type");
6785         }
6786 }
6787
6788 static void arrays_complete(struct compile_state *state, struct type *type)
6789 {
6790         if ((type->type & TYPE_MASK) == TYPE_ARRAY) {
6791                 if (type->elements == ELEMENT_COUNT_UNSPECIFIED) {
6792                         error(state, 0, "array size not specified");
6793                 }
6794                 arrays_complete(state, type->left);
6795         }
6796 }
6797
6798 static unsigned int get_basic_type(struct type *type)
6799 {
6800         unsigned int basic;
6801         basic = type->type & TYPE_MASK;
6802         /* Convert enums to ints */
6803         if (basic == TYPE_ENUM) {
6804                 basic = TYPE_INT;
6805         }
6806         /* Convert bitfields to standard types */
6807         else if (basic == TYPE_BITFIELD) {
6808                 if (type->elements <= SIZEOF_CHAR) {
6809                         basic = TYPE_CHAR;
6810                 }
6811                 else if (type->elements <= SIZEOF_SHORT) {
6812                         basic = TYPE_SHORT;
6813                 }
6814                 else if (type->elements <= SIZEOF_INT) {
6815                         basic = TYPE_INT;
6816                 }
6817                 else if (type->elements <= SIZEOF_LONG) {
6818                         basic = TYPE_LONG;
6819                 }
6820                 if (!TYPE_SIGNED(type->left->type)) {
6821                         basic += 1;
6822                 }
6823         }
6824         return basic;
6825 }
6826
6827 static unsigned int do_integral_promotion(unsigned int type)
6828 {
6829         if (TYPE_INTEGER(type) && (TYPE_RANK(type) < TYPE_RANK(TYPE_INT))) {
6830                 type = TYPE_INT;
6831         }
6832         return type;
6833 }
6834
6835 static unsigned int do_arithmetic_conversion(
6836         unsigned int left, unsigned int right)
6837 {
6838         if ((left == TYPE_LDOUBLE) || (right == TYPE_LDOUBLE)) {
6839                 return TYPE_LDOUBLE;
6840         }
6841         else if ((left == TYPE_DOUBLE) || (right == TYPE_DOUBLE)) {
6842                 return TYPE_DOUBLE;
6843         }
6844         else if ((left == TYPE_FLOAT) || (right == TYPE_FLOAT)) {
6845                 return TYPE_FLOAT;
6846         }
6847         left = do_integral_promotion(left);
6848         right = do_integral_promotion(right);
6849         /* If both operands have the same size done */
6850         if (left == right) {
6851                 return left;
6852         }
6853         /* If both operands have the same signedness pick the larger */
6854         else if (!!TYPE_UNSIGNED(left) == !!TYPE_UNSIGNED(right)) {
6855                 return (TYPE_RANK(left) >= TYPE_RANK(right)) ? left : right;
6856         }
6857         /* If the signed type can hold everything use it */
6858         else if (TYPE_SIGNED(left) && (TYPE_RANK(left) > TYPE_RANK(right))) {
6859                 return left;
6860         }
6861         else if (TYPE_SIGNED(right) && (TYPE_RANK(right) > TYPE_RANK(left))) {
6862                 return right;
6863         }
6864         /* Convert to the unsigned type with the same rank as the signed type */
6865         else if (TYPE_SIGNED(left)) {
6866                 return TYPE_MKUNSIGNED(left);
6867         }
6868         else {
6869                 return TYPE_MKUNSIGNED(right);
6870         }
6871 }
6872
6873 /* see if two types are the same except for qualifiers */
6874 static int equiv_types(struct type *left, struct type *right)
6875 {
6876         unsigned int type;
6877         /* Error if the basic types do not match */
6878         if ((left->type & TYPE_MASK) != (right->type & TYPE_MASK)) {
6879                 return 0;
6880         }
6881         type = left->type & TYPE_MASK;
6882         /* If the basic types match and it is a void type we are done */
6883         if (type == TYPE_VOID) {
6884                 return 1;
6885         }
6886         /* For bitfields we need to compare the sizes */
6887         else if (type == TYPE_BITFIELD) {
6888                 return (left->elements == right->elements) &&
6889                         (TYPE_SIGNED(left->left->type) == TYPE_SIGNED(right->left->type));
6890         }
6891         /* if the basic types match and it is an arithmetic type we are done */
6892         else if (TYPE_ARITHMETIC(type)) {
6893                 return 1;
6894         }
6895         /* If it is a pointer type recurse and keep testing */
6896         else if (type == TYPE_POINTER) {
6897                 return equiv_types(left->left, right->left);
6898         }
6899         else if (type == TYPE_ARRAY) {
6900                 return (left->elements == right->elements) &&
6901                         equiv_types(left->left, right->left);
6902         }
6903         /* test for struct equality */
6904         else if (type == TYPE_STRUCT) {
6905                 return left->type_ident == right->type_ident;
6906         }
6907         /* test for union equality */
6908         else if (type == TYPE_UNION) {
6909                 return left->type_ident == right->type_ident;
6910         }
6911         /* Test for equivalent functions */
6912         else if (type == TYPE_FUNCTION) {
6913                 return equiv_types(left->left, right->left) &&
6914                         equiv_types(left->right, right->right);
6915         }
6916         /* We only see TYPE_PRODUCT as part of function equivalence matching */
6917         /* We also see TYPE_PRODUCT as part of of tuple equivalence matchin */
6918         else if (type == TYPE_PRODUCT) {
6919                 return equiv_types(left->left, right->left) &&
6920                         equiv_types(left->right, right->right);
6921         }
6922         /* We should see TYPE_OVERLAP when comparing joins */
6923         else if (type == TYPE_OVERLAP) {
6924                 return equiv_types(left->left, right->left) &&
6925                         equiv_types(left->right, right->right);
6926         }
6927         /* Test for equivalence of tuples */
6928         else if (type == TYPE_TUPLE) {
6929                 return (left->elements == right->elements) &&
6930                         equiv_types(left->left, right->left);
6931         }
6932         /* Test for equivalence of joins */
6933         else if (type == TYPE_JOIN) {
6934                 return (left->elements == right->elements) &&
6935                         equiv_types(left->left, right->left);
6936         }
6937         else {
6938                 return 0;
6939         }
6940 }
6941
6942 static int equiv_ptrs(struct type *left, struct type *right)
6943 {
6944         if (((left->type & TYPE_MASK) != TYPE_POINTER) ||
6945                 ((right->type & TYPE_MASK) != TYPE_POINTER)) {
6946                 return 0;
6947         }
6948         return equiv_types(left->left, right->left);
6949 }
6950
6951 static struct type *compatible_types(struct type *left, struct type *right)
6952 {
6953         struct type *result;
6954         unsigned int type, qual_type;
6955         /* Error if the basic types do not match */
6956         if ((left->type & TYPE_MASK) != (right->type & TYPE_MASK)) {
6957                 return 0;
6958         }
6959         type = left->type & TYPE_MASK;
6960         qual_type = (left->type & ~STOR_MASK) | (right->type & ~STOR_MASK);
6961         result = 0;
6962         /* if the basic types match and it is an arithmetic type we are done */
6963         if (TYPE_ARITHMETIC(type)) {
6964                 result = new_type(qual_type, 0, 0);
6965         }
6966         /* If it is a pointer type recurse and keep testing */
6967         else if (type == TYPE_POINTER) {
6968                 result = compatible_types(left->left, right->left);
6969                 if (result) {
6970                         result = new_type(qual_type, result, 0);
6971                 }
6972         }
6973         /* test for struct equality */
6974         else if (type == TYPE_STRUCT) {
6975                 if (left->type_ident == right->type_ident) {
6976                         result = left;
6977                 }
6978         }
6979         /* test for union equality */
6980         else if (type == TYPE_UNION) {
6981                 if (left->type_ident == right->type_ident) {
6982                         result = left;
6983                 }
6984         }
6985         /* Test for equivalent functions */
6986         else if (type == TYPE_FUNCTION) {
6987                 struct type *lf, *rf;
6988                 lf = compatible_types(left->left, right->left);
6989                 rf = compatible_types(left->right, right->right);
6990                 if (lf && rf) {
6991                         result = new_type(qual_type, lf, rf);
6992                 }
6993         }
6994         /* We only see TYPE_PRODUCT as part of function equivalence matching */
6995         else if (type == TYPE_PRODUCT) {
6996                 struct type *lf, *rf;
6997                 lf = compatible_types(left->left, right->left);
6998                 rf = compatible_types(left->right, right->right);
6999                 if (lf && rf) {
7000                         result = new_type(qual_type, lf, rf);
7001                 }
7002         }
7003         else {
7004                 /* Nothing else is compatible */
7005         }
7006         return result;
7007 }
7008
7009 /* See if left is a equivalent to right or right is a union member of left */
7010 static int is_subset_type(struct type *left, struct type *right)
7011 {
7012         if (equiv_types(left, right)) {
7013                 return 1;
7014         }
7015         if ((left->type & TYPE_MASK) == TYPE_JOIN) {
7016                 struct type *member, *mnext;
7017                 mnext = left->left;
7018                 while(mnext) {
7019                         member = mnext;
7020                         mnext = 0;
7021                         if ((member->type & TYPE_MASK) == TYPE_OVERLAP) {
7022                                 mnext = member->right;
7023                                 member = member->left;
7024                         }
7025                         if (is_subset_type( member, right)) {
7026                                 return 1;
7027                         }
7028                 }
7029         }
7030         return 0;
7031 }
7032
7033 static struct type *compatible_ptrs(struct type *left, struct type *right)
7034 {
7035         struct type *result;
7036         if (((left->type & TYPE_MASK) != TYPE_POINTER) ||
7037                 ((right->type & TYPE_MASK) != TYPE_POINTER)) {
7038                 return 0;
7039         }
7040         result = compatible_types(left->left, right->left);
7041         if (result) {
7042                 unsigned int qual_type;
7043                 qual_type = (left->type & ~STOR_MASK) | (right->type & ~STOR_MASK);
7044                 result = new_type(qual_type, result, 0);
7045         }
7046         return result;
7047         
7048 }
7049 static struct triple *integral_promotion(
7050         struct compile_state *state, struct triple *def)
7051 {
7052         struct type *type;
7053         type = def->type;
7054         /* As all operations are carried out in registers
7055          * the values are converted on load I just convert
7056          * logical type of the operand.
7057          */
7058         if (TYPE_INTEGER(type->type)) {
7059                 unsigned int int_type;
7060                 int_type = type->type & ~TYPE_MASK;
7061                 int_type |= do_integral_promotion(get_basic_type(type));
7062                 if (int_type != type->type) {
7063                         if (def->op != OP_LOAD) {
7064                                 def->type = new_type(int_type, 0, 0);
7065                         }
7066                         else {
7067                                 def = triple(state, OP_CONVERT, 
7068                                         new_type(int_type, 0, 0), def, 0);
7069                         }
7070                 }
7071         }
7072         return def;
7073 }
7074
7075
7076 static void arithmetic(struct compile_state *state, struct triple *def)
7077 {
7078         if (!TYPE_ARITHMETIC(def->type->type)) {
7079                 error(state, 0, "arithmetic type expexted");
7080         }
7081 }
7082
7083 static void ptr_arithmetic(struct compile_state *state, struct triple *def)
7084 {
7085         if (!TYPE_PTR(def->type->type) && !TYPE_ARITHMETIC(def->type->type)) {
7086                 error(state, def, "pointer or arithmetic type expected");
7087         }
7088 }
7089
7090 static int is_integral(struct triple *ins)
7091 {
7092         return TYPE_INTEGER(ins->type->type);
7093 }
7094
7095 static void integral(struct compile_state *state, struct triple *def)
7096 {
7097         if (!is_integral(def)) {
7098                 error(state, 0, "integral type expected");
7099         }
7100 }
7101
7102
7103 static void bool(struct compile_state *state, struct triple *def)
7104 {
7105         if (!TYPE_ARITHMETIC(def->type->type) &&
7106                 ((def->type->type & TYPE_MASK) != TYPE_POINTER)) {
7107                 error(state, 0, "arithmetic or pointer type expected");
7108         }
7109 }
7110
7111 static int is_signed(struct type *type)
7112 {
7113         if ((type->type & TYPE_MASK) == TYPE_BITFIELD) {
7114                 type = type->left;
7115         }
7116         return !!TYPE_SIGNED(type->type);
7117 }
7118 static int is_compound_type(struct type *type)
7119 {
7120         int is_compound;
7121         switch((type->type & TYPE_MASK)) {
7122         case TYPE_ARRAY:
7123         case TYPE_STRUCT:
7124         case TYPE_TUPLE:
7125         case TYPE_UNION:
7126         case TYPE_JOIN: 
7127                 is_compound = 1;
7128                 break;
7129         default:
7130                 is_compound = 0;
7131                 break;
7132         }
7133         return is_compound;
7134 }
7135
7136 /* Is this value located in a register otherwise it must be in memory */
7137 static int is_in_reg(struct compile_state *state, struct triple *def)
7138 {
7139         int in_reg;
7140         if (def->op == OP_ADECL) {
7141                 in_reg = 1;
7142         }
7143         else if ((def->op == OP_SDECL) || (def->op == OP_DEREF)) {
7144                 in_reg = 0;
7145         }
7146         else if (triple_is_part(state, def)) {
7147                 in_reg = is_in_reg(state, MISC(def, 0));
7148         }
7149         else {
7150                 internal_error(state, def, "unknown expr storage location");
7151                 in_reg = -1;
7152         }
7153         return in_reg;
7154 }
7155
7156 /* Is this an auto or static variable location? Something that can
7157  * be assigned to.  Otherwise it must must be a pure value, a temporary.
7158  */
7159 static int is_lvalue(struct compile_state *state, struct triple *def)
7160 {
7161         int ret;
7162         ret = 0;
7163         if (!def) {
7164                 return 0;
7165         }
7166         if ((def->op == OP_ADECL) || 
7167                 (def->op == OP_SDECL) || 
7168                 (def->op == OP_DEREF) ||
7169                 (def->op == OP_BLOBCONST) ||
7170                 (def->op == OP_LIST)) {
7171                 ret = 1;
7172         }
7173         else if (triple_is_part(state, def)) {
7174                 ret = is_lvalue(state, MISC(def, 0));
7175         }
7176         return ret;
7177 }
7178
7179 static void clvalue(struct compile_state *state, struct triple *def)
7180 {
7181         if (!def) {
7182                 internal_error(state, def, "nothing where lvalue expected?");
7183         }
7184         if (!is_lvalue(state, def)) { 
7185                 error(state, def, "lvalue expected");
7186         }
7187 }
7188 static void lvalue(struct compile_state *state, struct triple *def)
7189 {
7190         clvalue(state, def);
7191         if (def->type->type & QUAL_CONST) {
7192                 error(state, def, "modifable lvalue expected");
7193         }
7194 }
7195
7196 static int is_pointer(struct triple *def)
7197 {
7198         return (def->type->type & TYPE_MASK) == TYPE_POINTER;
7199 }
7200
7201 static void pointer(struct compile_state *state, struct triple *def)
7202 {
7203         if (!is_pointer(def)) {
7204                 error(state, def, "pointer expected");
7205         }
7206 }
7207
7208 static struct triple *int_const(
7209         struct compile_state *state, struct type *type, ulong_t value)
7210 {
7211         struct triple *result;
7212         switch(type->type & TYPE_MASK) {
7213         case TYPE_CHAR:
7214         case TYPE_INT:   case TYPE_UINT:
7215         case TYPE_LONG:  case TYPE_ULONG:
7216                 break;
7217         default:
7218                 internal_error(state, 0, "constant for unknown type");
7219         }
7220         result = triple(state, OP_INTCONST, type, 0, 0);
7221         result->u.cval = value;
7222         return result;
7223 }
7224
7225
7226 static struct triple *read_expr(struct compile_state *state, struct triple *def);
7227
7228 static struct triple *do_mk_addr_expr(struct compile_state *state, 
7229         struct triple *expr, struct type *type, ulong_t offset)
7230 {
7231         struct triple *result;
7232         struct type *ptr_type;
7233         clvalue(state, expr);
7234
7235         ptr_type = new_type(TYPE_POINTER | (type->type & QUAL_MASK), type, 0);
7236
7237         
7238         result = 0;
7239         if (expr->op == OP_ADECL) {
7240                 error(state, expr, "address of auto variables not supported");
7241         }
7242         else if (expr->op == OP_SDECL) {
7243                 result = triple(state, OP_ADDRCONST, ptr_type, 0, 0);
7244                 MISC(result, 0) = expr;
7245                 result->u.cval = offset;
7246         }
7247         else if (expr->op == OP_DEREF) {
7248                 result = triple(state, OP_ADD, ptr_type,
7249                         RHS(expr, 0),
7250                         int_const(state, &ulong_type, offset));
7251         }
7252         else if (expr->op == OP_BLOBCONST) {
7253                 FINISHME();
7254                 internal_error(state, expr, "not yet implemented");
7255         }
7256         else if (expr->op == OP_LIST) {
7257                 error(state, 0, "Function addresses not supported");
7258         }
7259         else if (triple_is_part(state, expr)) {
7260                 struct triple *part;
7261                 part = expr;
7262                 expr = MISC(expr, 0);
7263                 if (part->op == OP_DOT) {
7264                         offset += bits_to_bytes(
7265                                 field_offset(state, expr->type, part->u.field));
7266                 }
7267                 else if (part->op == OP_INDEX) {
7268                         offset += bits_to_bytes(
7269                                 index_offset(state, expr->type, part->u.cval));
7270                 }
7271                 else {
7272                         internal_error(state, part, "unhandled part type");
7273                 }
7274                 result = do_mk_addr_expr(state, expr, type, offset);
7275         }
7276         if (!result) {
7277                 internal_error(state, expr, "cannot take address of expression");
7278         }
7279         return result;
7280 }
7281
7282 static struct triple *mk_addr_expr(
7283         struct compile_state *state, struct triple *expr, ulong_t offset)
7284 {
7285         return do_mk_addr_expr(state, expr, expr->type, offset);
7286 }
7287
7288 static struct triple *mk_deref_expr(
7289         struct compile_state *state, struct triple *expr)
7290 {
7291         struct type *base_type;
7292         pointer(state, expr);
7293         base_type = expr->type->left;
7294         return triple(state, OP_DEREF, base_type, expr, 0);
7295 }
7296
7297 /* lvalue conversions always apply except when certain operators
7298  * are applied.  So I apply apply it when I know no more
7299  * operators will be applied.
7300  */
7301 static struct triple *lvalue_conversion(struct compile_state *state, struct triple *def)
7302 {
7303         /* Tranform an array to a pointer to the first element */
7304         if ((def->type->type & TYPE_MASK) == TYPE_ARRAY) {
7305                 struct type *type;
7306                 type = new_type(
7307                         TYPE_POINTER | (def->type->type & QUAL_MASK),
7308                         def->type->left, 0);
7309                 if ((def->op == OP_SDECL) || IS_CONST_OP(def->op)) {
7310                         struct triple *addrconst;
7311                         if ((def->op != OP_SDECL) && (def->op != OP_BLOBCONST)) {
7312                                 internal_error(state, def, "bad array constant");
7313                         }
7314                         addrconst = triple(state, OP_ADDRCONST, type, 0, 0);
7315                         MISC(addrconst, 0) = def;
7316                         def = addrconst;
7317                 }
7318                 else {
7319                         def = triple(state, OP_CONVERT, type, def, 0);
7320                 }
7321         }
7322         /* Transform a function to a pointer to it */
7323         else if ((def->type->type & TYPE_MASK) == TYPE_FUNCTION) {
7324                 def = mk_addr_expr(state, def, 0);
7325         }
7326         return def;
7327 }
7328
7329 static struct triple *deref_field(
7330         struct compile_state *state, struct triple *expr, struct hash_entry *field)
7331 {
7332         struct triple *result;
7333         struct type *type, *member;
7334         ulong_t offset;
7335         if (!field) {
7336                 internal_error(state, 0, "No field passed to deref_field");
7337         }
7338         result = 0;
7339         type = expr->type;
7340         if (((type->type & TYPE_MASK) != TYPE_STRUCT) &&
7341                 ((type->type & TYPE_MASK) != TYPE_UNION)) {
7342                 error(state, 0, "request for member %s in something not a struct or union",
7343                         field->name);
7344         }
7345         member = field_type(state, type, field);
7346         if ((type->type & STOR_MASK) == STOR_PERM) {
7347                 /* Do the pointer arithmetic to get a deref the field */
7348                 offset = bits_to_bytes(field_offset(state, type, field));
7349                 result = do_mk_addr_expr(state, expr, member, offset);
7350                 result = mk_deref_expr(state, result);
7351         }
7352         else {
7353                 /* Find the variable for the field I want. */
7354                 result = triple(state, OP_DOT, member, expr, 0);
7355                 result->u.field = field;
7356         }
7357         return result;
7358 }
7359
7360 static struct triple *deref_index(
7361         struct compile_state *state, struct triple *expr, size_t index)
7362 {
7363         struct triple *result;
7364         struct type *type, *member;
7365         ulong_t offset;
7366
7367         result = 0;
7368         type = expr->type;
7369         member = index_type(state, type, index);
7370
7371         if ((type->type & STOR_MASK) == STOR_PERM) {
7372                 offset = bits_to_bytes(index_offset(state, type, index));
7373                 result = do_mk_addr_expr(state, expr, member, offset);
7374                 result = mk_deref_expr(state, result);
7375         }
7376         else {
7377                 result = triple(state, OP_INDEX, member, expr, 0);
7378                 result->u.cval = index;
7379         }
7380         return result;
7381 }
7382
7383 static struct triple *read_expr(struct compile_state *state, struct triple *def)
7384 {
7385         int op;
7386         if  (!def) {
7387                 return 0;
7388         }
7389 #warning "CHECK_ME is this the only place I need to do lvalue conversions?"
7390         /* Transform lvalues into something we can read */
7391         def = lvalue_conversion(state, def);
7392         if (!is_lvalue(state, def)) {
7393                 return def;
7394         }
7395         if (is_in_reg(state, def)) {
7396                 op = OP_READ;
7397         } else {
7398                 if (def->op == OP_SDECL) {
7399                         def = mk_addr_expr(state, def, 0);
7400                         def = mk_deref_expr(state, def);
7401                 }
7402                 op = OP_LOAD;
7403         }
7404         def = triple(state, op, def->type, def, 0);
7405         if (def->type->type & QUAL_VOLATILE) {
7406                 def->id |= TRIPLE_FLAG_VOLATILE;
7407         }
7408         return def;
7409 }
7410
7411 int is_write_compatible(struct compile_state *state, 
7412         struct type *dest, struct type *rval)
7413 {
7414         int compatible = 0;
7415         /* Both operands have arithmetic type */
7416         if (TYPE_ARITHMETIC(dest->type) && TYPE_ARITHMETIC(rval->type)) {
7417                 compatible = 1;
7418         }
7419         /* One operand is a pointer and the other is a pointer to void */
7420         else if (((dest->type & TYPE_MASK) == TYPE_POINTER) &&
7421                 ((rval->type & TYPE_MASK) == TYPE_POINTER) &&
7422                 (((dest->left->type & TYPE_MASK) == TYPE_VOID) ||
7423                         ((rval->left->type & TYPE_MASK) == TYPE_VOID))) {
7424                 compatible = 1;
7425         }
7426         /* If both types are the same without qualifiers we are good */
7427         else if (equiv_ptrs(dest, rval)) {
7428                 compatible = 1;
7429         }
7430         /* test for struct/union equality  */
7431         else if (equiv_types(dest, rval)) {
7432                 compatible = 1;
7433         }
7434         return compatible;
7435 }
7436
7437 static void write_compatible(struct compile_state *state,
7438         struct type *dest, struct type *rval)
7439 {
7440         if (!is_write_compatible(state, dest, rval)) {
7441                 FILE *fp = state->errout;
7442                 fprintf(fp, "dest: ");
7443                 name_of(fp, dest);
7444                 fprintf(fp,"\nrval: ");
7445                 name_of(fp, rval);
7446                 fprintf(fp, "\n");
7447                 error(state, 0, "Incompatible types in assignment");
7448         }
7449 }
7450
7451 static int is_init_compatible(struct compile_state *state,
7452         struct type *dest, struct type *rval)
7453 {
7454         int compatible = 0;
7455         if (is_write_compatible(state, dest, rval)) {
7456                 compatible = 1;
7457         }
7458         else if (equiv_types(dest, rval)) {
7459                 compatible = 1;
7460         }
7461         return compatible;
7462 }
7463
7464 static struct triple *write_expr(
7465         struct compile_state *state, struct triple *dest, struct triple *rval)
7466 {
7467         struct triple *def;
7468         int op;
7469
7470         def = 0;
7471         if (!rval) {
7472                 internal_error(state, 0, "missing rval");
7473         }
7474
7475         if (rval->op == OP_LIST) {
7476                 internal_error(state, 0, "expression of type OP_LIST?");
7477         }
7478         if (!is_lvalue(state, dest)) {
7479                 internal_error(state, 0, "writing to a non lvalue?");
7480         }
7481         if (dest->type->type & QUAL_CONST) {
7482                 internal_error(state, 0, "modifable lvalue expexted");
7483         }
7484
7485         write_compatible(state, dest->type, rval->type);
7486         if (!equiv_types(dest->type, rval->type)) {
7487                 rval = triple(state, OP_CONVERT, dest->type, rval, 0);
7488         }
7489
7490         /* Now figure out which assignment operator to use */
7491         op = -1;
7492         if (is_in_reg(state, dest)) {
7493                 def = triple(state, OP_WRITE, dest->type, rval, dest);
7494                 if (MISC(def, 0) != dest) {
7495                         internal_error(state, def, "huh?");
7496                 }
7497                 if (RHS(def, 0) != rval) {
7498                         internal_error(state, def, "huh?");
7499                 }
7500         } else {
7501                 def = triple(state, OP_STORE, dest->type, dest, rval);
7502         }
7503         if (def->type->type & QUAL_VOLATILE) {
7504                 def->id |= TRIPLE_FLAG_VOLATILE;
7505         }
7506         return def;
7507 }
7508
7509 static struct triple *init_expr(
7510         struct compile_state *state, struct triple *dest, struct triple *rval)
7511 {
7512         struct triple *def;
7513
7514         def = 0;
7515         if (!rval) {
7516                 internal_error(state, 0, "missing rval");
7517         }
7518         if ((dest->type->type & STOR_MASK) != STOR_PERM) {
7519                 rval = read_expr(state, rval);
7520                 def = write_expr(state, dest, rval);
7521         }
7522         else {
7523                 /* Fill in the array size if necessary */
7524                 if (((dest->type->type & TYPE_MASK) == TYPE_ARRAY) &&
7525                         ((rval->type->type & TYPE_MASK) == TYPE_ARRAY)) {
7526                         if (dest->type->elements == ELEMENT_COUNT_UNSPECIFIED) {
7527                                 dest->type->elements = rval->type->elements;
7528                         }
7529                 }
7530                 if (!equiv_types(dest->type, rval->type)) {
7531                         error(state, 0, "Incompatible types in inializer");
7532                 }
7533                 MISC(dest, 0) = rval;
7534                 insert_triple(state, dest, rval);
7535                 rval->id |= TRIPLE_FLAG_FLATTENED;
7536                 use_triple(MISC(dest, 0), dest);
7537         }
7538         return def;
7539 }
7540
7541 struct type *arithmetic_result(
7542         struct compile_state *state, struct triple *left, struct triple *right)
7543 {
7544         struct type *type;
7545         /* Sanity checks to ensure I am working with arithmetic types */
7546         arithmetic(state, left);
7547         arithmetic(state, right);
7548         type = new_type(
7549                 do_arithmetic_conversion(
7550                         get_basic_type(left->type),
7551                         get_basic_type(right->type)),
7552                 0, 0);
7553         return type;
7554 }
7555
7556 struct type *ptr_arithmetic_result(
7557         struct compile_state *state, struct triple *left, struct triple *right)
7558 {
7559         struct type *type;
7560         /* Sanity checks to ensure I am working with the proper types */
7561         ptr_arithmetic(state, left);
7562         arithmetic(state, right);
7563         if (TYPE_ARITHMETIC(left->type->type) && 
7564                 TYPE_ARITHMETIC(right->type->type)) {
7565                 type = arithmetic_result(state, left, right);
7566         }
7567         else if (TYPE_PTR(left->type->type)) {
7568                 type = left->type;
7569         }
7570         else {
7571                 internal_error(state, 0, "huh?");
7572                 type = 0;
7573         }
7574         return type;
7575 }
7576
7577 /* boolean helper function */
7578
7579 static struct triple *ltrue_expr(struct compile_state *state, 
7580         struct triple *expr)
7581 {
7582         switch(expr->op) {
7583         case OP_LTRUE:   case OP_LFALSE:  case OP_EQ:      case OP_NOTEQ:
7584         case OP_SLESS:   case OP_ULESS:   case OP_SMORE:   case OP_UMORE:
7585         case OP_SLESSEQ: case OP_ULESSEQ: case OP_SMOREEQ: case OP_UMOREEQ:
7586                 /* If the expression is already boolean do nothing */
7587                 break;
7588         default:
7589                 expr = triple(state, OP_LTRUE, &int_type, expr, 0);
7590                 break;
7591         }
7592         return expr;
7593 }
7594
7595 static struct triple *lfalse_expr(struct compile_state *state, 
7596         struct triple *expr)
7597 {
7598         return triple(state, OP_LFALSE, &int_type, expr, 0);
7599 }
7600
7601 static struct triple *mkland_expr(
7602         struct compile_state *state,
7603         struct triple *left, struct triple *right)
7604 {
7605         struct triple *def, *val, *var, *jmp, *mid, *end;
7606         struct triple *lstore, *rstore;
7607
7608         /* Generate some intermediate triples */
7609         end = label(state);
7610         var = variable(state, &int_type);
7611         
7612         /* Store the left hand side value */
7613         lstore = write_expr(state, var, left);
7614
7615         /* Jump if the value is false */
7616         jmp =  branch(state, end, 
7617                 lfalse_expr(state, read_expr(state, var)));
7618         mid = label(state);
7619         
7620         /* Store the right hand side value */
7621         rstore = write_expr(state, var, right);
7622
7623         /* An expression for the computed value */
7624         val = read_expr(state, var);
7625
7626         /* Generate the prog for a logical and */
7627         def = mkprog(state, var, lstore, jmp, mid, rstore, end, val, 0);
7628         
7629         return def;
7630 }
7631
7632 static struct triple *mklor_expr(
7633         struct compile_state *state,
7634         struct triple *left, struct triple *right)
7635 {
7636         struct triple *def, *val, *var, *jmp, *mid, *end;
7637
7638         /* Generate some intermediate triples */
7639         end = label(state);
7640         var = variable(state, &int_type);
7641         
7642         /* Store the left hand side value */
7643         left = write_expr(state, var, left);
7644         
7645         /* Jump if the value is true */
7646         jmp = branch(state, end, read_expr(state, var));
7647         mid = label(state);
7648         
7649         /* Store the right hand side value */
7650         right = write_expr(state, var, right);
7651                 
7652         /* An expression for the computed value*/
7653         val = read_expr(state, var);
7654
7655         /* Generate the prog for a logical or */
7656         def = mkprog(state, var, left, jmp, mid, right, end, val, 0);
7657
7658         return def;
7659 }
7660
7661 static struct triple *mkcond_expr(
7662         struct compile_state *state, 
7663         struct triple *test, struct triple *left, struct triple *right)
7664 {
7665         struct triple *def, *val, *var, *jmp1, *jmp2, *top, *mid, *end;
7666         struct type *result_type;
7667         unsigned int left_type, right_type;
7668         bool(state, test);
7669         left_type = left->type->type;
7670         right_type = right->type->type;
7671         result_type = 0;
7672         /* Both operands have arithmetic type */
7673         if (TYPE_ARITHMETIC(left_type) && TYPE_ARITHMETIC(right_type)) {
7674                 result_type = arithmetic_result(state, left, right);
7675         }
7676         /* Both operands have void type */
7677         else if (((left_type & TYPE_MASK) == TYPE_VOID) &&
7678                 ((right_type & TYPE_MASK) == TYPE_VOID)) {
7679                 result_type = &void_type;
7680         }
7681         /* pointers to the same type... */
7682         else if ((result_type = compatible_ptrs(left->type, right->type))) {
7683                 ;
7684         }
7685         /* Both operands are pointers and left is a pointer to void */
7686         else if (((left_type & TYPE_MASK) == TYPE_POINTER) &&
7687                 ((right_type & TYPE_MASK) == TYPE_POINTER) &&
7688                 ((left->type->left->type & TYPE_MASK) == TYPE_VOID)) {
7689                 result_type = right->type;
7690         }
7691         /* Both operands are pointers and right is a pointer to void */
7692         else if (((left_type & TYPE_MASK) == TYPE_POINTER) &&
7693                 ((right_type & TYPE_MASK) == TYPE_POINTER) &&
7694                 ((right->type->left->type & TYPE_MASK) == TYPE_VOID)) {
7695                 result_type = left->type;
7696         }
7697         if (!result_type) {
7698                 error(state, 0, "Incompatible types in conditional expression");
7699         }
7700         /* Generate some intermediate triples */
7701         mid = label(state);
7702         end = label(state);
7703         var = variable(state, result_type);
7704
7705         /* Branch if the test is false */
7706         jmp1 = branch(state, mid, lfalse_expr(state, read_expr(state, test)));
7707         top = label(state);
7708
7709         /* Store the left hand side value */
7710         left = write_expr(state, var, left);
7711
7712         /* Branch to the end */
7713         jmp2 = branch(state, end, 0);
7714
7715         /* Store the right hand side value */
7716         right = write_expr(state, var, right);
7717         
7718         /* An expression for the computed value */
7719         val = read_expr(state, var);
7720
7721         /* Generate the prog for a conditional expression */
7722         def = mkprog(state, var, jmp1, top, left, jmp2, mid, right, end, val, 0);
7723
7724         return def;
7725 }
7726
7727
7728 static int expr_depth(struct compile_state *state, struct triple *ins)
7729 {
7730 #warning "FIXME move optimal ordering of subexpressions into the optimizer"
7731         int count;
7732         count = 0;
7733         if (!ins || (ins->id & TRIPLE_FLAG_FLATTENED)) {
7734                 count = 0;
7735         }
7736         else if (ins->op == OP_DEREF) {
7737                 count = expr_depth(state, RHS(ins, 0)) - 1;
7738         }
7739         else if (ins->op == OP_VAL) {
7740                 count = expr_depth(state, RHS(ins, 0)) - 1;
7741         }
7742         else if (ins->op == OP_FCALL) {
7743                 /* Don't figure the depth of a call just guess it is huge */
7744                 count = 1000;
7745         }
7746         else {
7747                 struct triple **expr;
7748                 expr = triple_rhs(state, ins, 0);
7749                 for(;expr; expr = triple_rhs(state, ins, expr)) {
7750                         if (*expr) {
7751                                 int depth;
7752                                 depth = expr_depth(state, *expr);
7753                                 if (depth > count) {
7754                                         count = depth;
7755                                 }
7756                         }
7757                 }
7758         }
7759         return count + 1;
7760 }
7761
7762 static struct triple *flatten_generic(
7763         struct compile_state *state, struct triple *first, struct triple *ptr,
7764         int ignored)
7765 {
7766         struct rhs_vector {
7767                 int depth;
7768                 struct triple **ins;
7769         } vector[MAX_RHS];
7770         int i, rhs, lhs;
7771         /* Only operations with just a rhs and a lhs should come here */
7772         rhs = ptr->rhs;
7773         lhs = ptr->lhs;
7774         if (TRIPLE_SIZE(ptr) != lhs + rhs + ignored) {
7775                 internal_error(state, ptr, "unexpected args for: %d %s",
7776                         ptr->op, tops(ptr->op));
7777         }
7778         /* Find the depth of the rhs elements */
7779         for(i = 0; i < rhs; i++) {
7780                 vector[i].ins = &RHS(ptr, i);
7781                 vector[i].depth = expr_depth(state, *vector[i].ins);
7782         }
7783         /* Selection sort the rhs */
7784         for(i = 0; i < rhs; i++) {
7785                 int j, max = i;
7786                 for(j = i + 1; j < rhs; j++ ) {
7787                         if (vector[j].depth > vector[max].depth) {
7788                                 max = j;
7789                         }
7790                 }
7791                 if (max != i) {
7792                         struct rhs_vector tmp;
7793                         tmp = vector[i];
7794                         vector[i] = vector[max];
7795                         vector[max] = tmp;
7796                 }
7797         }
7798         /* Now flatten the rhs elements */
7799         for(i = 0; i < rhs; i++) {
7800                 *vector[i].ins = flatten(state, first, *vector[i].ins);
7801                 use_triple(*vector[i].ins, ptr);
7802         }
7803         if (lhs) {
7804                 insert_triple(state, first, ptr);
7805                 ptr->id |= TRIPLE_FLAG_FLATTENED;
7806                 ptr->id &= ~TRIPLE_FLAG_LOCAL;
7807                 
7808                 /* Now flatten the lhs elements */
7809                 for(i = 0; i < lhs; i++) {
7810                         struct triple **ins = &LHS(ptr, i);
7811                         *ins = flatten(state, first, *ins);
7812                         use_triple(*ins, ptr);
7813                 }
7814         }
7815         return ptr;
7816 }
7817
7818 static struct triple *flatten_prog(
7819         struct compile_state *state, struct triple *first, struct triple *ptr)
7820 {
7821         struct triple *head, *body, *val;
7822         head = RHS(ptr, 0);
7823         RHS(ptr, 0) = 0;
7824         val  = head->prev;
7825         body = head->next;
7826         release_triple(state, head);
7827         release_triple(state, ptr);
7828         val->next        = first;
7829         body->prev       = first->prev;
7830         body->prev->next = body;
7831         val->next->prev  = val;
7832
7833         if (triple_is_cbranch(state, body->prev) ||
7834                 triple_is_call(state, body->prev)) {
7835                 unuse_triple(first, body->prev);
7836                 use_triple(body, body->prev);
7837         }
7838         
7839         if (!(val->id & TRIPLE_FLAG_FLATTENED)) {
7840                 internal_error(state, val, "val not flattened?");
7841         }
7842
7843         return val;
7844 }
7845
7846
7847 static struct triple *flatten_part(
7848         struct compile_state *state, struct triple *first, struct triple *ptr)
7849 {
7850         if (!triple_is_part(state, ptr)) {
7851                 internal_error(state, ptr,  "not a part");
7852         }
7853         if (ptr->rhs || ptr->lhs || ptr->targ || (ptr->misc != 1)) {
7854                 internal_error(state, ptr, "unexpected args for: %d %s",
7855                         ptr->op, tops(ptr->op));
7856         }
7857         MISC(ptr, 0) = flatten(state, first, MISC(ptr, 0));
7858         use_triple(MISC(ptr, 0), ptr);
7859         return flatten_generic(state, first, ptr, 1);
7860 }
7861
7862 static struct triple *flatten(
7863         struct compile_state *state, struct triple *first, struct triple *ptr)
7864 {
7865         struct triple *orig_ptr;
7866         if (!ptr)
7867                 return 0;
7868         do {
7869                 orig_ptr = ptr;
7870                 /* Only flatten triples once */
7871                 if (ptr->id & TRIPLE_FLAG_FLATTENED) {
7872                         return ptr;
7873                 }
7874                 switch(ptr->op) {
7875                 case OP_VAL:
7876                         RHS(ptr, 0) = flatten(state, first, RHS(ptr, 0));
7877                         return MISC(ptr, 0);
7878                         break;
7879                 case OP_PROG:
7880                         ptr = flatten_prog(state, first, ptr);
7881                         break;
7882                 case OP_FCALL:
7883                         ptr = flatten_generic(state, first, ptr, 1);
7884                         insert_triple(state, first, ptr);
7885                         ptr->id |= TRIPLE_FLAG_FLATTENED;
7886                         ptr->id &= ~TRIPLE_FLAG_LOCAL;
7887                         if (ptr->next != ptr) {
7888                                 use_triple(ptr->next, ptr);
7889                         }
7890                         break;
7891                 case OP_READ:
7892                 case OP_LOAD:
7893                         RHS(ptr, 0) = flatten(state, first, RHS(ptr, 0));
7894                         use_triple(RHS(ptr, 0), ptr);
7895                         break;
7896                 case OP_WRITE:
7897                         ptr = flatten_generic(state, first, ptr, 1);
7898                         MISC(ptr, 0) = flatten(state, first, MISC(ptr, 0));
7899                         use_triple(MISC(ptr, 0), ptr);
7900                         break;
7901                 case OP_BRANCH:
7902                         use_triple(TARG(ptr, 0), ptr);
7903                         break;
7904                 case OP_CBRANCH:
7905                         RHS(ptr, 0) = flatten(state, first, RHS(ptr, 0));
7906                         use_triple(RHS(ptr, 0), ptr);
7907                         use_triple(TARG(ptr, 0), ptr);
7908                         insert_triple(state, first, ptr);
7909                         ptr->id |= TRIPLE_FLAG_FLATTENED;
7910                         ptr->id &= ~TRIPLE_FLAG_LOCAL;
7911                         if (ptr->next != ptr) {
7912                                 use_triple(ptr->next, ptr);
7913                         }
7914                         break;
7915                 case OP_CALL:
7916                         MISC(ptr, 0) = flatten(state, first, MISC(ptr, 0));
7917                         use_triple(MISC(ptr, 0), ptr);
7918                         use_triple(TARG(ptr, 0), ptr);
7919                         insert_triple(state, first, ptr);
7920                         ptr->id |= TRIPLE_FLAG_FLATTENED;
7921                         ptr->id &= ~TRIPLE_FLAG_LOCAL;
7922                         if (ptr->next != ptr) {
7923                                 use_triple(ptr->next, ptr);
7924                         }
7925                         break;
7926                 case OP_RET:
7927                         RHS(ptr, 0) = flatten(state, first, RHS(ptr, 0));
7928                         use_triple(RHS(ptr, 0), ptr);
7929                         break;
7930                 case OP_BLOBCONST:
7931                         insert_triple(state, state->global_pool, ptr);
7932                         ptr->id |= TRIPLE_FLAG_FLATTENED;
7933                         ptr->id &= ~TRIPLE_FLAG_LOCAL;
7934                         ptr = triple(state, OP_SDECL, ptr->type, ptr, 0);
7935                         use_triple(MISC(ptr, 0), ptr);
7936                         break;
7937                 case OP_DEREF:
7938                         /* Since OP_DEREF is just a marker delete it when I flatten it */
7939                         ptr = RHS(ptr, 0);
7940                         RHS(orig_ptr, 0) = 0;
7941                         free_triple(state, orig_ptr);
7942                         break;
7943                 case OP_DOT:
7944                         if (RHS(ptr, 0)->op == OP_DEREF) {
7945                                 struct triple *base, *left;
7946                                 ulong_t offset;
7947                                 base = MISC(ptr, 0);
7948                                 offset = bits_to_bytes(field_offset(state, base->type, ptr->u.field));
7949                                 left = RHS(base, 0);
7950                                 ptr = triple(state, OP_ADD, left->type, 
7951                                         read_expr(state, left),
7952                                         int_const(state, &ulong_type, offset));
7953                                 free_triple(state, base);
7954                         }
7955                         else {
7956                                 ptr = flatten_part(state, first, ptr);
7957                         }
7958                         break;
7959                 case OP_INDEX:
7960                         if (RHS(ptr, 0)->op == OP_DEREF) {
7961                                 struct triple *base, *left;
7962                                 ulong_t offset;
7963                                 base = MISC(ptr, 0);
7964                                 offset = bits_to_bytes(index_offset(state, base->type, ptr->u.cval));
7965                                 left = RHS(base, 0);
7966                                 ptr = triple(state, OP_ADD, left->type,
7967                                         read_expr(state, left),
7968                                         int_const(state, &long_type, offset));
7969                                 free_triple(state, base);
7970                         }
7971                         else {
7972                                 ptr = flatten_part(state, first, ptr);
7973                         }
7974                         break;
7975                 case OP_PIECE:
7976                         ptr = flatten_part(state, first, ptr);
7977                         use_triple(ptr, MISC(ptr, 0));
7978                         break;
7979                 case OP_ADDRCONST:
7980                         MISC(ptr, 0) = flatten(state, first, MISC(ptr, 0));
7981                         use_triple(MISC(ptr, 0), ptr);
7982                         break;
7983                 case OP_SDECL:
7984                         first = state->global_pool;
7985                         MISC(ptr, 0) = flatten(state, first, MISC(ptr, 0));
7986                         use_triple(MISC(ptr, 0), ptr);
7987                         insert_triple(state, first, ptr);
7988                         ptr->id |= TRIPLE_FLAG_FLATTENED;
7989                         ptr->id &= ~TRIPLE_FLAG_LOCAL;
7990                         return ptr;
7991                 case OP_ADECL:
7992                         ptr = flatten_generic(state, first, ptr, 0);
7993                         break;
7994                 default:
7995                         /* Flatten the easy cases we don't override */
7996                         ptr = flatten_generic(state, first, ptr, 0);
7997                         break;
7998                 }
7999         } while(ptr && (ptr != orig_ptr));
8000         if (ptr && !(ptr->id & TRIPLE_FLAG_FLATTENED)) {
8001                 insert_triple(state, first, ptr);
8002                 ptr->id |= TRIPLE_FLAG_FLATTENED;
8003                 ptr->id &= ~TRIPLE_FLAG_LOCAL;
8004         }
8005         return ptr;
8006 }
8007
8008 static void release_expr(struct compile_state *state, struct triple *expr)
8009 {
8010         struct triple *head;
8011         head = label(state);
8012         flatten(state, head, expr);
8013         while(head->next != head) {
8014                 release_triple(state, head->next);
8015         }
8016         free_triple(state, head);
8017 }
8018
8019 static int replace_rhs_use(struct compile_state *state,
8020         struct triple *orig, struct triple *new, struct triple *use)
8021 {
8022         struct triple **expr;
8023         int found;
8024         found = 0;
8025         expr = triple_rhs(state, use, 0);
8026         for(;expr; expr = triple_rhs(state, use, expr)) {
8027                 if (*expr == orig) {
8028                         *expr = new;
8029                         found = 1;
8030                 }
8031         }
8032         if (found) {
8033                 unuse_triple(orig, use);
8034                 use_triple(new, use);
8035         }
8036         return found;
8037 }
8038
8039 static int replace_lhs_use(struct compile_state *state,
8040         struct triple *orig, struct triple *new, struct triple *use)
8041 {
8042         struct triple **expr;
8043         int found;
8044         found = 0;
8045         expr = triple_lhs(state, use, 0);
8046         for(;expr; expr = triple_lhs(state, use, expr)) {
8047                 if (*expr == orig) {
8048                         *expr = new;
8049                         found = 1;
8050                 }
8051         }
8052         if (found) {
8053                 unuse_triple(orig, use);
8054                 use_triple(new, use);
8055         }
8056         return found;
8057 }
8058
8059 static int replace_misc_use(struct compile_state *state,
8060         struct triple *orig, struct triple *new, struct triple *use)
8061 {
8062         struct triple **expr;
8063         int found;
8064         found = 0;
8065         expr = triple_misc(state, use, 0);
8066         for(;expr; expr = triple_misc(state, use, expr)) {
8067                 if (*expr == orig) {
8068                         *expr = new;
8069                         found = 1;
8070                 }
8071         }
8072         if (found) {
8073                 unuse_triple(orig, use);
8074                 use_triple(new, use);
8075         }
8076         return found;
8077 }
8078
8079 static int replace_targ_use(struct compile_state *state,
8080         struct triple *orig, struct triple *new, struct triple *use)
8081 {
8082         struct triple **expr;
8083         int found;
8084         found = 0;
8085         expr = triple_targ(state, use, 0);
8086         for(;expr; expr = triple_targ(state, use, expr)) {
8087                 if (*expr == orig) {
8088                         *expr = new;
8089                         found = 1;
8090                 }
8091         }
8092         if (found) {
8093                 unuse_triple(orig, use);
8094                 use_triple(new, use);
8095         }
8096         return found;
8097 }
8098
8099 static void replace_use(struct compile_state *state,
8100         struct triple *orig, struct triple *new, struct triple *use)
8101 {
8102         int found;
8103         found = 0;
8104         found |= replace_rhs_use(state, orig, new, use);
8105         found |= replace_lhs_use(state, orig, new, use);
8106         found |= replace_misc_use(state, orig, new, use);
8107         found |= replace_targ_use(state, orig, new, use);
8108         if (!found) {
8109                 internal_error(state, use, "use without use");
8110         }
8111 }
8112
8113 static void propogate_use(struct compile_state *state,
8114         struct triple *orig, struct triple *new)
8115 {
8116         struct triple_set *user, *next;
8117         for(user = orig->use; user; user = next) {
8118                 /* Careful replace_use modifies the use chain and
8119                  * removes use.  So we must get a copy of the next
8120                  * entry early.
8121                  */
8122                 next = user->next;
8123                 replace_use(state, orig, new, user->member);
8124         }
8125         if (orig->use) {
8126                 internal_error(state, orig, "used after propogate_use");
8127         }
8128 }
8129
8130 /*
8131  * Code generators
8132  * ===========================
8133  */
8134
8135 static struct triple *mk_cast_expr(
8136         struct compile_state *state, struct type *type, struct triple *expr)
8137 {
8138         struct triple *def;
8139         def = read_expr(state, expr);
8140         def = triple(state, OP_CONVERT, type, def, 0);
8141         return def;
8142 }
8143
8144 static struct triple *mk_add_expr(
8145         struct compile_state *state, struct triple *left, struct triple *right)
8146 {
8147         struct type *result_type;
8148         /* Put pointer operands on the left */
8149         if (is_pointer(right)) {
8150                 struct triple *tmp;
8151                 tmp = left;
8152                 left = right;
8153                 right = tmp;
8154         }
8155         left  = read_expr(state, left);
8156         right = read_expr(state, right);
8157         result_type = ptr_arithmetic_result(state, left, right);
8158         if (is_pointer(left)) {
8159                 struct type *ptr_math;
8160                 int op;
8161                 if (is_signed(right->type)) {
8162                         ptr_math = &long_type;
8163                         op = OP_SMUL;
8164                 } else {
8165                         ptr_math = &ulong_type;
8166                         op = OP_UMUL;
8167                 }
8168                 if (!equiv_types(right->type, ptr_math)) {
8169                         right = mk_cast_expr(state, ptr_math, right);
8170                 }
8171                 right = triple(state, op, ptr_math, right, 
8172                         int_const(state, ptr_math, 
8173                                 size_of_in_bytes(state, left->type->left)));
8174         }
8175         return triple(state, OP_ADD, result_type, left, right);
8176 }
8177
8178 static struct triple *mk_sub_expr(
8179         struct compile_state *state, struct triple *left, struct triple *right)
8180 {
8181         struct type *result_type;
8182         result_type = ptr_arithmetic_result(state, left, right);
8183         left  = read_expr(state, left);
8184         right = read_expr(state, right);
8185         if (is_pointer(left)) {
8186                 struct type *ptr_math;
8187                 int op;
8188                 if (is_signed(right->type)) {
8189                         ptr_math = &long_type;
8190                         op = OP_SMUL;
8191                 } else {
8192                         ptr_math = &ulong_type;
8193                         op = OP_UMUL;
8194                 }
8195                 if (!equiv_types(right->type, ptr_math)) {
8196                         right = mk_cast_expr(state, ptr_math, right);
8197                 }
8198                 right = triple(state, op, ptr_math, right, 
8199                         int_const(state, ptr_math, 
8200                                 size_of_in_bytes(state, left->type->left)));
8201         }
8202         return triple(state, OP_SUB, result_type, left, right);
8203 }
8204
8205 static struct triple *mk_pre_inc_expr(
8206         struct compile_state *state, struct triple *def)
8207 {
8208         struct triple *val;
8209         lvalue(state, def);
8210         val = mk_add_expr(state, def, int_const(state, &int_type, 1));
8211         return triple(state, OP_VAL, def->type,
8212                 write_expr(state, def, val),
8213                 val);
8214 }
8215
8216 static struct triple *mk_pre_dec_expr(
8217         struct compile_state *state, struct triple *def)
8218 {
8219         struct triple *val;
8220         lvalue(state, def);
8221         val = mk_sub_expr(state, def, int_const(state, &int_type, 1));
8222         return triple(state, OP_VAL, def->type,
8223                 write_expr(state, def, val),
8224                 val);
8225 }
8226
8227 static struct triple *mk_post_inc_expr(
8228         struct compile_state *state, struct triple *def)
8229 {
8230         struct triple *val;
8231         lvalue(state, def);
8232         val = read_expr(state, def);
8233         return triple(state, OP_VAL, def->type,
8234                 write_expr(state, def,
8235                         mk_add_expr(state, val, int_const(state, &int_type, 1)))
8236                 , val);
8237 }
8238
8239 static struct triple *mk_post_dec_expr(
8240         struct compile_state *state, struct triple *def)
8241 {
8242         struct triple *val;
8243         lvalue(state, def);
8244         val = read_expr(state, def);
8245         return triple(state, OP_VAL, def->type, 
8246                 write_expr(state, def,
8247                         mk_sub_expr(state, val, int_const(state, &int_type, 1)))
8248                 , val);
8249 }
8250
8251 static struct triple *mk_subscript_expr(
8252         struct compile_state *state, struct triple *left, struct triple *right)
8253 {
8254         left  = read_expr(state, left);
8255         right = read_expr(state, right);
8256         if (!is_pointer(left) && !is_pointer(right)) {
8257                 error(state, left, "subscripted value is not a pointer");
8258         }
8259         return mk_deref_expr(state, mk_add_expr(state, left, right));
8260 }
8261
8262
8263 /*
8264  * Compile time evaluation
8265  * ===========================
8266  */
8267 static int is_const(struct triple *ins)
8268 {
8269         return IS_CONST_OP(ins->op);
8270 }
8271
8272 static int is_simple_const(struct triple *ins)
8273 {
8274         /* Is this a constant that u.cval has the value.
8275          * Or equivalently is this a constant that read_const
8276          * works on.
8277          * So far only OP_INTCONST qualifies.  
8278          */
8279         return (ins->op == OP_INTCONST);
8280 }
8281
8282 static int constants_equal(struct compile_state *state, 
8283         struct triple *left, struct triple *right)
8284 {
8285         int equal;
8286         if ((left->op == OP_UNKNOWNVAL) || (right->op == OP_UNKNOWNVAL)) {
8287                 equal = 0;
8288         }
8289         else if (!is_const(left) || !is_const(right)) {
8290                 equal = 0;
8291         }
8292         else if (left->op != right->op) {
8293                 equal = 0;
8294         }
8295         else if (!equiv_types(left->type, right->type)) {
8296                 equal = 0;
8297         }
8298         else {
8299                 equal = 0;
8300                 switch(left->op) {
8301                 case OP_INTCONST:
8302                         if (left->u.cval == right->u.cval) {
8303                                 equal = 1;
8304                         }
8305                         break;
8306                 case OP_BLOBCONST:
8307                 {
8308                         size_t lsize, rsize, bytes;
8309                         lsize = size_of(state, left->type);
8310                         rsize = size_of(state, right->type);
8311                         if (lsize != rsize) {
8312                                 break;
8313                         }
8314                         bytes = bits_to_bytes(lsize);
8315                         if (memcmp(left->u.blob, right->u.blob, bytes) == 0) {
8316                                 equal = 1;
8317                         }
8318                         break;
8319                 }
8320                 case OP_ADDRCONST:
8321                         if ((MISC(left, 0) == MISC(right, 0)) &&
8322                                 (left->u.cval == right->u.cval)) {
8323                                 equal = 1;
8324                         }
8325                         break;
8326                 default:
8327                         internal_error(state, left, "uknown constant type");
8328                         break;
8329                 }
8330         }
8331         return equal;
8332 }
8333
8334 static int is_zero(struct triple *ins)
8335 {
8336         return is_simple_const(ins) && (ins->u.cval == 0);
8337 }
8338
8339 static int is_one(struct triple *ins)
8340 {
8341         return is_simple_const(ins) && (ins->u.cval == 1);
8342 }
8343
8344 static long_t bit_count(ulong_t value)
8345 {
8346         int count;
8347         int i;
8348         count = 0;
8349         for(i = (sizeof(ulong_t)*8) -1; i >= 0; i--) {
8350                 ulong_t mask;
8351                 mask = 1;
8352                 mask <<= i;
8353                 if (value & mask) {
8354                         count++;
8355                 }
8356         }
8357         return count;
8358         
8359 }
8360 static long_t bsr(ulong_t value)
8361 {
8362         int i;
8363         for(i = (sizeof(ulong_t)*8) -1; i >= 0; i--) {
8364                 ulong_t mask;
8365                 mask = 1;
8366                 mask <<= i;
8367                 if (value & mask) {
8368                         return i;
8369                 }
8370         }
8371         return -1;
8372 }
8373
8374 static long_t bsf(ulong_t value)
8375 {
8376         int i;
8377         for(i = 0; i < (sizeof(ulong_t)*8); i++) {
8378                 ulong_t mask;
8379                 mask = 1;
8380                 mask <<= 1;
8381                 if (value & mask) {
8382                         return i;
8383                 }
8384         }
8385         return -1;
8386 }
8387
8388 static long_t ilog2(ulong_t value)
8389 {
8390         return bsr(value);
8391 }
8392
8393 static long_t tlog2(struct triple *ins)
8394 {
8395         return ilog2(ins->u.cval);
8396 }
8397
8398 static int is_pow2(struct triple *ins)
8399 {
8400         ulong_t value, mask;
8401         long_t log;
8402         if (!is_const(ins)) {
8403                 return 0;
8404         }
8405         value = ins->u.cval;
8406         log = ilog2(value);
8407         if (log == -1) {
8408                 return 0;
8409         }
8410         mask = 1;
8411         mask <<= log;
8412         return  ((value & mask) == value);
8413 }
8414
8415 static ulong_t read_const(struct compile_state *state,
8416         struct triple *ins, struct triple *rhs)
8417 {
8418         switch(rhs->type->type &TYPE_MASK) {
8419         case TYPE_CHAR:   
8420         case TYPE_SHORT:
8421         case TYPE_INT:
8422         case TYPE_LONG:
8423         case TYPE_UCHAR:   
8424         case TYPE_USHORT:  
8425         case TYPE_UINT:
8426         case TYPE_ULONG:
8427         case TYPE_POINTER:
8428         case TYPE_BITFIELD:
8429                 break;
8430         default:
8431                 fprintf(state->errout, "type: ");
8432                 name_of(state->errout, rhs->type);
8433                 fprintf(state->errout, "\n");
8434                 internal_warning(state, rhs, "bad type to read_const");
8435                 break;
8436         }
8437         if (!is_simple_const(rhs)) {
8438                 internal_error(state, rhs, "bad op to read_const");
8439         }
8440         return rhs->u.cval;
8441 }
8442
8443 static long_t read_sconst(struct compile_state *state,
8444         struct triple *ins, struct triple *rhs)
8445 {
8446         return (long_t)(rhs->u.cval);
8447 }
8448
8449 int const_ltrue(struct compile_state *state, struct triple *ins, struct triple *rhs)
8450 {
8451         if (!is_const(rhs)) {
8452                 internal_error(state, 0, "non const passed to const_true");
8453         }
8454         return !is_zero(rhs);
8455 }
8456
8457 int const_eq(struct compile_state *state, struct triple *ins,
8458         struct triple *left, struct triple *right)
8459 {
8460         int result;
8461         if (!is_const(left) || !is_const(right)) {
8462                 internal_warning(state, ins, "non const passed to const_eq");
8463                 result = -1;
8464         }
8465         else if (left == right) {
8466                 result = 1;
8467         }
8468         else if (is_simple_const(left) && is_simple_const(right)) {
8469                 ulong_t lval, rval;
8470                 lval = read_const(state, ins, left);
8471                 rval = read_const(state, ins, right);
8472                 result = (lval == rval);
8473         }
8474         else if ((left->op == OP_ADDRCONST) && 
8475                 (right->op == OP_ADDRCONST)) {
8476                 result = (MISC(left, 0) == MISC(right, 0)) &&
8477                         (left->u.cval == right->u.cval);
8478         }
8479         else {
8480                 internal_warning(state, ins, "incomparable constants passed to const_eq");
8481                 result = -1;
8482         }
8483         return result;
8484         
8485 }
8486
8487 int const_ucmp(struct compile_state *state, struct triple *ins,
8488         struct triple *left, struct triple *right)
8489 {
8490         int result;
8491         if (!is_const(left) || !is_const(right)) {
8492                 internal_warning(state, ins, "non const past to const_ucmp");
8493                 result = -2;
8494         }
8495         else if (left == right) {
8496                 result = 0;
8497         }
8498         else if (is_simple_const(left) && is_simple_const(right)) {
8499                 ulong_t lval, rval;
8500                 lval = read_const(state, ins, left);
8501                 rval = read_const(state, ins, right);
8502                 result = 0;
8503                 if (lval > rval) {
8504                         result = 1;
8505                 } else if (rval > lval) {
8506                         result = -1;
8507                 }
8508         }
8509         else if ((left->op == OP_ADDRCONST) && 
8510                 (right->op == OP_ADDRCONST) &&
8511                 (MISC(left, 0) == MISC(right, 0))) {
8512                 result = 0;
8513                 if (left->u.cval > right->u.cval) {
8514                         result = 1;
8515                 } else if (left->u.cval < right->u.cval) {
8516                         result = -1;
8517                 }
8518         }
8519         else {
8520                 internal_warning(state, ins, "incomparable constants passed to const_ucmp");
8521                 result = -2;
8522         }
8523         return result;
8524 }
8525
8526 int const_scmp(struct compile_state *state, struct triple *ins,
8527         struct triple *left, struct triple *right)
8528 {
8529         int result;
8530         if (!is_const(left) || !is_const(right)) {
8531                 internal_warning(state, ins, "non const past to ucmp_const");
8532                 result = -2;
8533         }
8534         else if (left == right) {
8535                 result = 0;
8536         }
8537         else if (is_simple_const(left) && is_simple_const(right)) {
8538                 long_t lval, rval;
8539                 lval = read_sconst(state, ins, left);
8540                 rval = read_sconst(state, ins, right);
8541                 result = 0;
8542                 if (lval > rval) {
8543                         result = 1;
8544                 } else if (rval > lval) {
8545                         result = -1;
8546                 }
8547         }
8548         else {
8549                 internal_warning(state, ins, "incomparable constants passed to const_scmp");
8550                 result = -2;
8551         }
8552         return result;
8553 }
8554
8555 static void unuse_rhs(struct compile_state *state, struct triple *ins)
8556 {
8557         struct triple **expr;
8558         expr = triple_rhs(state, ins, 0);
8559         for(;expr;expr = triple_rhs(state, ins, expr)) {
8560                 if (*expr) {
8561                         unuse_triple(*expr, ins);
8562                         *expr = 0;
8563                 }
8564         }
8565 }
8566
8567 static void unuse_lhs(struct compile_state *state, struct triple *ins)
8568 {
8569         struct triple **expr;
8570         expr = triple_lhs(state, ins, 0);
8571         for(;expr;expr = triple_lhs(state, ins, expr)) {
8572                 unuse_triple(*expr, ins);
8573                 *expr = 0;
8574         }
8575 }
8576
8577 static void unuse_misc(struct compile_state *state, struct triple *ins)
8578 {
8579         struct triple **expr;
8580         expr = triple_misc(state, ins, 0);
8581         for(;expr;expr = triple_misc(state, ins, expr)) {
8582                 unuse_triple(*expr, ins);
8583                 *expr = 0;
8584         }
8585 }
8586
8587 static void unuse_targ(struct compile_state *state, struct triple *ins)
8588 {
8589         int i;
8590         struct triple **slot;
8591         slot = &TARG(ins, 0);
8592         for(i = 0; i < ins->targ; i++) {
8593                 unuse_triple(slot[i], ins);
8594                 slot[i] = 0;
8595         }
8596 }
8597
8598 static void check_lhs(struct compile_state *state, struct triple *ins)
8599 {
8600         struct triple **expr;
8601         expr = triple_lhs(state, ins, 0);
8602         for(;expr;expr = triple_lhs(state, ins, expr)) {
8603                 internal_error(state, ins, "unexpected lhs");
8604         }
8605         
8606 }
8607
8608 static void check_misc(struct compile_state *state, struct triple *ins)
8609 {
8610         struct triple **expr;
8611         expr = triple_misc(state, ins, 0);
8612         for(;expr;expr = triple_misc(state, ins, expr)) {
8613                 if (*expr) {
8614                         internal_error(state, ins, "unexpected misc");
8615                 }
8616         }
8617 }
8618
8619 static void check_targ(struct compile_state *state, struct triple *ins)
8620 {
8621         struct triple **expr;
8622         expr = triple_targ(state, ins, 0);
8623         for(;expr;expr = triple_targ(state, ins, expr)) {
8624                 internal_error(state, ins, "unexpected targ");
8625         }
8626 }
8627
8628 static void wipe_ins(struct compile_state *state, struct triple *ins)
8629 {
8630         /* Becareful which instructions you replace the wiped
8631          * instruction with, as there are not enough slots
8632          * in all instructions to hold all others.
8633          */
8634         check_targ(state, ins);
8635         check_misc(state, ins);
8636         unuse_rhs(state, ins);
8637         unuse_lhs(state, ins);
8638         ins->lhs  = 0;
8639         ins->rhs  = 0;
8640         ins->misc = 0;
8641         ins->targ = 0;
8642 }
8643
8644 static void wipe_branch(struct compile_state *state, struct triple *ins)
8645 {
8646         /* Becareful which instructions you replace the wiped
8647          * instruction with, as there are not enough slots
8648          * in all instructions to hold all others.
8649          */
8650         unuse_rhs(state, ins);
8651         unuse_lhs(state, ins);
8652         unuse_misc(state, ins);
8653         unuse_targ(state, ins);
8654         ins->lhs  = 0;
8655         ins->rhs  = 0;
8656         ins->misc = 0;
8657         ins->targ = 0;
8658 }
8659
8660 static void mkcopy(struct compile_state *state, 
8661         struct triple *ins, struct triple *rhs)
8662 {
8663         struct block *block;
8664         if (!equiv_types(ins->type, rhs->type)) {
8665                 FILE *fp = state->errout;
8666                 fprintf(fp, "src type: ");
8667                 name_of(fp, rhs->type);
8668                 fprintf(fp, "\ndst type: ");
8669                 name_of(fp, ins->type);
8670                 fprintf(fp, "\n");
8671                 internal_error(state, ins, "mkcopy type mismatch");
8672         }
8673         block = block_of_triple(state, ins);
8674         wipe_ins(state, ins);
8675         ins->op = OP_COPY;
8676         ins->rhs  = 1;
8677         ins->u.block = block;
8678         RHS(ins, 0) = rhs;
8679         use_triple(RHS(ins, 0), ins);
8680 }
8681
8682 static void mkconst(struct compile_state *state, 
8683         struct triple *ins, ulong_t value)
8684 {
8685         if (!is_integral(ins) && !is_pointer(ins)) {
8686                 fprintf(state->errout, "type: ");
8687                 name_of(state->errout, ins->type);
8688                 fprintf(state->errout, "\n");
8689                 internal_error(state, ins, "unknown type to make constant value: %ld",
8690                         value);
8691         }
8692         wipe_ins(state, ins);
8693         ins->op = OP_INTCONST;
8694         ins->u.cval = value;
8695 }
8696
8697 static void mkaddr_const(struct compile_state *state,
8698         struct triple *ins, struct triple *sdecl, ulong_t value)
8699 {
8700         if ((sdecl->op != OP_SDECL) && (sdecl->op != OP_LABEL)) {
8701                 internal_error(state, ins, "bad base for addrconst");
8702         }
8703         wipe_ins(state, ins);
8704         ins->op = OP_ADDRCONST;
8705         ins->misc = 1;
8706         MISC(ins, 0) = sdecl;
8707         ins->u.cval = value;
8708         use_triple(sdecl, ins);
8709 }
8710
8711 #if DEBUG_DECOMPOSE_PRINT_TUPLES
8712 static void print_tuple(struct compile_state *state, 
8713         struct triple *ins, struct triple *tuple)
8714 {
8715         FILE *fp = state->dbgout;
8716         fprintf(fp, "%5s %p tuple: %p ", tops(ins->op), ins, tuple);
8717         name_of(fp, tuple->type);
8718         if (tuple->lhs > 0) {
8719                 fprintf(fp, " lhs: ");
8720                 name_of(fp, LHS(tuple, 0)->type);
8721         }
8722         fprintf(fp, "\n");
8723         
8724 }
8725 #endif
8726
8727 static struct triple *decompose_with_tuple(struct compile_state *state, 
8728         struct triple *ins, struct triple *tuple)
8729 {
8730         struct triple *next;
8731         next = ins->next;
8732         flatten(state, next, tuple);
8733 #if DEBUG_DECOMPOSE_PRINT_TUPLES
8734         print_tuple(state, ins, tuple);
8735 #endif
8736
8737         if (!is_compound_type(tuple->type) && (tuple->lhs > 0)) {
8738                 struct triple *tmp;
8739                 if (tuple->lhs != 1) {
8740                         internal_error(state, tuple, "plain type in multiple registers?");
8741                 }
8742                 tmp = LHS(tuple, 0);
8743                 release_triple(state, tuple);
8744                 tuple = tmp;
8745         }
8746
8747         propogate_use(state, ins, tuple);
8748         release_triple(state, ins);
8749         
8750         return next;
8751 }
8752
8753 static struct triple *decompose_unknownval(struct compile_state *state,
8754         struct triple *ins)
8755 {
8756         struct triple *tuple;
8757         ulong_t i;
8758
8759 #if DEBUG_DECOMPOSE_HIRES
8760         FILE *fp = state->dbgout;
8761         fprintf(fp, "unknown type: ");
8762         name_of(fp, ins->type);
8763         fprintf(fp, "\n");
8764 #endif
8765
8766         get_occurance(ins->occurance);
8767         tuple = alloc_triple(state, OP_TUPLE, ins->type, -1, -1, 
8768                 ins->occurance);
8769
8770         for(i = 0; i < tuple->lhs; i++) {
8771                 struct type *piece_type;
8772                 struct triple *unknown;
8773
8774                 piece_type = reg_type(state, ins->type, i * REG_SIZEOF_REG);
8775                 get_occurance(tuple->occurance);
8776                 unknown = alloc_triple(state, OP_UNKNOWNVAL, piece_type, 0, 0,
8777                         tuple->occurance);
8778                 LHS(tuple, i) = unknown;
8779         }
8780         return decompose_with_tuple(state, ins, tuple);
8781 }
8782
8783
8784 static struct triple *decompose_read(struct compile_state *state, 
8785         struct triple *ins)
8786 {
8787         struct triple *tuple, *lval;
8788         ulong_t i;
8789
8790         lval = RHS(ins, 0);
8791
8792         if (lval->op == OP_PIECE) {
8793                 return ins->next;
8794         }
8795         get_occurance(ins->occurance);
8796         tuple = alloc_triple(state, OP_TUPLE, lval->type, -1, -1,
8797                 ins->occurance);
8798
8799         if ((tuple->lhs != lval->lhs) &&
8800                 (!triple_is_def(state, lval) || (tuple->lhs != 1))) 
8801         {
8802                 internal_error(state, ins, "lhs size inconsistency?");
8803         }
8804         for(i = 0; i < tuple->lhs; i++) {
8805                 struct triple *piece, *read, *bitref;
8806                 if ((i != 0) || !triple_is_def(state, lval)) {
8807                         piece = LHS(lval, i);
8808                 } else {
8809                         piece = lval;
8810                 }
8811
8812                 /* See if the piece is really a bitref */
8813                 bitref = 0;
8814                 if (piece->op == OP_BITREF) {
8815                         bitref = piece;
8816                         piece = RHS(bitref, 0);
8817                 }
8818
8819                 get_occurance(tuple->occurance);
8820                 read = alloc_triple(state, OP_READ, piece->type, -1, -1, 
8821                         tuple->occurance);
8822                 RHS(read, 0) = piece;
8823
8824                 if (bitref) {
8825                         struct triple *extract;
8826                         int op;
8827                         if (is_signed(bitref->type->left)) {
8828                                 op = OP_SEXTRACT;
8829                         } else {
8830                                 op = OP_UEXTRACT;
8831                         }
8832                         get_occurance(tuple->occurance);
8833                         extract = alloc_triple(state, op, bitref->type, -1, -1,
8834                                 tuple->occurance);
8835                         RHS(extract, 0) = read;
8836                         extract->u.bitfield.size   = bitref->u.bitfield.size;
8837                         extract->u.bitfield.offset = bitref->u.bitfield.offset;
8838
8839                         read = extract;
8840                 }
8841
8842                 LHS(tuple, i) = read;
8843         }
8844         return decompose_with_tuple(state, ins, tuple);
8845 }
8846
8847 static struct triple *decompose_write(struct compile_state *state, 
8848         struct triple *ins)
8849 {
8850         struct triple *tuple, *lval, *val;
8851         ulong_t i;
8852         
8853         lval = MISC(ins, 0);
8854         val = RHS(ins, 0);
8855         get_occurance(ins->occurance);
8856         tuple = alloc_triple(state, OP_TUPLE, ins->type, -1, -1,
8857                 ins->occurance);
8858
8859         if ((tuple->lhs != lval->lhs) &&
8860                 (!triple_is_def(state, lval) || tuple->lhs != 1)) 
8861         {
8862                 internal_error(state, ins, "lhs size inconsistency?");
8863         }
8864         for(i = 0; i < tuple->lhs; i++) {
8865                 struct triple *piece, *write, *pval, *bitref;
8866                 if ((i != 0) || !triple_is_def(state, lval)) {
8867                         piece = LHS(lval, i);
8868                 } else {
8869                         piece = lval;
8870                 }
8871                 if ((i == 0) && (tuple->lhs == 1) && (val->lhs == 0)) {
8872                         pval = val;
8873                 }
8874                 else {
8875                         if (i > val->lhs) {
8876                                 internal_error(state, ins, "lhs size inconsistency?");
8877                         }
8878                         pval = LHS(val, i);
8879                 }
8880                 
8881                 /* See if the piece is really a bitref */
8882                 bitref = 0;
8883                 if (piece->op == OP_BITREF) {
8884                         struct triple *read, *deposit;
8885                         bitref = piece;
8886                         piece = RHS(bitref, 0);
8887
8888                         /* Read the destination register */
8889                         get_occurance(tuple->occurance);
8890                         read = alloc_triple(state, OP_READ, piece->type, -1, -1,
8891                                 tuple->occurance);
8892                         RHS(read, 0) = piece;
8893
8894                         /* Deposit the new bitfield value */
8895                         get_occurance(tuple->occurance);
8896                         deposit = alloc_triple(state, OP_DEPOSIT, piece->type, -1, -1,
8897                                 tuple->occurance);
8898                         RHS(deposit, 0) = read;
8899                         RHS(deposit, 1) = pval;
8900                         deposit->u.bitfield.size   = bitref->u.bitfield.size;
8901                         deposit->u.bitfield.offset = bitref->u.bitfield.offset;
8902
8903                         /* Now write the newly generated value */
8904                         pval = deposit;
8905                 }
8906
8907                 get_occurance(tuple->occurance);
8908                 write = alloc_triple(state, OP_WRITE, piece->type, -1, -1, 
8909                         tuple->occurance);
8910                 MISC(write, 0) = piece;
8911                 RHS(write, 0) = pval;
8912                 LHS(tuple, i) = write;
8913         }
8914         return decompose_with_tuple(state, ins, tuple);
8915 }
8916
8917 struct decompose_load_info {
8918         struct occurance *occurance;
8919         struct triple *lval;
8920         struct triple *tuple;
8921 };
8922 static void decompose_load_cb(struct compile_state *state,
8923         struct type *type, size_t reg_offset, size_t mem_offset, void *arg)
8924 {
8925         struct decompose_load_info *info = arg;
8926         struct triple *load;
8927         
8928         if (reg_offset > info->tuple->lhs) {
8929                 internal_error(state, info->tuple, "lhs to small?");
8930         }
8931         get_occurance(info->occurance);
8932         load = alloc_triple(state, OP_LOAD, type, -1, -1, info->occurance);
8933         RHS(load, 0) = mk_addr_expr(state, info->lval, mem_offset);
8934         LHS(info->tuple, reg_offset/REG_SIZEOF_REG) = load;
8935 }
8936
8937 static struct triple *decompose_load(struct compile_state *state, 
8938         struct triple *ins)
8939 {
8940         struct triple *tuple;
8941         struct decompose_load_info info;
8942
8943         if (!is_compound_type(ins->type)) {
8944                 return ins->next;
8945         }
8946         get_occurance(ins->occurance);
8947         tuple = alloc_triple(state, OP_TUPLE, ins->type, -1, -1,
8948                 ins->occurance);
8949
8950         info.occurance = ins->occurance;
8951         info.lval      = RHS(ins, 0);
8952         info.tuple     = tuple;
8953         walk_type_fields(state, ins->type, 0, 0, decompose_load_cb, &info);
8954
8955         return decompose_with_tuple(state, ins, tuple);
8956 }
8957
8958
8959 struct decompose_store_info {
8960         struct occurance *occurance;
8961         struct triple *lval;
8962         struct triple *val;
8963         struct triple *tuple;
8964 };
8965 static void decompose_store_cb(struct compile_state *state,
8966         struct type *type, size_t reg_offset, size_t mem_offset, void *arg)
8967 {
8968         struct decompose_store_info *info = arg;
8969         struct triple *store;
8970         
8971         if (reg_offset > info->tuple->lhs) {
8972                 internal_error(state, info->tuple, "lhs to small?");
8973         }
8974         get_occurance(info->occurance);
8975         store = alloc_triple(state, OP_STORE, type, -1, -1, info->occurance);
8976         RHS(store, 0) = mk_addr_expr(state, info->lval, mem_offset);
8977         RHS(store, 1) = LHS(info->val, reg_offset);
8978         LHS(info->tuple, reg_offset/REG_SIZEOF_REG) = store;
8979 }
8980
8981 static struct triple *decompose_store(struct compile_state *state, 
8982         struct triple *ins)
8983 {
8984         struct triple *tuple;
8985         struct decompose_store_info info;
8986
8987         if (!is_compound_type(ins->type)) {
8988                 return ins->next;
8989         }
8990         get_occurance(ins->occurance);
8991         tuple = alloc_triple(state, OP_TUPLE, ins->type, -1, -1,
8992                 ins->occurance);
8993
8994         info.occurance = ins->occurance;
8995         info.lval      = RHS(ins, 0);
8996         info.val       = RHS(ins, 1);
8997         info.tuple     = tuple;
8998         walk_type_fields(state, ins->type, 0, 0, decompose_store_cb, &info);
8999
9000         return decompose_with_tuple(state, ins, tuple);
9001 }
9002
9003 static struct triple *decompose_dot(struct compile_state *state, 
9004         struct triple *ins)
9005 {
9006         struct triple *tuple, *lval;
9007         struct type *type;
9008         size_t reg_offset;
9009         int i, idx;
9010
9011         lval = MISC(ins, 0);
9012         reg_offset = field_reg_offset(state, lval->type, ins->u.field);
9013         idx  = reg_offset/REG_SIZEOF_REG;
9014         type = field_type(state, lval->type, ins->u.field);
9015 #if DEBUG_DECOMPOSE_HIRES
9016         {
9017                 FILE *fp = state->dbgout;
9018                 fprintf(fp, "field type: ");
9019                 name_of(fp, type);
9020                 fprintf(fp, "\n");
9021         }
9022 #endif
9023
9024         get_occurance(ins->occurance);
9025         tuple = alloc_triple(state, OP_TUPLE, type, -1, -1, 
9026                 ins->occurance);
9027
9028         if (((ins->type->type & TYPE_MASK) == TYPE_BITFIELD) &&
9029                 (tuple->lhs != 1))
9030         {
9031                 internal_error(state, ins, "multi register bitfield?");
9032         }
9033
9034         for(i = 0; i < tuple->lhs; i++, idx++) {
9035                 struct triple *piece;
9036                 if (!triple_is_def(state, lval)) {
9037                         if (idx > lval->lhs) {
9038                                 internal_error(state, ins, "inconsistent lhs count");
9039                         }
9040                         piece = LHS(lval, idx);
9041                 } else {
9042                         if (idx != 0) {
9043                                 internal_error(state, ins, "bad reg_offset into def");
9044                         }
9045                         if (i != 0) {
9046                                 internal_error(state, ins, "bad reg count from def");
9047                         }
9048                         piece = lval;
9049                 }
9050
9051                 /* Remember the offset of the bitfield */
9052                 if ((type->type & TYPE_MASK) == TYPE_BITFIELD) {
9053                         get_occurance(ins->occurance);
9054                         piece = build_triple(state, OP_BITREF, type, piece, 0,
9055                                 ins->occurance);
9056                         piece->u.bitfield.size   = size_of(state, type);
9057                         piece->u.bitfield.offset = reg_offset % REG_SIZEOF_REG;
9058                 }
9059                 else if ((reg_offset % REG_SIZEOF_REG) != 0) {
9060                         internal_error(state, ins, 
9061                                 "request for a nonbitfield sub register?");
9062                 }
9063
9064                 LHS(tuple, i) = piece;
9065         }
9066
9067         return decompose_with_tuple(state, ins, tuple);
9068 }
9069
9070 static struct triple *decompose_index(struct compile_state *state, 
9071         struct triple *ins)
9072 {
9073         struct triple *tuple, *lval;
9074         struct type *type;
9075         int i, idx;
9076
9077         lval = MISC(ins, 0);
9078         idx = index_reg_offset(state, lval->type, ins->u.cval)/REG_SIZEOF_REG;
9079         type = index_type(state, lval->type, ins->u.cval);
9080 #if DEBUG_DECOMPOSE_HIRES
9081 {
9082         FILE *fp = state->dbgout;
9083         fprintf(fp, "index type: ");
9084         name_of(fp, type);
9085         fprintf(fp, "\n");
9086 }
9087 #endif
9088
9089         get_occurance(ins->occurance);
9090         tuple = alloc_triple(state, OP_TUPLE, type, -1, -1, 
9091                 ins->occurance);
9092
9093         for(i = 0; i < tuple->lhs; i++, idx++) {
9094                 struct triple *piece;
9095                 if (!triple_is_def(state, lval)) {
9096                         if (idx > lval->lhs) {
9097                                 internal_error(state, ins, "inconsistent lhs count");
9098                         }
9099                         piece = LHS(lval, idx);
9100                 } else {
9101                         if (idx != 0) {
9102                                 internal_error(state, ins, "bad reg_offset into def");
9103                         }
9104                         if (i != 0) {
9105                                 internal_error(state, ins, "bad reg count from def");
9106                         }
9107                         piece = lval;
9108                 }
9109                 LHS(tuple, i) = piece;
9110         }
9111
9112         return decompose_with_tuple(state, ins, tuple);
9113 }
9114
9115 static void decompose_compound_types(struct compile_state *state)
9116 {
9117         struct triple *ins, *next, *first;
9118         FILE *fp;
9119         fp = state->dbgout;
9120         first = state->first;
9121         ins = first;
9122
9123         /* Pass one expand compound values into pseudo registers.
9124          */
9125         next = first;
9126         do {
9127                 ins = next;
9128                 next = ins->next;
9129                 switch(ins->op) {
9130                 case OP_UNKNOWNVAL:
9131                         next = decompose_unknownval(state, ins);
9132                         break;
9133
9134                 case OP_READ:
9135                         next = decompose_read(state, ins);
9136                         break;
9137
9138                 case OP_WRITE:
9139                         next = decompose_write(state, ins);
9140                         break;
9141
9142
9143                 /* Be very careful with the load/store logic. These
9144                  * operations must convert from the in register layout
9145                  * to the in memory layout, which is nontrivial.
9146                  */
9147                 case OP_LOAD:
9148                         next = decompose_load(state, ins);
9149                         break;
9150                 case OP_STORE:
9151                         next = decompose_store(state, ins);
9152                         break;
9153
9154                 case OP_DOT:
9155                         next = decompose_dot(state, ins);
9156                         break;
9157                 case OP_INDEX:
9158                         next = decompose_index(state, ins);
9159                         break;
9160                         
9161                 }
9162 #if DEBUG_DECOMPOSE_HIRES
9163                 fprintf(fp, "decompose next: %p \n", next);
9164                 fflush(fp);
9165                 fprintf(fp, "next->op: %d %s\n",
9166                         next->op, tops(next->op));
9167                 /* High resolution debugging mode */
9168                 print_triples(state);
9169 #endif
9170         } while (next != first);
9171
9172         /* Pass two remove the tuples.
9173          */
9174         ins = first;
9175         do {
9176                 next = ins->next;
9177                 if (ins->op == OP_TUPLE) {
9178                         if (ins->use) {
9179                                 internal_error(state, ins, "tuple used");
9180                         }
9181                         else {
9182                                 release_triple(state, ins);
9183                         }
9184                 } 
9185                 ins = next;
9186         } while(ins != first);
9187         ins = first;
9188         do {
9189                 next = ins->next;
9190                 if (ins->op == OP_BITREF) {
9191                         if (ins->use) {
9192                                 internal_error(state, ins, "bitref used");
9193                         } 
9194                         else {
9195                                 release_triple(state, ins);
9196                         }
9197                 }
9198                 ins = next;
9199         } while(ins != first);
9200
9201         /* Pass three verify the state and set ->id to 0.
9202          */
9203         next = first;
9204         do {
9205                 ins = next;
9206                 next = ins->next;
9207                 ins->id &= ~TRIPLE_FLAG_FLATTENED;
9208                 if (triple_stores_block(state, ins)) {
9209                         ins->u.block = 0;
9210                 }
9211                 if (triple_is_def(state, ins)) {
9212                         if (reg_size_of(state, ins->type) > REG_SIZEOF_REG) {
9213                                 internal_error(state, ins, "multi register value remains?");
9214                         }
9215                 }
9216                 if (ins->op == OP_DOT) {
9217                         internal_error(state, ins, "OP_DOT remains?");
9218                 }
9219                 if (ins->op == OP_INDEX) {
9220                         internal_error(state, ins, "OP_INDEX remains?");
9221                 }
9222                 if (ins->op == OP_BITREF) {
9223                         internal_error(state, ins, "OP_BITREF remains?");
9224                 }
9225                 if (ins->op == OP_TUPLE) {
9226                         internal_error(state, ins, "OP_TUPLE remains?");
9227                 }
9228         } while(next != first);
9229 }
9230
9231 /* For those operations that cannot be simplified */
9232 static void simplify_noop(struct compile_state *state, struct triple *ins)
9233 {
9234         return;
9235 }
9236
9237 static void simplify_smul(struct compile_state *state, struct triple *ins)
9238 {
9239         if (is_const(RHS(ins, 0)) && !is_const(RHS(ins, 1))) {
9240                 struct triple *tmp;
9241                 tmp = RHS(ins, 0);
9242                 RHS(ins, 0) = RHS(ins, 1);
9243                 RHS(ins, 1) = tmp;
9244         }
9245         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
9246                 long_t left, right;
9247                 left  = read_sconst(state, ins, RHS(ins, 0));
9248                 right = read_sconst(state, ins, RHS(ins, 1));
9249                 mkconst(state, ins, left * right);
9250         }
9251         else if (is_zero(RHS(ins, 1))) {
9252                 mkconst(state, ins, 0);
9253         }
9254         else if (is_one(RHS(ins, 1))) {
9255                 mkcopy(state, ins, RHS(ins, 0));
9256         }
9257         else if (is_pow2(RHS(ins, 1))) {
9258                 struct triple *val;
9259                 val = int_const(state, ins->type, tlog2(RHS(ins, 1)));
9260                 ins->op = OP_SL;
9261                 insert_triple(state, state->global_pool, val);
9262                 unuse_triple(RHS(ins, 1), ins);
9263                 use_triple(val, ins);
9264                 RHS(ins, 1) = val;
9265         }
9266 }
9267
9268 static void simplify_umul(struct compile_state *state, struct triple *ins)
9269 {
9270         if (is_const(RHS(ins, 0)) && !is_const(RHS(ins, 1))) {
9271                 struct triple *tmp;
9272                 tmp = RHS(ins, 0);
9273                 RHS(ins, 0) = RHS(ins, 1);
9274                 RHS(ins, 1) = tmp;
9275         }
9276         if (is_simple_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9277                 ulong_t left, right;
9278                 left  = read_const(state, ins, RHS(ins, 0));
9279                 right = read_const(state, ins, RHS(ins, 1));
9280                 mkconst(state, ins, left * right);
9281         }
9282         else if (is_zero(RHS(ins, 1))) {
9283                 mkconst(state, ins, 0);
9284         }
9285         else if (is_one(RHS(ins, 1))) {
9286                 mkcopy(state, ins, RHS(ins, 0));
9287         }
9288         else if (is_pow2(RHS(ins, 1))) {
9289                 struct triple *val;
9290                 val = int_const(state, ins->type, tlog2(RHS(ins, 1)));
9291                 ins->op = OP_SL;
9292                 insert_triple(state, state->global_pool, val);
9293                 unuse_triple(RHS(ins, 1), ins);
9294                 use_triple(val, ins);
9295                 RHS(ins, 1) = val;
9296         }
9297 }
9298
9299 static void simplify_sdiv(struct compile_state *state, struct triple *ins)
9300 {
9301         if (is_const(RHS(ins, 0)) && is_const(RHS(ins, 1))) {
9302                 long_t left, right;
9303                 left  = read_sconst(state, ins, RHS(ins, 0));
9304                 right = read_sconst(state, ins, RHS(ins, 1));
9305                 mkconst(state, ins, left / right);
9306         }
9307         else if (is_zero(RHS(ins, 0))) {
9308                 mkconst(state, ins, 0);
9309         }
9310         else if (is_zero(RHS(ins, 1))) {
9311                 error(state, ins, "division by zero");
9312         }
9313         else if (is_one(RHS(ins, 1))) {
9314                 mkcopy(state, ins, RHS(ins, 0));
9315         }
9316         else if (is_pow2(RHS(ins, 1))) {
9317                 struct triple *val;
9318                 val = int_const(state, ins->type, tlog2(RHS(ins, 1)));
9319                 ins->op = OP_SSR;
9320                 insert_triple(state, state->global_pool, val);
9321                 unuse_triple(RHS(ins, 1), ins);
9322                 use_triple(val, ins);
9323                 RHS(ins, 1) = val;
9324         }
9325 }
9326
9327 static void simplify_udiv(struct compile_state *state, struct triple *ins)
9328 {
9329         if (is_simple_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9330                 ulong_t left, right;
9331                 left  = read_const(state, ins, RHS(ins, 0));
9332                 right = read_const(state, ins, RHS(ins, 1));
9333                 mkconst(state, ins, left / right);
9334         }
9335         else if (is_zero(RHS(ins, 0))) {
9336                 mkconst(state, ins, 0);
9337         }
9338         else if (is_zero(RHS(ins, 1))) {
9339                 error(state, ins, "division by zero");
9340         }
9341         else if (is_one(RHS(ins, 1))) {
9342                 mkcopy(state, ins, RHS(ins, 0));
9343         }
9344         else if (is_pow2(RHS(ins, 1))) {
9345                 struct triple *val;
9346                 val = int_const(state, ins->type, tlog2(RHS(ins, 1)));
9347                 ins->op = OP_USR;
9348                 insert_triple(state, state->global_pool, val);
9349                 unuse_triple(RHS(ins, 1), ins);
9350                 use_triple(val, ins);
9351                 RHS(ins, 1) = val;
9352         }
9353 }
9354
9355 static void simplify_smod(struct compile_state *state, struct triple *ins)
9356 {
9357         if (is_simple_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9358                 long_t left, right;
9359                 left  = read_const(state, ins, RHS(ins, 0));
9360                 right = read_const(state, ins, RHS(ins, 1));
9361                 mkconst(state, ins, left % right);
9362         }
9363         else if (is_zero(RHS(ins, 0))) {
9364                 mkconst(state, ins, 0);
9365         }
9366         else if (is_zero(RHS(ins, 1))) {
9367                 error(state, ins, "division by zero");
9368         }
9369         else if (is_one(RHS(ins, 1))) {
9370                 mkconst(state, ins, 0);
9371         }
9372         else if (is_pow2(RHS(ins, 1))) {
9373                 struct triple *val;
9374                 val = int_const(state, ins->type, RHS(ins, 1)->u.cval - 1);
9375                 ins->op = OP_AND;
9376                 insert_triple(state, state->global_pool, val);
9377                 unuse_triple(RHS(ins, 1), ins);
9378                 use_triple(val, ins);
9379                 RHS(ins, 1) = val;
9380         }
9381 }
9382
9383 static void simplify_umod(struct compile_state *state, struct triple *ins)
9384 {
9385         if (is_simple_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9386                 ulong_t left, right;
9387                 left  = read_const(state, ins, RHS(ins, 0));
9388                 right = read_const(state, ins, RHS(ins, 1));
9389                 mkconst(state, ins, left % right);
9390         }
9391         else if (is_zero(RHS(ins, 0))) {
9392                 mkconst(state, ins, 0);
9393         }
9394         else if (is_zero(RHS(ins, 1))) {
9395                 error(state, ins, "division by zero");
9396         }
9397         else if (is_one(RHS(ins, 1))) {
9398                 mkconst(state, ins, 0);
9399         }
9400         else if (is_pow2(RHS(ins, 1))) {
9401                 struct triple *val;
9402                 val = int_const(state, ins->type, RHS(ins, 1)->u.cval - 1);
9403                 ins->op = OP_AND;
9404                 insert_triple(state, state->global_pool, val);
9405                 unuse_triple(RHS(ins, 1), ins);
9406                 use_triple(val, ins);
9407                 RHS(ins, 1) = val;
9408         }
9409 }
9410
9411 static void simplify_add(struct compile_state *state, struct triple *ins)
9412 {
9413         /* start with the pointer on the left */
9414         if (is_pointer(RHS(ins, 1))) {
9415                 struct triple *tmp;
9416                 tmp = RHS(ins, 0);
9417                 RHS(ins, 0) = RHS(ins, 1);
9418                 RHS(ins, 1) = tmp;
9419         }
9420         if (is_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9421                 if (RHS(ins, 0)->op == OP_INTCONST) {
9422                         ulong_t left, right;
9423                         left  = read_const(state, ins, RHS(ins, 0));
9424                         right = read_const(state, ins, RHS(ins, 1));
9425                         mkconst(state, ins, left + right);
9426                 }
9427                 else if (RHS(ins, 0)->op == OP_ADDRCONST) {
9428                         struct triple *sdecl;
9429                         ulong_t left, right;
9430                         sdecl = MISC(RHS(ins, 0), 0);
9431                         left  = RHS(ins, 0)->u.cval;
9432                         right = RHS(ins, 1)->u.cval;
9433                         mkaddr_const(state, ins, sdecl, left + right);
9434                 }
9435                 else {
9436                         internal_warning(state, ins, "Optimize me!");
9437                 }
9438         }
9439         else if (is_const(RHS(ins, 0)) && !is_const(RHS(ins, 1))) {
9440                 struct triple *tmp;
9441                 tmp = RHS(ins, 1);
9442                 RHS(ins, 1) = RHS(ins, 0);
9443                 RHS(ins, 0) = tmp;
9444         }
9445 }
9446
9447 static void simplify_sub(struct compile_state *state, struct triple *ins)
9448 {
9449         if (is_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9450                 if (RHS(ins, 0)->op == OP_INTCONST) {
9451                         ulong_t left, right;
9452                         left  = read_const(state, ins, RHS(ins, 0));
9453                         right = read_const(state, ins, RHS(ins, 1));
9454                         mkconst(state, ins, left - right);
9455                 }
9456                 else if (RHS(ins, 0)->op == OP_ADDRCONST) {
9457                         struct triple *sdecl;
9458                         ulong_t left, right;
9459                         sdecl = MISC(RHS(ins, 0), 0);
9460                         left  = RHS(ins, 0)->u.cval;
9461                         right = RHS(ins, 1)->u.cval;
9462                         mkaddr_const(state, ins, sdecl, left - right);
9463                 }
9464                 else {
9465                         internal_warning(state, ins, "Optimize me!");
9466                 }
9467         }
9468 }
9469
9470 static void simplify_sl(struct compile_state *state, struct triple *ins)
9471 {
9472         if (is_simple_const(RHS(ins, 1))) {
9473                 ulong_t right;
9474                 right = read_const(state, ins, RHS(ins, 1));
9475                 if (right >= (size_of(state, ins->type))) {
9476                         warning(state, ins, "left shift count >= width of type");
9477                 }
9478         }
9479         if (is_simple_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9480                 ulong_t left, right;
9481                 left  = read_const(state, ins, RHS(ins, 0));
9482                 right = read_const(state, ins, RHS(ins, 1));
9483                 mkconst(state, ins,  left << right);
9484         }
9485 }
9486
9487 static void simplify_usr(struct compile_state *state, struct triple *ins)
9488 {
9489         if (is_simple_const(RHS(ins, 1))) {
9490                 ulong_t right;
9491                 right = read_const(state, ins, RHS(ins, 1));
9492                 if (right >= (size_of(state, ins->type))) {
9493                         warning(state, ins, "right shift count >= width of type");
9494                 }
9495         }
9496         if (is_simple_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9497                 ulong_t left, right;
9498                 left  = read_const(state, ins, RHS(ins, 0));
9499                 right = read_const(state, ins, RHS(ins, 1));
9500                 mkconst(state, ins, left >> right);
9501         }
9502 }
9503
9504 static void simplify_ssr(struct compile_state *state, struct triple *ins)
9505 {
9506         if (is_simple_const(RHS(ins, 1))) {
9507                 ulong_t right;
9508                 right = read_const(state, ins, RHS(ins, 1));
9509                 if (right >= (size_of(state, ins->type))) {
9510                         warning(state, ins, "right shift count >= width of type");
9511                 }
9512         }
9513         if (is_simple_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9514                 long_t left, right;
9515                 left  = read_sconst(state, ins, RHS(ins, 0));
9516                 right = read_sconst(state, ins, RHS(ins, 1));
9517                 mkconst(state, ins, left >> right);
9518         }
9519 }
9520
9521 static void simplify_and(struct compile_state *state, struct triple *ins)
9522 {
9523         struct triple *left, *right;
9524         left = RHS(ins, 0);
9525         right = RHS(ins, 1);
9526
9527         if (is_simple_const(left) && is_simple_const(right)) {
9528                 ulong_t lval, rval;
9529                 lval = read_const(state, ins, left);
9530                 rval = read_const(state, ins, right);
9531                 mkconst(state, ins, lval & rval);
9532         }
9533         else if (is_zero(right) || is_zero(left)) {
9534                 mkconst(state, ins, 0);
9535         }
9536 }
9537
9538 static void simplify_or(struct compile_state *state, struct triple *ins)
9539 {
9540         struct triple *left, *right;
9541         left = RHS(ins, 0);
9542         right = RHS(ins, 1);
9543
9544         if (is_simple_const(left) && is_simple_const(right)) {
9545                 ulong_t lval, rval;
9546                 lval = read_const(state, ins, left);
9547                 rval = read_const(state, ins, right);
9548                 mkconst(state, ins, lval | rval);
9549         }
9550 #if 0 /* I need to handle type mismatches here... */
9551         else if (is_zero(right)) {
9552                 mkcopy(state, ins, left);
9553         }
9554         else if (is_zero(left)) {
9555                 mkcopy(state, ins, right);
9556         }
9557 #endif
9558 }
9559
9560 static void simplify_xor(struct compile_state *state, struct triple *ins)
9561 {
9562         if (is_simple_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9563                 ulong_t left, right;
9564                 left  = read_const(state, ins, RHS(ins, 0));
9565                 right = read_const(state, ins, RHS(ins, 1));
9566                 mkconst(state, ins, left ^ right);
9567         }
9568 }
9569
9570 static void simplify_pos(struct compile_state *state, struct triple *ins)
9571 {
9572         if (is_const(RHS(ins, 0))) {
9573                 mkconst(state, ins, RHS(ins, 0)->u.cval);
9574         }
9575         else {
9576                 mkcopy(state, ins, RHS(ins, 0));
9577         }
9578 }
9579
9580 static void simplify_neg(struct compile_state *state, struct triple *ins)
9581 {
9582         if (is_simple_const(RHS(ins, 0))) {
9583                 ulong_t left;
9584                 left = read_const(state, ins, RHS(ins, 0));
9585                 mkconst(state, ins, -left);
9586         }
9587         else if (RHS(ins, 0)->op == OP_NEG) {
9588                 mkcopy(state, ins, RHS(RHS(ins, 0), 0));
9589         }
9590 }
9591
9592 static void simplify_invert(struct compile_state *state, struct triple *ins)
9593 {
9594         if (is_simple_const(RHS(ins, 0))) {
9595                 ulong_t left;
9596                 left = read_const(state, ins, RHS(ins, 0));
9597                 mkconst(state, ins, ~left);
9598         }
9599 }
9600
9601 static void simplify_eq(struct compile_state *state, struct triple *ins)
9602 {
9603         struct triple *left, *right;
9604         left = RHS(ins, 0);
9605         right = RHS(ins, 1);
9606
9607         if (is_const(left) && is_const(right)) {
9608                 int val;
9609                 val = const_eq(state, ins, left, right);
9610                 if (val >= 0) {
9611                         mkconst(state, ins, val == 1);
9612                 }
9613         }
9614         else if (left == right) {
9615                 mkconst(state, ins, 1);
9616         }
9617 }
9618
9619 static void simplify_noteq(struct compile_state *state, struct triple *ins)
9620 {
9621         struct triple *left, *right;
9622         left = RHS(ins, 0);
9623         right = RHS(ins, 1);
9624
9625         if (is_const(left) && is_const(right)) {
9626                 int val;
9627                 val = const_eq(state, ins, left, right);
9628                 if (val >= 0) {
9629                         mkconst(state, ins, val != 1);
9630                 }
9631         }
9632         if (left == right) {
9633                 mkconst(state, ins, 0);
9634         }
9635 }
9636
9637 static void simplify_sless(struct compile_state *state, struct triple *ins)
9638 {
9639         struct triple *left, *right;
9640         left = RHS(ins, 0);
9641         right = RHS(ins, 1);
9642
9643         if (is_const(left) && is_const(right)) {
9644                 int val;
9645                 val = const_scmp(state, ins, left, right);
9646                 if ((val >= -1) && (val <= 1)) {
9647                         mkconst(state, ins, val < 0);
9648                 }
9649         }
9650         else if (left == right) {
9651                 mkconst(state, ins, 0);
9652         }
9653 }
9654
9655 static void simplify_uless(struct compile_state *state, struct triple *ins)
9656 {
9657         struct triple *left, *right;
9658         left = RHS(ins, 0);
9659         right = RHS(ins, 1);
9660
9661         if (is_const(left) && is_const(right)) {
9662                 int val;
9663                 val = const_ucmp(state, ins, left, right);
9664                 if ((val >= -1) && (val <= 1)) {
9665                         mkconst(state, ins, val < 0);
9666                 }
9667         }
9668         else if (is_zero(right)) {
9669                 mkconst(state, ins, 0);
9670         }
9671         else if (left == right) {
9672                 mkconst(state, ins, 0);
9673         }
9674 }
9675
9676 static void simplify_smore(struct compile_state *state, struct triple *ins)
9677 {
9678         struct triple *left, *right;
9679         left = RHS(ins, 0);
9680         right = RHS(ins, 1);
9681
9682         if (is_const(left) && is_const(right)) {
9683                 int val;
9684                 val = const_scmp(state, ins, left, right);
9685                 if ((val >= -1) && (val <= 1)) {
9686                         mkconst(state, ins, val > 0);
9687                 }
9688         }
9689         else if (left == right) {
9690                 mkconst(state, ins, 0);
9691         }
9692 }
9693
9694 static void simplify_umore(struct compile_state *state, struct triple *ins)
9695 {
9696         struct triple *left, *right;
9697         left = RHS(ins, 0);
9698         right = RHS(ins, 1);
9699
9700         if (is_const(left) && is_const(right)) {
9701                 int val;
9702                 val = const_ucmp(state, ins, left, right);
9703                 if ((val >= -1) && (val <= 1)) {
9704                         mkconst(state, ins, val > 0);
9705                 }
9706         }
9707         else if (is_zero(left)) {
9708                 mkconst(state, ins, 0);
9709         }
9710         else if (left == right) {
9711                 mkconst(state, ins, 0);
9712         }
9713 }
9714
9715
9716 static void simplify_slesseq(struct compile_state *state, struct triple *ins)
9717 {
9718         struct triple *left, *right;
9719         left = RHS(ins, 0);
9720         right = RHS(ins, 1);
9721
9722         if (is_const(left) && is_const(right)) {
9723                 int val;
9724                 val = const_scmp(state, ins, left, right);
9725                 if ((val >= -1) && (val <= 1)) {
9726                         mkconst(state, ins, val <= 0);
9727                 }
9728         }
9729         else if (left == right) {
9730                 mkconst(state, ins, 1);
9731         }
9732 }
9733
9734 static void simplify_ulesseq(struct compile_state *state, struct triple *ins)
9735 {
9736         struct triple *left, *right;
9737         left = RHS(ins, 0);
9738         right = RHS(ins, 1);
9739
9740         if (is_const(left) && is_const(right)) {
9741                 int val;
9742                 val = const_ucmp(state, ins, left, right);
9743                 if ((val >= -1) && (val <= 1)) {
9744                         mkconst(state, ins, val <= 0);
9745                 }
9746         }
9747         else if (is_zero(left)) {
9748                 mkconst(state, ins, 1);
9749         }
9750         else if (left == right) {
9751                 mkconst(state, ins, 1);
9752         }
9753 }
9754
9755 static void simplify_smoreeq(struct compile_state *state, struct triple *ins)
9756 {
9757         struct triple *left, *right;
9758         left = RHS(ins, 0);
9759         right = RHS(ins, 1);
9760
9761         if (is_const(left) && is_const(right)) {
9762                 int val;
9763                 val = const_scmp(state, ins, left, right);
9764                 if ((val >= -1) && (val <= 1)) {
9765                         mkconst(state, ins, val >= 0);
9766                 }
9767         }
9768         else if (left == right) {
9769                 mkconst(state, ins, 1);
9770         }
9771 }
9772
9773 static void simplify_umoreeq(struct compile_state *state, struct triple *ins)
9774 {
9775         struct triple *left, *right;
9776         left = RHS(ins, 0);
9777         right = RHS(ins, 1);
9778
9779         if (is_const(left) && is_const(right)) {
9780                 int val;
9781                 val = const_ucmp(state, ins, left, right);
9782                 if ((val >= -1) && (val <= 1)) {
9783                         mkconst(state, ins, val >= 0);
9784                 }
9785         }
9786         else if (is_zero(right)) {
9787                 mkconst(state, ins, 1);
9788         }
9789         else if (left == right) {
9790                 mkconst(state, ins, 1);
9791         }
9792 }
9793
9794 static void simplify_lfalse(struct compile_state *state, struct triple *ins)
9795 {
9796         struct triple *rhs;
9797         rhs = RHS(ins, 0);
9798
9799         if (is_const(rhs)) {
9800                 mkconst(state, ins, !const_ltrue(state, ins, rhs));
9801         }
9802         /* Otherwise if I am the only user... */
9803         else if ((rhs->use) &&
9804                 (rhs->use->member == ins) && (rhs->use->next == 0)) {
9805                 int need_copy = 1;
9806                 /* Invert a boolean operation */
9807                 switch(rhs->op) {
9808                 case OP_LTRUE:   rhs->op = OP_LFALSE;  break;
9809                 case OP_LFALSE:  rhs->op = OP_LTRUE;   break;
9810                 case OP_EQ:      rhs->op = OP_NOTEQ;   break;
9811                 case OP_NOTEQ:   rhs->op = OP_EQ;      break;
9812                 case OP_SLESS:   rhs->op = OP_SMOREEQ; break;
9813                 case OP_ULESS:   rhs->op = OP_UMOREEQ; break;
9814                 case OP_SMORE:   rhs->op = OP_SLESSEQ; break;
9815                 case OP_UMORE:   rhs->op = OP_ULESSEQ; break;
9816                 case OP_SLESSEQ: rhs->op = OP_SMORE;   break;
9817                 case OP_ULESSEQ: rhs->op = OP_UMORE;   break;
9818                 case OP_SMOREEQ: rhs->op = OP_SLESS;   break;
9819                 case OP_UMOREEQ: rhs->op = OP_ULESS;   break;
9820                 default:
9821                         need_copy = 0;
9822                         break;
9823                 }
9824                 if (need_copy) {
9825                         mkcopy(state, ins, rhs);
9826                 }
9827         }
9828 }
9829
9830 static void simplify_ltrue (struct compile_state *state, struct triple *ins)
9831 {
9832         struct triple *rhs;
9833         rhs = RHS(ins, 0);
9834
9835         if (is_const(rhs)) {
9836                 mkconst(state, ins, const_ltrue(state, ins, rhs));
9837         }
9838         else switch(rhs->op) {
9839         case OP_LTRUE:   case OP_LFALSE:  case OP_EQ:      case OP_NOTEQ:
9840         case OP_SLESS:   case OP_ULESS:   case OP_SMORE:   case OP_UMORE:
9841         case OP_SLESSEQ: case OP_ULESSEQ: case OP_SMOREEQ: case OP_UMOREEQ:
9842                 mkcopy(state, ins, rhs);
9843         }
9844
9845 }
9846
9847 static void simplify_load(struct compile_state *state, struct triple *ins)
9848 {
9849         struct triple *addr, *sdecl, *blob;
9850
9851         /* If I am doing a load with a constant pointer from a constant
9852          * table get the value.
9853          */
9854         addr = RHS(ins, 0);
9855         if ((addr->op == OP_ADDRCONST) && (sdecl = MISC(addr, 0)) &&
9856                 (sdecl->op == OP_SDECL) && (blob = MISC(sdecl, 0)) &&
9857                 (blob->op == OP_BLOBCONST)) {
9858                 unsigned char buffer[SIZEOF_WORD];
9859                 size_t reg_size, mem_size;
9860                 const char *src, *end;
9861                 ulong_t val;
9862                 reg_size = reg_size_of(state, ins->type);
9863                 if (reg_size > REG_SIZEOF_REG) {
9864                         internal_error(state, ins, "load size greater than register");
9865                 }
9866                 mem_size = size_of(state, ins->type);
9867                 end = blob->u.blob;
9868                 end += bits_to_bytes(size_of(state, sdecl->type));
9869                 src = blob->u.blob;
9870                 src += addr->u.cval;
9871
9872                 if (src > end) {
9873                         /*
9874                          * The constant puts the load address out of bounds for
9875                          * the array.  However the load may be only conditionally
9876                          * called and it may never be called with this argument.
9877                          * So we can't error here because we don't know 
9878                          * if the load will actually be executed.  So instead
9879                          * simply avoid performing the the optimization.
9880                          */
9881                         return;
9882                 }
9883
9884                 memset(buffer, 0, sizeof(buffer));
9885                 memcpy(buffer, src, bits_to_bytes(mem_size));
9886
9887                 switch(mem_size) {
9888                 case SIZEOF_I8:  val = *((uint8_t *) buffer); break;
9889                 case SIZEOF_I16: val = *((uint16_t *)buffer); break;
9890                 case SIZEOF_I32: val = *((uint32_t *)buffer); break;
9891                 case SIZEOF_I64: val = *((uint64_t *)buffer); break;
9892                 default:
9893                         internal_error(state, ins, "mem_size: %d not handled",
9894                                 mem_size);
9895                         val = 0;
9896                         break;
9897                 }
9898                 mkconst(state, ins, val);
9899         }
9900 }
9901
9902 static void simplify_uextract(struct compile_state *state, struct triple *ins)
9903 {
9904         if (is_simple_const(RHS(ins, 0))) {
9905                 ulong_t val;
9906                 ulong_t mask;
9907                 val = read_const(state, ins, RHS(ins, 0));
9908                 mask = 1;
9909                 mask <<= ins->u.bitfield.size;
9910                 mask -= 1;
9911                 val >>= ins->u.bitfield.offset;
9912                 val &= mask;
9913                 mkconst(state, ins, val);
9914         }
9915 }
9916
9917 static void simplify_sextract(struct compile_state *state, struct triple *ins)
9918 {
9919         if (is_simple_const(RHS(ins, 0))) {
9920                 ulong_t val;
9921                 ulong_t mask;
9922                 long_t sval;
9923                 val = read_const(state, ins, RHS(ins, 0));
9924                 mask = 1;
9925                 mask <<= ins->u.bitfield.size;
9926                 mask -= 1;
9927                 val >>= ins->u.bitfield.offset;
9928                 val &= mask;
9929                 val <<= (SIZEOF_LONG - ins->u.bitfield.size);
9930                 sval = val;
9931                 sval >>= (SIZEOF_LONG - ins->u.bitfield.size); 
9932                 mkconst(state, ins, sval);
9933         }
9934 }
9935
9936 static void simplify_deposit(struct compile_state *state, struct triple *ins)
9937 {
9938         if (is_simple_const(RHS(ins, 0)) && is_simple_const(RHS(ins, 1))) {
9939                 ulong_t targ, val;
9940                 ulong_t mask;
9941                 targ = read_const(state, ins, RHS(ins, 0));
9942                 val  = read_const(state, ins, RHS(ins, 1));
9943                 mask = 1;
9944                 mask <<= ins->u.bitfield.size;
9945                 mask -= 1;
9946                 mask <<= ins->u.bitfield.offset;
9947                 targ &= ~mask;
9948                 val <<= ins->u.bitfield.offset;
9949                 val &= mask;
9950                 targ |= val;
9951                 mkconst(state, ins, targ);
9952         }
9953 }
9954
9955 static void simplify_copy(struct compile_state *state, struct triple *ins)
9956 {
9957         struct triple *right;
9958         right = RHS(ins, 0);
9959         if (is_subset_type(ins->type, right->type)) {
9960                 ins->type = right->type;
9961         }
9962         if (equiv_types(ins->type, right->type)) {
9963                 ins->op = OP_COPY;/* I don't need to convert if the types match */
9964         } else {
9965                 if (ins->op == OP_COPY) {
9966                         internal_error(state, ins, "type mismatch on copy");
9967                 }
9968         }
9969         if (is_const(right) && (right->op == OP_ADDRCONST) && is_pointer(ins)) {
9970                 struct triple *sdecl;
9971                 ulong_t offset;
9972                 sdecl  = MISC(right, 0);
9973                 offset = right->u.cval;
9974                 mkaddr_const(state, ins, sdecl, offset);
9975         }
9976         else if (is_const(right) && is_write_compatible(state, ins->type, right->type)) {
9977                 switch(right->op) {
9978                 case OP_INTCONST:
9979                 {
9980                         ulong_t left;
9981                         left = read_const(state, ins, right);
9982                         /* Ensure I have not overflowed the destination. */
9983                         if (size_of(state, right->type) > size_of(state, ins->type)) {
9984                                 ulong_t mask;
9985                                 mask = 1;
9986                                 mask <<= size_of(state, ins->type);
9987                                 mask -= 1;
9988                                 left &= mask;
9989                         }
9990                         /* Ensure I am properly sign extended */
9991                         if (size_of(state, right->type) < size_of(state, ins->type) &&
9992                                 is_signed(right->type)) {
9993                                 long_t val;
9994                                 int shift;
9995                                 shift = SIZEOF_LONG - size_of(state, right->type);
9996                                 val = left;
9997                                 val <<= shift;
9998                                 val >>= shift;
9999                                 left = val;
10000                         }
10001                         mkconst(state, ins, left);
10002                         break;
10003                 }
10004                 default:
10005                         internal_error(state, ins, "uknown constant");
10006                         break;
10007                 }
10008         }
10009 }
10010
10011 static int phi_present(struct block *block)
10012 {
10013         struct triple *ptr;
10014         if (!block) {
10015                 return 0;
10016         }
10017         ptr = block->first;
10018         do {
10019                 if (ptr->op == OP_PHI) {
10020                         return 1;
10021                 }
10022                 ptr = ptr->next;
10023         } while(ptr != block->last);
10024         return 0;
10025 }
10026
10027 static int phi_dependency(struct block *block)
10028 {
10029         /* A block has a phi dependency if a phi function
10030          * depends on that block to exist, and makes a block
10031          * that is otherwise useless unsafe to remove.
10032          */
10033         if (block) {
10034                 struct block_set *edge;
10035                 for(edge = block->edges; edge; edge = edge->next) {
10036                         if (phi_present(edge->member)) {
10037                                 return 1;
10038                         }
10039                 }
10040         }
10041         return 0;
10042 }
10043
10044 static struct triple *branch_target(struct compile_state *state, struct triple *ins)
10045 {
10046         struct triple *targ;
10047         targ = TARG(ins, 0);
10048         /* During scc_transform temporary triples are allocated that
10049          * loop back onto themselves. If I see one don't advance the
10050          * target.
10051          */
10052         while(triple_is_structural(state, targ) && 
10053                 (targ->next != targ) && (targ->next != state->first)) {
10054                 targ = targ->next;
10055         }
10056         return targ;
10057 }
10058
10059
10060 static void simplify_branch(struct compile_state *state, struct triple *ins)
10061 {
10062         int simplified, loops;
10063         if ((ins->op != OP_BRANCH) && (ins->op != OP_CBRANCH)) {
10064                 internal_error(state, ins, "not branch");
10065         }
10066         if (ins->use != 0) {
10067                 internal_error(state, ins, "branch use");
10068         }
10069         /* The challenge here with simplify branch is that I need to 
10070          * make modifications to the control flow graph as well
10071          * as to the branch instruction itself.  That is handled
10072          * by rebuilding the basic blocks after simplify all is called.
10073          */
10074
10075         /* If we have a branch to an unconditional branch update
10076          * our target.  But watch out for dependencies from phi
10077          * functions.
10078          * Also only do this a limited number of times so
10079          * we don't get into an infinite loop.
10080          */
10081         loops = 0;
10082         do {
10083                 struct triple *targ;
10084                 simplified = 0;
10085                 targ = branch_target(state, ins);
10086                 if ((targ != ins) && (targ->op == OP_BRANCH) && 
10087                         !phi_dependency(targ->u.block))
10088                 {
10089                         unuse_triple(TARG(ins, 0), ins);
10090                         TARG(ins, 0) = TARG(targ, 0);
10091                         use_triple(TARG(ins, 0), ins);
10092                         simplified = 1;
10093                 }
10094         } while(simplified && (++loops < 20));
10095
10096         /* If we have a conditional branch with a constant condition
10097          * make it an unconditional branch.
10098          */
10099         if ((ins->op == OP_CBRANCH) && is_simple_const(RHS(ins, 0))) {
10100                 struct triple *targ;
10101                 ulong_t value;
10102                 value = read_const(state, ins, RHS(ins, 0));
10103                 unuse_triple(RHS(ins, 0), ins);
10104                 targ = TARG(ins, 0);
10105                 ins->rhs  = 0;
10106                 ins->targ = 1;
10107                 ins->op = OP_BRANCH;
10108                 if (value) {
10109                         unuse_triple(ins->next, ins);
10110                         TARG(ins, 0) = targ;
10111                 }
10112                 else {
10113                         unuse_triple(targ, ins);
10114                         TARG(ins, 0) = ins->next;
10115                 }
10116         }
10117
10118         /* If we have a branch to the next instruction,
10119          * make it a noop.
10120          */
10121         if (TARG(ins, 0) == ins->next) {
10122                 unuse_triple(TARG(ins, 0), ins);
10123                 if (ins->op == OP_CBRANCH) {
10124                         unuse_triple(RHS(ins, 0), ins);
10125                         unuse_triple(ins->next, ins);
10126                 }
10127                 ins->lhs = 0;
10128                 ins->rhs = 0;
10129                 ins->misc = 0;
10130                 ins->targ = 0;
10131                 ins->op = OP_NOOP;
10132                 if (ins->use) {
10133                         internal_error(state, ins, "noop use != 0");
10134                 }
10135         }
10136 }
10137
10138 static void simplify_label(struct compile_state *state, struct triple *ins)
10139 {
10140         /* Ignore volatile labels */
10141         if (!triple_is_pure(state, ins, ins->id)) {
10142                 return;
10143         }
10144         if (ins->use == 0) {
10145                 ins->op = OP_NOOP;
10146         }
10147         else if (ins->prev->op == OP_LABEL) {
10148                 /* In general it is not safe to merge one label that
10149                  * imediately follows another.  The problem is that the empty
10150                  * looking block may have phi functions that depend on it.
10151                  */
10152                 if (!phi_dependency(ins->prev->u.block)) {
10153                         struct triple_set *user, *next;
10154                         ins->op = OP_NOOP;
10155                         for(user = ins->use; user; user = next) {
10156                                 struct triple *use, **expr;
10157                                 next = user->next;
10158                                 use = user->member;
10159                                 expr = triple_targ(state, use, 0);
10160                                 for(;expr; expr = triple_targ(state, use, expr)) {
10161                                         if (*expr == ins) {
10162                                                 *expr = ins->prev;
10163                                                 unuse_triple(ins, use);
10164                                                 use_triple(ins->prev, use);
10165                                         }
10166                                         
10167                                 }
10168                         }
10169                         if (ins->use) {
10170                                 internal_error(state, ins, "noop use != 0");
10171                         }
10172                 }
10173         }
10174 }
10175
10176 static void simplify_phi(struct compile_state *state, struct triple *ins)
10177 {
10178         struct triple **slot;
10179         struct triple *value;
10180         int zrhs, i;
10181         ulong_t cvalue;
10182         slot = &RHS(ins, 0);
10183         zrhs = ins->rhs;
10184         if (zrhs == 0) {
10185                 return;
10186         }
10187         /* See if all of the rhs members of a phi have the same value */
10188         if (slot[0] && is_simple_const(slot[0])) {
10189                 cvalue = read_const(state, ins, slot[0]);
10190                 for(i = 1; i < zrhs; i++) {
10191                         if (    !slot[i] ||
10192                                 !is_simple_const(slot[i]) ||
10193                                 !equiv_types(slot[0]->type, slot[i]->type) ||
10194                                 (cvalue != read_const(state, ins, slot[i]))) {
10195                                 break;
10196                         }
10197                 }
10198                 if (i == zrhs) {
10199                         mkconst(state, ins, cvalue);
10200                         return;
10201                 }
10202         }
10203         
10204         /* See if all of rhs members of a phi are the same */
10205         value = slot[0];
10206         for(i = 1; i < zrhs; i++) {
10207                 if (slot[i] != value) {
10208                         break;
10209                 }
10210         }
10211         if (i == zrhs) {
10212                 /* If the phi has a single value just copy it */
10213                 if (!is_subset_type(ins->type, value->type)) {
10214                         internal_error(state, ins, "bad input type to phi");
10215                 }
10216                 /* Make the types match */
10217                 if (!equiv_types(ins->type, value->type)) {
10218                         ins->type = value->type;
10219                 }
10220                 /* Now make the actual copy */
10221                 mkcopy(state, ins, value);
10222                 return;
10223         }
10224 }
10225
10226
10227 static void simplify_bsf(struct compile_state *state, struct triple *ins)
10228 {
10229         if (is_simple_const(RHS(ins, 0))) {
10230                 ulong_t left;
10231                 left = read_const(state, ins, RHS(ins, 0));
10232                 mkconst(state, ins, bsf(left));
10233         }
10234 }
10235
10236 static void simplify_bsr(struct compile_state *state, struct triple *ins)
10237 {
10238         if (is_simple_const(RHS(ins, 0))) {
10239                 ulong_t left;
10240                 left = read_const(state, ins, RHS(ins, 0));
10241                 mkconst(state, ins, bsr(left));
10242         }
10243 }
10244
10245
10246 typedef void (*simplify_t)(struct compile_state *state, struct triple *ins);
10247 static const struct simplify_table {
10248         simplify_t func;
10249         unsigned long flag;
10250 } table_simplify[] = {
10251 #define simplify_sdivt    simplify_noop
10252 #define simplify_udivt    simplify_noop
10253 #define simplify_piece    simplify_noop
10254
10255 [OP_SDIVT      ] = { simplify_sdivt,    COMPILER_SIMPLIFY_ARITH },
10256 [OP_UDIVT      ] = { simplify_udivt,    COMPILER_SIMPLIFY_ARITH },
10257 [OP_SMUL       ] = { simplify_smul,     COMPILER_SIMPLIFY_ARITH },
10258 [OP_UMUL       ] = { simplify_umul,     COMPILER_SIMPLIFY_ARITH },
10259 [OP_SDIV       ] = { simplify_sdiv,     COMPILER_SIMPLIFY_ARITH },
10260 [OP_UDIV       ] = { simplify_udiv,     COMPILER_SIMPLIFY_ARITH },
10261 [OP_SMOD       ] = { simplify_smod,     COMPILER_SIMPLIFY_ARITH },
10262 [OP_UMOD       ] = { simplify_umod,     COMPILER_SIMPLIFY_ARITH },
10263 [OP_ADD        ] = { simplify_add,      COMPILER_SIMPLIFY_ARITH },
10264 [OP_SUB        ] = { simplify_sub,      COMPILER_SIMPLIFY_ARITH },
10265 [OP_SL         ] = { simplify_sl,       COMPILER_SIMPLIFY_SHIFT },
10266 [OP_USR        ] = { simplify_usr,      COMPILER_SIMPLIFY_SHIFT },
10267 [OP_SSR        ] = { simplify_ssr,      COMPILER_SIMPLIFY_SHIFT },
10268 [OP_AND        ] = { simplify_and,      COMPILER_SIMPLIFY_BITWISE },
10269 [OP_XOR        ] = { simplify_xor,      COMPILER_SIMPLIFY_BITWISE },
10270 [OP_OR         ] = { simplify_or,       COMPILER_SIMPLIFY_BITWISE },
10271 [OP_POS        ] = { simplify_pos,      COMPILER_SIMPLIFY_ARITH },
10272 [OP_NEG        ] = { simplify_neg,      COMPILER_SIMPLIFY_ARITH },
10273 [OP_INVERT     ] = { simplify_invert,   COMPILER_SIMPLIFY_BITWISE },
10274
10275 [OP_EQ         ] = { simplify_eq,       COMPILER_SIMPLIFY_LOGICAL },
10276 [OP_NOTEQ      ] = { simplify_noteq,    COMPILER_SIMPLIFY_LOGICAL },
10277 [OP_SLESS      ] = { simplify_sless,    COMPILER_SIMPLIFY_LOGICAL },
10278 [OP_ULESS      ] = { simplify_uless,    COMPILER_SIMPLIFY_LOGICAL },
10279 [OP_SMORE      ] = { simplify_smore,    COMPILER_SIMPLIFY_LOGICAL },
10280 [OP_UMORE      ] = { simplify_umore,    COMPILER_SIMPLIFY_LOGICAL },
10281 [OP_SLESSEQ    ] = { simplify_slesseq,  COMPILER_SIMPLIFY_LOGICAL },
10282 [OP_ULESSEQ    ] = { simplify_ulesseq,  COMPILER_SIMPLIFY_LOGICAL },
10283 [OP_SMOREEQ    ] = { simplify_smoreeq,  COMPILER_SIMPLIFY_LOGICAL },
10284 [OP_UMOREEQ    ] = { simplify_umoreeq,  COMPILER_SIMPLIFY_LOGICAL },
10285 [OP_LFALSE     ] = { simplify_lfalse,   COMPILER_SIMPLIFY_LOGICAL },
10286 [OP_LTRUE      ] = { simplify_ltrue,    COMPILER_SIMPLIFY_LOGICAL },
10287
10288 [OP_LOAD       ] = { simplify_load,     COMPILER_SIMPLIFY_OP },
10289 [OP_STORE      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10290
10291 [OP_UEXTRACT   ] = { simplify_uextract, COMPILER_SIMPLIFY_BITFIELD },
10292 [OP_SEXTRACT   ] = { simplify_sextract, COMPILER_SIMPLIFY_BITFIELD },
10293 [OP_DEPOSIT    ] = { simplify_deposit,  COMPILER_SIMPLIFY_BITFIELD },
10294
10295 [OP_NOOP       ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10296
10297 [OP_INTCONST   ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10298 [OP_BLOBCONST  ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10299 [OP_ADDRCONST  ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10300 [OP_UNKNOWNVAL ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10301
10302 [OP_WRITE      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10303 [OP_READ       ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10304 [OP_COPY       ] = { simplify_copy,     COMPILER_SIMPLIFY_COPY },
10305 [OP_CONVERT    ] = { simplify_copy,     COMPILER_SIMPLIFY_COPY },
10306 [OP_PIECE      ] = { simplify_piece,    COMPILER_SIMPLIFY_OP },
10307 [OP_ASM        ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10308
10309 [OP_DOT        ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10310 [OP_INDEX      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10311
10312 [OP_LIST       ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10313 [OP_BRANCH     ] = { simplify_branch,   COMPILER_SIMPLIFY_BRANCH },
10314 [OP_CBRANCH    ] = { simplify_branch,   COMPILER_SIMPLIFY_BRANCH },
10315 [OP_CALL       ] = { simplify_noop,     COMPILER_SIMPLIFY_BRANCH },
10316 [OP_RET        ] = { simplify_noop,     COMPILER_SIMPLIFY_BRANCH },
10317 [OP_LABEL      ] = { simplify_label,    COMPILER_SIMPLIFY_LABEL },
10318 [OP_ADECL      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10319 [OP_SDECL      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10320 [OP_PHI        ] = { simplify_phi,      COMPILER_SIMPLIFY_PHI },
10321
10322 [OP_INB        ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10323 [OP_INW        ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10324 [OP_INL        ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10325 [OP_OUTB       ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10326 [OP_OUTW       ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10327 [OP_OUTL       ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10328 [OP_BSF        ] = { simplify_bsf,      COMPILER_SIMPLIFY_OP },
10329 [OP_BSR        ] = { simplify_bsr,      COMPILER_SIMPLIFY_OP },
10330 [OP_RDMSR      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10331 [OP_WRMSR      ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },               
10332 [OP_HLT        ] = { simplify_noop,     COMPILER_SIMPLIFY_OP },
10333 };
10334
10335 static inline void debug_simplify(struct compile_state *state, 
10336         simplify_t do_simplify, struct triple *ins)
10337 {
10338 #if DEBUG_SIMPLIFY_HIRES
10339                 if (state->functions_joined && (do_simplify != simplify_noop)) {
10340                         /* High resolution debugging mode */
10341                         fprintf(state->dbgout, "simplifing: ");
10342                         display_triple(state->dbgout, ins);
10343                 }
10344 #endif
10345                 do_simplify(state, ins);
10346 #if DEBUG_SIMPLIFY_HIRES
10347                 if (state->functions_joined && (do_simplify != simplify_noop)) {
10348                         /* High resolution debugging mode */
10349                         fprintf(state->dbgout, "simplified: ");
10350                         display_triple(state->dbgout, ins);
10351                 }
10352 #endif
10353 }
10354 static void simplify(struct compile_state *state, struct triple *ins)
10355 {
10356         int op;
10357         simplify_t do_simplify;
10358         if (ins == &unknown_triple) {
10359                 internal_error(state, ins, "simplifying the unknown triple?");
10360         }
10361         do {
10362                 op = ins->op;
10363                 do_simplify = 0;
10364                 if ((op < 0) || (op > sizeof(table_simplify)/sizeof(table_simplify[0]))) {
10365                         do_simplify = 0;
10366                 }
10367                 else {
10368                         do_simplify = table_simplify[op].func;
10369                 }
10370                 if (do_simplify && 
10371                         !(state->compiler->flags & table_simplify[op].flag)) {
10372                         do_simplify = simplify_noop;
10373                 }
10374                 if (do_simplify && (ins->id & TRIPLE_FLAG_VOLATILE)) {
10375                         do_simplify = simplify_noop;
10376                 }
10377         
10378                 if (!do_simplify) {
10379                         internal_error(state, ins, "cannot simplify op: %d %s",
10380                                 op, tops(op));
10381                         return;
10382                 }
10383                 debug_simplify(state, do_simplify, ins);
10384         } while(ins->op != op);
10385 }
10386
10387 static void rebuild_ssa_form(struct compile_state *state);
10388
10389 static void simplify_all(struct compile_state *state)
10390 {
10391         struct triple *ins, *first;
10392         if (!(state->compiler->flags & COMPILER_SIMPLIFY)) {
10393                 return;
10394         }
10395         first = state->first;
10396         ins = first->prev;
10397         do {
10398                 simplify(state, ins);
10399                 ins = ins->prev;
10400         } while(ins != first->prev);
10401         ins = first;
10402         do {
10403                 simplify(state, ins);
10404                 ins = ins->next;
10405         }while(ins != first);
10406         rebuild_ssa_form(state);
10407
10408         print_blocks(state, __func__, state->dbgout);
10409 }
10410
10411 /*
10412  * Builtins....
10413  * ============================
10414  */
10415
10416 static void register_builtin_function(struct compile_state *state,
10417         const char *name, int op, struct type *rtype, ...)
10418 {
10419         struct type *ftype, *atype, *ctype, *crtype, *param, **next;
10420         struct triple *def, *arg, *result, *work, *last, *first, *retvar, *ret;
10421         struct hash_entry *ident;
10422         struct file_state file;
10423         int parameters;
10424         int name_len;
10425         va_list args;
10426         int i;
10427
10428         /* Dummy file state to get debug handling right */
10429         memset(&file, 0, sizeof(file));
10430         file.basename = "<built-in>";
10431         file.line = 1;
10432         file.report_line = 1;
10433         file.report_name = file.basename;
10434         file.prev = state->file;
10435         state->file = &file;
10436         state->function = name;
10437
10438         /* Find the Parameter count */
10439         valid_op(state, op);
10440         parameters = table_ops[op].rhs;
10441         if (parameters < 0 ) {
10442                 internal_error(state, 0, "Invalid builtin parameter count");
10443         }
10444
10445         /* Find the function type */
10446         ftype = new_type(TYPE_FUNCTION | STOR_INLINE | STOR_STATIC, rtype, 0);
10447         ftype->elements = parameters;
10448         next = &ftype->right;
10449         va_start(args, rtype);
10450         for(i = 0; i < parameters; i++) {
10451                 atype = va_arg(args, struct type *);
10452                 if (!*next) {
10453                         *next = atype;
10454                 } else {
10455                         *next = new_type(TYPE_PRODUCT, *next, atype);
10456                         next = &((*next)->right);
10457                 }
10458         }
10459         if (!*next) {
10460                 *next = &void_type;
10461         }
10462         va_end(args);
10463
10464         /* Get the initial closure type */
10465         ctype = new_type(TYPE_JOIN, &void_type, 0);
10466         ctype->elements = 1;
10467
10468         /* Get the return type */
10469         crtype = new_type(TYPE_TUPLE, new_type(TYPE_PRODUCT, ctype, rtype), 0);
10470         crtype->elements = 2;
10471
10472         /* Generate the needed triples */
10473         def = triple(state, OP_LIST, ftype, 0, 0);
10474         first = label(state);
10475         RHS(def, 0) = first;
10476         result = flatten(state, first, variable(state, crtype));
10477         retvar = flatten(state, first, variable(state, &void_ptr_type));
10478         ret = triple(state, OP_RET, &void_type, read_expr(state, retvar), 0);
10479
10480         /* Now string them together */
10481         param = ftype->right;
10482         for(i = 0; i < parameters; i++) {
10483                 if ((param->type & TYPE_MASK) == TYPE_PRODUCT) {
10484                         atype = param->left;
10485                 } else {
10486                         atype = param;
10487                 }
10488                 arg = flatten(state, first, variable(state, atype));
10489                 param = param->right;
10490         }
10491         work = new_triple(state, op, rtype, -1, parameters);
10492         generate_lhs_pieces(state, work);
10493         for(i = 0; i < parameters; i++) {
10494                 RHS(work, i) = read_expr(state, farg(state, def, i));
10495         }
10496         if ((rtype->type & TYPE_MASK) != TYPE_VOID) {
10497                 work = write_expr(state, deref_index(state, result, 1), work);
10498         }
10499         work = flatten(state, first, work);
10500         last = flatten(state, first, label(state));
10501         ret  = flatten(state, first, ret);
10502         name_len = strlen(name);
10503         ident = lookup(state, name, name_len);
10504         ftype->type_ident = ident;
10505         symbol(state, ident, &ident->sym_ident, def, ftype);
10506         
10507         state->file = file.prev;
10508         state->function = 0;
10509         state->main_function = 0;
10510
10511         if (!state->functions) {
10512                 state->functions = def;
10513         } else {
10514                 insert_triple(state, state->functions, def);
10515         }
10516         if (state->compiler->debug & DEBUG_INLINE) {
10517                 FILE *fp = state->dbgout;
10518                 fprintf(fp, "\n");
10519                 loc(fp, state, 0);
10520                 fprintf(fp, "\n__________ %s _________\n", __FUNCTION__);
10521                 display_func(state, fp, def);
10522                 fprintf(fp, "__________ %s _________ done\n\n", __FUNCTION__);
10523         }
10524 }
10525
10526 static struct type *partial_struct(struct compile_state *state,
10527         const char *field_name, struct type *type, struct type *rest)
10528 {
10529         struct hash_entry *field_ident;
10530         struct type *result;
10531         int field_name_len;
10532
10533         field_name_len = strlen(field_name);
10534         field_ident = lookup(state, field_name, field_name_len);
10535
10536         result = clone_type(0, type);
10537         result->field_ident = field_ident;
10538
10539         if (rest) {
10540                 result = new_type(TYPE_PRODUCT, result, rest);
10541         }
10542         return result;
10543 }
10544
10545 static struct type *register_builtin_type(struct compile_state *state,
10546         const char *name, struct type *type)
10547 {
10548         struct hash_entry *ident;
10549         int name_len;
10550
10551         name_len = strlen(name);
10552         ident = lookup(state, name, name_len);
10553         
10554         if ((type->type & TYPE_MASK) == TYPE_PRODUCT) {
10555                 ulong_t elements = 0;
10556                 struct type *field;
10557                 type = new_type(TYPE_STRUCT, type, 0);
10558                 field = type->left;
10559                 while((field->type & TYPE_MASK) == TYPE_PRODUCT) {
10560                         elements++;
10561                         field = field->right;
10562                 }
10563                 elements++;
10564                 symbol(state, ident, &ident->sym_tag, 0, type);
10565                 type->type_ident = ident;
10566                 type->elements = elements;
10567         }
10568         symbol(state, ident, &ident->sym_ident, 0, type);
10569         ident->tok = TOK_TYPE_NAME;
10570         return type;
10571 }
10572
10573
10574 static void register_builtins(struct compile_state *state)
10575 {
10576         struct type *div_type, *ldiv_type;
10577         struct type *udiv_type, *uldiv_type;
10578         struct type *msr_type;
10579
10580         div_type = register_builtin_type(state, "__builtin_div_t",
10581                 partial_struct(state, "quot", &int_type,
10582                 partial_struct(state, "rem",  &int_type, 0)));
10583         ldiv_type = register_builtin_type(state, "__builtin_ldiv_t",
10584                 partial_struct(state, "quot", &long_type,
10585                 partial_struct(state, "rem",  &long_type, 0)));
10586         udiv_type = register_builtin_type(state, "__builtin_udiv_t",
10587                 partial_struct(state, "quot", &uint_type,
10588                 partial_struct(state, "rem",  &uint_type, 0)));
10589         uldiv_type = register_builtin_type(state, "__builtin_uldiv_t",
10590                 partial_struct(state, "quot", &ulong_type,
10591                 partial_struct(state, "rem",  &ulong_type, 0)));
10592
10593         register_builtin_function(state, "__builtin_div",   OP_SDIVT, div_type,
10594                 &int_type, &int_type);
10595         register_builtin_function(state, "__builtin_ldiv",  OP_SDIVT, ldiv_type,
10596                 &long_type, &long_type);
10597         register_builtin_function(state, "__builtin_udiv",  OP_UDIVT, udiv_type,
10598                 &uint_type, &uint_type);
10599         register_builtin_function(state, "__builtin_uldiv", OP_UDIVT, uldiv_type,
10600                 &ulong_type, &ulong_type);
10601
10602         register_builtin_function(state, "__builtin_inb", OP_INB, &uchar_type, 
10603                 &ushort_type);
10604         register_builtin_function(state, "__builtin_inw", OP_INW, &ushort_type,
10605                 &ushort_type);
10606         register_builtin_function(state, "__builtin_inl", OP_INL, &uint_type,   
10607                 &ushort_type);
10608
10609         register_builtin_function(state, "__builtin_outb", OP_OUTB, &void_type, 
10610                 &uchar_type, &ushort_type);
10611         register_builtin_function(state, "__builtin_outw", OP_OUTW, &void_type, 
10612                 &ushort_type, &ushort_type);
10613         register_builtin_function(state, "__builtin_outl", OP_OUTL, &void_type, 
10614                 &uint_type, &ushort_type);
10615         
10616         register_builtin_function(state, "__builtin_bsf", OP_BSF, &int_type, 
10617                 &int_type);
10618         register_builtin_function(state, "__builtin_bsr", OP_BSR, &int_type, 
10619                 &int_type);
10620
10621         msr_type = register_builtin_type(state, "__builtin_msr_t",
10622                 partial_struct(state, "lo", &ulong_type,
10623                 partial_struct(state, "hi", &ulong_type, 0)));
10624
10625         register_builtin_function(state, "__builtin_rdmsr", OP_RDMSR, msr_type,
10626                 &ulong_type);
10627         register_builtin_function(state, "__builtin_wrmsr", OP_WRMSR, &void_type,
10628                 &ulong_type, &ulong_type, &ulong_type);
10629         
10630         register_builtin_function(state, "__builtin_hlt", OP_HLT, &void_type, 
10631                 &void_type);
10632 }
10633
10634 static struct type *declarator(
10635         struct compile_state *state, struct type *type, 
10636         struct hash_entry **ident, int need_ident);
10637 static void decl(struct compile_state *state, struct triple *first);
10638 static struct type *specifier_qualifier_list(struct compile_state *state);
10639 static int isdecl_specifier(int tok);
10640 static struct type *decl_specifiers(struct compile_state *state);
10641 static int istype(int tok);
10642 static struct triple *expr(struct compile_state *state);
10643 static struct triple *assignment_expr(struct compile_state *state);
10644 static struct type *type_name(struct compile_state *state);
10645 static void statement(struct compile_state *state, struct triple *first);
10646
10647 static struct triple *call_expr(
10648         struct compile_state *state, struct triple *func)
10649 {
10650         struct triple *def;
10651         struct type *param, *type;
10652         ulong_t pvals, index;
10653
10654         if ((func->type->type & TYPE_MASK) != TYPE_FUNCTION) {
10655                 error(state, 0, "Called object is not a function");
10656         }
10657         if (func->op != OP_LIST) {
10658                 internal_error(state, 0, "improper function");
10659         }
10660         eat(state, TOK_LPAREN);
10661         /* Find the return type without any specifiers */
10662         type = clone_type(0, func->type->left);
10663         /* Count the number of rhs entries for OP_FCALL */
10664         param = func->type->right;
10665         pvals = 0;
10666         while((param->type & TYPE_MASK) == TYPE_PRODUCT) {
10667                 pvals++;
10668                 param = param->right;
10669         }
10670         if ((param->type & TYPE_MASK) != TYPE_VOID) {
10671                 pvals++;
10672         }
10673         def = new_triple(state, OP_FCALL, type, -1, pvals);
10674         MISC(def, 0) = func;
10675
10676         param = func->type->right;
10677         for(index = 0; index < pvals; index++) {
10678                 struct triple *val;
10679                 struct type *arg_type;
10680                 val = read_expr(state, assignment_expr(state));
10681                 arg_type = param;
10682                 if ((param->type & TYPE_MASK) == TYPE_PRODUCT) {
10683                         arg_type = param->left;
10684                 }
10685                 write_compatible(state, arg_type, val->type);
10686                 RHS(def, index) = val;
10687                 if (index != (pvals - 1)) {
10688                         eat(state, TOK_COMMA);
10689                         param = param->right;
10690                 }
10691         }
10692         eat(state, TOK_RPAREN);
10693         return def;
10694 }
10695
10696
10697 static struct triple *character_constant(struct compile_state *state)
10698 {
10699         struct triple *def;
10700         struct token *tk;
10701         const signed char *str, *end;
10702         int c;
10703         int str_len;
10704         tk = eat(state, TOK_LIT_CHAR);
10705         str = tk->val.str + 1;
10706         str_len = tk->str_len - 2;
10707         if (str_len <= 0) {
10708                 error(state, 0, "empty character constant");
10709         }
10710         end = str + str_len;
10711         c = char_value(state, &str, end);
10712         if (str != end) {
10713                 error(state, 0, "multibyte character constant not supported");
10714         }
10715         def = int_const(state, &char_type, (ulong_t)((long_t)c));
10716         return def;
10717 }
10718
10719 static struct triple *string_constant(struct compile_state *state)
10720 {
10721         struct triple *def;
10722         struct token *tk;
10723         struct type *type;
10724         const signed char *str, *end;
10725         signed char *buf, *ptr;
10726         int str_len;
10727
10728         buf = 0;
10729         type = new_type(TYPE_ARRAY, &char_type, 0);
10730         type->elements = 0;
10731         /* The while loop handles string concatenation */
10732         do {
10733                 tk = eat(state, TOK_LIT_STRING);
10734                 str = tk->val.str + 1;
10735                 str_len = tk->str_len - 2;
10736                 if (str_len < 0) {
10737                         error(state, 0, "negative string constant length");
10738                 }
10739                 end = str + str_len;
10740                 ptr = buf;
10741                 buf = xmalloc(type->elements + str_len + 1, "string_constant");
10742                 memcpy(buf, ptr, type->elements);
10743                 ptr = buf + type->elements;
10744                 do {
10745                         *ptr++ = char_value(state, &str, end);
10746                 } while(str < end);
10747                 type->elements = ptr - buf;
10748         } while(peek(state) == TOK_LIT_STRING);
10749         *ptr = '\0';
10750         type->elements += 1;
10751         def = triple(state, OP_BLOBCONST, type, 0, 0);
10752         def->u.blob = buf;
10753
10754         return def;
10755 }
10756
10757
10758 static struct triple *integer_constant(struct compile_state *state)
10759 {
10760         struct triple *def;
10761         unsigned long val;
10762         struct token *tk;
10763         char *end;
10764         int u, l, decimal;
10765         struct type *type;
10766
10767         tk = eat(state, TOK_LIT_INT);
10768         errno = 0;
10769         decimal = (tk->val.str[0] != '0');
10770         val = strtoul(tk->val.str, &end, 0);
10771         if ((val > ULONG_T_MAX) || ((val == ULONG_MAX) && (errno == ERANGE))) {
10772                 error(state, 0, "Integer constant to large");
10773         }
10774         u = l = 0;
10775         if ((*end == 'u') || (*end == 'U')) {
10776                 u = 1;
10777                         end++;
10778         }
10779         if ((*end == 'l') || (*end == 'L')) {
10780                 l = 1;
10781                 end++;
10782         }
10783         if ((*end == 'u') || (*end == 'U')) {
10784                 u = 1;
10785                 end++;
10786         }
10787         if (*end) {
10788                 error(state, 0, "Junk at end of integer constant");
10789         }
10790         if (u && l)  {
10791                 type = &ulong_type;
10792         }
10793         else if (l) {
10794                 type = &long_type;
10795                 if (!decimal && (val > LONG_T_MAX)) {
10796                         type = &ulong_type;
10797                 }
10798         }
10799         else if (u) {
10800                 type = &uint_type;
10801                 if (val > UINT_T_MAX) {
10802                         type = &ulong_type;
10803                 }
10804         }
10805         else {
10806                 type = &int_type;
10807                 if (!decimal && (val > INT_T_MAX) && (val <= UINT_T_MAX)) {
10808                         type = &uint_type;
10809                 }
10810                 else if (!decimal && (val > LONG_T_MAX)) {
10811                         type = &ulong_type;
10812                 }
10813                 else if (val > INT_T_MAX) {
10814                         type = &long_type;
10815                 }
10816         }
10817         def = int_const(state, type, val);
10818         return def;
10819 }
10820
10821 static struct triple *primary_expr(struct compile_state *state)
10822 {
10823         struct triple *def;
10824         int tok;
10825         tok = peek(state);
10826         switch(tok) {
10827         case TOK_IDENT:
10828         {
10829                 struct hash_entry *ident;
10830                 /* Here ident is either:
10831                  * a varable name
10832                  * a function name
10833                  */
10834                 ident = eat(state, TOK_IDENT)->ident;
10835                 if (!ident->sym_ident) {
10836                         error(state, 0, "%s undeclared", ident->name);
10837                 }
10838                 def = ident->sym_ident->def;
10839                 break;
10840         }
10841         case TOK_ENUM_CONST:
10842         {
10843                 struct hash_entry *ident;
10844                 /* Here ident is an enumeration constant */
10845                 ident = eat(state, TOK_ENUM_CONST)->ident;
10846                 if (!ident->sym_ident) {
10847                         error(state, 0, "%s undeclared", ident->name);
10848                 }
10849                 def = ident->sym_ident->def;
10850                 break;
10851         }
10852         case TOK_MIDENT:
10853         {
10854                 struct hash_entry *ident;
10855                 ident = eat(state, TOK_MIDENT)->ident;
10856                 warning(state, 0, "Replacing undefined macro: %s with 0",
10857                         ident->name);
10858                 def = int_const(state, &int_type, 0);
10859                 break;
10860         }
10861         case TOK_LPAREN:
10862                 eat(state, TOK_LPAREN);
10863                 def = expr(state);
10864                 eat(state, TOK_RPAREN);
10865                 break;
10866         case TOK_LIT_INT:
10867                 def = integer_constant(state);
10868                 break;
10869         case TOK_LIT_FLOAT:
10870                 eat(state, TOK_LIT_FLOAT);
10871                 error(state, 0, "Floating point constants not supported");
10872                 def = 0;
10873                 FINISHME();
10874                 break;
10875         case TOK_LIT_CHAR:
10876                 def = character_constant(state);
10877                 break;
10878         case TOK_LIT_STRING:
10879                 def = string_constant(state);
10880                 break;
10881         default:
10882                 def = 0;
10883                 error(state, 0, "Unexpected token: %s\n", tokens[tok]);
10884         }
10885         return def;
10886 }
10887
10888 static struct triple *postfix_expr(struct compile_state *state)
10889 {
10890         struct triple *def;
10891         int postfix;
10892         def = primary_expr(state);
10893         do {
10894                 struct triple *left;
10895                 int tok;
10896                 postfix = 1;
10897                 left = def;
10898                 switch((tok = peek(state))) {
10899                 case TOK_LBRACKET:
10900                         eat(state, TOK_LBRACKET);
10901                         def = mk_subscript_expr(state, left, expr(state));
10902                         eat(state, TOK_RBRACKET);
10903                         break;
10904                 case TOK_LPAREN:
10905                         def = call_expr(state, def);
10906                         break;
10907                 case TOK_DOT:
10908                 {
10909                         struct hash_entry *field;
10910                         eat(state, TOK_DOT);
10911                         field = eat(state, TOK_IDENT)->ident;
10912                         def = deref_field(state, def, field);
10913                         break;
10914                 }
10915                 case TOK_ARROW:
10916                 {
10917                         struct hash_entry *field;
10918                         eat(state, TOK_ARROW);
10919                         field = eat(state, TOK_IDENT)->ident;
10920                         def = mk_deref_expr(state, read_expr(state, def));
10921                         def = deref_field(state, def, field);
10922                         break;
10923                 }
10924                 case TOK_PLUSPLUS:
10925                         eat(state, TOK_PLUSPLUS);
10926                         def = mk_post_inc_expr(state, left);
10927                         break;
10928                 case TOK_MINUSMINUS:
10929                         eat(state, TOK_MINUSMINUS);
10930                         def = mk_post_dec_expr(state, left);
10931                         break;
10932                 default:
10933                         postfix = 0;
10934                         break;
10935                 }
10936         } while(postfix);
10937         return def;
10938 }
10939
10940 static struct triple *cast_expr(struct compile_state *state);
10941
10942 static struct triple *unary_expr(struct compile_state *state)
10943 {
10944         struct triple *def, *right;
10945         int tok;
10946         switch((tok = peek(state))) {
10947         case TOK_PLUSPLUS:
10948                 eat(state, TOK_PLUSPLUS);
10949                 def = mk_pre_inc_expr(state, unary_expr(state));
10950                 break;
10951         case TOK_MINUSMINUS:
10952                 eat(state, TOK_MINUSMINUS);
10953                 def = mk_pre_dec_expr(state, unary_expr(state));
10954                 break;
10955         case TOK_AND:
10956                 eat(state, TOK_AND);
10957                 def = mk_addr_expr(state, cast_expr(state), 0);
10958                 break;
10959         case TOK_STAR:
10960                 eat(state, TOK_STAR);
10961                 def = mk_deref_expr(state, read_expr(state, cast_expr(state)));
10962                 break;
10963         case TOK_PLUS:
10964                 eat(state, TOK_PLUS);
10965                 right = read_expr(state, cast_expr(state));
10966                 arithmetic(state, right);
10967                 def = integral_promotion(state, right);
10968                 break;
10969         case TOK_MINUS:
10970                 eat(state, TOK_MINUS);
10971                 right = read_expr(state, cast_expr(state));
10972                 arithmetic(state, right);
10973                 def = integral_promotion(state, right);
10974                 def = triple(state, OP_NEG, def->type, def, 0);
10975                 break;
10976         case TOK_TILDE:
10977                 eat(state, TOK_TILDE);
10978                 right = read_expr(state, cast_expr(state));
10979                 integral(state, right);
10980                 def = integral_promotion(state, right);
10981                 def = triple(state, OP_INVERT, def->type, def, 0);
10982                 break;
10983         case TOK_BANG:
10984                 eat(state, TOK_BANG);
10985                 right = read_expr(state, cast_expr(state));
10986                 bool(state, right);
10987                 def = lfalse_expr(state, right);
10988                 break;
10989         case TOK_SIZEOF:
10990         {
10991                 struct type *type;
10992                 int tok1, tok2;
10993                 eat(state, TOK_SIZEOF);
10994                 tok1 = peek(state);
10995                 tok2 = peek2(state);
10996                 if ((tok1 == TOK_LPAREN) && istype(tok2)) {
10997                         eat(state, TOK_LPAREN);
10998                         type = type_name(state);
10999                         eat(state, TOK_RPAREN);
11000                 }
11001                 else {
11002                         struct triple *expr;
11003                         expr = unary_expr(state);
11004                         type = expr->type;
11005                         release_expr(state, expr);
11006                 }
11007                 def = int_const(state, &ulong_type, size_of_in_bytes(state, type));
11008                 break;
11009         }
11010         case TOK_ALIGNOF:
11011         {
11012                 struct type *type;
11013                 int tok1, tok2;
11014                 eat(state, TOK_ALIGNOF);
11015                 tok1 = peek(state);
11016                 tok2 = peek2(state);
11017                 if ((tok1 == TOK_LPAREN) && istype(tok2)) {
11018                         eat(state, TOK_LPAREN);
11019                         type = type_name(state);
11020                         eat(state, TOK_RPAREN);
11021                 }
11022                 else {
11023                         struct triple *expr;
11024                         expr = unary_expr(state);
11025                         type = expr->type;
11026                         release_expr(state, expr);
11027                 }
11028                 def = int_const(state, &ulong_type, align_of_in_bytes(state, type));
11029                 break;
11030         }
11031         case TOK_MDEFINED:
11032         {
11033                 /* We only come here if we are called from the preprocessor */
11034                 struct hash_entry *ident;
11035                 int parens;
11036                 eat(state, TOK_MDEFINED);
11037                 parens = 0;
11038                 if (pp_peek(state) == TOK_LPAREN) {
11039                         pp_eat(state, TOK_LPAREN);
11040                         parens = 1;
11041                 }
11042                 ident = pp_eat(state, TOK_MIDENT)->ident;
11043                 if (parens) {
11044                         eat(state, TOK_RPAREN);
11045                 }
11046                 def = int_const(state, &int_type, ident->sym_define != 0);
11047                 break;
11048         }
11049         default:
11050                 def = postfix_expr(state);
11051                 break;
11052         }
11053         return def;
11054 }
11055
11056 static struct triple *cast_expr(struct compile_state *state)
11057 {
11058         struct triple *def;
11059         int tok1, tok2;
11060         tok1 = peek(state);
11061         tok2 = peek2(state);
11062         if ((tok1 == TOK_LPAREN) && istype(tok2)) {
11063                 struct type *type;
11064                 eat(state, TOK_LPAREN);
11065                 type = type_name(state);
11066                 eat(state, TOK_RPAREN);
11067                 def = mk_cast_expr(state, type, cast_expr(state));
11068         }
11069         else {
11070                 def = unary_expr(state);
11071         }
11072         return def;
11073 }
11074
11075 static struct triple *mult_expr(struct compile_state *state)
11076 {
11077         struct triple *def;
11078         int done;
11079         def = cast_expr(state);
11080         do {
11081                 struct triple *left, *right;
11082                 struct type *result_type;
11083                 int tok, op, sign;
11084                 done = 0;
11085                 tok = peek(state);
11086                 switch(tok) {
11087                 case TOK_STAR:
11088                 case TOK_DIV:
11089                 case TOK_MOD:
11090                         left = read_expr(state, def);
11091                         arithmetic(state, left);
11092
11093                         eat(state, tok);
11094
11095                         right = read_expr(state, cast_expr(state));
11096                         arithmetic(state, right);
11097
11098                         result_type = arithmetic_result(state, left, right);
11099                         sign = is_signed(result_type);
11100                         op = -1;
11101                         switch(tok) {
11102                         case TOK_STAR: op = sign? OP_SMUL : OP_UMUL; break;
11103                         case TOK_DIV:  op = sign? OP_SDIV : OP_UDIV; break;
11104                         case TOK_MOD:  op = sign? OP_SMOD : OP_UMOD; break;
11105                         }
11106                         def = triple(state, op, result_type, left, right);
11107                         break;
11108                 default:
11109                         done = 1;
11110                         break;
11111                 }
11112         } while(!done);
11113         return def;
11114 }
11115
11116 static struct triple *add_expr(struct compile_state *state)
11117 {
11118         struct triple *def;
11119         int done;
11120         def = mult_expr(state);
11121         do {
11122                 done = 0;
11123                 switch( peek(state)) {
11124                 case TOK_PLUS:
11125                         eat(state, TOK_PLUS);
11126                         def = mk_add_expr(state, def, mult_expr(state));
11127                         break;
11128                 case TOK_MINUS:
11129                         eat(state, TOK_MINUS);
11130                         def = mk_sub_expr(state, def, mult_expr(state));
11131                         break;
11132                 default:
11133                         done = 1;
11134                         break;
11135                 }
11136         } while(!done);
11137         return def;
11138 }
11139
11140 static struct triple *shift_expr(struct compile_state *state)
11141 {
11142         struct triple *def;
11143         int done;
11144         def = add_expr(state);
11145         do {
11146                 struct triple *left, *right;
11147                 int tok, op;
11148                 done = 0;
11149                 switch((tok = peek(state))) {
11150                 case TOK_SL:
11151                 case TOK_SR:
11152                         left = read_expr(state, def);
11153                         integral(state, left);
11154                         left = integral_promotion(state, left);
11155
11156                         eat(state, tok);
11157
11158                         right = read_expr(state, add_expr(state));
11159                         integral(state, right);
11160                         right = integral_promotion(state, right);
11161                         
11162                         op = (tok == TOK_SL)? OP_SL : 
11163                                 is_signed(left->type)? OP_SSR: OP_USR;
11164
11165                         def = triple(state, op, left->type, left, right);
11166                         break;
11167                 default:
11168                         done = 1;
11169                         break;
11170                 }
11171         } while(!done);
11172         return def;
11173 }
11174
11175 static struct triple *relational_expr(struct compile_state *state)
11176 {
11177 #warning "Extend relational exprs to work on more than arithmetic types"
11178         struct triple *def;
11179         int done;
11180         def = shift_expr(state);
11181         do {
11182                 struct triple *left, *right;
11183                 struct type *arg_type;
11184                 int tok, op, sign;
11185                 done = 0;
11186                 switch((tok = peek(state))) {
11187                 case TOK_LESS:
11188                 case TOK_MORE:
11189                 case TOK_LESSEQ:
11190                 case TOK_MOREEQ:
11191                         left = read_expr(state, def);
11192                         arithmetic(state, left);
11193
11194                         eat(state, tok);
11195
11196                         right = read_expr(state, shift_expr(state));
11197                         arithmetic(state, right);
11198
11199                         arg_type = arithmetic_result(state, left, right);
11200                         sign = is_signed(arg_type);
11201                         op = -1;
11202                         switch(tok) {
11203                         case TOK_LESS:   op = sign? OP_SLESS : OP_ULESS; break;
11204                         case TOK_MORE:   op = sign? OP_SMORE : OP_UMORE; break;
11205                         case TOK_LESSEQ: op = sign? OP_SLESSEQ : OP_ULESSEQ; break;
11206                         case TOK_MOREEQ: op = sign? OP_SMOREEQ : OP_UMOREEQ; break;
11207                         }
11208                         def = triple(state, op, &int_type, left, right);
11209                         break;
11210                 default:
11211                         done = 1;
11212                         break;
11213                 }
11214         } while(!done);
11215         return def;
11216 }
11217
11218 static struct triple *equality_expr(struct compile_state *state)
11219 {
11220 #warning "Extend equality exprs to work on more than arithmetic types"
11221         struct triple *def;
11222         int done;
11223         def = relational_expr(state);
11224         do {
11225                 struct triple *left, *right;
11226                 int tok, op;
11227                 done = 0;
11228                 switch((tok = peek(state))) {
11229                 case TOK_EQEQ:
11230                 case TOK_NOTEQ:
11231                         left = read_expr(state, def);
11232                         arithmetic(state, left);
11233                         eat(state, tok);
11234                         right = read_expr(state, relational_expr(state));
11235                         arithmetic(state, right);
11236                         op = (tok == TOK_EQEQ) ? OP_EQ: OP_NOTEQ;
11237                         def = triple(state, op, &int_type, left, right);
11238                         break;
11239                 default:
11240                         done = 1;
11241                         break;
11242                 }
11243         } while(!done);
11244         return def;
11245 }
11246
11247 static struct triple *and_expr(struct compile_state *state)
11248 {
11249         struct triple *def;
11250         def = equality_expr(state);
11251         while(peek(state) == TOK_AND) {
11252                 struct triple *left, *right;
11253                 struct type *result_type;
11254                 left = read_expr(state, def);
11255                 integral(state, left);
11256                 eat(state, TOK_AND);
11257                 right = read_expr(state, equality_expr(state));
11258                 integral(state, right);
11259                 result_type = arithmetic_result(state, left, right);
11260                 def = triple(state, OP_AND, result_type, left, right);
11261         }
11262         return def;
11263 }
11264
11265 static struct triple *xor_expr(struct compile_state *state)
11266 {
11267         struct triple *def;
11268         def = and_expr(state);
11269         while(peek(state) == TOK_XOR) {
11270                 struct triple *left, *right;
11271                 struct type *result_type;
11272                 left = read_expr(state, def);
11273                 integral(state, left);
11274                 eat(state, TOK_XOR);
11275                 right = read_expr(state, and_expr(state));
11276                 integral(state, right);
11277                 result_type = arithmetic_result(state, left, right);
11278                 def = triple(state, OP_XOR, result_type, left, right);
11279         }
11280         return def;
11281 }
11282
11283 static struct triple *or_expr(struct compile_state *state)
11284 {
11285         struct triple *def;
11286         def = xor_expr(state);
11287         while(peek(state) == TOK_OR) {
11288                 struct triple *left, *right;
11289                 struct type *result_type;
11290                 left = read_expr(state, def);
11291                 integral(state, left);
11292                 eat(state, TOK_OR);
11293                 right = read_expr(state, xor_expr(state));
11294                 integral(state, right);
11295                 result_type = arithmetic_result(state, left, right);
11296                 def = triple(state, OP_OR, result_type, left, right);
11297         }
11298         return def;
11299 }
11300
11301 static struct triple *land_expr(struct compile_state *state)
11302 {
11303         struct triple *def;
11304         def = or_expr(state);
11305         while(peek(state) == TOK_LOGAND) {
11306                 struct triple *left, *right;
11307                 left = read_expr(state, def);
11308                 bool(state, left);
11309                 eat(state, TOK_LOGAND);
11310                 right = read_expr(state, or_expr(state));
11311                 bool(state, right);
11312
11313                 def = mkland_expr(state,
11314                         ltrue_expr(state, left),
11315                         ltrue_expr(state, right));
11316         }
11317         return def;
11318 }
11319
11320 static struct triple *lor_expr(struct compile_state *state)
11321 {
11322         struct triple *def;
11323         def = land_expr(state);
11324         while(peek(state) == TOK_LOGOR) {
11325                 struct triple *left, *right;
11326                 left = read_expr(state, def);
11327                 bool(state, left);
11328                 eat(state, TOK_LOGOR);
11329                 right = read_expr(state, land_expr(state));
11330                 bool(state, right);
11331
11332                 def = mklor_expr(state, 
11333                         ltrue_expr(state, left),
11334                         ltrue_expr(state, right));
11335         }
11336         return def;
11337 }
11338
11339 static struct triple *conditional_expr(struct compile_state *state)
11340 {
11341         struct triple *def;
11342         def = lor_expr(state);
11343         if (peek(state) == TOK_QUEST) {
11344                 struct triple *test, *left, *right;
11345                 bool(state, def);
11346                 test = ltrue_expr(state, read_expr(state, def));
11347                 eat(state, TOK_QUEST);
11348                 left = read_expr(state, expr(state));
11349                 eat(state, TOK_COLON);
11350                 right = read_expr(state, conditional_expr(state));
11351
11352                 def = mkcond_expr(state, test, left, right);
11353         }
11354         return def;
11355 }
11356
11357 struct cv_triple {
11358         struct triple *val;
11359         int id;
11360 };
11361
11362 static void set_cv(struct compile_state *state, struct cv_triple *cv,
11363         struct triple *dest, struct triple *val)
11364 {
11365         if (cv[dest->id].val) {
11366                 free_triple(state, cv[dest->id].val);
11367         }
11368         cv[dest->id].val = val;
11369 }
11370 static struct triple *get_cv(struct compile_state *state, struct cv_triple *cv,
11371         struct triple *src)
11372 {
11373         return cv[src->id].val;
11374 }
11375
11376 static struct triple *eval_const_expr(
11377         struct compile_state *state, struct triple *expr)
11378 {
11379         struct triple *def;
11380         if (is_const(expr)) {
11381                 def = expr;
11382         }
11383         else {
11384                 /* If we don't start out as a constant simplify into one */
11385                 struct triple *head, *ptr;
11386                 struct cv_triple *cv;
11387                 int i, count;
11388                 head = label(state); /* dummy initial triple */
11389                 flatten(state, head, expr);
11390                 count = 1;
11391                 for(ptr = head->next; ptr != head; ptr = ptr->next) {
11392                         count++;
11393                 }
11394                 cv = xcmalloc(sizeof(struct cv_triple)*count, "const value vector");
11395                 i = 1;
11396                 for(ptr = head->next; ptr != head; ptr = ptr->next) {
11397                         cv[i].val = 0;
11398                         cv[i].id  = ptr->id;
11399                         ptr->id   = i;
11400                         i++;
11401                 }
11402                 ptr = head->next;
11403                 do {
11404                         valid_ins(state, ptr);
11405                         if ((ptr->op == OP_PHI) || (ptr->op == OP_LIST)) {
11406                                 internal_error(state, ptr, 
11407                                         "unexpected %s in constant expression",
11408                                         tops(ptr->op));
11409                         }
11410                         else if (ptr->op == OP_LIST) {
11411                         }
11412                         else if (triple_is_structural(state, ptr)) {
11413                                 ptr = ptr->next;
11414                         }
11415                         else if (triple_is_ubranch(state, ptr)) {
11416                                 ptr = TARG(ptr, 0);
11417                         }
11418                         else if (triple_is_cbranch(state, ptr)) {
11419                                 struct triple *cond_val;
11420                                 cond_val = get_cv(state, cv, RHS(ptr, 0));
11421                                 if (!cond_val || !is_const(cond_val) || 
11422                                         (cond_val->op != OP_INTCONST)) 
11423                                 {
11424                                         internal_error(state, ptr, "bad branch condition");
11425                                 }
11426                                 if (cond_val->u.cval == 0) {
11427                                         ptr = ptr->next;
11428                                 } else {
11429                                         ptr = TARG(ptr, 0);
11430                                 }
11431                         }
11432                         else if (triple_is_branch(state, ptr)) {
11433                                 error(state, ptr, "bad branch type in constant expression");
11434                         }
11435                         else if (ptr->op == OP_WRITE) {
11436                                 struct triple *val;
11437                                 val = get_cv(state, cv, RHS(ptr, 0));
11438                                 
11439                                 set_cv(state, cv, MISC(ptr, 0), 
11440                                         copy_triple(state, val));
11441                                 set_cv(state, cv, ptr, 
11442                                         copy_triple(state, val));
11443                                 ptr = ptr->next;
11444                         }
11445                         else if (ptr->op == OP_READ) {
11446                                 set_cv(state, cv, ptr, 
11447                                         copy_triple(state, 
11448                                                 get_cv(state, cv, RHS(ptr, 0))));
11449                                 ptr = ptr->next;
11450                         }
11451                         else if (triple_is_pure(state, ptr, cv[ptr->id].id)) {
11452                                 struct triple *val, **rhs;
11453                                 val = copy_triple(state, ptr);
11454                                 rhs = triple_rhs(state, val, 0);
11455                                 for(; rhs; rhs = triple_rhs(state, val, rhs)) {
11456                                         if (!*rhs) {
11457                                                 internal_error(state, ptr, "Missing rhs");
11458                                         }
11459                                         *rhs = get_cv(state, cv, *rhs);
11460                                 }
11461                                 simplify(state, val);
11462                                 set_cv(state, cv, ptr, val);
11463                                 ptr = ptr->next;
11464                         }
11465                         else {
11466                                 error(state, ptr, "impure operation in constant expression");
11467                         }
11468                         
11469                 } while(ptr != head);
11470
11471                 /* Get the result value */
11472                 def = get_cv(state, cv, head->prev);
11473                 cv[head->prev->id].val = 0;
11474
11475                 /* Free the temporary values */
11476                 for(i = 0; i < count; i++) {
11477                         if (cv[i].val) {
11478                                 free_triple(state, cv[i].val);
11479                                 cv[i].val = 0;
11480                         }
11481                 }
11482                 xfree(cv);
11483                 /* Free the intermediate expressions */
11484                 while(head->next != head) {
11485                         release_triple(state, head->next);
11486                 }
11487                 free_triple(state, head);
11488         }
11489         if (!is_const(def)) {
11490                 error(state, expr, "Not a constant expression");
11491         }
11492         return def;
11493 }
11494
11495 static struct triple *constant_expr(struct compile_state *state)
11496 {
11497         return eval_const_expr(state, conditional_expr(state));
11498 }
11499
11500 static struct triple *assignment_expr(struct compile_state *state)
11501 {
11502         struct triple *def, *left, *right;
11503         int tok, op, sign;
11504         /* The C grammer in K&R shows assignment expressions
11505          * only taking unary expressions as input on their
11506          * left hand side.  But specifies the precedence of
11507          * assignemnt as the lowest operator except for comma.
11508          *
11509          * Allowing conditional expressions on the left hand side
11510          * of an assignement results in a grammar that accepts
11511          * a larger set of statements than standard C.   As long
11512          * as the subset of the grammar that is standard C behaves
11513          * correctly this should cause no problems.
11514          * 
11515          * For the extra token strings accepted by the grammar
11516          * none of them should produce a valid lvalue, so they
11517          * should not produce functioning programs.
11518          *
11519          * GCC has this bug as well, so surprises should be minimal.
11520          */
11521         def = conditional_expr(state);
11522         left = def;
11523         switch((tok = peek(state))) {
11524         case TOK_EQ:
11525                 lvalue(state, left);
11526                 eat(state, TOK_EQ);
11527                 def = write_expr(state, left, 
11528                         read_expr(state, assignment_expr(state)));
11529                 break;
11530         case TOK_TIMESEQ:
11531         case TOK_DIVEQ:
11532         case TOK_MODEQ:
11533                 lvalue(state, left);
11534                 arithmetic(state, left);
11535                 eat(state, tok);
11536                 right = read_expr(state, assignment_expr(state));
11537                 arithmetic(state, right);
11538
11539                 sign = is_signed(left->type);
11540                 op = -1;
11541                 switch(tok) {
11542                 case TOK_TIMESEQ: op = sign? OP_SMUL : OP_UMUL; break;
11543                 case TOK_DIVEQ:   op = sign? OP_SDIV : OP_UDIV; break;
11544                 case TOK_MODEQ:   op = sign? OP_SMOD : OP_UMOD; break;
11545                 }
11546                 def = write_expr(state, left,
11547                         triple(state, op, left->type, 
11548                                 read_expr(state, left), right));
11549                 break;
11550         case TOK_PLUSEQ:
11551                 lvalue(state, left);
11552                 eat(state, TOK_PLUSEQ);
11553                 def = write_expr(state, left,
11554                         mk_add_expr(state, left, assignment_expr(state)));
11555                 break;
11556         case TOK_MINUSEQ:
11557                 lvalue(state, left);
11558                 eat(state, TOK_MINUSEQ);
11559                 def = write_expr(state, left,
11560                         mk_sub_expr(state, left, assignment_expr(state)));
11561                 break;
11562         case TOK_SLEQ:
11563         case TOK_SREQ:
11564         case TOK_ANDEQ:
11565         case TOK_XOREQ:
11566         case TOK_OREQ:
11567                 lvalue(state, left);
11568                 integral(state, left);
11569                 eat(state, tok);
11570                 right = read_expr(state, assignment_expr(state));
11571                 integral(state, right);
11572                 right = integral_promotion(state, right);
11573                 sign = is_signed(left->type);
11574                 op = -1;
11575                 switch(tok) {
11576                 case TOK_SLEQ:  op = OP_SL; break;
11577                 case TOK_SREQ:  op = sign? OP_SSR: OP_USR; break;
11578                 case TOK_ANDEQ: op = OP_AND; break;
11579                 case TOK_XOREQ: op = OP_XOR; break;
11580                 case TOK_OREQ:  op = OP_OR; break;
11581                 }
11582                 def = write_expr(state, left,
11583                         triple(state, op, left->type, 
11584                                 read_expr(state, left), right));
11585                 break;
11586         }
11587         return def;
11588 }
11589
11590 static struct triple *expr(struct compile_state *state)
11591 {
11592         struct triple *def;
11593         def = assignment_expr(state);
11594         while(peek(state) == TOK_COMMA) {
11595                 eat(state, TOK_COMMA);
11596                 def = mkprog(state, def, assignment_expr(state), 0);
11597         }
11598         return def;
11599 }
11600
11601 static void expr_statement(struct compile_state *state, struct triple *first)
11602 {
11603         if (peek(state) != TOK_SEMI) {
11604                 /* lvalue conversions always apply except when certian operators
11605                  * are applied.  I apply the lvalue conversions here
11606                  * as I know no more operators will be applied.
11607                  */
11608                 flatten(state, first, lvalue_conversion(state, expr(state)));
11609         }
11610         eat(state, TOK_SEMI);
11611 }
11612
11613 static void if_statement(struct compile_state *state, struct triple *first)
11614 {
11615         struct triple *test, *jmp1, *jmp2, *middle, *end;
11616
11617         jmp1 = jmp2 = middle = 0;
11618         eat(state, TOK_IF);
11619         eat(state, TOK_LPAREN);
11620         test = expr(state);
11621         bool(state, test);
11622         /* Cleanup and invert the test */
11623         test = lfalse_expr(state, read_expr(state, test));
11624         eat(state, TOK_RPAREN);
11625         /* Generate the needed pieces */
11626         middle = label(state);
11627         jmp1 = branch(state, middle, test);
11628         /* Thread the pieces together */
11629         flatten(state, first, test);
11630         flatten(state, first, jmp1);
11631         flatten(state, first, label(state));
11632         statement(state, first);
11633         if (peek(state) == TOK_ELSE) {
11634                 eat(state, TOK_ELSE);
11635                 /* Generate the rest of the pieces */
11636                 end = label(state);
11637                 jmp2 = branch(state, end, 0);
11638                 /* Thread them together */
11639                 flatten(state, first, jmp2);
11640                 flatten(state, first, middle);
11641                 statement(state, first);
11642                 flatten(state, first, end);
11643         }
11644         else {
11645                 flatten(state, first, middle);
11646         }
11647 }
11648
11649 static void for_statement(struct compile_state *state, struct triple *first)
11650 {
11651         struct triple *head, *test, *tail, *jmp1, *jmp2, *end;
11652         struct triple *label1, *label2, *label3;
11653         struct hash_entry *ident;
11654
11655         eat(state, TOK_FOR);
11656         eat(state, TOK_LPAREN);
11657         head = test = tail = jmp1 = jmp2 = 0;
11658         if (peek(state) != TOK_SEMI) {
11659                 head = expr(state);
11660         } 
11661         eat(state, TOK_SEMI);
11662         if (peek(state) != TOK_SEMI) {
11663                 test = expr(state);
11664                 bool(state, test);
11665                 test = ltrue_expr(state, read_expr(state, test));
11666         }
11667         eat(state, TOK_SEMI);
11668         if (peek(state) != TOK_RPAREN) {
11669                 tail = expr(state);
11670         }
11671         eat(state, TOK_RPAREN);
11672         /* Generate the needed pieces */
11673         label1 = label(state);
11674         label2 = label(state);
11675         label3 = label(state);
11676         if (test) {
11677                 jmp1 = branch(state, label3, 0);
11678                 jmp2 = branch(state, label1, test);
11679         }
11680         else {
11681                 jmp2 = branch(state, label1, 0);
11682         }
11683         end = label(state);
11684         /* Remember where break and continue go */
11685         start_scope(state);
11686         ident = state->i_break;
11687         symbol(state, ident, &ident->sym_ident, end, end->type);
11688         ident = state->i_continue;
11689         symbol(state, ident, &ident->sym_ident, label2, label2->type);
11690         /* Now include the body */
11691         flatten(state, first, head);
11692         flatten(state, first, jmp1);
11693         flatten(state, first, label1);
11694         statement(state, first);
11695         flatten(state, first, label2);
11696         flatten(state, first, tail);
11697         flatten(state, first, label3);
11698         flatten(state, first, test);
11699         flatten(state, first, jmp2);
11700         flatten(state, first, end);
11701         /* Cleanup the break/continue scope */
11702         end_scope(state);
11703 }
11704
11705 static void while_statement(struct compile_state *state, struct triple *first)
11706 {
11707         struct triple *label1, *test, *label2, *jmp1, *jmp2, *end;
11708         struct hash_entry *ident;
11709         eat(state, TOK_WHILE);
11710         eat(state, TOK_LPAREN);
11711         test = expr(state);
11712         bool(state, test);
11713         test = ltrue_expr(state, read_expr(state, test));
11714         eat(state, TOK_RPAREN);
11715         /* Generate the needed pieces */
11716         label1 = label(state);
11717         label2 = label(state);
11718         jmp1 = branch(state, label2, 0);
11719         jmp2 = branch(state, label1, test);
11720         end = label(state);
11721         /* Remember where break and continue go */
11722         start_scope(state);
11723         ident = state->i_break;
11724         symbol(state, ident, &ident->sym_ident, end, end->type);
11725         ident = state->i_continue;
11726         symbol(state, ident, &ident->sym_ident, label2, label2->type);
11727         /* Thread them together */
11728         flatten(state, first, jmp1);
11729         flatten(state, first, label1);
11730         statement(state, first);
11731         flatten(state, first, label2);
11732         flatten(state, first, test);
11733         flatten(state, first, jmp2);
11734         flatten(state, first, end);
11735         /* Cleanup the break/continue scope */
11736         end_scope(state);
11737 }
11738
11739 static void do_statement(struct compile_state *state, struct triple *first)
11740 {
11741         struct triple *label1, *label2, *test, *end;
11742         struct hash_entry *ident;
11743         eat(state, TOK_DO);
11744         /* Generate the needed pieces */
11745         label1 = label(state);
11746         label2 = label(state);
11747         end = label(state);
11748         /* Remember where break and continue go */
11749         start_scope(state);
11750         ident = state->i_break;
11751         symbol(state, ident, &ident->sym_ident, end, end->type);
11752         ident = state->i_continue;
11753         symbol(state, ident, &ident->sym_ident, label2, label2->type);
11754         /* Now include the body */
11755         flatten(state, first, label1);
11756         statement(state, first);
11757         /* Cleanup the break/continue scope */
11758         end_scope(state);
11759         /* Eat the rest of the loop */
11760         eat(state, TOK_WHILE);
11761         eat(state, TOK_LPAREN);
11762         test = read_expr(state, expr(state));
11763         bool(state, test);
11764         eat(state, TOK_RPAREN);
11765         eat(state, TOK_SEMI);
11766         /* Thread the pieces together */
11767         test = ltrue_expr(state, test);
11768         flatten(state, first, label2);
11769         flatten(state, first, test);
11770         flatten(state, first, branch(state, label1, test));
11771         flatten(state, first, end);
11772 }
11773
11774
11775 static void return_statement(struct compile_state *state, struct triple *first)
11776 {
11777         struct triple *jmp, *mv, *dest, *var, *val;
11778         int last;
11779         eat(state, TOK_RETURN);
11780
11781 #warning "FIXME implement a more general excess branch elimination"
11782         val = 0;
11783         /* If we have a return value do some more work */
11784         if (peek(state) != TOK_SEMI) {
11785                 val = read_expr(state, expr(state));
11786         }
11787         eat(state, TOK_SEMI);
11788
11789         /* See if this last statement in a function */
11790         last = ((peek(state) == TOK_RBRACE) && 
11791                 (state->scope_depth == GLOBAL_SCOPE_DEPTH +2));
11792
11793         /* Find the return variable */
11794         var = fresult(state, state->main_function);
11795
11796         /* Find the return destination */
11797         dest = state->i_return->sym_ident->def;
11798         mv = jmp = 0;
11799         /* If needed generate a jump instruction */
11800         if (!last) {
11801                 jmp = branch(state, dest, 0);
11802         }
11803         /* If needed generate an assignment instruction */
11804         if (val) {
11805                 mv = write_expr(state, deref_index(state, var, 1), val);
11806         }
11807         /* Now put the code together */
11808         if (mv) {
11809                 flatten(state, first, mv);
11810                 flatten(state, first, jmp);
11811         }
11812         else if (jmp) {
11813                 flatten(state, first, jmp);
11814         }
11815 }
11816
11817 static void break_statement(struct compile_state *state, struct triple *first)
11818 {
11819         struct triple *dest;
11820         eat(state, TOK_BREAK);
11821         eat(state, TOK_SEMI);
11822         if (!state->i_break->sym_ident) {
11823                 error(state, 0, "break statement not within loop or switch");
11824         }
11825         dest = state->i_break->sym_ident->def;
11826         flatten(state, first, branch(state, dest, 0));
11827 }
11828
11829 static void continue_statement(struct compile_state *state, struct triple *first)
11830 {
11831         struct triple *dest;
11832         eat(state, TOK_CONTINUE);
11833         eat(state, TOK_SEMI);
11834         if (!state->i_continue->sym_ident) {
11835                 error(state, 0, "continue statement outside of a loop");
11836         }
11837         dest = state->i_continue->sym_ident->def;
11838         flatten(state, first, branch(state, dest, 0));
11839 }
11840
11841 static void goto_statement(struct compile_state *state, struct triple *first)
11842 {
11843         struct hash_entry *ident;
11844         eat(state, TOK_GOTO);
11845         ident = eat(state, TOK_IDENT)->ident;
11846         if (!ident->sym_label) {
11847                 /* If this is a forward branch allocate the label now,
11848                  * it will be flattend in the appropriate location later.
11849                  */
11850                 struct triple *ins;
11851                 ins = label(state);
11852                 label_symbol(state, ident, ins, FUNCTION_SCOPE_DEPTH);
11853         }
11854         eat(state, TOK_SEMI);
11855
11856         flatten(state, first, branch(state, ident->sym_label->def, 0));
11857 }
11858
11859 static void labeled_statement(struct compile_state *state, struct triple *first)
11860 {
11861         struct triple *ins;
11862         struct hash_entry *ident;
11863
11864         ident = eat(state, TOK_IDENT)->ident;
11865         if (ident->sym_label && ident->sym_label->def) {
11866                 ins = ident->sym_label->def;
11867                 put_occurance(ins->occurance);
11868                 ins->occurance = new_occurance(state);
11869         }
11870         else {
11871                 ins = label(state);
11872                 label_symbol(state, ident, ins, FUNCTION_SCOPE_DEPTH);
11873         }
11874         if (ins->id & TRIPLE_FLAG_FLATTENED) {
11875                 error(state, 0, "label %s already defined", ident->name);
11876         }
11877         flatten(state, first, ins);
11878
11879         eat(state, TOK_COLON);
11880         statement(state, first);
11881 }
11882
11883 static void switch_statement(struct compile_state *state, struct triple *first)
11884 {
11885         struct triple *value, *top, *end, *dbranch;
11886         struct hash_entry *ident;
11887
11888         /* See if we have a valid switch statement */
11889         eat(state, TOK_SWITCH);
11890         eat(state, TOK_LPAREN);
11891         value = expr(state);
11892         integral(state, value);
11893         value = read_expr(state, value);
11894         eat(state, TOK_RPAREN);
11895         /* Generate the needed pieces */
11896         top = label(state);
11897         end = label(state);
11898         dbranch = branch(state, end, 0);
11899         /* Remember where case branches and break goes */
11900         start_scope(state);
11901         ident = state->i_switch;
11902         symbol(state, ident, &ident->sym_ident, value, value->type);
11903         ident = state->i_case;
11904         symbol(state, ident, &ident->sym_ident, top, top->type);
11905         ident = state->i_break;
11906         symbol(state, ident, &ident->sym_ident, end, end->type);
11907         ident = state->i_default;
11908         symbol(state, ident, &ident->sym_ident, dbranch, dbranch->type);
11909         /* Thread them together */
11910         flatten(state, first, value);
11911         flatten(state, first, top);
11912         flatten(state, first, dbranch);
11913         statement(state, first);
11914         flatten(state, first, end);
11915         /* Cleanup the switch scope */
11916         end_scope(state);
11917 }
11918
11919 static void case_statement(struct compile_state *state, struct triple *first)
11920 {
11921         struct triple *cvalue, *dest, *test, *jmp;
11922         struct triple *ptr, *value, *top, *dbranch;
11923
11924         /* See if w have a valid case statement */
11925         eat(state, TOK_CASE);
11926         cvalue = constant_expr(state);
11927         integral(state, cvalue);
11928         if (cvalue->op != OP_INTCONST) {
11929                 error(state, 0, "integer constant expected");
11930         }
11931         eat(state, TOK_COLON);
11932         if (!state->i_case->sym_ident) {
11933                 error(state, 0, "case statement not within a switch");
11934         }
11935
11936         /* Lookup the interesting pieces */
11937         top = state->i_case->sym_ident->def;
11938         value = state->i_switch->sym_ident->def;
11939         dbranch = state->i_default->sym_ident->def;
11940
11941         /* See if this case label has already been used */
11942         for(ptr = top; ptr != dbranch; ptr = ptr->next) {
11943                 if (ptr->op != OP_EQ) {
11944                         continue;
11945                 }
11946                 if (RHS(ptr, 1)->u.cval == cvalue->u.cval) {
11947                         error(state, 0, "duplicate case %d statement",
11948                                 cvalue->u.cval);
11949                 }
11950         }
11951         /* Generate the needed pieces */
11952         dest = label(state);
11953         test = triple(state, OP_EQ, &int_type, value, cvalue);
11954         jmp = branch(state, dest, test);
11955         /* Thread the pieces together */
11956         flatten(state, dbranch, test);
11957         flatten(state, dbranch, jmp);
11958         flatten(state, dbranch, label(state));
11959         flatten(state, first, dest);
11960         statement(state, first);
11961 }
11962
11963 static void default_statement(struct compile_state *state, struct triple *first)
11964 {
11965         struct triple *dest;
11966         struct triple *dbranch, *end;
11967
11968         /* See if we have a valid default statement */
11969         eat(state, TOK_DEFAULT);
11970         eat(state, TOK_COLON);
11971
11972         if (!state->i_case->sym_ident) {
11973                 error(state, 0, "default statement not within a switch");
11974         }
11975
11976         /* Lookup the interesting pieces */
11977         dbranch = state->i_default->sym_ident->def;
11978         end = state->i_break->sym_ident->def;
11979
11980         /* See if a default statement has already happened */
11981         if (TARG(dbranch, 0) != end) {
11982                 error(state, 0, "duplicate default statement");
11983         }
11984
11985         /* Generate the needed pieces */
11986         dest = label(state);
11987
11988         /* Blame the branch on the default statement */
11989         put_occurance(dbranch->occurance);
11990         dbranch->occurance = new_occurance(state);
11991
11992         /* Thread the pieces together */
11993         TARG(dbranch, 0) = dest;
11994         use_triple(dest, dbranch);
11995         flatten(state, first, dest);
11996         statement(state, first);
11997 }
11998
11999 static void asm_statement(struct compile_state *state, struct triple *first)
12000 {
12001         struct asm_info *info;
12002         struct {
12003                 struct triple *constraint;
12004                 struct triple *expr;
12005         } out_param[MAX_LHS], in_param[MAX_RHS], clob_param[MAX_LHS];
12006         struct triple *def, *asm_str;
12007         int out, in, clobbers, more, colons, i;
12008         int flags;
12009
12010         flags = 0;
12011         eat(state, TOK_ASM);
12012         /* For now ignore the qualifiers */
12013         switch(peek(state)) {
12014         case TOK_CONST:
12015                 eat(state, TOK_CONST);
12016                 break;
12017         case TOK_VOLATILE:
12018                 eat(state, TOK_VOLATILE);
12019                 flags |= TRIPLE_FLAG_VOLATILE;
12020                 break;
12021         }
12022         eat(state, TOK_LPAREN);
12023         asm_str = string_constant(state);
12024
12025         colons = 0;
12026         out = in = clobbers = 0;
12027         /* Outputs */
12028         if ((colons == 0) && (peek(state) == TOK_COLON)) {
12029                 eat(state, TOK_COLON);
12030                 colons++;
12031                 more = (peek(state) == TOK_LIT_STRING);
12032                 while(more) {
12033                         struct triple *var;
12034                         struct triple *constraint;
12035                         char *str;
12036                         more = 0;
12037                         if (out > MAX_LHS) {
12038                                 error(state, 0, "Maximum output count exceeded.");
12039                         }
12040                         constraint = string_constant(state);
12041                         str = constraint->u.blob;
12042                         if (str[0] != '=') {
12043                                 error(state, 0, "Output constraint does not start with =");
12044                         }
12045                         constraint->u.blob = str + 1;
12046                         eat(state, TOK_LPAREN);
12047                         var = conditional_expr(state);
12048                         eat(state, TOK_RPAREN);
12049
12050                         lvalue(state, var);
12051                         out_param[out].constraint = constraint;
12052                         out_param[out].expr       = var;
12053                         if (peek(state) == TOK_COMMA) {
12054                                 eat(state, TOK_COMMA);
12055                                 more = 1;
12056                         }
12057                         out++;
12058                 }
12059         }
12060         /* Inputs */
12061         if ((colons == 1) && (peek(state) == TOK_COLON)) {
12062                 eat(state, TOK_COLON);
12063                 colons++;
12064                 more = (peek(state) == TOK_LIT_STRING);
12065                 while(more) {
12066                         struct triple *val;
12067                         struct triple *constraint;
12068                         char *str;
12069                         more = 0;
12070                         if (in > MAX_RHS) {
12071                                 error(state, 0, "Maximum input count exceeded.");
12072                         }
12073                         constraint = string_constant(state);
12074                         str = constraint->u.blob;
12075                         if (digitp(str[0] && str[1] == '\0')) {
12076                                 int val;
12077                                 val = digval(str[0]);
12078                                 if ((val < 0) || (val >= out)) {
12079                                         error(state, 0, "Invalid input constraint %d", val);
12080                                 }
12081                         }
12082                         eat(state, TOK_LPAREN);
12083                         val = conditional_expr(state);
12084                         eat(state, TOK_RPAREN);
12085
12086                         in_param[in].constraint = constraint;
12087                         in_param[in].expr       = val;
12088                         if (peek(state) == TOK_COMMA) {
12089                                 eat(state, TOK_COMMA);
12090                                 more = 1;
12091                         }
12092                         in++;
12093                 }
12094         }
12095
12096         /* Clobber */
12097         if ((colons == 2) && (peek(state) == TOK_COLON)) {
12098                 eat(state, TOK_COLON);
12099                 colons++;
12100                 more = (peek(state) == TOK_LIT_STRING);
12101                 while(more) {
12102                         struct triple *clobber;
12103                         more = 0;
12104                         if ((clobbers + out) > MAX_LHS) {
12105                                 error(state, 0, "Maximum clobber limit exceeded.");
12106                         }
12107                         clobber = string_constant(state);
12108
12109                         clob_param[clobbers].constraint = clobber;
12110                         if (peek(state) == TOK_COMMA) {
12111                                 eat(state, TOK_COMMA);
12112                                 more = 1;
12113                         }
12114                         clobbers++;
12115                 }
12116         }
12117         eat(state, TOK_RPAREN);
12118         eat(state, TOK_SEMI);
12119
12120
12121         info = xcmalloc(sizeof(*info), "asm_info");
12122         info->str = asm_str->u.blob;
12123         free_triple(state, asm_str);
12124
12125         def = new_triple(state, OP_ASM, &void_type, clobbers + out, in);
12126         def->u.ainfo = info;
12127         def->id |= flags;
12128
12129         /* Find the register constraints */
12130         for(i = 0; i < out; i++) {
12131                 struct triple *constraint;
12132                 constraint = out_param[i].constraint;
12133                 info->tmpl.lhs[i] = arch_reg_constraint(state, 
12134                         out_param[i].expr->type, constraint->u.blob);
12135                 free_triple(state, constraint);
12136         }
12137         for(; i - out < clobbers; i++) {
12138                 struct triple *constraint;
12139                 constraint = clob_param[i - out].constraint;
12140                 info->tmpl.lhs[i] = arch_reg_clobber(state, constraint->u.blob);
12141                 free_triple(state, constraint);
12142         }
12143         for(i = 0; i < in; i++) {
12144                 struct triple *constraint;
12145                 const char *str;
12146                 constraint = in_param[i].constraint;
12147                 str = constraint->u.blob;
12148                 if (digitp(str[0]) && str[1] == '\0') {
12149                         struct reg_info cinfo;
12150                         int val;
12151                         val = digval(str[0]);
12152                         cinfo.reg = info->tmpl.lhs[val].reg;
12153                         cinfo.regcm = arch_type_to_regcm(state, in_param[i].expr->type);
12154                         cinfo.regcm &= info->tmpl.lhs[val].regcm;
12155                         if (cinfo.reg == REG_UNSET) {
12156                                 cinfo.reg = REG_VIRT0 + val;
12157                         }
12158                         if (cinfo.regcm == 0) {
12159                                 error(state, 0, "No registers for %d", val);
12160                         }
12161                         info->tmpl.lhs[val] = cinfo;
12162                         info->tmpl.rhs[i]   = cinfo;
12163                                 
12164                 } else {
12165                         info->tmpl.rhs[i] = arch_reg_constraint(state, 
12166                                 in_param[i].expr->type, str);
12167                 }
12168                 free_triple(state, constraint);
12169         }
12170
12171         /* Now build the helper expressions */
12172         for(i = 0; i < in; i++) {
12173                 RHS(def, i) = read_expr(state, in_param[i].expr);
12174         }
12175         flatten(state, first, def);
12176         for(i = 0; i < (out + clobbers); i++) {
12177                 struct type *type;
12178                 struct triple *piece;
12179                 if (i < out) {
12180                         type = out_param[i].expr->type;
12181                 } else {
12182                         size_t size = arch_reg_size(info->tmpl.lhs[i].reg);
12183                         if (size >= SIZEOF_LONG) {
12184                                 type = &ulong_type;
12185                         } 
12186                         else if (size >= SIZEOF_INT) {
12187                                 type = &uint_type;
12188                         }
12189                         else if (size >= SIZEOF_SHORT) {
12190                                 type = &ushort_type;
12191                         }
12192                         else {
12193                                 type = &uchar_type;
12194                         }
12195                 }
12196                 piece = triple(state, OP_PIECE, type, def, 0);
12197                 piece->u.cval = i;
12198                 LHS(def, i) = piece;
12199                 flatten(state, first, piece);
12200         }
12201         /* And write the helpers to their destinations */
12202         for(i = 0; i < out; i++) {
12203                 struct triple *piece;
12204                 piece = LHS(def, i);
12205                 flatten(state, first,
12206                         write_expr(state, out_param[i].expr, piece));
12207         }
12208 }
12209
12210
12211 static int isdecl(int tok)
12212 {
12213         switch(tok) {
12214         case TOK_AUTO:
12215         case TOK_REGISTER:
12216         case TOK_STATIC:
12217         case TOK_EXTERN:
12218         case TOK_TYPEDEF:
12219         case TOK_CONST:
12220         case TOK_RESTRICT:
12221         case TOK_VOLATILE:
12222         case TOK_VOID:
12223         case TOK_CHAR:
12224         case TOK_SHORT:
12225         case TOK_INT:
12226         case TOK_LONG:
12227         case TOK_FLOAT:
12228         case TOK_DOUBLE:
12229         case TOK_SIGNED:
12230         case TOK_UNSIGNED:
12231         case TOK_STRUCT:
12232         case TOK_UNION:
12233         case TOK_ENUM:
12234         case TOK_TYPE_NAME: /* typedef name */
12235                 return 1;
12236         default:
12237                 return 0;
12238         }
12239 }
12240
12241 static void compound_statement(struct compile_state *state, struct triple *first)
12242 {
12243         eat(state, TOK_LBRACE);
12244         start_scope(state);
12245
12246         /* statement-list opt */
12247         while (peek(state) != TOK_RBRACE) {
12248                 statement(state, first);
12249         }
12250         end_scope(state);
12251         eat(state, TOK_RBRACE);
12252 }
12253
12254 static void statement(struct compile_state *state, struct triple *first)
12255 {
12256         int tok;
12257         tok = peek(state);
12258         if (tok == TOK_LBRACE) {
12259                 compound_statement(state, first);
12260         }
12261         else if (tok == TOK_IF) {
12262                 if_statement(state, first); 
12263         }
12264         else if (tok == TOK_FOR) {
12265                 for_statement(state, first);
12266         }
12267         else if (tok == TOK_WHILE) {
12268                 while_statement(state, first);
12269         }
12270         else if (tok == TOK_DO) {
12271                 do_statement(state, first);
12272         }
12273         else if (tok == TOK_RETURN) {
12274                 return_statement(state, first);
12275         }
12276         else if (tok == TOK_BREAK) {
12277                 break_statement(state, first);
12278         }
12279         else if (tok == TOK_CONTINUE) {
12280                 continue_statement(state, first);
12281         }
12282         else if (tok == TOK_GOTO) {
12283                 goto_statement(state, first);
12284         }
12285         else if (tok == TOK_SWITCH) {
12286                 switch_statement(state, first);
12287         }
12288         else if (tok == TOK_ASM) {
12289                 asm_statement(state, first);
12290         }
12291         else if ((tok == TOK_IDENT) && (peek2(state) == TOK_COLON)) {
12292                 labeled_statement(state, first); 
12293         }
12294         else if (tok == TOK_CASE) {
12295                 case_statement(state, first);
12296         }
12297         else if (tok == TOK_DEFAULT) {
12298                 default_statement(state, first);
12299         }
12300         else if (isdecl(tok)) {
12301                 /* This handles C99 intermixing of statements and decls */
12302                 decl(state, first);
12303         }
12304         else {
12305                 expr_statement(state, first);
12306         }
12307 }
12308
12309 static struct type *param_decl(struct compile_state *state)
12310 {
12311         struct type *type;
12312         struct hash_entry *ident;
12313         /* Cheat so the declarator will know we are not global */
12314         start_scope(state); 
12315         ident = 0;
12316         type = decl_specifiers(state);
12317         type = declarator(state, type, &ident, 0);
12318         type->field_ident = ident;
12319         end_scope(state);
12320         return type;
12321 }
12322
12323 static struct type *param_type_list(struct compile_state *state, struct type *type)
12324 {
12325         struct type *ftype, **next;
12326         ftype = new_type(TYPE_FUNCTION | (type->type & STOR_MASK), type, param_decl(state));
12327         next = &ftype->right;
12328         ftype->elements = 1;
12329         while(peek(state) == TOK_COMMA) {
12330                 eat(state, TOK_COMMA);
12331                 if (peek(state) == TOK_DOTS) {
12332                         eat(state, TOK_DOTS);
12333                         error(state, 0, "variadic functions not supported");
12334                 }
12335                 else {
12336                         *next = new_type(TYPE_PRODUCT, *next, param_decl(state));
12337                         next = &((*next)->right);
12338                         ftype->elements++;
12339                 }
12340         }
12341         return ftype;
12342 }
12343
12344 static struct type *type_name(struct compile_state *state)
12345 {
12346         struct type *type;
12347         type = specifier_qualifier_list(state);
12348         /* abstract-declarator (may consume no tokens) */
12349         type = declarator(state, type, 0, 0);
12350         return type;
12351 }
12352
12353 static struct type *direct_declarator(
12354         struct compile_state *state, struct type *type, 
12355         struct hash_entry **pident, int need_ident)
12356 {
12357         struct hash_entry *ident;
12358         struct type *outer;
12359         int op;
12360         outer = 0;
12361         arrays_complete(state, type);
12362         switch(peek(state)) {
12363         case TOK_IDENT:
12364                 ident = eat(state, TOK_IDENT)->ident;
12365                 if (!ident) {
12366                         error(state, 0, "Unexpected identifier found");
12367                 }
12368                 /* The name of what we are declaring */
12369                 *pident = ident;
12370                 break;
12371         case TOK_LPAREN:
12372                 eat(state, TOK_LPAREN);
12373                 outer = declarator(state, type, pident, need_ident);
12374                 eat(state, TOK_RPAREN);
12375                 break;
12376         default:
12377                 if (need_ident) {
12378                         error(state, 0, "Identifier expected");
12379                 }
12380                 break;
12381         }
12382         do {
12383                 op = 1;
12384                 arrays_complete(state, type);
12385                 switch(peek(state)) {
12386                 case TOK_LPAREN:
12387                         eat(state, TOK_LPAREN);
12388                         type = param_type_list(state, type);
12389                         eat(state, TOK_RPAREN);
12390                         break;
12391                 case TOK_LBRACKET:
12392                 {
12393                         unsigned int qualifiers;
12394                         struct triple *value;
12395                         value = 0;
12396                         eat(state, TOK_LBRACKET);
12397                         if (peek(state) != TOK_RBRACKET) {
12398                                 value = constant_expr(state);
12399                                 integral(state, value);
12400                         }
12401                         eat(state, TOK_RBRACKET);
12402
12403                         qualifiers = type->type & (QUAL_MASK | STOR_MASK);
12404                         type = new_type(TYPE_ARRAY | qualifiers, type, 0);
12405                         if (value) {
12406                                 type->elements = value->u.cval;
12407                                 free_triple(state, value);
12408                         } else {
12409                                 type->elements = ELEMENT_COUNT_UNSPECIFIED;
12410                                 op = 0;
12411                         }
12412                 }
12413                         break;
12414                 default:
12415                         op = 0;
12416                         break;
12417                 }
12418         } while(op);
12419         if (outer) {
12420                 struct type *inner;
12421                 arrays_complete(state, type);
12422                 FINISHME();
12423                 for(inner = outer; inner->left; inner = inner->left)
12424                         ;
12425                 inner->left = type;
12426                 type = outer;
12427         }
12428         return type;
12429 }
12430
12431 static struct type *declarator(
12432         struct compile_state *state, struct type *type, 
12433         struct hash_entry **pident, int need_ident)
12434 {
12435         while(peek(state) == TOK_STAR) {
12436                 eat(state, TOK_STAR);
12437                 type = new_type(TYPE_POINTER | (type->type & STOR_MASK), type, 0);
12438         }
12439         type = direct_declarator(state, type, pident, need_ident);
12440         return type;
12441 }
12442
12443 static struct type *typedef_name(
12444         struct compile_state *state, unsigned int specifiers)
12445 {
12446         struct hash_entry *ident;
12447         struct type *type;
12448         ident = eat(state, TOK_TYPE_NAME)->ident;
12449         type = ident->sym_ident->type;
12450         specifiers |= type->type & QUAL_MASK;
12451         if ((specifiers & (STOR_MASK | QUAL_MASK)) != 
12452                 (type->type & (STOR_MASK | QUAL_MASK))) {
12453                 type = clone_type(specifiers, type);
12454         }
12455         return type;
12456 }
12457
12458 static struct type *enum_specifier(
12459         struct compile_state *state, unsigned int spec)
12460 {
12461         struct hash_entry *ident;
12462         ulong_t base;
12463         int tok;
12464         struct type *enum_type;
12465         enum_type = 0;
12466         ident = 0;
12467         eat(state, TOK_ENUM);
12468         tok = peek(state);
12469         if ((tok == TOK_IDENT) || (tok == TOK_ENUM_CONST) || (tok == TOK_TYPE_NAME)) {
12470                 ident = eat(state, tok)->ident;
12471         }
12472         base = 0;
12473         if (!ident || (peek(state) == TOK_LBRACE)) {
12474                 struct type **next;
12475                 eat(state, TOK_LBRACE);
12476                 enum_type = new_type(TYPE_ENUM | spec, 0, 0);
12477                 enum_type->type_ident = ident;
12478                 next = &enum_type->right;
12479                 do {
12480                         struct hash_entry *eident;
12481                         struct triple *value;
12482                         struct type *entry;
12483                         eident = eat(state, TOK_IDENT)->ident;
12484                         if (eident->sym_ident) {
12485                                 error(state, 0, "%s already declared", 
12486                                         eident->name);
12487                         }
12488                         eident->tok = TOK_ENUM_CONST;
12489                         if (peek(state) == TOK_EQ) {
12490                                 struct triple *val;
12491                                 eat(state, TOK_EQ);
12492                                 val = constant_expr(state);
12493                                 integral(state, val);
12494                                 base = val->u.cval;
12495                         }
12496                         value = int_const(state, &int_type, base);
12497                         symbol(state, eident, &eident->sym_ident, value, &int_type);
12498                         entry = new_type(TYPE_LIST, 0, 0);
12499                         entry->field_ident = eident;
12500                         *next = entry;
12501                         next = &entry->right;
12502                         base += 1;
12503                         if (peek(state) == TOK_COMMA) {
12504                                 eat(state, TOK_COMMA);
12505                         }
12506                 } while(peek(state) != TOK_RBRACE);
12507                 eat(state, TOK_RBRACE);
12508                 if (ident) {
12509                         symbol(state, ident, &ident->sym_tag, 0, enum_type);
12510                 }
12511         }
12512         if (ident && ident->sym_tag &&
12513                 ident->sym_tag->type &&
12514                 ((ident->sym_tag->type->type & TYPE_MASK) == TYPE_ENUM)) {
12515                 enum_type = clone_type(spec, ident->sym_tag->type);
12516         }
12517         else if (ident && !enum_type) {
12518                 error(state, 0, "enum %s undeclared", ident->name);
12519         }
12520         return enum_type;
12521 }
12522
12523 static struct type *struct_declarator(
12524         struct compile_state *state, struct type *type, struct hash_entry **ident)
12525 {
12526         if (peek(state) != TOK_COLON) {
12527                 type = declarator(state, type, ident, 1);
12528         }
12529         if (peek(state) == TOK_COLON) {
12530                 struct triple *value;
12531                 eat(state, TOK_COLON);
12532                 value = constant_expr(state);
12533                 if (value->op != OP_INTCONST) {
12534                         error(state, 0, "Invalid constant expression");
12535                 }
12536                 if (value->u.cval > size_of(state, type)) {
12537                         error(state, 0, "bitfield larger than base type");
12538                 }
12539                 if (!TYPE_INTEGER(type->type) || ((type->type & TYPE_MASK) == TYPE_BITFIELD)) {
12540                         error(state, 0, "bitfield base not an integer type");
12541                 }
12542                 type = new_type(TYPE_BITFIELD, type, 0);
12543                 type->elements = value->u.cval;
12544         }
12545         return type;
12546 }
12547
12548 static struct type *struct_or_union_specifier(
12549         struct compile_state *state, unsigned int spec)
12550 {
12551         struct type *struct_type;
12552         struct hash_entry *ident;
12553         unsigned int type_main;
12554         unsigned int type_join;
12555         int tok;
12556         struct_type = 0;
12557         ident = 0;
12558         switch(peek(state)) {
12559         case TOK_STRUCT:
12560                 eat(state, TOK_STRUCT);
12561                 type_main = TYPE_STRUCT;
12562                 type_join = TYPE_PRODUCT;
12563                 break;
12564         case TOK_UNION:
12565                 eat(state, TOK_UNION);
12566                 type_main = TYPE_UNION;
12567                 type_join = TYPE_OVERLAP;
12568                 break;
12569         default:
12570                 eat(state, TOK_STRUCT);
12571                 type_main = TYPE_STRUCT;
12572                 type_join = TYPE_PRODUCT;
12573                 break;
12574         }
12575         tok = peek(state);
12576         if ((tok == TOK_IDENT) || (tok == TOK_ENUM_CONST) || (tok == TOK_TYPE_NAME)) {
12577                 ident = eat(state, tok)->ident;
12578         }
12579         if (!ident || (peek(state) == TOK_LBRACE)) {
12580                 ulong_t elements;
12581                 struct type **next;
12582                 elements = 0;
12583                 eat(state, TOK_LBRACE);
12584                 next = &struct_type;
12585                 do {
12586                         struct type *base_type;
12587                         int done;
12588                         base_type = specifier_qualifier_list(state);
12589                         do {
12590                                 struct type *type;
12591                                 struct hash_entry *fident;
12592                                 done = 1;
12593                                 type = struct_declarator(state, base_type, &fident);
12594                                 elements++;
12595                                 if (peek(state) == TOK_COMMA) {
12596                                         done = 0;
12597                                         eat(state, TOK_COMMA);
12598                                 }
12599                                 type = clone_type(0, type);
12600                                 type->field_ident = fident;
12601                                 if (*next) {
12602                                         *next = new_type(type_join, *next, type);
12603                                         next = &((*next)->right);
12604                                 } else {
12605                                         *next = type;
12606                                 }
12607                         } while(!done);
12608                         eat(state, TOK_SEMI);
12609                 } while(peek(state) != TOK_RBRACE);
12610                 eat(state, TOK_RBRACE);
12611                 struct_type = new_type(type_main | spec, struct_type, 0);
12612                 struct_type->type_ident = ident;
12613                 struct_type->elements = elements;
12614                 if (ident) {
12615                         symbol(state, ident, &ident->sym_tag, 0, struct_type);
12616                 }
12617         }
12618         if (ident && ident->sym_tag && 
12619                 ident->sym_tag->type && 
12620                 ((ident->sym_tag->type->type & TYPE_MASK) == type_main)) {
12621                 struct_type = clone_type(spec, ident->sym_tag->type);
12622         }
12623         else if (ident && !struct_type) {
12624                 error(state, 0, "%s %s undeclared", 
12625                         (type_main == TYPE_STRUCT)?"struct" : "union",
12626                         ident->name);
12627         }
12628         return struct_type;
12629 }
12630
12631 static unsigned int storage_class_specifier_opt(struct compile_state *state)
12632 {
12633         unsigned int specifiers;
12634         switch(peek(state)) {
12635         case TOK_AUTO:
12636                 eat(state, TOK_AUTO);
12637                 specifiers = STOR_AUTO;
12638                 break;
12639         case TOK_REGISTER:
12640                 eat(state, TOK_REGISTER);
12641                 specifiers = STOR_REGISTER;
12642                 break;
12643         case TOK_STATIC:
12644                 eat(state, TOK_STATIC);
12645                 specifiers = STOR_STATIC;
12646                 break;
12647         case TOK_EXTERN:
12648                 eat(state, TOK_EXTERN);
12649                 specifiers = STOR_EXTERN;
12650                 break;
12651         case TOK_TYPEDEF:
12652                 eat(state, TOK_TYPEDEF);
12653                 specifiers = STOR_TYPEDEF;
12654                 break;
12655         default:
12656                 if (state->scope_depth <= GLOBAL_SCOPE_DEPTH) {
12657                         specifiers = STOR_LOCAL;
12658                 }
12659                 else {
12660                         specifiers = STOR_AUTO;
12661                 }
12662         }
12663         return specifiers;
12664 }
12665
12666 static unsigned int function_specifier_opt(struct compile_state *state)
12667 {
12668         /* Ignore the inline keyword */
12669         unsigned int specifiers;
12670         specifiers = 0;
12671         switch(peek(state)) {
12672         case TOK_INLINE:
12673                 eat(state, TOK_INLINE);
12674                 specifiers = STOR_INLINE;
12675         }
12676         return specifiers;
12677 }
12678
12679 static unsigned int attrib(struct compile_state *state, unsigned int attributes)
12680 {
12681         int tok = peek(state);
12682         switch(tok) {
12683         case TOK_COMMA:
12684         case TOK_LPAREN:
12685                 /* The empty attribute ignore it */
12686                 break;
12687         case TOK_IDENT:
12688         case TOK_ENUM_CONST:
12689         case TOK_TYPE_NAME:
12690         {
12691                 struct hash_entry *ident;
12692                 ident = eat(state, TOK_IDENT)->ident;
12693
12694                 if (ident == state->i_noinline) {
12695                         if (attributes & ATTRIB_ALWAYS_INLINE) {
12696                                 error(state, 0, "both always_inline and noinline attribtes");
12697                         }
12698                         attributes |= ATTRIB_NOINLINE;
12699                 }
12700                 else if (ident == state->i_always_inline) {
12701                         if (attributes & ATTRIB_NOINLINE) {
12702                                 error(state, 0, "both noinline and always_inline attribtes");
12703                         }
12704                         attributes |= ATTRIB_ALWAYS_INLINE;
12705                 }
12706                 else {
12707                         error(state, 0, "Unknown attribute:%s", ident->name);
12708                 }
12709                 break;
12710         }
12711         default:
12712                 error(state, 0, "Unexpected token: %s\n", tokens[tok]);
12713                 break;
12714         }
12715         return attributes;
12716 }
12717
12718 static unsigned int attribute_list(struct compile_state *state, unsigned type)
12719 {
12720         type = attrib(state, type);
12721         while(peek(state) == TOK_COMMA) {
12722                 eat(state, TOK_COMMA);
12723                 type = attrib(state, type);
12724         }
12725         return type;
12726 }
12727
12728 static unsigned int attributes_opt(struct compile_state *state, unsigned type)
12729 {
12730         if (peek(state) == TOK_ATTRIBUTE) {
12731                 eat(state, TOK_ATTRIBUTE);
12732                 eat(state, TOK_LPAREN);
12733                 eat(state, TOK_LPAREN);
12734                 type = attribute_list(state, type);
12735                 eat(state, TOK_RPAREN);
12736                 eat(state, TOK_RPAREN);
12737         }
12738         return type;
12739 }
12740
12741 static unsigned int type_qualifiers(struct compile_state *state)
12742 {
12743         unsigned int specifiers;
12744         int done;
12745         done = 0;
12746         specifiers = QUAL_NONE;
12747         do {
12748                 switch(peek(state)) {
12749                 case TOK_CONST:
12750                         eat(state, TOK_CONST);
12751                         specifiers |= QUAL_CONST;
12752                         break;
12753                 case TOK_VOLATILE:
12754                         eat(state, TOK_VOLATILE);
12755                         specifiers |= QUAL_VOLATILE;
12756                         break;
12757                 case TOK_RESTRICT:
12758                         eat(state, TOK_RESTRICT);
12759                         specifiers |= QUAL_RESTRICT;
12760                         break;
12761                 default:
12762                         done = 1;
12763                         break;
12764                 }
12765         } while(!done);
12766         return specifiers;
12767 }
12768
12769 static struct type *type_specifier(
12770         struct compile_state *state, unsigned int spec)
12771 {
12772         struct type *type;
12773         int tok;
12774         type = 0;
12775         switch((tok = peek(state))) {
12776         case TOK_VOID:
12777                 eat(state, TOK_VOID);
12778                 type = new_type(TYPE_VOID | spec, 0, 0);
12779                 break;
12780         case TOK_CHAR:
12781                 eat(state, TOK_CHAR);
12782                 type = new_type(TYPE_CHAR | spec, 0, 0);
12783                 break;
12784         case TOK_SHORT:
12785                 eat(state, TOK_SHORT);
12786                 if (peek(state) == TOK_INT) {
12787                         eat(state, TOK_INT);
12788                 }
12789                 type = new_type(TYPE_SHORT | spec, 0, 0);
12790                 break;
12791         case TOK_INT:
12792                 eat(state, TOK_INT);
12793                 type = new_type(TYPE_INT | spec, 0, 0);
12794                 break;
12795         case TOK_LONG:
12796                 eat(state, TOK_LONG);
12797                 switch(peek(state)) {
12798                 case TOK_LONG:
12799                         eat(state, TOK_LONG);
12800                         error(state, 0, "long long not supported");
12801                         break;
12802                 case TOK_DOUBLE:
12803                         eat(state, TOK_DOUBLE);
12804                         error(state, 0, "long double not supported");
12805                         break;
12806                 case TOK_INT:
12807                         eat(state, TOK_INT);
12808                         type = new_type(TYPE_LONG | spec, 0, 0);
12809                         break;
12810                 default:
12811                         type = new_type(TYPE_LONG | spec, 0, 0);
12812                         break;
12813                 }
12814                 break;
12815         case TOK_FLOAT:
12816                 eat(state, TOK_FLOAT);
12817                 error(state, 0, "type float not supported");
12818                 break;
12819         case TOK_DOUBLE:
12820                 eat(state, TOK_DOUBLE);
12821                 error(state, 0, "type double not supported");
12822                 break;
12823         case TOK_SIGNED:
12824                 eat(state, TOK_SIGNED);
12825                 switch(peek(state)) {
12826                 case TOK_LONG:
12827                         eat(state, TOK_LONG);
12828                         switch(peek(state)) {
12829                         case TOK_LONG:
12830                                 eat(state, TOK_LONG);
12831                                 error(state, 0, "type long long not supported");
12832                                 break;
12833                         case TOK_INT:
12834                                 eat(state, TOK_INT);
12835                                 type = new_type(TYPE_LONG | spec, 0, 0);
12836                                 break;
12837                         default:
12838                                 type = new_type(TYPE_LONG | spec, 0, 0);
12839                                 break;
12840                         }
12841                         break;
12842                 case TOK_INT:
12843                         eat(state, TOK_INT);
12844                         type = new_type(TYPE_INT | spec, 0, 0);
12845                         break;
12846                 case TOK_SHORT:
12847                         eat(state, TOK_SHORT);
12848                         type = new_type(TYPE_SHORT | spec, 0, 0);
12849                         break;
12850                 case TOK_CHAR:
12851                         eat(state, TOK_CHAR);
12852                         type = new_type(TYPE_CHAR | spec, 0, 0);
12853                         break;
12854                 default:
12855                         type = new_type(TYPE_INT | spec, 0, 0);
12856                         break;
12857                 }
12858                 break;
12859         case TOK_UNSIGNED:
12860                 eat(state, TOK_UNSIGNED);
12861                 switch(peek(state)) {
12862                 case TOK_LONG:
12863                         eat(state, TOK_LONG);
12864                         switch(peek(state)) {
12865                         case TOK_LONG:
12866                                 eat(state, TOK_LONG);
12867                                 error(state, 0, "unsigned long long not supported");
12868                                 break;
12869                         case TOK_INT:
12870                                 eat(state, TOK_INT);
12871                                 type = new_type(TYPE_ULONG | spec, 0, 0);
12872                                 break;
12873                         default:
12874                                 type = new_type(TYPE_ULONG | spec, 0, 0);
12875                                 break;
12876                         }
12877                         break;
12878                 case TOK_INT:
12879                         eat(state, TOK_INT);
12880                         type = new_type(TYPE_UINT | spec, 0, 0);
12881                         break;
12882                 case TOK_SHORT:
12883                         eat(state, TOK_SHORT);
12884                         type = new_type(TYPE_USHORT | spec, 0, 0);
12885                         break;
12886                 case TOK_CHAR:
12887                         eat(state, TOK_CHAR);
12888                         type = new_type(TYPE_UCHAR | spec, 0, 0);
12889                         break;
12890                 default:
12891                         type = new_type(TYPE_UINT | spec, 0, 0);
12892                         break;
12893                 }
12894                 break;
12895                 /* struct or union specifier */
12896         case TOK_STRUCT:
12897         case TOK_UNION:
12898                 type = struct_or_union_specifier(state, spec);
12899                 break;
12900                 /* enum-spefifier */
12901         case TOK_ENUM:
12902                 type = enum_specifier(state, spec);
12903                 break;
12904                 /* typedef name */
12905         case TOK_TYPE_NAME:
12906                 type = typedef_name(state, spec);
12907                 break;
12908         default:
12909                 error(state, 0, "bad type specifier %s", 
12910                         tokens[tok]);
12911                 break;
12912         }
12913         return type;
12914 }
12915
12916 static int istype(int tok)
12917 {
12918         switch(tok) {
12919         case TOK_CONST:
12920         case TOK_RESTRICT:
12921         case TOK_VOLATILE:
12922         case TOK_VOID:
12923         case TOK_CHAR:
12924         case TOK_SHORT:
12925         case TOK_INT:
12926         case TOK_LONG:
12927         case TOK_FLOAT:
12928         case TOK_DOUBLE:
12929         case TOK_SIGNED:
12930         case TOK_UNSIGNED:
12931         case TOK_STRUCT:
12932         case TOK_UNION:
12933         case TOK_ENUM:
12934         case TOK_TYPE_NAME:
12935                 return 1;
12936         default:
12937                 return 0;
12938         }
12939 }
12940
12941
12942 static struct type *specifier_qualifier_list(struct compile_state *state)
12943 {
12944         struct type *type;
12945         unsigned int specifiers = 0;
12946
12947         /* type qualifiers */
12948         specifiers |= type_qualifiers(state);
12949
12950         /* type specifier */
12951         type = type_specifier(state, specifiers);
12952
12953         return type;
12954 }
12955
12956 static int isdecl_specifier(int tok)
12957 {
12958         switch(tok) {
12959                 /* storage class specifier */
12960         case TOK_AUTO:
12961         case TOK_REGISTER:
12962         case TOK_STATIC:
12963         case TOK_EXTERN:
12964         case TOK_TYPEDEF:
12965                 /* type qualifier */
12966         case TOK_CONST:
12967         case TOK_RESTRICT:
12968         case TOK_VOLATILE:
12969                 /* type specifiers */
12970         case TOK_VOID:
12971         case TOK_CHAR:
12972         case TOK_SHORT:
12973         case TOK_INT:
12974         case TOK_LONG:
12975         case TOK_FLOAT:
12976         case TOK_DOUBLE:
12977         case TOK_SIGNED:
12978         case TOK_UNSIGNED:
12979                 /* struct or union specifier */
12980         case TOK_STRUCT:
12981         case TOK_UNION:
12982                 /* enum-spefifier */
12983         case TOK_ENUM:
12984                 /* typedef name */
12985         case TOK_TYPE_NAME:
12986                 /* function specifiers */
12987         case TOK_INLINE:
12988                 return 1;
12989         default:
12990                 return 0;
12991         }
12992 }
12993
12994 static struct type *decl_specifiers(struct compile_state *state)
12995 {
12996         struct type *type;
12997         unsigned int specifiers;
12998         /* I am overly restrictive in the arragement of specifiers supported.
12999          * C is overly flexible in this department it makes interpreting
13000          * the parse tree difficult.
13001          */
13002         specifiers = 0;
13003
13004         /* storage class specifier */
13005         specifiers |= storage_class_specifier_opt(state);
13006
13007         /* function-specifier */
13008         specifiers |= function_specifier_opt(state);
13009
13010         /* attributes */
13011         specifiers |= attributes_opt(state, 0);
13012
13013         /* type qualifier */
13014         specifiers |= type_qualifiers(state);
13015
13016         /* type specifier */
13017         type = type_specifier(state, specifiers);
13018         return type;
13019 }
13020
13021 struct field_info {
13022         struct type *type;
13023         size_t offset;
13024 };
13025
13026 static struct field_info designator(struct compile_state *state, struct type *type)
13027 {
13028         int tok;
13029         struct field_info info;
13030         info.offset = ~0U;
13031         info.type = 0;
13032         do {
13033                 switch(peek(state)) {
13034                 case TOK_LBRACKET:
13035                 {
13036                         struct triple *value;
13037                         if ((type->type & TYPE_MASK) != TYPE_ARRAY) {
13038                                 error(state, 0, "Array designator not in array initializer");
13039                         }
13040                         eat(state, TOK_LBRACKET);
13041                         value = constant_expr(state);
13042                         eat(state, TOK_RBRACKET);
13043
13044                         info.type = type->left;
13045                         info.offset = value->u.cval * size_of(state, info.type);
13046                         break;
13047                 }
13048                 case TOK_DOT:
13049                 {
13050                         struct hash_entry *field;
13051                         if (((type->type & TYPE_MASK) != TYPE_STRUCT) &&
13052                                 ((type->type & TYPE_MASK) != TYPE_UNION))
13053                         {
13054                                 error(state, 0, "Struct designator not in struct initializer");
13055                         }
13056                         eat(state, TOK_DOT);
13057                         field = eat(state, TOK_IDENT)->ident;
13058                         info.offset = field_offset(state, type, field);
13059                         info.type   = field_type(state, type, field);
13060                         break;
13061                 }
13062                 default:
13063                         error(state, 0, "Invalid designator");
13064                 }
13065                 tok = peek(state);
13066         } while((tok == TOK_LBRACKET) || (tok == TOK_DOT));
13067         eat(state, TOK_EQ);
13068         return info;
13069 }
13070
13071 static struct triple *initializer(
13072         struct compile_state *state, struct type *type)
13073 {
13074         struct triple *result;
13075 #warning "FIXME more consistent initializer handling (where should eval_const_expr go?"
13076         if (peek(state) != TOK_LBRACE) {
13077                 result = assignment_expr(state);
13078                 if (((type->type & TYPE_MASK) == TYPE_ARRAY) &&
13079                         (type->elements == ELEMENT_COUNT_UNSPECIFIED) &&
13080                         ((result->type->type & TYPE_MASK) == TYPE_ARRAY) &&
13081                         (result->type->elements != ELEMENT_COUNT_UNSPECIFIED) &&
13082                         (equiv_types(type->left, result->type->left))) {
13083                         type->elements = result->type->elements;
13084                 }
13085                 if (is_lvalue(state, result) && 
13086                         ((result->type->type & TYPE_MASK) == TYPE_ARRAY) &&
13087                         (type->type & TYPE_MASK) != TYPE_ARRAY)
13088                 {
13089                         result = lvalue_conversion(state, result);
13090                 }
13091                 if (!is_init_compatible(state, type, result->type)) {
13092                         error(state, 0, "Incompatible types in initializer");
13093                 }
13094                 if (!equiv_types(type, result->type)) {
13095                         result = mk_cast_expr(state, type, result);
13096                 }
13097         }
13098         else {
13099                 int comma;
13100                 size_t max_offset;
13101                 struct field_info info;
13102                 void *buf;
13103                 if (((type->type & TYPE_MASK) != TYPE_ARRAY) &&
13104                         ((type->type & TYPE_MASK) != TYPE_STRUCT)) {
13105                         internal_error(state, 0, "unknown initializer type");
13106                 }
13107                 info.offset = 0;
13108                 info.type = type->left;
13109                 if ((type->type & TYPE_MASK) == TYPE_STRUCT) {
13110                         info.type = next_field(state, type, 0);
13111                 }
13112                 if (type->elements == ELEMENT_COUNT_UNSPECIFIED) {
13113                         max_offset = 0;
13114                 } else {
13115                         max_offset = size_of(state, type);
13116                 }
13117                 buf = xcmalloc(bits_to_bytes(max_offset), "initializer");
13118                 eat(state, TOK_LBRACE);
13119                 do {
13120                         struct triple *value;
13121                         struct type *value_type;
13122                         size_t value_size;
13123                         void *dest;
13124                         int tok;
13125                         comma = 0;
13126                         tok = peek(state);
13127                         if ((tok == TOK_LBRACKET) || (tok == TOK_DOT)) {
13128                                 info = designator(state, type);
13129                         }
13130                         if ((type->elements != ELEMENT_COUNT_UNSPECIFIED) &&
13131                                 (info.offset >= max_offset)) {
13132                                 error(state, 0, "element beyond bounds");
13133                         }
13134                         value_type = info.type;
13135                         value = eval_const_expr(state, initializer(state, value_type));
13136                         value_size = size_of(state, value_type);
13137                         if (((type->type & TYPE_MASK) == TYPE_ARRAY) &&
13138                                 (type->elements == ELEMENT_COUNT_UNSPECIFIED) &&
13139                                 (max_offset <= info.offset)) {
13140                                 void *old_buf;
13141                                 size_t old_size;
13142                                 old_buf = buf;
13143                                 old_size = max_offset;
13144                                 max_offset = info.offset + value_size;
13145                                 buf = xmalloc(bits_to_bytes(max_offset), "initializer");
13146                                 memcpy(buf, old_buf, bits_to_bytes(old_size));
13147                                 xfree(old_buf);
13148                         }
13149                         dest = ((char *)buf) + bits_to_bytes(info.offset);
13150 #if DEBUG_INITIALIZER
13151                         fprintf(state->errout, "dest = buf + %d max_offset: %d value_size: %d op: %d\n", 
13152                                 dest - buf,
13153                                 bits_to_bytes(max_offset),
13154                                 bits_to_bytes(value_size),
13155                                 value->op);
13156 #endif
13157                         if (value->op == OP_BLOBCONST) {
13158                                 memcpy(dest, value->u.blob, bits_to_bytes(value_size));
13159                         }
13160                         else if ((value->op == OP_INTCONST) && (value_size == SIZEOF_I8)) {
13161 #if DEBUG_INITIALIZER
13162                                 fprintf(state->errout, "byte: %02x\n", value->u.cval & 0xff);
13163 #endif
13164                                 *((uint8_t *)dest) = value->u.cval & 0xff;
13165                         }
13166                         else if ((value->op == OP_INTCONST) && (value_size == SIZEOF_I16)) {
13167                                 *((uint16_t *)dest) = value->u.cval & 0xffff;
13168                         }
13169                         else if ((value->op == OP_INTCONST) && (value_size == SIZEOF_I32)) {
13170                                 *((uint32_t *)dest) = value->u.cval & 0xffffffff;
13171                         }
13172                         else {
13173                                 internal_error(state, 0, "unhandled constant initializer");
13174                         }
13175                         free_triple(state, value);
13176                         if (peek(state) == TOK_COMMA) {
13177                                 eat(state, TOK_COMMA);
13178                                 comma = 1;
13179                         }
13180                         info.offset += value_size;
13181                         if ((type->type & TYPE_MASK) == TYPE_STRUCT) {
13182                                 info.type = next_field(state, type, info.type);
13183                                 info.offset = field_offset(state, type, 
13184                                         info.type->field_ident);
13185                         }
13186                 } while(comma && (peek(state) != TOK_RBRACE));
13187                 if ((type->elements == ELEMENT_COUNT_UNSPECIFIED) &&
13188                         ((type->type & TYPE_MASK) == TYPE_ARRAY)) {
13189                         type->elements = max_offset / size_of(state, type->left);
13190                 }
13191                 eat(state, TOK_RBRACE);
13192                 result = triple(state, OP_BLOBCONST, type, 0, 0);
13193                 result->u.blob = buf;
13194         }
13195         return result;
13196 }
13197
13198 static void resolve_branches(struct compile_state *state, struct triple *first)
13199 {
13200         /* Make a second pass and finish anything outstanding
13201          * with respect to branches.  The only outstanding item
13202          * is to see if there are goto to labels that have not
13203          * been defined and to error about them.
13204          */
13205         int i;
13206         struct triple *ins;
13207         /* Also error on branches that do not use their targets */
13208         ins = first;
13209         do {
13210                 if (!triple_is_ret(state, ins)) {
13211                         struct triple **expr ;
13212                         struct triple_set *set;
13213                         expr = triple_targ(state, ins, 0);
13214                         for(; expr; expr = triple_targ(state, ins, expr)) {
13215                                 struct triple *targ;
13216                                 targ = *expr;
13217                                 for(set = targ?targ->use:0; set; set = set->next) {
13218                                         if (set->member == ins) {
13219                                                 break;
13220                                         }
13221                                 }
13222                                 if (!set) {
13223                                         internal_error(state, ins, "targ not used");
13224                                 }
13225                         }
13226                 }
13227                 ins = ins->next;
13228         } while(ins != first);
13229         /* See if there are goto to labels that have not been defined */
13230         for(i = 0; i < HASH_TABLE_SIZE; i++) {
13231                 struct hash_entry *entry;
13232                 for(entry = state->hash_table[i]; entry; entry = entry->next) {
13233                         struct triple *ins;
13234                         if (!entry->sym_label) {
13235                                 continue;
13236                         }
13237                         ins = entry->sym_label->def;
13238                         if (!(ins->id & TRIPLE_FLAG_FLATTENED)) {
13239                                 error(state, ins, "label `%s' used but not defined",
13240                                         entry->name);
13241                         }
13242                 }
13243         }
13244 }
13245
13246 static struct triple *function_definition(
13247         struct compile_state *state, struct type *type)
13248 {
13249         struct triple *def, *tmp, *first, *end, *retvar, *result, *ret;
13250         struct triple *fname;
13251         struct type *fname_type;
13252         struct hash_entry *ident;
13253         struct type *param, *crtype, *ctype;
13254         int i;
13255         if ((type->type &TYPE_MASK) != TYPE_FUNCTION) {
13256                 error(state, 0, "Invalid function header");
13257         }
13258
13259         /* Verify the function type */
13260         if (((type->right->type & TYPE_MASK) != TYPE_VOID)  &&
13261                 ((type->right->type & TYPE_MASK) != TYPE_PRODUCT) &&
13262                 (type->right->field_ident == 0)) {
13263                 error(state, 0, "Invalid function parameters");
13264         }
13265         param = type->right;
13266         i = 0;
13267         while((param->type & TYPE_MASK) == TYPE_PRODUCT) {
13268                 i++;
13269                 if (!param->left->field_ident) {
13270                         error(state, 0, "No identifier for parameter %d\n", i);
13271                 }
13272                 param = param->right;
13273         }
13274         i++;
13275         if (((param->type & TYPE_MASK) != TYPE_VOID) && !param->field_ident) {
13276                 error(state, 0, "No identifier for paramter %d\n", i);
13277         }
13278         
13279         /* Get a list of statements for this function. */
13280         def = triple(state, OP_LIST, type, 0, 0);
13281
13282         /* Start a new scope for the passed parameters */
13283         start_scope(state);
13284
13285         /* Put a label at the very start of a function */
13286         first = label(state);
13287         RHS(def, 0) = first;
13288
13289         /* Put a label at the very end of a function */
13290         end = label(state);
13291         flatten(state, first, end);
13292         /* Remember where return goes */
13293         ident = state->i_return;
13294         symbol(state, ident, &ident->sym_ident, end, end->type);
13295
13296         /* Get the initial closure type */
13297         ctype = new_type(TYPE_JOIN, &void_type, 0);
13298         ctype->elements = 1;
13299
13300         /* Add a variable for the return value */
13301         crtype = new_type(TYPE_TUPLE, 
13302                 /* Remove all type qualifiers from the return type */
13303                 new_type(TYPE_PRODUCT, ctype, clone_type(0, type->left)), 0);
13304         crtype->elements = 2;
13305         result = flatten(state, end, variable(state, crtype));
13306
13307         /* Allocate a variable for the return address */
13308         retvar = flatten(state, end, variable(state, &void_ptr_type));
13309
13310         /* Add in the return instruction */
13311         ret = triple(state, OP_RET, &void_type, read_expr(state, retvar), 0);
13312         ret = flatten(state, first, ret);
13313
13314         /* Walk through the parameters and create symbol table entries
13315          * for them.
13316          */
13317         param = type->right;
13318         while((param->type & TYPE_MASK) == TYPE_PRODUCT) {
13319                 ident = param->left->field_ident;
13320                 tmp = variable(state, param->left);
13321                 var_symbol(state, ident, tmp);
13322                 flatten(state, end, tmp);
13323                 param = param->right;
13324         }
13325         if ((param->type & TYPE_MASK) != TYPE_VOID) {
13326                 /* And don't forget the last parameter */
13327                 ident = param->field_ident;
13328                 tmp = variable(state, param);
13329                 symbol(state, ident, &ident->sym_ident, tmp, tmp->type);
13330                 flatten(state, end, tmp);
13331         }
13332
13333         /* Add the declaration static const char __func__ [] = "func-name"  */
13334         fname_type = new_type(TYPE_ARRAY, 
13335                 clone_type(QUAL_CONST | STOR_STATIC, &char_type), 0);
13336         fname_type->type |= QUAL_CONST | STOR_STATIC;
13337         fname_type->elements = strlen(state->function) + 1;
13338
13339         fname = triple(state, OP_BLOBCONST, fname_type, 0, 0);
13340         fname->u.blob = (void *)state->function;
13341         fname = flatten(state, end, fname);
13342
13343         ident = state->i___func__;
13344         symbol(state, ident, &ident->sym_ident, fname, fname_type);
13345
13346         /* Remember which function I am compiling.
13347          * Also assume the last defined function is the main function.
13348          */
13349         state->main_function = def;
13350
13351         /* Now get the actual function definition */
13352         compound_statement(state, end);
13353
13354         /* Finish anything unfinished with branches */
13355         resolve_branches(state, first);
13356
13357         /* Remove the parameter scope */
13358         end_scope(state);
13359
13360
13361         /* Remember I have defined a function */
13362         if (!state->functions) {
13363                 state->functions = def;
13364         } else {
13365                 insert_triple(state, state->functions, def);
13366         }
13367         if (state->compiler->debug & DEBUG_INLINE) {
13368                 FILE *fp = state->dbgout;
13369                 fprintf(fp, "\n");
13370                 loc(fp, state, 0);
13371                 fprintf(fp, "\n__________ %s _________\n", __FUNCTION__);
13372                 display_func(state, fp, def);
13373                 fprintf(fp, "__________ %s _________ done\n\n", __FUNCTION__);
13374         }
13375
13376         return def;
13377 }
13378
13379 static struct triple *do_decl(struct compile_state *state, 
13380         struct type *type, struct hash_entry *ident)
13381 {
13382         struct triple *def;
13383         def = 0;
13384         /* Clean up the storage types used */
13385         switch (type->type & STOR_MASK) {
13386         case STOR_AUTO:
13387         case STOR_STATIC:
13388                 /* These are the good types I am aiming for */
13389                 break;
13390         case STOR_REGISTER:
13391                 type->type &= ~STOR_MASK;
13392                 type->type |= STOR_AUTO;
13393                 break;
13394         case STOR_LOCAL:
13395         case STOR_EXTERN:
13396                 type->type &= ~STOR_MASK;
13397                 type->type |= STOR_STATIC;
13398                 break;
13399         case STOR_TYPEDEF:
13400                 if (!ident) {
13401                         error(state, 0, "typedef without name");
13402                 }
13403                 symbol(state, ident, &ident->sym_ident, 0, type);
13404                 ident->tok = TOK_TYPE_NAME;
13405                 return 0;
13406                 break;
13407         default:
13408                 internal_error(state, 0, "Undefined storage class");
13409         }
13410         if ((type->type & TYPE_MASK) == TYPE_FUNCTION) {
13411                 error(state, 0, "Function prototypes not supported");
13412         }
13413         if (ident && 
13414                 ((type->type & STOR_MASK) == STOR_STATIC) &&
13415                 ((type->type & QUAL_CONST) == 0)) {
13416                 error(state, 0, "non const static variables not supported");
13417         }
13418         if (ident) {
13419                 def = variable(state, type);
13420                 var_symbol(state, ident, def);
13421         }
13422         return def;
13423 }
13424
13425 static void decl(struct compile_state *state, struct triple *first)
13426 {
13427         struct type *base_type, *type;
13428         struct hash_entry *ident;
13429         struct triple *def;
13430         int global;
13431         global = (state->scope_depth <= GLOBAL_SCOPE_DEPTH);
13432         base_type = decl_specifiers(state);
13433         ident = 0;
13434         type = declarator(state, base_type, &ident, 0);
13435         type->type = attributes_opt(state, type->type);
13436         if (global && ident && (peek(state) == TOK_LBRACE)) {
13437                 /* function */
13438                 type->type_ident = ident;
13439                 state->function = ident->name;
13440                 def = function_definition(state, type);
13441                 symbol(state, ident, &ident->sym_ident, def, type);
13442                 state->function = 0;
13443         }
13444         else {
13445                 int done;
13446                 flatten(state, first, do_decl(state, type, ident));
13447                 /* type or variable definition */
13448                 do {
13449                         done = 1;
13450                         if (peek(state) == TOK_EQ) {
13451                                 if (!ident) {
13452                                         error(state, 0, "cannot assign to a type");
13453                                 }
13454                                 eat(state, TOK_EQ);
13455                                 flatten(state, first,
13456                                         init_expr(state, 
13457                                                 ident->sym_ident->def, 
13458                                                 initializer(state, type)));
13459                         }
13460                         arrays_complete(state, type);
13461                         if (peek(state) == TOK_COMMA) {
13462                                 eat(state, TOK_COMMA);
13463                                 ident = 0;
13464                                 type = declarator(state, base_type, &ident, 0);
13465                                 flatten(state, first, do_decl(state, type, ident));
13466                                 done = 0;
13467                         }
13468                 } while(!done);
13469                 eat(state, TOK_SEMI);
13470         }
13471 }
13472
13473 static void decls(struct compile_state *state)
13474 {
13475         struct triple *list;
13476         int tok;
13477         list = label(state);
13478         while(1) {
13479                 tok = peek(state);
13480                 if (tok == TOK_EOF) {
13481                         return;
13482                 }
13483                 if (tok == TOK_SPACE) {
13484                         eat(state, TOK_SPACE);
13485                 }
13486                 decl(state, list);
13487                 if (list->next != list) {
13488                         error(state, 0, "global variables not supported");
13489                 }
13490         }
13491 }
13492
13493 /* 
13494  * Function inlining
13495  */
13496 struct triple_reg_set {
13497         struct triple_reg_set *next;
13498         struct triple *member;
13499         struct triple *new;
13500 };
13501 struct reg_block {
13502         struct block *block;
13503         struct triple_reg_set *in;
13504         struct triple_reg_set *out;
13505         int vertex;
13506 };
13507 static void setup_basic_blocks(struct compile_state *, struct basic_blocks *bb);
13508 static void analyze_basic_blocks(struct compile_state *state, struct basic_blocks *bb);
13509 static void free_basic_blocks(struct compile_state *, struct basic_blocks *bb);
13510 static int tdominates(struct compile_state *state, struct triple *dom, struct triple *sub);
13511 static void walk_blocks(struct compile_state *state, struct basic_blocks *bb,
13512         void (*cb)(struct compile_state *state, struct block *block, void *arg),
13513         void *arg);
13514 static void print_block(
13515         struct compile_state *state, struct block *block, void *arg);
13516 static int do_triple_set(struct triple_reg_set **head, 
13517         struct triple *member, struct triple *new_member);
13518 static void do_triple_unset(struct triple_reg_set **head, struct triple *member);
13519 static struct reg_block *compute_variable_lifetimes(
13520         struct compile_state *state, struct basic_blocks *bb);
13521 static void free_variable_lifetimes(struct compile_state *state, 
13522         struct basic_blocks *bb, struct reg_block *blocks);
13523 static void print_live_variables(struct compile_state *state, 
13524         struct basic_blocks *bb, struct reg_block *rb, FILE *fp);
13525
13526
13527 static struct triple *call(struct compile_state *state,
13528         struct triple *retvar, struct triple *ret_addr, 
13529         struct triple *targ, struct triple *ret)
13530 {
13531         struct triple *call;
13532
13533         if (!retvar || !is_lvalue(state, retvar)) {
13534                 internal_error(state, 0, "writing to a non lvalue?");
13535         }
13536         write_compatible(state, retvar->type, &void_ptr_type);
13537
13538         call = new_triple(state, OP_CALL, &void_type, 1, 0);
13539         TARG(call, 0) = targ;
13540         MISC(call, 0) = ret;
13541         if (!targ || (targ->op != OP_LABEL)) {
13542                 internal_error(state, 0, "call not to a label");
13543         }
13544         if (!ret || (ret->op != OP_RET)) {
13545                 internal_error(state, 0, "call not matched with return");
13546         }
13547         return call;
13548 }
13549
13550 static void walk_functions(struct compile_state *state,
13551         void (*cb)(struct compile_state *state, struct triple *func, void *arg),
13552         void *arg)
13553 {
13554         struct triple *func, *first;
13555         func = first = state->functions;
13556         do {
13557                 cb(state, func, arg);
13558                 func = func->next;
13559         } while(func != first);
13560 }
13561
13562 static void reverse_walk_functions(struct compile_state *state,
13563         void (*cb)(struct compile_state *state, struct triple *func, void *arg),
13564         void *arg)
13565 {
13566         struct triple *func, *first;
13567         func = first = state->functions;
13568         do {
13569                 func = func->prev;
13570                 cb(state, func, arg);
13571         } while(func != first);
13572 }
13573
13574
13575 static void mark_live(struct compile_state *state, struct triple *func, void *arg)
13576 {
13577         struct triple *ptr, *first;
13578         if (func->u.cval == 0) {
13579                 return;
13580         }
13581         ptr = first = RHS(func, 0);
13582         do {
13583                 if (ptr->op == OP_FCALL) {
13584                         struct triple *called_func;
13585                         called_func = MISC(ptr, 0);
13586                         /* Mark the called function as used */
13587                         if (!(func->id & TRIPLE_FLAG_FLATTENED)) {
13588                                 called_func->u.cval++;
13589                         }
13590                         /* Remove the called function from the list */
13591                         called_func->prev->next = called_func->next;
13592                         called_func->next->prev = called_func->prev;
13593
13594                         /* Place the called function before me on the list */
13595                         called_func->next       = func;
13596                         called_func->prev       = func->prev;
13597                         called_func->prev->next = called_func;
13598                         called_func->next->prev = called_func;
13599                 }
13600                 ptr = ptr->next;
13601         } while(ptr != first);
13602         func->id |= TRIPLE_FLAG_FLATTENED;
13603 }
13604
13605 static void mark_live_functions(struct compile_state *state)
13606 {
13607         /* Ensure state->main_function is the last function in 
13608          * the list of functions.
13609          */
13610         if ((state->main_function->next != state->functions) ||
13611                 (state->functions->prev != state->main_function)) {
13612                 internal_error(state, 0, 
13613                         "state->main_function is not at the end of the function list ");
13614         }
13615         state->main_function->u.cval = 1;
13616         reverse_walk_functions(state, mark_live, 0);
13617 }
13618
13619 static int local_triple(struct compile_state *state, 
13620         struct triple *func, struct triple *ins)
13621 {
13622         int local = (ins->id & TRIPLE_FLAG_LOCAL);
13623 #if 0
13624         if (!local) {
13625                 FILE *fp = state->errout;
13626                 fprintf(fp, "global: ");
13627                 display_triple(fp, ins);
13628         }
13629 #endif
13630         return local;
13631 }
13632
13633 struct triple *copy_func(struct compile_state *state, struct triple *ofunc, 
13634         struct occurance *base_occurance)
13635 {
13636         struct triple *nfunc;
13637         struct triple *nfirst, *ofirst;
13638         struct triple *new, *old;
13639
13640         if (state->compiler->debug & DEBUG_INLINE) {
13641                 FILE *fp = state->dbgout;
13642                 fprintf(fp, "\n");
13643                 loc(fp, state, 0);
13644                 fprintf(fp, "\n__________ %s _________\n", __FUNCTION__);
13645                 display_func(state, fp, ofunc);
13646                 fprintf(fp, "__________ %s _________ done\n\n", __FUNCTION__);
13647         }
13648
13649         /* Make a new copy of the old function */
13650         nfunc = triple(state, OP_LIST, ofunc->type, 0, 0);
13651         nfirst = 0;
13652         ofirst = old = RHS(ofunc, 0);
13653         do {
13654                 struct triple *new;
13655                 struct occurance *occurance;
13656                 int old_lhs, old_rhs;
13657                 old_lhs = old->lhs;
13658                 old_rhs = old->rhs;
13659                 occurance = inline_occurance(state, base_occurance, old->occurance);
13660                 if (ofunc->u.cval && (old->op == OP_FCALL)) {
13661                         MISC(old, 0)->u.cval += 1;
13662                 }
13663                 new = alloc_triple(state, old->op, old->type, old_lhs, old_rhs,
13664                         occurance);
13665                 if (!triple_stores_block(state, new)) {
13666                         memcpy(&new->u, &old->u, sizeof(new->u));
13667                 }
13668                 if (!nfirst) {
13669                         RHS(nfunc, 0) = nfirst = new;
13670                 }
13671                 else {
13672                         insert_triple(state, nfirst, new);
13673                 }
13674                 new->id |= TRIPLE_FLAG_FLATTENED;
13675                 new->id |= old->id & TRIPLE_FLAG_COPY;
13676                 
13677                 /* During the copy remember new as user of old */
13678                 use_triple(old, new);
13679
13680                 /* Remember which instructions are local */
13681                 old->id |= TRIPLE_FLAG_LOCAL;
13682                 old = old->next;
13683         } while(old != ofirst);
13684
13685         /* Make a second pass to fix up any unresolved references */
13686         old = ofirst;
13687         new = nfirst;
13688         do {
13689                 struct triple **oexpr, **nexpr;
13690                 int count, i;
13691                 /* Lookup where the copy is, to join pointers */
13692                 count = TRIPLE_SIZE(old);
13693                 for(i = 0; i < count; i++) {
13694                         oexpr = &old->param[i];
13695                         nexpr = &new->param[i];
13696                         if (*oexpr && !*nexpr) {
13697                                 if (!local_triple(state, ofunc, *oexpr)) {
13698                                         *nexpr = *oexpr;
13699                                 }
13700                                 else if ((*oexpr)->use) {
13701                                         *nexpr = (*oexpr)->use->member;
13702                                 }
13703                                 if (*nexpr == old) {
13704                                         internal_error(state, 0, "new == old?");
13705                                 }
13706                                 use_triple(*nexpr, new);
13707                         }
13708                         if (!*nexpr && *oexpr) {
13709                                 internal_error(state, 0, "Could not copy %d", i);
13710                         }
13711                 }
13712                 old = old->next;
13713                 new = new->next;
13714         } while((old != ofirst) && (new != nfirst));
13715         
13716         /* Make a third pass to cleanup the extra useses */
13717         old = ofirst;
13718         new = nfirst;
13719         do {
13720                 unuse_triple(old, new);
13721                 /* Forget which instructions are local */
13722                 old->id &= ~TRIPLE_FLAG_LOCAL;
13723                 old = old->next;
13724                 new = new->next;
13725         } while ((old != ofirst) && (new != nfirst));
13726         return nfunc;
13727 }
13728
13729 static void expand_inline_call(
13730         struct compile_state *state, struct triple *me, struct triple *fcall)
13731 {
13732         /* Inline the function call */
13733         struct type *ptype;
13734         struct triple *ofunc, *nfunc, *nfirst, *result, *retvar, *ins;
13735         struct triple *end, *nend;
13736         int pvals, i;
13737
13738         /* Find the triples */
13739         ofunc = MISC(fcall, 0);
13740         if (ofunc->op != OP_LIST) {
13741                 internal_error(state, 0, "improper function");
13742         }
13743         nfunc = copy_func(state, ofunc, fcall->occurance);
13744         /* Prepend the parameter reading into the new function list */
13745         ptype = nfunc->type->right;
13746         pvals = fcall->rhs;
13747         for(i = 0; i < pvals; i++) {
13748                 struct type *atype;
13749                 struct triple *arg, *param;
13750                 atype = ptype;
13751                 if ((ptype->type & TYPE_MASK) == TYPE_PRODUCT) {
13752                         atype = ptype->left;
13753                 }
13754                 param = farg(state, nfunc, i);
13755                 if ((param->type->type & TYPE_MASK) != (atype->type & TYPE_MASK)) {
13756                         internal_error(state, fcall, "param %d type mismatch", i);
13757                 }
13758                 arg = RHS(fcall, i);
13759                 flatten(state, fcall, write_expr(state, param, arg));
13760                 ptype = ptype->right;
13761         }
13762         result = 0;
13763         if ((nfunc->type->left->type & TYPE_MASK) != TYPE_VOID) {
13764                 result = read_expr(state, 
13765                         deref_index(state, fresult(state, nfunc), 1));
13766         }
13767         if (state->compiler->debug & DEBUG_INLINE) {
13768                 FILE *fp = state->dbgout;
13769                 fprintf(fp, "\n");
13770                 loc(fp, state, 0);
13771                 fprintf(fp, "\n__________ %s _________\n", __FUNCTION__);
13772                 display_func(state, fp, nfunc);
13773                 fprintf(fp, "__________ %s _________ done\n\n", __FUNCTION__);
13774         }
13775
13776         /* 
13777          * Get rid of the extra triples 
13778          */
13779         /* Remove the read of the return address */
13780         ins = RHS(nfunc, 0)->prev->prev;
13781         if ((ins->op != OP_READ) || (RHS(ins, 0) != fretaddr(state, nfunc))) {
13782                 internal_error(state, ins, "Not return addres read?");
13783         }
13784         release_triple(state, ins);
13785         /* Remove the return instruction */
13786         ins = RHS(nfunc, 0)->prev;
13787         if (ins->op != OP_RET) {
13788                 internal_error(state, ins, "Not return?");
13789         }
13790         release_triple(state, ins);
13791         /* Remove the retaddres variable */
13792         retvar = fretaddr(state, nfunc);
13793         if ((retvar->lhs != 1) || 
13794                 (retvar->op != OP_ADECL) ||
13795                 (retvar->next->op != OP_PIECE) ||
13796                 (MISC(retvar->next, 0) != retvar)) {
13797                 internal_error(state, retvar, "Not the return address?");
13798         }
13799         release_triple(state, retvar->next);
13800         release_triple(state, retvar);
13801
13802         /* Remove the label at the start of the function */
13803         ins = RHS(nfunc, 0);
13804         if (ins->op != OP_LABEL) {
13805                 internal_error(state, ins, "Not label?");
13806         }
13807         nfirst = ins->next;
13808         free_triple(state, ins);
13809         /* Release the new function header */
13810         RHS(nfunc, 0) = 0;
13811         free_triple(state, nfunc);
13812
13813         /* Append the new function list onto the return list */
13814         end = fcall->prev;
13815         nend = nfirst->prev;
13816         end->next    = nfirst;
13817         nfirst->prev = end;
13818         nend->next   = fcall;
13819         fcall->prev  = nend;
13820
13821         /* Now the result reading code */
13822         if (result) {
13823                 result = flatten(state, fcall, result);
13824                 propogate_use(state, fcall, result);
13825         }
13826
13827         /* Release the original fcall instruction */
13828         release_triple(state, fcall);
13829
13830         return;
13831 }
13832
13833 /*
13834  *
13835  * Type of the result variable.
13836  * 
13837  *                                     result
13838  *                                        |
13839  *                             +----------+------------+
13840  *                             |                       |
13841  *                     union of closures         result_type
13842  *                             |
13843  *          +------------------+---------------+
13844  *          |                                  |
13845  *       closure1                    ...   closuerN
13846  *          |                                  | 
13847  *  +----+--+-+--------+-----+       +----+----+---+-----+
13848  *  |    |    |        |     |       |    |        |     |
13849  * var1 var2 var3 ... varN result   var1 var2 ... varN result
13850  *                           |
13851  *                  +--------+---------+
13852  *                  |                  |
13853  *          union of closures     result_type
13854  *                  |
13855  *            +-----+-------------------+
13856  *            |                         |
13857  *         closure1            ...  closureN
13858  *            |                         |
13859  *  +-----+---+----+----+      +----+---+----+-----+
13860  *  |     |        |    |      |    |        |     |
13861  * var1 var2 ... varN result  var1 var2 ... varN result
13862  */
13863
13864 static int add_closure_type(struct compile_state *state, 
13865         struct triple *func, struct type *closure_type)
13866 {
13867         struct type *type, *ctype, **next;
13868         struct triple *var, *new_var;
13869         int i;
13870
13871 #if 0
13872         FILE *fp = state->errout;
13873         fprintf(fp, "original_type: ");
13874         name_of(fp, fresult(state, func)->type);
13875         fprintf(fp, "\n");
13876 #endif
13877         /* find the original type */
13878         var = fresult(state, func);
13879         type = var->type;
13880         if (type->elements != 2) {
13881                 internal_error(state, var, "bad return type");
13882         }
13883
13884         /* Find the complete closure type and update it */
13885         ctype = type->left->left;
13886         next = &ctype->left;
13887         while(((*next)->type & TYPE_MASK) == TYPE_OVERLAP) {
13888                 next = &(*next)->right;
13889         }
13890         *next = new_type(TYPE_OVERLAP, *next, dup_type(state, closure_type));
13891         ctype->elements += 1;
13892
13893 #if 0
13894         fprintf(fp, "new_type: ");
13895         name_of(fp, type);
13896         fprintf(fp, "\n");
13897         fprintf(fp, "ctype: %p %d bits: %d ", 
13898                 ctype, ctype->elements, reg_size_of(state, ctype));
13899         name_of(fp, ctype);
13900         fprintf(fp, "\n");
13901 #endif
13902         
13903         /* Regenerate the variable with the new type definition */
13904         new_var = pre_triple(state, var, OP_ADECL, type, 0, 0);
13905         new_var->id |= TRIPLE_FLAG_FLATTENED;
13906         for(i = 0; i < new_var->lhs; i++) {
13907                 LHS(new_var, i)->id |= TRIPLE_FLAG_FLATTENED;
13908         }
13909         
13910         /* Point everyone at the new variable */
13911         propogate_use(state, var, new_var);
13912
13913         /* Release the original variable */
13914         for(i = 0; i < var->lhs; i++) {
13915                 release_triple(state, LHS(var, i));
13916         }
13917         release_triple(state, var);
13918         
13919         /* Return the index of the added closure type */
13920         return ctype->elements - 1;
13921 }
13922
13923 static struct triple *closure_expr(struct compile_state *state,
13924         struct triple *func, int closure_idx, int var_idx)
13925 {
13926         return deref_index(state,
13927                 deref_index(state,
13928                         deref_index(state, fresult(state, func), 0),
13929                         closure_idx),
13930                 var_idx);
13931 }
13932
13933
13934 static void insert_triple_set(
13935         struct triple_reg_set **head, struct triple *member)
13936 {
13937         struct triple_reg_set *new;
13938         new = xcmalloc(sizeof(*new), "triple_set");
13939         new->member = member;
13940         new->new    = 0;
13941         new->next   = *head;
13942         *head       = new;
13943 }
13944
13945 static int ordered_triple_set(
13946         struct triple_reg_set **head, struct triple *member)
13947 {
13948         struct triple_reg_set **ptr;
13949         if (!member)
13950                 return 0;
13951         ptr = head;
13952         while(*ptr) {
13953                 if (member == (*ptr)->member) {
13954                         return 0;
13955                 }
13956                 /* keep the list ordered */
13957                 if (member->id < (*ptr)->member->id) {
13958                         break;
13959                 }
13960                 ptr = &(*ptr)->next;
13961         }
13962         insert_triple_set(ptr, member);
13963         return 1;
13964 }
13965
13966
13967 static void free_closure_variables(struct compile_state *state,
13968         struct triple_reg_set **enclose)
13969 {
13970         struct triple_reg_set *entry, *next;
13971         for(entry = *enclose; entry; entry = next) {
13972                 next = entry->next;
13973                 do_triple_unset(enclose, entry->member);
13974         }
13975 }
13976
13977 static int lookup_closure_index(struct compile_state *state,
13978         struct triple *me, struct triple *val)
13979 {
13980         struct triple *first, *ins, *next;
13981         first = RHS(me, 0);
13982         ins = next = first;
13983         do {
13984                 struct triple *result;
13985                 struct triple *index0, *index1, *index2, *read, *write;
13986                 ins = next;
13987                 next = ins->next;
13988                 if (ins->op != OP_CALL) {
13989                         continue;
13990                 }
13991                 /* I am at a previous call point examine it closely */
13992                 if (ins->next->op != OP_LABEL) {
13993                         internal_error(state, ins, "call not followed by label");
13994                 }
13995                 /* Does this call does not enclose any variables? */
13996                 if ((ins->next->next->op != OP_INDEX) ||
13997                         (ins->next->next->u.cval != 0) ||
13998                         (result = MISC(ins->next->next, 0)) ||
13999                         (result->id & TRIPLE_FLAG_LOCAL)) {
14000                         continue;
14001                 }
14002                 index0 = ins->next->next;
14003                 /* The pattern is:
14004                  * 0 index result < 0 >
14005                  * 1 index 0 < ? >
14006                  * 2 index 1 < ? >
14007                  * 3 read  2
14008                  * 4 write 3 var
14009                  */
14010                 for(index0 = ins->next->next;
14011                         (index0->op == OP_INDEX) &&
14012                                 (MISC(index0, 0) == result) &&
14013                                 (index0->u.cval == 0) ; 
14014                         index0 = write->next)
14015                 {
14016                         index1 = index0->next;
14017                         index2 = index1->next;
14018                         read   = index2->next;
14019                         write  = read->next;
14020                         if ((index0->op != OP_INDEX) ||
14021                                 (index1->op != OP_INDEX) ||
14022                                 (index2->op != OP_INDEX) ||
14023                                 (read->op != OP_READ) ||
14024                                 (write->op != OP_WRITE) ||
14025                                 (MISC(index1, 0) != index0) ||
14026                                 (MISC(index2, 0) != index1) ||
14027                                 (RHS(read, 0) != index2) ||
14028                                 (RHS(write, 0) != read)) {
14029                                 internal_error(state, index0, "bad var read");
14030                         }
14031                         if (MISC(write, 0) == val) {
14032                                 return index2->u.cval;
14033                         }
14034                 }
14035         } while(next != first);
14036         return -1;
14037 }
14038
14039 static inline int enclose_triple(struct triple *ins)
14040 {
14041         return (ins && ((ins->type->type & TYPE_MASK) != TYPE_VOID));
14042 }
14043
14044 static void compute_closure_variables(struct compile_state *state,
14045         struct triple *me, struct triple *fcall, struct triple_reg_set **enclose)
14046 {
14047         struct triple_reg_set *set, *vars, **last_var;
14048         struct basic_blocks bb;
14049         struct reg_block *rb;
14050         struct block *block;
14051         struct triple *old_result, *first, *ins;
14052         size_t count, idx;
14053         unsigned long used_indicies;
14054         int i, max_index;
14055 #define MAX_INDICIES (sizeof(used_indicies)*CHAR_BIT)
14056 #define ID_BITS(X) ((X) & (TRIPLE_FLAG_LOCAL -1))
14057         struct { 
14058                 unsigned id;
14059                 int index;
14060         } *info;
14061
14062         
14063         /* Find the basic blocks of this function */
14064         bb.func = me;
14065         bb.first = RHS(me, 0);
14066         old_result = 0;
14067         if (!triple_is_ret(state, bb.first->prev)) {
14068                 bb.func = 0;
14069         } else {
14070                 old_result = fresult(state, me);
14071         }
14072         analyze_basic_blocks(state, &bb);
14073
14074         /* Find which variables are currently alive in a given block */
14075         rb = compute_variable_lifetimes(state, &bb);
14076
14077         /* Find the variables that are currently alive */
14078         block = block_of_triple(state, fcall);
14079         if (!block || (block->vertex <= 0) || (block->vertex > bb.last_vertex)) {
14080                 internal_error(state, fcall, "No reg block? block: %p", block);
14081         }
14082
14083 #if DEBUG_EXPLICIT_CLOSURES
14084         print_live_variables(state, &bb, rb, state->dbgout);
14085         fflush(state->dbgout);
14086 #endif
14087
14088         /* Count the number of triples in the function */
14089         first = RHS(me, 0);
14090         ins = first;
14091         count = 0;
14092         do {
14093                 count++;
14094                 ins = ins->next;
14095         } while(ins != first);
14096
14097         /* Allocate some memory to temorary hold the id info */
14098         info = xcmalloc(sizeof(*info) * (count +1), "info");
14099
14100         /* Mark the local function */
14101         first = RHS(me, 0);
14102         ins = first;
14103         idx = 1;
14104         do {
14105                 info[idx].id = ins->id;
14106                 ins->id = TRIPLE_FLAG_LOCAL | idx;
14107                 idx++;
14108                 ins = ins->next;
14109         } while(ins != first);
14110
14111         /* 
14112          * Build the list of variables to enclose.
14113          *
14114          * A target it to put the same variable in the
14115          * same slot for ever call of a given function.
14116          * After coloring this removes all of the variable
14117          * manipulation code.
14118          *
14119          * The list of variables to enclose is built ordered
14120          * program order because except in corner cases this
14121          * gives me the stability of assignment I need.
14122          *
14123          * To gurantee that stability I lookup the variables
14124          * to see where they have been used before and
14125          * I build my final list with the assigned indicies.
14126          */
14127         vars = 0;
14128         if (enclose_triple(old_result)) {
14129                 ordered_triple_set(&vars, old_result);
14130         }
14131         for(set = rb[block->vertex].out; set; set = set->next) {
14132                 if (!enclose_triple(set->member)) {
14133                         continue;
14134                 }
14135                 if ((set->member == fcall) || (set->member == old_result)) {
14136                         continue;
14137                 }
14138                 if (!local_triple(state, me, set->member)) {
14139                         internal_error(state, set->member, "not local?");
14140                 }
14141                 ordered_triple_set(&vars, set->member);
14142         }
14143
14144         /* Lookup the current indicies of the live varialbe */
14145         used_indicies = 0;
14146         max_index = -1;
14147         for(set = vars; set ; set = set->next) {
14148                 struct triple *ins;
14149                 int index;
14150                 ins = set->member;
14151                 index  = lookup_closure_index(state, me, ins);
14152                 info[ID_BITS(ins->id)].index = index;
14153                 if (index < 0) {
14154                         continue;
14155                 }
14156                 if (index >= MAX_INDICIES) {
14157                         internal_error(state, ins, "index unexpectedly large");
14158                 }
14159                 if (used_indicies & (1 << index)) {
14160                         internal_error(state, ins, "index previously used?");
14161                 }
14162                 /* Remember which indicies have been used */
14163                 used_indicies |= (1 << index);
14164                 if (index > max_index) {
14165                         max_index = index;
14166                 }
14167         }
14168
14169         /* Walk through the live variables and make certain
14170          * everything is assigned an index.
14171          */
14172         for(set = vars; set; set = set->next) {
14173                 struct triple *ins;
14174                 int index;
14175                 ins = set->member;
14176                 index = info[ID_BITS(ins->id)].index;
14177                 if (index >= 0) {
14178                         continue;
14179                 }
14180                 /* Find the lowest unused index value */
14181                 for(index = 0; index < MAX_INDICIES; index++) {
14182                         if (!(used_indicies & (1 << index))) {
14183                                 break;
14184                         }
14185                 }
14186                 if (index == MAX_INDICIES) {
14187                         internal_error(state, ins, "no free indicies?");
14188                 }
14189                 info[ID_BITS(ins->id)].index = index;
14190                 /* Remember which indicies have been used */
14191                 used_indicies |= (1 << index);
14192                 if (index > max_index) {
14193                         max_index = index;
14194                 }
14195         }
14196
14197         /* Build the return list of variables with positions matching
14198          * their indicies.
14199          */
14200         *enclose = 0;
14201         last_var = enclose;
14202         for(i = 0; i <= max_index; i++) {
14203                 struct triple *var;
14204                 var = 0;
14205                 if (used_indicies & (1 << i)) {
14206                         for(set = vars; set; set = set->next) {
14207                                 int index;
14208                                 index = info[ID_BITS(set->member->id)].index;
14209                                 if (index == i) {
14210                                         var = set->member;
14211                                         break;
14212                                 }
14213                         }
14214                         if (!var) {
14215                                 internal_error(state, me, "missing variable");
14216                         }
14217                 }
14218                 insert_triple_set(last_var, var);
14219                 last_var = &(*last_var)->next;
14220         }
14221
14222 #if DEBUG_EXPLICIT_CLOSURES
14223         /* Print out the variables to be enclosed */
14224         loc(state->dbgout, state, fcall);
14225         fprintf(state->dbgout, "Alive: \n");
14226         for(set = *enclose; set; set = set->next) {
14227                 display_triple(state->dbgout, set->member);
14228         }
14229         fflush(state->dbgout);
14230 #endif
14231
14232         /* Clear the marks */
14233         ins = first;
14234         do {
14235                 ins->id = info[ID_BITS(ins->id)].id;
14236                 ins = ins->next;
14237         } while(ins != first);
14238
14239         /* Release the ordered list of live variables */
14240         free_closure_variables(state, &vars);
14241
14242         /* Release the storage of the old ids */
14243         xfree(info);
14244
14245         /* Release the variable lifetime information */
14246         free_variable_lifetimes(state, &bb, rb);
14247
14248         /* Release the basic blocks of this function */
14249         free_basic_blocks(state, &bb);
14250 }
14251
14252 static void expand_function_call(
14253         struct compile_state *state, struct triple *me, struct triple *fcall)
14254 {
14255         /* Generate an ordinary function call */
14256         struct type *closure_type, **closure_next;
14257         struct triple *func, *func_first, *func_last, *retvar;
14258         struct triple *first;
14259         struct type *ptype, *rtype;
14260         struct triple *jmp;
14261         struct triple *ret_addr, *ret_loc, *ret_set;
14262         struct triple_reg_set *enclose, *set;
14263         int closure_idx, pvals, i;
14264
14265 #if DEBUG_EXPLICIT_CLOSURES
14266         FILE *fp = state->dbgout;
14267         fprintf(fp, "\ndisplay_func(me) ptr: %p\n", fcall);
14268         display_func(state, fp, MISC(fcall, 0));
14269         display_func(state, fp, me);
14270         fprintf(fp, "__________ %s _________ done\n\n", __FUNCTION__);
14271 #endif
14272
14273         /* Find the triples */
14274         func = MISC(fcall, 0);
14275         func_first = RHS(func, 0);
14276         retvar = fretaddr(state, func);
14277         func_last  = func_first->prev;
14278         first = fcall->next;
14279
14280         /* Find what I need to enclose */
14281         compute_closure_variables(state, me, fcall, &enclose);
14282
14283         /* Compute the closure type */
14284         closure_type = new_type(TYPE_TUPLE, 0, 0);
14285         closure_type->elements = 0;
14286         closure_next = &closure_type->left;
14287         for(set = enclose; set ; set = set->next) {
14288                 struct type *type;
14289                 type = &void_type;
14290                 if (set->member) {
14291                         type = set->member->type;
14292                 }
14293                 if (!*closure_next) {
14294                         *closure_next = type;
14295                 } else {
14296                         *closure_next = new_type(TYPE_PRODUCT, *closure_next, 
14297                                 type);
14298                         closure_next = &(*closure_next)->right;
14299                 }
14300                 closure_type->elements += 1;
14301         }
14302         if (closure_type->elements == 0) {
14303                 closure_type->type = TYPE_VOID;
14304         }
14305
14306
14307 #if DEBUG_EXPLICIT_CLOSURES
14308         fprintf(state->dbgout, "closure type: ");
14309         name_of(state->dbgout, closure_type);
14310         fprintf(state->dbgout, "\n");
14311 #endif
14312
14313         /* Update the called functions closure variable */
14314         closure_idx = add_closure_type(state, func, closure_type);
14315
14316         /* Generate some needed triples */
14317         ret_loc = label(state);
14318         ret_addr = triple(state, OP_ADDRCONST, &void_ptr_type, ret_loc, 0);
14319
14320         /* Pass the parameters to the new function */
14321         ptype = func->type->right;
14322         pvals = fcall->rhs;
14323         for(i = 0; i < pvals; i++) {
14324                 struct type *atype;
14325                 struct triple *arg, *param;
14326                 atype = ptype;
14327                 if ((ptype->type & TYPE_MASK) == TYPE_PRODUCT) {
14328                         atype = ptype->left;
14329                 }
14330                 param = farg(state, func, i);
14331                 if ((param->type->type & TYPE_MASK) != (atype->type & TYPE_MASK)) {
14332                         internal_error(state, fcall, "param type mismatch");
14333                 }
14334                 arg = RHS(fcall, i);
14335                 flatten(state, first, write_expr(state, param, arg));
14336                 ptype = ptype->right;
14337         }
14338         rtype = func->type->left;
14339
14340         /* Thread the triples together */
14341         ret_loc       = flatten(state, first, ret_loc);
14342
14343         /* Save the active variables in the result variable */
14344         for(i = 0, set = enclose; set ; set = set->next, i++) {
14345                 if (!set->member) {
14346                         continue;
14347                 }
14348                 flatten(state, ret_loc,
14349                         write_expr(state,
14350                                 closure_expr(state, func, closure_idx, i),
14351                                 read_expr(state, set->member)));
14352         }
14353
14354         /* Initialize the return value */
14355         if ((rtype->type & TYPE_MASK) != TYPE_VOID) {
14356                 flatten(state, ret_loc, 
14357                         write_expr(state, 
14358                                 deref_index(state, fresult(state, func), 1),
14359                                 new_triple(state, OP_UNKNOWNVAL, rtype,  0, 0)));
14360         }
14361
14362         ret_addr      = flatten(state, ret_loc, ret_addr);
14363         ret_set       = flatten(state, ret_loc, write_expr(state, retvar, ret_addr));
14364         jmp           = flatten(state, ret_loc, 
14365                 call(state, retvar, ret_addr, func_first, func_last));
14366
14367         /* Find the result */
14368         if ((rtype->type & TYPE_MASK) != TYPE_VOID) {
14369                 struct triple * result;
14370                 result = flatten(state, first, 
14371                         read_expr(state, 
14372                                 deref_index(state, fresult(state, func), 1)));
14373
14374                 propogate_use(state, fcall, result);
14375         }
14376
14377         /* Release the original fcall instruction */
14378         release_triple(state, fcall);
14379
14380         /* Restore the active variables from the result variable */
14381         for(i = 0, set = enclose; set ; set = set->next, i++) {
14382                 struct triple_set *use, *next;
14383                 struct triple *new;
14384                 struct basic_blocks bb;
14385                 if (!set->member || (set->member == fcall)) {
14386                         continue;
14387                 }
14388                 /* Generate an expression for the value */
14389                 new = flatten(state, first,
14390                         read_expr(state, 
14391                                 closure_expr(state, func, closure_idx, i)));
14392
14393
14394                 /* If the original is an lvalue restore the preserved value */
14395                 if (is_lvalue(state, set->member)) {
14396                         flatten(state, first,
14397                                 write_expr(state, set->member, new));
14398                         continue;
14399                 }
14400                 /*
14401                  * If the original is a value update the dominated uses.
14402                  */
14403                 
14404                 /* Analyze the basic blocks so I can see who dominates whom */
14405                 bb.func = me;
14406                 bb.first = RHS(me, 0);
14407                 if (!triple_is_ret(state, bb.first->prev)) {
14408                         bb.func = 0;
14409                 }
14410                 analyze_basic_blocks(state, &bb);
14411                 
14412
14413 #if DEBUG_EXPLICIT_CLOSURES
14414                 fprintf(state->errout, "Updating domindated uses: %p -> %p\n",
14415                         set->member, new);
14416 #endif
14417                 /* If fcall dominates the use update the expression */
14418                 for(use = set->member->use; use; use = next) {
14419                         /* Replace use modifies the use chain and 
14420                          * removes use, so I must take a copy of the
14421                          * next entry early.
14422                          */
14423                         next = use->next;
14424                         if (!tdominates(state, fcall, use->member)) {
14425                                 continue;
14426                         }
14427                         replace_use(state, set->member, new, use->member);
14428                 }
14429
14430                 /* Release the basic blocks, the instructions will be
14431                  * different next time, and flatten/insert_triple does
14432                  * not update the block values so I can't cache the analysis.
14433                  */
14434                 free_basic_blocks(state, &bb);
14435         }
14436
14437         /* Release the closure variable list */
14438         free_closure_variables(state, &enclose);
14439
14440         if (state->compiler->debug & DEBUG_INLINE) {
14441                 FILE *fp = state->dbgout;
14442                 fprintf(fp, "\n");
14443                 loc(fp, state, 0);
14444                 fprintf(fp, "\n__________ %s _________\n", __FUNCTION__);
14445                 display_func(state, fp, func);
14446                 display_func(state, fp, me);
14447                 fprintf(fp, "__________ %s _________ done\n\n", __FUNCTION__);
14448         }
14449
14450         return;
14451 }
14452
14453 static int do_inline(struct compile_state *state, struct triple *func)
14454 {
14455         int do_inline;
14456         int policy;
14457
14458         policy = state->compiler->flags & COMPILER_INLINE_MASK;
14459         switch(policy) {
14460         case COMPILER_INLINE_ALWAYS:
14461                 do_inline = 1;
14462                 if (func->type->type & ATTRIB_NOINLINE) {
14463                         error(state, func, "noinline with always_inline compiler option");
14464                 }
14465                 break;
14466         case COMPILER_INLINE_NEVER:
14467                 do_inline = 0;
14468                 if (func->type->type & ATTRIB_ALWAYS_INLINE) {
14469                         error(state, func, "always_inline with noinline compiler option");
14470                 }
14471                 break;
14472         case COMPILER_INLINE_DEFAULTON:
14473                 switch(func->type->type & STOR_MASK) {
14474                 case STOR_STATIC | STOR_INLINE:
14475                 case STOR_LOCAL  | STOR_INLINE:
14476                 case STOR_EXTERN | STOR_INLINE:
14477                         do_inline = 1;
14478                         break;
14479                 default:
14480                         do_inline = 1;
14481                         break;
14482                 }
14483                 break;
14484         case COMPILER_INLINE_DEFAULTOFF:
14485                 switch(func->type->type & STOR_MASK) {
14486                 case STOR_STATIC | STOR_INLINE:
14487                 case STOR_LOCAL  | STOR_INLINE:
14488                 case STOR_EXTERN | STOR_INLINE:
14489                         do_inline = 1;
14490                         break;
14491                 default:
14492                         do_inline = 0;
14493                         break;
14494                 }
14495                 break;
14496         case COMPILER_INLINE_NOPENALTY:
14497                 switch(func->type->type & STOR_MASK) {
14498                 case STOR_STATIC | STOR_INLINE:
14499                 case STOR_LOCAL  | STOR_INLINE:
14500                 case STOR_EXTERN | STOR_INLINE:
14501                         do_inline = 1;
14502                         break;
14503                 default:
14504                         do_inline = (func->u.cval == 1);
14505                         break;
14506                 }
14507                 break;
14508         default:
14509                 do_inline = 0;
14510                 internal_error(state, 0, "Unimplemented inline policy");
14511                 break;
14512         }
14513         /* Force inlining */
14514         if (func->type->type & ATTRIB_NOINLINE) {
14515                 do_inline = 0;
14516         }
14517         if (func->type->type & ATTRIB_ALWAYS_INLINE) {
14518                 do_inline = 1;
14519         }
14520         return do_inline;
14521 }
14522
14523 static void inline_function(struct compile_state *state, struct triple *me, void *arg)
14524 {
14525         struct triple *first, *ptr, *next;
14526         /* If the function is not used don't bother */
14527         if (me->u.cval <= 0) {
14528                 return;
14529         }
14530         if (state->compiler->debug & DEBUG_CALLS2) {
14531                 FILE *fp = state->dbgout;
14532                 fprintf(fp, "in: %s\n",
14533                         me->type->type_ident->name);
14534         }
14535
14536         first = RHS(me, 0);
14537         ptr = next = first;
14538         do {
14539                 struct triple *func, *prev;
14540                 ptr = next;
14541                 prev = ptr->prev;
14542                 next = ptr->next;
14543                 if (ptr->op != OP_FCALL) {
14544                         continue;
14545                 }
14546                 func = MISC(ptr, 0);
14547                 /* See if the function should be inlined */
14548                 if (!do_inline(state, func)) {
14549                         /* Put a label after the fcall */
14550                         post_triple(state, ptr, OP_LABEL, &void_type, 0, 0);
14551                         continue;
14552                 }
14553                 if (state->compiler->debug & DEBUG_CALLS) {
14554                         FILE *fp = state->dbgout;
14555                         if (state->compiler->debug & DEBUG_CALLS2) {
14556                                 loc(fp, state, ptr);
14557                         }
14558                         fprintf(fp, "inlining %s\n",
14559                                 func->type->type_ident->name);
14560                         fflush(fp);
14561                 }
14562
14563                 /* Update the function use counts */
14564                 func->u.cval -= 1;
14565
14566                 /* Replace the fcall with the called function */
14567                 expand_inline_call(state, me, ptr);
14568
14569                 next = prev->next;
14570         } while (next != first);
14571
14572         ptr = next = first;
14573         do {
14574                 struct triple *prev, *func;
14575                 ptr = next;
14576                 prev = ptr->prev;
14577                 next = ptr->next;
14578                 if (ptr->op != OP_FCALL) {
14579                         continue;
14580                 }
14581                 func = MISC(ptr, 0);
14582                 if (state->compiler->debug & DEBUG_CALLS) {
14583                         FILE *fp = state->dbgout;
14584                         if (state->compiler->debug & DEBUG_CALLS2) {
14585                                 loc(fp, state, ptr);
14586                         }
14587                         fprintf(fp, "calling %s\n",
14588                                 func->type->type_ident->name);
14589                         fflush(fp);
14590                 }
14591                 /* Replace the fcall with the instruction sequence
14592                  * needed to make the call.
14593                  */
14594                 expand_function_call(state, me, ptr);
14595                 next = prev->next;
14596         } while(next != first);
14597 }
14598
14599 static void inline_functions(struct compile_state *state, struct triple *func)
14600 {
14601         inline_function(state, func, 0);
14602         reverse_walk_functions(state, inline_function, 0);
14603 }
14604
14605 static void insert_function(struct compile_state *state,
14606         struct triple *func, void *arg)
14607 {
14608         struct triple *first, *end, *ffirst, *fend;
14609
14610         if (state->compiler->debug & DEBUG_INLINE) {
14611                 FILE *fp = state->errout;
14612                 fprintf(fp, "%s func count: %d\n", 
14613                         func->type->type_ident->name, func->u.cval);
14614         }
14615         if (func->u.cval == 0) {
14616                 return;
14617         }
14618
14619         /* Find the end points of the lists */
14620         first  = arg;
14621         end    = first->prev;
14622         ffirst = RHS(func, 0);
14623         fend   = ffirst->prev;
14624
14625         /* splice the lists together */
14626         end->next    = ffirst;
14627         ffirst->prev = end;
14628         fend->next   = first;
14629         first->prev  = fend;
14630 }
14631
14632 struct triple *input_asm(struct compile_state *state)
14633 {
14634         struct asm_info *info;
14635         struct triple *def;
14636         int i, out;
14637         
14638         info = xcmalloc(sizeof(*info), "asm_info");
14639         info->str = "";
14640
14641         out = sizeof(arch_input_regs)/sizeof(arch_input_regs[0]);
14642         memcpy(&info->tmpl.lhs, arch_input_regs, sizeof(arch_input_regs));
14643
14644         def = new_triple(state, OP_ASM, &void_type, out, 0);
14645         def->u.ainfo = info;
14646         def->id |= TRIPLE_FLAG_VOLATILE;
14647         
14648         for(i = 0; i < out; i++) {
14649                 struct triple *piece;
14650                 piece = triple(state, OP_PIECE, &int_type, def, 0);
14651                 piece->u.cval = i;
14652                 LHS(def, i) = piece;
14653         }
14654
14655         return def;
14656 }
14657
14658 struct triple *output_asm(struct compile_state *state)
14659 {
14660         struct asm_info *info;
14661         struct triple *def;
14662         int in;
14663         
14664         info = xcmalloc(sizeof(*info), "asm_info");
14665         info->str = "";
14666
14667         in = sizeof(arch_output_regs)/sizeof(arch_output_regs[0]);
14668         memcpy(&info->tmpl.rhs, arch_output_regs, sizeof(arch_output_regs));
14669
14670         def = new_triple(state, OP_ASM, &void_type, 0, in);
14671         def->u.ainfo = info;
14672         def->id |= TRIPLE_FLAG_VOLATILE;
14673         
14674         return def;
14675 }
14676
14677 static void join_functions(struct compile_state *state)
14678 {
14679         struct triple *jmp, *start, *end, *call, *in, *out, *func;
14680         struct file_state file;
14681         struct type *pnext, *param;
14682         struct type *result_type, *args_type;
14683         int idx;
14684
14685         /* Be clear the functions have not been joined yet */
14686         state->functions_joined = 0;
14687
14688         /* Dummy file state to get debug handing right */
14689         memset(&file, 0, sizeof(file));
14690         file.basename = "";
14691         file.line = 0;
14692         file.report_line = 0;
14693         file.report_name = file.basename;
14694         file.prev = state->file;
14695         state->file = &file;
14696         state->function = "";
14697
14698         if (!state->main_function) {
14699                 error(state, 0, "No functions to compile\n");
14700         }
14701
14702         /* The type of arguments */
14703         args_type   = state->main_function->type->right;
14704         /* The return type without any specifiers */
14705         result_type = clone_type(0, state->main_function->type->left);
14706
14707
14708         /* Verify the external arguments */
14709         if (registers_of(state, args_type) > ARCH_INPUT_REGS) {
14710                 error(state, state->main_function, 
14711                         "Too many external input arguments");
14712         }
14713         if (registers_of(state, result_type) > ARCH_OUTPUT_REGS) {
14714                 error(state, state->main_function, 
14715                         "Too many external output arguments");
14716         }
14717
14718         /* Lay down the basic program structure */
14719         end           = label(state);
14720         start         = label(state);
14721         start         = flatten(state, state->first, start);
14722         end           = flatten(state, state->first, end);
14723         in            = input_asm(state);
14724         out           = output_asm(state);
14725         call          = new_triple(state, OP_FCALL, result_type, -1, registers_of(state, args_type));
14726         MISC(call, 0) = state->main_function;
14727         in            = flatten(state, state->first, in);
14728         call          = flatten(state, state->first, call);
14729         out           = flatten(state, state->first, out);
14730
14731
14732         /* Read the external input arguments */
14733         pnext = args_type;
14734         idx = 0;
14735         while(pnext && ((pnext->type & TYPE_MASK) != TYPE_VOID)) {
14736                 struct triple *expr;
14737                 param = pnext;
14738                 pnext = 0;
14739                 if ((param->type & TYPE_MASK) == TYPE_PRODUCT) {
14740                         pnext = param->right;
14741                         param = param->left;
14742                 }
14743                 if (registers_of(state, param) != 1) {
14744                         error(state, state->main_function, 
14745                                 "Arg: %d %s requires multiple registers", 
14746                                 idx + 1, param->field_ident->name);
14747                 }
14748                 expr = read_expr(state, LHS(in, idx));
14749                 RHS(call, idx) = expr;
14750                 expr = flatten(state, call, expr);
14751                 use_triple(expr, call);
14752
14753                 idx++;  
14754         }
14755
14756
14757         /* Write the external output arguments */
14758         pnext = result_type;
14759         if ((pnext->type & TYPE_MASK) == TYPE_STRUCT) {
14760                 pnext = result_type->left;
14761         }
14762         for(idx = 0; idx < out->rhs; idx++) {
14763                 struct triple *expr;
14764                 param = pnext;
14765                 pnext = 0;
14766                 if (param && ((param->type & TYPE_MASK) == TYPE_PRODUCT)) {
14767                         pnext = param->right;
14768                         param = param->left;
14769                 }
14770                 if (param && ((param->type & TYPE_MASK) == TYPE_VOID)) {
14771                         param = 0;
14772                 }
14773                 if (param) {
14774                         if (registers_of(state, param) != 1) {
14775                                 error(state, state->main_function,
14776                                         "Result: %d %s requires multiple registers",
14777                                         idx, param->field_ident->name);
14778                         }
14779                         expr = read_expr(state, call);
14780                         if ((result_type->type & TYPE_MASK) == TYPE_STRUCT) {
14781                                 expr = deref_field(state, expr, param->field_ident);
14782                         }
14783                 } else {
14784                         expr = triple(state, OP_UNKNOWNVAL, &int_type, 0, 0);
14785                 }
14786                 flatten(state, out, expr);
14787                 RHS(out, idx) = expr;
14788                 use_triple(expr, out);
14789         }
14790
14791         /* Allocate a dummy containing function */
14792         func = triple(state, OP_LIST, 
14793                 new_type(TYPE_FUNCTION, &void_type, &void_type), 0, 0);
14794         func->type->type_ident = lookup(state, "", 0);
14795         RHS(func, 0) = state->first;
14796         func->u.cval = 1;
14797
14798         /* See which functions are called, and how often */
14799         mark_live_functions(state);
14800         inline_functions(state, func);
14801         walk_functions(state, insert_function, end);
14802
14803         if (start->next != end) {
14804                 jmp = flatten(state, start, branch(state, end, 0));
14805         }
14806
14807         /* OK now the functions have been joined. */
14808         state->functions_joined = 1;
14809
14810         /* Done now cleanup */
14811         state->file = file.prev;
14812         state->function = 0;
14813 }
14814
14815 /*
14816  * Data structurs for optimation.
14817  */
14818
14819
14820 static int do_use_block(
14821         struct block *used, struct block_set **head, struct block *user, 
14822         int front)
14823 {
14824         struct block_set **ptr, *new;
14825         if (!used)
14826                 return 0;
14827         if (!user)
14828                 return 0;
14829         ptr = head;
14830         while(*ptr) {
14831                 if ((*ptr)->member == user) {
14832                         return 0;
14833                 }
14834                 ptr = &(*ptr)->next;
14835         }
14836         new = xcmalloc(sizeof(*new), "block_set");
14837         new->member = user;
14838         if (front) {
14839                 new->next = *head;
14840                 *head = new;
14841         }
14842         else {
14843                 new->next = 0;
14844                 *ptr = new;
14845         }
14846         return 1;
14847 }
14848 static int do_unuse_block(
14849         struct block *used, struct block_set **head, struct block *unuser)
14850 {
14851         struct block_set *use, **ptr;
14852         int count;
14853         count = 0;
14854         ptr = head;
14855         while(*ptr) {
14856                 use = *ptr;
14857                 if (use->member == unuser) {
14858                         *ptr = use->next;
14859                         memset(use, -1, sizeof(*use));
14860                         xfree(use);
14861                         count += 1;
14862                 }
14863                 else {
14864                         ptr = &use->next;
14865                 }
14866         }
14867         return count;
14868 }
14869
14870 static void use_block(struct block *used, struct block *user)
14871 {
14872         int count;
14873         /* Append new to the head of the list, print_block
14874          * depends on this.
14875          */
14876         count = do_use_block(used, &used->use, user, 1); 
14877         used->users += count;
14878 }
14879 static void unuse_block(struct block *used, struct block *unuser)
14880 {
14881         int count;
14882         count = do_unuse_block(used, &used->use, unuser); 
14883         used->users -= count;
14884 }
14885
14886 static void add_block_edge(struct block *block, struct block *edge, int front)
14887 {
14888         int count;
14889         count = do_use_block(block, &block->edges, edge, front);
14890         block->edge_count += count;
14891 }
14892
14893 static void remove_block_edge(struct block *block, struct block *edge)
14894 {
14895         int count;
14896         count = do_unuse_block(block, &block->edges, edge);
14897         block->edge_count -= count;
14898 }
14899
14900 static void idom_block(struct block *idom, struct block *user)
14901 {
14902         do_use_block(idom, &idom->idominates, user, 0);
14903 }
14904
14905 static void unidom_block(struct block *idom, struct block *unuser)
14906 {
14907         do_unuse_block(idom, &idom->idominates, unuser);
14908 }
14909
14910 static void domf_block(struct block *block, struct block *domf)
14911 {
14912         do_use_block(block, &block->domfrontier, domf, 0);
14913 }
14914
14915 static void undomf_block(struct block *block, struct block *undomf)
14916 {
14917         do_unuse_block(block, &block->domfrontier, undomf);
14918 }
14919
14920 static void ipdom_block(struct block *ipdom, struct block *user)
14921 {
14922         do_use_block(ipdom, &ipdom->ipdominates, user, 0);
14923 }
14924
14925 static void unipdom_block(struct block *ipdom, struct block *unuser)
14926 {
14927         do_unuse_block(ipdom, &ipdom->ipdominates, unuser);
14928 }
14929
14930 static void ipdomf_block(struct block *block, struct block *ipdomf)
14931 {
14932         do_use_block(block, &block->ipdomfrontier, ipdomf, 0);
14933 }
14934
14935 static void unipdomf_block(struct block *block, struct block *unipdomf)
14936 {
14937         do_unuse_block(block, &block->ipdomfrontier, unipdomf);
14938 }
14939
14940 static int walk_triples(
14941         struct compile_state *state, 
14942         int (*cb)(struct compile_state *state, struct triple *ptr, void *arg),
14943         void *arg)
14944 {
14945         struct triple *ptr;
14946         int result;
14947         ptr = state->first;
14948         do {
14949                 result = cb(state, ptr, arg);
14950                 if (ptr->next->prev != ptr) {
14951                         internal_error(state, ptr->next, "bad prev");
14952                 }
14953                 ptr = ptr->next;
14954         } while((result == 0) && (ptr != state->first));
14955         return result;
14956 }
14957
14958 #define PRINT_LIST 1
14959 static int do_print_triple(struct compile_state *state, struct triple *ins, void *arg)
14960 {
14961         FILE *fp = arg;
14962         int op;
14963         op = ins->op;
14964         if (op == OP_LIST) {
14965 #if !PRINT_LIST
14966                 return 0;
14967 #endif
14968         }
14969         if ((op == OP_LABEL) && (ins->use)) {
14970                 fprintf(fp, "\n%p:\n", ins);
14971         }
14972         display_triple(fp, ins);
14973
14974         if (triple_is_branch(state, ins) && ins->use && 
14975                 (ins->op != OP_RET) && (ins->op != OP_FCALL)) {
14976                 internal_error(state, ins, "branch used?");
14977         }
14978         if (triple_is_branch(state, ins)) {
14979                 fprintf(fp, "\n");
14980         }
14981         return 0;
14982 }
14983
14984 static void print_triples(struct compile_state *state)
14985 {
14986         if (state->compiler->debug & DEBUG_TRIPLES) {
14987                 FILE *fp = state->dbgout;
14988                 fprintf(fp, "--------------- triples ---------------\n");
14989                 walk_triples(state, do_print_triple, fp);
14990                 fprintf(fp, "\n");
14991         }
14992 }
14993
14994 struct cf_block {
14995         struct block *block;
14996 };
14997 static void find_cf_blocks(struct cf_block *cf, struct block *block)
14998 {
14999         struct block_set *edge;
15000         if (!block || (cf[block->vertex].block == block)) {
15001                 return;
15002         }
15003         cf[block->vertex].block = block;
15004         for(edge = block->edges; edge; edge = edge->next) {
15005                 find_cf_blocks(cf, edge->member);
15006         }
15007 }
15008
15009 static void print_control_flow(struct compile_state *state,
15010         FILE *fp, struct basic_blocks *bb)
15011 {
15012         struct cf_block *cf;
15013         int i;
15014         fprintf(fp, "\ncontrol flow\n");
15015         cf = xcmalloc(sizeof(*cf) * (bb->last_vertex + 1), "cf_block");
15016         find_cf_blocks(cf, bb->first_block);
15017
15018         for(i = 1; i <= bb->last_vertex; i++) {
15019                 struct block *block;
15020                 struct block_set *edge;
15021                 block = cf[i].block;
15022                 if (!block)
15023                         continue;
15024                 fprintf(fp, "(%p) %d:", block, block->vertex);
15025                 for(edge = block->edges; edge; edge = edge->next) {
15026                         fprintf(fp, " %d", edge->member->vertex);
15027                 }
15028                 fprintf(fp, "\n");
15029         }
15030
15031         xfree(cf);
15032 }
15033
15034 static void free_basic_block(struct compile_state *state, struct block *block)
15035 {
15036         struct block_set *edge, *entry;
15037         struct block *child;
15038         if (!block) {
15039                 return;
15040         }
15041         if (block->vertex == -1) {
15042                 return;
15043         }
15044         block->vertex = -1;
15045         for(edge = block->edges; edge; edge = edge->next) {
15046                 if (edge->member) {
15047                         unuse_block(edge->member, block);
15048                 }
15049         }
15050         if (block->idom) {
15051                 unidom_block(block->idom, block);
15052         }
15053         block->idom = 0;
15054         if (block->ipdom) {
15055                 unipdom_block(block->ipdom, block);
15056         }
15057         block->ipdom = 0;
15058         while((entry = block->use)) {
15059                 child = entry->member;
15060                 unuse_block(block, child);
15061                 if (child && (child->vertex != -1)) {
15062                         for(edge = child->edges; edge; edge = edge->next) {
15063                                 edge->member = 0;
15064                         }
15065                 }
15066         }
15067         while((entry = block->idominates)) {
15068                 child = entry->member;
15069                 unidom_block(block, child);
15070                 if (child && (child->vertex != -1)) {
15071                         child->idom = 0;
15072                 }
15073         }
15074         while((entry = block->domfrontier)) {
15075                 child = entry->member;
15076                 undomf_block(block, child);
15077         }
15078         while((entry = block->ipdominates)) {
15079                 child = entry->member;
15080                 unipdom_block(block, child);
15081                 if (child && (child->vertex != -1)) {
15082                         child->ipdom = 0;
15083                 }
15084         }
15085         while((entry = block->ipdomfrontier)) {
15086                 child = entry->member;
15087                 unipdomf_block(block, child);
15088         }
15089         if (block->users != 0) {
15090                 internal_error(state, 0, "block still has users");
15091         }
15092         while((edge = block->edges)) {
15093                 child = edge->member;
15094                 remove_block_edge(block, child);
15095                 
15096                 if (child && (child->vertex != -1)) {
15097                         free_basic_block(state, child);
15098                 }
15099         }
15100         memset(block, -1, sizeof(*block));
15101         xfree(block);
15102 }
15103
15104 static void free_basic_blocks(struct compile_state *state, 
15105         struct basic_blocks *bb)
15106 {
15107         struct triple *first, *ins;
15108         free_basic_block(state, bb->first_block);
15109         bb->last_vertex = 0;
15110         bb->first_block = bb->last_block = 0;
15111         first = bb->first;
15112         ins = first;
15113         do {
15114                 if (triple_stores_block(state, ins)) {
15115                         ins->u.block = 0;
15116                 }
15117                 ins = ins->next;
15118         } while(ins != first);
15119         
15120 }
15121
15122 static struct block *basic_block(struct compile_state *state, 
15123         struct basic_blocks *bb, struct triple *first)
15124 {
15125         struct block *block;
15126         struct triple *ptr;
15127         if (!triple_is_label(state, first)) {
15128                 internal_error(state, first, "block does not start with a label");
15129         }
15130         /* See if this basic block has already been setup */
15131         if (first->u.block != 0) {
15132                 return first->u.block;
15133         }
15134         /* Allocate another basic block structure */
15135         bb->last_vertex += 1;
15136         block = xcmalloc(sizeof(*block), "block");
15137         block->first = block->last = first;
15138         block->vertex = bb->last_vertex;
15139         ptr = first;
15140         do {
15141                 if ((ptr != first) && triple_is_label(state, ptr) && (ptr->use)) { 
15142                         break;
15143                 }
15144                 block->last = ptr;
15145                 /* If ptr->u is not used remember where the baic block is */
15146                 if (triple_stores_block(state, ptr)) {
15147                         ptr->u.block = block;
15148                 }
15149                 if (triple_is_branch(state, ptr)) {
15150                         break;
15151                 }
15152                 ptr = ptr->next;
15153         } while (ptr != bb->first);
15154         if ((ptr == bb->first) ||
15155                 ((ptr->next == bb->first) && (
15156                         triple_is_end(state, ptr) || 
15157                         triple_is_ret(state, ptr))))
15158         {
15159                 /* The block has no outflowing edges */
15160         }
15161         else if (triple_is_label(state, ptr)) {
15162                 struct block *next;
15163                 next = basic_block(state, bb, ptr);
15164                 add_block_edge(block, next, 0);
15165                 use_block(next, block);
15166         }
15167         else if (triple_is_branch(state, ptr)) {
15168                 struct triple **expr, *first;
15169                 struct block *child;
15170                 /* Find the branch targets.
15171                  * I special case the first branch as that magically
15172                  * avoids some difficult cases for the register allocator.
15173                  */
15174                 expr = triple_edge_targ(state, ptr, 0);
15175                 if (!expr) {
15176                         internal_error(state, ptr, "branch without targets");
15177                 }
15178                 first = *expr;
15179                 expr = triple_edge_targ(state, ptr, expr);
15180                 for(; expr; expr = triple_edge_targ(state, ptr, expr)) {
15181                         if (!*expr) continue;
15182                         child = basic_block(state, bb, *expr);
15183                         use_block(child, block);
15184                         add_block_edge(block, child, 0);
15185                 }
15186                 if (first) {
15187                         child = basic_block(state, bb, first);
15188                         use_block(child, block);
15189                         add_block_edge(block, child, 1);
15190
15191                         /* Be certain the return block of a call is
15192                          * in a basic block.  When it is not find
15193                          * start of the block, insert a label if
15194                          * necessary and build the basic block.
15195                          * Then add a fake edge from the start block
15196                          * to the return block of the function.
15197                          */
15198                         if (state->functions_joined && triple_is_call(state, ptr)
15199                                 && !block_of_triple(state, MISC(ptr, 0))) {
15200                                 struct block *tail;
15201                                 struct triple *start;
15202                                 start = triple_to_block_start(state, MISC(ptr, 0));
15203                                 if (!triple_is_label(state, start)) {
15204                                         start = pre_triple(state,
15205                                                 start, OP_LABEL, &void_type, 0, 0);
15206                                 }
15207                                 tail = basic_block(state, bb, start);
15208                                 add_block_edge(child, tail, 0);
15209                                 use_block(tail, child);
15210                         }
15211                 }
15212         }
15213         else {
15214                 internal_error(state, 0, "Bad basic block split");
15215         }
15216 #if 0
15217 {
15218         struct block_set *edge;
15219         FILE *fp = state->errout;
15220         fprintf(fp, "basic_block: %10p [%2d] ( %10p - %10p )",
15221                 block, block->vertex, 
15222                 block->first, block->last);
15223         for(edge = block->edges; edge; edge = edge->next) {
15224                 fprintf(fp, " %10p [%2d]",
15225                         edge->member ? edge->member->first : 0,
15226                         edge->member ? edge->member->vertex : -1);
15227         }
15228         fprintf(fp, "\n");
15229 }
15230 #endif
15231         return block;
15232 }
15233
15234
15235 static void walk_blocks(struct compile_state *state, struct basic_blocks *bb,
15236         void (*cb)(struct compile_state *state, struct block *block, void *arg),
15237         void *arg)
15238 {
15239         struct triple *ptr, *first;
15240         struct block *last_block;
15241         last_block = 0;
15242         first = bb->first;
15243         ptr = first;
15244         do {
15245                 if (triple_stores_block(state, ptr)) {
15246                         struct block *block;
15247                         block = ptr->u.block;
15248                         if (block && (block != last_block)) {
15249                                 cb(state, block, arg);
15250                         }
15251                         last_block = block;
15252                 }
15253                 ptr = ptr->next;
15254         } while(ptr != first);
15255 }
15256
15257 static void print_block(
15258         struct compile_state *state, struct block *block, void *arg)
15259 {
15260         struct block_set *user, *edge;
15261         struct triple *ptr;
15262         FILE *fp = arg;
15263
15264         fprintf(fp, "\nblock: %p (%d) ",
15265                 block, 
15266                 block->vertex);
15267
15268         for(edge = block->edges; edge; edge = edge->next) {
15269                 fprintf(fp, " %p<-%p",
15270                         edge->member,
15271                         (edge->member && edge->member->use)?
15272                         edge->member->use->member : 0);
15273         }
15274         fprintf(fp, "\n");
15275         if (block->first->op == OP_LABEL) {
15276                 fprintf(fp, "%p:\n", block->first);
15277         }
15278         for(ptr = block->first; ; ) {
15279                 display_triple(fp, ptr);
15280                 if (ptr == block->last)
15281                         break;
15282                 ptr = ptr->next;
15283                 if (ptr == block->first) {
15284                         internal_error(state, 0, "missing block last?");
15285                 }
15286         }
15287         fprintf(fp, "users %d: ", block->users);
15288         for(user = block->use; user; user = user->next) {
15289                 fprintf(fp, "%p (%d) ", 
15290                         user->member,
15291                         user->member->vertex);
15292         }
15293         fprintf(fp,"\n\n");
15294 }
15295
15296
15297 static void romcc_print_blocks(struct compile_state *state, FILE *fp)
15298 {
15299         fprintf(fp, "--------------- blocks ---------------\n");
15300         walk_blocks(state, &state->bb, print_block, fp);
15301 }
15302 static void print_blocks(struct compile_state *state, const char *func, FILE *fp)
15303 {
15304         static void print_dominators(struct compile_state *state, FILE *fp, struct basic_blocks *bb);
15305         static void print_dominance_frontiers(struct compile_state *state, FILE *fp, struct basic_blocks *bb);
15306         if (state->compiler->debug & DEBUG_BASIC_BLOCKS) {
15307                 fprintf(fp, "After %s\n", func);
15308                 romcc_print_blocks(state, fp);
15309                 if (state->compiler->debug & DEBUG_FDOMINATORS) {
15310                         print_dominators(state, fp, &state->bb);
15311                         print_dominance_frontiers(state, fp, &state->bb);
15312                 }
15313                 print_control_flow(state, fp, &state->bb);
15314         }
15315 }
15316
15317 static void prune_nonblock_triples(struct compile_state *state, 
15318         struct basic_blocks *bb)
15319 {
15320         struct block *block;
15321         struct triple *first, *ins, *next;
15322         /* Delete the triples not in a basic block */
15323         block = 0;
15324         first = bb->first;
15325         ins = first;
15326         do {
15327                 next = ins->next;
15328                 if (ins->op == OP_LABEL) {
15329                         block = ins->u.block;
15330                 }
15331                 if (!block) {
15332                         struct triple_set *use;
15333                         for(use = ins->use; use; use = use->next) {
15334                                 struct block *block;
15335                                 block = block_of_triple(state, use->member);
15336                                 if (block != 0) {
15337                                         internal_error(state, ins, "pruning used ins?");
15338                                 }
15339                         }
15340                         release_triple(state, ins);
15341                 }
15342                 if (block && block->last == ins) {
15343                         block = 0;
15344                 }
15345                 ins = next;
15346         } while(ins != first);
15347 }
15348
15349 static void setup_basic_blocks(struct compile_state *state, 
15350         struct basic_blocks *bb)
15351 {
15352         if (!triple_stores_block(state, bb->first)) {
15353                 internal_error(state, 0, "ins will not store block?");
15354         }
15355         /* Initialize the state */
15356         bb->first_block = bb->last_block = 0;
15357         bb->last_vertex = 0;
15358         free_basic_blocks(state, bb);
15359
15360         /* Find the basic blocks */
15361         bb->first_block = basic_block(state, bb, bb->first);
15362
15363         /* Be certain the last instruction of a function, or the
15364          * entire program is in a basic block.  When it is not find 
15365          * the start of the block, insert a label if necessary and build 
15366          * basic block.  Then add a fake edge from the start block
15367          * to the final block.
15368          */
15369         if (!block_of_triple(state, bb->first->prev)) {
15370                 struct triple *start;
15371                 struct block *tail;
15372                 start = triple_to_block_start(state, bb->first->prev);
15373                 if (!triple_is_label(state, start)) {
15374                         start = pre_triple(state,
15375                                 start, OP_LABEL, &void_type, 0, 0);
15376                 }
15377                 tail = basic_block(state, bb, start);
15378                 add_block_edge(bb->first_block, tail, 0);
15379                 use_block(tail, bb->first_block);
15380         }
15381         
15382         /* Find the last basic block.
15383          */
15384         bb->last_block = block_of_triple(state, bb->first->prev);
15385
15386         /* Delete the triples not in a basic block */
15387         prune_nonblock_triples(state, bb);
15388
15389 #if 0
15390         /* If we are debugging print what I have just done */
15391         if (state->compiler->debug & DEBUG_BASIC_BLOCKS) {
15392                 print_blocks(state, state->dbgout);
15393                 print_control_flow(state, bb);
15394         }
15395 #endif
15396 }
15397
15398
15399 struct sdom_block {
15400         struct block *block;
15401         struct sdom_block *sdominates;
15402         struct sdom_block *sdom_next;
15403         struct sdom_block *sdom;
15404         struct sdom_block *label;
15405         struct sdom_block *parent;
15406         struct sdom_block *ancestor;
15407         int vertex;
15408 };
15409
15410
15411 static void unsdom_block(struct sdom_block *block)
15412 {
15413         struct sdom_block **ptr;
15414         if (!block->sdom_next) {
15415                 return;
15416         }
15417         ptr = &block->sdom->sdominates;
15418         while(*ptr) {
15419                 if ((*ptr) == block) {
15420                         *ptr = block->sdom_next;
15421                         return;
15422                 }
15423                 ptr = &(*ptr)->sdom_next;
15424         }
15425 }
15426
15427 static void sdom_block(struct sdom_block *sdom, struct sdom_block *block)
15428 {
15429         unsdom_block(block);
15430         block->sdom = sdom;
15431         block->sdom_next = sdom->sdominates;
15432         sdom->sdominates = block;
15433 }
15434
15435
15436
15437 static int initialize_sdblock(struct sdom_block *sd,
15438         struct block *parent, struct block *block, int vertex)
15439 {
15440         struct block_set *edge;
15441         if (!block || (sd[block->vertex].block == block)) {
15442                 return vertex;
15443         }
15444         vertex += 1;
15445         /* Renumber the blocks in a convinient fashion */
15446         block->vertex = vertex;
15447         sd[vertex].block    = block;
15448         sd[vertex].sdom     = &sd[vertex];
15449         sd[vertex].label    = &sd[vertex];
15450         sd[vertex].parent   = parent? &sd[parent->vertex] : 0;
15451         sd[vertex].ancestor = 0;
15452         sd[vertex].vertex   = vertex;
15453         for(edge = block->edges; edge; edge = edge->next) {
15454                 vertex = initialize_sdblock(sd, block, edge->member, vertex);
15455         }
15456         return vertex;
15457 }
15458
15459 static int initialize_spdblock(
15460         struct compile_state *state, struct sdom_block *sd,
15461         struct block *parent, struct block *block, int vertex)
15462 {
15463         struct block_set *user;
15464         if (!block || (sd[block->vertex].block == block)) {
15465                 return vertex;
15466         }
15467         vertex += 1;
15468         /* Renumber the blocks in a convinient fashion */
15469         block->vertex = vertex;
15470         sd[vertex].block    = block;
15471         sd[vertex].sdom     = &sd[vertex];
15472         sd[vertex].label    = &sd[vertex];
15473         sd[vertex].parent   = parent? &sd[parent->vertex] : 0;
15474         sd[vertex].ancestor = 0;
15475         sd[vertex].vertex   = vertex;
15476         for(user = block->use; user; user = user->next) {
15477                 vertex = initialize_spdblock(state, sd, block, user->member, vertex);
15478         }
15479         return vertex;
15480 }
15481
15482 static int setup_spdblocks(struct compile_state *state, 
15483         struct basic_blocks *bb, struct sdom_block *sd)
15484 {
15485         struct block *block;
15486         int vertex;
15487         /* Setup as many sdpblocks as possible without using fake edges */
15488         vertex = initialize_spdblock(state, sd, 0, bb->last_block, 0);
15489
15490         /* Walk through the graph and find unconnected blocks.  Add a
15491          * fake edge from the unconnected blocks to the end of the
15492          * graph. 
15493          */
15494         block = bb->first_block->last->next->u.block;
15495         for(; block && block != bb->first_block; block = block->last->next->u.block) {
15496                 if (sd[block->vertex].block == block) {
15497                         continue;
15498                 }
15499 #if DEBUG_SDP_BLOCKS
15500                 {
15501                         FILE *fp = state->errout;
15502                         fprintf(fp, "Adding %d\n", vertex +1);
15503                 }
15504 #endif
15505                 add_block_edge(block, bb->last_block, 0);
15506                 use_block(bb->last_block, block);
15507
15508                 vertex = initialize_spdblock(state, sd, bb->last_block, block, vertex);
15509         }
15510         return vertex;
15511 }
15512
15513 static void compress_ancestors(struct sdom_block *v)
15514 {
15515         /* This procedure assumes ancestor(v) != 0 */
15516         /* if (ancestor(ancestor(v)) != 0) {
15517          *      compress(ancestor(ancestor(v)));
15518          *      if (semi(label(ancestor(v))) < semi(label(v))) {
15519          *              label(v) = label(ancestor(v));
15520          *      }
15521          *      ancestor(v) = ancestor(ancestor(v));
15522          * }
15523          */
15524         if (!v->ancestor) {
15525                 return;
15526         }
15527         if (v->ancestor->ancestor) {
15528                 compress_ancestors(v->ancestor->ancestor);
15529                 if (v->ancestor->label->sdom->vertex < v->label->sdom->vertex) {
15530                         v->label = v->ancestor->label;
15531                 }
15532                 v->ancestor = v->ancestor->ancestor;
15533         }
15534 }
15535
15536 static void compute_sdom(struct compile_state *state, 
15537         struct basic_blocks *bb, struct sdom_block *sd)
15538 {
15539         int i;
15540         /* // step 2 
15541          *  for each v <= pred(w) {
15542          *      u = EVAL(v);
15543          *      if (semi[u] < semi[w] { 
15544          *              semi[w] = semi[u]; 
15545          *      } 
15546          * }
15547          * add w to bucket(vertex(semi[w]));
15548          * LINK(parent(w), w);
15549          *
15550          * // step 3
15551          * for each v <= bucket(parent(w)) {
15552          *      delete v from bucket(parent(w));
15553          *      u = EVAL(v);
15554          *      dom(v) = (semi[u] < semi[v]) ? u : parent(w);
15555          * }
15556          */
15557         for(i = bb->last_vertex; i >= 2; i--) {
15558                 struct sdom_block *v, *parent, *next;
15559                 struct block_set *user;
15560                 struct block *block;
15561                 block = sd[i].block;
15562                 parent = sd[i].parent;
15563                 /* Step 2 */
15564                 for(user = block->use; user; user = user->next) {
15565                         struct sdom_block *v, *u;
15566                         v = &sd[user->member->vertex];
15567                         u = !(v->ancestor)? v : (compress_ancestors(v), v->label);
15568                         if (u->sdom->vertex < sd[i].sdom->vertex) {
15569                                 sd[i].sdom = u->sdom;
15570                         }
15571                 }
15572                 sdom_block(sd[i].sdom, &sd[i]);
15573                 sd[i].ancestor = parent;
15574                 /* Step 3 */
15575                 for(v = parent->sdominates; v; v = next) {
15576                         struct sdom_block *u;
15577                         next = v->sdom_next;
15578                         unsdom_block(v);
15579                         u = (!v->ancestor) ? v : (compress_ancestors(v), v->label);
15580                         v->block->idom = (u->sdom->vertex < v->sdom->vertex)? 
15581                                 u->block : parent->block;
15582                 }
15583         }
15584 }
15585
15586 static void compute_spdom(struct compile_state *state, 
15587         struct basic_blocks *bb, struct sdom_block *sd)
15588 {
15589         int i;
15590         /* // step 2 
15591          *  for each v <= pred(w) {
15592          *      u = EVAL(v);
15593          *      if (semi[u] < semi[w] { 
15594          *              semi[w] = semi[u]; 
15595          *      } 
15596          * }
15597          * add w to bucket(vertex(semi[w]));
15598          * LINK(parent(w), w);
15599          *
15600          * // step 3
15601          * for each v <= bucket(parent(w)) {
15602          *      delete v from bucket(parent(w));
15603          *      u = EVAL(v);
15604          *      dom(v) = (semi[u] < semi[v]) ? u : parent(w);
15605          * }
15606          */
15607         for(i = bb->last_vertex; i >= 2; i--) {
15608                 struct sdom_block *u, *v, *parent, *next;
15609                 struct block_set *edge;
15610                 struct block *block;
15611                 block = sd[i].block;
15612                 parent = sd[i].parent;
15613                 /* Step 2 */
15614                 for(edge = block->edges; edge; edge = edge->next) {
15615                         v = &sd[edge->member->vertex];
15616                         u = !(v->ancestor)? v : (compress_ancestors(v), v->label);
15617                         if (u->sdom->vertex < sd[i].sdom->vertex) {
15618                                 sd[i].sdom = u->sdom;
15619                         }
15620                 }
15621                 sdom_block(sd[i].sdom, &sd[i]);
15622                 sd[i].ancestor = parent;
15623                 /* Step 3 */
15624                 for(v = parent->sdominates; v; v = next) {
15625                         struct sdom_block *u;
15626                         next = v->sdom_next;
15627                         unsdom_block(v);
15628                         u = (!v->ancestor) ? v : (compress_ancestors(v), v->label);
15629                         v->block->ipdom = (u->sdom->vertex < v->sdom->vertex)? 
15630                                 u->block : parent->block;
15631                 }
15632         }
15633 }
15634
15635 static void compute_idom(struct compile_state *state, 
15636         struct basic_blocks *bb, struct sdom_block *sd)
15637 {
15638         int i;
15639         for(i = 2; i <= bb->last_vertex; i++) {
15640                 struct block *block;
15641                 block = sd[i].block;
15642                 if (block->idom->vertex != sd[i].sdom->vertex) {
15643                         block->idom = block->idom->idom;
15644                 }
15645                 idom_block(block->idom, block);
15646         }
15647         sd[1].block->idom = 0;
15648 }
15649
15650 static void compute_ipdom(struct compile_state *state, 
15651         struct basic_blocks *bb, struct sdom_block *sd)
15652 {
15653         int i;
15654         for(i = 2; i <= bb->last_vertex; i++) {
15655                 struct block *block;
15656                 block = sd[i].block;
15657                 if (block->ipdom->vertex != sd[i].sdom->vertex) {
15658                         block->ipdom = block->ipdom->ipdom;
15659                 }
15660                 ipdom_block(block->ipdom, block);
15661         }
15662         sd[1].block->ipdom = 0;
15663 }
15664
15665         /* Theorem 1:
15666          *   Every vertex of a flowgraph G = (V, E, r) except r has
15667          *   a unique immediate dominator.  
15668          *   The edges {(idom(w), w) |w <= V - {r}} form a directed tree
15669          *   rooted at r, called the dominator tree of G, such that 
15670          *   v dominates w if and only if v is a proper ancestor of w in
15671          *   the dominator tree.
15672          */
15673         /* Lemma 1:  
15674          *   If v and w are vertices of G such that v <= w,
15675          *   than any path from v to w must contain a common ancestor
15676          *   of v and w in T.
15677          */
15678         /* Lemma 2:  For any vertex w != r, idom(w) -> w */
15679         /* Lemma 3:  For any vertex w != r, sdom(w) -> w */
15680         /* Lemma 4:  For any vertex w != r, idom(w) -> sdom(w) */
15681         /* Theorem 2:
15682          *   Let w != r.  Suppose every u for which sdom(w) -> u -> w satisfies
15683          *   sdom(u) >= sdom(w).  Then idom(w) = sdom(w).
15684          */
15685         /* Theorem 3:
15686          *   Let w != r and let u be a vertex for which sdom(u) is 
15687          *   minimum amoung vertices u satisfying sdom(w) -> u -> w.
15688          *   Then sdom(u) <= sdom(w) and idom(u) = idom(w).
15689          */
15690         /* Lemma 5:  Let vertices v,w satisfy v -> w.
15691          *           Then v -> idom(w) or idom(w) -> idom(v)
15692          */
15693
15694 static void find_immediate_dominators(struct compile_state *state,
15695         struct basic_blocks *bb)
15696 {
15697         struct sdom_block *sd;
15698         /* w->sdom = min{v| there is a path v = v0,v1,...,vk = w such that:
15699          *           vi > w for (1 <= i <= k - 1}
15700          */
15701         /* Theorem 4:
15702          *   For any vertex w != r.
15703          *   sdom(w) = min(
15704          *                 {v|(v,w) <= E  and v < w } U 
15705          *                 {sdom(u) | u > w and there is an edge (v, w) such that u -> v})
15706          */
15707         /* Corollary 1:
15708          *   Let w != r and let u be a vertex for which sdom(u) is 
15709          *   minimum amoung vertices u satisfying sdom(w) -> u -> w.
15710          *   Then:
15711          *                   { sdom(w) if sdom(w) = sdom(u),
15712          *        idom(w) = {
15713          *                   { idom(u) otherwise
15714          */
15715         /* The algorithm consists of the following 4 steps.
15716          * Step 1.  Carry out a depth-first search of the problem graph.  
15717          *    Number the vertices from 1 to N as they are reached during
15718          *    the search.  Initialize the variables used in succeeding steps.
15719          * Step 2.  Compute the semidominators of all vertices by applying
15720          *    theorem 4.   Carry out the computation vertex by vertex in
15721          *    decreasing order by number.
15722          * Step 3.  Implicitly define the immediate dominator of each vertex
15723          *    by applying Corollary 1.
15724          * Step 4.  Explicitly define the immediate dominator of each vertex,
15725          *    carrying out the computation vertex by vertex in increasing order
15726          *    by number.
15727          */
15728         /* Step 1 initialize the basic block information */
15729         sd = xcmalloc(sizeof(*sd) * (bb->last_vertex + 1), "sdom_state");
15730         initialize_sdblock(sd, 0, bb->first_block, 0);
15731 #if 0
15732         sd[1].size  = 0;
15733         sd[1].label = 0;
15734         sd[1].sdom  = 0;
15735 #endif
15736         /* Step 2 compute the semidominators */
15737         /* Step 3 implicitly define the immediate dominator of each vertex */
15738         compute_sdom(state, bb, sd);
15739         /* Step 4 explicitly define the immediate dominator of each vertex */
15740         compute_idom(state, bb, sd);
15741         xfree(sd);
15742 }
15743
15744 static void find_post_dominators(struct compile_state *state,
15745         struct basic_blocks *bb)
15746 {
15747         struct sdom_block *sd;
15748         int vertex;
15749         /* Step 1 initialize the basic block information */
15750         sd = xcmalloc(sizeof(*sd) * (bb->last_vertex + 1), "sdom_state");
15751
15752         vertex = setup_spdblocks(state, bb, sd);
15753         if (vertex != bb->last_vertex) {
15754                 internal_error(state, 0, "missing %d blocks",
15755                         bb->last_vertex - vertex);
15756         }
15757
15758         /* Step 2 compute the semidominators */
15759         /* Step 3 implicitly define the immediate dominator of each vertex */
15760         compute_spdom(state, bb, sd);
15761         /* Step 4 explicitly define the immediate dominator of each vertex */
15762         compute_ipdom(state, bb, sd);
15763         xfree(sd);
15764 }
15765
15766
15767
15768 static void find_block_domf(struct compile_state *state, struct block *block)
15769 {
15770         struct block *child;
15771         struct block_set *user, *edge;
15772         if (block->domfrontier != 0) {
15773                 internal_error(state, block->first, "domfrontier present?");
15774         }
15775         for(user = block->idominates; user; user = user->next) {
15776                 child = user->member;
15777                 if (child->idom != block) {
15778                         internal_error(state, block->first, "bad idom");
15779                 }
15780                 find_block_domf(state, child);
15781         }
15782         for(edge = block->edges; edge; edge = edge->next) {
15783                 if (edge->member->idom != block) {
15784                         domf_block(block, edge->member);
15785                 }
15786         }
15787         for(user = block->idominates; user; user = user->next) {
15788                 struct block_set *frontier;
15789                 child = user->member;
15790                 for(frontier = child->domfrontier; frontier; frontier = frontier->next) {
15791                         if (frontier->member->idom != block) {
15792                                 domf_block(block, frontier->member);
15793                         }
15794                 }
15795         }
15796 }
15797
15798 static void find_block_ipdomf(struct compile_state *state, struct block *block)
15799 {
15800         struct block *child;
15801         struct block_set *user;
15802         if (block->ipdomfrontier != 0) {
15803                 internal_error(state, block->first, "ipdomfrontier present?");
15804         }
15805         for(user = block->ipdominates; user; user = user->next) {
15806                 child = user->member;
15807                 if (child->ipdom != block) {
15808                         internal_error(state, block->first, "bad ipdom");
15809                 }
15810                 find_block_ipdomf(state, child);
15811         }
15812         for(user = block->use; user; user = user->next) {
15813                 if (user->member->ipdom != block) {
15814                         ipdomf_block(block, user->member);
15815                 }
15816         }
15817         for(user = block->ipdominates; user; user = user->next) {
15818                 struct block_set *frontier;
15819                 child = user->member;
15820                 for(frontier = child->ipdomfrontier; frontier; frontier = frontier->next) {
15821                         if (frontier->member->ipdom != block) {
15822                                 ipdomf_block(block, frontier->member);
15823                         }
15824                 }
15825         }
15826 }
15827
15828 static void print_dominated(
15829         struct compile_state *state, struct block *block, void *arg)
15830 {
15831         struct block_set *user;
15832         FILE *fp = arg;
15833
15834         fprintf(fp, "%d:", block->vertex);
15835         for(user = block->idominates; user; user = user->next) {
15836                 fprintf(fp, " %d", user->member->vertex);
15837                 if (user->member->idom != block) {
15838                         internal_error(state, user->member->first, "bad idom");
15839                 }
15840         }
15841         fprintf(fp,"\n");
15842 }
15843
15844 static void print_dominated2(
15845         struct compile_state *state, FILE *fp, int depth, struct block *block)
15846 {
15847         struct block_set *user;
15848         struct triple *ins;
15849         struct occurance *ptr, *ptr2;
15850         const char *filename1, *filename2;
15851         int equal_filenames;
15852         int i;
15853         for(i = 0; i < depth; i++) {
15854                 fprintf(fp, "   ");
15855         }
15856         fprintf(fp, "%3d: %p (%p - %p) @", 
15857                 block->vertex, block, block->first, block->last);
15858         ins = block->first;
15859         while(ins != block->last && (ins->occurance->line == 0)) {
15860                 ins = ins->next;
15861         }
15862         ptr = ins->occurance;
15863         ptr2 = block->last->occurance;
15864         filename1 = ptr->filename? ptr->filename : "";
15865         filename2 = ptr2->filename? ptr2->filename : "";
15866         equal_filenames = (strcmp(filename1, filename2) == 0);
15867         if ((ptr == ptr2) || (equal_filenames && ptr->line == ptr2->line)) {
15868                 fprintf(fp, " %s:%d", ptr->filename, ptr->line);
15869         } else if (equal_filenames) {
15870                 fprintf(fp, " %s:(%d - %d)",
15871                         ptr->filename, ptr->line, ptr2->line);
15872         } else {
15873                 fprintf(fp, " (%s:%d - %s:%d)",
15874                         ptr->filename, ptr->line,
15875                         ptr2->filename, ptr2->line);
15876         }
15877         fprintf(fp, "\n");
15878         for(user = block->idominates; user; user = user->next) {
15879                 print_dominated2(state, fp, depth + 1, user->member);
15880         }
15881 }
15882
15883 static void print_dominators(struct compile_state *state, FILE *fp, struct basic_blocks *bb)
15884 {
15885         fprintf(fp, "\ndominates\n");
15886         walk_blocks(state, bb, print_dominated, fp);
15887         fprintf(fp, "dominates\n");
15888         print_dominated2(state, fp, 0, bb->first_block);
15889 }
15890
15891
15892 static int print_frontiers(
15893         struct compile_state *state, FILE *fp, struct block *block, int vertex)
15894 {
15895         struct block_set *user, *edge;
15896
15897         if (!block || (block->vertex != vertex + 1)) {
15898                 return vertex;
15899         }
15900         vertex += 1;
15901
15902         fprintf(fp, "%d:", block->vertex);
15903         for(user = block->domfrontier; user; user = user->next) {
15904                 fprintf(fp, " %d", user->member->vertex);
15905         }
15906         fprintf(fp, "\n");
15907         
15908         for(edge = block->edges; edge; edge = edge->next) {
15909                 vertex = print_frontiers(state, fp, edge->member, vertex);
15910         }
15911         return vertex;
15912 }
15913 static void print_dominance_frontiers(struct compile_state *state,
15914         FILE *fp, struct basic_blocks *bb)
15915 {
15916         fprintf(fp, "\ndominance frontiers\n");
15917         print_frontiers(state, fp, bb->first_block, 0);
15918         
15919 }
15920
15921 static void analyze_idominators(struct compile_state *state, struct basic_blocks *bb)
15922 {
15923         /* Find the immediate dominators */
15924         find_immediate_dominators(state, bb);
15925         /* Find the dominance frontiers */
15926         find_block_domf(state, bb->first_block);
15927         /* If debuging print the print what I have just found */
15928         if (state->compiler->debug & DEBUG_FDOMINATORS) {
15929                 print_dominators(state, state->dbgout, bb);
15930                 print_dominance_frontiers(state, state->dbgout, bb);
15931                 print_control_flow(state, state->dbgout, bb);
15932         }
15933 }
15934
15935
15936 static void print_ipdominated(
15937         struct compile_state *state, struct block *block, void *arg)
15938 {
15939         struct block_set *user;
15940         FILE *fp = arg;
15941
15942         fprintf(fp, "%d:", block->vertex);
15943         for(user = block->ipdominates; user; user = user->next) {
15944                 fprintf(fp, " %d", user->member->vertex);
15945                 if (user->member->ipdom != block) {
15946                         internal_error(state, user->member->first, "bad ipdom");
15947                 }
15948         }
15949         fprintf(fp, "\n");
15950 }
15951
15952 static void print_ipdominators(struct compile_state *state, FILE *fp,
15953         struct basic_blocks *bb)
15954 {
15955         fprintf(fp, "\nipdominates\n");
15956         walk_blocks(state, bb, print_ipdominated, fp);
15957 }
15958
15959 static int print_pfrontiers(
15960         struct compile_state *state, FILE *fp, struct block *block, int vertex)
15961 {
15962         struct block_set *user;
15963
15964         if (!block || (block->vertex != vertex + 1)) {
15965                 return vertex;
15966         }
15967         vertex += 1;
15968
15969         fprintf(fp, "%d:", block->vertex);
15970         for(user = block->ipdomfrontier; user; user = user->next) {
15971                 fprintf(fp, " %d", user->member->vertex);
15972         }
15973         fprintf(fp, "\n");
15974         for(user = block->use; user; user = user->next) {
15975                 vertex = print_pfrontiers(state, fp, user->member, vertex);
15976         }
15977         return vertex;
15978 }
15979 static void print_ipdominance_frontiers(struct compile_state *state,
15980         FILE *fp, struct basic_blocks *bb)
15981 {
15982         fprintf(fp, "\nipdominance frontiers\n");
15983         print_pfrontiers(state, fp, bb->last_block, 0);
15984         
15985 }
15986
15987 static void analyze_ipdominators(struct compile_state *state,
15988         struct basic_blocks *bb)
15989 {
15990         /* Find the post dominators */
15991         find_post_dominators(state, bb);
15992         /* Find the control dependencies (post dominance frontiers) */
15993         find_block_ipdomf(state, bb->last_block);
15994         /* If debuging print the print what I have just found */
15995         if (state->compiler->debug & DEBUG_RDOMINATORS) {
15996                 print_ipdominators(state, state->dbgout, bb);
15997                 print_ipdominance_frontiers(state, state->dbgout, bb);
15998                 print_control_flow(state, state->dbgout, bb);
15999         }
16000 }
16001
16002 static int bdominates(struct compile_state *state,
16003         struct block *dom, struct block *sub)
16004 {
16005         while(sub && (sub != dom)) {
16006                 sub = sub->idom;
16007         }
16008         return sub == dom;
16009 }
16010
16011 static int tdominates(struct compile_state *state,
16012         struct triple *dom, struct triple *sub)
16013 {
16014         struct block *bdom, *bsub;
16015         int result;
16016         bdom = block_of_triple(state, dom);
16017         bsub = block_of_triple(state, sub);
16018         if (bdom != bsub) {
16019                 result = bdominates(state, bdom, bsub);
16020         } 
16021         else {
16022                 struct triple *ins;
16023                 if (!bdom || !bsub) {
16024                         internal_error(state, dom, "huh?");
16025                 }
16026                 ins = sub;
16027                 while((ins != bsub->first) && (ins != dom)) {
16028                         ins = ins->prev;
16029                 }
16030                 result = (ins == dom);
16031         }
16032         return result;
16033 }
16034
16035 static void analyze_basic_blocks(
16036         struct compile_state *state, struct basic_blocks *bb)
16037 {
16038         setup_basic_blocks(state, bb);
16039         analyze_idominators(state, bb);
16040         analyze_ipdominators(state, bb);
16041 }
16042
16043 static void insert_phi_operations(struct compile_state *state)
16044 {
16045         size_t size;
16046         struct triple *first;
16047         int *has_already, *work;
16048         struct block *work_list, **work_list_tail;
16049         int iter;
16050         struct triple *var, *vnext;
16051
16052         size = sizeof(int) * (state->bb.last_vertex + 1);
16053         has_already = xcmalloc(size, "has_already");
16054         work =        xcmalloc(size, "work");
16055         iter = 0;
16056
16057         first = state->first;
16058         for(var = first->next; var != first ; var = vnext) {
16059                 struct block *block;
16060                 struct triple_set *user, *unext;
16061                 vnext = var->next;
16062
16063                 if (!triple_is_auto_var(state, var) || !var->use) {
16064                         continue;
16065                 }
16066                         
16067                 iter += 1;
16068                 work_list = 0;
16069                 work_list_tail = &work_list;
16070                 for(user = var->use; user; user = unext) {
16071                         unext = user->next;
16072                         if (MISC(var, 0) == user->member) {
16073                                 continue;
16074                         }
16075                         if (user->member->op == OP_READ) {
16076                                 continue;
16077                         }
16078                         if (user->member->op != OP_WRITE) {
16079                                 internal_error(state, user->member, 
16080                                         "bad variable access");
16081                         }
16082                         block = user->member->u.block;
16083                         if (!block) {
16084                                 warning(state, user->member, "dead code");
16085                                 release_triple(state, user->member);
16086                                 continue;
16087                         }
16088                         if (work[block->vertex] >= iter) {
16089                                 continue;
16090                         }
16091                         work[block->vertex] = iter;
16092                         *work_list_tail = block;
16093                         block->work_next = 0;
16094                         work_list_tail = &block->work_next;
16095                 }
16096                 for(block = work_list; block; block = block->work_next) {
16097                         struct block_set *df;
16098                         for(df = block->domfrontier; df; df = df->next) {
16099                                 struct triple *phi;
16100                                 struct block *front;
16101                                 int in_edges;
16102                                 front = df->member;
16103
16104                                 if (has_already[front->vertex] >= iter) {
16105                                         continue;
16106                                 }
16107                                 /* Count how many edges flow into this block */
16108                                 in_edges = front->users;
16109                                 /* Insert a phi function for this variable */
16110                                 get_occurance(var->occurance);
16111                                 phi = alloc_triple(
16112                                         state, OP_PHI, var->type, -1, in_edges, 
16113                                         var->occurance);
16114                                 phi->u.block = front;
16115                                 MISC(phi, 0) = var;
16116                                 use_triple(var, phi);
16117 #if 1
16118                                 if (phi->rhs != in_edges) {
16119                                         internal_error(state, phi, "phi->rhs: %d != in_edges: %d",
16120                                                 phi->rhs, in_edges);
16121                                 }
16122 #endif
16123                                 /* Insert the phi functions immediately after the label */
16124                                 insert_triple(state, front->first->next, phi);
16125                                 if (front->first == front->last) {
16126                                         front->last = front->first->next;
16127                                 }
16128                                 has_already[front->vertex] = iter;
16129                                 transform_to_arch_instruction(state, phi);
16130
16131                                 /* If necessary plan to visit the basic block */
16132                                 if (work[front->vertex] >= iter) {
16133                                         continue;
16134                                 }
16135                                 work[front->vertex] = iter;
16136                                 *work_list_tail = front;
16137                                 front->work_next = 0;
16138                                 work_list_tail = &front->work_next;
16139                         }
16140                 }
16141         }
16142         xfree(has_already);
16143         xfree(work);
16144 }
16145
16146
16147 struct stack {
16148         struct triple_set *top;
16149         unsigned orig_id;
16150 };
16151
16152 static int count_auto_vars(struct compile_state *state)
16153 {
16154         struct triple *first, *ins;
16155         int auto_vars = 0;
16156         first = state->first;
16157         ins = first;
16158         do {
16159                 if (triple_is_auto_var(state, ins)) {
16160                         auto_vars += 1;
16161                 }
16162                 ins = ins->next;
16163         } while(ins != first);
16164         return auto_vars;
16165 }
16166
16167 static void number_auto_vars(struct compile_state *state, struct stack *stacks)
16168 {
16169         struct triple *first, *ins;
16170         int auto_vars = 0;
16171         first = state->first;
16172         ins = first;
16173         do {
16174                 if (triple_is_auto_var(state, ins)) {
16175                         auto_vars += 1;
16176                         stacks[auto_vars].orig_id = ins->id;
16177                         ins->id = auto_vars;
16178                 }
16179                 ins = ins->next;
16180         } while(ins != first);
16181 }
16182
16183 static void restore_auto_vars(struct compile_state *state, struct stack *stacks)
16184 {
16185         struct triple *first, *ins;
16186         first = state->first;
16187         ins = first;
16188         do {
16189                 if (triple_is_auto_var(state, ins)) {
16190                         ins->id = stacks[ins->id].orig_id;
16191                 }
16192                 ins = ins->next;
16193         } while(ins != first);
16194 }
16195
16196 static struct triple *peek_triple(struct stack *stacks, struct triple *var)
16197 {
16198         struct triple_set *head;
16199         struct triple *top_val;
16200         top_val = 0;
16201         head = stacks[var->id].top;
16202         if (head) {
16203                 top_val = head->member;
16204         }
16205         return top_val;
16206 }
16207
16208 static void push_triple(struct stack *stacks, struct triple *var, struct triple *val)
16209 {
16210         struct triple_set *new;
16211         /* Append new to the head of the list,
16212          * it's the only sensible behavoir for a stack.
16213          */
16214         new = xcmalloc(sizeof(*new), "triple_set");
16215         new->member = val;
16216         new->next   = stacks[var->id].top;
16217         stacks[var->id].top = new;
16218 }
16219
16220 static void pop_triple(struct stack *stacks, struct triple *var, struct triple *oldval)
16221 {
16222         struct triple_set *set, **ptr;
16223         ptr = &stacks[var->id].top;
16224         while(*ptr) {
16225                 set = *ptr;
16226                 if (set->member == oldval) {
16227                         *ptr = set->next;
16228                         xfree(set);
16229                         /* Only free one occurance from the stack */
16230                         return;
16231                 }
16232                 else {
16233                         ptr = &set->next;
16234                 }
16235         }
16236 }
16237
16238 /*
16239  * C(V)
16240  * S(V)
16241  */
16242 static void fixup_block_phi_variables(
16243         struct compile_state *state, struct stack *stacks, struct block *parent, struct block *block)
16244 {
16245         struct block_set *set;
16246         struct triple *ptr;
16247         int edge;
16248         if (!parent || !block)
16249                 return;
16250         /* Find the edge I am coming in on */
16251         edge = 0;
16252         for(set = block->use; set; set = set->next, edge++) {
16253                 if (set->member == parent) {
16254                         break;
16255                 }
16256         }
16257         if (!set) {
16258                 internal_error(state, 0, "phi input is not on a control predecessor");
16259         }
16260         for(ptr = block->first; ; ptr = ptr->next) {
16261                 if (ptr->op == OP_PHI) {
16262                         struct triple *var, *val, **slot;
16263                         var = MISC(ptr, 0);
16264                         if (!var) {
16265                                 internal_error(state, ptr, "no var???");
16266                         }
16267                         /* Find the current value of the variable */
16268                         val = peek_triple(stacks, var);
16269                         if (val && ((val->op == OP_WRITE) || (val->op == OP_READ))) {
16270                                 internal_error(state, val, "bad value in phi");
16271                         }
16272                         if (edge >= ptr->rhs) {
16273                                 internal_error(state, ptr, "edges > phi rhs");
16274                         }
16275                         slot = &RHS(ptr, edge);
16276                         if ((*slot != 0) && (*slot != val)) {
16277                                 internal_error(state, ptr, "phi already bound on this edge");
16278                         }
16279                         *slot = val;
16280                         use_triple(val, ptr);
16281                 }
16282                 if (ptr == block->last) {
16283                         break;
16284                 }
16285         }
16286 }
16287
16288
16289 static void rename_block_variables(
16290         struct compile_state *state, struct stack *stacks, struct block *block)
16291 {
16292         struct block_set *user, *edge;
16293         struct triple *ptr, *next, *last;
16294         int done;
16295         if (!block)
16296                 return;
16297         last = block->first;
16298         done = 0;
16299         for(ptr = block->first; !done; ptr = next) {
16300                 next = ptr->next;
16301                 if (ptr == block->last) {
16302                         done = 1;
16303                 }
16304                 /* RHS(A) */
16305                 if (ptr->op == OP_READ) {
16306                         struct triple *var, *val;
16307                         var = RHS(ptr, 0);
16308                         if (!triple_is_auto_var(state, var)) {
16309                                 internal_error(state, ptr, "read of non auto var!");
16310                         }
16311                         unuse_triple(var, ptr);
16312                         /* Find the current value of the variable */
16313                         val = peek_triple(stacks, var);
16314                         if (!val) {
16315                                 /* Let the optimizer at variables that are not initially
16316                                  * set.  But give it a bogus value so things seem to
16317                                  * work by accident.  This is useful for bitfields because
16318                                  * setting them always involves a read-modify-write.
16319                                  */
16320                                 if (TYPE_ARITHMETIC(ptr->type->type)) {
16321                                         val = pre_triple(state, ptr, OP_INTCONST, ptr->type, 0, 0);
16322                                         val->u.cval = 0xdeadbeaf;
16323                                 } else {
16324                                         val = pre_triple(state, ptr, OP_UNKNOWNVAL, ptr->type, 0, 0);
16325                                 }
16326                         }
16327                         if (!val) {
16328                                 error(state, ptr, "variable used without being set");
16329                         }
16330                         if ((val->op == OP_WRITE) || (val->op == OP_READ)) {
16331                                 internal_error(state, val, "bad value in read");
16332                         }
16333                         propogate_use(state, ptr, val);
16334                         release_triple(state, ptr);
16335                         continue;
16336                 }
16337                 /* LHS(A) */
16338                 if (ptr->op == OP_WRITE) {
16339                         struct triple *var, *val, *tval;
16340                         var = MISC(ptr, 0);
16341                         if (!triple_is_auto_var(state, var)) {
16342                                 internal_error(state, ptr, "write to non auto var!");
16343                         }
16344                         tval = val = RHS(ptr, 0);
16345                         if ((val->op == OP_WRITE) || (val->op == OP_READ) ||
16346                                 triple_is_auto_var(state, val)) {
16347                                 internal_error(state, ptr, "bad value in write");
16348                         }
16349                         /* Insert a cast if the types differ */
16350                         if (!is_subset_type(ptr->type, val->type)) {
16351                                 if (val->op == OP_INTCONST) {
16352                                         tval = pre_triple(state, ptr, OP_INTCONST, ptr->type, 0, 0);
16353                                         tval->u.cval = val->u.cval;
16354                                 }
16355                                 else {
16356                                         tval = pre_triple(state, ptr, OP_CONVERT, ptr->type, val, 0);
16357                                         use_triple(val, tval);
16358                                 }
16359                                 transform_to_arch_instruction(state, tval);
16360                                 unuse_triple(val, ptr);
16361                                 RHS(ptr, 0) = tval;
16362                                 use_triple(tval, ptr);
16363                         }
16364                         propogate_use(state, ptr, tval);
16365                         unuse_triple(var, ptr);
16366                         /* Push OP_WRITE ptr->right onto a stack of variable uses */
16367                         push_triple(stacks, var, tval);
16368                 }
16369                 if (ptr->op == OP_PHI) {
16370                         struct triple *var;
16371                         var = MISC(ptr, 0);
16372                         if (!triple_is_auto_var(state, var)) {
16373                                 internal_error(state, ptr, "phi references non auto var!");
16374                         }
16375                         /* Push OP_PHI onto a stack of variable uses */
16376                         push_triple(stacks, var, ptr);
16377                 }
16378                 last = ptr;
16379         }
16380         block->last = last;
16381
16382         /* Fixup PHI functions in the cf successors */
16383         for(edge = block->edges; edge; edge = edge->next) {
16384                 fixup_block_phi_variables(state, stacks, block, edge->member);
16385         }
16386         /* rename variables in the dominated nodes */
16387         for(user = block->idominates; user; user = user->next) {
16388                 rename_block_variables(state, stacks, user->member);
16389         }
16390         /* pop the renamed variable stack */
16391         last = block->first;
16392         done = 0;
16393         for(ptr = block->first; !done ; ptr = next) {
16394                 next = ptr->next;
16395                 if (ptr == block->last) {
16396                         done = 1;
16397                 }
16398                 if (ptr->op == OP_WRITE) {
16399                         struct triple *var;
16400                         var = MISC(ptr, 0);
16401                         /* Pop OP_WRITE ptr->right from the stack of variable uses */
16402                         pop_triple(stacks, var, RHS(ptr, 0));
16403                         release_triple(state, ptr);
16404                         continue;
16405                 }
16406                 if (ptr->op == OP_PHI) {
16407                         struct triple *var;
16408                         var = MISC(ptr, 0);
16409                         /* Pop OP_WRITE ptr->right from the stack of variable uses */
16410                         pop_triple(stacks, var, ptr);
16411                 }
16412                 last = ptr;
16413         }
16414         block->last = last;
16415 }
16416
16417 static void rename_variables(struct compile_state *state)
16418 {
16419         struct stack *stacks;
16420         int auto_vars;
16421
16422         /* Allocate stacks for the Variables */
16423         auto_vars = count_auto_vars(state);
16424         stacks = xcmalloc(sizeof(stacks[0])*(auto_vars + 1), "auto var stacks");
16425
16426         /* Give each auto_var a stack */
16427         number_auto_vars(state, stacks);
16428
16429         /* Rename the variables */
16430         rename_block_variables(state, stacks, state->bb.first_block);
16431
16432         /* Remove the stacks from the auto_vars */
16433         restore_auto_vars(state, stacks);
16434         xfree(stacks);
16435 }
16436
16437 static void prune_block_variables(struct compile_state *state,
16438         struct block *block)
16439 {
16440         struct block_set *user;
16441         struct triple *next, *ptr;
16442         int done;
16443
16444         done = 0;
16445         for(ptr = block->first; !done; ptr = next) {
16446                 /* Be extremely careful I am deleting the list
16447                  * as I walk trhough it.
16448                  */
16449                 next = ptr->next;
16450                 if (ptr == block->last) {
16451                         done = 1;
16452                 }
16453                 if (triple_is_auto_var(state, ptr)) {
16454                         struct triple_set *user, *next;
16455                         for(user = ptr->use; user; user = next) {
16456                                 struct triple *use;
16457                                 next = user->next;
16458                                 use = user->member;
16459                                 if (MISC(ptr, 0) == user->member) {
16460                                         continue;
16461                                 }
16462                                 if (use->op != OP_PHI) {
16463                                         internal_error(state, use, "decl still used");
16464                                 }
16465                                 if (MISC(use, 0) != ptr) {
16466                                         internal_error(state, use, "bad phi use of decl");
16467                                 }
16468                                 unuse_triple(ptr, use);
16469                                 MISC(use, 0) = 0;
16470                         }
16471                         if ((ptr->u.cval == 0) && (MISC(ptr, 0)->lhs == 1)) {
16472                                 /* Delete the adecl */
16473                                 release_triple(state, MISC(ptr, 0));
16474                                 /* And the piece */
16475                                 release_triple(state, ptr);
16476                         }
16477                         continue;
16478                 }
16479         }
16480         for(user = block->idominates; user; user = user->next) {
16481                 prune_block_variables(state, user->member);
16482         }
16483 }
16484
16485 struct phi_triple {
16486         struct triple *phi;
16487         unsigned orig_id;
16488         int alive;
16489 };
16490
16491 static void keep_phi(struct compile_state *state, struct phi_triple *live, struct triple *phi)
16492 {
16493         struct triple **slot;
16494         int zrhs, i;
16495         if (live[phi->id].alive) {
16496                 return;
16497         }
16498         live[phi->id].alive = 1;
16499         zrhs = phi->rhs;
16500         slot = &RHS(phi, 0);
16501         for(i = 0; i < zrhs; i++) {
16502                 struct triple *used;
16503                 used = slot[i];
16504                 if (used && (used->op == OP_PHI)) {
16505                         keep_phi(state, live, used);
16506                 }
16507         }
16508 }
16509
16510 static void prune_unused_phis(struct compile_state *state)
16511 {
16512         struct triple *first, *phi;
16513         struct phi_triple *live;
16514         int phis, i;
16515         
16516         /* Find the first instruction */
16517         first = state->first;
16518
16519         /* Count how many phi functions I need to process */
16520         phis = 0;
16521         for(phi = first->next; phi != first; phi = phi->next) {
16522                 if (phi->op == OP_PHI) {
16523                         phis += 1;
16524                 }
16525         }
16526         
16527         /* Mark them all dead */
16528         live = xcmalloc(sizeof(*live) * (phis + 1), "phi_triple");
16529         phis = 0;
16530         for(phi = first->next; phi != first; phi = phi->next) {
16531                 if (phi->op != OP_PHI) {
16532                         continue;
16533                 }
16534                 live[phis].alive   = 0;
16535                 live[phis].orig_id = phi->id;
16536                 live[phis].phi     = phi;
16537                 phi->id = phis;
16538                 phis += 1;
16539         }
16540         
16541         /* Mark phis alive that are used by non phis */
16542         for(i = 0; i < phis; i++) {
16543                 struct triple_set *set;
16544                 for(set = live[i].phi->use; !live[i].alive && set; set = set->next) {
16545                         if (set->member->op != OP_PHI) {
16546                                 keep_phi(state, live, live[i].phi);
16547                                 break;
16548                         }
16549                 }
16550         }
16551
16552         /* Delete the extraneous phis */
16553         for(i = 0; i < phis; i++) {
16554                 struct triple **slot;
16555                 int zrhs, j;
16556                 if (!live[i].alive) {
16557                         release_triple(state, live[i].phi);
16558                         continue;
16559                 }
16560                 phi = live[i].phi;
16561                 slot = &RHS(phi, 0);
16562                 zrhs = phi->rhs;
16563                 for(j = 0; j < zrhs; j++) {
16564                         if(!slot[j]) {
16565                                 struct triple *unknown;
16566                                 get_occurance(phi->occurance);
16567                                 unknown = flatten(state, state->global_pool,
16568                                         alloc_triple(state, OP_UNKNOWNVAL,
16569                                                 phi->type, 0, 0, phi->occurance));
16570                                 slot[j] = unknown;
16571                                 use_triple(unknown, phi);
16572                                 transform_to_arch_instruction(state, unknown);
16573 #if 0                           
16574                                 warning(state, phi, "variable not set at index %d on all paths to use", j);
16575 #endif
16576                         }
16577                 }
16578         }
16579         xfree(live);
16580 }
16581
16582 static void transform_to_ssa_form(struct compile_state *state)
16583 {
16584         insert_phi_operations(state);
16585         rename_variables(state);
16586
16587         prune_block_variables(state, state->bb.first_block);
16588         prune_unused_phis(state);
16589
16590         print_blocks(state, __func__, state->dbgout);
16591 }
16592
16593
16594 static void clear_vertex(
16595         struct compile_state *state, struct block *block, void *arg)
16596 {
16597         /* Clear the current blocks vertex and the vertex of all
16598          * of the current blocks neighbors in case there are malformed
16599          * blocks with now instructions at this point.
16600          */
16601         struct block_set *user, *edge;
16602         block->vertex = 0;
16603         for(edge = block->edges; edge; edge = edge->next) {
16604                 edge->member->vertex = 0;
16605         }
16606         for(user = block->use; user; user = user->next) {
16607                 user->member->vertex = 0;
16608         }
16609 }
16610
16611 static void mark_live_block(
16612         struct compile_state *state, struct block *block, int *next_vertex)
16613 {
16614         /* See if this is a block that has not been marked */
16615         if (block->vertex != 0) {
16616                 return;
16617         }
16618         block->vertex = *next_vertex;
16619         *next_vertex += 1;
16620         if (triple_is_branch(state, block->last)) {
16621                 struct triple **targ;
16622                 targ = triple_edge_targ(state, block->last, 0);
16623                 for(; targ; targ = triple_edge_targ(state, block->last, targ)) {
16624                         if (!*targ) {
16625                                 continue;
16626                         }
16627                         if (!triple_stores_block(state, *targ)) {
16628                                 internal_error(state, 0, "bad targ");
16629                         }
16630                         mark_live_block(state, (*targ)->u.block, next_vertex);
16631                 }
16632                 /* Ensure the last block of a function remains alive */
16633                 if (triple_is_call(state, block->last)) {
16634                         mark_live_block(state, MISC(block->last, 0)->u.block, next_vertex);
16635                 }
16636         }
16637         else if (block->last->next != state->first) {
16638                 struct triple *ins;
16639                 ins = block->last->next;
16640                 if (!triple_stores_block(state, ins)) {
16641                         internal_error(state, 0, "bad block start");
16642                 }
16643                 mark_live_block(state, ins->u.block, next_vertex);
16644         }
16645 }
16646
16647 static void transform_from_ssa_form(struct compile_state *state)
16648 {
16649         /* To get out of ssa form we insert moves on the incoming
16650          * edges to blocks containting phi functions.
16651          */
16652         struct triple *first;
16653         struct triple *phi, *var, *next;
16654         int next_vertex;
16655
16656         /* Walk the control flow to see which blocks remain alive */
16657         walk_blocks(state, &state->bb, clear_vertex, 0);
16658         next_vertex = 1;
16659         mark_live_block(state, state->bb.first_block, &next_vertex);
16660
16661         /* Walk all of the operations to find the phi functions */
16662         first = state->first;
16663         for(phi = first->next; phi != first ; phi = next) {
16664                 struct block_set *set;
16665                 struct block *block;
16666                 struct triple **slot;
16667                 struct triple *var;
16668                 struct triple_set *use, *use_next;
16669                 int edge, writers, readers;
16670                 next = phi->next;
16671                 if (phi->op != OP_PHI) {
16672                         continue;
16673                 }
16674
16675                 block = phi->u.block;
16676                 slot  = &RHS(phi, 0);
16677
16678                 /* If this phi is in a dead block just forget it */
16679                 if (block->vertex == 0) {
16680                         release_triple(state, phi);
16681                         continue;
16682                 }
16683
16684                 /* Forget uses from code in dead blocks */
16685                 for(use = phi->use; use; use = use_next) {
16686                         struct block *ublock;
16687                         struct triple **expr;
16688                         use_next = use->next;
16689                         ublock = block_of_triple(state, use->member);
16690                         if ((use->member == phi) || (ublock->vertex != 0)) {
16691                                 continue;
16692                         }
16693                         expr = triple_rhs(state, use->member, 0);
16694                         for(; expr; expr = triple_rhs(state, use->member, expr)) {
16695                                 if (*expr == phi) {
16696                                         *expr = 0;
16697                                 }
16698                         }
16699                         unuse_triple(phi, use->member);
16700                 }
16701                 /* A variable to replace the phi function */
16702                 if (registers_of(state, phi->type) != 1) {
16703                         internal_error(state, phi, "phi->type does not fit in a single register!");
16704                 }
16705                 var = post_triple(state, phi, OP_ADECL, phi->type, 0, 0);
16706                 var = var->next; /* point at the var */
16707                         
16708                 /* Replaces use of phi with var */
16709                 propogate_use(state, phi, var);
16710
16711                 /* Count the readers */
16712                 readers = 0;
16713                 for(use = var->use; use; use = use->next) {
16714                         if (use->member != MISC(var, 0)) {
16715                                 readers++;
16716                         }
16717                 }
16718
16719                 /* Walk all of the incoming edges/blocks and insert moves.
16720                  */
16721                 writers = 0;
16722                 for(edge = 0, set = block->use; set; set = set->next, edge++) {
16723                         struct block *eblock, *vblock;
16724                         struct triple *move;
16725                         struct triple *val, *base;
16726                         eblock = set->member;
16727                         val = slot[edge];
16728                         slot[edge] = 0;
16729                         unuse_triple(val, phi);
16730                         vblock = block_of_triple(state, val);
16731
16732                         /* If we don't have a value that belongs in an OP_WRITE
16733                          * continue on.
16734                          */
16735                         if (!val || (val == &unknown_triple) || (val == phi)
16736                                 || (vblock && (vblock->vertex == 0))) {
16737                                 continue;
16738                         }
16739                         /* If the value should never occur error */
16740                         if (!vblock) {
16741                                 internal_error(state, val, "no vblock?");
16742                                 continue;
16743                         }
16744
16745                         /* If the value occurs in a dead block see if a replacement
16746                          * block can be found.
16747                          */
16748                         while(eblock && (eblock->vertex == 0)) {
16749                                 eblock = eblock->idom;
16750                         }
16751                         /* If not continue on with the next value. */
16752                         if (!eblock || (eblock->vertex == 0)) {
16753                                 continue;
16754                         }
16755
16756                         /* If we have an empty incoming block ignore it. */
16757                         if (!eblock->first) {
16758                                 internal_error(state, 0, "empty block?");
16759                         }
16760                         
16761                         /* Make certain the write is placed in the edge block... */
16762                         /* Walk through the edge block backwards to find an
16763                          * appropriate location for the OP_WRITE.
16764                          */
16765                         for(base = eblock->last; base != eblock->first; base = base->prev) {
16766                                 struct triple **expr;
16767                                 if (base->op == OP_PIECE) {
16768                                         base = MISC(base, 0);
16769                                 }
16770                                 if ((base == var) || (base == val)) {
16771                                         goto out;
16772                                 }
16773                                 expr = triple_lhs(state, base, 0);
16774                                 for(; expr; expr = triple_lhs(state, base, expr)) {
16775                                         if ((*expr) == val) {
16776                                                 goto out;
16777                                         }
16778                                 }
16779                                 expr = triple_rhs(state, base, 0);
16780                                 for(; expr; expr = triple_rhs(state, base, expr)) {
16781                                         if ((*expr) == var) {
16782                                                 goto out;
16783                                         }
16784                                 }
16785                         }
16786                 out:
16787                         if (triple_is_branch(state, base)) {
16788                                 internal_error(state, base,
16789                                         "Could not insert write to phi");
16790                         }
16791                         move = post_triple(state, base, OP_WRITE, var->type, val, var);
16792                         use_triple(val, move);
16793                         use_triple(var, move);
16794                         writers++;
16795                 }
16796                 if (!writers && readers) {
16797                         internal_error(state, var, "no value written to in use phi?");
16798                 }
16799                 /* If var is not used free it */
16800                 if (!writers) {
16801                         release_triple(state, MISC(var, 0));
16802                         release_triple(state, var);
16803                 }
16804                 /* Release the phi function */
16805                 release_triple(state, phi);
16806         }
16807         
16808         /* Walk all of the operations to find the adecls */
16809         for(var = first->next; var != first ; var = var->next) {
16810                 struct triple_set *use, *use_next;
16811                 if (!triple_is_auto_var(state, var)) {
16812                         continue;
16813                 }
16814
16815                 /* Walk through all of the rhs uses of var and
16816                  * replace them with read of var.
16817                  */
16818                 for(use = var->use; use; use = use_next) {
16819                         struct triple *read, *user;
16820                         struct triple **slot;
16821                         int zrhs, i, used;
16822                         use_next = use->next;
16823                         user = use->member;
16824                         
16825                         /* Generate a read of var */
16826                         read = pre_triple(state, user, OP_READ, var->type, var, 0);
16827                         use_triple(var, read);
16828
16829                         /* Find the rhs uses and see if they need to be replaced */
16830                         used = 0;
16831                         zrhs = user->rhs;
16832                         slot = &RHS(user, 0);
16833                         for(i = 0; i < zrhs; i++) {
16834                                 if (slot[i] == var) {
16835                                         slot[i] = read;
16836                                         used = 1;
16837                                 }
16838                         }
16839                         /* If we did use it cleanup the uses */
16840                         if (used) {
16841                                 unuse_triple(var, user);
16842                                 use_triple(read, user);
16843                         } 
16844                         /* If we didn't use it release the extra triple */
16845                         else {
16846                                 release_triple(state, read);
16847                         }
16848                 }
16849         }
16850 }
16851
16852 #define HI() if (state->compiler->debug & DEBUG_REBUILD_SSA_FORM) { \
16853         FILE *fp = state->dbgout; \
16854         fprintf(fp, "@ %s:%d\n", __FILE__, __LINE__); romcc_print_blocks(state, fp); \
16855         } 
16856
16857 static void rebuild_ssa_form(struct compile_state *state)
16858 {
16859 HI();
16860         transform_from_ssa_form(state);
16861 HI();
16862         state->bb.first = state->first;
16863         free_basic_blocks(state, &state->bb);
16864         analyze_basic_blocks(state, &state->bb);
16865 HI();
16866         insert_phi_operations(state);
16867 HI();
16868         rename_variables(state);
16869 HI();
16870         
16871         prune_block_variables(state, state->bb.first_block);
16872 HI();
16873         prune_unused_phis(state);
16874 HI();
16875 }
16876 #undef HI
16877
16878 /* 
16879  * Register conflict resolution
16880  * =========================================================
16881  */
16882
16883 static struct reg_info find_def_color(
16884         struct compile_state *state, struct triple *def)
16885 {
16886         struct triple_set *set;
16887         struct reg_info info;
16888         info.reg = REG_UNSET;
16889         info.regcm = 0;
16890         if (!triple_is_def(state, def)) {
16891                 return info;
16892         }
16893         info = arch_reg_lhs(state, def, 0);
16894         if (info.reg >= MAX_REGISTERS) {
16895                 info.reg = REG_UNSET;
16896         }
16897         for(set = def->use; set; set = set->next) {
16898                 struct reg_info tinfo;
16899                 int i;
16900                 i = find_rhs_use(state, set->member, def);
16901                 if (i < 0) {
16902                         continue;
16903                 }
16904                 tinfo = arch_reg_rhs(state, set->member, i);
16905                 if (tinfo.reg >= MAX_REGISTERS) {
16906                         tinfo.reg = REG_UNSET;
16907                 }
16908                 if ((tinfo.reg != REG_UNSET) && 
16909                         (info.reg != REG_UNSET) &&
16910                         (tinfo.reg != info.reg)) {
16911                         internal_error(state, def, "register conflict");
16912                 }
16913                 if ((info.regcm & tinfo.regcm) == 0) {
16914                         internal_error(state, def, "regcm conflict %x & %x == 0",
16915                                 info.regcm, tinfo.regcm);
16916                 }
16917                 if (info.reg == REG_UNSET) {
16918                         info.reg = tinfo.reg;
16919                 }
16920                 info.regcm &= tinfo.regcm;
16921         }
16922         if (info.reg >= MAX_REGISTERS) {
16923                 internal_error(state, def, "register out of range");
16924         }
16925         return info;
16926 }
16927
16928 static struct reg_info find_lhs_pre_color(
16929         struct compile_state *state, struct triple *ins, int index)
16930 {
16931         struct reg_info info;
16932         int zlhs, zrhs, i;
16933         zrhs = ins->rhs;
16934         zlhs = ins->lhs;
16935         if (!zlhs && triple_is_def(state, ins)) {
16936                 zlhs = 1;
16937         }
16938         if (index >= zlhs) {
16939                 internal_error(state, ins, "Bad lhs %d", index);
16940         }
16941         info = arch_reg_lhs(state, ins, index);
16942         for(i = 0; i < zrhs; i++) {
16943                 struct reg_info rinfo;
16944                 rinfo = arch_reg_rhs(state, ins, i);
16945                 if ((info.reg == rinfo.reg) &&
16946                         (rinfo.reg >= MAX_REGISTERS)) {
16947                         struct reg_info tinfo;
16948                         tinfo = find_lhs_pre_color(state, RHS(ins, index), 0);
16949                         info.reg = tinfo.reg;
16950                         info.regcm &= tinfo.regcm;
16951                         break;
16952                 }
16953         }
16954         if (info.reg >= MAX_REGISTERS) {
16955                 info.reg = REG_UNSET;
16956         }
16957         return info;
16958 }
16959
16960 static struct reg_info find_rhs_post_color(
16961         struct compile_state *state, struct triple *ins, int index);
16962
16963 static struct reg_info find_lhs_post_color(
16964         struct compile_state *state, struct triple *ins, int index)
16965 {
16966         struct triple_set *set;
16967         struct reg_info info;
16968         struct triple *lhs;
16969 #if DEBUG_TRIPLE_COLOR
16970         fprintf(state->errout, "find_lhs_post_color(%p, %d)\n",
16971                 ins, index);
16972 #endif
16973         if ((index == 0) && triple_is_def(state, ins)) {
16974                 lhs = ins;
16975         }
16976         else if (index < ins->lhs) {
16977                 lhs = LHS(ins, index);
16978         }
16979         else {
16980                 internal_error(state, ins, "Bad lhs %d", index);
16981                 lhs = 0;
16982         }
16983         info = arch_reg_lhs(state, ins, index);
16984         if (info.reg >= MAX_REGISTERS) {
16985                 info.reg = REG_UNSET;
16986         }
16987         for(set = lhs->use; set; set = set->next) {
16988                 struct reg_info rinfo;
16989                 struct triple *user;
16990                 int zrhs, i;
16991                 user = set->member;
16992                 zrhs = user->rhs;
16993                 for(i = 0; i < zrhs; i++) {
16994                         if (RHS(user, i) != lhs) {
16995                                 continue;
16996                         }
16997                         rinfo = find_rhs_post_color(state, user, i);
16998                         if ((info.reg != REG_UNSET) &&
16999                                 (rinfo.reg != REG_UNSET) &&
17000                                 (info.reg != rinfo.reg)) {
17001                                 internal_error(state, ins, "register conflict");
17002                         }
17003                         if ((info.regcm & rinfo.regcm) == 0) {
17004                                 internal_error(state, ins, "regcm conflict %x & %x == 0",
17005                                         info.regcm, rinfo.regcm);
17006                         }
17007                         if (info.reg == REG_UNSET) {
17008                                 info.reg = rinfo.reg;
17009                         }
17010                         info.regcm &= rinfo.regcm;
17011                 }
17012         }
17013 #if DEBUG_TRIPLE_COLOR
17014         fprintf(state->errout, "find_lhs_post_color(%p, %d) -> ( %d, %x)\n",
17015                 ins, index, info.reg, info.regcm);
17016 #endif
17017         return info;
17018 }
17019
17020 static struct reg_info find_rhs_post_color(
17021         struct compile_state *state, struct triple *ins, int index)
17022 {
17023         struct reg_info info, rinfo;
17024         int zlhs, i;
17025 #if DEBUG_TRIPLE_COLOR
17026         fprintf(state->errout, "find_rhs_post_color(%p, %d)\n",
17027                 ins, index);
17028 #endif
17029         rinfo = arch_reg_rhs(state, ins, index);
17030         zlhs = ins->lhs;
17031         if (!zlhs && triple_is_def(state, ins)) {
17032                 zlhs = 1;
17033         }
17034         info = rinfo;
17035         if (info.reg >= MAX_REGISTERS) {
17036                 info.reg = REG_UNSET;
17037         }
17038         for(i = 0; i < zlhs; i++) {
17039                 struct reg_info linfo;
17040                 linfo = arch_reg_lhs(state, ins, i);
17041                 if ((linfo.reg == rinfo.reg) &&
17042                         (linfo.reg >= MAX_REGISTERS)) {
17043                         struct reg_info tinfo;
17044                         tinfo = find_lhs_post_color(state, ins, i);
17045                         if (tinfo.reg >= MAX_REGISTERS) {
17046                                 tinfo.reg = REG_UNSET;
17047                         }
17048                         info.regcm &= linfo.regcm;
17049                         info.regcm &= tinfo.regcm;
17050                         if (info.reg != REG_UNSET) {
17051                                 internal_error(state, ins, "register conflict");
17052                         }
17053                         if (info.regcm == 0) {
17054                                 internal_error(state, ins, "regcm conflict");
17055                         }
17056                         info.reg = tinfo.reg;
17057                 }
17058         }
17059 #if DEBUG_TRIPLE_COLOR
17060         fprintf(state->errout, "find_rhs_post_color(%p, %d) -> ( %d, %x)\n",
17061                 ins, index, info.reg, info.regcm);
17062 #endif
17063         return info;
17064 }
17065
17066 static struct reg_info find_lhs_color(
17067         struct compile_state *state, struct triple *ins, int index)
17068 {
17069         struct reg_info pre, post, info;
17070 #if DEBUG_TRIPLE_COLOR
17071         fprintf(state->errout, "find_lhs_color(%p, %d)\n",
17072                 ins, index);
17073 #endif
17074         pre = find_lhs_pre_color(state, ins, index);
17075         post = find_lhs_post_color(state, ins, index);
17076         if ((pre.reg != post.reg) &&
17077                 (pre.reg != REG_UNSET) &&
17078                 (post.reg != REG_UNSET)) {
17079                 internal_error(state, ins, "register conflict");
17080         }
17081         info.regcm = pre.regcm & post.regcm;
17082         info.reg = pre.reg;
17083         if (info.reg == REG_UNSET) {
17084                 info.reg = post.reg;
17085         }
17086 #if DEBUG_TRIPLE_COLOR
17087         fprintf(state->errout, "find_lhs_color(%p, %d) -> ( %d, %x) ... (%d, %x) (%d, %x)\n",
17088                 ins, index, info.reg, info.regcm,
17089                 pre.reg, pre.regcm, post.reg, post.regcm);
17090 #endif
17091         return info;
17092 }
17093
17094 static struct triple *post_copy(struct compile_state *state, struct triple *ins)
17095 {
17096         struct triple_set *entry, *next;
17097         struct triple *out;
17098         struct reg_info info, rinfo;
17099
17100         info = arch_reg_lhs(state, ins, 0);
17101         out = post_triple(state, ins, OP_COPY, ins->type, ins, 0);
17102         use_triple(RHS(out, 0), out);
17103         /* Get the users of ins to use out instead */
17104         for(entry = ins->use; entry; entry = next) {
17105                 int i;
17106                 next = entry->next;
17107                 if (entry->member == out) {
17108                         continue;
17109                 }
17110                 i = find_rhs_use(state, entry->member, ins);
17111                 if (i < 0) {
17112                         continue;
17113                 }
17114                 rinfo = arch_reg_rhs(state, entry->member, i);
17115                 if ((info.reg == REG_UNNEEDED) && (rinfo.reg == REG_UNNEEDED)) {
17116                         continue;
17117                 }
17118                 replace_rhs_use(state, ins, out, entry->member);
17119         }
17120         transform_to_arch_instruction(state, out);
17121         return out;
17122 }
17123
17124 static struct triple *typed_pre_copy(
17125         struct compile_state *state, struct type *type, struct triple *ins, int index)
17126 {
17127         /* Carefully insert enough operations so that I can
17128          * enter any operation with a GPR32.
17129          */
17130         struct triple *in;
17131         struct triple **expr;
17132         unsigned classes;
17133         struct reg_info info;
17134         int op;
17135         if (ins->op == OP_PHI) {
17136                 internal_error(state, ins, "pre_copy on a phi?");
17137         }
17138         classes = arch_type_to_regcm(state, type);
17139         info = arch_reg_rhs(state, ins, index);
17140         expr = &RHS(ins, index);
17141         if ((info.regcm & classes) == 0) {
17142                 FILE *fp = state->errout;
17143                 fprintf(fp, "src_type: ");
17144                 name_of(fp, ins->type);
17145                 fprintf(fp, "\ndst_type: ");
17146                 name_of(fp, type);
17147                 fprintf(fp, "\n");
17148                 internal_error(state, ins, "pre_copy with no register classes");
17149         }
17150         op = OP_COPY;
17151         if (!equiv_types(type, (*expr)->type)) {
17152                 op = OP_CONVERT;
17153         }
17154         in = pre_triple(state, ins, op, type, *expr, 0);
17155         unuse_triple(*expr, ins);
17156         *expr = in;
17157         use_triple(RHS(in, 0), in);
17158         use_triple(in, ins);
17159         transform_to_arch_instruction(state, in);
17160         return in;
17161         
17162 }
17163 static struct triple *pre_copy(
17164         struct compile_state *state, struct triple *ins, int index)
17165 {
17166         return typed_pre_copy(state, RHS(ins, index)->type, ins, index);
17167 }
17168
17169
17170 static void insert_copies_to_phi(struct compile_state *state)
17171 {
17172         /* To get out of ssa form we insert moves on the incoming
17173          * edges to blocks containting phi functions.
17174          */
17175         struct triple *first;
17176         struct triple *phi;
17177
17178         /* Walk all of the operations to find the phi functions */
17179         first = state->first;
17180         for(phi = first->next; phi != first ; phi = phi->next) {
17181                 struct block_set *set;
17182                 struct block *block;
17183                 struct triple **slot, *copy;
17184                 int edge;
17185                 if (phi->op != OP_PHI) {
17186                         continue;
17187                 }
17188                 phi->id |= TRIPLE_FLAG_POST_SPLIT;
17189                 block = phi->u.block;
17190                 slot  = &RHS(phi, 0);
17191                 /* Phi's that feed into mandatory live range joins
17192                  * cause nasty complications.  Insert a copy of
17193                  * the phi value so I never have to deal with
17194                  * that in the rest of the code.
17195                  */
17196                 copy = post_copy(state, phi);
17197                 copy->id |= TRIPLE_FLAG_PRE_SPLIT;
17198                 /* Walk all of the incoming edges/blocks and insert moves.
17199                  */
17200                 for(edge = 0, set = block->use; set; set = set->next, edge++) {
17201                         struct block *eblock;
17202                         struct triple *move;
17203                         struct triple *val;
17204                         struct triple *ptr;
17205                         eblock = set->member;
17206                         val = slot[edge];
17207
17208                         if (val == phi) {
17209                                 continue;
17210                         }
17211
17212                         get_occurance(val->occurance);
17213                         move = build_triple(state, OP_COPY, val->type, val, 0,
17214                                 val->occurance);
17215                         move->u.block = eblock;
17216                         move->id |= TRIPLE_FLAG_PRE_SPLIT;
17217                         use_triple(val, move);
17218                         
17219                         slot[edge] = move;
17220                         unuse_triple(val, phi);
17221                         use_triple(move, phi);
17222
17223                         /* Walk up the dominator tree until I have found the appropriate block */
17224                         while(eblock && !tdominates(state, val, eblock->last)) {
17225                                 eblock = eblock->idom;
17226                         }
17227                         if (!eblock) {
17228                                 internal_error(state, phi, "Cannot find block dominated by %p",
17229                                         val);
17230                         }
17231
17232                         /* Walk through the block backwards to find
17233                          * an appropriate location for the OP_COPY.
17234                          */
17235                         for(ptr = eblock->last; ptr != eblock->first; ptr = ptr->prev) {
17236                                 struct triple **expr;
17237                                 if (ptr->op == OP_PIECE) {
17238                                         ptr = MISC(ptr, 0);
17239                                 }
17240                                 if ((ptr == phi) || (ptr == val)) {
17241                                         goto out;
17242                                 }
17243                                 expr = triple_lhs(state, ptr, 0);
17244                                 for(;expr; expr = triple_lhs(state, ptr, expr)) {
17245                                         if ((*expr) == val) {
17246                                                 goto out;
17247                                         }
17248                                 }
17249                                 expr = triple_rhs(state, ptr, 0);
17250                                 for(;expr; expr = triple_rhs(state, ptr, expr)) {
17251                                         if ((*expr) == phi) {
17252                                                 goto out;
17253                                         }
17254                                 }
17255                         }
17256                 out:
17257                         if (triple_is_branch(state, ptr)) {
17258                                 internal_error(state, ptr,
17259                                         "Could not insert write to phi");
17260                         }
17261                         insert_triple(state, after_lhs(state, ptr), move);
17262                         if (eblock->last == after_lhs(state, ptr)->prev) {
17263                                 eblock->last = move;
17264                         }
17265                         transform_to_arch_instruction(state, move);
17266                 }
17267         }
17268         print_blocks(state, __func__, state->dbgout);
17269 }
17270
17271 struct triple_reg_set;
17272 struct reg_block;
17273
17274
17275 static int do_triple_set(struct triple_reg_set **head, 
17276         struct triple *member, struct triple *new_member)
17277 {
17278         struct triple_reg_set **ptr, *new;
17279         if (!member)
17280                 return 0;
17281         ptr = head;
17282         while(*ptr) {
17283                 if ((*ptr)->member == member) {
17284                         return 0;
17285                 }
17286                 ptr = &(*ptr)->next;
17287         }
17288         new = xcmalloc(sizeof(*new), "triple_set");
17289         new->member = member;
17290         new->new    = new_member;
17291         new->next   = *head;
17292         *head       = new;
17293         return 1;
17294 }
17295
17296 static void do_triple_unset(struct triple_reg_set **head, struct triple *member)
17297 {
17298         struct triple_reg_set *entry, **ptr;
17299         ptr = head;
17300         while(*ptr) {
17301                 entry = *ptr;
17302                 if (entry->member == member) {
17303                         *ptr = entry->next;
17304                         xfree(entry);
17305                         return;
17306                 }
17307                 else {
17308                         ptr = &entry->next;
17309                 }
17310         }
17311 }
17312
17313 static int in_triple(struct reg_block *rb, struct triple *in)
17314 {
17315         return do_triple_set(&rb->in, in, 0);
17316 }
17317 static void unin_triple(struct reg_block *rb, struct triple *unin)
17318 {
17319         do_triple_unset(&rb->in, unin);
17320 }
17321
17322 static int out_triple(struct reg_block *rb, struct triple *out)
17323 {
17324         return do_triple_set(&rb->out, out, 0);
17325 }
17326 static void unout_triple(struct reg_block *rb, struct triple *unout)
17327 {
17328         do_triple_unset(&rb->out, unout);
17329 }
17330
17331 static int initialize_regblock(struct reg_block *blocks,
17332         struct block *block, int vertex)
17333 {
17334         struct block_set *user;
17335         if (!block || (blocks[block->vertex].block == block)) {
17336                 return vertex;
17337         }
17338         vertex += 1;
17339         /* Renumber the blocks in a convinient fashion */
17340         block->vertex = vertex;
17341         blocks[vertex].block    = block;
17342         blocks[vertex].vertex   = vertex;
17343         for(user = block->use; user; user = user->next) {
17344                 vertex = initialize_regblock(blocks, user->member, vertex);
17345         }
17346         return vertex;
17347 }
17348
17349 static struct triple *part_to_piece(struct compile_state *state, struct triple *ins)
17350 {
17351 /* Part to piece is a best attempt and it cannot be correct all by
17352  * itself.  If various values are read as different sizes in different
17353  * parts of the code this function cannot work.  Or rather it cannot
17354  * work in conjunction with compute_variable_liftimes.  As the
17355  * analysis will get confused.
17356  */
17357         struct triple *base;
17358         unsigned reg;
17359         if (!is_lvalue(state, ins)) {
17360                 return ins;
17361         }
17362         base = 0;
17363         reg = 0;
17364         while(ins && triple_is_part(state, ins) && (ins->op != OP_PIECE)) {
17365                 base = MISC(ins, 0);
17366                 switch(ins->op) {
17367                 case OP_INDEX:
17368                         reg += index_reg_offset(state, base->type, ins->u.cval)/REG_SIZEOF_REG;
17369                         break;
17370                 case OP_DOT:
17371                         reg += field_reg_offset(state, base->type, ins->u.field)/REG_SIZEOF_REG;
17372                         break;
17373                 default:
17374                         internal_error(state, ins, "unhandled part");
17375                         break;
17376                 }
17377                 ins = base;
17378         }
17379         if (base) {
17380                 if (reg > base->lhs) {
17381                         internal_error(state, base, "part out of range?");
17382                 }
17383                 ins = LHS(base, reg);
17384         }
17385         return ins;
17386 }
17387
17388 static int this_def(struct compile_state *state, 
17389         struct triple *ins, struct triple *other)
17390 {
17391         if (ins == other) {
17392                 return 1;
17393         }
17394         if (ins->op == OP_WRITE) {
17395                 ins = part_to_piece(state, MISC(ins, 0));
17396         }
17397         return ins == other;
17398 }
17399
17400 static int phi_in(struct compile_state *state, struct reg_block *blocks,
17401         struct reg_block *rb, struct block *suc)
17402 {
17403         /* Read the conditional input set of a successor block
17404          * (i.e. the input to the phi nodes) and place it in the
17405          * current blocks output set.
17406          */
17407         struct block_set *set;
17408         struct triple *ptr;
17409         int edge;
17410         int done, change;
17411         change = 0;
17412         /* Find the edge I am coming in on */
17413         for(edge = 0, set = suc->use; set; set = set->next, edge++) {
17414                 if (set->member == rb->block) {
17415                         break;
17416                 }
17417         }
17418         if (!set) {
17419                 internal_error(state, 0, "Not coming on a control edge?");
17420         }
17421         for(done = 0, ptr = suc->first; !done; ptr = ptr->next) {
17422                 struct triple **slot, *expr, *ptr2;
17423                 int out_change, done2;
17424                 done = (ptr == suc->last);
17425                 if (ptr->op != OP_PHI) {
17426                         continue;
17427                 }
17428                 slot = &RHS(ptr, 0);
17429                 expr = slot[edge];
17430                 out_change = out_triple(rb, expr);
17431                 if (!out_change) {
17432                         continue;
17433                 }
17434                 /* If we don't define the variable also plast it
17435                  * in the current blocks input set.
17436                  */
17437                 ptr2 = rb->block->first;
17438                 for(done2 = 0; !done2; ptr2 = ptr2->next) {
17439                         if (this_def(state, ptr2, expr)) {
17440                                 break;
17441                         }
17442                         done2 = (ptr2 == rb->block->last);
17443                 }
17444                 if (!done2) {
17445                         continue;
17446                 }
17447                 change |= in_triple(rb, expr);
17448         }
17449         return change;
17450 }
17451
17452 static int reg_in(struct compile_state *state, struct reg_block *blocks,
17453         struct reg_block *rb, struct block *suc)
17454 {
17455         struct triple_reg_set *in_set;
17456         int change;
17457         change = 0;
17458         /* Read the input set of a successor block
17459          * and place it in the current blocks output set.
17460          */
17461         in_set = blocks[suc->vertex].in;
17462         for(; in_set; in_set = in_set->next) {
17463                 int out_change, done;
17464                 struct triple *first, *last, *ptr;
17465                 out_change = out_triple(rb, in_set->member);
17466                 if (!out_change) {
17467                         continue;
17468                 }
17469                 /* If we don't define the variable also place it
17470                  * in the current blocks input set.
17471                  */
17472                 first = rb->block->first;
17473                 last = rb->block->last;
17474                 done = 0;
17475                 for(ptr = first; !done; ptr = ptr->next) {
17476                         if (this_def(state, ptr, in_set->member)) {
17477                                 break;
17478                         }
17479                         done = (ptr == last);
17480                 }
17481                 if (!done) {
17482                         continue;
17483                 }
17484                 change |= in_triple(rb, in_set->member);
17485         }
17486         change |= phi_in(state, blocks, rb, suc);
17487         return change;
17488 }
17489
17490 static int use_in(struct compile_state *state, struct reg_block *rb)
17491 {
17492         /* Find the variables we use but don't define and add
17493          * it to the current blocks input set.
17494          */
17495 #warning "FIXME is this O(N^2) algorithm bad?"
17496         struct block *block;
17497         struct triple *ptr;
17498         int done;
17499         int change;
17500         block = rb->block;
17501         change = 0;
17502         for(done = 0, ptr = block->last; !done; ptr = ptr->prev) {
17503                 struct triple **expr;
17504                 done = (ptr == block->first);
17505                 /* The variable a phi function uses depends on the
17506                  * control flow, and is handled in phi_in, not
17507                  * here.
17508                  */
17509                 if (ptr->op == OP_PHI) {
17510                         continue;
17511                 }
17512                 expr = triple_rhs(state, ptr, 0);
17513                 for(;expr; expr = triple_rhs(state, ptr, expr)) {
17514                         struct triple *rhs, *test;
17515                         int tdone;
17516                         rhs = part_to_piece(state, *expr);
17517                         if (!rhs) {
17518                                 continue;
17519                         }
17520
17521                         /* See if rhs is defined in this block.
17522                          * A write counts as a definition.
17523                          */
17524                         for(tdone = 0, test = ptr; !tdone; test = test->prev) {
17525                                 tdone = (test == block->first);
17526                                 if (this_def(state, test, rhs)) {
17527                                         rhs = 0;
17528                                         break;
17529                                 }
17530                         }
17531                         /* If I still have a valid rhs add it to in */
17532                         change |= in_triple(rb, rhs);
17533                 }
17534         }
17535         return change;
17536 }
17537
17538 static struct reg_block *compute_variable_lifetimes(
17539         struct compile_state *state, struct basic_blocks *bb)
17540 {
17541         struct reg_block *blocks;
17542         int change;
17543         blocks = xcmalloc(
17544                 sizeof(*blocks)*(bb->last_vertex + 1), "reg_block");
17545         initialize_regblock(blocks, bb->last_block, 0);
17546         do {
17547                 int i;
17548                 change = 0;
17549                 for(i = 1; i <= bb->last_vertex; i++) {
17550                         struct block_set *edge;
17551                         struct reg_block *rb;
17552                         rb = &blocks[i];
17553                         /* Add the all successor's input set to in */
17554                         for(edge = rb->block->edges; edge; edge = edge->next) {
17555                                 change |= reg_in(state, blocks, rb, edge->member);
17556                         }
17557                         /* Add use to in... */
17558                         change |= use_in(state, rb);
17559                 }
17560         } while(change);
17561         return blocks;
17562 }
17563
17564 static void free_variable_lifetimes(struct compile_state *state, 
17565         struct basic_blocks *bb, struct reg_block *blocks)
17566 {
17567         int i;
17568         /* free in_set && out_set on each block */
17569         for(i = 1; i <= bb->last_vertex; i++) {
17570                 struct triple_reg_set *entry, *next;
17571                 struct reg_block *rb;
17572                 rb = &blocks[i];
17573                 for(entry = rb->in; entry ; entry = next) {
17574                         next = entry->next;
17575                         do_triple_unset(&rb->in, entry->member);
17576                 }
17577                 for(entry = rb->out; entry; entry = next) {
17578                         next = entry->next;
17579                         do_triple_unset(&rb->out, entry->member);
17580                 }
17581         }
17582         xfree(blocks);
17583
17584 }
17585
17586 typedef void (*wvl_cb_t)(
17587         struct compile_state *state, 
17588         struct reg_block *blocks, struct triple_reg_set *live, 
17589         struct reg_block *rb, struct triple *ins, void *arg);
17590
17591 static void walk_variable_lifetimes(struct compile_state *state,
17592         struct basic_blocks *bb, struct reg_block *blocks, 
17593         wvl_cb_t cb, void *arg)
17594 {
17595         int i;
17596         
17597         for(i = 1; i <= state->bb.last_vertex; i++) {
17598                 struct triple_reg_set *live;
17599                 struct triple_reg_set *entry, *next;
17600                 struct triple *ptr, *prev;
17601                 struct reg_block *rb;
17602                 struct block *block;
17603                 int done;
17604
17605                 /* Get the blocks */
17606                 rb = &blocks[i];
17607                 block = rb->block;
17608
17609                 /* Copy out into live */
17610                 live = 0;
17611                 for(entry = rb->out; entry; entry = next) {
17612                         next = entry->next;
17613                         do_triple_set(&live, entry->member, entry->new);
17614                 }
17615                 /* Walk through the basic block calculating live */
17616                 for(done = 0, ptr = block->last; !done; ptr = prev) {
17617                         struct triple **expr;
17618
17619                         prev = ptr->prev;
17620                         done = (ptr == block->first);
17621
17622                         /* Ensure the current definition is in live */
17623                         if (triple_is_def(state, ptr)) {
17624                                 do_triple_set(&live, ptr, 0);
17625                         }
17626
17627                         /* Inform the callback function of what is
17628                          * going on.
17629                          */
17630                          cb(state, blocks, live, rb, ptr, arg);
17631                         
17632                         /* Remove the current definition from live */
17633                         do_triple_unset(&live, ptr);
17634
17635                         /* Add the current uses to live.
17636                          *
17637                          * It is safe to skip phi functions because they do
17638                          * not have any block local uses, and the block
17639                          * output sets already properly account for what
17640                          * control flow depedent uses phi functions do have.
17641                          */
17642                         if (ptr->op == OP_PHI) {
17643                                 continue;
17644                         }
17645                         expr = triple_rhs(state, ptr, 0);
17646                         for(;expr; expr = triple_rhs(state, ptr, expr)) {
17647                                 /* If the triple is not a definition skip it. */
17648                                 if (!*expr || !triple_is_def(state, *expr)) {
17649                                         continue;
17650                                 }
17651                                 do_triple_set(&live, *expr, 0);
17652                         }
17653                 }
17654                 /* Free live */
17655                 for(entry = live; entry; entry = next) {
17656                         next = entry->next;
17657                         do_triple_unset(&live, entry->member);
17658                 }
17659         }
17660 }
17661
17662 struct print_live_variable_info {
17663         struct reg_block *rb;
17664         FILE *fp;
17665 };
17666 static void print_live_variables_block(
17667         struct compile_state *state, struct block *block, void *arg)
17668
17669 {
17670         struct print_live_variable_info *info = arg;
17671         struct block_set *edge;
17672         FILE *fp = info->fp;
17673         struct reg_block *rb;
17674         struct triple *ptr;
17675         int phi_present;
17676         int done;
17677         rb = &info->rb[block->vertex];
17678
17679         fprintf(fp, "\nblock: %p (%d),",
17680                 block,  block->vertex);
17681         for(edge = block->edges; edge; edge = edge->next) {
17682                 fprintf(fp, " %p<-%p",
17683                         edge->member, 
17684                         edge->member && edge->member->use?edge->member->use->member : 0);
17685         }
17686         fprintf(fp, "\n");
17687         if (rb->in) {
17688                 struct triple_reg_set *in_set;
17689                 fprintf(fp, "        in:");
17690                 for(in_set = rb->in; in_set; in_set = in_set->next) {
17691                         fprintf(fp, " %-10p", in_set->member);
17692                 }
17693                 fprintf(fp, "\n");
17694         }
17695         phi_present = 0;
17696         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
17697                 done = (ptr == block->last);
17698                 if (ptr->op == OP_PHI) {
17699                         phi_present = 1;
17700                         break;
17701                 }
17702         }
17703         if (phi_present) {
17704                 int edge;
17705                 for(edge = 0; edge < block->users; edge++) {
17706                         fprintf(fp, "     in(%d):", edge);
17707                         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
17708                                 struct triple **slot;
17709                                 done = (ptr == block->last);
17710                                 if (ptr->op != OP_PHI) {
17711                                         continue;
17712                                 }
17713                                 slot = &RHS(ptr, 0);
17714                                 fprintf(fp, " %-10p", slot[edge]);
17715                         }
17716                         fprintf(fp, "\n");
17717                 }
17718         }
17719         if (block->first->op == OP_LABEL) {
17720                 fprintf(fp, "%p:\n", block->first);
17721         }
17722         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
17723                 done = (ptr == block->last);
17724                 display_triple(fp, ptr);
17725         }
17726         if (rb->out) {
17727                 struct triple_reg_set *out_set;
17728                 fprintf(fp, "       out:");
17729                 for(out_set = rb->out; out_set; out_set = out_set->next) {
17730                         fprintf(fp, " %-10p", out_set->member);
17731                 }
17732                 fprintf(fp, "\n");
17733         }
17734         fprintf(fp, "\n");
17735 }
17736
17737 static void print_live_variables(struct compile_state *state, 
17738         struct basic_blocks *bb, struct reg_block *rb, FILE *fp)
17739 {
17740         struct print_live_variable_info info;
17741         info.rb = rb;
17742         info.fp = fp;
17743         fprintf(fp, "\nlive variables by block\n");
17744         walk_blocks(state, bb, print_live_variables_block, &info);
17745
17746 }
17747
17748
17749 static int count_triples(struct compile_state *state)
17750 {
17751         struct triple *first, *ins;
17752         int triples = 0;
17753         first = state->first;
17754         ins = first;
17755         do {
17756                 triples++;
17757                 ins = ins->next;
17758         } while (ins != first);
17759         return triples;
17760 }
17761
17762
17763 struct dead_triple {
17764         struct triple *triple;
17765         struct dead_triple *work_next;
17766         struct block *block;
17767         int old_id;
17768         int flags;
17769 #define TRIPLE_FLAG_ALIVE 1
17770 #define TRIPLE_FLAG_FREE  1
17771 };
17772
17773 static void print_dead_triples(struct compile_state *state, 
17774         struct dead_triple *dtriple)
17775 {
17776         struct triple *first, *ins;
17777         struct dead_triple *dt;
17778         FILE *fp;
17779         if (!(state->compiler->debug & DEBUG_TRIPLES)) {
17780                 return;
17781         }
17782         fp = state->dbgout;
17783         fprintf(fp, "--------------- dtriples ---------------\n");
17784         first = state->first;
17785         ins = first;
17786         do {
17787                 dt = &dtriple[ins->id];
17788                 if ((ins->op == OP_LABEL) && (ins->use)) {
17789                         fprintf(fp, "\n%p:\n", ins);
17790                 }
17791                 fprintf(fp, "%c", 
17792                         (dt->flags & TRIPLE_FLAG_ALIVE)?' ': '-');
17793                 display_triple(fp, ins);
17794                 if (triple_is_branch(state, ins)) {
17795                         fprintf(fp, "\n");
17796                 }
17797                 ins = ins->next;
17798         } while(ins != first);
17799         fprintf(fp, "\n");
17800 }
17801
17802
17803 static void awaken(
17804         struct compile_state *state,
17805         struct dead_triple *dtriple, struct triple **expr,
17806         struct dead_triple ***work_list_tail)
17807 {
17808         struct triple *triple;
17809         struct dead_triple *dt;
17810         if (!expr) {
17811                 return;
17812         }
17813         triple = *expr;
17814         if (!triple) {
17815                 return;
17816         }
17817         if (triple->id <= 0)  {
17818                 internal_error(state, triple, "bad triple id: %d",
17819                         triple->id);
17820         }
17821         if (triple->op == OP_NOOP) {
17822                 internal_error(state, triple, "awakening noop?");
17823                 return;
17824         }
17825         dt = &dtriple[triple->id];
17826         if (!(dt->flags & TRIPLE_FLAG_ALIVE)) {
17827                 dt->flags |= TRIPLE_FLAG_ALIVE;
17828                 if (!dt->work_next) {
17829                         **work_list_tail = dt;
17830                         *work_list_tail = &dt->work_next;
17831                 }
17832         }
17833 }
17834
17835 static void eliminate_inefectual_code(struct compile_state *state)
17836 {
17837         struct block *block;
17838         struct dead_triple *dtriple, *work_list, **work_list_tail, *dt;
17839         int triples, i;
17840         struct triple *first, *final, *ins;
17841
17842         if (!(state->compiler->flags & COMPILER_ELIMINATE_INEFECTUAL_CODE)) {
17843                 return;
17844         }
17845
17846         /* Setup the work list */
17847         work_list = 0;
17848         work_list_tail = &work_list;
17849
17850         first = state->first;
17851         final = state->first->prev;
17852
17853         /* Count how many triples I have */
17854         triples = count_triples(state);
17855
17856         /* Now put then in an array and mark all of the triples dead */
17857         dtriple = xcmalloc(sizeof(*dtriple) * (triples + 1), "dtriples");
17858         
17859         ins = first;
17860         i = 1;
17861         block = 0;
17862         do {
17863                 dtriple[i].triple = ins;
17864                 dtriple[i].block  = block_of_triple(state, ins);
17865                 dtriple[i].flags  = 0;
17866                 dtriple[i].old_id = ins->id;
17867                 ins->id = i;
17868                 /* See if it is an operation we always keep */
17869                 if (!triple_is_pure(state, ins, dtriple[i].old_id)) {
17870                         awaken(state, dtriple, &ins, &work_list_tail);
17871                 }
17872                 i++;
17873                 ins = ins->next;
17874         } while(ins != first);
17875         while(work_list) {
17876                 struct block *block;
17877                 struct dead_triple *dt;
17878                 struct block_set *user;
17879                 struct triple **expr;
17880                 dt = work_list;
17881                 work_list = dt->work_next;
17882                 if (!work_list) {
17883                         work_list_tail = &work_list;
17884                 }
17885                 /* Make certain the block the current instruction is in lives */
17886                 block = block_of_triple(state, dt->triple);
17887                 awaken(state, dtriple, &block->first, &work_list_tail);
17888                 if (triple_is_branch(state, block->last)) {
17889                         awaken(state, dtriple, &block->last, &work_list_tail);
17890                 } else {
17891                         awaken(state, dtriple, &block->last->next, &work_list_tail);
17892                 }
17893
17894                 /* Wake up the data depencencies of this triple */
17895                 expr = 0;
17896                 do {
17897                         expr = triple_rhs(state, dt->triple, expr);
17898                         awaken(state, dtriple, expr, &work_list_tail);
17899                 } while(expr);
17900                 do {
17901                         expr = triple_lhs(state, dt->triple, expr);
17902                         awaken(state, dtriple, expr, &work_list_tail);
17903                 } while(expr);
17904                 do {
17905                         expr = triple_misc(state, dt->triple, expr);
17906                         awaken(state, dtriple, expr, &work_list_tail);
17907                 } while(expr);
17908                 /* Wake up the forward control dependencies */
17909                 do {
17910                         expr = triple_targ(state, dt->triple, expr);
17911                         awaken(state, dtriple, expr, &work_list_tail);
17912                 } while(expr);
17913                 /* Wake up the reverse control dependencies of this triple */
17914                 for(user = dt->block->ipdomfrontier; user; user = user->next) {
17915                         struct triple *last;
17916                         last = user->member->last;
17917                         while((last->op == OP_NOOP) && (last != user->member->first)) {
17918                                 internal_warning(state, last, "awakening noop?");
17919                                 last = last->prev;
17920                         }
17921                         awaken(state, dtriple, &last, &work_list_tail);
17922                 }
17923         }
17924         print_dead_triples(state, dtriple);
17925         for(dt = &dtriple[1]; dt <= &dtriple[triples]; dt++) {
17926                 if ((dt->triple->op == OP_NOOP) && 
17927                         (dt->flags & TRIPLE_FLAG_ALIVE)) {
17928                         internal_error(state, dt->triple, "noop effective?");
17929                 }
17930                 dt->triple->id = dt->old_id;    /* Restore the color */
17931                 if (!(dt->flags & TRIPLE_FLAG_ALIVE)) {
17932                         release_triple(state, dt->triple);
17933                 }
17934         }
17935         xfree(dtriple);
17936
17937         rebuild_ssa_form(state);
17938
17939         print_blocks(state, __func__, state->dbgout);
17940 }
17941
17942
17943 static void insert_mandatory_copies(struct compile_state *state)
17944 {
17945         struct triple *ins, *first;
17946
17947         /* The object is with a minimum of inserted copies,
17948          * to resolve in fundamental register conflicts between
17949          * register value producers and consumers.
17950          * Theoretically we may be greater than minimal when we
17951          * are inserting copies before instructions but that
17952          * case should be rare.
17953          */
17954         first = state->first;
17955         ins = first;
17956         do {
17957                 struct triple_set *entry, *next;
17958                 struct triple *tmp;
17959                 struct reg_info info;
17960                 unsigned reg, regcm;
17961                 int do_post_copy, do_pre_copy;
17962                 tmp = 0;
17963                 if (!triple_is_def(state, ins)) {
17964                         goto next;
17965                 }
17966                 /* Find the architecture specific color information */
17967                 info = find_lhs_pre_color(state, ins, 0);
17968                 if (info.reg >= MAX_REGISTERS) {
17969                         info.reg = REG_UNSET;
17970                 }
17971
17972                 reg = REG_UNSET;
17973                 regcm = arch_type_to_regcm(state, ins->type);
17974                 do_post_copy = do_pre_copy = 0;
17975
17976                 /* Walk through the uses of ins and check for conflicts */
17977                 for(entry = ins->use; entry; entry = next) {
17978                         struct reg_info rinfo;
17979                         int i;
17980                         next = entry->next;
17981                         i = find_rhs_use(state, entry->member, ins);
17982                         if (i < 0) {
17983                                 continue;
17984                         }
17985                         
17986                         /* Find the users color requirements */
17987                         rinfo = arch_reg_rhs(state, entry->member, i);
17988                         if (rinfo.reg >= MAX_REGISTERS) {
17989                                 rinfo.reg = REG_UNSET;
17990                         }
17991                         
17992                         /* See if I need a pre_copy */
17993                         if (rinfo.reg != REG_UNSET) {
17994                                 if ((reg != REG_UNSET) && (reg != rinfo.reg)) {
17995                                         do_pre_copy = 1;
17996                                 }
17997                                 reg = rinfo.reg;
17998                         }
17999                         regcm &= rinfo.regcm;
18000                         regcm = arch_regcm_normalize(state, regcm);
18001                         if (regcm == 0) {
18002                                 do_pre_copy = 1;
18003                         }
18004                         /* Always use pre_copies for constants.
18005                          * They do not take up any registers until a
18006                          * copy places them in one.
18007                          */
18008                         if ((info.reg == REG_UNNEEDED) && 
18009                                 (rinfo.reg != REG_UNNEEDED)) {
18010                                 do_pre_copy = 1;
18011                         }
18012                 }
18013                 do_post_copy =
18014                         !do_pre_copy &&
18015                         (((info.reg != REG_UNSET) && 
18016                                 (reg != REG_UNSET) &&
18017                                 (info.reg != reg)) ||
18018                         ((info.regcm & regcm) == 0));
18019
18020                 reg = info.reg;
18021                 regcm = info.regcm;
18022                 /* Walk through the uses of ins and do a pre_copy or see if a post_copy is warranted */
18023                 for(entry = ins->use; entry; entry = next) {
18024                         struct reg_info rinfo;
18025                         int i;
18026                         next = entry->next;
18027                         i = find_rhs_use(state, entry->member, ins);
18028                         if (i < 0) {
18029                                 continue;
18030                         }
18031                         
18032                         /* Find the users color requirements */
18033                         rinfo = arch_reg_rhs(state, entry->member, i);
18034                         if (rinfo.reg >= MAX_REGISTERS) {
18035                                 rinfo.reg = REG_UNSET;
18036                         }
18037
18038                         /* Now see if it is time to do the pre_copy */
18039                         if (rinfo.reg != REG_UNSET) {
18040                                 if (((reg != REG_UNSET) && (reg != rinfo.reg)) ||
18041                                         ((regcm & rinfo.regcm) == 0) ||
18042                                         /* Don't let a mandatory coalesce sneak
18043                                          * into a operation that is marked to prevent
18044                                          * coalescing.
18045                                          */
18046                                         ((reg != REG_UNNEEDED) &&
18047                                         ((ins->id & TRIPLE_FLAG_POST_SPLIT) ||
18048                                         (entry->member->id & TRIPLE_FLAG_PRE_SPLIT)))
18049                                         ) {
18050                                         if (do_pre_copy) {
18051                                                 struct triple *user;
18052                                                 user = entry->member;
18053                                                 if (RHS(user, i) != ins) {
18054                                                         internal_error(state, user, "bad rhs");
18055                                                 }
18056                                                 tmp = pre_copy(state, user, i);
18057                                                 tmp->id |= TRIPLE_FLAG_PRE_SPLIT;
18058                                                 continue;
18059                                         } else {
18060                                                 do_post_copy = 1;
18061                                         }
18062                                 }
18063                                 reg = rinfo.reg;
18064                         }
18065                         if ((regcm & rinfo.regcm) == 0) {
18066                                 if (do_pre_copy) {
18067                                         struct triple *user;
18068                                         user = entry->member;
18069                                         if (RHS(user, i) != ins) {
18070                                                 internal_error(state, user, "bad rhs");
18071                                         }
18072                                         tmp = pre_copy(state, user, i);
18073                                         tmp->id |= TRIPLE_FLAG_PRE_SPLIT;
18074                                         continue;
18075                                 } else {
18076                                         do_post_copy = 1;
18077                                 }
18078                         }
18079                         regcm &= rinfo.regcm;
18080                         
18081                 }
18082                 if (do_post_copy) {
18083                         struct reg_info pre, post;
18084                         tmp = post_copy(state, ins);
18085                         tmp->id |= TRIPLE_FLAG_PRE_SPLIT;
18086                         pre = arch_reg_lhs(state, ins, 0);
18087                         post = arch_reg_lhs(state, tmp, 0);
18088                         if ((pre.reg == post.reg) && (pre.regcm == post.regcm)) {
18089                                 internal_error(state, tmp, "useless copy");
18090                         }
18091                 }
18092         next:
18093                 ins = ins->next;
18094         } while(ins != first);
18095
18096         print_blocks(state, __func__, state->dbgout);
18097 }
18098
18099
18100 struct live_range_edge;
18101 struct live_range_def;
18102 struct live_range {
18103         struct live_range_edge *edges;
18104         struct live_range_def *defs;
18105 /* Note. The list pointed to by defs is kept in order.
18106  * That is baring splits in the flow control
18107  * defs dominates defs->next wich dominates defs->next->next
18108  * etc.
18109  */
18110         unsigned color;
18111         unsigned classes;
18112         unsigned degree;
18113         unsigned length;
18114         struct live_range *group_next, **group_prev;
18115 };
18116
18117 struct live_range_edge {
18118         struct live_range_edge *next;
18119         struct live_range *node;
18120 };
18121
18122 struct live_range_def {
18123         struct live_range_def *next;
18124         struct live_range_def *prev;
18125         struct live_range *lr;
18126         struct triple *def;
18127         unsigned orig_id;
18128 };
18129
18130 #define LRE_HASH_SIZE 2048
18131 struct lre_hash {
18132         struct lre_hash *next;
18133         struct live_range *left;
18134         struct live_range *right;
18135 };
18136
18137
18138 struct reg_state {
18139         struct lre_hash *hash[LRE_HASH_SIZE];
18140         struct reg_block *blocks;
18141         struct live_range_def *lrd;
18142         struct live_range *lr;
18143         struct live_range *low, **low_tail;
18144         struct live_range *high, **high_tail;
18145         unsigned defs;
18146         unsigned ranges;
18147         int passes, max_passes;
18148 };
18149
18150
18151 struct print_interference_block_info {
18152         struct reg_state *rstate;
18153         FILE *fp;
18154         int need_edges;
18155 };
18156 static void print_interference_block(
18157         struct compile_state *state, struct block *block, void *arg)
18158
18159 {
18160         struct print_interference_block_info *info = arg;
18161         struct reg_state *rstate = info->rstate;
18162         struct block_set *edge;
18163         FILE *fp = info->fp;
18164         struct reg_block *rb;
18165         struct triple *ptr;
18166         int phi_present;
18167         int done;
18168         rb = &rstate->blocks[block->vertex];
18169
18170         fprintf(fp, "\nblock: %p (%d),",
18171                 block,  block->vertex);
18172         for(edge = block->edges; edge; edge = edge->next) {
18173                 fprintf(fp, " %p<-%p",
18174                         edge->member, 
18175                         edge->member && edge->member->use?edge->member->use->member : 0);
18176         }
18177         fprintf(fp, "\n");
18178         if (rb->in) {
18179                 struct triple_reg_set *in_set;
18180                 fprintf(fp, "        in:");
18181                 for(in_set = rb->in; in_set; in_set = in_set->next) {
18182                         fprintf(fp, " %-10p", in_set->member);
18183                 }
18184                 fprintf(fp, "\n");
18185         }
18186         phi_present = 0;
18187         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
18188                 done = (ptr == block->last);
18189                 if (ptr->op == OP_PHI) {
18190                         phi_present = 1;
18191                         break;
18192                 }
18193         }
18194         if (phi_present) {
18195                 int edge;
18196                 for(edge = 0; edge < block->users; edge++) {
18197                         fprintf(fp, "     in(%d):", edge);
18198                         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
18199                                 struct triple **slot;
18200                                 done = (ptr == block->last);
18201                                 if (ptr->op != OP_PHI) {
18202                                         continue;
18203                                 }
18204                                 slot = &RHS(ptr, 0);
18205                                 fprintf(fp, " %-10p", slot[edge]);
18206                         }
18207                         fprintf(fp, "\n");
18208                 }
18209         }
18210         if (block->first->op == OP_LABEL) {
18211                 fprintf(fp, "%p:\n", block->first);
18212         }
18213         for(done = 0, ptr = block->first; !done; ptr = ptr->next) {
18214                 struct live_range *lr;
18215                 unsigned id;
18216                 int op;
18217                 op = ptr->op;
18218                 done = (ptr == block->last);
18219                 lr = rstate->lrd[ptr->id].lr;
18220                 
18221                 id = ptr->id;
18222                 ptr->id = rstate->lrd[id].orig_id;
18223                 SET_REG(ptr->id, lr->color);
18224                 display_triple(fp, ptr);
18225                 ptr->id = id;
18226
18227                 if (triple_is_def(state, ptr) && (lr->defs == 0)) {
18228                         internal_error(state, ptr, "lr has no defs!");
18229                 }
18230                 if (info->need_edges) {
18231                         if (lr->defs) {
18232                                 struct live_range_def *lrd;
18233                                 fprintf(fp, "       range:");
18234                                 lrd = lr->defs;
18235                                 do {
18236                                         fprintf(fp, " %-10p", lrd->def);
18237                                         lrd = lrd->next;
18238                                 } while(lrd != lr->defs);
18239                                 fprintf(fp, "\n");
18240                         }
18241                         if (lr->edges > 0) {
18242                                 struct live_range_edge *edge;
18243                                 fprintf(fp, "       edges:");
18244                                 for(edge = lr->edges; edge; edge = edge->next) {
18245                                         struct live_range_def *lrd;
18246                                         lrd = edge->node->defs;
18247                                         do {
18248                                                 fprintf(fp, " %-10p", lrd->def);
18249                                                 lrd = lrd->next;
18250                                         } while(lrd != edge->node->defs);
18251                                         fprintf(fp, "|");
18252                                 }
18253                                 fprintf(fp, "\n");
18254                         }
18255                 }
18256                 /* Do a bunch of sanity checks */
18257                 valid_ins(state, ptr);
18258                 if ((ptr->id < 0) || (ptr->id > rstate->defs)) {
18259                         internal_error(state, ptr, "Invalid triple id: %d",
18260                                 ptr->id);
18261                 }
18262         }
18263         if (rb->out) {
18264                 struct triple_reg_set *out_set;
18265                 fprintf(fp, "       out:");
18266                 for(out_set = rb->out; out_set; out_set = out_set->next) {
18267                         fprintf(fp, " %-10p", out_set->member);
18268                 }
18269                 fprintf(fp, "\n");
18270         }
18271         fprintf(fp, "\n");
18272 }
18273
18274 static void print_interference_blocks(
18275         struct compile_state *state, struct reg_state *rstate, FILE *fp, int need_edges)
18276 {
18277         struct print_interference_block_info info;
18278         info.rstate = rstate;
18279         info.fp = fp;
18280         info.need_edges = need_edges;
18281         fprintf(fp, "\nlive variables by block\n");
18282         walk_blocks(state, &state->bb, print_interference_block, &info);
18283
18284 }
18285
18286 static unsigned regc_max_size(struct compile_state *state, int classes)
18287 {
18288         unsigned max_size;
18289         int i;
18290         max_size = 0;
18291         for(i = 0; i < MAX_REGC; i++) {
18292                 if (classes & (1 << i)) {
18293                         unsigned size;
18294                         size = arch_regc_size(state, i);
18295                         if (size > max_size) {
18296                                 max_size = size;
18297                         }
18298                 }
18299         }
18300         return max_size;
18301 }
18302
18303 static int reg_is_reg(struct compile_state *state, int reg1, int reg2)
18304 {
18305         unsigned equivs[MAX_REG_EQUIVS];
18306         int i;
18307         if ((reg1 < 0) || (reg1 >= MAX_REGISTERS)) {
18308                 internal_error(state, 0, "invalid register");
18309         }
18310         if ((reg2 < 0) || (reg2 >= MAX_REGISTERS)) {
18311                 internal_error(state, 0, "invalid register");
18312         }
18313         arch_reg_equivs(state, equivs, reg1);
18314         for(i = 0; (i < MAX_REG_EQUIVS) && equivs[i] != REG_UNSET; i++) {
18315                 if (equivs[i] == reg2) {
18316                         return 1;
18317                 }
18318         }
18319         return 0;
18320 }
18321
18322 static void reg_fill_used(struct compile_state *state, char *used, int reg)
18323 {
18324         unsigned equivs[MAX_REG_EQUIVS];
18325         int i;
18326         if (reg == REG_UNNEEDED) {
18327                 return;
18328         }
18329         arch_reg_equivs(state, equivs, reg);
18330         for(i = 0; (i < MAX_REG_EQUIVS) && equivs[i] != REG_UNSET; i++) {
18331                 used[equivs[i]] = 1;
18332         }
18333         return;
18334 }
18335
18336 static void reg_inc_used(struct compile_state *state, char *used, int reg)
18337 {
18338         unsigned equivs[MAX_REG_EQUIVS];
18339         int i;
18340         if (reg == REG_UNNEEDED) {
18341                 return;
18342         }
18343         arch_reg_equivs(state, equivs, reg);
18344         for(i = 0; (i < MAX_REG_EQUIVS) && equivs[i] != REG_UNSET; i++) {
18345                 used[equivs[i]] += 1;
18346         }
18347         return;
18348 }
18349
18350 static unsigned int hash_live_edge(
18351         struct live_range *left, struct live_range *right)
18352 {
18353         unsigned int hash, val;
18354         unsigned long lval, rval;
18355         lval = ((unsigned long)left)/sizeof(struct live_range);
18356         rval = ((unsigned long)right)/sizeof(struct live_range);
18357         hash = 0;
18358         while(lval) {
18359                 val = lval & 0xff;
18360                 lval >>= 8;
18361                 hash = (hash *263) + val;
18362         }
18363         while(rval) {
18364                 val = rval & 0xff;
18365                 rval >>= 8;
18366                 hash = (hash *263) + val;
18367         }
18368         hash = hash & (LRE_HASH_SIZE - 1);
18369         return hash;
18370 }
18371
18372 static struct lre_hash **lre_probe(struct reg_state *rstate,
18373         struct live_range *left, struct live_range *right)
18374 {
18375         struct lre_hash **ptr;
18376         unsigned int index;
18377         /* Ensure left <= right */
18378         if (left > right) {
18379                 struct live_range *tmp;
18380                 tmp = left;
18381                 left = right;
18382                 right = tmp;
18383         }
18384         index = hash_live_edge(left, right);
18385         
18386         ptr = &rstate->hash[index];
18387         while(*ptr) {
18388                 if (((*ptr)->left == left) && ((*ptr)->right == right)) {
18389                         break;
18390                 }
18391                 ptr = &(*ptr)->next;
18392         }
18393         return ptr;
18394 }
18395
18396 static int interfere(struct reg_state *rstate,
18397         struct live_range *left, struct live_range *right)
18398 {
18399         struct lre_hash **ptr;
18400         ptr = lre_probe(rstate, left, right);
18401         return ptr && *ptr;
18402 }
18403
18404 static void add_live_edge(struct reg_state *rstate, 
18405         struct live_range *left, struct live_range *right)
18406 {
18407         /* FIXME the memory allocation overhead is noticeable here... */
18408         struct lre_hash **ptr, *new_hash;
18409         struct live_range_edge *edge;
18410
18411         if (left == right) {
18412                 return;
18413         }
18414         if ((left == &rstate->lr[0]) || (right == &rstate->lr[0])) {
18415                 return;
18416         }
18417         /* Ensure left <= right */
18418         if (left > right) {
18419                 struct live_range *tmp;
18420                 tmp = left;
18421                 left = right;
18422                 right = tmp;
18423         }
18424         ptr = lre_probe(rstate, left, right);
18425         if (*ptr) {
18426                 return;
18427         }
18428 #if 0
18429         fprintf(state->errout, "new_live_edge(%p, %p)\n",
18430                 left, right);
18431 #endif
18432         new_hash = xmalloc(sizeof(*new_hash), "lre_hash");
18433         new_hash->next  = *ptr;
18434         new_hash->left  = left;
18435         new_hash->right = right;
18436         *ptr = new_hash;
18437
18438         edge = xmalloc(sizeof(*edge), "live_range_edge");
18439         edge->next   = left->edges;
18440         edge->node   = right;
18441         left->edges  = edge;
18442         left->degree += 1;
18443         
18444         edge = xmalloc(sizeof(*edge), "live_range_edge");
18445         edge->next    = right->edges;
18446         edge->node    = left;
18447         right->edges  = edge;
18448         right->degree += 1;
18449 }
18450
18451 static void remove_live_edge(struct reg_state *rstate,
18452         struct live_range *left, struct live_range *right)
18453 {
18454         struct live_range_edge *edge, **ptr;
18455         struct lre_hash **hptr, *entry;
18456         hptr = lre_probe(rstate, left, right);
18457         if (!hptr || !*hptr) {
18458                 return;
18459         }
18460         entry = *hptr;
18461         *hptr = entry->next;
18462         xfree(entry);
18463
18464         for(ptr = &left->edges; *ptr; ptr = &(*ptr)->next) {
18465                 edge = *ptr;
18466                 if (edge->node == right) {
18467                         *ptr = edge->next;
18468                         memset(edge, 0, sizeof(*edge));
18469                         xfree(edge);
18470                         right->degree--;
18471                         break;
18472                 }
18473         }
18474         for(ptr = &right->edges; *ptr; ptr = &(*ptr)->next) {
18475                 edge = *ptr;
18476                 if (edge->node == left) {
18477                         *ptr = edge->next;
18478                         memset(edge, 0, sizeof(*edge));
18479                         xfree(edge);
18480                         left->degree--;
18481                         break;
18482                 }
18483         }
18484 }
18485
18486 static void remove_live_edges(struct reg_state *rstate, struct live_range *range)
18487 {
18488         struct live_range_edge *edge, *next;
18489         for(edge = range->edges; edge; edge = next) {
18490                 next = edge->next;
18491                 remove_live_edge(rstate, range, edge->node);
18492         }
18493 }
18494
18495 static void transfer_live_edges(struct reg_state *rstate, 
18496         struct live_range *dest, struct live_range *src)
18497 {
18498         struct live_range_edge *edge, *next;
18499         for(edge = src->edges; edge; edge = next) {
18500                 struct live_range *other;
18501                 next = edge->next;
18502                 other = edge->node;
18503                 remove_live_edge(rstate, src, other);
18504                 add_live_edge(rstate, dest, other);
18505         }
18506 }
18507
18508
18509 /* Interference graph...
18510  * 
18511  * new(n) --- Return a graph with n nodes but no edges.
18512  * add(g,x,y) --- Return a graph including g with an between x and y
18513  * interfere(g, x, y) --- Return true if there exists an edge between the nodes
18514  *                x and y in the graph g
18515  * degree(g, x) --- Return the degree of the node x in the graph g
18516  * neighbors(g, x, f) --- Apply function f to each neighbor of node x in the graph g
18517  *
18518  * Implement with a hash table && a set of adjcency vectors.
18519  * The hash table supports constant time implementations of add and interfere.
18520  * The adjacency vectors support an efficient implementation of neighbors.
18521  */
18522
18523 /* 
18524  *     +---------------------------------------------------+
18525  *     |         +--------------+                          |
18526  *     v         v              |                          |
18527  * renumber -> build graph -> colalesce -> spill_costs -> simplify -> select 
18528  *
18529  * -- In simplify implment optimistic coloring... (No backtracking)
18530  * -- Implement Rematerialization it is the only form of spilling we can perform
18531  *    Essentially this means dropping a constant from a register because
18532  *    we can regenerate it later.
18533  *
18534  * --- Very conservative colalescing (don't colalesce just mark the opportunities)
18535  *     coalesce at phi points...
18536  * --- Bias coloring if at all possible do the coalesing a compile time.
18537  *
18538  *
18539  */
18540
18541 static void different_colored(
18542         struct compile_state *state, struct reg_state *rstate, 
18543         struct triple *parent, struct triple *ins)
18544 {
18545         struct live_range *lr;
18546         struct triple **expr;
18547         lr = rstate->lrd[ins->id].lr;
18548         expr = triple_rhs(state, ins, 0);
18549         for(;expr; expr = triple_rhs(state, ins, expr)) {
18550                 struct live_range *lr2;
18551                 if (!*expr || (*expr == parent) || (*expr == ins)) {
18552                         continue;
18553                 }
18554                 lr2 = rstate->lrd[(*expr)->id].lr;
18555                 if (lr->color == lr2->color) {
18556                         internal_error(state, ins, "live range too big");
18557                 }
18558         }
18559 }
18560
18561
18562 static struct live_range *coalesce_ranges(
18563         struct compile_state *state, struct reg_state *rstate,
18564         struct live_range *lr1, struct live_range *lr2)
18565 {
18566         struct live_range_def *head, *mid1, *mid2, *end, *lrd;
18567         unsigned color;
18568         unsigned classes;
18569         if (lr1 == lr2) {
18570                 return lr1;
18571         }
18572         if (!lr1->defs || !lr2->defs) {
18573                 internal_error(state, 0,
18574                         "cannot coalese dead live ranges");
18575         }
18576         if ((lr1->color == REG_UNNEEDED) ||
18577                 (lr2->color == REG_UNNEEDED)) {
18578                 internal_error(state, 0, 
18579                         "cannot coalesce live ranges without a possible color");
18580         }
18581         if ((lr1->color != lr2->color) &&
18582                 (lr1->color != REG_UNSET) &&
18583                 (lr2->color != REG_UNSET)) {
18584                 internal_error(state, lr1->defs->def, 
18585                         "cannot coalesce live ranges of different colors");
18586         }
18587         color = lr1->color;
18588         if (color == REG_UNSET) {
18589                 color = lr2->color;
18590         }
18591         classes = lr1->classes & lr2->classes;
18592         if (!classes) {
18593                 internal_error(state, lr1->defs->def,
18594                         "cannot coalesce live ranges with dissimilar register classes");
18595         }
18596         if (state->compiler->debug & DEBUG_COALESCING) {
18597                 FILE *fp = state->errout;
18598                 fprintf(fp, "coalescing:");
18599                 lrd = lr1->defs;
18600                 do {
18601                         fprintf(fp, " %p", lrd->def);
18602                         lrd = lrd->next;
18603                 } while(lrd != lr1->defs);
18604                 fprintf(fp, " |");
18605                 lrd = lr2->defs;
18606                 do {
18607                         fprintf(fp, " %p", lrd->def);
18608                         lrd = lrd->next;
18609                 } while(lrd != lr2->defs);
18610                 fprintf(fp, "\n");
18611         }
18612         /* If there is a clear dominate live range put it in lr1,
18613          * For purposes of this test phi functions are
18614          * considered dominated by the definitions that feed into
18615          * them. 
18616          */
18617         if ((lr1->defs->prev->def->op == OP_PHI) ||
18618                 ((lr2->defs->prev->def->op != OP_PHI) &&
18619                 tdominates(state, lr2->defs->def, lr1->defs->def))) {
18620                 struct live_range *tmp;
18621                 tmp = lr1;
18622                 lr1 = lr2;
18623                 lr2 = tmp;
18624         }
18625 #if 0
18626         if (lr1->defs->orig_id  & TRIPLE_FLAG_POST_SPLIT) {
18627                 fprintf(state->errout, "lr1 post\n");
18628         }
18629         if (lr1->defs->orig_id & TRIPLE_FLAG_PRE_SPLIT) {
18630                 fprintf(state->errout, "lr1 pre\n");
18631         }
18632         if (lr2->defs->orig_id  & TRIPLE_FLAG_POST_SPLIT) {
18633                 fprintf(state->errout, "lr2 post\n");
18634         }
18635         if (lr2->defs->orig_id & TRIPLE_FLAG_PRE_SPLIT) {
18636                 fprintf(state->errout, "lr2 pre\n");
18637         }
18638 #endif
18639 #if 0
18640         fprintf(state->errout, "coalesce color1(%p): %3d color2(%p) %3d\n",
18641                 lr1->defs->def,
18642                 lr1->color,
18643                 lr2->defs->def,
18644                 lr2->color);
18645 #endif
18646         
18647         /* Append lr2 onto lr1 */
18648 #warning "FIXME should this be a merge instead of a splice?"
18649         /* This FIXME item applies to the correctness of live_range_end 
18650          * and to the necessity of making multiple passes of coalesce_live_ranges.
18651          * A failure to find some coalesce opportunities in coaleace_live_ranges
18652          * does not impact the correct of the compiler just the efficiency with
18653          * which registers are allocated.
18654          */
18655         head = lr1->defs;
18656         mid1 = lr1->defs->prev;
18657         mid2 = lr2->defs;
18658         end  = lr2->defs->prev;
18659         
18660         head->prev = end;
18661         end->next  = head;
18662
18663         mid1->next = mid2;
18664         mid2->prev = mid1;
18665
18666         /* Fixup the live range in the added live range defs */
18667         lrd = head;
18668         do {
18669                 lrd->lr = lr1;
18670                 lrd = lrd->next;
18671         } while(lrd != head);
18672
18673         /* Mark lr2 as free. */
18674         lr2->defs = 0;
18675         lr2->color = REG_UNNEEDED;
18676         lr2->classes = 0;
18677
18678         if (!lr1->defs) {
18679                 internal_error(state, 0, "lr1->defs == 0 ?");
18680         }
18681
18682         lr1->color   = color;
18683         lr1->classes = classes;
18684
18685         /* Keep the graph in sync by transfering the edges from lr2 to lr1 */
18686         transfer_live_edges(rstate, lr1, lr2);
18687
18688         return lr1;
18689 }
18690
18691 static struct live_range_def *live_range_head(
18692         struct compile_state *state, struct live_range *lr,
18693         struct live_range_def *last)
18694 {
18695         struct live_range_def *result;
18696         result = 0;
18697         if (last == 0) {
18698                 result = lr->defs;
18699         }
18700         else if (!tdominates(state, lr->defs->def, last->next->def)) {
18701                 result = last->next;
18702         }
18703         return result;
18704 }
18705
18706 static struct live_range_def *live_range_end(
18707         struct compile_state *state, struct live_range *lr,
18708         struct live_range_def *last)
18709 {
18710         struct live_range_def *result;
18711         result = 0;
18712         if (last == 0) {
18713                 result = lr->defs->prev;
18714         }
18715         else if (!tdominates(state, last->prev->def, lr->defs->prev->def)) {
18716                 result = last->prev;
18717         }
18718         return result;
18719 }
18720
18721
18722 static void initialize_live_ranges(
18723         struct compile_state *state, struct reg_state *rstate)
18724 {
18725         struct triple *ins, *first;
18726         size_t count, size;
18727         int i, j;
18728
18729         first = state->first;
18730         /* First count how many instructions I have.
18731          */
18732         count = count_triples(state);
18733         /* Potentially I need one live range definitions for each
18734          * instruction.
18735          */
18736         rstate->defs = count;
18737         /* Potentially I need one live range for each instruction
18738          * plus an extra for the dummy live range.
18739          */
18740         rstate->ranges = count + 1;
18741         size = sizeof(rstate->lrd[0]) * rstate->defs;
18742         rstate->lrd = xcmalloc(size, "live_range_def");
18743         size = sizeof(rstate->lr[0]) * rstate->ranges;
18744         rstate->lr  = xcmalloc(size, "live_range");
18745
18746         /* Setup the dummy live range */
18747         rstate->lr[0].classes = 0;
18748         rstate->lr[0].color = REG_UNSET;
18749         rstate->lr[0].defs = 0;
18750         i = j = 0;
18751         ins = first;
18752         do {
18753                 /* If the triple is a variable give it a live range */
18754                 if (triple_is_def(state, ins)) {
18755                         struct reg_info info;
18756                         /* Find the architecture specific color information */
18757                         info = find_def_color(state, ins);
18758                         i++;
18759                         rstate->lr[i].defs    = &rstate->lrd[j];
18760                         rstate->lr[i].color   = info.reg;
18761                         rstate->lr[i].classes = info.regcm;
18762                         rstate->lr[i].degree  = 0;
18763                         rstate->lrd[j].lr = &rstate->lr[i];
18764                 } 
18765                 /* Otherwise give the triple the dummy live range. */
18766                 else {
18767                         rstate->lrd[j].lr = &rstate->lr[0];
18768                 }
18769
18770                 /* Initalize the live_range_def */
18771                 rstate->lrd[j].next    = &rstate->lrd[j];
18772                 rstate->lrd[j].prev    = &rstate->lrd[j];
18773                 rstate->lrd[j].def     = ins;
18774                 rstate->lrd[j].orig_id = ins->id;
18775                 ins->id = j;
18776
18777                 j++;
18778                 ins = ins->next;
18779         } while(ins != first);
18780         rstate->ranges = i;
18781
18782         /* Make a second pass to handle achitecture specific register
18783          * constraints.
18784          */
18785         ins = first;
18786         do {
18787                 int zlhs, zrhs, i, j;
18788                 if (ins->id > rstate->defs) {
18789                         internal_error(state, ins, "bad id");
18790                 }
18791                 
18792                 /* Walk through the template of ins and coalesce live ranges */
18793                 zlhs = ins->lhs;
18794                 if ((zlhs == 0) && triple_is_def(state, ins)) {
18795                         zlhs = 1;
18796                 }
18797                 zrhs = ins->rhs;
18798
18799                 if (state->compiler->debug & DEBUG_COALESCING2) {
18800                         fprintf(state->errout, "mandatory coalesce: %p %d %d\n",
18801                                 ins, zlhs, zrhs);
18802                 }
18803
18804                 for(i = 0; i < zlhs; i++) {
18805                         struct reg_info linfo;
18806                         struct live_range_def *lhs;
18807                         linfo = arch_reg_lhs(state, ins, i);
18808                         if (linfo.reg < MAX_REGISTERS) {
18809                                 continue;
18810                         }
18811                         if (triple_is_def(state, ins)) {
18812                                 lhs = &rstate->lrd[ins->id];
18813                         } else {
18814                                 lhs = &rstate->lrd[LHS(ins, i)->id];
18815                         }
18816
18817                         if (state->compiler->debug & DEBUG_COALESCING2) {
18818                                 fprintf(state->errout, "coalesce lhs(%d): %p %d\n",
18819                                         i, lhs, linfo.reg);
18820                         }
18821
18822                         for(j = 0; j < zrhs; j++) {
18823                                 struct reg_info rinfo;
18824                                 struct live_range_def *rhs;
18825                                 rinfo = arch_reg_rhs(state, ins, j);
18826                                 if (rinfo.reg < MAX_REGISTERS) {
18827                                         continue;
18828                                 }
18829                                 rhs = &rstate->lrd[RHS(ins, j)->id];
18830
18831                                 if (state->compiler->debug & DEBUG_COALESCING2) {
18832                                         fprintf(state->errout, "coalesce rhs(%d): %p %d\n",
18833                                                 j, rhs, rinfo.reg);
18834                                 }
18835
18836                                 if (rinfo.reg == linfo.reg) {
18837                                         coalesce_ranges(state, rstate, 
18838                                                 lhs->lr, rhs->lr);
18839                                 }
18840                         }
18841                 }
18842                 ins = ins->next;
18843         } while(ins != first);
18844 }
18845
18846 static void graph_ins(
18847         struct compile_state *state, 
18848         struct reg_block *blocks, struct triple_reg_set *live, 
18849         struct reg_block *rb, struct triple *ins, void *arg)
18850 {
18851         struct reg_state *rstate = arg;
18852         struct live_range *def;
18853         struct triple_reg_set *entry;
18854
18855         /* If the triple is not a definition
18856          * we do not have a definition to add to
18857          * the interference graph.
18858          */
18859         if (!triple_is_def(state, ins)) {
18860                 return;
18861         }
18862         def = rstate->lrd[ins->id].lr;
18863         
18864         /* Create an edge between ins and everything that is
18865          * alive, unless the live_range cannot share
18866          * a physical register with ins.
18867          */
18868         for(entry = live; entry; entry = entry->next) {
18869                 struct live_range *lr;
18870                 if ((entry->member->id < 0) || (entry->member->id > rstate->defs)) {
18871                         internal_error(state, 0, "bad entry?");
18872                 }
18873                 lr = rstate->lrd[entry->member->id].lr;
18874                 if (def == lr) {
18875                         continue;
18876                 }
18877                 if (!arch_regcm_intersect(def->classes, lr->classes)) {
18878                         continue;
18879                 }
18880                 add_live_edge(rstate, def, lr);
18881         }
18882         return;
18883 }
18884
18885 static struct live_range *get_verify_live_range(
18886         struct compile_state *state, struct reg_state *rstate, struct triple *ins)
18887 {
18888         struct live_range *lr;
18889         struct live_range_def *lrd;
18890         int ins_found;
18891         if ((ins->id < 0) || (ins->id > rstate->defs)) {
18892                 internal_error(state, ins, "bad ins?");
18893         }
18894         lr = rstate->lrd[ins->id].lr;
18895         ins_found = 0;
18896         lrd = lr->defs;
18897         do {
18898                 if (lrd->def == ins) {
18899                         ins_found = 1;
18900                 }
18901                 lrd = lrd->next;
18902         } while(lrd != lr->defs);
18903         if (!ins_found) {
18904                 internal_error(state, ins, "ins not in live range");
18905         }
18906         return lr;
18907 }
18908
18909 static void verify_graph_ins(
18910         struct compile_state *state, 
18911         struct reg_block *blocks, struct triple_reg_set *live, 
18912         struct reg_block *rb, struct triple *ins, void *arg)
18913 {
18914         struct reg_state *rstate = arg;
18915         struct triple_reg_set *entry1, *entry2;
18916
18917
18918         /* Compare live against edges and make certain the code is working */
18919         for(entry1 = live; entry1; entry1 = entry1->next) {
18920                 struct live_range *lr1;
18921                 lr1 = get_verify_live_range(state, rstate, entry1->member);
18922                 for(entry2 = live; entry2; entry2 = entry2->next) {
18923                         struct live_range *lr2;
18924                         struct live_range_edge *edge2;
18925                         int lr1_found;
18926                         int lr2_degree;
18927                         if (entry2 == entry1) {
18928                                 continue;
18929                         }
18930                         lr2 = get_verify_live_range(state, rstate, entry2->member);
18931                         if (lr1 == lr2) {
18932                                 internal_error(state, entry2->member, 
18933                                         "live range with 2 values simultaneously alive");
18934                         }
18935                         if (!arch_regcm_intersect(lr1->classes, lr2->classes)) {
18936                                 continue;
18937                         }
18938                         if (!interfere(rstate, lr1, lr2)) {
18939                                 internal_error(state, entry2->member, 
18940                                         "edges don't interfere?");
18941                         }
18942                                 
18943                         lr1_found = 0;
18944                         lr2_degree = 0;
18945                         for(edge2 = lr2->edges; edge2; edge2 = edge2->next) {
18946                                 lr2_degree++;
18947                                 if (edge2->node == lr1) {
18948                                         lr1_found = 1;
18949                                 }
18950                         }
18951                         if (lr2_degree != lr2->degree) {
18952                                 internal_error(state, entry2->member,
18953                                         "computed degree: %d does not match reported degree: %d\n",
18954                                         lr2_degree, lr2->degree);
18955                         }
18956                         if (!lr1_found) {
18957                                 internal_error(state, entry2->member, "missing edge");
18958                         }
18959                 }
18960         }
18961         return;
18962 }
18963
18964
18965 static void print_interference_ins(
18966         struct compile_state *state, 
18967         struct reg_block *blocks, struct triple_reg_set *live, 
18968         struct reg_block *rb, struct triple *ins, void *arg)
18969 {
18970         struct reg_state *rstate = arg;
18971         struct live_range *lr;
18972         unsigned id;
18973         FILE *fp = state->dbgout;
18974
18975         lr = rstate->lrd[ins->id].lr;
18976         id = ins->id;
18977         ins->id = rstate->lrd[id].orig_id;
18978         SET_REG(ins->id, lr->color);
18979         display_triple(state->dbgout, ins);
18980         ins->id = id;
18981
18982         if (lr->defs) {
18983                 struct live_range_def *lrd;
18984                 fprintf(fp, "       range:");
18985                 lrd = lr->defs;
18986                 do {
18987                         fprintf(fp, " %-10p", lrd->def);
18988                         lrd = lrd->next;
18989                 } while(lrd != lr->defs);
18990                 fprintf(fp, "\n");
18991         }
18992         if (live) {
18993                 struct triple_reg_set *entry;
18994                 fprintf(fp, "        live:");
18995                 for(entry = live; entry; entry = entry->next) {
18996                         fprintf(fp, " %-10p", entry->member);
18997                 }
18998                 fprintf(fp, "\n");
18999         }
19000         if (lr->edges) {
19001                 struct live_range_edge *entry;
19002                 fprintf(fp, "       edges:");
19003                 for(entry = lr->edges; entry; entry = entry->next) {
19004                         struct live_range_def *lrd;
19005                         lrd = entry->node->defs;
19006                         do {
19007                                 fprintf(fp, " %-10p", lrd->def);
19008                                 lrd = lrd->next;
19009                         } while(lrd != entry->node->defs);
19010                         fprintf(fp, "|");
19011                 }
19012                 fprintf(fp, "\n");
19013         }
19014         if (triple_is_branch(state, ins)) {
19015                 fprintf(fp, "\n");
19016         }
19017         return;
19018 }
19019
19020 static int coalesce_live_ranges(
19021         struct compile_state *state, struct reg_state *rstate)
19022 {
19023         /* At the point where a value is moved from one
19024          * register to another that value requires two
19025          * registers, thus increasing register pressure.
19026          * Live range coaleescing reduces the register
19027          * pressure by keeping a value in one register
19028          * longer.
19029          *
19030          * In the case of a phi function all paths leading
19031          * into it must be allocated to the same register
19032          * otherwise the phi function may not be removed.
19033          *
19034          * Forcing a value to stay in a single register
19035          * for an extended period of time does have
19036          * limitations when applied to non homogenous
19037          * register pool.  
19038          *
19039          * The two cases I have identified are:
19040          * 1) Two forced register assignments may
19041          *    collide.
19042          * 2) Registers may go unused because they
19043          *    are only good for storing the value
19044          *    and not manipulating it.
19045          *
19046          * Because of this I need to split live ranges,
19047          * even outside of the context of coalesced live
19048          * ranges.  The need to split live ranges does
19049          * impose some constraints on live range coalescing.
19050          *
19051          * - Live ranges may not be coalesced across phi
19052          *   functions.  This creates a 2 headed live
19053          *   range that cannot be sanely split.
19054          *
19055          * - phi functions (coalesced in initialize_live_ranges) 
19056          *   are handled as pre split live ranges so we will
19057          *   never attempt to split them.
19058          */
19059         int coalesced;
19060         int i;
19061
19062         coalesced = 0;
19063         for(i = 0; i <= rstate->ranges; i++) {
19064                 struct live_range *lr1;
19065                 struct live_range_def *lrd1;
19066                 lr1 = &rstate->lr[i];
19067                 if (!lr1->defs) {
19068                         continue;
19069                 }
19070                 lrd1 = live_range_end(state, lr1, 0);
19071                 for(; lrd1; lrd1 = live_range_end(state, lr1, lrd1)) {
19072                         struct triple_set *set;
19073                         if (lrd1->def->op != OP_COPY) {
19074                                 continue;
19075                         }
19076                         /* Skip copies that are the result of a live range split. */
19077                         if (lrd1->orig_id & TRIPLE_FLAG_POST_SPLIT) {
19078                                 continue;
19079                         }
19080                         for(set = lrd1->def->use; set; set = set->next) {
19081                                 struct live_range_def *lrd2;
19082                                 struct live_range *lr2, *res;
19083
19084                                 lrd2 = &rstate->lrd[set->member->id];
19085
19086                                 /* Don't coalesce with instructions
19087                                  * that are the result of a live range
19088                                  * split.
19089                                  */
19090                                 if (lrd2->orig_id & TRIPLE_FLAG_PRE_SPLIT) {
19091                                         continue;
19092                                 }
19093                                 lr2 = rstate->lrd[set->member->id].lr;
19094                                 if (lr1 == lr2) {
19095                                         continue;
19096                                 }
19097                                 if ((lr1->color != lr2->color) &&
19098                                         (lr1->color != REG_UNSET) &&
19099                                         (lr2->color != REG_UNSET)) {
19100                                         continue;
19101                                 }
19102                                 if ((lr1->classes & lr2->classes) == 0) {
19103                                         continue;
19104                                 }
19105                                 
19106                                 if (interfere(rstate, lr1, lr2)) {
19107                                         continue;
19108                                 }
19109
19110                                 res = coalesce_ranges(state, rstate, lr1, lr2);
19111                                 coalesced += 1;
19112                                 if (res != lr1) {
19113                                         goto next;
19114                                 }
19115                         }
19116                 }
19117         next:
19118                 ;
19119         }
19120         return coalesced;
19121 }
19122
19123
19124 static void fix_coalesce_conflicts(struct compile_state *state,
19125         struct reg_block *blocks, struct triple_reg_set *live,
19126         struct reg_block *rb, struct triple *ins, void *arg)
19127 {
19128         int *conflicts = arg;
19129         int zlhs, zrhs, i, j;
19130
19131         /* See if we have a mandatory coalesce operation between
19132          * a lhs and a rhs value.  If so and the rhs value is also
19133          * alive then this triple needs to be pre copied.  Otherwise
19134          * we would have two definitions in the same live range simultaneously
19135          * alive.
19136          */
19137         zlhs = ins->lhs;
19138         if ((zlhs == 0) && triple_is_def(state, ins)) {
19139                 zlhs = 1;
19140         }
19141         zrhs = ins->rhs;
19142         for(i = 0; i < zlhs; i++) {
19143                 struct reg_info linfo;
19144                 linfo = arch_reg_lhs(state, ins, i);
19145                 if (linfo.reg < MAX_REGISTERS) {
19146                         continue;
19147                 }
19148                 for(j = 0; j < zrhs; j++) {
19149                         struct reg_info rinfo;
19150                         struct triple *rhs;
19151                         struct triple_reg_set *set;
19152                         int found;
19153                         found = 0;
19154                         rinfo = arch_reg_rhs(state, ins, j);
19155                         if (rinfo.reg != linfo.reg) {
19156                                 continue;
19157                         }
19158                         rhs = RHS(ins, j);
19159                         for(set = live; set && !found; set = set->next) {
19160                                 if (set->member == rhs) {
19161                                         found = 1;
19162                                 }
19163                         }
19164                         if (found) {
19165                                 struct triple *copy;
19166                                 copy = pre_copy(state, ins, j);
19167                                 copy->id |= TRIPLE_FLAG_PRE_SPLIT;
19168                                 (*conflicts)++;
19169                         }
19170                 }
19171         }
19172         return;
19173 }
19174
19175 static int correct_coalesce_conflicts(
19176         struct compile_state *state, struct reg_block *blocks)
19177 {
19178         int conflicts;
19179         conflicts = 0;
19180         walk_variable_lifetimes(state, &state->bb, blocks, 
19181                 fix_coalesce_conflicts, &conflicts);
19182         return conflicts;
19183 }
19184
19185 static void replace_set_use(struct compile_state *state,
19186         struct triple_reg_set *head, struct triple *orig, struct triple *new)
19187 {
19188         struct triple_reg_set *set;
19189         for(set = head; set; set = set->next) {
19190                 if (set->member == orig) {
19191                         set->member = new;
19192                 }
19193         }
19194 }
19195
19196 static void replace_block_use(struct compile_state *state, 
19197         struct reg_block *blocks, struct triple *orig, struct triple *new)
19198 {
19199         int i;
19200 #warning "WISHLIST visit just those blocks that need it *"
19201         for(i = 1; i <= state->bb.last_vertex; i++) {
19202                 struct reg_block *rb;
19203                 rb = &blocks[i];
19204                 replace_set_use(state, rb->in, orig, new);
19205                 replace_set_use(state, rb->out, orig, new);
19206         }
19207 }
19208
19209 static void color_instructions(struct compile_state *state)
19210 {
19211         struct triple *ins, *first;
19212         first = state->first;
19213         ins = first;
19214         do {
19215                 if (triple_is_def(state, ins)) {
19216                         struct reg_info info;
19217                         info = find_lhs_color(state, ins, 0);
19218                         if (info.reg >= MAX_REGISTERS) {
19219                                 info.reg = REG_UNSET;
19220                         }
19221                         SET_INFO(ins->id, info);
19222                 }
19223                 ins = ins->next;
19224         } while(ins != first);
19225 }
19226
19227 static struct reg_info read_lhs_color(
19228         struct compile_state *state, struct triple *ins, int index)
19229 {
19230         struct reg_info info;
19231         if ((index == 0) && triple_is_def(state, ins)) {
19232                 info.reg   = ID_REG(ins->id);
19233                 info.regcm = ID_REGCM(ins->id);
19234         }
19235         else if (index < ins->lhs) {
19236                 info = read_lhs_color(state, LHS(ins, index), 0);
19237         }
19238         else {
19239                 internal_error(state, ins, "Bad lhs %d", index);
19240                 info.reg = REG_UNSET;
19241                 info.regcm = 0;
19242         }
19243         return info;
19244 }
19245
19246 static struct triple *resolve_tangle(
19247         struct compile_state *state, struct triple *tangle)
19248 {
19249         struct reg_info info, uinfo;
19250         struct triple_set *set, *next;
19251         struct triple *copy;
19252
19253 #warning "WISHLIST recalculate all affected instructions colors"
19254         info = find_lhs_color(state, tangle, 0);
19255         for(set = tangle->use; set; set = next) {
19256                 struct triple *user;
19257                 int i, zrhs;
19258                 next = set->next;
19259                 user = set->member;
19260                 zrhs = user->rhs;
19261                 for(i = 0; i < zrhs; i++) {
19262                         if (RHS(user, i) != tangle) {
19263                                 continue;
19264                         }
19265                         uinfo = find_rhs_post_color(state, user, i);
19266                         if (uinfo.reg == info.reg) {
19267                                 copy = pre_copy(state, user, i);
19268                                 copy->id |= TRIPLE_FLAG_PRE_SPLIT;
19269                                 SET_INFO(copy->id, uinfo);
19270                         }
19271                 }
19272         }
19273         copy = 0;
19274         uinfo = find_lhs_pre_color(state, tangle, 0);
19275         if (uinfo.reg == info.reg) {
19276                 struct reg_info linfo;
19277                 copy = post_copy(state, tangle);
19278                 copy->id |= TRIPLE_FLAG_PRE_SPLIT;
19279                 linfo = find_lhs_color(state, copy, 0);
19280                 SET_INFO(copy->id, linfo);
19281         }
19282         info = find_lhs_color(state, tangle, 0);
19283         SET_INFO(tangle->id, info);
19284         
19285         return copy;
19286 }
19287
19288
19289 static void fix_tangles(struct compile_state *state,
19290         struct reg_block *blocks, struct triple_reg_set *live,
19291         struct reg_block *rb, struct triple *ins, void *arg)
19292 {
19293         int *tangles = arg;
19294         struct triple *tangle;
19295         do {
19296                 char used[MAX_REGISTERS];
19297                 struct triple_reg_set *set;
19298                 tangle = 0;
19299
19300                 /* Find out which registers have multiple uses at this point */
19301                 memset(used, 0, sizeof(used));
19302                 for(set = live; set; set = set->next) {
19303                         struct reg_info info;
19304                         info = read_lhs_color(state, set->member, 0);
19305                         if (info.reg == REG_UNSET) {
19306                                 continue;
19307                         }
19308                         reg_inc_used(state, used, info.reg);
19309                 }
19310                 
19311                 /* Now find the least dominated definition of a register in
19312                  * conflict I have seen so far.
19313                  */
19314                 for(set = live; set; set = set->next) {
19315                         struct reg_info info;
19316                         info = read_lhs_color(state, set->member, 0);
19317                         if (used[info.reg] < 2) {
19318                                 continue;
19319                         }
19320                         /* Changing copies that feed into phi functions
19321                          * is incorrect.
19322                          */
19323                         if (set->member->use && 
19324                                 (set->member->use->member->op == OP_PHI)) {
19325                                 continue;
19326                         }
19327                         if (!tangle || tdominates(state, set->member, tangle)) {
19328                                 tangle = set->member;
19329                         }
19330                 }
19331                 /* If I have found a tangle resolve it */
19332                 if (tangle) {
19333                         struct triple *post_copy;
19334                         (*tangles)++;
19335                         post_copy = resolve_tangle(state, tangle);
19336                         if (post_copy) {
19337                                 replace_block_use(state, blocks, tangle, post_copy);
19338                         }
19339                         if (post_copy && (tangle != ins)) {
19340                                 replace_set_use(state, live, tangle, post_copy);
19341                         }
19342                 }
19343         } while(tangle);
19344         return;
19345 }
19346
19347 static int correct_tangles(
19348         struct compile_state *state, struct reg_block *blocks)
19349 {
19350         int tangles;
19351         tangles = 0;
19352         color_instructions(state);
19353         walk_variable_lifetimes(state, &state->bb, blocks, 
19354                 fix_tangles, &tangles);
19355         return tangles;
19356 }
19357
19358
19359 static void ids_from_rstate(struct compile_state *state, struct reg_state *rstate);
19360 static void cleanup_rstate(struct compile_state *state, struct reg_state *rstate);
19361
19362 struct triple *find_constrained_def(
19363         struct compile_state *state, struct live_range *range, struct triple *constrained)
19364 {
19365         struct live_range_def *lrd, *lrd_next;
19366         lrd_next = range->defs;
19367         do {
19368                 struct reg_info info;
19369                 unsigned regcm;
19370
19371                 lrd = lrd_next;
19372                 lrd_next = lrd->next;
19373
19374                 regcm = arch_type_to_regcm(state, lrd->def->type);
19375                 info = find_lhs_color(state, lrd->def, 0);
19376                 regcm      = arch_regcm_reg_normalize(state, regcm);
19377                 info.regcm = arch_regcm_reg_normalize(state, info.regcm);
19378                 /* If the 2 register class masks are equal then
19379                  * the current register class is not constrained.
19380                  */
19381                 if (regcm == info.regcm) {
19382                         continue;
19383                 }
19384                 
19385                 /* If there is just one use.
19386                  * That use cannot accept a larger register class.
19387                  * There are no intervening definitions except
19388                  * definitions that feed into that use.
19389                  * Then a triple is not constrained.
19390                  * FIXME handle this case!
19391                  */
19392 #warning "FIXME ignore cases that cannot be fixed (a definition followed by a use)"
19393                 
19394
19395                 /* Of the constrained live ranges deal with the
19396                  * least dominated one first.
19397                  */
19398                 if (state->compiler->debug & DEBUG_RANGE_CONFLICTS) {
19399                         fprintf(state->errout, "canidate: %p %-8s regcm: %x %x\n",
19400                                 lrd->def, tops(lrd->def->op), regcm, info.regcm);
19401                 }
19402                 if (!constrained || 
19403                         tdominates(state, lrd->def, constrained))
19404                 {
19405                         constrained = lrd->def;
19406                 }
19407         } while(lrd_next != range->defs);
19408         return constrained;
19409 }
19410
19411 static int split_constrained_ranges(
19412         struct compile_state *state, struct reg_state *rstate, 
19413         struct live_range *range)
19414 {
19415         /* Walk through the edges in conflict and our current live
19416          * range, and find definitions that are more severly constrained
19417          * than they type of data they contain require.
19418          * 
19419          * Then pick one of those ranges and relax the constraints.
19420          */
19421         struct live_range_edge *edge;
19422         struct triple *constrained;
19423
19424         constrained = 0;
19425         for(edge = range->edges; edge; edge = edge->next) {
19426                 constrained = find_constrained_def(state, edge->node, constrained);
19427         }
19428 #warning "FIXME should I call find_constrained_def here only if no previous constrained def was found?"
19429         if (!constrained) {
19430                 constrained = find_constrained_def(state, range, constrained);
19431         }
19432
19433         if (state->compiler->debug & DEBUG_RANGE_CONFLICTS) {
19434                 fprintf(state->errout, "constrained: ");
19435                 display_triple(state->errout, constrained);
19436         }
19437         if (constrained) {
19438                 ids_from_rstate(state, rstate);
19439                 cleanup_rstate(state, rstate);
19440                 resolve_tangle(state, constrained);
19441         }
19442         return !!constrained;
19443 }
19444         
19445 static int split_ranges(
19446         struct compile_state *state, struct reg_state *rstate,
19447         char *used, struct live_range *range)
19448 {
19449         int split;
19450         if (state->compiler->debug & DEBUG_RANGE_CONFLICTS) {
19451                 fprintf(state->errout, "split_ranges %d %s %p\n", 
19452                         rstate->passes, tops(range->defs->def->op), range->defs->def);
19453         }
19454         if ((range->color == REG_UNNEEDED) ||
19455                 (rstate->passes >= rstate->max_passes)) {
19456                 return 0;
19457         }
19458         split = split_constrained_ranges(state, rstate, range);
19459
19460         /* Ideally I would split the live range that will not be used
19461          * for the longest period of time in hopes that this will 
19462          * (a) allow me to spill a register or
19463          * (b) allow me to place a value in another register.
19464          *
19465          * So far I don't have a test case for this, the resolving
19466          * of mandatory constraints has solved all of my
19467          * know issues.  So I have choosen not to write any
19468          * code until I cat get a better feel for cases where
19469          * it would be useful to have.
19470          *
19471          */
19472 #warning "WISHLIST implement live range splitting..."
19473         
19474         if (!split && (state->compiler->debug & DEBUG_RANGE_CONFLICTS2)) {
19475                 FILE *fp = state->errout;
19476                 print_interference_blocks(state, rstate, fp, 0);
19477                 print_dominators(state, fp, &state->bb);
19478         }
19479         return split;
19480 }
19481
19482 static FILE *cgdebug_fp(struct compile_state *state)
19483 {
19484         FILE *fp;
19485         fp = 0;
19486         if (!fp && (state->compiler->debug & DEBUG_COLOR_GRAPH2)) {
19487                 fp = state->errout;
19488         }
19489         if (!fp && (state->compiler->debug & DEBUG_COLOR_GRAPH)) {
19490                 fp = state->dbgout;
19491         }
19492         return fp;
19493 }
19494
19495 static void cgdebug_printf(struct compile_state *state, const char *fmt, ...)
19496 {
19497         FILE *fp;
19498         fp = cgdebug_fp(state);
19499         if (fp) {
19500                 va_list args;
19501                 va_start(args, fmt);
19502                 vfprintf(fp, fmt, args);
19503                 va_end(args);
19504         }
19505 }
19506
19507 static void cgdebug_flush(struct compile_state *state)
19508 {
19509         FILE *fp;
19510         fp = cgdebug_fp(state);
19511         if (fp) {
19512                 fflush(fp);
19513         }
19514 }
19515
19516 static void cgdebug_loc(struct compile_state *state, struct triple *ins)
19517 {
19518         FILE *fp;
19519         fp = cgdebug_fp(state);
19520         if (fp) {
19521                 loc(fp, state, ins);
19522         }
19523 }
19524
19525 static int select_free_color(struct compile_state *state, 
19526         struct reg_state *rstate, struct live_range *range)
19527 {
19528         struct triple_set *entry;
19529         struct live_range_def *lrd;
19530         struct live_range_def *phi;
19531         struct live_range_edge *edge;
19532         char used[MAX_REGISTERS];
19533         struct triple **expr;
19534
19535         /* Instead of doing just the trivial color select here I try
19536          * a few extra things because a good color selection will help reduce
19537          * copies.
19538          */
19539
19540         /* Find the registers currently in use */
19541         memset(used, 0, sizeof(used));
19542         for(edge = range->edges; edge; edge = edge->next) {
19543                 if (edge->node->color == REG_UNSET) {
19544                         continue;
19545                 }
19546                 reg_fill_used(state, used, edge->node->color);
19547         }
19548
19549         if (state->compiler->debug & DEBUG_COLOR_GRAPH2) {
19550                 int i;
19551                 i = 0;
19552                 for(edge = range->edges; edge; edge = edge->next) {
19553                         i++;
19554                 }
19555                 cgdebug_printf(state, "\n%s edges: %d", 
19556                         tops(range->defs->def->op), i);
19557                 cgdebug_loc(state, range->defs->def);
19558                 cgdebug_printf(state, "\n");
19559                 for(i = 0; i < MAX_REGISTERS; i++) {
19560                         if (used[i]) {
19561                                 cgdebug_printf(state, "used: %s\n",
19562                                         arch_reg_str(i));
19563                         }
19564                 }
19565         }       
19566
19567         /* If a color is already assigned see if it will work */
19568         if (range->color != REG_UNSET) {
19569                 struct live_range_def *lrd;
19570                 if (!used[range->color]) {
19571                         return 1;
19572                 }
19573                 for(edge = range->edges; edge; edge = edge->next) {
19574                         if (edge->node->color != range->color) {
19575                                 continue;
19576                         }
19577                         warning(state, edge->node->defs->def, "edge: ");
19578                         lrd = edge->node->defs;
19579                         do {
19580                                 warning(state, lrd->def, " %p %s",
19581                                         lrd->def, tops(lrd->def->op));
19582                                 lrd = lrd->next;
19583                         } while(lrd != edge->node->defs);
19584                 }
19585                 lrd = range->defs;
19586                 warning(state, range->defs->def, "def: ");
19587                 do {
19588                         warning(state, lrd->def, " %p %s",
19589                                 lrd->def, tops(lrd->def->op));
19590                         lrd = lrd->next;
19591                 } while(lrd != range->defs);
19592                 internal_error(state, range->defs->def,
19593                         "live range with already used color %s",
19594                         arch_reg_str(range->color));
19595         }
19596
19597         /* If I feed into an expression reuse it's color.
19598          * This should help remove copies in the case of 2 register instructions
19599          * and phi functions.
19600          */
19601         phi = 0;
19602         lrd = live_range_end(state, range, 0);
19603         for(; (range->color == REG_UNSET) && lrd ; lrd = live_range_end(state, range, lrd)) {
19604                 entry = lrd->def->use;
19605                 for(;(range->color == REG_UNSET) && entry; entry = entry->next) {
19606                         struct live_range_def *insd;
19607                         unsigned regcm;
19608                         insd = &rstate->lrd[entry->member->id];
19609                         if (insd->lr->defs == 0) {
19610                                 continue;
19611                         }
19612                         if (!phi && (insd->def->op == OP_PHI) &&
19613                                 !interfere(rstate, range, insd->lr)) {
19614                                 phi = insd;
19615                         }
19616                         if (insd->lr->color == REG_UNSET) {
19617                                 continue;
19618                         }
19619                         regcm = insd->lr->classes;
19620                         if (((regcm & range->classes) == 0) ||
19621                                 (used[insd->lr->color])) {
19622                                 continue;
19623                         }
19624                         if (interfere(rstate, range, insd->lr)) {
19625                                 continue;
19626                         }
19627                         range->color = insd->lr->color;
19628                 }
19629         }
19630         /* If I feed into a phi function reuse it's color or the color
19631          * of something else that feeds into the phi function.
19632          */
19633         if (phi) {
19634                 if (phi->lr->color != REG_UNSET) {
19635                         if (used[phi->lr->color]) {
19636                                 range->color = phi->lr->color;
19637                         }
19638                 }
19639                 else {
19640                         expr = triple_rhs(state, phi->def, 0);
19641                         for(; expr; expr = triple_rhs(state, phi->def, expr)) {
19642                                 struct live_range *lr;
19643                                 unsigned regcm;
19644                                 if (!*expr) {
19645                                         continue;
19646                                 }
19647                                 lr = rstate->lrd[(*expr)->id].lr;
19648                                 if (lr->color == REG_UNSET) {
19649                                         continue;
19650                                 }
19651                                 regcm = lr->classes;
19652                                 if (((regcm & range->classes) == 0) ||
19653                                         (used[lr->color])) {
19654                                         continue;
19655                                 }
19656                                 if (interfere(rstate, range, lr)) {
19657                                         continue;
19658                                 }
19659                                 range->color = lr->color;
19660                         }
19661                 }
19662         }
19663         /* If I don't interfere with a rhs node reuse it's color */
19664         lrd = live_range_head(state, range, 0);
19665         for(; (range->color == REG_UNSET) && lrd ; lrd = live_range_head(state, range, lrd)) {
19666                 expr = triple_rhs(state, lrd->def, 0);
19667                 for(; expr; expr = triple_rhs(state, lrd->def, expr)) {
19668                         struct live_range *lr;
19669                         unsigned regcm;
19670                         if (!*expr) {
19671                                 continue;
19672                         }
19673                         lr = rstate->lrd[(*expr)->id].lr;
19674                         if (lr->color == REG_UNSET) {
19675                                 continue;
19676                         }
19677                         regcm = lr->classes;
19678                         if (((regcm & range->classes) == 0) ||
19679                                 (used[lr->color])) {
19680                                 continue;
19681                         }
19682                         if (interfere(rstate, range, lr)) {
19683                                 continue;
19684                         }
19685                         range->color = lr->color;
19686                         break;
19687                 }
19688         }
19689         /* If I have not opportunitically picked a useful color
19690          * pick the first color that is free.
19691          */
19692         if (range->color == REG_UNSET) {
19693                 range->color = 
19694                         arch_select_free_register(state, used, range->classes);
19695         }
19696         if (range->color == REG_UNSET) {
19697                 struct live_range_def *lrd;
19698                 int i;
19699                 if (split_ranges(state, rstate, used, range)) {
19700                         return 0;
19701                 }
19702                 for(edge = range->edges; edge; edge = edge->next) {
19703                         warning(state, edge->node->defs->def, "edge reg %s",
19704                                 arch_reg_str(edge->node->color));
19705                         lrd = edge->node->defs;
19706                         do {
19707                                 warning(state, lrd->def, " %s %p",
19708                                         tops(lrd->def->op), lrd->def);
19709                                 lrd = lrd->next;
19710                         } while(lrd != edge->node->defs);
19711                 }
19712                 warning(state, range->defs->def, "range: ");
19713                 lrd = range->defs;
19714                 do {
19715                         warning(state, lrd->def, " %s %p",
19716                                 tops(lrd->def->op), lrd->def);
19717                         lrd = lrd->next;
19718                 } while(lrd != range->defs);
19719                         
19720                 warning(state, range->defs->def, "classes: %x",
19721                         range->classes);
19722                 for(i = 0; i < MAX_REGISTERS; i++) {
19723                         if (used[i]) {
19724                                 warning(state, range->defs->def, "used: %s",
19725                                         arch_reg_str(i));
19726                         }
19727                 }
19728                 error(state, range->defs->def, "too few registers");
19729         }
19730         range->classes &= arch_reg_regcm(state, range->color);
19731         if ((range->color == REG_UNSET) || (range->classes == 0)) {
19732                 internal_error(state, range->defs->def, "select_free_color did not?");
19733         }
19734         return 1;
19735 }
19736
19737 static int color_graph(struct compile_state *state, struct reg_state *rstate)
19738 {
19739         int colored;
19740         struct live_range_edge *edge;
19741         struct live_range *range;
19742         if (rstate->low) {
19743                 cgdebug_printf(state, "Lo: ");
19744                 range = rstate->low;
19745                 if (*range->group_prev != range) {
19746                         internal_error(state, 0, "lo: *prev != range?");
19747                 }
19748                 *range->group_prev = range->group_next;
19749                 if (range->group_next) {
19750                         range->group_next->group_prev = range->group_prev;
19751                 }
19752                 if (&range->group_next == rstate->low_tail) {
19753                         rstate->low_tail = range->group_prev;
19754                 }
19755                 if (rstate->low == range) {
19756                         internal_error(state, 0, "low: next != prev?");
19757                 }
19758         }
19759         else if (rstate->high) {
19760                 cgdebug_printf(state, "Hi: ");
19761                 range = rstate->high;
19762                 if (*range->group_prev != range) {
19763                         internal_error(state, 0, "hi: *prev != range?");
19764                 }
19765                 *range->group_prev = range->group_next;
19766                 if (range->group_next) {
19767                         range->group_next->group_prev = range->group_prev;
19768                 }
19769                 if (&range->group_next == rstate->high_tail) {
19770                         rstate->high_tail = range->group_prev;
19771                 }
19772                 if (rstate->high == range) {
19773                         internal_error(state, 0, "high: next != prev?");
19774                 }
19775         }
19776         else {
19777                 return 1;
19778         }
19779         cgdebug_printf(state, " %d\n", range - rstate->lr);
19780         range->group_prev = 0;
19781         for(edge = range->edges; edge; edge = edge->next) {
19782                 struct live_range *node;
19783                 node = edge->node;
19784                 /* Move nodes from the high to the low list */
19785                 if (node->group_prev && (node->color == REG_UNSET) &&
19786                         (node->degree == regc_max_size(state, node->classes))) {
19787                         if (*node->group_prev != node) {
19788                                 internal_error(state, 0, "move: *prev != node?");
19789                         }
19790                         *node->group_prev = node->group_next;
19791                         if (node->group_next) {
19792                                 node->group_next->group_prev = node->group_prev;
19793                         }
19794                         if (&node->group_next == rstate->high_tail) {
19795                                 rstate->high_tail = node->group_prev;
19796                         }
19797                         cgdebug_printf(state, "Moving...%d to low\n", node - rstate->lr);
19798                         node->group_prev  = rstate->low_tail;
19799                         node->group_next  = 0;
19800                         *rstate->low_tail = node;
19801                         rstate->low_tail  = &node->group_next;
19802                         if (*node->group_prev != node) {
19803                                 internal_error(state, 0, "move2: *prev != node?");
19804                         }
19805                 }
19806                 node->degree -= 1;
19807         }
19808         colored = color_graph(state, rstate);
19809         if (colored) {
19810                 cgdebug_printf(state, "Coloring %d @", range - rstate->lr);
19811                 cgdebug_loc(state, range->defs->def);
19812                 cgdebug_flush(state);
19813                 colored = select_free_color(state, rstate, range);
19814                 if (colored) {
19815                         cgdebug_printf(state, " %s\n", arch_reg_str(range->color));
19816                 }
19817         }
19818         return colored;
19819 }
19820
19821 static void verify_colors(struct compile_state *state, struct reg_state *rstate)
19822 {
19823         struct live_range *lr;
19824         struct live_range_edge *edge;
19825         struct triple *ins, *first;
19826         char used[MAX_REGISTERS];
19827         first = state->first;
19828         ins = first;
19829         do {
19830                 if (triple_is_def(state, ins)) {
19831                         if ((ins->id < 0) || (ins->id > rstate->defs)) {
19832                                 internal_error(state, ins, 
19833                                         "triple without a live range def");
19834                         }
19835                         lr = rstate->lrd[ins->id].lr;
19836                         if (lr->color == REG_UNSET) {
19837                                 internal_error(state, ins,
19838                                         "triple without a color");
19839                         }
19840                         /* Find the registers used by the edges */
19841                         memset(used, 0, sizeof(used));
19842                         for(edge = lr->edges; edge; edge = edge->next) {
19843                                 if (edge->node->color == REG_UNSET) {
19844                                         internal_error(state, 0,
19845                                                 "live range without a color");
19846                         }
19847                                 reg_fill_used(state, used, edge->node->color);
19848                         }
19849                         if (used[lr->color]) {
19850                                 internal_error(state, ins,
19851                                         "triple with already used color");
19852                         }
19853                 }
19854                 ins = ins->next;
19855         } while(ins != first);
19856 }
19857
19858 static void color_triples(struct compile_state *state, struct reg_state *rstate)
19859 {
19860         struct live_range_def *lrd;
19861         struct live_range *lr;
19862         struct triple *first, *ins;
19863         first = state->first;
19864         ins = first;
19865         do {
19866                 if ((ins->id < 0) || (ins->id > rstate->defs)) {
19867                         internal_error(state, ins, 
19868                                 "triple without a live range");
19869                 }
19870                 lrd = &rstate->lrd[ins->id];
19871                 lr = lrd->lr;
19872                 ins->id = lrd->orig_id;
19873                 SET_REG(ins->id, lr->color);
19874                 ins = ins->next;
19875         } while (ins != first);
19876 }
19877
19878 static struct live_range *merge_sort_lr(
19879         struct live_range *first, struct live_range *last)
19880 {
19881         struct live_range *mid, *join, **join_tail, *pick;
19882         size_t size;
19883         size = (last - first) + 1;
19884         if (size >= 2) {
19885                 mid = first + size/2;
19886                 first = merge_sort_lr(first, mid -1);
19887                 mid   = merge_sort_lr(mid, last);
19888                 
19889                 join = 0;
19890                 join_tail = &join;
19891                 /* merge the two lists */
19892                 while(first && mid) {
19893                         if ((first->degree < mid->degree) ||
19894                                 ((first->degree == mid->degree) &&
19895                                         (first->length < mid->length))) {
19896                                 pick = first;
19897                                 first = first->group_next;
19898                                 if (first) {
19899                                         first->group_prev = 0;
19900                                 }
19901                         }
19902                         else {
19903                                 pick = mid;
19904                                 mid = mid->group_next;
19905                                 if (mid) {
19906                                         mid->group_prev = 0;
19907                                 }
19908                         }
19909                         pick->group_next = 0;
19910                         pick->group_prev = join_tail;
19911                         *join_tail = pick;
19912                         join_tail = &pick->group_next;
19913                 }
19914                 /* Splice the remaining list */
19915                 pick = (first)? first : mid;
19916                 *join_tail = pick;
19917                 if (pick) { 
19918                         pick->group_prev = join_tail;
19919                 }
19920         }
19921         else {
19922                 if (!first->defs) {
19923                         first = 0;
19924                 }
19925                 join = first;
19926         }
19927         return join;
19928 }
19929
19930 static void ids_from_rstate(struct compile_state *state, 
19931         struct reg_state *rstate)
19932 {
19933         struct triple *ins, *first;
19934         if (!rstate->defs) {
19935                 return;
19936         }
19937         /* Display the graph if desired */
19938         if (state->compiler->debug & DEBUG_INTERFERENCE) {
19939                 FILE *fp = state->dbgout;
19940                 print_interference_blocks(state, rstate, fp, 0);
19941                 print_control_flow(state, fp, &state->bb);
19942                 fflush(fp);
19943         }
19944         first = state->first;
19945         ins = first;
19946         do {
19947                 if (ins->id) {
19948                         struct live_range_def *lrd;
19949                         lrd = &rstate->lrd[ins->id];
19950                         ins->id = lrd->orig_id;
19951                 }
19952                 ins = ins->next;
19953         } while(ins != first);
19954 }
19955
19956 static void cleanup_live_edges(struct reg_state *rstate)
19957 {
19958         int i;
19959         /* Free the edges on each node */
19960         for(i = 1; i <= rstate->ranges; i++) {
19961                 remove_live_edges(rstate, &rstate->lr[i]);
19962         }
19963 }
19964
19965 static void cleanup_rstate(struct compile_state *state, struct reg_state *rstate)
19966 {
19967         cleanup_live_edges(rstate);
19968         xfree(rstate->lrd);
19969         xfree(rstate->lr);
19970
19971         /* Free the variable lifetime information */
19972         if (rstate->blocks) {
19973                 free_variable_lifetimes(state, &state->bb, rstate->blocks);
19974         }
19975         rstate->defs = 0;
19976         rstate->ranges = 0;
19977         rstate->lrd = 0;
19978         rstate->lr = 0;
19979         rstate->blocks = 0;
19980 }
19981
19982 static void verify_consistency(struct compile_state *state);
19983 static void allocate_registers(struct compile_state *state)
19984 {
19985         struct reg_state rstate;
19986         int colored;
19987
19988         /* Clear out the reg_state */
19989         memset(&rstate, 0, sizeof(rstate));
19990         rstate.max_passes = state->compiler->max_allocation_passes;
19991
19992         do {
19993                 struct live_range **point, **next;
19994                 int conflicts;
19995                 int tangles;
19996                 int coalesced;
19997
19998                 if (state->compiler->debug & DEBUG_RANGE_CONFLICTS) {
19999                         FILE *fp = state->errout;
20000                         fprintf(fp, "pass: %d\n", rstate.passes);
20001                         fflush(fp);
20002                 }
20003
20004                 /* Restore ids */
20005                 ids_from_rstate(state, &rstate);
20006
20007                 /* Cleanup the temporary data structures */
20008                 cleanup_rstate(state, &rstate);
20009
20010                 /* Compute the variable lifetimes */
20011                 rstate.blocks = compute_variable_lifetimes(state, &state->bb);
20012
20013                 /* Fix invalid mandatory live range coalesce conflicts */
20014                 conflicts = correct_coalesce_conflicts(state, rstate.blocks);
20015
20016                 /* Fix two simultaneous uses of the same register.
20017                  * In a few pathlogical cases a partial untangle moves
20018                  * the tangle to a part of the graph we won't revisit.
20019                  * So we keep looping until we have no more tangle fixes
20020                  * to apply.
20021                  */
20022                 do {
20023                         tangles = correct_tangles(state, rstate.blocks);
20024                 } while(tangles);
20025
20026                 
20027                 print_blocks(state, "resolve_tangles", state->dbgout);
20028                 verify_consistency(state);
20029                 
20030                 /* Allocate and initialize the live ranges */
20031                 initialize_live_ranges(state, &rstate);
20032
20033                 /* Note currently doing coalescing in a loop appears to 
20034                  * buys me nothing.  The code is left this way in case
20035                  * there is some value in it.  Or if a future bugfix
20036                  * yields some benefit.
20037                  */
20038                 do {
20039                         if (state->compiler->debug & DEBUG_COALESCING) {
20040                                 fprintf(state->errout, "coalescing\n");
20041                         }
20042
20043                         /* Remove any previous live edge calculations */
20044                         cleanup_live_edges(&rstate);
20045
20046                         /* Compute the interference graph */
20047                         walk_variable_lifetimes(
20048                                 state, &state->bb, rstate.blocks, 
20049                                 graph_ins, &rstate);
20050                         
20051                         /* Display the interference graph if desired */
20052                         if (state->compiler->debug & DEBUG_INTERFERENCE) {
20053                                 print_interference_blocks(state, &rstate, state->dbgout, 1);
20054                                 fprintf(state->dbgout, "\nlive variables by instruction\n");
20055                                 walk_variable_lifetimes(
20056                                         state, &state->bb, rstate.blocks, 
20057                                         print_interference_ins, &rstate);
20058                         }
20059                         
20060                         coalesced = coalesce_live_ranges(state, &rstate);
20061
20062                         if (state->compiler->debug & DEBUG_COALESCING) {
20063                                 fprintf(state->errout, "coalesced: %d\n", coalesced);
20064                         }
20065                 } while(coalesced);
20066
20067 #if DEBUG_CONSISTENCY > 1
20068 # if 0
20069                 fprintf(state->errout, "verify_graph_ins...\n");
20070 # endif
20071                 /* Verify the interference graph */
20072                 walk_variable_lifetimes(
20073                         state, &state->bb, rstate.blocks, 
20074                         verify_graph_ins, &rstate);
20075 # if 0
20076                 fprintf(state->errout, "verify_graph_ins done\n");
20077 #endif
20078 #endif
20079                         
20080                 /* Build the groups low and high.  But with the nodes
20081                  * first sorted by degree order.
20082                  */
20083                 rstate.low_tail  = &rstate.low;
20084                 rstate.high_tail = &rstate.high;
20085                 rstate.high = merge_sort_lr(&rstate.lr[1], &rstate.lr[rstate.ranges]);
20086                 if (rstate.high) {
20087                         rstate.high->group_prev = &rstate.high;
20088                 }
20089                 for(point = &rstate.high; *point; point = &(*point)->group_next)
20090                         ;
20091                 rstate.high_tail = point;
20092                 /* Walk through the high list and move everything that needs
20093                  * to be onto low.
20094                  */
20095                 for(point = &rstate.high; *point; point = next) {
20096                         struct live_range *range;
20097                         next = &(*point)->group_next;
20098                         range = *point;
20099                         
20100                         /* If it has a low degree or it already has a color
20101                          * place the node in low.
20102                          */
20103                         if ((range->degree < regc_max_size(state, range->classes)) ||
20104                                 (range->color != REG_UNSET)) {
20105                                 cgdebug_printf(state, "Lo: %5d degree %5d%s\n", 
20106                                         range - rstate.lr, range->degree,
20107                                         (range->color != REG_UNSET) ? " (colored)": "");
20108                                 *range->group_prev = range->group_next;
20109                                 if (range->group_next) {
20110                                         range->group_next->group_prev = range->group_prev;
20111                                 }
20112                                 if (&range->group_next == rstate.high_tail) {
20113                                         rstate.high_tail = range->group_prev;
20114                                 }
20115                                 range->group_prev  = rstate.low_tail;
20116                                 range->group_next  = 0;
20117                                 *rstate.low_tail   = range;
20118                                 rstate.low_tail    = &range->group_next;
20119                                 next = point;
20120                         }
20121                         else {
20122                                 cgdebug_printf(state, "hi: %5d degree %5d%s\n", 
20123                                         range - rstate.lr, range->degree,
20124                                         (range->color != REG_UNSET) ? " (colored)": "");
20125                         }
20126                 }
20127                 /* Color the live_ranges */
20128                 colored = color_graph(state, &rstate);
20129                 rstate.passes++;
20130         } while (!colored);
20131
20132         /* Verify the graph was properly colored */
20133         verify_colors(state, &rstate);
20134
20135         /* Move the colors from the graph to the triples */
20136         color_triples(state, &rstate);
20137
20138         /* Cleanup the temporary data structures */
20139         cleanup_rstate(state, &rstate);
20140
20141         /* Display the new graph */
20142         print_blocks(state, __func__, state->dbgout);
20143 }
20144
20145 /* Sparce Conditional Constant Propogation
20146  * =========================================
20147  */
20148 struct ssa_edge;
20149 struct flow_block;
20150 struct lattice_node {
20151         unsigned old_id;
20152         struct triple *def;
20153         struct ssa_edge *out;
20154         struct flow_block *fblock;
20155         struct triple *val;
20156         /* lattice high   val == def
20157          * lattice const  is_const(val)
20158          * lattice low    other
20159          */
20160 };
20161 struct ssa_edge {
20162         struct lattice_node *src;
20163         struct lattice_node *dst;
20164         struct ssa_edge *work_next;
20165         struct ssa_edge *work_prev;
20166         struct ssa_edge *out_next;
20167 };
20168 struct flow_edge {
20169         struct flow_block *src;
20170         struct flow_block *dst;
20171         struct flow_edge *work_next;
20172         struct flow_edge *work_prev;
20173         struct flow_edge *in_next;
20174         struct flow_edge *out_next;
20175         int executable;
20176 };
20177 #define MAX_FLOW_BLOCK_EDGES 3
20178 struct flow_block {
20179         struct block *block;
20180         struct flow_edge *in;
20181         struct flow_edge *out;
20182         struct flow_edge *edges;
20183 };
20184
20185 struct scc_state {
20186         int ins_count;
20187         struct lattice_node *lattice;
20188         struct ssa_edge     *ssa_edges;
20189         struct flow_block   *flow_blocks;
20190         struct flow_edge    *flow_work_list;
20191         struct ssa_edge     *ssa_work_list;
20192 };
20193
20194
20195 static int is_scc_const(struct compile_state *state, struct triple *ins)
20196 {
20197         return ins && (triple_is_ubranch(state, ins) || is_const(ins));
20198 }
20199
20200 static int is_lattice_hi(struct compile_state *state, struct lattice_node *lnode)
20201 {
20202         return !is_scc_const(state, lnode->val) && (lnode->val == lnode->def);
20203 }
20204
20205 static int is_lattice_const(struct compile_state *state, struct lattice_node *lnode)
20206 {
20207         return is_scc_const(state, lnode->val);
20208 }
20209
20210 static int is_lattice_lo(struct compile_state *state, struct lattice_node *lnode)
20211 {
20212         return (lnode->val != lnode->def) && !is_scc_const(state, lnode->val);
20213 }
20214
20215 static void scc_add_fedge(struct compile_state *state, struct scc_state *scc, 
20216         struct flow_edge *fedge)
20217 {
20218         if (state->compiler->debug & DEBUG_SCC_TRANSFORM2) {
20219                 fprintf(state->errout, "adding fedge: %p (%4d -> %5d)\n",
20220                         fedge,
20221                         fedge->src->block?fedge->src->block->last->id: 0,
20222                         fedge->dst->block?fedge->dst->block->first->id: 0);
20223         }
20224         if ((fedge == scc->flow_work_list) ||
20225                 (fedge->work_next != fedge) ||
20226                 (fedge->work_prev != fedge)) {
20227
20228                 if (state->compiler->debug & DEBUG_SCC_TRANSFORM2) {
20229                         fprintf(state->errout, "dupped fedge: %p\n",
20230                                 fedge);
20231                 }
20232                 return;
20233         }
20234         if (!scc->flow_work_list) {
20235                 scc->flow_work_list = fedge;
20236                 fedge->work_next = fedge->work_prev = fedge;
20237         }
20238         else {
20239                 struct flow_edge *ftail;
20240                 ftail = scc->flow_work_list->work_prev;
20241                 fedge->work_next = ftail->work_next;
20242                 fedge->work_prev = ftail;
20243                 fedge->work_next->work_prev = fedge;
20244                 fedge->work_prev->work_next = fedge;
20245         }
20246 }
20247
20248 static struct flow_edge *scc_next_fedge(
20249         struct compile_state *state, struct scc_state *scc)
20250 {
20251         struct flow_edge *fedge;
20252         fedge = scc->flow_work_list;
20253         if (fedge) {
20254                 fedge->work_next->work_prev = fedge->work_prev;
20255                 fedge->work_prev->work_next = fedge->work_next;
20256                 if (fedge->work_next != fedge) {
20257                         scc->flow_work_list = fedge->work_next;
20258                 } else {
20259                         scc->flow_work_list = 0;
20260                 }
20261                 fedge->work_next = fedge->work_prev = fedge;
20262         }
20263         return fedge;
20264 }
20265
20266 static void scc_add_sedge(struct compile_state *state, struct scc_state *scc,
20267         struct ssa_edge *sedge)
20268 {
20269         if (state->compiler->debug & DEBUG_SCC_TRANSFORM2) {
20270                 fprintf(state->errout, "adding sedge: %5d (%4d -> %5d)\n",
20271                         sedge - scc->ssa_edges,
20272                         sedge->src->def->id,
20273                         sedge->dst->def->id);
20274         }
20275         if ((sedge == scc->ssa_work_list) ||
20276                 (sedge->work_next != sedge) ||
20277                 (sedge->work_prev != sedge)) {
20278
20279                 if (state->compiler->debug & DEBUG_SCC_TRANSFORM2) {
20280                         fprintf(state->errout, "dupped sedge: %5d\n",
20281                                 sedge - scc->ssa_edges);
20282                 }
20283                 return;
20284         }
20285         if (!scc->ssa_work_list) {
20286                 scc->ssa_work_list = sedge;
20287                 sedge->work_next = sedge->work_prev = sedge;
20288         }
20289         else {
20290                 struct ssa_edge *stail;
20291                 stail = scc->ssa_work_list->work_prev;
20292                 sedge->work_next = stail->work_next;
20293                 sedge->work_prev = stail;
20294                 sedge->work_next->work_prev = sedge;
20295                 sedge->work_prev->work_next = sedge;
20296         }
20297 }
20298
20299 static struct ssa_edge *scc_next_sedge(
20300         struct compile_state *state, struct scc_state *scc)
20301 {
20302         struct ssa_edge *sedge;
20303         sedge = scc->ssa_work_list;
20304         if (sedge) {
20305                 sedge->work_next->work_prev = sedge->work_prev;
20306                 sedge->work_prev->work_next = sedge->work_next;
20307                 if (sedge->work_next != sedge) {
20308                         scc->ssa_work_list = sedge->work_next;
20309                 } else {
20310                         scc->ssa_work_list = 0;
20311                 }
20312                 sedge->work_next = sedge->work_prev = sedge;
20313         }
20314         return sedge;
20315 }
20316
20317 static void initialize_scc_state(
20318         struct compile_state *state, struct scc_state *scc)
20319 {
20320         int ins_count, ssa_edge_count;
20321         int ins_index, ssa_edge_index, fblock_index;
20322         struct triple *first, *ins;
20323         struct block *block;
20324         struct flow_block *fblock;
20325
20326         memset(scc, 0, sizeof(*scc));
20327
20328         /* Inialize pass zero find out how much memory we need */
20329         first = state->first;
20330         ins = first;
20331         ins_count = ssa_edge_count = 0;
20332         do {
20333                 struct triple_set *edge;
20334                 ins_count += 1;
20335                 for(edge = ins->use; edge; edge = edge->next) {
20336                         ssa_edge_count++;
20337                 }
20338                 ins = ins->next;
20339         } while(ins != first);
20340         if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
20341                 fprintf(state->errout, "ins_count: %d ssa_edge_count: %d vertex_count: %d\n",
20342                         ins_count, ssa_edge_count, state->bb.last_vertex);
20343         }
20344         scc->ins_count   = ins_count;
20345         scc->lattice     = 
20346                 xcmalloc(sizeof(*scc->lattice)*(ins_count + 1), "lattice");
20347         scc->ssa_edges   = 
20348                 xcmalloc(sizeof(*scc->ssa_edges)*(ssa_edge_count + 1), "ssa_edges");
20349         scc->flow_blocks = 
20350                 xcmalloc(sizeof(*scc->flow_blocks)*(state->bb.last_vertex + 1), 
20351                         "flow_blocks");
20352
20353         /* Initialize pass one collect up the nodes */
20354         fblock = 0;
20355         block = 0;
20356         ins_index = ssa_edge_index = fblock_index = 0;
20357         ins = first;
20358         do {
20359                 if ((ins->op == OP_LABEL) && (block != ins->u.block)) {
20360                         block = ins->u.block;
20361                         if (!block) {
20362                                 internal_error(state, ins, "label without block");
20363                         }
20364                         fblock_index += 1;
20365                         block->vertex = fblock_index;
20366                         fblock = &scc->flow_blocks[fblock_index];
20367                         fblock->block = block;
20368                         fblock->edges = xcmalloc(sizeof(*fblock->edges)*block->edge_count,
20369                                 "flow_edges");
20370                 }
20371                 {
20372                         struct lattice_node *lnode;
20373                         ins_index += 1;
20374                         lnode = &scc->lattice[ins_index];
20375                         lnode->def = ins;
20376                         lnode->out = 0;
20377                         lnode->fblock = fblock;
20378                         lnode->val = ins; /* LATTICE HIGH */
20379                         if (lnode->val->op == OP_UNKNOWNVAL) {
20380                                 lnode->val = 0; /* LATTICE LOW by definition */
20381                         }
20382                         lnode->old_id = ins->id;
20383                         ins->id = ins_index;
20384                 }
20385                 ins = ins->next;
20386         } while(ins != first);
20387         /* Initialize pass two collect up the edges */
20388         block = 0;
20389         fblock = 0;
20390         ins = first;
20391         do {
20392                 {
20393                         struct triple_set *edge;
20394                         struct ssa_edge **stail;
20395                         struct lattice_node *lnode;
20396                         lnode = &scc->lattice[ins->id];
20397                         lnode->out = 0;
20398                         stail = &lnode->out;
20399                         for(edge = ins->use; edge; edge = edge->next) {
20400                                 struct ssa_edge *sedge;
20401                                 ssa_edge_index += 1;
20402                                 sedge = &scc->ssa_edges[ssa_edge_index];
20403                                 *stail = sedge;
20404                                 stail = &sedge->out_next;
20405                                 sedge->src = lnode;
20406                                 sedge->dst = &scc->lattice[edge->member->id];
20407                                 sedge->work_next = sedge->work_prev = sedge;
20408                                 sedge->out_next = 0;
20409                         }
20410                 }
20411                 if ((ins->op == OP_LABEL) && (block != ins->u.block)) {
20412                         struct flow_edge *fedge, **ftail;
20413                         struct block_set *bedge;
20414                         block = ins->u.block;
20415                         fblock = &scc->flow_blocks[block->vertex];
20416                         fblock->in = 0;
20417                         fblock->out = 0;
20418                         ftail = &fblock->out;
20419
20420                         fedge = fblock->edges;
20421                         bedge = block->edges;
20422                         for(; bedge; bedge = bedge->next, fedge++) {
20423                                 fedge->dst = &scc->flow_blocks[bedge->member->vertex];
20424                                 if (fedge->dst->block != bedge->member) {
20425                                         internal_error(state, 0, "block mismatch");
20426                                 }
20427                                 *ftail = fedge;
20428                                 ftail = &fedge->out_next;
20429                                 fedge->out_next = 0;
20430                         }
20431                         for(fedge = fblock->out; fedge; fedge = fedge->out_next) {
20432                                 fedge->src = fblock;
20433                                 fedge->work_next = fedge->work_prev = fedge;
20434                                 fedge->executable = 0;
20435                         }
20436                 }
20437                 ins = ins->next;
20438         } while (ins != first);
20439         block = 0;
20440         fblock = 0;
20441         ins = first;
20442         do {
20443                 if ((ins->op  == OP_LABEL) && (block != ins->u.block)) {
20444                         struct flow_edge **ftail;
20445                         struct block_set *bedge;
20446                         block = ins->u.block;
20447                         fblock = &scc->flow_blocks[block->vertex];
20448                         ftail = &fblock->in;
20449                         for(bedge = block->use; bedge; bedge = bedge->next) {
20450                                 struct block *src_block;
20451                                 struct flow_block *sfblock;
20452                                 struct flow_edge *sfedge;
20453                                 src_block = bedge->member;
20454                                 sfblock = &scc->flow_blocks[src_block->vertex];
20455                                 for(sfedge = sfblock->out; sfedge; sfedge = sfedge->out_next) {
20456                                         if (sfedge->dst == fblock) {
20457                                                 break;
20458                                         }
20459                                 }
20460                                 if (!sfedge) {
20461                                         internal_error(state, 0, "edge mismatch");
20462                                 }
20463                                 *ftail = sfedge;
20464                                 ftail = &sfedge->in_next;
20465                                 sfedge->in_next = 0;
20466                         }
20467                 }
20468                 ins = ins->next;
20469         } while(ins != first);
20470         /* Setup a dummy block 0 as a node above the start node */
20471         {
20472                 struct flow_block *fblock, *dst;
20473                 struct flow_edge *fedge;
20474                 fblock = &scc->flow_blocks[0];
20475                 fblock->block = 0;
20476                 fblock->edges = xcmalloc(sizeof(*fblock->edges)*1, "flow_edges");
20477                 fblock->in = 0;
20478                 fblock->out = fblock->edges;
20479                 dst = &scc->flow_blocks[state->bb.first_block->vertex];
20480                 fedge = fblock->edges;
20481                 fedge->src        = fblock;
20482                 fedge->dst        = dst;
20483                 fedge->work_next  = fedge;
20484                 fedge->work_prev  = fedge;
20485                 fedge->in_next    = fedge->dst->in;
20486                 fedge->out_next   = 0;
20487                 fedge->executable = 0;
20488                 fedge->dst->in = fedge;
20489                 
20490                 /* Initialize the work lists */
20491                 scc->flow_work_list = 0;
20492                 scc->ssa_work_list  = 0;
20493                 scc_add_fedge(state, scc, fedge);
20494         }
20495         if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
20496                 fprintf(state->errout, "ins_index: %d ssa_edge_index: %d fblock_index: %d\n",
20497                         ins_index, ssa_edge_index, fblock_index);
20498         }
20499 }
20500
20501         
20502 static void free_scc_state(
20503         struct compile_state *state, struct scc_state *scc)
20504 {
20505         int i;
20506         for(i = 0; i < state->bb.last_vertex + 1; i++) {
20507                 struct flow_block *fblock;
20508                 fblock = &scc->flow_blocks[i];
20509                 if (fblock->edges) {
20510                         xfree(fblock->edges);
20511                         fblock->edges = 0;
20512                 }
20513         }
20514         xfree(scc->flow_blocks);
20515         xfree(scc->ssa_edges);
20516         xfree(scc->lattice);
20517         
20518 }
20519
20520 static struct lattice_node *triple_to_lattice(
20521         struct compile_state *state, struct scc_state *scc, struct triple *ins)
20522 {
20523         if (ins->id <= 0) {
20524                 internal_error(state, ins, "bad id");
20525         }
20526         return &scc->lattice[ins->id];
20527 }
20528
20529 static struct triple *preserve_lval(
20530         struct compile_state *state, struct lattice_node *lnode)
20531 {
20532         struct triple *old;
20533         /* Preserve the original value */
20534         if (lnode->val) {
20535                 old = dup_triple(state, lnode->val);
20536                 if (lnode->val != lnode->def) {
20537                         xfree(lnode->val);
20538                 }
20539                 lnode->val = 0;
20540         } else {
20541                 old = 0;
20542         }
20543         return old;
20544 }
20545
20546 static int lval_changed(struct compile_state *state, 
20547         struct triple *old, struct lattice_node *lnode)
20548 {
20549         int changed;
20550         /* See if the lattice value has changed */
20551         changed = 1;
20552         if (!old && !lnode->val) {
20553                 changed = 0;
20554         }
20555         if (changed &&
20556                 lnode->val && old &&
20557                 (memcmp(lnode->val->param, old->param,
20558                         TRIPLE_SIZE(lnode->val) * sizeof(lnode->val->param[0])) == 0) &&
20559                 (memcmp(&lnode->val->u, &old->u, sizeof(old->u)) == 0)) {
20560                 changed = 0;
20561         }
20562         if (old) {
20563                 xfree(old);
20564         }
20565         return changed;
20566
20567 }
20568
20569 static void scc_debug_lnode(
20570         struct compile_state *state, struct scc_state *scc,
20571         struct lattice_node *lnode, int changed)
20572 {
20573         if ((state->compiler->debug & DEBUG_SCC_TRANSFORM2) && lnode->val) {
20574                 display_triple_changes(state->errout, lnode->val, lnode->def);
20575         }
20576         if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
20577                 FILE *fp = state->errout;
20578                 struct triple *val, **expr;
20579                 val = lnode->val? lnode->val : lnode->def;
20580                 fprintf(fp, "%p %s %3d %10s (",
20581                         lnode->def, 
20582                         ((lnode->def->op == OP_PHI)? "phi: ": "expr:"),
20583                         lnode->def->id,
20584                         tops(lnode->def->op));
20585                 expr = triple_rhs(state, lnode->def, 0);
20586                 for(;expr;expr = triple_rhs(state, lnode->def, expr)) {
20587                         if (*expr) {
20588                                 fprintf(fp, " %d", (*expr)->id);
20589                         }
20590                 }
20591                 if (val->op == OP_INTCONST) {
20592                         fprintf(fp, " <0x%08lx>", (unsigned long)(val->u.cval));
20593                 }
20594                 fprintf(fp, " ) -> %s %s\n",
20595                         (is_lattice_hi(state, lnode)? "hi":
20596                                 is_lattice_const(state, lnode)? "const" : "lo"),
20597                         changed? "changed" : ""
20598                         );
20599         }
20600 }
20601
20602 static int compute_lnode_val(struct compile_state *state, struct scc_state *scc,
20603         struct lattice_node *lnode)
20604 {
20605         int changed;
20606         struct triple *old, *scratch;
20607         struct triple **dexpr, **vexpr;
20608         int count, i;
20609         
20610         /* Store the original value */
20611         old = preserve_lval(state, lnode);
20612
20613         /* Reinitialize the value */
20614         lnode->val = scratch = dup_triple(state, lnode->def);
20615         scratch->id = lnode->old_id;
20616         scratch->next     = scratch;
20617         scratch->prev     = scratch;
20618         scratch->use      = 0;
20619
20620         count = TRIPLE_SIZE(scratch);
20621         for(i = 0; i < count; i++) {
20622                 dexpr = &lnode->def->param[i];
20623                 vexpr = &scratch->param[i];
20624                 *vexpr = *dexpr;
20625                 if (((i < TRIPLE_MISC_OFF(scratch)) ||
20626                         (i >= TRIPLE_TARG_OFF(scratch))) &&
20627                         *dexpr) {
20628                         struct lattice_node *tmp;
20629                         tmp = triple_to_lattice(state, scc, *dexpr);
20630                         *vexpr = (tmp->val)? tmp->val : tmp->def;
20631                 }
20632         }
20633         if (triple_is_branch(state, scratch)) {
20634                 scratch->next = lnode->def->next;
20635         }
20636         /* Recompute the value */
20637 #warning "FIXME see if simplify does anything bad"
20638         /* So far it looks like only the strength reduction
20639          * optimization are things I need to worry about.
20640          */
20641         simplify(state, scratch);
20642         /* Cleanup my value */
20643         if (scratch->use) {
20644                 internal_error(state, lnode->def, "scratch used?");
20645         }
20646         if ((scratch->prev != scratch) ||
20647                 ((scratch->next != scratch) &&
20648                         (!triple_is_branch(state, lnode->def) ||
20649                                 (scratch->next != lnode->def->next)))) {
20650                 internal_error(state, lnode->def, "scratch in list?");
20651         }
20652         /* undo any uses... */
20653         count = TRIPLE_SIZE(scratch);
20654         for(i = 0; i < count; i++) {
20655                 vexpr = &scratch->param[i];
20656                 if (*vexpr) {
20657                         unuse_triple(*vexpr, scratch);
20658                 }
20659         }
20660         if (lnode->val->op == OP_UNKNOWNVAL) {
20661                 lnode->val = 0; /* Lattice low by definition */
20662         }
20663         /* Find the case when I am lattice high */
20664         if (lnode->val && 
20665                 (lnode->val->op == lnode->def->op) &&
20666                 (memcmp(lnode->val->param, lnode->def->param, 
20667                         count * sizeof(lnode->val->param[0])) == 0) &&
20668                 (memcmp(&lnode->val->u, &lnode->def->u, sizeof(lnode->def->u)) == 0)) {
20669                 lnode->val = lnode->def;
20670         }
20671         /* Only allow lattice high when all of my inputs
20672          * are also lattice high.  Occassionally I can
20673          * have constants with a lattice low input, so
20674          * I do not need to check that case.
20675          */
20676         if (is_lattice_hi(state, lnode)) {
20677                 struct lattice_node *tmp;
20678                 int rhs;
20679                 rhs = lnode->val->rhs;
20680                 for(i = 0; i < rhs; i++) {
20681                         tmp = triple_to_lattice(state, scc, RHS(lnode->val, i));
20682                         if (!is_lattice_hi(state, tmp)) {
20683                                 lnode->val = 0;
20684                                 break;
20685                         }
20686                 }
20687         }
20688         /* Find the cases that are always lattice lo */
20689         if (lnode->val && 
20690                 triple_is_def(state, lnode->val) &&
20691                 !triple_is_pure(state, lnode->val, lnode->old_id)) {
20692                 lnode->val = 0;
20693         }
20694         /* See if the lattice value has changed */
20695         changed = lval_changed(state, old, lnode);
20696         /* See if this value should not change */
20697         if ((lnode->val != lnode->def) && 
20698                 ((      !triple_is_def(state, lnode->def)  &&
20699                         !triple_is_cbranch(state, lnode->def)) ||
20700                         (lnode->def->op == OP_PIECE))) {
20701 #warning "FIXME constant propogate through expressions with multiple left hand sides"
20702                 if (changed) {
20703                         internal_warning(state, lnode->def, "non def changes value?");
20704                 }
20705                 lnode->val = 0;
20706         }
20707
20708         /* See if we need to free the scratch value */
20709         if (lnode->val != scratch) {
20710                 xfree(scratch);
20711         }
20712         
20713         return changed;
20714 }
20715
20716
20717 static void scc_visit_cbranch(struct compile_state *state, struct scc_state *scc,
20718         struct lattice_node *lnode)
20719 {
20720         struct lattice_node *cond;
20721         struct flow_edge *left, *right;
20722         int changed;
20723
20724         /* Update the branch value */
20725         changed = compute_lnode_val(state, scc, lnode);
20726         scc_debug_lnode(state, scc, lnode, changed);
20727
20728         /* This only applies to conditional branches */
20729         if (!triple_is_cbranch(state, lnode->def)) {
20730                 internal_error(state, lnode->def, "not a conditional branch");
20731         }
20732
20733         if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
20734                 struct flow_edge *fedge;
20735                 FILE *fp = state->errout;
20736                 fprintf(fp, "%s: %d (",
20737                         tops(lnode->def->op),
20738                         lnode->def->id);
20739                 
20740                 for(fedge = lnode->fblock->out; fedge; fedge = fedge->out_next) {
20741                         fprintf(fp, " %d", fedge->dst->block->vertex);
20742                 }
20743                 fprintf(fp, " )");
20744                 if (lnode->def->rhs > 0) {
20745                         fprintf(fp, " <- %d",
20746                                 RHS(lnode->def, 0)->id);
20747                 }
20748                 fprintf(fp, "\n");
20749         }
20750         cond = triple_to_lattice(state, scc, RHS(lnode->def,0));
20751         for(left = cond->fblock->out; left; left = left->out_next) {
20752                 if (left->dst->block->first == lnode->def->next) {
20753                         break;
20754                 }
20755         }
20756         if (!left) {
20757                 internal_error(state, lnode->def, "Cannot find left branch edge");
20758         }
20759         for(right = cond->fblock->out; right; right = right->out_next) {
20760                 if (right->dst->block->first == TARG(lnode->def, 0)) {
20761                         break;
20762                 }
20763         }
20764         if (!right) {
20765                 internal_error(state, lnode->def, "Cannot find right branch edge");
20766         }
20767         /* I should only come here if the controlling expressions value
20768          * has changed, which means it must be either a constant or lo.
20769          */
20770         if (is_lattice_hi(state, cond)) {
20771                 internal_error(state, cond->def, "condition high?");
20772                 return;
20773         }
20774         if (is_lattice_lo(state, cond)) {
20775                 scc_add_fedge(state, scc, left);
20776                 scc_add_fedge(state, scc, right);
20777         }
20778         else if (cond->val->u.cval) {
20779                 scc_add_fedge(state, scc, right);
20780         } else {
20781                 scc_add_fedge(state, scc, left);
20782         }
20783
20784 }
20785
20786
20787 static void scc_add_sedge_dst(struct compile_state *state, 
20788         struct scc_state *scc, struct ssa_edge *sedge)
20789 {
20790         if (triple_is_cbranch(state, sedge->dst->def)) {
20791                 scc_visit_cbranch(state, scc, sedge->dst);
20792         }
20793         else if (triple_is_def(state, sedge->dst->def)) {
20794                 scc_add_sedge(state, scc, sedge);
20795         }
20796 }
20797
20798 static void scc_visit_phi(struct compile_state *state, struct scc_state *scc, 
20799         struct lattice_node *lnode)
20800 {
20801         struct lattice_node *tmp;
20802         struct triple **slot, *old;
20803         struct flow_edge *fedge;
20804         int changed;
20805         int index;
20806         if (lnode->def->op != OP_PHI) {
20807                 internal_error(state, lnode->def, "not phi");
20808         }
20809         /* Store the original value */
20810         old = preserve_lval(state, lnode);
20811
20812         /* default to lattice high */
20813         lnode->val = lnode->def;
20814         slot = &RHS(lnode->def, 0);
20815         index = 0;
20816         for(fedge = lnode->fblock->in; fedge; index++, fedge = fedge->in_next) {
20817                 if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
20818                         fprintf(state->errout, "Examining edge: %d vertex: %d executable: %d\n", 
20819                                 index,
20820                                 fedge->dst->block->vertex,
20821                                 fedge->executable
20822                                 );
20823                 }
20824                 if (!fedge->executable) {
20825                         continue;
20826                 }
20827                 if (!slot[index]) {
20828                         internal_error(state, lnode->def, "no phi value");
20829                 }
20830                 tmp = triple_to_lattice(state, scc, slot[index]);
20831                 /* meet(X, lattice low) = lattice low */
20832                 if (is_lattice_lo(state, tmp)) {
20833                         lnode->val = 0;
20834                 }
20835                 /* meet(X, lattice high) = X */
20836                 else if (is_lattice_hi(state, tmp)) {
20837                         lnode->val = lnode->val;
20838                 }
20839                 /* meet(lattice high, X) = X */
20840                 else if (is_lattice_hi(state, lnode)) {
20841                         lnode->val = dup_triple(state, tmp->val);
20842                         /* Only change the type if necessary */
20843                         if (!is_subset_type(lnode->def->type, tmp->val->type)) {
20844                                 lnode->val->type = lnode->def->type;
20845                         }
20846                 }
20847                 /* meet(const, const) = const or lattice low */
20848                 else if (!constants_equal(state, lnode->val, tmp->val)) {
20849                         lnode->val = 0;
20850                 }
20851
20852                 /* meet(lattice low, X) = lattice low */
20853                 if (is_lattice_lo(state, lnode)) {
20854                         lnode->val = 0;
20855                         break;
20856                 }
20857         }
20858         changed = lval_changed(state, old, lnode);
20859         scc_debug_lnode(state, scc, lnode, changed);
20860
20861         /* If the lattice value has changed update the work lists. */
20862         if (changed) {
20863                 struct ssa_edge *sedge;
20864                 for(sedge = lnode->out; sedge; sedge = sedge->out_next) {
20865                         scc_add_sedge_dst(state, scc, sedge);
20866                 }
20867         }
20868 }
20869
20870
20871 static void scc_visit_expr(struct compile_state *state, struct scc_state *scc,
20872         struct lattice_node *lnode)
20873 {
20874         int changed;
20875
20876         if (!triple_is_def(state, lnode->def)) {
20877                 internal_warning(state, lnode->def, "not visiting an expression?");
20878         }
20879         changed = compute_lnode_val(state, scc, lnode);
20880         scc_debug_lnode(state, scc, lnode, changed);
20881
20882         if (changed) {
20883                 struct ssa_edge *sedge;
20884                 for(sedge = lnode->out; sedge; sedge = sedge->out_next) {
20885                         scc_add_sedge_dst(state, scc, sedge);
20886                 }
20887         }
20888 }
20889
20890 static void scc_writeback_values(
20891         struct compile_state *state, struct scc_state *scc)
20892 {
20893         struct triple *first, *ins;
20894         first = state->first;
20895         ins = first;
20896         do {
20897                 struct lattice_node *lnode;
20898                 lnode = triple_to_lattice(state, scc, ins);
20899                 if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
20900                         if (is_lattice_hi(state, lnode) &&
20901                                 (lnode->val->op != OP_NOOP))
20902                         {
20903                                 struct flow_edge *fedge;
20904                                 int executable;
20905                                 executable = 0;
20906                                 for(fedge = lnode->fblock->in; 
20907                                     !executable && fedge; fedge = fedge->in_next) {
20908                                         executable |= fedge->executable;
20909                                 }
20910                                 if (executable) {
20911                                         internal_warning(state, lnode->def,
20912                                                 "lattice node %d %s->%s still high?",
20913                                                 ins->id, 
20914                                                 tops(lnode->def->op),
20915                                                 tops(lnode->val->op));
20916                                 }
20917                         }
20918                 }
20919
20920                 /* Restore id */
20921                 ins->id = lnode->old_id;
20922                 if (lnode->val && (lnode->val != ins)) {
20923                         /* See if it something I know how to write back */
20924                         switch(lnode->val->op) {
20925                         case OP_INTCONST:
20926                                 mkconst(state, ins, lnode->val->u.cval);
20927                                 break;
20928                         case OP_ADDRCONST:
20929                                 mkaddr_const(state, ins, 
20930                                         MISC(lnode->val, 0), lnode->val->u.cval);
20931                                 break;
20932                         default:
20933                                 /* By default don't copy the changes,
20934                                  * recompute them in place instead.
20935                                  */
20936                                 simplify(state, ins);
20937                                 break;
20938                         }
20939                         if (is_const(lnode->val) &&
20940                                 !constants_equal(state, lnode->val, ins)) {
20941                                 internal_error(state, 0, "constants not equal");
20942                         }
20943                         /* Free the lattice nodes */
20944                         xfree(lnode->val);
20945                         lnode->val = 0;
20946                 }
20947                 ins = ins->next;
20948         } while(ins != first);
20949 }
20950
20951 static void scc_transform(struct compile_state *state)
20952 {
20953         struct scc_state scc;
20954         if (!(state->compiler->flags & COMPILER_SCC_TRANSFORM)) {
20955                 return;
20956         }
20957
20958         initialize_scc_state(state, &scc);
20959
20960         while(scc.flow_work_list || scc.ssa_work_list) {
20961                 struct flow_edge *fedge;
20962                 struct ssa_edge *sedge;
20963                 struct flow_edge *fptr;
20964                 while((fedge = scc_next_fedge(state, &scc))) {
20965                         struct block *block;
20966                         struct triple *ptr;
20967                         struct flow_block *fblock;
20968                         int reps;
20969                         int done;
20970                         if (fedge->executable) {
20971                                 continue;
20972                         }
20973                         if (!fedge->dst) {
20974                                 internal_error(state, 0, "fedge without dst");
20975                         }
20976                         if (!fedge->src) {
20977                                 internal_error(state, 0, "fedge without src");
20978                         }
20979                         fedge->executable = 1;
20980                         fblock = fedge->dst;
20981                         block = fblock->block;
20982                         reps = 0;
20983                         for(fptr = fblock->in; fptr; fptr = fptr->in_next) {
20984                                 if (fptr->executable) {
20985                                         reps++;
20986                                 }
20987                         }
20988                         
20989                         if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
20990                                 fprintf(state->errout, "vertex: %d reps: %d\n", 
20991                                         block->vertex, reps);
20992                         }
20993
20994                         done = 0;
20995                         for(ptr = block->first; !done; ptr = ptr->next) {
20996                                 struct lattice_node *lnode;
20997                                 done = (ptr == block->last);
20998                                 lnode = &scc.lattice[ptr->id];
20999                                 if (ptr->op == OP_PHI) {
21000                                         scc_visit_phi(state, &scc, lnode);
21001                                 }
21002                                 else if ((reps == 1) && triple_is_def(state, ptr))
21003                                 {
21004                                         scc_visit_expr(state, &scc, lnode);
21005                                 }
21006                         }
21007                         /* Add unconditional branch edges */
21008                         if (!triple_is_cbranch(state, fblock->block->last)) {
21009                                 struct flow_edge *out;
21010                                 for(out = fblock->out; out; out = out->out_next) {
21011                                         scc_add_fedge(state, &scc, out);
21012                                 }
21013                         }
21014                 }
21015                 while((sedge = scc_next_sedge(state, &scc))) {
21016                         struct lattice_node *lnode;
21017                         struct flow_block *fblock;
21018                         lnode = sedge->dst;
21019                         fblock = lnode->fblock;
21020
21021                         if (state->compiler->debug & DEBUG_SCC_TRANSFORM) {
21022                                 fprintf(state->errout, "sedge: %5d (%5d -> %5d)\n",
21023                                         sedge - scc.ssa_edges,
21024                                         sedge->src->def->id,
21025                                         sedge->dst->def->id);
21026                         }
21027
21028                         if (lnode->def->op == OP_PHI) {
21029                                 scc_visit_phi(state, &scc, lnode);
21030                         }
21031                         else {
21032                                 for(fptr = fblock->in; fptr; fptr = fptr->in_next) {
21033                                         if (fptr->executable) {
21034                                                 break;
21035                                         }
21036                                 }
21037                                 if (fptr) {
21038                                         scc_visit_expr(state, &scc, lnode);
21039                                 }
21040                         }
21041                 }
21042         }
21043         
21044         scc_writeback_values(state, &scc);
21045         free_scc_state(state, &scc);
21046         rebuild_ssa_form(state);
21047         
21048         print_blocks(state, __func__, state->dbgout);
21049 }
21050
21051
21052 static void transform_to_arch_instructions(struct compile_state *state)
21053 {
21054         struct triple *ins, *first;
21055         first = state->first;
21056         ins = first;
21057         do {
21058                 ins = transform_to_arch_instruction(state, ins);
21059         } while(ins != first);
21060         
21061         print_blocks(state, __func__, state->dbgout);
21062 }
21063
21064 #if DEBUG_CONSISTENCY
21065 static void verify_uses(struct compile_state *state)
21066 {
21067         struct triple *first, *ins;
21068         struct triple_set *set;
21069         first = state->first;
21070         ins = first;
21071         do {
21072                 struct triple **expr;
21073                 expr = triple_rhs(state, ins, 0);
21074                 for(; expr; expr = triple_rhs(state, ins, expr)) {
21075                         struct triple *rhs;
21076                         rhs = *expr;
21077                         for(set = rhs?rhs->use:0; set; set = set->next) {
21078                                 if (set->member == ins) {
21079                                         break;
21080                                 }
21081                         }
21082                         if (!set) {
21083                                 internal_error(state, ins, "rhs not used");
21084                         }
21085                 }
21086                 expr = triple_lhs(state, ins, 0);
21087                 for(; expr; expr = triple_lhs(state, ins, expr)) {
21088                         struct triple *lhs;
21089                         lhs = *expr;
21090                         for(set =  lhs?lhs->use:0; set; set = set->next) {
21091                                 if (set->member == ins) {
21092                                         break;
21093                                 }
21094                         }
21095                         if (!set) {
21096                                 internal_error(state, ins, "lhs not used");
21097                         }
21098                 }
21099                 expr = triple_misc(state, ins, 0);
21100                 if (ins->op != OP_PHI) {
21101                         for(; expr; expr = triple_targ(state, ins, expr)) {
21102                                 struct triple *misc;
21103                                 misc = *expr;
21104                                 for(set = misc?misc->use:0; set; set = set->next) {
21105                                         if (set->member == ins) {
21106                                                 break;
21107                                         }
21108                                 }
21109                                 if (!set) {
21110                                         internal_error(state, ins, "misc not used");
21111                                 }
21112                         }
21113                 }
21114                 if (!triple_is_ret(state, ins)) {
21115                         expr = triple_targ(state, ins, 0);
21116                         for(; expr; expr = triple_targ(state, ins, expr)) {
21117                                 struct triple *targ;
21118                                 targ = *expr;
21119                                 for(set = targ?targ->use:0; set; set = set->next) {
21120                                         if (set->member == ins) {
21121                                                 break;
21122                                         }
21123                                 }
21124                                 if (!set) {
21125                                         internal_error(state, ins, "targ not used");
21126                                 }
21127                         }
21128                 }
21129                 ins = ins->next;
21130         } while(ins != first);
21131         
21132 }
21133 static void verify_blocks_present(struct compile_state *state)
21134 {
21135         struct triple *first, *ins;
21136         if (!state->bb.first_block) {
21137                 return;
21138         }
21139         first = state->first;
21140         ins = first;
21141         do {
21142                 valid_ins(state, ins);
21143                 if (triple_stores_block(state, ins)) {
21144                         if (!ins->u.block) {
21145                                 internal_error(state, ins, 
21146                                         "%p not in a block?", ins);
21147                         }
21148                 }
21149                 ins = ins->next;
21150         } while(ins != first);
21151         
21152         
21153 }
21154
21155 static int edge_present(struct compile_state *state, struct block *block, struct triple *edge)
21156 {
21157         struct block_set *bedge;
21158         struct block *targ;
21159         targ = block_of_triple(state, edge);
21160         for(bedge = block->edges; bedge; bedge = bedge->next) {
21161                 if (bedge->member == targ) {
21162                         return 1;
21163                 }
21164         }
21165         return 0;
21166 }
21167
21168 static void verify_blocks(struct compile_state *state)
21169 {
21170         struct triple *ins;
21171         struct block *block;
21172         int blocks;
21173         block = state->bb.first_block;
21174         if (!block) {
21175                 return;
21176         }
21177         blocks = 0;
21178         do {
21179                 int users;
21180                 struct block_set *user, *edge;
21181                 blocks++;
21182                 for(ins = block->first; ins != block->last->next; ins = ins->next) {
21183                         if (triple_stores_block(state, ins) && (ins->u.block != block)) {
21184                                 internal_error(state, ins, "inconsitent block specified");
21185                         }
21186                         valid_ins(state, ins);
21187                 }
21188                 users = 0;
21189                 for(user = block->use; user; user = user->next) {
21190                         users++;
21191                         if (!user->member->first) {
21192                                 internal_error(state, block->first, "user is empty");
21193                         }
21194                         if ((block == state->bb.last_block) &&
21195                                 (user->member == state->bb.first_block)) {
21196                                 continue;
21197                         }
21198                         for(edge = user->member->edges; edge; edge = edge->next) {
21199                                 if (edge->member == block) {
21200                                         break;
21201                                 }
21202                         }
21203                         if (!edge) {
21204                                 internal_error(state, user->member->first,
21205                                         "user does not use block");
21206                         }
21207                 }
21208                 if (triple_is_branch(state, block->last)) {
21209                         struct triple **expr;
21210                         expr = triple_edge_targ(state, block->last, 0);
21211                         for(;expr; expr = triple_edge_targ(state, block->last, expr)) {
21212                                 if (*expr && !edge_present(state, block, *expr)) {
21213                                         internal_error(state, block->last, "no edge to targ");
21214                                 }
21215                         }
21216                 }
21217                 if (!triple_is_ubranch(state, block->last) &&
21218                         (block != state->bb.last_block) &&
21219                         !edge_present(state, block, block->last->next)) {
21220                         internal_error(state, block->last, "no edge to block->last->next");
21221                 }
21222                 for(edge = block->edges; edge; edge = edge->next) {
21223                         for(user = edge->member->use; user; user = user->next) {
21224                                 if (user->member == block) {
21225                                         break;
21226                                 }
21227                         }
21228                         if (!user || user->member != block) {
21229                                 internal_error(state, block->first,
21230                                         "block does not use edge");
21231                         }
21232                         if (!edge->member->first) {
21233                                 internal_error(state, block->first, "edge block is empty");
21234                         }
21235                 }
21236                 if (block->users != users) {
21237                         internal_error(state, block->first, 
21238                                 "computed users %d != stored users %d",
21239                                 users, block->users);
21240                 }
21241                 if (!triple_stores_block(state, block->last->next)) {
21242                         internal_error(state, block->last->next, 
21243                                 "cannot find next block");
21244                 }
21245                 block = block->last->next->u.block;
21246                 if (!block) {
21247                         internal_error(state, block->last->next,
21248                                 "bad next block");
21249                 }
21250         } while(block != state->bb.first_block);
21251         if (blocks != state->bb.last_vertex) {
21252                 internal_error(state, 0, "computed blocks: %d != stored blocks %d",
21253                         blocks, state->bb.last_vertex);
21254         }
21255 }
21256
21257 static void verify_domination(struct compile_state *state)
21258 {
21259         struct triple *first, *ins;
21260         struct triple_set *set;
21261         if (!state->bb.first_block) {
21262                 return;
21263         }
21264         
21265         first = state->first;
21266         ins = first;
21267         do {
21268                 for(set = ins->use; set; set = set->next) {
21269                         struct triple **slot;
21270                         struct triple *use_point;
21271                         int i, zrhs;
21272                         use_point = 0;
21273                         zrhs = set->member->rhs;
21274                         slot = &RHS(set->member, 0);
21275                         /* See if the use is on the right hand side */
21276                         for(i = 0; i < zrhs; i++) {
21277                                 if (slot[i] == ins) {
21278                                         break;
21279                                 }
21280                         }
21281                         if (i < zrhs) {
21282                                 use_point = set->member;
21283                                 if (set->member->op == OP_PHI) {
21284                                         struct block_set *bset;
21285                                         int edge;
21286                                         bset = set->member->u.block->use;
21287                                         for(edge = 0; bset && (edge < i); edge++) {
21288                                                 bset = bset->next;
21289                                         }
21290                                         if (!bset) {
21291                                                 internal_error(state, set->member, 
21292                                                         "no edge for phi rhs %d", i);
21293                                         }
21294                                         use_point = bset->member->last;
21295                                 }
21296                         }
21297                         if (use_point &&
21298                                 !tdominates(state, ins, use_point)) {
21299                                 if (is_const(ins)) {
21300                                         internal_warning(state, ins, 
21301                                         "non dominated rhs use point %p?", use_point);
21302                                 }
21303                                 else {
21304                                         internal_error(state, ins, 
21305                                                 "non dominated rhs use point %p?", use_point);
21306                                 }
21307                         }
21308                 }
21309                 ins = ins->next;
21310         } while(ins != first);
21311 }
21312
21313 static void verify_rhs(struct compile_state *state)
21314 {
21315         struct triple *first, *ins;
21316         first = state->first;
21317         ins = first;
21318         do {
21319                 struct triple **slot;
21320                 int zrhs, i;
21321                 zrhs = ins->rhs;
21322                 slot = &RHS(ins, 0);
21323                 for(i = 0; i < zrhs; i++) {
21324                         if (slot[i] == 0) {
21325                                 internal_error(state, ins,
21326                                         "missing rhs %d on %s",
21327                                         i, tops(ins->op));
21328                         }
21329                         if ((ins->op != OP_PHI) && (slot[i] == ins)) {
21330                                 internal_error(state, ins,
21331                                         "ins == rhs[%d] on %s",
21332                                         i, tops(ins->op));
21333                         }
21334                 }
21335                 ins = ins->next;
21336         } while(ins != first);
21337 }
21338
21339 static void verify_piece(struct compile_state *state)
21340 {
21341         struct triple *first, *ins;
21342         first = state->first;
21343         ins = first;
21344         do {
21345                 struct triple *ptr;
21346                 int lhs, i;
21347                 lhs = ins->lhs;
21348                 for(ptr = ins->next, i = 0; i < lhs; i++, ptr = ptr->next) {
21349                         if (ptr != LHS(ins, i)) {
21350                                 internal_error(state, ins, "malformed lhs on %s",
21351                                         tops(ins->op));
21352                         }
21353                         if (ptr->op != OP_PIECE) {
21354                                 internal_error(state, ins, "bad lhs op %s at %d on %s",
21355                                         tops(ptr->op), i, tops(ins->op));
21356                         }
21357                         if (ptr->u.cval != i) {
21358                                 internal_error(state, ins, "bad u.cval of %d %d expected",
21359                                         ptr->u.cval, i);
21360                         }
21361                 }
21362                 ins = ins->next;
21363         } while(ins != first);
21364 }
21365
21366 static void verify_ins_colors(struct compile_state *state)
21367 {
21368         struct triple *first, *ins;
21369         
21370         first = state->first;
21371         ins = first;
21372         do {
21373                 ins = ins->next;
21374         } while(ins != first);
21375 }
21376
21377 static void verify_unknown(struct compile_state *state)
21378 {
21379         struct triple *first, *ins;
21380         if (    (unknown_triple.next != &unknown_triple) ||
21381                 (unknown_triple.prev != &unknown_triple) ||
21382 #if 0
21383                 (unknown_triple.use != 0) ||
21384 #endif
21385                 (unknown_triple.op != OP_UNKNOWNVAL) ||
21386                 (unknown_triple.lhs != 0) ||
21387                 (unknown_triple.rhs != 0) ||
21388                 (unknown_triple.misc != 0) ||
21389                 (unknown_triple.targ != 0) ||
21390                 (unknown_triple.template_id != 0) ||
21391                 (unknown_triple.id != -1) ||
21392                 (unknown_triple.type != &unknown_type) ||
21393                 (unknown_triple.occurance != &dummy_occurance) ||
21394                 (unknown_triple.param[0] != 0) ||
21395                 (unknown_triple.param[1] != 0)) {
21396                 internal_error(state, &unknown_triple, "unknown_triple corrupted!");
21397         }
21398         if (    (dummy_occurance.count != 2) ||
21399                 (strcmp(dummy_occurance.filename, __FILE__) != 0) ||
21400                 (strcmp(dummy_occurance.function, "") != 0) ||
21401                 (dummy_occurance.col != 0) ||
21402                 (dummy_occurance.parent != 0)) {
21403                 internal_error(state, &unknown_triple, "dummy_occurance corrupted!");
21404         }
21405         if (    (unknown_type.type != TYPE_UNKNOWN)) {
21406                 internal_error(state, &unknown_triple, "unknown_type corrupted!");
21407         }
21408         first = state->first;
21409         ins = first;
21410         do {
21411                 int params, i;
21412                 if (ins == &unknown_triple) {
21413                         internal_error(state, ins, "unknown triple in list");
21414                 }
21415                 params = TRIPLE_SIZE(ins);
21416                 for(i = 0; i < params; i++) {
21417                         if (ins->param[i] == &unknown_triple) {
21418                                 internal_error(state, ins, "unknown triple used!");
21419                         }
21420                 }
21421                 ins = ins->next;
21422         } while(ins != first);
21423 }
21424
21425 static void verify_types(struct compile_state *state)
21426 {
21427         struct triple *first, *ins;
21428         first = state->first;
21429         ins = first;
21430         do {
21431                 struct type *invalid;
21432                 invalid = invalid_type(state, ins->type);
21433                 if (invalid) {
21434                         FILE *fp = state->errout;
21435                         fprintf(fp, "type: ");
21436                         name_of(fp, ins->type);
21437                         fprintf(fp, "\n");
21438                         fprintf(fp, "invalid type: ");
21439                         name_of(fp, invalid);
21440                         fprintf(fp, "\n");
21441                         internal_error(state, ins, "invalid ins type");
21442                 }
21443         } while(ins != first);
21444 }
21445
21446 static void verify_copy(struct compile_state *state)
21447 {
21448         struct triple *first, *ins, *next;
21449         first = state->first;
21450         next = ins = first;
21451         do {
21452                 ins = next;
21453                 next = ins->next;
21454                 if (ins->op != OP_COPY) {
21455                         continue;
21456                 }
21457                 if (!equiv_types(ins->type, RHS(ins, 0)->type)) {
21458                         FILE *fp = state->errout;
21459                         fprintf(fp, "src type: ");
21460                         name_of(fp, RHS(ins, 0)->type);
21461                         fprintf(fp, "\n");
21462                         fprintf(fp, "dst type: ");
21463                         name_of(fp, ins->type);
21464                         fprintf(fp, "\n");
21465                         internal_error(state, ins, "type mismatch in copy");
21466                 }
21467         } while(next != first);
21468 }
21469
21470 static void verify_consistency(struct compile_state *state)
21471 {
21472         verify_unknown(state);
21473         verify_uses(state);
21474         verify_blocks_present(state);
21475         verify_blocks(state);
21476         verify_domination(state);
21477         verify_rhs(state);
21478         verify_piece(state);
21479         verify_ins_colors(state);
21480         verify_types(state);
21481         verify_copy(state);
21482         if (state->compiler->debug & DEBUG_VERIFICATION) {
21483                 fprintf(state->dbgout, "consistency verified\n");
21484         }
21485 }
21486 #else 
21487 static void verify_consistency(struct compile_state *state) {}
21488 #endif /* DEBUG_CONSISTENCY */
21489
21490 static void optimize(struct compile_state *state)
21491 {
21492         /* Join all of the functions into one giant function */
21493         join_functions(state);
21494
21495         /* Dump what the instruction graph intially looks like */
21496         print_triples(state);
21497
21498         /* Replace structures with simpler data types */
21499         decompose_compound_types(state);
21500         print_triples(state);
21501
21502         verify_consistency(state);
21503         /* Analyze the intermediate code */
21504         state->bb.first = state->first;
21505         analyze_basic_blocks(state, &state->bb);
21506
21507         /* Transform the code to ssa form. */
21508         /*
21509          * The transformation to ssa form puts a phi function
21510          * on each of edge of a dominance frontier where that
21511          * phi function might be needed.  At -O2 if we don't
21512          * eleminate the excess phi functions we can get an
21513          * exponential code size growth.  So I kill the extra
21514          * phi functions early and I kill them often.
21515          */
21516         transform_to_ssa_form(state);
21517         verify_consistency(state);
21518
21519         /* Remove dead code */
21520         eliminate_inefectual_code(state);
21521         verify_consistency(state);
21522
21523         /* Do strength reduction and simple constant optimizations */
21524         simplify_all(state);
21525         verify_consistency(state);
21526         /* Propogate constants throughout the code */
21527         scc_transform(state);
21528         verify_consistency(state);
21529 #warning "WISHLIST implement single use constants (least possible register pressure)"
21530 #warning "WISHLIST implement induction variable elimination"
21531         /* Select architecture instructions and an initial partial
21532          * coloring based on architecture constraints.
21533          */
21534         transform_to_arch_instructions(state);
21535         verify_consistency(state);
21536
21537         /* Remove dead code */
21538         eliminate_inefectual_code(state);
21539         verify_consistency(state);
21540
21541         /* Color all of the variables to see if they will fit in registers */
21542         insert_copies_to_phi(state);
21543         verify_consistency(state);
21544
21545         insert_mandatory_copies(state);
21546         verify_consistency(state);
21547
21548         allocate_registers(state);
21549         verify_consistency(state);
21550
21551         /* Remove the optimization information.
21552          * This is more to check for memory consistency than to free memory.
21553          */
21554         free_basic_blocks(state, &state->bb);
21555 }
21556
21557 static void print_op_asm(struct compile_state *state,
21558         struct triple *ins, FILE *fp)
21559 {
21560         struct asm_info *info;
21561         const char *ptr;
21562         unsigned lhs, rhs, i;
21563         info = ins->u.ainfo;
21564         lhs = ins->lhs;
21565         rhs = ins->rhs;
21566         /* Don't count the clobbers in lhs */
21567         for(i = 0; i < lhs; i++) {
21568                 if (LHS(ins, i)->type == &void_type) {
21569                         break;
21570                 }
21571         }
21572         lhs = i;
21573         fprintf(fp, "#ASM\n");
21574         fputc('\t', fp);
21575         for(ptr = info->str; *ptr; ptr++) {
21576                 char *next;
21577                 unsigned long param;
21578                 struct triple *piece;
21579                 if (*ptr != '%') {
21580                         fputc(*ptr, fp);
21581                         continue;
21582                 }
21583                 ptr++;
21584                 if (*ptr == '%') {
21585                         fputc('%', fp);
21586                         continue;
21587                 }
21588                 param = strtoul(ptr, &next, 10);
21589                 if (ptr == next) {
21590                         error(state, ins, "Invalid asm template");
21591                 }
21592                 if (param >= (lhs + rhs)) {
21593                         error(state, ins, "Invalid param %%%u in asm template",
21594                                 param);
21595                 }
21596                 piece = (param < lhs)? LHS(ins, param) : RHS(ins, param - lhs);
21597                 fprintf(fp, "%s", 
21598                         arch_reg_str(ID_REG(piece->id)));
21599                 ptr = next -1;
21600         }
21601         fprintf(fp, "\n#NOT ASM\n");
21602 }
21603
21604
21605 /* Only use the low x86 byte registers.  This allows me
21606  * allocate the entire register when a byte register is used.
21607  */
21608 #define X86_4_8BIT_GPRS 1
21609
21610 /* x86 featrues */
21611 #define X86_MMX_REGS  (1<<0)
21612 #define X86_XMM_REGS  (1<<1)
21613 #define X86_NOOP_COPY (1<<2)
21614
21615 /* The x86 register classes */
21616 #define REGC_FLAGS       0
21617 #define REGC_GPR8        1
21618 #define REGC_GPR16       2
21619 #define REGC_GPR32       3
21620 #define REGC_DIVIDEND64  4
21621 #define REGC_DIVIDEND32  5
21622 #define REGC_MMX         6
21623 #define REGC_XMM         7
21624 #define REGC_GPR32_8     8
21625 #define REGC_GPR16_8     9
21626 #define REGC_GPR8_LO    10
21627 #define REGC_IMM32      11
21628 #define REGC_IMM16      12
21629 #define REGC_IMM8       13
21630 #define LAST_REGC  REGC_IMM8
21631 #if LAST_REGC >= MAX_REGC
21632 #error "MAX_REGC is to low"
21633 #endif
21634
21635 /* Register class masks */
21636 #define REGCM_FLAGS      (1 << REGC_FLAGS)
21637 #define REGCM_GPR8       (1 << REGC_GPR8)
21638 #define REGCM_GPR16      (1 << REGC_GPR16)
21639 #define REGCM_GPR32      (1 << REGC_GPR32)
21640 #define REGCM_DIVIDEND64 (1 << REGC_DIVIDEND64)
21641 #define REGCM_DIVIDEND32 (1 << REGC_DIVIDEND32)
21642 #define REGCM_MMX        (1 << REGC_MMX)
21643 #define REGCM_XMM        (1 << REGC_XMM)
21644 #define REGCM_GPR32_8    (1 << REGC_GPR32_8)
21645 #define REGCM_GPR16_8    (1 << REGC_GPR16_8)
21646 #define REGCM_GPR8_LO    (1 << REGC_GPR8_LO)
21647 #define REGCM_IMM32      (1 << REGC_IMM32)
21648 #define REGCM_IMM16      (1 << REGC_IMM16)
21649 #define REGCM_IMM8       (1 << REGC_IMM8)
21650 #define REGCM_ALL        ((1 << (LAST_REGC + 1)) - 1)
21651 #define REGCM_IMMALL    (REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8)
21652
21653 /* The x86 registers */
21654 #define REG_EFLAGS  2
21655 #define REGC_FLAGS_FIRST REG_EFLAGS
21656 #define REGC_FLAGS_LAST  REG_EFLAGS
21657 #define REG_AL      3
21658 #define REG_BL      4
21659 #define REG_CL      5
21660 #define REG_DL      6
21661 #define REG_AH      7
21662 #define REG_BH      8
21663 #define REG_CH      9
21664 #define REG_DH      10
21665 #define REGC_GPR8_LO_FIRST REG_AL
21666 #define REGC_GPR8_LO_LAST  REG_DL
21667 #define REGC_GPR8_FIRST  REG_AL
21668 #define REGC_GPR8_LAST   REG_DH
21669 #define REG_AX     11
21670 #define REG_BX     12
21671 #define REG_CX     13
21672 #define REG_DX     14
21673 #define REG_SI     15
21674 #define REG_DI     16
21675 #define REG_BP     17
21676 #define REG_SP     18
21677 #define REGC_GPR16_FIRST REG_AX
21678 #define REGC_GPR16_LAST  REG_SP
21679 #define REG_EAX    19
21680 #define REG_EBX    20
21681 #define REG_ECX    21
21682 #define REG_EDX    22
21683 #define REG_ESI    23
21684 #define REG_EDI    24
21685 #define REG_EBP    25
21686 #define REG_ESP    26
21687 #define REGC_GPR32_FIRST REG_EAX
21688 #define REGC_GPR32_LAST  REG_ESP
21689 #define REG_EDXEAX 27
21690 #define REGC_DIVIDEND64_FIRST REG_EDXEAX
21691 #define REGC_DIVIDEND64_LAST  REG_EDXEAX
21692 #define REG_DXAX   28
21693 #define REGC_DIVIDEND32_FIRST REG_DXAX
21694 #define REGC_DIVIDEND32_LAST  REG_DXAX
21695 #define REG_MMX0   29
21696 #define REG_MMX1   30
21697 #define REG_MMX2   31
21698 #define REG_MMX3   32
21699 #define REG_MMX4   33
21700 #define REG_MMX5   34
21701 #define REG_MMX6   35
21702 #define REG_MMX7   36
21703 #define REGC_MMX_FIRST REG_MMX0
21704 #define REGC_MMX_LAST  REG_MMX7
21705 #define REG_XMM0   37
21706 #define REG_XMM1   38
21707 #define REG_XMM2   39
21708 #define REG_XMM3   40
21709 #define REG_XMM4   41
21710 #define REG_XMM5   42
21711 #define REG_XMM6   43
21712 #define REG_XMM7   44
21713 #define REGC_XMM_FIRST REG_XMM0
21714 #define REGC_XMM_LAST  REG_XMM7
21715 #warning "WISHLIST figure out how to use pinsrw and pextrw to better use extended regs"
21716 #define LAST_REG   REG_XMM7
21717
21718 #define REGC_GPR32_8_FIRST REG_EAX
21719 #define REGC_GPR32_8_LAST  REG_EDX
21720 #define REGC_GPR16_8_FIRST REG_AX
21721 #define REGC_GPR16_8_LAST  REG_DX
21722
21723 #define REGC_IMM8_FIRST    -1
21724 #define REGC_IMM8_LAST     -1
21725 #define REGC_IMM16_FIRST   -2
21726 #define REGC_IMM16_LAST    -1
21727 #define REGC_IMM32_FIRST   -4
21728 #define REGC_IMM32_LAST    -1
21729
21730 #if LAST_REG >= MAX_REGISTERS
21731 #error "MAX_REGISTERS to low"
21732 #endif
21733
21734
21735 static unsigned regc_size[LAST_REGC +1] = {
21736         [REGC_FLAGS]      = REGC_FLAGS_LAST      - REGC_FLAGS_FIRST + 1,
21737         [REGC_GPR8]       = REGC_GPR8_LAST       - REGC_GPR8_FIRST + 1,
21738         [REGC_GPR16]      = REGC_GPR16_LAST      - REGC_GPR16_FIRST + 1,
21739         [REGC_GPR32]      = REGC_GPR32_LAST      - REGC_GPR32_FIRST + 1,
21740         [REGC_DIVIDEND64] = REGC_DIVIDEND64_LAST - REGC_DIVIDEND64_FIRST + 1,
21741         [REGC_DIVIDEND32] = REGC_DIVIDEND32_LAST - REGC_DIVIDEND32_FIRST + 1,
21742         [REGC_MMX]        = REGC_MMX_LAST        - REGC_MMX_FIRST + 1,
21743         [REGC_XMM]        = REGC_XMM_LAST        - REGC_XMM_FIRST + 1,
21744         [REGC_GPR32_8]    = REGC_GPR32_8_LAST    - REGC_GPR32_8_FIRST + 1,
21745         [REGC_GPR16_8]    = REGC_GPR16_8_LAST    - REGC_GPR16_8_FIRST + 1,
21746         [REGC_GPR8_LO]    = REGC_GPR8_LO_LAST    - REGC_GPR8_LO_FIRST + 1,
21747         [REGC_IMM32]      = 0,
21748         [REGC_IMM16]      = 0,
21749         [REGC_IMM8]       = 0,
21750 };
21751
21752 static const struct {
21753         int first, last;
21754 } regcm_bound[LAST_REGC + 1] = {
21755         [REGC_FLAGS]      = { REGC_FLAGS_FIRST,      REGC_FLAGS_LAST },
21756         [REGC_GPR8]       = { REGC_GPR8_FIRST,       REGC_GPR8_LAST },
21757         [REGC_GPR16]      = { REGC_GPR16_FIRST,      REGC_GPR16_LAST },
21758         [REGC_GPR32]      = { REGC_GPR32_FIRST,      REGC_GPR32_LAST },
21759         [REGC_DIVIDEND64] = { REGC_DIVIDEND64_FIRST, REGC_DIVIDEND64_LAST },
21760         [REGC_DIVIDEND32] = { REGC_DIVIDEND32_FIRST, REGC_DIVIDEND32_LAST },
21761         [REGC_MMX]        = { REGC_MMX_FIRST,        REGC_MMX_LAST },
21762         [REGC_XMM]        = { REGC_XMM_FIRST,        REGC_XMM_LAST },
21763         [REGC_GPR32_8]    = { REGC_GPR32_8_FIRST,    REGC_GPR32_8_LAST },
21764         [REGC_GPR16_8]    = { REGC_GPR16_8_FIRST,    REGC_GPR16_8_LAST },
21765         [REGC_GPR8_LO]    = { REGC_GPR8_LO_FIRST,    REGC_GPR8_LO_LAST },
21766         [REGC_IMM32]      = { REGC_IMM32_FIRST,      REGC_IMM32_LAST },
21767         [REGC_IMM16]      = { REGC_IMM16_FIRST,      REGC_IMM16_LAST },
21768         [REGC_IMM8]       = { REGC_IMM8_FIRST,       REGC_IMM8_LAST },
21769 };
21770
21771 #if ARCH_INPUT_REGS != 4
21772 #error ARCH_INPUT_REGS size mismatch
21773 #endif
21774 static const struct reg_info arch_input_regs[ARCH_INPUT_REGS] = {
21775         { .reg = REG_EAX, .regcm = REGCM_GPR32 },
21776         { .reg = REG_EBX, .regcm = REGCM_GPR32 },
21777         { .reg = REG_ECX, .regcm = REGCM_GPR32 },
21778         { .reg = REG_EDX, .regcm = REGCM_GPR32 },
21779 };
21780
21781 #if ARCH_OUTPUT_REGS != 4
21782 #error ARCH_INPUT_REGS size mismatch
21783 #endif
21784 static const struct reg_info arch_output_regs[ARCH_OUTPUT_REGS] = {
21785         { .reg = REG_EAX, .regcm = REGCM_GPR32 },
21786         { .reg = REG_EBX, .regcm = REGCM_GPR32 },
21787         { .reg = REG_ECX, .regcm = REGCM_GPR32 },
21788         { .reg = REG_EDX, .regcm = REGCM_GPR32 },
21789 };
21790
21791 static void init_arch_state(struct arch_state *arch)
21792 {
21793         memset(arch, 0, sizeof(*arch));
21794         arch->features = 0;
21795 }
21796
21797 static const struct compiler_flag arch_flags[] = {
21798         { "mmx",       X86_MMX_REGS },
21799         { "sse",       X86_XMM_REGS },
21800         { "noop-copy", X86_NOOP_COPY },
21801         { 0,     0 },
21802 };
21803 static const struct compiler_flag arch_cpus[] = {
21804         { "i386", 0 },
21805         { "p2",   X86_MMX_REGS },
21806         { "p3",   X86_MMX_REGS | X86_XMM_REGS },
21807         { "p4",   X86_MMX_REGS | X86_XMM_REGS },
21808         { "k7",   X86_MMX_REGS },
21809         { "k8",   X86_MMX_REGS | X86_XMM_REGS },
21810         { "c3",   X86_MMX_REGS },
21811         { "c3-2", X86_MMX_REGS | X86_XMM_REGS }, /* Nehemiah */
21812         {  0,     0 }
21813 };
21814 static int arch_encode_flag(struct arch_state *arch, const char *flag)
21815 {
21816         int result;
21817         int act;
21818
21819         act = 1;
21820         result = -1;
21821         if (strncmp(flag, "no-", 3) == 0) {
21822                 flag += 3;
21823                 act = 0;
21824         }
21825         if (act && strncmp(flag, "cpu=", 4) == 0) {
21826                 flag += 4;
21827                 result = set_flag(arch_cpus, &arch->features, 1, flag);
21828         }
21829         else {
21830                 result = set_flag(arch_flags, &arch->features, act, flag);
21831         }
21832         return result;
21833 }
21834
21835 static void arch_usage(FILE *fp)
21836 {
21837         flag_usage(fp, arch_flags, "-m", "-mno-");
21838         flag_usage(fp, arch_cpus, "-mcpu=", 0);
21839 }
21840
21841 static unsigned arch_regc_size(struct compile_state *state, int class)
21842 {
21843         if ((class < 0) || (class > LAST_REGC)) {
21844                 return 0;
21845         }
21846         return regc_size[class];
21847 }
21848
21849 static int arch_regcm_intersect(unsigned regcm1, unsigned regcm2)
21850 {
21851         /* See if two register classes may have overlapping registers */
21852         unsigned gpr_mask = REGCM_GPR8 | REGCM_GPR8_LO | REGCM_GPR16_8 | REGCM_GPR16 |
21853                 REGCM_GPR32_8 | REGCM_GPR32 | 
21854                 REGCM_DIVIDEND32 | REGCM_DIVIDEND64;
21855
21856         /* Special case for the immediates */
21857         if ((regcm1 & (REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8)) &&
21858                 ((regcm1 & ~(REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8)) == 0) &&
21859                 (regcm2 & (REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8)) &&
21860                 ((regcm2 & ~(REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8)) == 0)) { 
21861                 return 0;
21862         }
21863         return (regcm1 & regcm2) ||
21864                 ((regcm1 & gpr_mask) && (regcm2 & gpr_mask));
21865 }
21866
21867 static void arch_reg_equivs(
21868         struct compile_state *state, unsigned *equiv, int reg)
21869 {
21870         if ((reg < 0) || (reg > LAST_REG)) {
21871                 internal_error(state, 0, "invalid register");
21872         }
21873         *equiv++ = reg;
21874         switch(reg) {
21875         case REG_AL:
21876 #if X86_4_8BIT_GPRS
21877                 *equiv++ = REG_AH;
21878 #endif
21879                 *equiv++ = REG_AX;
21880                 *equiv++ = REG_EAX;
21881                 *equiv++ = REG_DXAX;
21882                 *equiv++ = REG_EDXEAX;
21883                 break;
21884         case REG_AH:
21885 #if X86_4_8BIT_GPRS
21886                 *equiv++ = REG_AL;
21887 #endif
21888                 *equiv++ = REG_AX;
21889                 *equiv++ = REG_EAX;
21890                 *equiv++ = REG_DXAX;
21891                 *equiv++ = REG_EDXEAX;
21892                 break;
21893         case REG_BL:  
21894 #if X86_4_8BIT_GPRS
21895                 *equiv++ = REG_BH;
21896 #endif
21897                 *equiv++ = REG_BX;
21898                 *equiv++ = REG_EBX;
21899                 break;
21900
21901         case REG_BH:
21902 #if X86_4_8BIT_GPRS
21903                 *equiv++ = REG_BL;
21904 #endif
21905                 *equiv++ = REG_BX;
21906                 *equiv++ = REG_EBX;
21907                 break;
21908         case REG_CL:
21909 #if X86_4_8BIT_GPRS
21910                 *equiv++ = REG_CH;
21911 #endif
21912                 *equiv++ = REG_CX;
21913                 *equiv++ = REG_ECX;
21914                 break;
21915
21916         case REG_CH:
21917 #if X86_4_8BIT_GPRS
21918                 *equiv++ = REG_CL;
21919 #endif
21920                 *equiv++ = REG_CX;
21921                 *equiv++ = REG_ECX;
21922                 break;
21923         case REG_DL:
21924 #if X86_4_8BIT_GPRS
21925                 *equiv++ = REG_DH;
21926 #endif
21927                 *equiv++ = REG_DX;
21928                 *equiv++ = REG_EDX;
21929                 *equiv++ = REG_DXAX;
21930                 *equiv++ = REG_EDXEAX;
21931                 break;
21932         case REG_DH:
21933 #if X86_4_8BIT_GPRS
21934                 *equiv++ = REG_DL;
21935 #endif
21936                 *equiv++ = REG_DX;
21937                 *equiv++ = REG_EDX;
21938                 *equiv++ = REG_DXAX;
21939                 *equiv++ = REG_EDXEAX;
21940                 break;
21941         case REG_AX:
21942                 *equiv++ = REG_AL;
21943                 *equiv++ = REG_AH;
21944                 *equiv++ = REG_EAX;
21945                 *equiv++ = REG_DXAX;
21946                 *equiv++ = REG_EDXEAX;
21947                 break;
21948         case REG_BX:
21949                 *equiv++ = REG_BL;
21950                 *equiv++ = REG_BH;
21951                 *equiv++ = REG_EBX;
21952                 break;
21953         case REG_CX:  
21954                 *equiv++ = REG_CL;
21955                 *equiv++ = REG_CH;
21956                 *equiv++ = REG_ECX;
21957                 break;
21958         case REG_DX:  
21959                 *equiv++ = REG_DL;
21960                 *equiv++ = REG_DH;
21961                 *equiv++ = REG_EDX;
21962                 *equiv++ = REG_DXAX;
21963                 *equiv++ = REG_EDXEAX;
21964                 break;
21965         case REG_SI:  
21966                 *equiv++ = REG_ESI;
21967                 break;
21968         case REG_DI:
21969                 *equiv++ = REG_EDI;
21970                 break;
21971         case REG_BP:
21972                 *equiv++ = REG_EBP;
21973                 break;
21974         case REG_SP:
21975                 *equiv++ = REG_ESP;
21976                 break;
21977         case REG_EAX:
21978                 *equiv++ = REG_AL;
21979                 *equiv++ = REG_AH;
21980                 *equiv++ = REG_AX;
21981                 *equiv++ = REG_DXAX;
21982                 *equiv++ = REG_EDXEAX;
21983                 break;
21984         case REG_EBX:
21985                 *equiv++ = REG_BL;
21986                 *equiv++ = REG_BH;
21987                 *equiv++ = REG_BX;
21988                 break;
21989         case REG_ECX:
21990                 *equiv++ = REG_CL;
21991                 *equiv++ = REG_CH;
21992                 *equiv++ = REG_CX;
21993                 break;
21994         case REG_EDX:
21995                 *equiv++ = REG_DL;
21996                 *equiv++ = REG_DH;
21997                 *equiv++ = REG_DX;
21998                 *equiv++ = REG_DXAX;
21999                 *equiv++ = REG_EDXEAX;
22000                 break;
22001         case REG_ESI: 
22002                 *equiv++ = REG_SI;
22003                 break;
22004         case REG_EDI: 
22005                 *equiv++ = REG_DI;
22006                 break;
22007         case REG_EBP: 
22008                 *equiv++ = REG_BP;
22009                 break;
22010         case REG_ESP: 
22011                 *equiv++ = REG_SP;
22012                 break;
22013         case REG_DXAX: 
22014                 *equiv++ = REG_AL;
22015                 *equiv++ = REG_AH;
22016                 *equiv++ = REG_DL;
22017                 *equiv++ = REG_DH;
22018                 *equiv++ = REG_AX;
22019                 *equiv++ = REG_DX;
22020                 *equiv++ = REG_EAX;
22021                 *equiv++ = REG_EDX;
22022                 *equiv++ = REG_EDXEAX;
22023                 break;
22024         case REG_EDXEAX: 
22025                 *equiv++ = REG_AL;
22026                 *equiv++ = REG_AH;
22027                 *equiv++ = REG_DL;
22028                 *equiv++ = REG_DH;
22029                 *equiv++ = REG_AX;
22030                 *equiv++ = REG_DX;
22031                 *equiv++ = REG_EAX;
22032                 *equiv++ = REG_EDX;
22033                 *equiv++ = REG_DXAX;
22034                 break;
22035         }
22036         *equiv++ = REG_UNSET; 
22037 }
22038
22039 static unsigned arch_avail_mask(struct compile_state *state)
22040 {
22041         unsigned avail_mask;
22042         /* REGCM_GPR8 is not available */
22043         avail_mask = REGCM_GPR8_LO | REGCM_GPR16_8 | REGCM_GPR16 | 
22044                 REGCM_GPR32 | REGCM_GPR32_8 | 
22045                 REGCM_DIVIDEND32 | REGCM_DIVIDEND64 |
22046                 REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8 | REGCM_FLAGS;
22047         if (state->arch->features & X86_MMX_REGS) {
22048                 avail_mask |= REGCM_MMX;
22049         }
22050         if (state->arch->features & X86_XMM_REGS) {
22051                 avail_mask |= REGCM_XMM;
22052         }
22053         return avail_mask;
22054 }
22055
22056 static unsigned arch_regcm_normalize(struct compile_state *state, unsigned regcm)
22057 {
22058         unsigned mask, result;
22059         int class, class2;
22060         result = regcm;
22061
22062         for(class = 0, mask = 1; mask; mask <<= 1, class++) {
22063                 if ((result & mask) == 0) {
22064                         continue;
22065                 }
22066                 if (class > LAST_REGC) {
22067                         result &= ~mask;
22068                 }
22069                 for(class2 = 0; class2 <= LAST_REGC; class2++) {
22070                         if ((regcm_bound[class2].first >= regcm_bound[class].first) &&
22071                                 (regcm_bound[class2].last <= regcm_bound[class].last)) {
22072                                 result |= (1 << class2);
22073                         }
22074                 }
22075         }
22076         result &= arch_avail_mask(state);
22077         return result;
22078 }
22079
22080 static unsigned arch_regcm_reg_normalize(struct compile_state *state, unsigned regcm)
22081 {
22082         /* Like arch_regcm_normalize except immediate register classes are excluded */
22083         regcm = arch_regcm_normalize(state, regcm);
22084         /* Remove the immediate register classes */
22085         regcm &= ~(REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8);
22086         return regcm;
22087         
22088 }
22089
22090 static unsigned arch_reg_regcm(struct compile_state *state, int reg)
22091 {
22092         unsigned mask;
22093         int class;
22094         mask = 0;
22095         for(class = 0; class <= LAST_REGC; class++) {
22096                 if ((reg >= regcm_bound[class].first) &&
22097                         (reg <= regcm_bound[class].last)) {
22098                         mask |= (1 << class);
22099                 }
22100         }
22101         if (!mask) {
22102                 internal_error(state, 0, "reg %d not in any class", reg);
22103         }
22104         return mask;
22105 }
22106
22107 static struct reg_info arch_reg_constraint(
22108         struct compile_state *state, struct type *type, const char *constraint)
22109 {
22110         static const struct {
22111                 char class;
22112                 unsigned int mask;
22113                 unsigned int reg;
22114         } constraints[] = {
22115                 { 'r', REGCM_GPR32,   REG_UNSET },
22116                 { 'g', REGCM_GPR32,   REG_UNSET },
22117                 { 'p', REGCM_GPR32,   REG_UNSET },
22118                 { 'q', REGCM_GPR8_LO, REG_UNSET },
22119                 { 'Q', REGCM_GPR32_8, REG_UNSET },
22120                 { 'x', REGCM_XMM,     REG_UNSET },
22121                 { 'y', REGCM_MMX,     REG_UNSET },
22122                 { 'a', REGCM_GPR32,   REG_EAX },
22123                 { 'b', REGCM_GPR32,   REG_EBX },
22124                 { 'c', REGCM_GPR32,   REG_ECX },
22125                 { 'd', REGCM_GPR32,   REG_EDX },
22126                 { 'D', REGCM_GPR32,   REG_EDI },
22127                 { 'S', REGCM_GPR32,   REG_ESI },
22128                 { '\0', 0, REG_UNSET },
22129         };
22130         unsigned int regcm;
22131         unsigned int mask, reg;
22132         struct reg_info result;
22133         const char *ptr;
22134         regcm = arch_type_to_regcm(state, type);
22135         reg = REG_UNSET;
22136         mask = 0;
22137         for(ptr = constraint; *ptr; ptr++) {
22138                 int i;
22139                 if (*ptr ==  ' ') {
22140                         continue;
22141                 }
22142                 for(i = 0; constraints[i].class != '\0'; i++) {
22143                         if (constraints[i].class == *ptr) {
22144                                 break;
22145                         }
22146                 }
22147                 if (constraints[i].class == '\0') {
22148                         error(state, 0, "invalid register constraint ``%c''", *ptr);
22149                         break;
22150                 }
22151                 if ((constraints[i].mask & regcm) == 0) {
22152                         error(state, 0, "invalid register class %c specified",
22153                                 *ptr);
22154                 }
22155                 mask |= constraints[i].mask;
22156                 if (constraints[i].reg != REG_UNSET) {
22157                         if ((reg != REG_UNSET) && (reg != constraints[i].reg)) {
22158                                 error(state, 0, "Only one register may be specified");
22159                         }
22160                         reg = constraints[i].reg;
22161                 }
22162         }
22163         result.reg = reg;
22164         result.regcm = mask;
22165         return result;
22166 }
22167
22168 static struct reg_info arch_reg_clobber(
22169         struct compile_state *state, const char *clobber)
22170 {
22171         struct reg_info result;
22172         if (strcmp(clobber, "memory") == 0) {
22173                 result.reg = REG_UNSET;
22174                 result.regcm = 0;
22175         }
22176         else if (strcmp(clobber, "eax") == 0) {
22177                 result.reg = REG_EAX;
22178                 result.regcm = REGCM_GPR32;
22179         }
22180         else if (strcmp(clobber, "ebx") == 0) {
22181                 result.reg = REG_EBX;
22182                 result.regcm = REGCM_GPR32;
22183         }
22184         else if (strcmp(clobber, "ecx") == 0) {
22185                 result.reg = REG_ECX;
22186                 result.regcm = REGCM_GPR32;
22187         }
22188         else if (strcmp(clobber, "edx") == 0) {
22189                 result.reg = REG_EDX;
22190                 result.regcm = REGCM_GPR32;
22191         }
22192         else if (strcmp(clobber, "esi") == 0) {
22193                 result.reg = REG_ESI;
22194                 result.regcm = REGCM_GPR32;
22195         }
22196         else if (strcmp(clobber, "edi") == 0) {
22197                 result.reg = REG_EDI;
22198                 result.regcm = REGCM_GPR32;
22199         }
22200         else if (strcmp(clobber, "ebp") == 0) {
22201                 result.reg = REG_EBP;
22202                 result.regcm = REGCM_GPR32;
22203         }
22204         else if (strcmp(clobber, "esp") == 0) {
22205                 result.reg = REG_ESP;
22206                 result.regcm = REGCM_GPR32;
22207         }
22208         else if (strcmp(clobber, "cc") == 0) {
22209                 result.reg = REG_EFLAGS;
22210                 result.regcm = REGCM_FLAGS;
22211         }
22212         else if ((strncmp(clobber, "xmm", 3) == 0)  &&
22213                 octdigitp(clobber[3]) && (clobber[4] == '\0')) {
22214                 result.reg = REG_XMM0 + octdigval(clobber[3]);
22215                 result.regcm = REGCM_XMM;
22216         }
22217         else if ((strncmp(clobber, "mm", 2) == 0) &&
22218                 octdigitp(clobber[3]) && (clobber[4] == '\0')) {
22219                 result.reg = REG_MMX0 + octdigval(clobber[3]);
22220                 result.regcm = REGCM_MMX;
22221         }
22222         else {
22223                 error(state, 0, "unknown register name `%s' in asm",
22224                         clobber);
22225                 result.reg = REG_UNSET;
22226                 result.regcm = 0;
22227         }
22228         return result;
22229 }
22230
22231 static int do_select_reg(struct compile_state *state, 
22232         char *used, int reg, unsigned classes)
22233 {
22234         unsigned mask;
22235         if (used[reg]) {
22236                 return REG_UNSET;
22237         }
22238         mask = arch_reg_regcm(state, reg);
22239         return (classes & mask) ? reg : REG_UNSET;
22240 }
22241
22242 static int arch_select_free_register(
22243         struct compile_state *state, char *used, int classes)
22244 {
22245         /* Live ranges with the most neighbors are colored first.
22246          *
22247          * Generally it does not matter which colors are given
22248          * as the register allocator attempts to color live ranges
22249          * in an order where you are guaranteed not to run out of colors.
22250          *
22251          * Occasionally the register allocator cannot find an order
22252          * of register selection that will find a free color.  To
22253          * increase the odds the register allocator will work when
22254          * it guesses first give out registers from register classes
22255          * least likely to run out of registers.
22256          * 
22257          */
22258         int i, reg;
22259         reg = REG_UNSET;
22260         for(i = REGC_XMM_FIRST; (reg == REG_UNSET) && (i <= REGC_XMM_LAST); i++) {
22261                 reg = do_select_reg(state, used, i, classes);
22262         }
22263         for(i = REGC_MMX_FIRST; (reg == REG_UNSET) && (i <= REGC_MMX_LAST); i++) {
22264                 reg = do_select_reg(state, used, i, classes);
22265         }
22266         for(i = REGC_GPR32_LAST; (reg == REG_UNSET) && (i >= REGC_GPR32_FIRST); i--) {
22267                 reg = do_select_reg(state, used, i, classes);
22268         }
22269         for(i = REGC_GPR16_FIRST; (reg == REG_UNSET) && (i <= REGC_GPR16_LAST); i++) {
22270                 reg = do_select_reg(state, used, i, classes);
22271         }
22272         for(i = REGC_GPR8_FIRST; (reg == REG_UNSET) && (i <= REGC_GPR8_LAST); i++) {
22273                 reg = do_select_reg(state, used, i, classes);
22274         }
22275         for(i = REGC_GPR8_LO_FIRST; (reg == REG_UNSET) && (i <= REGC_GPR8_LO_LAST); i++) {
22276                 reg = do_select_reg(state, used, i, classes);
22277         }
22278         for(i = REGC_DIVIDEND32_FIRST; (reg == REG_UNSET) && (i <= REGC_DIVIDEND32_LAST); i++) {
22279                 reg = do_select_reg(state, used, i, classes);
22280         }
22281         for(i = REGC_DIVIDEND64_FIRST; (reg == REG_UNSET) && (i <= REGC_DIVIDEND64_LAST); i++) {
22282                 reg = do_select_reg(state, used, i, classes);
22283         }
22284         for(i = REGC_FLAGS_FIRST; (reg == REG_UNSET) && (i <= REGC_FLAGS_LAST); i++) {
22285                 reg = do_select_reg(state, used, i, classes);
22286         }
22287         return reg;
22288 }
22289
22290
22291 static unsigned arch_type_to_regcm(struct compile_state *state, struct type *type) 
22292 {
22293 #warning "FIXME force types smaller (if legal) before I get here"
22294         unsigned mask;
22295         mask = 0;
22296         switch(type->type & TYPE_MASK) {
22297         case TYPE_ARRAY:
22298         case TYPE_VOID: 
22299                 mask = 0; 
22300                 break;
22301         case TYPE_CHAR:
22302         case TYPE_UCHAR:
22303                 mask = REGCM_GPR8 | REGCM_GPR8_LO |
22304                         REGCM_GPR16 | REGCM_GPR16_8 | 
22305                         REGCM_GPR32 | REGCM_GPR32_8 |
22306                         REGCM_DIVIDEND32 | REGCM_DIVIDEND64 |
22307                         REGCM_MMX | REGCM_XMM |
22308                         REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8;
22309                 break;
22310         case TYPE_SHORT:
22311         case TYPE_USHORT:
22312                 mask =  REGCM_GPR16 | REGCM_GPR16_8 |
22313                         REGCM_GPR32 | REGCM_GPR32_8 |
22314                         REGCM_DIVIDEND32 | REGCM_DIVIDEND64 |
22315                         REGCM_MMX | REGCM_XMM |
22316                         REGCM_IMM32 | REGCM_IMM16;
22317                 break;
22318         case TYPE_ENUM:
22319         case TYPE_INT:
22320         case TYPE_UINT:
22321         case TYPE_LONG:
22322         case TYPE_ULONG:
22323         case TYPE_POINTER:
22324                 mask =  REGCM_GPR32 | REGCM_GPR32_8 |
22325                         REGCM_DIVIDEND32 | REGCM_DIVIDEND64 |
22326                         REGCM_MMX | REGCM_XMM |
22327                         REGCM_IMM32;
22328                 break;
22329         case TYPE_JOIN:
22330         case TYPE_UNION:
22331                 mask = arch_type_to_regcm(state, type->left);
22332                 break;
22333         case TYPE_OVERLAP:
22334                 mask = arch_type_to_regcm(state, type->left) &
22335                         arch_type_to_regcm(state, type->right);
22336                 break;
22337         case TYPE_BITFIELD:
22338                 mask = arch_type_to_regcm(state, type->left);
22339                 break;
22340         default:
22341                 fprintf(state->errout, "type: ");
22342                 name_of(state->errout, type);
22343                 fprintf(state->errout, "\n");
22344                 internal_error(state, 0, "no register class for type");
22345                 break;
22346         }
22347         mask = arch_regcm_normalize(state, mask);
22348         return mask;
22349 }
22350
22351 static int is_imm32(struct triple *imm)
22352 {
22353         return ((imm->op == OP_INTCONST) && (imm->u.cval <= 0xffffffffUL)) ||
22354                 (imm->op == OP_ADDRCONST);
22355         
22356 }
22357 static int is_imm16(struct triple *imm)
22358 {
22359         return ((imm->op == OP_INTCONST) && (imm->u.cval <= 0xffff));
22360 }
22361 static int is_imm8(struct triple *imm)
22362 {
22363         return ((imm->op == OP_INTCONST) && (imm->u.cval <= 0xff));
22364 }
22365
22366 static int get_imm32(struct triple *ins, struct triple **expr)
22367 {
22368         struct triple *imm;
22369         imm = *expr;
22370         while(imm->op == OP_COPY) {
22371                 imm = RHS(imm, 0);
22372         }
22373         if (!is_imm32(imm)) {
22374                 return 0;
22375         }
22376         unuse_triple(*expr, ins);
22377         use_triple(imm, ins);
22378         *expr = imm;
22379         return 1;
22380 }
22381
22382 static int get_imm8(struct triple *ins, struct triple **expr)
22383 {
22384         struct triple *imm;
22385         imm = *expr;
22386         while(imm->op == OP_COPY) {
22387                 imm = RHS(imm, 0);
22388         }
22389         if (!is_imm8(imm)) {
22390                 return 0;
22391         }
22392         unuse_triple(*expr, ins);
22393         use_triple(imm, ins);
22394         *expr = imm;
22395         return 1;
22396 }
22397
22398 #define TEMPLATE_NOP           0
22399 #define TEMPLATE_INTCONST8     1
22400 #define TEMPLATE_INTCONST32    2
22401 #define TEMPLATE_UNKNOWNVAL    3
22402 #define TEMPLATE_COPY8_REG     5
22403 #define TEMPLATE_COPY16_REG    6
22404 #define TEMPLATE_COPY32_REG    7
22405 #define TEMPLATE_COPY_IMM8     8
22406 #define TEMPLATE_COPY_IMM16    9
22407 #define TEMPLATE_COPY_IMM32   10
22408 #define TEMPLATE_PHI8         11
22409 #define TEMPLATE_PHI16        12
22410 #define TEMPLATE_PHI32        13
22411 #define TEMPLATE_STORE8       14
22412 #define TEMPLATE_STORE16      15
22413 #define TEMPLATE_STORE32      16
22414 #define TEMPLATE_LOAD8        17
22415 #define TEMPLATE_LOAD16       18
22416 #define TEMPLATE_LOAD32       19
22417 #define TEMPLATE_BINARY8_REG  20
22418 #define TEMPLATE_BINARY16_REG 21
22419 #define TEMPLATE_BINARY32_REG 22
22420 #define TEMPLATE_BINARY8_IMM  23
22421 #define TEMPLATE_BINARY16_IMM 24
22422 #define TEMPLATE_BINARY32_IMM 25
22423 #define TEMPLATE_SL8_CL       26
22424 #define TEMPLATE_SL16_CL      27
22425 #define TEMPLATE_SL32_CL      28
22426 #define TEMPLATE_SL8_IMM      29
22427 #define TEMPLATE_SL16_IMM     30
22428 #define TEMPLATE_SL32_IMM     31
22429 #define TEMPLATE_UNARY8       32
22430 #define TEMPLATE_UNARY16      33
22431 #define TEMPLATE_UNARY32      34
22432 #define TEMPLATE_CMP8_REG     35
22433 #define TEMPLATE_CMP16_REG    36
22434 #define TEMPLATE_CMP32_REG    37
22435 #define TEMPLATE_CMP8_IMM     38
22436 #define TEMPLATE_CMP16_IMM    39
22437 #define TEMPLATE_CMP32_IMM    40
22438 #define TEMPLATE_TEST8        41
22439 #define TEMPLATE_TEST16       42
22440 #define TEMPLATE_TEST32       43
22441 #define TEMPLATE_SET          44
22442 #define TEMPLATE_JMP          45
22443 #define TEMPLATE_RET          46
22444 #define TEMPLATE_INB_DX       47
22445 #define TEMPLATE_INB_IMM      48
22446 #define TEMPLATE_INW_DX       49
22447 #define TEMPLATE_INW_IMM      50
22448 #define TEMPLATE_INL_DX       51
22449 #define TEMPLATE_INL_IMM      52
22450 #define TEMPLATE_OUTB_DX      53
22451 #define TEMPLATE_OUTB_IMM     54
22452 #define TEMPLATE_OUTW_DX      55
22453 #define TEMPLATE_OUTW_IMM     56
22454 #define TEMPLATE_OUTL_DX      57
22455 #define TEMPLATE_OUTL_IMM     58
22456 #define TEMPLATE_BSF          59
22457 #define TEMPLATE_RDMSR        60
22458 #define TEMPLATE_WRMSR        61
22459 #define TEMPLATE_UMUL8        62
22460 #define TEMPLATE_UMUL16       63
22461 #define TEMPLATE_UMUL32       64
22462 #define TEMPLATE_DIV8         65
22463 #define TEMPLATE_DIV16        66
22464 #define TEMPLATE_DIV32        67
22465 #define LAST_TEMPLATE       TEMPLATE_DIV32
22466 #if LAST_TEMPLATE >= MAX_TEMPLATES
22467 #error "MAX_TEMPLATES to low"
22468 #endif
22469
22470 #define COPY8_REGCM     (REGCM_DIVIDEND64 | REGCM_DIVIDEND32 | REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO | REGCM_MMX | REGCM_XMM)
22471 #define COPY16_REGCM    (REGCM_DIVIDEND64 | REGCM_DIVIDEND32 | REGCM_GPR32 | REGCM_GPR16 | REGCM_MMX | REGCM_XMM)  
22472 #define COPY32_REGCM    (REGCM_DIVIDEND64 | REGCM_DIVIDEND32 | REGCM_GPR32 | REGCM_MMX | REGCM_XMM)
22473
22474
22475 static struct ins_template templates[] = {
22476         [TEMPLATE_NOP]      = {
22477                 .lhs = { 
22478                         [ 0] = { REG_UNNEEDED, REGCM_IMMALL },
22479                         [ 1] = { REG_UNNEEDED, REGCM_IMMALL },
22480                         [ 2] = { REG_UNNEEDED, REGCM_IMMALL },
22481                         [ 3] = { REG_UNNEEDED, REGCM_IMMALL },
22482                         [ 4] = { REG_UNNEEDED, REGCM_IMMALL },
22483                         [ 5] = { REG_UNNEEDED, REGCM_IMMALL },
22484                         [ 6] = { REG_UNNEEDED, REGCM_IMMALL },
22485                         [ 7] = { REG_UNNEEDED, REGCM_IMMALL },
22486                         [ 8] = { REG_UNNEEDED, REGCM_IMMALL },
22487                         [ 9] = { REG_UNNEEDED, REGCM_IMMALL },
22488                         [10] = { REG_UNNEEDED, REGCM_IMMALL },
22489                         [11] = { REG_UNNEEDED, REGCM_IMMALL },
22490                         [12] = { REG_UNNEEDED, REGCM_IMMALL },
22491                         [13] = { REG_UNNEEDED, REGCM_IMMALL },
22492                         [14] = { REG_UNNEEDED, REGCM_IMMALL },
22493                         [15] = { REG_UNNEEDED, REGCM_IMMALL },
22494                         [16] = { REG_UNNEEDED, REGCM_IMMALL },
22495                         [17] = { REG_UNNEEDED, REGCM_IMMALL },
22496                         [18] = { REG_UNNEEDED, REGCM_IMMALL },
22497                         [19] = { REG_UNNEEDED, REGCM_IMMALL },
22498                         [20] = { REG_UNNEEDED, REGCM_IMMALL },
22499                         [21] = { REG_UNNEEDED, REGCM_IMMALL },
22500                         [22] = { REG_UNNEEDED, REGCM_IMMALL },
22501                         [23] = { REG_UNNEEDED, REGCM_IMMALL },
22502                         [24] = { REG_UNNEEDED, REGCM_IMMALL },
22503                         [25] = { REG_UNNEEDED, REGCM_IMMALL },
22504                         [26] = { REG_UNNEEDED, REGCM_IMMALL },
22505                         [27] = { REG_UNNEEDED, REGCM_IMMALL },
22506                         [28] = { REG_UNNEEDED, REGCM_IMMALL },
22507                         [29] = { REG_UNNEEDED, REGCM_IMMALL },
22508                         [30] = { REG_UNNEEDED, REGCM_IMMALL },
22509                         [31] = { REG_UNNEEDED, REGCM_IMMALL },
22510                         [32] = { REG_UNNEEDED, REGCM_IMMALL },
22511                         [33] = { REG_UNNEEDED, REGCM_IMMALL },
22512                         [34] = { REG_UNNEEDED, REGCM_IMMALL },
22513                         [35] = { REG_UNNEEDED, REGCM_IMMALL },
22514                         [36] = { REG_UNNEEDED, REGCM_IMMALL },
22515                         [37] = { REG_UNNEEDED, REGCM_IMMALL },
22516                         [38] = { REG_UNNEEDED, REGCM_IMMALL },
22517                         [39] = { REG_UNNEEDED, REGCM_IMMALL },
22518                         [40] = { REG_UNNEEDED, REGCM_IMMALL },
22519                         [41] = { REG_UNNEEDED, REGCM_IMMALL },
22520                         [42] = { REG_UNNEEDED, REGCM_IMMALL },
22521                         [43] = { REG_UNNEEDED, REGCM_IMMALL },
22522                         [44] = { REG_UNNEEDED, REGCM_IMMALL },
22523                         [45] = { REG_UNNEEDED, REGCM_IMMALL },
22524                         [46] = { REG_UNNEEDED, REGCM_IMMALL },
22525                         [47] = { REG_UNNEEDED, REGCM_IMMALL },
22526                         [48] = { REG_UNNEEDED, REGCM_IMMALL },
22527                         [49] = { REG_UNNEEDED, REGCM_IMMALL },
22528                         [50] = { REG_UNNEEDED, REGCM_IMMALL },
22529                         [51] = { REG_UNNEEDED, REGCM_IMMALL },
22530                         [52] = { REG_UNNEEDED, REGCM_IMMALL },
22531                         [53] = { REG_UNNEEDED, REGCM_IMMALL },
22532                         [54] = { REG_UNNEEDED, REGCM_IMMALL },
22533                         [55] = { REG_UNNEEDED, REGCM_IMMALL },
22534                         [56] = { REG_UNNEEDED, REGCM_IMMALL },
22535                         [57] = { REG_UNNEEDED, REGCM_IMMALL },
22536                         [58] = { REG_UNNEEDED, REGCM_IMMALL },
22537                         [59] = { REG_UNNEEDED, REGCM_IMMALL },
22538                         [60] = { REG_UNNEEDED, REGCM_IMMALL },
22539                         [61] = { REG_UNNEEDED, REGCM_IMMALL },
22540                         [62] = { REG_UNNEEDED, REGCM_IMMALL },
22541                         [63] = { REG_UNNEEDED, REGCM_IMMALL },
22542                 },
22543         },
22544         [TEMPLATE_INTCONST8] = { 
22545                 .lhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
22546         },
22547         [TEMPLATE_INTCONST32] = { 
22548                 .lhs = { [0] = { REG_UNNEEDED, REGCM_IMM32 } },
22549         },
22550         [TEMPLATE_UNKNOWNVAL] = {
22551                 .lhs = { [0] = { REG_UNSET, COPY32_REGCM } },
22552         },
22553         [TEMPLATE_COPY8_REG] = {
22554                 .lhs = { [0] = { REG_UNSET, COPY8_REGCM } },
22555                 .rhs = { [0] = { REG_UNSET, COPY8_REGCM }  },
22556         },
22557         [TEMPLATE_COPY16_REG] = {
22558                 .lhs = { [0] = { REG_UNSET, COPY16_REGCM } },
22559                 .rhs = { [0] = { REG_UNSET, COPY16_REGCM }  },
22560         },
22561         [TEMPLATE_COPY32_REG] = {
22562                 .lhs = { [0] = { REG_UNSET, COPY32_REGCM } },
22563                 .rhs = { [0] = { REG_UNSET, COPY32_REGCM }  },
22564         },
22565         [TEMPLATE_COPY_IMM8] = {
22566                 .lhs = { [0] = { REG_UNSET, COPY8_REGCM } },
22567                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
22568         },
22569         [TEMPLATE_COPY_IMM16] = {
22570                 .lhs = { [0] = { REG_UNSET, COPY16_REGCM } },
22571                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM16 | REGCM_IMM8 } },
22572         },
22573         [TEMPLATE_COPY_IMM32] = {
22574                 .lhs = { [0] = { REG_UNSET, COPY32_REGCM } },
22575                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8 } },
22576         },
22577         [TEMPLATE_PHI8] = { 
22578                 .lhs = { [0] = { REG_VIRT0, COPY8_REGCM } },
22579                 .rhs = { [0] = { REG_VIRT0, COPY8_REGCM } },
22580         },
22581         [TEMPLATE_PHI16] = { 
22582                 .lhs = { [0] = { REG_VIRT0, COPY16_REGCM } },
22583                 .rhs = { [0] = { REG_VIRT0, COPY16_REGCM } }, 
22584         },
22585         [TEMPLATE_PHI32] = { 
22586                 .lhs = { [0] = { REG_VIRT0, COPY32_REGCM } },
22587                 .rhs = { [0] = { REG_VIRT0, COPY32_REGCM } }, 
22588         },
22589         [TEMPLATE_STORE8] = {
22590                 .rhs = { 
22591                         [0] = { REG_UNSET, REGCM_GPR32 },
22592                         [1] = { REG_UNSET, REGCM_GPR8_LO },
22593                 },
22594         },
22595         [TEMPLATE_STORE16] = {
22596                 .rhs = { 
22597                         [0] = { REG_UNSET, REGCM_GPR32 },
22598                         [1] = { REG_UNSET, REGCM_GPR16 },
22599                 },
22600         },
22601         [TEMPLATE_STORE32] = {
22602                 .rhs = { 
22603                         [0] = { REG_UNSET, REGCM_GPR32 },
22604                         [1] = { REG_UNSET, REGCM_GPR32 },
22605                 },
22606         },
22607         [TEMPLATE_LOAD8] = {
22608                 .lhs = { [0] = { REG_UNSET, REGCM_GPR8_LO } },
22609                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
22610         },
22611         [TEMPLATE_LOAD16] = {
22612                 .lhs = { [0] = { REG_UNSET, REGCM_GPR16 } },
22613                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
22614         },
22615         [TEMPLATE_LOAD32] = {
22616                 .lhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
22617                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
22618         },
22619         [TEMPLATE_BINARY8_REG] = {
22620                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
22621                 .rhs = { 
22622                         [0] = { REG_VIRT0, REGCM_GPR8_LO },
22623                         [1] = { REG_UNSET, REGCM_GPR8_LO },
22624                 },
22625         },
22626         [TEMPLATE_BINARY16_REG] = {
22627                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
22628                 .rhs = { 
22629                         [0] = { REG_VIRT0, REGCM_GPR16 },
22630                         [1] = { REG_UNSET, REGCM_GPR16 },
22631                 },
22632         },
22633         [TEMPLATE_BINARY32_REG] = {
22634                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
22635                 .rhs = { 
22636                         [0] = { REG_VIRT0, REGCM_GPR32 },
22637                         [1] = { REG_UNSET, REGCM_GPR32 },
22638                 },
22639         },
22640         [TEMPLATE_BINARY8_IMM] = {
22641                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
22642                 .rhs = { 
22643                         [0] = { REG_VIRT0,    REGCM_GPR8_LO },
22644                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
22645                 },
22646         },
22647         [TEMPLATE_BINARY16_IMM] = {
22648                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
22649                 .rhs = { 
22650                         [0] = { REG_VIRT0,    REGCM_GPR16 },
22651                         [1] = { REG_UNNEEDED, REGCM_IMM16 },
22652                 },
22653         },
22654         [TEMPLATE_BINARY32_IMM] = {
22655                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
22656                 .rhs = { 
22657                         [0] = { REG_VIRT0,    REGCM_GPR32 },
22658                         [1] = { REG_UNNEEDED, REGCM_IMM32 },
22659                 },
22660         },
22661         [TEMPLATE_SL8_CL] = {
22662                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
22663                 .rhs = { 
22664                         [0] = { REG_VIRT0, REGCM_GPR8_LO },
22665                         [1] = { REG_CL, REGCM_GPR8_LO },
22666                 },
22667         },
22668         [TEMPLATE_SL16_CL] = {
22669                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
22670                 .rhs = { 
22671                         [0] = { REG_VIRT0, REGCM_GPR16 },
22672                         [1] = { REG_CL, REGCM_GPR8_LO },
22673                 },
22674         },
22675         [TEMPLATE_SL32_CL] = {
22676                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
22677                 .rhs = { 
22678                         [0] = { REG_VIRT0, REGCM_GPR32 },
22679                         [1] = { REG_CL, REGCM_GPR8_LO },
22680                 },
22681         },
22682         [TEMPLATE_SL8_IMM] = {
22683                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
22684                 .rhs = { 
22685                         [0] = { REG_VIRT0,    REGCM_GPR8_LO },
22686                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
22687                 },
22688         },
22689         [TEMPLATE_SL16_IMM] = {
22690                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
22691                 .rhs = { 
22692                         [0] = { REG_VIRT0,    REGCM_GPR16 },
22693                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
22694                 },
22695         },
22696         [TEMPLATE_SL32_IMM] = {
22697                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
22698                 .rhs = { 
22699                         [0] = { REG_VIRT0,    REGCM_GPR32 },
22700                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
22701                 },
22702         },
22703         [TEMPLATE_UNARY8] = {
22704                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
22705                 .rhs = { [0] = { REG_VIRT0, REGCM_GPR8_LO } },
22706         },
22707         [TEMPLATE_UNARY16] = {
22708                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
22709                 .rhs = { [0] = { REG_VIRT0, REGCM_GPR16 } },
22710         },
22711         [TEMPLATE_UNARY32] = {
22712                 .lhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
22713                 .rhs = { [0] = { REG_VIRT0, REGCM_GPR32 } },
22714         },
22715         [TEMPLATE_CMP8_REG] = {
22716                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22717                 .rhs = {
22718                         [0] = { REG_UNSET, REGCM_GPR8_LO },
22719                         [1] = { REG_UNSET, REGCM_GPR8_LO },
22720                 },
22721         },
22722         [TEMPLATE_CMP16_REG] = {
22723                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22724                 .rhs = {
22725                         [0] = { REG_UNSET, REGCM_GPR16 },
22726                         [1] = { REG_UNSET, REGCM_GPR16 },
22727                 },
22728         },
22729         [TEMPLATE_CMP32_REG] = {
22730                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22731                 .rhs = {
22732                         [0] = { REG_UNSET, REGCM_GPR32 },
22733                         [1] = { REG_UNSET, REGCM_GPR32 },
22734                 },
22735         },
22736         [TEMPLATE_CMP8_IMM] = {
22737                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22738                 .rhs = {
22739                         [0] = { REG_UNSET, REGCM_GPR8_LO },
22740                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
22741                 },
22742         },
22743         [TEMPLATE_CMP16_IMM] = {
22744                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22745                 .rhs = {
22746                         [0] = { REG_UNSET, REGCM_GPR16 },
22747                         [1] = { REG_UNNEEDED, REGCM_IMM16 },
22748                 },
22749         },
22750         [TEMPLATE_CMP32_IMM] = {
22751                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22752                 .rhs = {
22753                         [0] = { REG_UNSET, REGCM_GPR32 },
22754                         [1] = { REG_UNNEEDED, REGCM_IMM32 },
22755                 },
22756         },
22757         [TEMPLATE_TEST8] = {
22758                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22759                 .rhs = { [0] = { REG_UNSET, REGCM_GPR8_LO } },
22760         },
22761         [TEMPLATE_TEST16] = {
22762                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22763                 .rhs = { [0] = { REG_UNSET, REGCM_GPR16 } },
22764         },
22765         [TEMPLATE_TEST32] = {
22766                 .lhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22767                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
22768         },
22769         [TEMPLATE_SET] = {
22770                 .lhs = { [0] = { REG_UNSET, REGCM_GPR8_LO } },
22771                 .rhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22772         },
22773         [TEMPLATE_JMP] = {
22774                 .rhs = { [0] = { REG_EFLAGS, REGCM_FLAGS } },
22775         },
22776         [TEMPLATE_RET] = {
22777                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
22778         },
22779         [TEMPLATE_INB_DX] = {
22780                 .lhs = { [0] = { REG_AL,  REGCM_GPR8_LO } },  
22781                 .rhs = { [0] = { REG_DX, REGCM_GPR16 } },
22782         },
22783         [TEMPLATE_INB_IMM] = {
22784                 .lhs = { [0] = { REG_AL,  REGCM_GPR8_LO } },  
22785                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
22786         },
22787         [TEMPLATE_INW_DX]  = { 
22788                 .lhs = { [0] = { REG_AX,  REGCM_GPR16 } }, 
22789                 .rhs = { [0] = { REG_DX, REGCM_GPR16 } },
22790         },
22791         [TEMPLATE_INW_IMM] = { 
22792                 .lhs = { [0] = { REG_AX,  REGCM_GPR16 } }, 
22793                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
22794         },
22795         [TEMPLATE_INL_DX]  = {
22796                 .lhs = { [0] = { REG_EAX, REGCM_GPR32 } },
22797                 .rhs = { [0] = { REG_DX, REGCM_GPR16 } },
22798         },
22799         [TEMPLATE_INL_IMM] = {
22800                 .lhs = { [0] = { REG_EAX, REGCM_GPR32 } },
22801                 .rhs = { [0] = { REG_UNNEEDED, REGCM_IMM8 } },
22802         },
22803         [TEMPLATE_OUTB_DX] = { 
22804                 .rhs = {
22805                         [0] = { REG_AL,  REGCM_GPR8_LO },
22806                         [1] = { REG_DX, REGCM_GPR16 },
22807                 },
22808         },
22809         [TEMPLATE_OUTB_IMM] = { 
22810                 .rhs = {
22811                         [0] = { REG_AL,  REGCM_GPR8_LO },  
22812                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
22813                 },
22814         },
22815         [TEMPLATE_OUTW_DX] = { 
22816                 .rhs = {
22817                         [0] = { REG_AX,  REGCM_GPR16 },
22818                         [1] = { REG_DX, REGCM_GPR16 },
22819                 },
22820         },
22821         [TEMPLATE_OUTW_IMM] = {
22822                 .rhs = {
22823                         [0] = { REG_AX,  REGCM_GPR16 }, 
22824                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
22825                 },
22826         },
22827         [TEMPLATE_OUTL_DX] = { 
22828                 .rhs = {
22829                         [0] = { REG_EAX, REGCM_GPR32 },
22830                         [1] = { REG_DX, REGCM_GPR16 },
22831                 },
22832         },
22833         [TEMPLATE_OUTL_IMM] = { 
22834                 .rhs = {
22835                         [0] = { REG_EAX, REGCM_GPR32 }, 
22836                         [1] = { REG_UNNEEDED, REGCM_IMM8 },
22837                 },
22838         },
22839         [TEMPLATE_BSF] = {
22840                 .lhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
22841                 .rhs = { [0] = { REG_UNSET, REGCM_GPR32 } },
22842         },
22843         [TEMPLATE_RDMSR] = {
22844                 .lhs = { 
22845                         [0] = { REG_EAX, REGCM_GPR32 },
22846                         [1] = { REG_EDX, REGCM_GPR32 },
22847                 },
22848                 .rhs = { [0] = { REG_ECX, REGCM_GPR32 } },
22849         },
22850         [TEMPLATE_WRMSR] = {
22851                 .rhs = {
22852                         [0] = { REG_ECX, REGCM_GPR32 },
22853                         [1] = { REG_EAX, REGCM_GPR32 },
22854                         [2] = { REG_EDX, REGCM_GPR32 },
22855                 },
22856         },
22857         [TEMPLATE_UMUL8] = {
22858                 .lhs = { [0] = { REG_AX, REGCM_GPR16 } },
22859                 .rhs = { 
22860                         [0] = { REG_AL, REGCM_GPR8_LO },
22861                         [1] = { REG_UNSET, REGCM_GPR8_LO },
22862                 },
22863         },
22864         [TEMPLATE_UMUL16] = {
22865                 .lhs = { [0] = { REG_DXAX, REGCM_DIVIDEND32 } },
22866                 .rhs = { 
22867                         [0] = { REG_AX, REGCM_GPR16 },
22868                         [1] = { REG_UNSET, REGCM_GPR16 },
22869                 },
22870         },
22871         [TEMPLATE_UMUL32] = {
22872                 .lhs = { [0] = { REG_EDXEAX, REGCM_DIVIDEND64 } },
22873                 .rhs = { 
22874                         [0] = { REG_EAX, REGCM_GPR32 },
22875                         [1] = { REG_UNSET, REGCM_GPR32 },
22876                 },
22877         },
22878         [TEMPLATE_DIV8] = {
22879                 .lhs = { 
22880                         [0] = { REG_AL, REGCM_GPR8_LO },
22881                         [1] = { REG_AH, REGCM_GPR8 },
22882                 },
22883                 .rhs = {
22884                         [0] = { REG_AX, REGCM_GPR16 },
22885                         [1] = { REG_UNSET, REGCM_GPR8_LO },
22886                 },
22887         },
22888         [TEMPLATE_DIV16] = {
22889                 .lhs = { 
22890                         [0] = { REG_AX, REGCM_GPR16 },
22891                         [1] = { REG_DX, REGCM_GPR16 },
22892                 },
22893                 .rhs = {
22894                         [0] = { REG_DXAX, REGCM_DIVIDEND32 },
22895                         [1] = { REG_UNSET, REGCM_GPR16 },
22896                 },
22897         },
22898         [TEMPLATE_DIV32] = {
22899                 .lhs = { 
22900                         [0] = { REG_EAX, REGCM_GPR32 },
22901                         [1] = { REG_EDX, REGCM_GPR32 },
22902                 },
22903                 .rhs = {
22904                         [0] = { REG_EDXEAX, REGCM_DIVIDEND64 },
22905                         [1] = { REG_UNSET, REGCM_GPR32 },
22906                 },
22907         },
22908 };
22909
22910 static void fixup_branch(struct compile_state *state,
22911         struct triple *branch, int jmp_op, int cmp_op, struct type *cmp_type,
22912         struct triple *left, struct triple *right)
22913 {
22914         struct triple *test;
22915         if (!left) {
22916                 internal_error(state, branch, "no branch test?");
22917         }
22918         test = pre_triple(state, branch,
22919                 cmp_op, cmp_type, left, right);
22920         test->template_id = TEMPLATE_TEST32; 
22921         if (cmp_op == OP_CMP) {
22922                 test->template_id = TEMPLATE_CMP32_REG;
22923                 if (get_imm32(test, &RHS(test, 1))) {
22924                         test->template_id = TEMPLATE_CMP32_IMM;
22925                 }
22926         }
22927         use_triple(RHS(test, 0), test);
22928         use_triple(RHS(test, 1), test);
22929         unuse_triple(RHS(branch, 0), branch);
22930         RHS(branch, 0) = test;
22931         branch->op = jmp_op;
22932         branch->template_id = TEMPLATE_JMP;
22933         use_triple(RHS(branch, 0), branch);
22934 }
22935
22936 static void fixup_branches(struct compile_state *state,
22937         struct triple *cmp, struct triple *use, int jmp_op)
22938 {
22939         struct triple_set *entry, *next;
22940         for(entry = use->use; entry; entry = next) {
22941                 next = entry->next;
22942                 if (entry->member->op == OP_COPY) {
22943                         fixup_branches(state, cmp, entry->member, jmp_op);
22944                 }
22945                 else if (entry->member->op == OP_CBRANCH) {
22946                         struct triple *branch;
22947                         struct triple *left, *right;
22948                         left = right = 0;
22949                         left = RHS(cmp, 0);
22950                         if (cmp->rhs > 1) {
22951                                 right = RHS(cmp, 1);
22952                         }
22953                         branch = entry->member;
22954                         fixup_branch(state, branch, jmp_op, 
22955                                 cmp->op, cmp->type, left, right);
22956                 }
22957         }
22958 }
22959
22960 static void bool_cmp(struct compile_state *state, 
22961         struct triple *ins, int cmp_op, int jmp_op, int set_op)
22962 {
22963         struct triple_set *entry, *next;
22964         struct triple *set, *convert;
22965
22966         /* Put a barrier up before the cmp which preceeds the
22967          * copy instruction.  If a set actually occurs this gives
22968          * us a chance to move variables in registers out of the way.
22969          */
22970
22971         /* Modify the comparison operator */
22972         ins->op = cmp_op;
22973         ins->template_id = TEMPLATE_TEST32;
22974         if (cmp_op == OP_CMP) {
22975                 ins->template_id = TEMPLATE_CMP32_REG;
22976                 if (get_imm32(ins, &RHS(ins, 1))) {
22977                         ins->template_id =  TEMPLATE_CMP32_IMM;
22978                 }
22979         }
22980         /* Generate the instruction sequence that will transform the
22981          * result of the comparison into a logical value.
22982          */
22983         set = post_triple(state, ins, set_op, &uchar_type, ins, 0);
22984         use_triple(ins, set);
22985         set->template_id = TEMPLATE_SET;
22986
22987         convert = set;
22988         if (!equiv_types(ins->type, set->type)) {
22989                 convert = post_triple(state, set, OP_CONVERT, ins->type, set, 0);
22990                 use_triple(set, convert);
22991                 convert->template_id = TEMPLATE_COPY32_REG;
22992         }
22993
22994         for(entry = ins->use; entry; entry = next) {
22995                 next = entry->next;
22996                 if (entry->member == set) {
22997                         continue;
22998                 }
22999                 replace_rhs_use(state, ins, convert, entry->member);
23000         }
23001         fixup_branches(state, ins, convert, jmp_op);
23002 }
23003
23004 struct reg_info arch_reg_lhs(struct compile_state *state, struct triple *ins, int index)
23005 {
23006         struct ins_template *template;
23007         struct reg_info result;
23008         int zlhs;
23009         if (ins->op == OP_PIECE) {
23010                 index = ins->u.cval;
23011                 ins = MISC(ins, 0);
23012         }
23013         zlhs = ins->lhs;
23014         if (triple_is_def(state, ins)) {
23015                 zlhs = 1;
23016         }
23017         if (index >= zlhs) {
23018                 internal_error(state, ins, "index %d out of range for %s",
23019                         index, tops(ins->op));
23020         }
23021         switch(ins->op) {
23022         case OP_ASM:
23023                 template = &ins->u.ainfo->tmpl;
23024                 break;
23025         default:
23026                 if (ins->template_id > LAST_TEMPLATE) {
23027                         internal_error(state, ins, "bad template number %d", 
23028                                 ins->template_id);
23029                 }
23030                 template = &templates[ins->template_id];
23031                 break;
23032         }
23033         result = template->lhs[index];
23034         result.regcm = arch_regcm_normalize(state, result.regcm);
23035         if (result.reg != REG_UNNEEDED) {
23036                 result.regcm &= ~(REGCM_IMM32 | REGCM_IMM16 | REGCM_IMM8);
23037         }
23038         if (result.regcm == 0) {
23039                 internal_error(state, ins, "lhs %d regcm == 0", index);
23040         }
23041         return result;
23042 }
23043
23044 struct reg_info arch_reg_rhs(struct compile_state *state, struct triple *ins, int index)
23045 {
23046         struct reg_info result;
23047         struct ins_template *template;
23048         if ((index > ins->rhs) ||
23049                 (ins->op == OP_PIECE)) {
23050                 internal_error(state, ins, "index %d out of range for %s\n",
23051                         index, tops(ins->op));
23052         }
23053         switch(ins->op) {
23054         case OP_ASM:
23055                 template = &ins->u.ainfo->tmpl;
23056                 break;
23057         case OP_PHI:
23058                 index = 0;
23059                 /* Fall through */
23060         default:
23061                 if (ins->template_id > LAST_TEMPLATE) {
23062                         internal_error(state, ins, "bad template number %d", 
23063                                 ins->template_id);
23064                 }
23065                 template = &templates[ins->template_id];
23066                 break;
23067         }
23068         result = template->rhs[index];
23069         result.regcm = arch_regcm_normalize(state, result.regcm);
23070         if (result.regcm == 0) {
23071                 internal_error(state, ins, "rhs %d regcm == 0", index);
23072         }
23073         return result;
23074 }
23075
23076 static struct triple *mod_div(struct compile_state *state,
23077         struct triple *ins, int div_op, int index)
23078 {
23079         struct triple *div, *piece0, *piece1;
23080         
23081         /* Generate the appropriate division instruction */
23082         div = post_triple(state, ins, div_op, ins->type, 0, 0);
23083         RHS(div, 0) = RHS(ins, 0);
23084         RHS(div, 1) = RHS(ins, 1);
23085         piece0 = LHS(div, 0);
23086         piece1 = LHS(div, 1);
23087         div->template_id  = TEMPLATE_DIV32;
23088         use_triple(RHS(div, 0), div);
23089         use_triple(RHS(div, 1), div);
23090         use_triple(LHS(div, 0), div);
23091         use_triple(LHS(div, 1), div);
23092
23093         /* Replate uses of ins with the appropriate piece of the div */
23094         propogate_use(state, ins, LHS(div, index));
23095         release_triple(state, ins);
23096
23097         /* Return the address of the next instruction */
23098         return piece1->next;
23099 }
23100
23101 static int noop_adecl(struct triple *adecl)
23102 {
23103         struct triple_set *use;
23104         /* It's a noop if it doesn't specify stoorage */
23105         if (adecl->lhs == 0) {
23106                 return 1;
23107         }
23108         /* Is the adecl used? If not it's a noop */
23109         for(use = adecl->use; use ; use = use->next) {
23110                 if ((use->member->op != OP_PIECE) ||
23111                         (MISC(use->member, 0) != adecl)) {
23112                         return 0;
23113                 }
23114         }
23115         return 1;
23116 }
23117
23118 static struct triple *x86_deposit(struct compile_state *state, struct triple *ins)
23119 {
23120         struct triple *mask, *nmask, *shift;
23121         struct triple *val, *val_mask, *val_shift;
23122         struct triple *targ, *targ_mask;
23123         struct triple *new;
23124         ulong_t the_mask, the_nmask;
23125
23126         targ = RHS(ins, 0);
23127         val = RHS(ins, 1);
23128
23129         /* Get constant for the mask value */
23130         the_mask = 1;
23131         the_mask <<= ins->u.bitfield.size;
23132         the_mask -= 1;
23133         the_mask <<= ins->u.bitfield.offset;
23134         mask = pre_triple(state, ins, OP_INTCONST, &uint_type, 0, 0);
23135         mask->u.cval = the_mask;
23136
23137         /* Get the inverted mask value */
23138         the_nmask = ~the_mask;
23139         nmask = pre_triple(state, ins, OP_INTCONST, &uint_type, 0, 0);
23140         nmask->u.cval = the_nmask;
23141
23142         /* Get constant for the shift value */
23143         shift = pre_triple(state, ins, OP_INTCONST, &uint_type, 0, 0);
23144         shift->u.cval = ins->u.bitfield.offset;
23145
23146         /* Shift and mask the source value */
23147         val_shift = val;
23148         if (shift->u.cval != 0) {
23149                 val_shift = pre_triple(state, ins, OP_SL, val->type, val, shift);
23150                 use_triple(val, val_shift);
23151                 use_triple(shift, val_shift);
23152         }
23153         val_mask = val_shift;
23154         if (is_signed(val->type)) {
23155                 val_mask = pre_triple(state, ins, OP_AND, val->type, val_shift, mask);
23156                 use_triple(val_shift, val_mask);
23157                 use_triple(mask, val_mask);
23158         }
23159
23160         /* Mask the target value */
23161         targ_mask = pre_triple(state, ins, OP_AND, targ->type, targ, nmask);
23162         use_triple(targ, targ_mask);
23163         use_triple(nmask, targ_mask);
23164
23165         /* Now combined them together */
23166         new = pre_triple(state, ins, OP_OR, targ->type, targ_mask, val_mask);
23167         use_triple(targ_mask, new);
23168         use_triple(val_mask, new);
23169
23170         /* Move all of the users over to the new expression */
23171         propogate_use(state, ins, new);
23172
23173         /* Delete the original triple */
23174         release_triple(state, ins);
23175
23176         /* Restart the transformation at mask */
23177         return mask;
23178 }
23179
23180 static struct triple *x86_extract(struct compile_state *state, struct triple *ins)
23181 {
23182         struct triple *mask, *shift;
23183         struct triple *val, *val_mask, *val_shift;
23184         ulong_t the_mask;
23185
23186         val = RHS(ins, 0);
23187
23188         /* Get constant for the mask value */
23189         the_mask = 1;
23190         the_mask <<= ins->u.bitfield.size;
23191         the_mask -= 1;
23192         mask = pre_triple(state, ins, OP_INTCONST, &int_type, 0, 0);
23193         mask->u.cval = the_mask;
23194
23195         /* Get constant for the right shift value */
23196         shift = pre_triple(state, ins, OP_INTCONST, &int_type, 0, 0);
23197         shift->u.cval = ins->u.bitfield.offset;
23198
23199         /* Shift arithmetic right, to correct the sign */
23200         val_shift = val;
23201         if (shift->u.cval != 0) {
23202                 int op;
23203                 if (ins->op == OP_SEXTRACT) {
23204                         op = OP_SSR;
23205                 } else {
23206                         op = OP_USR;
23207                 }
23208                 val_shift = pre_triple(state, ins, op, val->type, val, shift);
23209                 use_triple(val, val_shift);
23210                 use_triple(shift, val_shift);
23211         }
23212
23213         /* Finally mask the value */
23214         val_mask = pre_triple(state, ins, OP_AND, ins->type, val_shift, mask);
23215         use_triple(val_shift, val_mask);
23216         use_triple(mask,      val_mask);
23217
23218         /* Move all of the users over to the new expression */
23219         propogate_use(state, ins, val_mask);
23220
23221         /* Release the original instruction */
23222         release_triple(state, ins);
23223
23224         return mask;
23225
23226 }
23227
23228 static struct triple *transform_to_arch_instruction(
23229         struct compile_state *state, struct triple *ins)
23230 {
23231         /* Transform from generic 3 address instructions
23232          * to archtecture specific instructions.
23233          * And apply architecture specific constraints to instructions.
23234          * Copies are inserted to preserve the register flexibility
23235          * of 3 address instructions.
23236          */
23237         struct triple *next, *value;
23238         size_t size;
23239         next = ins->next;
23240         switch(ins->op) {
23241         case OP_INTCONST:
23242                 ins->template_id = TEMPLATE_INTCONST32;
23243                 if (ins->u.cval < 256) {
23244                         ins->template_id = TEMPLATE_INTCONST8;
23245                 }
23246                 break;
23247         case OP_ADDRCONST:
23248                 ins->template_id = TEMPLATE_INTCONST32;
23249                 break;
23250         case OP_UNKNOWNVAL:
23251                 ins->template_id = TEMPLATE_UNKNOWNVAL;
23252                 break;
23253         case OP_NOOP:
23254         case OP_SDECL:
23255         case OP_BLOBCONST:
23256         case OP_LABEL:
23257                 ins->template_id = TEMPLATE_NOP;
23258                 break;
23259         case OP_COPY:
23260         case OP_CONVERT:
23261                 size = size_of(state, ins->type);
23262                 value = RHS(ins, 0);
23263                 if (is_imm8(value) && (size <= SIZEOF_I8)) {
23264                         ins->template_id = TEMPLATE_COPY_IMM8;
23265                 }
23266                 else if (is_imm16(value) && (size <= SIZEOF_I16)) {
23267                         ins->template_id = TEMPLATE_COPY_IMM16;
23268                 }
23269                 else if (is_imm32(value) && (size <= SIZEOF_I32)) {
23270                         ins->template_id = TEMPLATE_COPY_IMM32;
23271                 }
23272                 else if (is_const(value)) {
23273                         internal_error(state, ins, "bad constant passed to copy");
23274                 }
23275                 else if (size <= SIZEOF_I8) {
23276                         ins->template_id = TEMPLATE_COPY8_REG;
23277                 }
23278                 else if (size <= SIZEOF_I16) {
23279                         ins->template_id = TEMPLATE_COPY16_REG;
23280                 }
23281                 else if (size <= SIZEOF_I32) {
23282                         ins->template_id = TEMPLATE_COPY32_REG;
23283                 }
23284                 else {
23285                         internal_error(state, ins, "bad type passed to copy");
23286                 }
23287                 break;
23288         case OP_PHI:
23289                 size = size_of(state, ins->type);
23290                 if (size <= SIZEOF_I8) {
23291                         ins->template_id = TEMPLATE_PHI8;
23292                 }
23293                 else if (size <= SIZEOF_I16) {
23294                         ins->template_id = TEMPLATE_PHI16;
23295                 }
23296                 else if (size <= SIZEOF_I32) {
23297                         ins->template_id = TEMPLATE_PHI32;
23298                 }
23299                 else {
23300                         internal_error(state, ins, "bad type passed to phi");
23301                 }
23302                 break;
23303         case OP_ADECL:
23304                 /* Adecls should always be treated as dead code and
23305                  * removed.  If we are not optimizing they may linger.
23306                  */
23307                 if (!noop_adecl(ins)) {
23308                         internal_error(state, ins, "adecl remains?");
23309                 }
23310                 ins->template_id = TEMPLATE_NOP;
23311                 next = after_lhs(state, ins);
23312                 break;
23313         case OP_STORE:
23314                 switch(ins->type->type & TYPE_MASK) {
23315                 case TYPE_CHAR:    case TYPE_UCHAR:
23316                         ins->template_id = TEMPLATE_STORE8;
23317                         break;
23318                 case TYPE_SHORT:   case TYPE_USHORT:
23319                         ins->template_id = TEMPLATE_STORE16;
23320                         break;
23321                 case TYPE_INT:     case TYPE_UINT:
23322                 case TYPE_LONG:    case TYPE_ULONG:
23323                 case TYPE_POINTER:
23324                         ins->template_id = TEMPLATE_STORE32;
23325                         break;
23326                 default:
23327                         internal_error(state, ins, "unknown type in store");
23328                         break;
23329                 }
23330                 break;
23331         case OP_LOAD:
23332                 switch(ins->type->type & TYPE_MASK) {
23333                 case TYPE_CHAR:   case TYPE_UCHAR:
23334                 case TYPE_SHORT:  case TYPE_USHORT:
23335                 case TYPE_INT:    case TYPE_UINT:
23336                 case TYPE_LONG:   case TYPE_ULONG:
23337                 case TYPE_POINTER:
23338                         break;
23339                 default:
23340                         internal_error(state, ins, "unknown type in load");
23341                         break;
23342                 }
23343                 ins->template_id = TEMPLATE_LOAD32;
23344                 break;
23345         case OP_ADD:
23346         case OP_SUB:
23347         case OP_AND:
23348         case OP_XOR:
23349         case OP_OR:
23350         case OP_SMUL:
23351                 ins->template_id = TEMPLATE_BINARY32_REG;
23352                 if (get_imm32(ins, &RHS(ins, 1))) {
23353                         ins->template_id = TEMPLATE_BINARY32_IMM;
23354                 }
23355                 break;
23356         case OP_SDIVT:
23357         case OP_UDIVT:
23358                 ins->template_id = TEMPLATE_DIV32;
23359                 next = after_lhs(state, ins);
23360                 break;
23361         case OP_UMUL:
23362                 ins->template_id = TEMPLATE_UMUL32;
23363                 break;
23364         case OP_UDIV:
23365                 next = mod_div(state, ins, OP_UDIVT, 0);
23366                 break;
23367         case OP_SDIV:
23368                 next = mod_div(state, ins, OP_SDIVT, 0);
23369                 break;
23370         case OP_UMOD:
23371                 next = mod_div(state, ins, OP_UDIVT, 1);
23372                 break;
23373         case OP_SMOD:
23374                 next = mod_div(state, ins, OP_SDIVT, 1);
23375                 break;
23376         case OP_SL:
23377         case OP_SSR:
23378         case OP_USR:
23379                 ins->template_id = TEMPLATE_SL32_CL;
23380                 if (get_imm8(ins, &RHS(ins, 1))) {
23381                         ins->template_id = TEMPLATE_SL32_IMM;
23382                 } else if (size_of(state, RHS(ins, 1)->type) > SIZEOF_CHAR) {
23383                         typed_pre_copy(state, &uchar_type, ins, 1);
23384                 }
23385                 break;
23386         case OP_INVERT:
23387         case OP_NEG:
23388                 ins->template_id = TEMPLATE_UNARY32;
23389                 break;
23390         case OP_EQ: 
23391                 bool_cmp(state, ins, OP_CMP, OP_JMP_EQ, OP_SET_EQ); 
23392                 break;
23393         case OP_NOTEQ:
23394                 bool_cmp(state, ins, OP_CMP, OP_JMP_NOTEQ, OP_SET_NOTEQ);
23395                 break;
23396         case OP_SLESS:
23397                 bool_cmp(state, ins, OP_CMP, OP_JMP_SLESS, OP_SET_SLESS);
23398                 break;
23399         case OP_ULESS:
23400                 bool_cmp(state, ins, OP_CMP, OP_JMP_ULESS, OP_SET_ULESS);
23401                 break;
23402         case OP_SMORE:
23403                 bool_cmp(state, ins, OP_CMP, OP_JMP_SMORE, OP_SET_SMORE);
23404                 break;
23405         case OP_UMORE:
23406                 bool_cmp(state, ins, OP_CMP, OP_JMP_UMORE, OP_SET_UMORE);
23407                 break;
23408         case OP_SLESSEQ:
23409                 bool_cmp(state, ins, OP_CMP, OP_JMP_SLESSEQ, OP_SET_SLESSEQ);
23410                 break;
23411         case OP_ULESSEQ:
23412                 bool_cmp(state, ins, OP_CMP, OP_JMP_ULESSEQ, OP_SET_ULESSEQ);
23413                 break;
23414         case OP_SMOREEQ:
23415                 bool_cmp(state, ins, OP_CMP, OP_JMP_SMOREEQ, OP_SET_SMOREEQ);
23416                 break;
23417         case OP_UMOREEQ:
23418                 bool_cmp(state, ins, OP_CMP, OP_JMP_UMOREEQ, OP_SET_UMOREEQ);
23419                 break;
23420         case OP_LTRUE:
23421                 bool_cmp(state, ins, OP_TEST, OP_JMP_NOTEQ, OP_SET_NOTEQ);
23422                 break;
23423         case OP_LFALSE:
23424                 bool_cmp(state, ins, OP_TEST, OP_JMP_EQ, OP_SET_EQ);
23425                 break;
23426         case OP_BRANCH:
23427                 ins->op = OP_JMP;
23428                 ins->template_id = TEMPLATE_NOP;
23429                 break;
23430         case OP_CBRANCH:
23431                 fixup_branch(state, ins, OP_JMP_NOTEQ, OP_TEST, 
23432                         RHS(ins, 0)->type, RHS(ins, 0), 0);
23433                 break;
23434         case OP_CALL:
23435                 ins->template_id = TEMPLATE_NOP;
23436                 break;
23437         case OP_RET:
23438                 ins->template_id = TEMPLATE_RET;
23439                 break;
23440         case OP_INB:
23441         case OP_INW:
23442         case OP_INL:
23443                 switch(ins->op) {
23444                 case OP_INB: ins->template_id = TEMPLATE_INB_DX; break;
23445                 case OP_INW: ins->template_id = TEMPLATE_INW_DX; break;
23446                 case OP_INL: ins->template_id = TEMPLATE_INL_DX; break;
23447                 }
23448                 if (get_imm8(ins, &RHS(ins, 0))) {
23449                         ins->template_id += 1;
23450                 }
23451                 break;
23452         case OP_OUTB:
23453         case OP_OUTW:
23454         case OP_OUTL:
23455                 switch(ins->op) {
23456                 case OP_OUTB: ins->template_id = TEMPLATE_OUTB_DX; break;
23457                 case OP_OUTW: ins->template_id = TEMPLATE_OUTW_DX; break;
23458                 case OP_OUTL: ins->template_id = TEMPLATE_OUTL_DX; break;
23459                 }
23460                 if (get_imm8(ins, &RHS(ins, 1))) {
23461                         ins->template_id += 1;
23462                 }
23463                 break;
23464         case OP_BSF:
23465         case OP_BSR:
23466                 ins->template_id = TEMPLATE_BSF;
23467                 break;
23468         case OP_RDMSR:
23469                 ins->template_id = TEMPLATE_RDMSR;
23470                 next = after_lhs(state, ins);
23471                 break;
23472         case OP_WRMSR:
23473                 ins->template_id = TEMPLATE_WRMSR;
23474                 break;
23475         case OP_HLT:
23476                 ins->template_id = TEMPLATE_NOP;
23477                 break;
23478         case OP_ASM:
23479                 ins->template_id = TEMPLATE_NOP;
23480                 next = after_lhs(state, ins);
23481                 break;
23482                 /* Already transformed instructions */
23483         case OP_TEST:
23484                 ins->template_id = TEMPLATE_TEST32;
23485                 break;
23486         case OP_CMP:
23487                 ins->template_id = TEMPLATE_CMP32_REG;
23488                 if (get_imm32(ins, &RHS(ins, 1))) {
23489                         ins->template_id = TEMPLATE_CMP32_IMM;
23490                 }
23491                 break;
23492         case OP_JMP:
23493                 ins->template_id = TEMPLATE_NOP;
23494                 break;
23495         case OP_JMP_EQ:      case OP_JMP_NOTEQ:
23496         case OP_JMP_SLESS:   case OP_JMP_ULESS:
23497         case OP_JMP_SMORE:   case OP_JMP_UMORE:
23498         case OP_JMP_SLESSEQ: case OP_JMP_ULESSEQ:
23499         case OP_JMP_SMOREEQ: case OP_JMP_UMOREEQ:
23500                 ins->template_id = TEMPLATE_JMP;
23501                 break;
23502         case OP_SET_EQ:      case OP_SET_NOTEQ:
23503         case OP_SET_SLESS:   case OP_SET_ULESS:
23504         case OP_SET_SMORE:   case OP_SET_UMORE:
23505         case OP_SET_SLESSEQ: case OP_SET_ULESSEQ:
23506         case OP_SET_SMOREEQ: case OP_SET_UMOREEQ:
23507                 ins->template_id = TEMPLATE_SET;
23508                 break;
23509         case OP_DEPOSIT:
23510                 next = x86_deposit(state, ins);
23511                 break;
23512         case OP_SEXTRACT:
23513         case OP_UEXTRACT:
23514                 next = x86_extract(state, ins);
23515                 break;
23516                 /* Unhandled instructions */
23517         case OP_PIECE:
23518         default:
23519                 internal_error(state, ins, "unhandled ins: %d %s",
23520                         ins->op, tops(ins->op));
23521                 break;
23522         }
23523         return next;
23524 }
23525
23526 static long next_label(struct compile_state *state)
23527 {
23528         static long label_counter = 1000;
23529         return ++label_counter;
23530 }
23531 static void generate_local_labels(struct compile_state *state)
23532 {
23533         struct triple *first, *label;
23534         first = state->first;
23535         label = first;
23536         do {
23537                 if ((label->op == OP_LABEL) || 
23538                         (label->op == OP_SDECL)) {
23539                         if (label->use) {
23540                                 label->u.cval = next_label(state);
23541                         } else {
23542                                 label->u.cval = 0;
23543                         }
23544                         
23545                 }
23546                 label = label->next;
23547         } while(label != first);
23548 }
23549
23550 static int check_reg(struct compile_state *state, 
23551         struct triple *triple, int classes)
23552 {
23553         unsigned mask;
23554         int reg;
23555         reg = ID_REG(triple->id);
23556         if (reg == REG_UNSET) {
23557                 internal_error(state, triple, "register not set");
23558         }
23559         mask = arch_reg_regcm(state, reg);
23560         if (!(classes & mask)) {
23561                 internal_error(state, triple, "reg %d in wrong class",
23562                         reg);
23563         }
23564         return reg;
23565 }
23566
23567
23568 #if REG_XMM7 != 44
23569 #error "Registers have renumberd fix arch_reg_str"
23570 #endif
23571 static const char *arch_regs[] = {
23572         "%unset",
23573         "%unneeded",
23574         "%eflags",
23575         "%al", "%bl", "%cl", "%dl", "%ah", "%bh", "%ch", "%dh",
23576         "%ax", "%bx", "%cx", "%dx", "%si", "%di", "%bp", "%sp",
23577         "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi", "%ebp", "%esp",
23578         "%edx:%eax",
23579         "%dx:%ax",
23580         "%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7",
23581         "%xmm0", "%xmm1", "%xmm2", "%xmm3", 
23582         "%xmm4", "%xmm5", "%xmm6", "%xmm7",
23583 };
23584 static const char *arch_reg_str(int reg)
23585 {
23586         if (!((reg >= REG_EFLAGS) && (reg <= REG_XMM7))) {
23587                 reg = 0;
23588         }
23589         return arch_regs[reg];
23590 }
23591
23592 static const char *reg(struct compile_state *state, struct triple *triple,
23593         int classes)
23594 {
23595         int reg;
23596         reg = check_reg(state, triple, classes);
23597         return arch_reg_str(reg);
23598 }
23599
23600 static int arch_reg_size(int reg)
23601 {
23602         int size;
23603         size = 0;
23604         if (reg == REG_EFLAGS) {
23605                 size = 32;
23606         }
23607         else if ((reg >= REG_AL) && (reg <= REG_DH)) {
23608                 size = 8;
23609         }
23610         else if ((reg >= REG_AX) && (reg <= REG_SP)) {
23611                 size = 16;
23612         }
23613         else if ((reg >= REG_EAX) && (reg <= REG_ESP)) {
23614                 size = 32;
23615         }
23616         else if (reg == REG_EDXEAX) {
23617                 size = 64;
23618         }
23619         else if (reg == REG_DXAX) {
23620                 size = 32;
23621         }
23622         else if ((reg >= REG_MMX0) && (reg <= REG_MMX7)) {
23623                 size = 64;
23624         }
23625         else if ((reg >= REG_XMM0) && (reg <= REG_XMM7)) {
23626                 size = 128;
23627         }
23628         return size;
23629 }
23630
23631 static int reg_size(struct compile_state *state, struct triple *ins)
23632 {
23633         int reg;
23634         reg = ID_REG(ins->id);
23635         if (reg == REG_UNSET) {
23636                 internal_error(state, ins, "register not set");
23637         }
23638         return arch_reg_size(reg);
23639 }
23640         
23641
23642
23643 const char *type_suffix(struct compile_state *state, struct type *type)
23644 {
23645         const char *suffix;
23646         switch(size_of(state, type)) {
23647         case SIZEOF_I8:  suffix = "b"; break;
23648         case SIZEOF_I16: suffix = "w"; break;
23649         case SIZEOF_I32: suffix = "l"; break;
23650         default:
23651                 internal_error(state, 0, "unknown suffix");
23652                 suffix = 0;
23653                 break;
23654         }
23655         return suffix;
23656 }
23657
23658 static void print_const_val(
23659         struct compile_state *state, struct triple *ins, FILE *fp)
23660 {
23661         switch(ins->op) {
23662         case OP_INTCONST:
23663                 fprintf(fp, " $%ld ", 
23664                         (long)(ins->u.cval));
23665                 break;
23666         case OP_ADDRCONST:
23667                 if ((MISC(ins, 0)->op != OP_SDECL) &&
23668                         (MISC(ins, 0)->op != OP_LABEL))
23669                 {
23670                         internal_error(state, ins, "bad base for addrconst");
23671                 }
23672                 if (MISC(ins, 0)->u.cval <= 0) {
23673                         internal_error(state, ins, "unlabeled constant");
23674                 }
23675                 fprintf(fp, " $L%s%lu+%lu ",
23676                         state->compiler->label_prefix, 
23677                         (unsigned long)(MISC(ins, 0)->u.cval),
23678                         (unsigned long)(ins->u.cval));
23679                 break;
23680         default:
23681                 internal_error(state, ins, "unknown constant type");
23682                 break;
23683         }
23684 }
23685
23686 static void print_const(struct compile_state *state,
23687         struct triple *ins, FILE *fp)
23688 {
23689         switch(ins->op) {
23690         case OP_INTCONST:
23691                 switch(ins->type->type & TYPE_MASK) {
23692                 case TYPE_CHAR:
23693                 case TYPE_UCHAR:
23694                         fprintf(fp, ".byte 0x%02lx\n", 
23695                                 (unsigned long)(ins->u.cval));
23696                         break;
23697                 case TYPE_SHORT:
23698                 case TYPE_USHORT:
23699                         fprintf(fp, ".short 0x%04lx\n", 
23700                                 (unsigned long)(ins->u.cval));
23701                         break;
23702                 case TYPE_INT:
23703                 case TYPE_UINT:
23704                 case TYPE_LONG:
23705                 case TYPE_ULONG:
23706                 case TYPE_POINTER:
23707                         fprintf(fp, ".int %lu\n", 
23708                                 (unsigned long)(ins->u.cval));
23709                         break;
23710                 default:
23711                         fprintf(state->errout, "type: ");
23712                         name_of(state->errout, ins->type);
23713                         fprintf(state->errout, "\n");
23714                         internal_error(state, ins, "Unknown constant type. Val: %lu",
23715                                 (unsigned long)(ins->u.cval));
23716                 }
23717                 
23718                 break;
23719         case OP_ADDRCONST:
23720                 if ((MISC(ins, 0)->op != OP_SDECL) &&
23721                         (MISC(ins, 0)->op != OP_LABEL)) {
23722                         internal_error(state, ins, "bad base for addrconst");
23723                 }
23724                 if (MISC(ins, 0)->u.cval <= 0) {
23725                         internal_error(state, ins, "unlabeled constant");
23726                 }
23727                 fprintf(fp, ".int L%s%lu+%lu\n",
23728                         state->compiler->label_prefix,
23729                         (unsigned long)(MISC(ins, 0)->u.cval),
23730                         (unsigned long)(ins->u.cval));
23731                 break;
23732         case OP_BLOBCONST:
23733         {
23734                 unsigned char *blob;
23735                 size_t size, i;
23736                 size = size_of_in_bytes(state, ins->type);
23737                 blob = ins->u.blob;
23738                 for(i = 0; i < size; i++) {
23739                         fprintf(fp, ".byte 0x%02x\n",
23740                                 blob[i]);
23741                 }
23742                 break;
23743         }
23744         default:
23745                 internal_error(state, ins, "Unknown constant type");
23746                 break;
23747         }
23748 }
23749
23750 #define TEXT_SECTION ".rom.text"
23751 #define DATA_SECTION ".rom.data"
23752
23753 static long get_const_pool_ref(
23754         struct compile_state *state, struct triple *ins, size_t size, FILE *fp)
23755 {
23756         size_t fill_bytes;
23757         long ref;
23758         ref = next_label(state);
23759         fprintf(fp, ".section \"" DATA_SECTION "\"\n");
23760         fprintf(fp, ".balign %d\n", align_of_in_bytes(state, ins->type));
23761         fprintf(fp, "L%s%lu:\n", state->compiler->label_prefix, ref);
23762         print_const(state, ins, fp);
23763         fill_bytes = bits_to_bytes(size - size_of(state, ins->type));
23764         if (fill_bytes) {
23765                 fprintf(fp, ".fill %d, 1, 0\n", fill_bytes);
23766         }
23767         fprintf(fp, ".section \"" TEXT_SECTION "\"\n");
23768         return ref;
23769 }
23770
23771 static long get_mask_pool_ref(
23772         struct compile_state *state, struct triple *ins, unsigned long mask, FILE *fp)
23773 {
23774         long ref;
23775         if (mask == 0xff) {
23776                 ref = 1;
23777         }
23778         else if (mask == 0xffff) {
23779                 ref = 2;
23780         }
23781         else {
23782                 ref = 0;
23783                 internal_error(state, ins, "unhandled mask value");
23784         }
23785         return ref;
23786 }
23787
23788 static void print_binary_op(struct compile_state *state,
23789         const char *op, struct triple *ins, FILE *fp) 
23790 {
23791         unsigned mask;
23792         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO;
23793         if (ID_REG(RHS(ins, 0)->id) != ID_REG(ins->id)) {
23794                 internal_error(state, ins, "invalid register assignment");
23795         }
23796         if (is_const(RHS(ins, 1))) {
23797                 fprintf(fp, "\t%s ", op);
23798                 print_const_val(state, RHS(ins, 1), fp);
23799                 fprintf(fp, ", %s\n",
23800                         reg(state, RHS(ins, 0), mask));
23801         }
23802         else {
23803                 unsigned lmask, rmask;
23804                 int lreg, rreg;
23805                 lreg = check_reg(state, RHS(ins, 0), mask);
23806                 rreg = check_reg(state, RHS(ins, 1), mask);
23807                 lmask = arch_reg_regcm(state, lreg);
23808                 rmask = arch_reg_regcm(state, rreg);
23809                 mask = lmask & rmask;
23810                 fprintf(fp, "\t%s %s, %s\n",
23811                         op,
23812                         reg(state, RHS(ins, 1), mask),
23813                         reg(state, RHS(ins, 0), mask));
23814         }
23815 }
23816 static void print_unary_op(struct compile_state *state, 
23817         const char *op, struct triple *ins, FILE *fp)
23818 {
23819         unsigned mask;
23820         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO;
23821         fprintf(fp, "\t%s %s\n",
23822                 op,
23823                 reg(state, RHS(ins, 0), mask));
23824 }
23825
23826 static void print_op_shift(struct compile_state *state,
23827         const char *op, struct triple *ins, FILE *fp)
23828 {
23829         unsigned mask;
23830         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO;
23831         if (ID_REG(RHS(ins, 0)->id) != ID_REG(ins->id)) {
23832                 internal_error(state, ins, "invalid register assignment");
23833         }
23834         if (is_const(RHS(ins, 1))) {
23835                 fprintf(fp, "\t%s ", op);
23836                 print_const_val(state, RHS(ins, 1), fp);
23837                 fprintf(fp, ", %s\n",
23838                         reg(state, RHS(ins, 0), mask));
23839         }
23840         else {
23841                 fprintf(fp, "\t%s %s, %s\n",
23842                         op,
23843                         reg(state, RHS(ins, 1), REGCM_GPR8_LO),
23844                         reg(state, RHS(ins, 0), mask));
23845         }
23846 }
23847
23848 static void print_op_in(struct compile_state *state, struct triple *ins, FILE *fp)
23849 {
23850         const char *op;
23851         int mask;
23852         int dreg;
23853         mask = 0;
23854         switch(ins->op) {
23855         case OP_INB: op = "inb", mask = REGCM_GPR8_LO; break;
23856         case OP_INW: op = "inw", mask = REGCM_GPR16; break;
23857         case OP_INL: op = "inl", mask = REGCM_GPR32; break;
23858         default:
23859                 internal_error(state, ins, "not an in operation");
23860                 op = 0;
23861                 break;
23862         }
23863         dreg = check_reg(state, ins, mask);
23864         if (!reg_is_reg(state, dreg, REG_EAX)) {
23865                 internal_error(state, ins, "dst != %%eax");
23866         }
23867         if (is_const(RHS(ins, 0))) {
23868                 fprintf(fp, "\t%s ", op);
23869                 print_const_val(state, RHS(ins, 0), fp);
23870                 fprintf(fp, ", %s\n",
23871                         reg(state, ins, mask));
23872         }
23873         else {
23874                 int addr_reg;
23875                 addr_reg = check_reg(state, RHS(ins, 0), REGCM_GPR16);
23876                 if (!reg_is_reg(state, addr_reg, REG_DX)) {
23877                         internal_error(state, ins, "src != %%dx");
23878                 }
23879                 fprintf(fp, "\t%s %s, %s\n",
23880                         op, 
23881                         reg(state, RHS(ins, 0), REGCM_GPR16),
23882                         reg(state, ins, mask));
23883         }
23884 }
23885
23886 static void print_op_out(struct compile_state *state, struct triple *ins, FILE *fp)
23887 {
23888         const char *op;
23889         int mask;
23890         int lreg;
23891         mask = 0;
23892         switch(ins->op) {
23893         case OP_OUTB: op = "outb", mask = REGCM_GPR8_LO; break;
23894         case OP_OUTW: op = "outw", mask = REGCM_GPR16; break;
23895         case OP_OUTL: op = "outl", mask = REGCM_GPR32; break;
23896         default:
23897                 internal_error(state, ins, "not an out operation");
23898                 op = 0;
23899                 break;
23900         }
23901         lreg = check_reg(state, RHS(ins, 0), mask);
23902         if (!reg_is_reg(state, lreg, REG_EAX)) {
23903                 internal_error(state, ins, "src != %%eax");
23904         }
23905         if (is_const(RHS(ins, 1))) {
23906                 fprintf(fp, "\t%s %s,", 
23907                         op, reg(state, RHS(ins, 0), mask));
23908                 print_const_val(state, RHS(ins, 1), fp);
23909                 fprintf(fp, "\n");
23910         }
23911         else {
23912                 int addr_reg;
23913                 addr_reg = check_reg(state, RHS(ins, 1), REGCM_GPR16);
23914                 if (!reg_is_reg(state, addr_reg, REG_DX)) {
23915                         internal_error(state, ins, "dst != %%dx");
23916                 }
23917                 fprintf(fp, "\t%s %s, %s\n",
23918                         op, 
23919                         reg(state, RHS(ins, 0), mask),
23920                         reg(state, RHS(ins, 1), REGCM_GPR16));
23921         }
23922 }
23923
23924 static void print_op_move(struct compile_state *state,
23925         struct triple *ins, FILE *fp)
23926 {
23927         /* op_move is complex because there are many types
23928          * of registers we can move between.
23929          * Because OP_COPY will be introduced in arbitrary locations
23930          * OP_COPY must not affect flags.
23931          * OP_CONVERT can change the flags and it is the only operation
23932          * where it is expected the types in the registers can change.
23933          */
23934         int omit_copy = 1; /* Is it o.k. to omit a noop copy? */
23935         struct triple *dst, *src;
23936         if (state->arch->features & X86_NOOP_COPY) {
23937                 omit_copy = 0;
23938         }
23939         if ((ins->op == OP_COPY) || (ins->op == OP_CONVERT)) {
23940                 src = RHS(ins, 0);
23941                 dst = ins;
23942         }
23943         else {
23944                 internal_error(state, ins, "unknown move operation");
23945                 src = dst = 0;
23946         }
23947         if (reg_size(state, dst) < size_of(state, dst->type)) {
23948                 internal_error(state, ins, "Invalid destination register");
23949         }
23950         if (!equiv_types(src->type, dst->type) && (dst->op == OP_COPY)) {
23951                 fprintf(state->errout, "src type: ");
23952                 name_of(state->errout, src->type);
23953                 fprintf(state->errout, "\n");
23954                 fprintf(state->errout, "dst type: ");
23955                 name_of(state->errout, dst->type);
23956                 fprintf(state->errout, "\n");
23957                 internal_error(state, ins, "Type mismatch for OP_COPY");
23958         }
23959
23960         if (!is_const(src)) {
23961                 int src_reg, dst_reg;
23962                 int src_regcm, dst_regcm;
23963                 src_reg   = ID_REG(src->id);
23964                 dst_reg   = ID_REG(dst->id);
23965                 src_regcm = arch_reg_regcm(state, src_reg);
23966                 dst_regcm = arch_reg_regcm(state, dst_reg);
23967                 /* If the class is the same just move the register */
23968                 if (src_regcm & dst_regcm & 
23969                         (REGCM_GPR8_LO | REGCM_GPR16 | REGCM_GPR32)) {
23970                         if ((src_reg != dst_reg) || !omit_copy) {
23971                                 fprintf(fp, "\tmov %s, %s\n",
23972                                         reg(state, src, src_regcm),
23973                                         reg(state, dst, dst_regcm));
23974                         }
23975                 }
23976                 /* Move 32bit to 16bit */
23977                 else if ((src_regcm & REGCM_GPR32) &&
23978                         (dst_regcm & REGCM_GPR16)) {
23979                         src_reg = (src_reg - REGC_GPR32_FIRST) + REGC_GPR16_FIRST;
23980                         if ((src_reg != dst_reg) || !omit_copy) {
23981                                 fprintf(fp, "\tmovw %s, %s\n",
23982                                         arch_reg_str(src_reg), 
23983                                         arch_reg_str(dst_reg));
23984                         }
23985                 }
23986                 /* Move from 32bit gprs to 16bit gprs */
23987                 else if ((src_regcm & REGCM_GPR32) &&
23988                         (dst_regcm & REGCM_GPR16)) {
23989                         dst_reg = (dst_reg - REGC_GPR16_FIRST) + REGC_GPR32_FIRST;
23990                         if ((src_reg != dst_reg) || !omit_copy) {
23991                                 fprintf(fp, "\tmov %s, %s\n",
23992                                         arch_reg_str(src_reg),
23993                                         arch_reg_str(dst_reg));
23994                         }
23995                 }
23996                 /* Move 32bit to 8bit */
23997                 else if ((src_regcm & REGCM_GPR32_8) &&
23998                         (dst_regcm & REGCM_GPR8_LO))
23999                 {
24000                         src_reg = (src_reg - REGC_GPR32_8_FIRST) + REGC_GPR8_FIRST;
24001                         if ((src_reg != dst_reg) || !omit_copy) {
24002                                 fprintf(fp, "\tmovb %s, %s\n",
24003                                         arch_reg_str(src_reg),
24004                                         arch_reg_str(dst_reg));
24005                         }
24006                 }
24007                 /* Move 16bit to 8bit */
24008                 else if ((src_regcm & REGCM_GPR16_8) &&
24009                         (dst_regcm & REGCM_GPR8_LO))
24010                 {
24011                         src_reg = (src_reg - REGC_GPR16_8_FIRST) + REGC_GPR8_FIRST;
24012                         if ((src_reg != dst_reg) || !omit_copy) {
24013                                 fprintf(fp, "\tmovb %s, %s\n",
24014                                         arch_reg_str(src_reg),
24015                                         arch_reg_str(dst_reg));
24016                         }
24017                 }
24018                 /* Move 8/16bit to 16/32bit */
24019                 else if ((src_regcm & (REGCM_GPR8_LO | REGCM_GPR16)) && 
24020                         (dst_regcm & (REGCM_GPR16 | REGCM_GPR32))) {
24021                         const char *op;
24022                         op = is_signed(src->type)? "movsx": "movzx";
24023                         fprintf(fp, "\t%s %s, %s\n",
24024                                 op,
24025                                 reg(state, src, src_regcm),
24026                                 reg(state, dst, dst_regcm));
24027                 }
24028                 /* Move between sse registers */
24029                 else if ((src_regcm & dst_regcm & REGCM_XMM)) {
24030                         if ((src_reg != dst_reg) || !omit_copy) {
24031                                 fprintf(fp, "\tmovdqa %s, %s\n",
24032                                         reg(state, src, src_regcm),
24033                                         reg(state, dst, dst_regcm));
24034                         }
24035                 }
24036                 /* Move between mmx registers */
24037                 else if ((src_regcm & dst_regcm & REGCM_MMX)) {
24038                         if ((src_reg != dst_reg) || !omit_copy) {
24039                                 fprintf(fp, "\tmovq %s, %s\n",
24040                                         reg(state, src, src_regcm),
24041                                         reg(state, dst, dst_regcm));
24042                         }
24043                 }
24044                 /* Move from sse to mmx registers */
24045                 else if ((src_regcm & REGCM_XMM) && (dst_regcm & REGCM_MMX)) {
24046                         fprintf(fp, "\tmovdq2q %s, %s\n",
24047                                 reg(state, src, src_regcm),
24048                                 reg(state, dst, dst_regcm));
24049                 }
24050                 /* Move from mmx to sse registers */
24051                 else if ((src_regcm & REGCM_MMX) && (dst_regcm & REGCM_XMM)) {
24052                         fprintf(fp, "\tmovq2dq %s, %s\n",
24053                                 reg(state, src, src_regcm),
24054                                 reg(state, dst, dst_regcm));
24055                 }
24056                 /* Move between 32bit gprs & mmx/sse registers */
24057                 else if ((src_regcm & (REGCM_GPR32 | REGCM_MMX | REGCM_XMM)) &&
24058                         (dst_regcm & (REGCM_GPR32 | REGCM_MMX | REGCM_XMM))) {
24059                         fprintf(fp, "\tmovd %s, %s\n",
24060                                 reg(state, src, src_regcm),
24061                                 reg(state, dst, dst_regcm));
24062                 }
24063                 /* Move from 16bit gprs &  mmx/sse registers */
24064                 else if ((src_regcm & REGCM_GPR16) &&
24065                         (dst_regcm & (REGCM_MMX | REGCM_XMM))) {
24066                         const char *op;
24067                         int mid_reg;
24068                         op = is_signed(src->type)? "movsx":"movzx";
24069                         mid_reg = (src_reg - REGC_GPR16_FIRST) + REGC_GPR32_FIRST;
24070                         fprintf(fp, "\t%s %s, %s\n\tmovd %s, %s\n",
24071                                 op,
24072                                 arch_reg_str(src_reg),
24073                                 arch_reg_str(mid_reg),
24074                                 arch_reg_str(mid_reg),
24075                                 arch_reg_str(dst_reg));
24076                 }
24077                 /* Move from mmx/sse registers to 16bit gprs */
24078                 else if ((src_regcm & (REGCM_MMX | REGCM_XMM)) &&
24079                         (dst_regcm & REGCM_GPR16)) {
24080                         dst_reg = (dst_reg - REGC_GPR16_FIRST) + REGC_GPR32_FIRST;
24081                         fprintf(fp, "\tmovd %s, %s\n",
24082                                 arch_reg_str(src_reg),
24083                                 arch_reg_str(dst_reg));
24084                 }
24085                 /* Move from gpr to 64bit dividend */
24086                 else if ((src_regcm & (REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO))  &&
24087                         (dst_regcm & REGCM_DIVIDEND64)) {
24088                         const char *extend;
24089                         extend = is_signed(src->type)? "cltd":"movl $0, %edx";
24090                         fprintf(fp, "\tmov %s, %%eax\n\t%s\n",
24091                                 arch_reg_str(src_reg), 
24092                                 extend);
24093                 }
24094                 /* Move from 64bit gpr to gpr */
24095                 else if ((src_regcm & REGCM_DIVIDEND64) &&
24096                         (dst_regcm & (REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO))) {
24097                         if (dst_regcm & REGCM_GPR32) {
24098                                 src_reg = REG_EAX;
24099                         } 
24100                         else if (dst_regcm & REGCM_GPR16) {
24101                                 src_reg = REG_AX;
24102                         }
24103                         else if (dst_regcm & REGCM_GPR8_LO) {
24104                                 src_reg = REG_AL;
24105                         }
24106                         fprintf(fp, "\tmov %s, %s\n",
24107                                 arch_reg_str(src_reg),
24108                                 arch_reg_str(dst_reg));
24109                 }
24110                 /* Move from mmx/sse registers to 64bit gpr */
24111                 else if ((src_regcm & (REGCM_MMX | REGCM_XMM)) &&
24112                         (dst_regcm & REGCM_DIVIDEND64)) {
24113                         const char *extend;
24114                         extend = is_signed(src->type)? "cltd": "movl $0, %edx";
24115                         fprintf(fp, "\tmovd %s, %%eax\n\t%s\n",
24116                                 arch_reg_str(src_reg),
24117                                 extend);
24118                 }
24119                 /* Move from 64bit gpr to mmx/sse register */
24120                 else if ((src_regcm & REGCM_DIVIDEND64) &&
24121                         (dst_regcm & (REGCM_XMM | REGCM_MMX))) {
24122                         fprintf(fp, "\tmovd %%eax, %s\n",
24123                                 arch_reg_str(dst_reg));
24124                 }
24125 #if X86_4_8BIT_GPRS
24126                 /* Move from 8bit gprs to  mmx/sse registers */
24127                 else if ((src_regcm & REGCM_GPR8_LO) && (src_reg <= REG_DL) &&
24128                         (dst_regcm & (REGCM_MMX | REGCM_XMM))) {
24129                         const char *op;
24130                         int mid_reg;
24131                         op = is_signed(src->type)? "movsx":"movzx";
24132                         mid_reg = (src_reg - REGC_GPR8_FIRST) + REGC_GPR32_FIRST;
24133                         fprintf(fp, "\t%s %s, %s\n\tmovd %s, %s\n",
24134                                 op,
24135                                 reg(state, src, src_regcm),
24136                                 arch_reg_str(mid_reg),
24137                                 arch_reg_str(mid_reg),
24138                                 reg(state, dst, dst_regcm));
24139                 }
24140                 /* Move from mmx/sse registers and 8bit gprs */
24141                 else if ((src_regcm & (REGCM_MMX | REGCM_XMM)) &&
24142                         (dst_regcm & REGCM_GPR8_LO) && (dst_reg <= REG_DL)) {
24143                         int mid_reg;
24144                         mid_reg = (dst_reg - REGC_GPR8_FIRST) + REGC_GPR32_FIRST;
24145                         fprintf(fp, "\tmovd %s, %s\n",
24146                                 reg(state, src, src_regcm),
24147                                 arch_reg_str(mid_reg));
24148                 }
24149                 /* Move from 32bit gprs to 8bit gprs */
24150                 else if ((src_regcm & REGCM_GPR32) &&
24151                         (dst_regcm & REGCM_GPR8_LO)) {
24152                         dst_reg = (dst_reg - REGC_GPR8_FIRST) + REGC_GPR32_FIRST;
24153                         if ((src_reg != dst_reg) || !omit_copy) {
24154                                 fprintf(fp, "\tmov %s, %s\n",
24155                                         arch_reg_str(src_reg),
24156                                         arch_reg_str(dst_reg));
24157                         }
24158                 }
24159                 /* Move from 16bit gprs to 8bit gprs */
24160                 else if ((src_regcm & REGCM_GPR16) &&
24161                         (dst_regcm & REGCM_GPR8_LO)) {
24162                         dst_reg = (dst_reg - REGC_GPR8_FIRST) + REGC_GPR16_FIRST;
24163                         if ((src_reg != dst_reg) || !omit_copy) {
24164                                 fprintf(fp, "\tmov %s, %s\n",
24165                                         arch_reg_str(src_reg),
24166                                         arch_reg_str(dst_reg));
24167                         }
24168                 }
24169 #endif /* X86_4_8BIT_GPRS */
24170                 /* Move from %eax:%edx to %eax:%edx */
24171                 else if ((src_regcm & REGCM_DIVIDEND64) &&
24172                         (dst_regcm & REGCM_DIVIDEND64) &&
24173                         (src_reg == dst_reg)) {
24174                         if (!omit_copy) {
24175                                 fprintf(fp, "\t/*mov %s, %s*/\n",
24176                                         arch_reg_str(src_reg),
24177                                         arch_reg_str(dst_reg));
24178                         }
24179                 }
24180                 else {
24181                         if ((src_regcm & ~REGCM_FLAGS) == 0) {
24182                                 internal_error(state, ins, "attempt to copy from %%eflags!");
24183                         }
24184                         internal_error(state, ins, "unknown copy type");
24185                 }
24186         }
24187         else {
24188                 size_t dst_size;
24189                 int dst_reg;
24190                 int dst_regcm;
24191                 dst_size = size_of(state, dst->type);
24192                 dst_reg = ID_REG(dst->id);
24193                 dst_regcm = arch_reg_regcm(state, dst_reg);
24194                 if (dst_regcm & (REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO)) {
24195                         fprintf(fp, "\tmov ");
24196                         print_const_val(state, src, fp);
24197                         fprintf(fp, ", %s\n",
24198                                 reg(state, dst, REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO));
24199                 }
24200                 else if (dst_regcm & REGCM_DIVIDEND64) {
24201                         if (dst_size > SIZEOF_I32) {
24202                                 internal_error(state, ins, "%dbit constant...", dst_size);
24203                         }
24204                         fprintf(fp, "\tmov $0, %%edx\n");
24205                         fprintf(fp, "\tmov ");
24206                         print_const_val(state, src, fp);
24207                         fprintf(fp, ", %%eax\n");
24208                 }
24209                 else if (dst_regcm & REGCM_DIVIDEND32) {
24210                         if (dst_size > SIZEOF_I16) {
24211                                 internal_error(state, ins, "%dbit constant...", dst_size);
24212                         }
24213                         fprintf(fp, "\tmov $0, %%dx\n");
24214                         fprintf(fp, "\tmov ");
24215                         print_const_val(state, src, fp);
24216                         fprintf(fp, ", %%ax");
24217                 }
24218                 else if (dst_regcm & (REGCM_XMM | REGCM_MMX)) {
24219                         long ref;
24220                         if (dst_size > SIZEOF_I32) {
24221                                 internal_error(state, ins, "%d bit constant...", dst_size);
24222                         }
24223                         ref = get_const_pool_ref(state, src, SIZEOF_I32, fp);
24224                         fprintf(fp, "\tmovd L%s%lu, %s\n",
24225                                 state->compiler->label_prefix, ref,
24226                                 reg(state, dst, (REGCM_XMM | REGCM_MMX)));
24227                 }
24228                 else {
24229                         internal_error(state, ins, "unknown copy immediate type");
24230                 }
24231         }
24232         /* Leave now if this is not a type conversion */
24233         if (ins->op != OP_CONVERT) {
24234                 return;
24235         }
24236         /* Now make certain I have not logically overflowed the destination */
24237         if ((size_of(state, src->type) > size_of(state, dst->type)) &&
24238                 (size_of(state, dst->type) < reg_size(state, dst)))
24239         {
24240                 unsigned long mask;
24241                 int dst_reg;
24242                 int dst_regcm;
24243                 if (size_of(state, dst->type) >= 32) {
24244                         fprintf(state->errout, "dst type: ");
24245                         name_of(state->errout, dst->type);
24246                         fprintf(state->errout, "\n");
24247                         internal_error(state, dst, "unhandled dst type size");
24248                 }
24249                 mask = 1;
24250                 mask <<= size_of(state, dst->type);
24251                 mask -= 1;
24252
24253                 dst_reg = ID_REG(dst->id);
24254                 dst_regcm = arch_reg_regcm(state, dst_reg);
24255
24256                 if (dst_regcm & (REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO)) {
24257                         fprintf(fp, "\tand $0x%lx, %s\n",
24258                                 mask, reg(state, dst, REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO));
24259                 }
24260                 else if (dst_regcm & REGCM_MMX) {
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_MMX));
24266                 }
24267                 else if (dst_regcm & REGCM_XMM) {
24268                         long ref;
24269                         ref = get_mask_pool_ref(state, dst, mask, fp);
24270                         fprintf(fp, "\tpand L%s%lu, %s\n",
24271                                 state->compiler->label_prefix, ref,
24272                                 reg(state, dst, REGCM_XMM));
24273                 }
24274                 else {
24275                         fprintf(state->errout, "dst type: ");
24276                         name_of(state->errout, dst->type);
24277                         fprintf(state->errout, "\n");
24278                         fprintf(state->errout, "dst: %s\n", reg(state, dst, REGCM_ALL));
24279                         internal_error(state, dst, "failed to trunc value: mask %lx", mask);
24280                 }
24281         }
24282         /* Make certain I am properly sign extended */
24283         if ((size_of(state, src->type) < size_of(state, dst->type)) &&
24284                 (is_signed(src->type)))
24285         {
24286                 int bits, reg_bits, shift_bits;
24287                 int dst_reg;
24288                 int dst_regcm;
24289
24290                 bits = size_of(state, src->type);
24291                 reg_bits = reg_size(state, dst);
24292                 if (reg_bits > 32) {
24293                         reg_bits = 32;
24294                 }
24295                 shift_bits = reg_bits - size_of(state, src->type);
24296                 dst_reg = ID_REG(dst->id);
24297                 dst_regcm = arch_reg_regcm(state, dst_reg);
24298
24299                 if (shift_bits < 0) {
24300                         internal_error(state, dst, "negative shift?");
24301                 }
24302
24303                 if (dst_regcm & (REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO)) {
24304                         fprintf(fp, "\tshl $%d, %s\n", 
24305                                 shift_bits, 
24306                                 reg(state, dst, REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO));
24307                         fprintf(fp, "\tsar $%d, %s\n", 
24308                                 shift_bits, 
24309                                 reg(state, dst, REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO));
24310                 }
24311                 else if (dst_regcm & (REGCM_MMX | REGCM_XMM)) {
24312                         fprintf(fp, "\tpslld $%d, %s\n",
24313                                 shift_bits, 
24314                                 reg(state, dst, REGCM_MMX | REGCM_XMM));
24315                         fprintf(fp, "\tpsrad $%d, %s\n",
24316                                 shift_bits, 
24317                                 reg(state, dst, REGCM_MMX | REGCM_XMM));
24318                 }
24319                 else {
24320                         fprintf(state->errout, "dst type: ");
24321                         name_of(state->errout, dst->type);
24322                         fprintf(state->errout, "\n");
24323                         fprintf(state->errout, "dst: %s\n", reg(state, dst, REGCM_ALL));
24324                         internal_error(state, dst, "failed to signed extend value");
24325                 }
24326         }
24327 }
24328
24329 static void print_op_load(struct compile_state *state,
24330         struct triple *ins, FILE *fp)
24331 {
24332         struct triple *dst, *src;
24333         const char *op;
24334         dst = ins;
24335         src = RHS(ins, 0);
24336         if (is_const(src) || is_const(dst)) {
24337                 internal_error(state, ins, "unknown load operation");
24338         }
24339         switch(ins->type->type & TYPE_MASK) {
24340         case TYPE_CHAR:   op = "movsbl"; break;
24341         case TYPE_UCHAR:  op = "movzbl"; break;
24342         case TYPE_SHORT:  op = "movswl"; break;
24343         case TYPE_USHORT: op = "movzwl"; break;
24344         case TYPE_INT:    case TYPE_UINT:
24345         case TYPE_LONG:   case TYPE_ULONG:
24346         case TYPE_POINTER:
24347                 op = "movl"; 
24348                 break;
24349         default:
24350                 internal_error(state, ins, "unknown type in load");
24351                 op = "<invalid opcode>";
24352                 break;
24353         }
24354         fprintf(fp, "\t%s (%s), %s\n",
24355                 op, 
24356                 reg(state, src, REGCM_GPR32),
24357                 reg(state, dst, REGCM_GPR32));
24358 }
24359
24360
24361 static void print_op_store(struct compile_state *state,
24362         struct triple *ins, FILE *fp)
24363 {
24364         struct triple *dst, *src;
24365         dst = RHS(ins, 0);
24366         src = RHS(ins, 1);
24367         if (is_const(src) && (src->op == OP_INTCONST)) {
24368                 long_t value;
24369                 value = (long_t)(src->u.cval);
24370                 fprintf(fp, "\tmov%s $%ld, (%s)\n",
24371                         type_suffix(state, src->type),
24372                         (long)(value),
24373                         reg(state, dst, REGCM_GPR32));
24374         }
24375         else if (is_const(dst) && (dst->op == OP_INTCONST)) {
24376                 fprintf(fp, "\tmov%s %s, 0x%08lx\n",
24377                         type_suffix(state, src->type),
24378                         reg(state, src, REGCM_GPR8_LO | REGCM_GPR16 | REGCM_GPR32),
24379                         (unsigned long)(dst->u.cval));
24380         }
24381         else {
24382                 if (is_const(src) || is_const(dst)) {
24383                         internal_error(state, ins, "unknown store operation");
24384                 }
24385                 fprintf(fp, "\tmov%s %s, (%s)\n",
24386                         type_suffix(state, src->type),
24387                         reg(state, src, REGCM_GPR8_LO | REGCM_GPR16 | REGCM_GPR32),
24388                         reg(state, dst, REGCM_GPR32));
24389         }
24390         
24391         
24392 }
24393
24394 static void print_op_smul(struct compile_state *state,
24395         struct triple *ins, FILE *fp)
24396 {
24397         if (!is_const(RHS(ins, 1))) {
24398                 fprintf(fp, "\timul %s, %s\n",
24399                         reg(state, RHS(ins, 1), REGCM_GPR32),
24400                         reg(state, RHS(ins, 0), REGCM_GPR32));
24401         }
24402         else {
24403                 fprintf(fp, "\timul ");
24404                 print_const_val(state, RHS(ins, 1), fp);
24405                 fprintf(fp, ", %s\n", reg(state, RHS(ins, 0), REGCM_GPR32));
24406         }
24407 }
24408
24409 static void print_op_cmp(struct compile_state *state,
24410         struct triple *ins, FILE *fp)
24411 {
24412         unsigned mask;
24413         int dreg;
24414         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO;
24415         dreg = check_reg(state, ins, REGCM_FLAGS);
24416         if (!reg_is_reg(state, dreg, REG_EFLAGS)) {
24417                 internal_error(state, ins, "bad dest register for cmp");
24418         }
24419         if (is_const(RHS(ins, 1))) {
24420                 fprintf(fp, "\tcmp ");
24421                 print_const_val(state, RHS(ins, 1), fp);
24422                 fprintf(fp, ", %s\n", reg(state, RHS(ins, 0), mask));
24423         }
24424         else {
24425                 unsigned lmask, rmask;
24426                 int lreg, rreg;
24427                 lreg = check_reg(state, RHS(ins, 0), mask);
24428                 rreg = check_reg(state, RHS(ins, 1), mask);
24429                 lmask = arch_reg_regcm(state, lreg);
24430                 rmask = arch_reg_regcm(state, rreg);
24431                 mask = lmask & rmask;
24432                 fprintf(fp, "\tcmp %s, %s\n",
24433                         reg(state, RHS(ins, 1), mask),
24434                         reg(state, RHS(ins, 0), mask));
24435         }
24436 }
24437
24438 static void print_op_test(struct compile_state *state,
24439         struct triple *ins, FILE *fp)
24440 {
24441         unsigned mask;
24442         mask = REGCM_GPR32 | REGCM_GPR16 | REGCM_GPR8_LO;
24443         fprintf(fp, "\ttest %s, %s\n",
24444                 reg(state, RHS(ins, 0), mask),
24445                 reg(state, RHS(ins, 0), mask));
24446 }
24447
24448 static void print_op_branch(struct compile_state *state,
24449         struct triple *branch, FILE *fp)
24450 {
24451         const char *bop = "j";
24452         if ((branch->op == OP_JMP) || (branch->op == OP_CALL)) {
24453                 if (branch->rhs != 0) {
24454                         internal_error(state, branch, "jmp with condition?");
24455                 }
24456                 bop = "jmp";
24457         }
24458         else {
24459                 struct triple *ptr;
24460                 if (branch->rhs != 1) {
24461                         internal_error(state, branch, "jmpcc without condition?");
24462                 }
24463                 check_reg(state, RHS(branch, 0), REGCM_FLAGS);
24464                 if ((RHS(branch, 0)->op != OP_CMP) &&
24465                         (RHS(branch, 0)->op != OP_TEST)) {
24466                         internal_error(state, branch, "bad branch test");
24467                 }
24468 #warning "FIXME I have observed instructions between the test and branch instructions"
24469                 ptr = RHS(branch, 0);
24470                 for(ptr = RHS(branch, 0)->next; ptr != branch; ptr = ptr->next) {
24471                         if (ptr->op != OP_COPY) {
24472                                 internal_error(state, branch, "branch does not follow test");
24473                         }
24474                 }
24475                 switch(branch->op) {
24476                 case OP_JMP_EQ:       bop = "jz";  break;
24477                 case OP_JMP_NOTEQ:    bop = "jnz"; break;
24478                 case OP_JMP_SLESS:    bop = "jl";  break;
24479                 case OP_JMP_ULESS:    bop = "jb";  break;
24480                 case OP_JMP_SMORE:    bop = "jg";  break;
24481                 case OP_JMP_UMORE:    bop = "ja";  break;
24482                 case OP_JMP_SLESSEQ:  bop = "jle"; break;
24483                 case OP_JMP_ULESSEQ:  bop = "jbe"; break;
24484                 case OP_JMP_SMOREEQ:  bop = "jge"; break;
24485                 case OP_JMP_UMOREEQ:  bop = "jae"; break;
24486                 default:
24487                         internal_error(state, branch, "Invalid branch op");
24488                         break;
24489                 }
24490                 
24491         }
24492 #if 1
24493         if (branch->op == OP_CALL) {
24494                 fprintf(fp, "\t/* call */\n");
24495         }
24496 #endif
24497         fprintf(fp, "\t%s L%s%lu\n",
24498                 bop, 
24499                 state->compiler->label_prefix,
24500                 (unsigned long)(TARG(branch, 0)->u.cval));
24501 }
24502
24503 static void print_op_ret(struct compile_state *state,
24504         struct triple *branch, FILE *fp)
24505 {
24506         fprintf(fp, "\tjmp *%s\n",
24507                 reg(state, RHS(branch, 0), REGCM_GPR32));
24508 }
24509
24510 static void print_op_set(struct compile_state *state,
24511         struct triple *set, FILE *fp)
24512 {
24513         const char *sop = "set";
24514         if (set->rhs != 1) {
24515                 internal_error(state, set, "setcc without condition?");
24516         }
24517         check_reg(state, RHS(set, 0), REGCM_FLAGS);
24518         if ((RHS(set, 0)->op != OP_CMP) &&
24519                 (RHS(set, 0)->op != OP_TEST)) {
24520                 internal_error(state, set, "bad set test");
24521         }
24522         if (RHS(set, 0)->next != set) {
24523                 internal_error(state, set, "set does not follow test");
24524         }
24525         switch(set->op) {
24526         case OP_SET_EQ:       sop = "setz";  break;
24527         case OP_SET_NOTEQ:    sop = "setnz"; break;
24528         case OP_SET_SLESS:    sop = "setl";  break;
24529         case OP_SET_ULESS:    sop = "setb";  break;
24530         case OP_SET_SMORE:    sop = "setg";  break;
24531         case OP_SET_UMORE:    sop = "seta";  break;
24532         case OP_SET_SLESSEQ:  sop = "setle"; break;
24533         case OP_SET_ULESSEQ:  sop = "setbe"; break;
24534         case OP_SET_SMOREEQ:  sop = "setge"; break;
24535         case OP_SET_UMOREEQ:  sop = "setae"; break;
24536         default:
24537                 internal_error(state, set, "Invalid set op");
24538                 break;
24539         }
24540         fprintf(fp, "\t%s %s\n",
24541                 sop, reg(state, set, REGCM_GPR8_LO));
24542 }
24543
24544 static void print_op_bit_scan(struct compile_state *state, 
24545         struct triple *ins, FILE *fp) 
24546 {
24547         const char *op;
24548         switch(ins->op) {
24549         case OP_BSF: op = "bsf"; break;
24550         case OP_BSR: op = "bsr"; break;
24551         default: 
24552                 internal_error(state, ins, "unknown bit scan");
24553                 op = 0;
24554                 break;
24555         }
24556         fprintf(fp, 
24557                 "\t%s %s, %s\n"
24558                 "\tjnz 1f\n"
24559                 "\tmovl $-1, %s\n"
24560                 "1:\n",
24561                 op,
24562                 reg(state, RHS(ins, 0), REGCM_GPR32),
24563                 reg(state, ins, REGCM_GPR32),
24564                 reg(state, ins, REGCM_GPR32));
24565 }
24566
24567
24568 static void print_sdecl(struct compile_state *state,
24569         struct triple *ins, FILE *fp)
24570 {
24571         fprintf(fp, ".section \"" DATA_SECTION "\"\n");
24572         fprintf(fp, ".balign %d\n", align_of_in_bytes(state, ins->type));
24573         fprintf(fp, "L%s%lu:\n", 
24574                 state->compiler->label_prefix, (unsigned long)(ins->u.cval));
24575         print_const(state, MISC(ins, 0), fp);
24576         fprintf(fp, ".section \"" TEXT_SECTION "\"\n");
24577                 
24578 }
24579
24580 static void print_instruction(struct compile_state *state,
24581         struct triple *ins, FILE *fp)
24582 {
24583         /* Assumption: after I have exted the register allocator
24584          * everything is in a valid register. 
24585          */
24586         switch(ins->op) {
24587         case OP_ASM:
24588                 print_op_asm(state, ins, fp);
24589                 break;
24590         case OP_ADD:    print_binary_op(state, "add", ins, fp); break;
24591         case OP_SUB:    print_binary_op(state, "sub", ins, fp); break;
24592         case OP_AND:    print_binary_op(state, "and", ins, fp); break;
24593         case OP_XOR:    print_binary_op(state, "xor", ins, fp); break;
24594         case OP_OR:     print_binary_op(state, "or",  ins, fp); break;
24595         case OP_SL:     print_op_shift(state, "shl", ins, fp); break;
24596         case OP_USR:    print_op_shift(state, "shr", ins, fp); break;
24597         case OP_SSR:    print_op_shift(state, "sar", ins, fp); break;
24598         case OP_POS:    break;
24599         case OP_NEG:    print_unary_op(state, "neg", ins, fp); break;
24600         case OP_INVERT: print_unary_op(state, "not", ins, fp); break;
24601         case OP_NOOP:
24602         case OP_INTCONST:
24603         case OP_ADDRCONST:
24604         case OP_BLOBCONST:
24605                 /* Don't generate anything here for constants */
24606         case OP_PHI:
24607                 /* Don't generate anything for variable declarations. */
24608                 break;
24609         case OP_UNKNOWNVAL:
24610                 fprintf(fp, " /* unknown %s */\n",
24611                         reg(state, ins, REGCM_ALL));
24612                 break;
24613         case OP_SDECL:
24614                 print_sdecl(state, ins, fp);
24615                 break;
24616         case OP_COPY:   
24617         case OP_CONVERT:
24618                 print_op_move(state, ins, fp);
24619                 break;
24620         case OP_LOAD:
24621                 print_op_load(state, ins, fp);
24622                 break;
24623         case OP_STORE:
24624                 print_op_store(state, ins, fp);
24625                 break;
24626         case OP_SMUL:
24627                 print_op_smul(state, ins, fp);
24628                 break;
24629         case OP_CMP:    print_op_cmp(state, ins, fp); break;
24630         case OP_TEST:   print_op_test(state, ins, fp); break;
24631         case OP_JMP:
24632         case OP_JMP_EQ:      case OP_JMP_NOTEQ:
24633         case OP_JMP_SLESS:   case OP_JMP_ULESS:
24634         case OP_JMP_SMORE:   case OP_JMP_UMORE:
24635         case OP_JMP_SLESSEQ: case OP_JMP_ULESSEQ:
24636         case OP_JMP_SMOREEQ: case OP_JMP_UMOREEQ:
24637         case OP_CALL:
24638                 print_op_branch(state, ins, fp);
24639                 break;
24640         case OP_RET:
24641                 print_op_ret(state, ins, fp);
24642                 break;
24643         case OP_SET_EQ:      case OP_SET_NOTEQ:
24644         case OP_SET_SLESS:   case OP_SET_ULESS:
24645         case OP_SET_SMORE:   case OP_SET_UMORE:
24646         case OP_SET_SLESSEQ: case OP_SET_ULESSEQ:
24647         case OP_SET_SMOREEQ: case OP_SET_UMOREEQ:
24648                 print_op_set(state, ins, fp);
24649                 break;
24650         case OP_INB:  case OP_INW:  case OP_INL:
24651                 print_op_in(state, ins, fp); 
24652                 break;
24653         case OP_OUTB: case OP_OUTW: case OP_OUTL:
24654                 print_op_out(state, ins, fp); 
24655                 break;
24656         case OP_BSF:
24657         case OP_BSR:
24658                 print_op_bit_scan(state, ins, fp);
24659                 break;
24660         case OP_RDMSR:
24661                 after_lhs(state, ins);
24662                 fprintf(fp, "\trdmsr\n");
24663                 break;
24664         case OP_WRMSR:
24665                 fprintf(fp, "\twrmsr\n");
24666                 break;
24667         case OP_HLT:
24668                 fprintf(fp, "\thlt\n");
24669                 break;
24670         case OP_SDIVT:
24671                 fprintf(fp, "\tidiv %s\n", reg(state, RHS(ins, 1), REGCM_GPR32));
24672                 break;
24673         case OP_UDIVT:
24674                 fprintf(fp, "\tdiv %s\n", reg(state, RHS(ins, 1), REGCM_GPR32));
24675                 break;
24676         case OP_UMUL:
24677                 fprintf(fp, "\tmul %s\n", reg(state, RHS(ins, 1), REGCM_GPR32));
24678                 break;
24679         case OP_LABEL:
24680                 if (!ins->use) {
24681                         return;
24682                 }
24683                 fprintf(fp, "L%s%lu:\n", 
24684                         state->compiler->label_prefix, (unsigned long)(ins->u.cval));
24685                 break;
24686         case OP_ADECL:
24687                 /* Ignore adecls with no registers error otherwise */
24688                 if (!noop_adecl(ins)) {
24689                         internal_error(state, ins, "adecl remains?");
24690                 }
24691                 break;
24692                 /* Ignore OP_PIECE */
24693         case OP_PIECE:
24694                 break;
24695                 /* Operations that should never get here */
24696         case OP_SDIV: case OP_UDIV:
24697         case OP_SMOD: case OP_UMOD:
24698         case OP_LTRUE:   case OP_LFALSE:  case OP_EQ:      case OP_NOTEQ:
24699         case OP_SLESS:   case OP_ULESS:   case OP_SMORE:   case OP_UMORE:
24700         case OP_SLESSEQ: case OP_ULESSEQ: case OP_SMOREEQ: case OP_UMOREEQ:
24701         default:
24702                 internal_error(state, ins, "unknown op: %d %s",
24703                         ins->op, tops(ins->op));
24704                 break;
24705         }
24706 }
24707
24708 static void print_instructions(struct compile_state *state)
24709 {
24710         struct triple *first, *ins;
24711         int print_location;
24712         struct occurance *last_occurance;
24713         FILE *fp;
24714         int max_inline_depth;
24715         max_inline_depth = 0;
24716         print_location = 1;
24717         last_occurance = 0;
24718         fp = state->output;
24719         /* Masks for common sizes */
24720         fprintf(fp, ".section \"" DATA_SECTION "\"\n");
24721         fprintf(fp, ".balign 16\n");
24722         fprintf(fp, "L%s1:\n", state->compiler->label_prefix);
24723         fprintf(fp, ".int 0xff, 0, 0, 0\n");
24724         fprintf(fp, "L%s2:\n", state->compiler->label_prefix);
24725         fprintf(fp, ".int 0xffff, 0, 0, 0\n");
24726         fprintf(fp, ".section \"" TEXT_SECTION "\"\n");
24727         first = state->first;
24728         ins = first;
24729         do {
24730                 if (print_location && 
24731                         last_occurance != ins->occurance) {
24732                         if (!ins->occurance->parent) {
24733                                 fprintf(fp, "\t/* %s,%s:%d.%d */\n",
24734                                         ins->occurance->function,
24735                                         ins->occurance->filename,
24736                                         ins->occurance->line,
24737                                         ins->occurance->col);
24738                         }
24739                         else {
24740                                 struct occurance *ptr;
24741                                 int inline_depth;
24742                                 fprintf(fp, "\t/*\n");
24743                                 inline_depth = 0;
24744                                 for(ptr = ins->occurance; ptr; ptr = ptr->parent) {
24745                                         inline_depth++;
24746                                         fprintf(fp, "\t * %s,%s:%d.%d\n",
24747                                                 ptr->function,
24748                                                 ptr->filename,
24749                                                 ptr->line,
24750                                                 ptr->col);
24751                                 }
24752                                 fprintf(fp, "\t */\n");
24753                                 if (inline_depth > max_inline_depth) {
24754                                         max_inline_depth = inline_depth;
24755                                 }
24756                         }
24757                         if (last_occurance) {
24758                                 put_occurance(last_occurance);
24759                         }
24760                         get_occurance(ins->occurance);
24761                         last_occurance = ins->occurance;
24762                 }
24763
24764                 print_instruction(state, ins, fp);
24765                 ins = ins->next;
24766         } while(ins != first);
24767         if (print_location) {
24768                 fprintf(fp, "/* max inline depth %d */\n",
24769                         max_inline_depth);
24770         }
24771 }
24772
24773 static void generate_code(struct compile_state *state)
24774 {
24775         generate_local_labels(state);
24776         print_instructions(state);
24777         
24778 }
24779
24780 static void print_preprocessed_tokens(struct compile_state *state)
24781 {
24782         int tok;
24783         FILE *fp;
24784         int line;
24785         const char *filename;
24786         fp = state->output;
24787         filename = 0;
24788         line = 0;
24789         for(;;) {
24790                 struct file_state *file;
24791                 struct token *tk;
24792                 const char *token_str;
24793                 tok = peek(state);
24794                 if (tok == TOK_EOF) {
24795                         break;
24796                 }
24797                 tk = eat(state, tok);
24798                 token_str = 
24799                         tk->ident ? tk->ident->name :
24800                         tk->str_len ? tk->val.str :
24801                         tokens[tk->tok];
24802
24803                 file = state->file;
24804                 while(file->macro && file->prev) {
24805                         file = file->prev;
24806                 }
24807                 if (!file->macro && 
24808                         ((file->line != line) || (file->basename != filename))) 
24809                 {
24810                         int i, col;
24811                         if ((file->basename == filename) &&
24812                                 (line < file->line)) {
24813                                 while(line < file->line) {
24814                                         fprintf(fp, "\n");
24815                                         line++;
24816                                 }
24817                         }
24818                         else {
24819                                 fprintf(fp, "\n#line %d \"%s\"\n",
24820                                         file->line, file->basename);
24821                         }
24822                         line = file->line;
24823                         filename = file->basename;
24824                         col = get_col(file) - strlen(token_str);
24825                         for(i = 0; i < col; i++) {
24826                                 fprintf(fp, " ");
24827                         }
24828                 }
24829                 
24830                 fprintf(fp, "%s ", token_str);
24831                 
24832                 if (state->compiler->debug & DEBUG_TOKENS) {
24833                         loc(state->dbgout, state, 0);
24834                         fprintf(state->dbgout, "%s <- `%s'\n",
24835                                 tokens[tok], token_str);
24836                 }
24837         }
24838 }
24839
24840 static void compile(const char *filename, 
24841         struct compiler_state *compiler, struct arch_state *arch)
24842 {
24843         int i;
24844         struct compile_state state;
24845         struct triple *ptr;
24846         memset(&state, 0, sizeof(state));
24847         state.compiler = compiler;
24848         state.arch     = arch;
24849         state.file = 0;
24850         for(i = 0; i < sizeof(state.token)/sizeof(state.token[0]); i++) {
24851                 memset(&state.token[i], 0, sizeof(state.token[i]));
24852                 state.token[i].tok = -1;
24853         }
24854         /* Remember the output descriptors */
24855         state.errout = stderr;
24856         state.dbgout = stdout;
24857         /* Remember the output filename */
24858         state.output    = fopen(state.compiler->ofilename, "w");
24859         if (!state.output) {
24860                 error(&state, 0, "Cannot open output file %s\n",
24861                         state.compiler->ofilename);
24862         }
24863         /* Make certain a good cleanup happens */
24864         exit_state = &state;
24865         atexit(exit_cleanup);
24866
24867         /* Prep the preprocessor */
24868         state.if_depth = 0;
24869         memset(state.if_bytes, 0, sizeof(state.if_bytes));
24870         /* register the C keywords */
24871         register_keywords(&state);
24872         /* register the keywords the macro preprocessor knows */
24873         register_macro_keywords(&state);
24874         /* generate some builtin macros */
24875         register_builtin_macros(&state);
24876         /* Memorize where some special keywords are. */
24877         state.i_switch        = lookup(&state, "switch", 6);
24878         state.i_case          = lookup(&state, "case", 4);
24879         state.i_continue      = lookup(&state, "continue", 8);
24880         state.i_break         = lookup(&state, "break", 5);
24881         state.i_default       = lookup(&state, "default", 7);
24882         state.i_return        = lookup(&state, "return", 6);
24883         /* Memorize where predefined macros are. */
24884         state.i___VA_ARGS__   = lookup(&state, "__VA_ARGS__", 11);
24885         state.i___FILE__      = lookup(&state, "__FILE__", 8);
24886         state.i___LINE__      = lookup(&state, "__LINE__", 8);
24887         /* Memorize where predefined identifiers are. */
24888         state.i___func__      = lookup(&state, "__func__", 8);
24889         /* Memorize where some attribute keywords are. */
24890         state.i_noinline      = lookup(&state, "noinline", 8);
24891         state.i_always_inline = lookup(&state, "always_inline", 13);
24892
24893         /* Process the command line macros */
24894         process_cmdline_macros(&state);
24895
24896         /* Allocate beginning bounding labels for the function list */
24897         state.first = label(&state);
24898         state.first->id |= TRIPLE_FLAG_VOLATILE;
24899         use_triple(state.first, state.first);
24900         ptr = label(&state);
24901         ptr->id |= TRIPLE_FLAG_VOLATILE;
24902         use_triple(ptr, ptr);
24903         flatten(&state, state.first, ptr);
24904
24905         /* Allocate a label for the pool of global variables */
24906         state.global_pool = label(&state);
24907         state.global_pool->id |= TRIPLE_FLAG_VOLATILE;
24908         flatten(&state, state.first, state.global_pool);
24909
24910         /* Enter the globl definition scope */
24911         start_scope(&state);
24912         register_builtins(&state);
24913         compile_file(&state, filename, 1);
24914
24915         /* Stop if all we want is preprocessor output */
24916         if (state.compiler->flags & COMPILER_PP_ONLY) {
24917                 print_preprocessed_tokens(&state);
24918                 return;
24919         }
24920
24921         decls(&state);
24922
24923         /* Exit the global definition scope */
24924         end_scope(&state);
24925
24926         /* Now that basic compilation has happened 
24927          * optimize the intermediate code 
24928          */
24929         optimize(&state);
24930
24931         generate_code(&state);
24932         if (state.compiler->debug) {
24933                 fprintf(state.errout, "done\n");
24934         }
24935         exit_state = 0;
24936 }
24937
24938 static void version(FILE *fp)
24939 {
24940         fprintf(fp, "romcc " VERSION " released " RELEASE_DATE "\n");
24941 }
24942
24943 static void usage(void)
24944 {
24945         FILE *fp = stdout;
24946         version(fp);
24947         fprintf(fp,
24948                 "\nUsage: romcc [options] <source>.c\n"
24949                 "Compile a C source file generating a binary that does not implicilty use RAM\n"
24950                 "Options: \n"
24951                 "-o <output file name>\n"
24952                 "-f<option>            Specify a generic compiler option\n"
24953                 "-m<option>            Specify a arch dependent option\n"
24954                 "--                    Specify this is the last option\n"
24955                 "\nGeneric compiler options:\n"
24956         );
24957         compiler_usage(fp);
24958         fprintf(fp,
24959                 "\nArchitecture compiler options:\n"
24960         );
24961         arch_usage(fp);
24962         fprintf(fp,
24963                 "\n"
24964         );
24965 }
24966
24967 static void arg_error(char *fmt, ...)
24968 {
24969         va_list args;
24970         va_start(args, fmt);
24971         vfprintf(stderr, fmt, args);
24972         va_end(args);
24973         usage();
24974         exit(1);
24975 }
24976
24977 int main(int argc, char **argv)
24978 {
24979         const char *filename;
24980         struct compiler_state compiler;
24981         struct arch_state arch;
24982         int all_opts;
24983         
24984         
24985         /* I don't want any surprises */
24986         setlocale(LC_ALL, "C");
24987
24988         init_compiler_state(&compiler);
24989         init_arch_state(&arch);
24990         filename = 0;
24991         all_opts = 0;
24992         while(argc > 1) {
24993                 if (!all_opts && (strcmp(argv[1], "-o") == 0) && (argc > 2)) {
24994                         compiler.ofilename = argv[2];
24995                         argv += 2;
24996                         argc -= 2;
24997                 }
24998                 else if (!all_opts && argv[1][0] == '-') {
24999                         int result;
25000                         result = -1;
25001                         if (strcmp(argv[1], "--") == 0) {
25002                                 result = 0;
25003                                 all_opts = 1;
25004                         }
25005                         else if (strncmp(argv[1], "-E", 2) == 0) {
25006                                 result = compiler_encode_flag(&compiler, argv[1]);
25007                         }
25008                         else if (strncmp(argv[1], "-O", 2) == 0) {
25009                                 result = compiler_encode_flag(&compiler, argv[1]);
25010                         }
25011                         else if (strncmp(argv[1], "-I", 2) == 0) {
25012                                 result = compiler_encode_flag(&compiler, argv[1]);
25013                         }
25014                         else if (strncmp(argv[1], "-D", 2) == 0) {
25015                                 result = compiler_encode_flag(&compiler, argv[1]);
25016                         }
25017                         else if (strncmp(argv[1], "-U", 2) == 0) {
25018                                 result = compiler_encode_flag(&compiler, argv[1]);
25019                         }
25020                         else if (strncmp(argv[1], "--label-prefix=", 15) == 0) {
25021                                 result = compiler_encode_flag(&compiler, argv[1]+2);
25022                         }
25023                         else if (strncmp(argv[1], "-f", 2) == 0) {
25024                                 result = compiler_encode_flag(&compiler, argv[1]+2);
25025                         }
25026                         else if (strncmp(argv[1], "-m", 2) == 0) {
25027                                 result = arch_encode_flag(&arch, argv[1]+2);
25028                         }
25029                         if (result < 0) {
25030                                 arg_error("Invalid option specified: %s\n",
25031                                         argv[1]);
25032                         }
25033                         argv++;
25034                         argc--;
25035                 }
25036                 else {
25037                         if (filename) {
25038                                 arg_error("Only one filename may be specified\n");
25039                         }
25040                         filename = argv[1];
25041                         argv++;
25042                         argc--;
25043                 }
25044         }
25045         if (!filename) {
25046                 arg_error("No filename specified\n");
25047         }
25048         compile(filename, &compiler, &arch);
25049
25050         return 0;
25051 }